aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/jogamp/opengl/JoglVersion.java2
-rw-r--r--src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java18
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/Animator.java28
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java10
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java4
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java45
-rw-r--r--src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java4
-rw-r--r--src/jogl/classes/javax/media/opengl/GLBase.java11
-rw-r--r--src/jogl/classes/javax/media/opengl/GLContext.java74
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawable.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/GLDrawableFactory.java111
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java287
-rw-r--r--src/jogl/classes/javax/media/opengl/GLUniformData.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLCanvas.java184
-rw-r--r--src/jogl/classes/javax/media/opengl/awt/GLJPanel.java246
-rw-r--r--src/jogl/classes/jogamp/graph/curve/text/GlyphString.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/FPSCounterImpl.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/GLContextImpl.java422
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java14
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java85
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableHelper.java217
-rw-r--r--src/jogl/classes/jogamp/opengl/GLDrawableImpl.java19
-rw-r--r--src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/GLPbufferImpl.java23
-rw-r--r--src/jogl/classes/jogamp/opengl/SharedResourceRunner.java158
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/Java2D.java59
-rw-r--r--src/jogl/classes/jogamp/opengl/awt/VersionApplet.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLContext.java40
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java12
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java115
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java7
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java20
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java39
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java221
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java41
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java239
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java24
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java22
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java27
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java30
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java35
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java131
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java19
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java95
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java24
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java6
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java1
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java9
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java304
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java41
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java24
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java182
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java16
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java20
-rw-r--r--src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java23
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java99
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java4
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java109
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java10
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java363
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java38
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java52
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java8
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java39
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java2
-rw-r--r--src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java29
-rw-r--r--src/jogl/native/GLDebugMessageHandler.c30
-rw-r--r--src/jogl/native/macosx/ContextUpdater.h6
-rw-r--r--src/jogl/native/macosx/ContextUpdater.m57
-rw-r--r--src/jogl/native/macosx/MacOSXCustomCGLCode.c5
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m140
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m480
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.h20
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface.m246
-rw-r--r--src/jogl/native/timespec.c63
-rw-r--r--src/jogl/native/timespec.h19
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java13
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java9
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java27
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java63
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java23
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java15
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java166
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java61
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java48
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java38
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java8
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java6
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java61
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java38
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java10
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java6
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java32
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java13
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java43
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java19
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java85
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java8
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java10
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java82
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java300
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java232
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java2
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java36
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java24
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java56
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java71
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java4
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java17
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java101
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java45
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java20
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java23
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java406
-rw-r--r--src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java (renamed from src/jogl/classes/jogamp/opengl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java)108
-rw-r--r--src/nativewindow/native/JAWT_DrawingSurfaceInfo.c7
-rw-r--r--src/nativewindow/native/macosx/OSXmisc.m227
-rw-r--r--src/nativewindow/native/windows/GDImisc.c32
-rw-r--r--src/nativewindow/native/x11/Xmisc.c10
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java7
-rw-r--r--src/newt/classes/com/jogamp/newt/NewtFactory.java140
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java14
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java76
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java297
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java98
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java46
-rw-r--r--src/newt/classes/com/jogamp/newt/event/InputEvent.java5
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseEvent.java14
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseListener.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java6
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java81
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MainThread.java32
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MonitorMode.java5
-rw-r--r--src/newt/classes/jogamp/newt/NEWTJNILibLoader.java4
-rw-r--r--src/newt/classes/jogamp/newt/OffscreenWindow.java37
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java138
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java370
-rw-r--r--src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java (renamed from src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java)36
-rw-r--r--src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java24
-rw-r--r--src/newt/classes/jogamp/newt/driver/DriverClearFocus.java12
-rw-r--r--src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java9
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java16
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java10
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java8
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java31
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java39
-rw-r--r--src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java18
-rw-r--r--src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java21
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java23
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java14
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/KDScreen.java22
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/KDWindow.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java262
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java72
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java450
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java28
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java57
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/X11Display.java34
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/X11Screen.java60
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/X11Window.java73
-rw-r--r--src/newt/native/KDWindow.c2
-rw-r--r--src/newt/native/KeyEvent.h27
-rw-r--r--src/newt/native/MacWindow.m295
-rw-r--r--src/newt/native/MouseEvent.h27
-rw-r--r--src/newt/native/NewtCommon.h27
-rw-r--r--src/newt/native/NewtMacWindow.h10
-rw-r--r--src/newt/native/NewtMacWindow.m111
-rw-r--r--src/newt/native/ScreenMode.h28
-rw-r--r--src/newt/native/Window.h27
-rw-r--r--src/newt/native/WindowEvent.h27
-rw-r--r--src/newt/native/WindowsWindow.c111
-rw-r--r--src/newt/native/X11Common.h80
-rw-r--r--src/newt/native/X11Display.c660
-rw-r--r--src/newt/native/X11Screen.c469
-rw-r--r--src/newt/native/X11Window.c1115
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java5
-rwxr-xr-xsrc/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java5
-rwxr-xr-xsrc/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UINewtDemo01.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java11
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java230
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLCanvasAWT.java52
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLWindowNEWT.java50
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNVSwapGroupNEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java127
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java156
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java778
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java157
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java125
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java144
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java124
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java127
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWTCardLayoutAnimatorStartStopBug532.java229
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java46
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemo01.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java12
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyNEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java15
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestGearsES1NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/newt/TestRedSquareES1NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestElektronenMultipliziererNEWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestGearsES2NEWT.java115
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/newt/TestRedSquareES2NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java30
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWTAnalyzeBug455.java171
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java17
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java7
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java13
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestRulerNEWT01.java16
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java10
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen01GLPBufferNEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java92
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle02NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java9
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java8
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows02NEWTAnimated.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java17
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java12
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java34
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java4
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java17
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01bNEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode02NEWT.java1
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/NewtAWTReparentingKeyAdapter.java6
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01NEWT.java3
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java2
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java5
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting03AWT.java72
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java334
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java205
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java209
-rw-r--r--src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java14
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java23
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java71
-rw-r--r--src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java1
-rw-r--r--src/test/jogamp/newt/WindowImplAccess.java16
-rw-r--r--src/test/native/displayMultiple02.c86
299 files changed, 12862 insertions, 5377 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
index d162f2bd8..8cb25174c 100644
--- a/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
+++ b/src/jogl/classes/com/jogamp/opengl/JoglVersion.java
@@ -70,7 +70,7 @@ public class JoglVersion extends JogampVersion {
public static StringBuilder getGLInfo(GL gl, StringBuilder sb) {
AbstractGraphicsDevice device = gl.getContext().getGLDrawable().getNativeSurface()
- .getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ .getGraphicsConfiguration().getScreen().getDevice();
if(null==sb) {
sb = new StringBuilder();
}
diff --git a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
index 9e4d76869..ba159b82c 100644
--- a/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/com/jogamp/opengl/cg/CgDynamicLibraryBundleInfo.java
@@ -28,12 +28,30 @@
package com.jogamp.opengl.cg;
+import com.jogamp.common.jvm.JNILibLoaderBase;
import com.jogamp.common.os.DynamicLibraryBundleInfo;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.cache.TempJarCache;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.*;
public class CgDynamicLibraryBundleInfo implements DynamicLibraryBundleInfo {
private static List<String> glueLibNames;
static {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ Platform.initSingleton();
+
+ if(TempJarCache.isInitialized()) {
+ // Cg class and natives are available in their single atomic JAR files only
+ JNILibLoaderBase.addNativeJarLibs(CgDynamicLibraryBundleInfo.class, "jogl_cg", null);
+ }
+ return null;
+ }
+ });
+
glueLibNames = new ArrayList<String>();
// glueLibNames.addAll(getGlueLibNamesPreload());
glueLibNames.add("jogl_cg");
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
index 93b75e70b..26d299663 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AWTAnimatorImpl.java
@@ -164,7 +164,7 @@ class AWTAnimatorImpl implements AnimatorBase.AnimatorImpl {
}
};
- public boolean skipWaitForCompletion(Thread thread) {
- return ((Thread.currentThread() == thread) || EventQueue.isDispatchThread());
+ public boolean blockUntilDone(Thread thread) {
+ return ((Thread.currentThread() != thread) && !EventQueue.isDispatchThread());
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/Animator.java b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
index 16aac957a..6d508f227 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/Animator.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/Animator.java
@@ -59,7 +59,9 @@ import javax.media.opengl.GLAutoDrawable;
*/
public class Animator extends AnimatorBase {
-
+ /** timeout in milliseconds, 15 frames @ 60Hz = 240ms, limiting {@link #finishLifecycleAction(Condition)} */
+ private static final long TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION = 15*16;
+
protected ThreadGroup threadGroup;
private Runnable runnable;
private boolean runAsFastAsPossible;
@@ -241,18 +243,24 @@ public class Animator extends AnimatorBase {
// dependencies on the Animator's internal thread. Currently we
// use a couple of heuristics to determine whether we should do
// the blocking wait().
- boolean doWait = !impl.skipWaitForCompletion(animThread);
- if (doWait) {
- while (condition.result()) {
- try {
- wait();
- } catch (InterruptedException ie) { }
- }
+ final boolean blocking = impl.blockUntilDone(animThread);
+ long remaining = blocking ? TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION : 0;
+ while (remaining>0 && condition.result()) {
+ long td = System.currentTimeMillis();
+ try {
+ wait(remaining);
+ } catch (InterruptedException ie) { }
+ remaining -= (System.currentTimeMillis() - td) ;
}
if(DEBUG) {
- System.err.println("finishLifecycleAction(" + condition.getClass().getName() + "): finished - waited " + doWait +
+ if(remaining<0) {
+ System.err.println("finishLifecycleAction(" + condition.getClass().getName() + "): ++++++ timeout reached ++++++ " + Thread.currentThread().getName());
+ }
+ System.err.println("finishLifecycleAction(" + condition.getClass().getName() + "): finished "+
+ "- blocking "+blocking+
+ ", waited " + (blocking ? ( TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION - remaining ) : 0 ) + "/" + TO_WAIT_FOR_FINISH_LIFECYCLE_ACTION +
", started: " + isStartedImpl() +", animating: " + isAnimatingImpl() +
- ", paused: " + isPausedImpl() + ", drawables " + drawables.size());
+ ", paused: " + isPausedImpl() + ", drawables " + drawables.size() + " - " + Thread.currentThread().getName());
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
index e84a9bf78..d65967da1 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/AnimatorBase.java
@@ -56,7 +56,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
public interface AnimatorImpl {
void display(ArrayList<GLAutoDrawable> drawables, boolean ignoreExceptions, boolean printExceptions);
- boolean skipWaitForCompletion(Thread thread);
+ boolean blockUntilDone(Thread thread);
}
protected ArrayList<GLAutoDrawable> drawables = new ArrayList<GLAutoDrawable>();
@@ -92,7 +92,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
public synchronized void add(GLAutoDrawable drawable) {
if(DEBUG) {
- System.err.println("Animator add: "+drawable.hashCode()+" - "+Thread.currentThread());
+ System.err.println("Animator add: "+drawable.hashCode()+" - "+Thread.currentThread().getName());
}
boolean paused = pause();
drawables.add(drawable);
@@ -101,7 +101,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
if(paused) {
resume();
}
- if(!impl.skipWaitForCompletion(animThread)) {
+ if(impl.blockUntilDone(animThread)) {
while(isStarted() && !isPaused() && !isAnimating()) {
try {
wait();
@@ -113,7 +113,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
public synchronized void remove(GLAutoDrawable drawable) {
if(DEBUG) {
- System.err.println("Animator remove: "+drawable.hashCode()+" - "+Thread.currentThread() + ": "+toString());
+ System.err.println("Animator remove: "+drawable.hashCode()+" - "+Thread.currentThread().getName() + ": "+toString());
}
boolean paused = pause();
@@ -123,7 +123,7 @@ public abstract class AnimatorBase implements GLAnimatorControl {
if(paused) {
resume();
}
- if(!impl.skipWaitForCompletion(animThread)) {
+ if(impl.blockUntilDone(animThread)) {
while(isStarted() && drawablesEmpty && isAnimating()) {
try {
wait();
diff --git a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
index bad268f70..23b0845ee 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/DefaultAnimatorImpl.java
@@ -60,7 +60,7 @@ class DefaultAnimatorImpl implements AnimatorBase.AnimatorImpl {
}
}
- public boolean skipWaitForCompletion(Thread thread) {
- return (Thread.currentThread() == thread);
+ public boolean blockUntilDone(Thread thread) {
+ return (Thread.currentThread() != thread);
}
}
diff --git a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
index f2e742cda..4ab603576 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/GLBuffers.java
@@ -49,9 +49,8 @@ import java.nio.*;
/**
* Utility routines for dealing with direct buffers.
- * @author Kenneth Russel
- * @author Sven Gothel
- * @author Michael Bien
+ *
+ * @author Kenneth Russel, et.al.
*/
public class GLBuffers extends Buffers {
@@ -66,7 +65,8 @@ public class GLBuffers extends Buffers {
* GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
* GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
* GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (25)
+ * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)
* @return -1 if glType is unhandled, otherwise the actual value > 0
*/
public static final int sizeOfGLType(int glType) {
@@ -97,6 +97,8 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_INT_24_8:
case GL2GL3.GL_UNSIGNED_INT_10F_11F_11F_REV:
case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL2.GL_HILO16_NV:
+ case GL2.GL_SIGNED_HILO16_NV:
return SIZEOF_INT;
case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
@@ -122,7 +124,8 @@ public class GLBuffers extends Buffers {
* GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
* GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
* GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (25)
+ * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)
* @return null if glType is unhandled, otherwise the new Buffer object
*/
public static final Buffer newDirectGLBuffer(int glType, int numElements) {
@@ -153,6 +156,8 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_INT_24_8:
case GL2GL3.GL_UNSIGNED_INT_10F_11F_11F_REV:
case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL2.GL_HILO16_NV:
+ case GL2.GL_SIGNED_HILO16_NV:
return newDirectIntBuffer(numElements);
case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
@@ -178,7 +183,8 @@ public class GLBuffers extends Buffers {
* GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
* GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
* GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (25)
+ * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV (27)
* @return null if glType is unhandled or parent is null or bufLen is 0, otherwise the new Buffer object
*/
public static final Buffer sliceGLBuffer(ByteBuffer parent, int bytePos, int byteLen, int glType) {
@@ -215,6 +221,8 @@ public class GLBuffers extends Buffers {
case GL2GL3.GL_UNSIGNED_INT_24_8:
case GL2GL3.GL_UNSIGNED_INT_10F_11F_11F_REV:
case GL2GL3.GL_UNSIGNED_INT_5_9_9_9_REV:
+ case GL2.GL_HILO16_NV:
+ case GL2.GL_SIGNED_HILO16_NV:
return parent.asIntBuffer();
case GL2GL3.GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
@@ -360,7 +368,7 @@ public class GLBuffers extends Buffers {
* GL_RGB, GL_BGR, GL_RGBA, GL_BGRA, GL_ABGR_EXT,
* GL_RED_INTEGER, GL_GREEN_INTEGER, GL_BLUE_INTEGER,
* GL_RG_INTEGER, GL_RGB_INTEGER, GL_BGR_INTEGER,
- * GL_RGBA_INTEGER, GL_BGRA_INTEGER (24)
+ * GL_RGBA_INTEGER, GL_BGRA_INTEGER, GL_HILO_NV, GL_SIGNED_HILO_NV (26)
*
* @param type must be one of
* GL_BITMAP,
@@ -373,7 +381,8 @@ public class GLBuffers extends Buffers {
* GL_UNSIGNED_INT_8_8_8_8, GL_UNSIGNED_INT_8_8_8_8_REV,
* GL_UNSIGNED_INT_10_10_10_2, GL_UNSIGNED_INT_2_10_10_10_REV
* GL_UNSIGNED_INT_24_8, GL_UNSIGNED_INT_10F_11F_11F_REV,
- * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV (26)
+ * GL_UNSIGNED_INT_5_9_9_9_REV, GL_FLOAT_32_UNSIGNED_INT_24_8_REV,
+ * GL_HILO16_NV, GL_SIGNED_HILO16_NV (28)
*
* @param width in pixels
* @param height in pixels
@@ -410,6 +419,8 @@ public class GLBuffers extends Buffers {
case GL.GL_LUMINANCE_ALPHA:
case GL2GL3.GL_RG:
case GL2GL3.GL_RG_INTEGER:
+ case GL2.GL_HILO_NV:
+ case GL2.GL_SIGNED_HILO_NV:
elements = 2;
break;
case GL.GL_RGB:
@@ -470,6 +481,11 @@ public class GLBuffers extends Buffers {
esize = 2;
elements = 1;
break;
+ case GL2.GL_HILO16_NV:
+ case GL2.GL_SIGNED_HILO16_NV:
+ esize = 2;
+ elements = 2;
+ break;
case GL2GL3.GL_UNSIGNED_INT_8_8_8_8:
case GL2GL3.GL_UNSIGNED_INT_8_8_8_8_REV:
case GL2GL3.GL_UNSIGNED_INT_10_10_10_2:
@@ -491,6 +507,19 @@ public class GLBuffers extends Buffers {
return sizeof(gl, tmp, elements * esize, width, height, depth, pack);
}
+
+ public static final int getNextPowerOf2(int number) {
+ if (((number-1) & number) == 0) {
+ //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
+ return number;
+ }
+ int power = 0;
+ while (number > 0) {
+ number = number>>1;
+ power++;
+ }
+ return (1<<power);
+ }
//----------------------------------------------------------------------
// Conversion routines
diff --git a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
index b6df365ba..7f3aa8a39 100644
--- a/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
+++ b/src/jogl/classes/com/jogamp/opengl/util/texture/Texture.java
@@ -1055,9 +1055,7 @@ public class Texture {
// Helper routines for disabling certain codepaths
private static boolean haveNPOT(GL gl) {
- return (!disableNPOT &&
- ( gl.isGLES2() ||
- gl.isExtensionAvailable("GL_ARB_texture_non_power_of_two") ) );
+ return !disableNPOT && gl.isNPOTTextureAvailable();
}
private static boolean haveTexRect(GL gl) {
diff --git a/src/jogl/classes/javax/media/opengl/GLBase.java b/src/jogl/classes/javax/media/opengl/GLBase.java
index f93d443e0..534e449bc 100644
--- a/src/jogl/classes/javax/media/opengl/GLBase.java
+++ b/src/jogl/classes/javax/media/opengl/GLBase.java
@@ -294,6 +294,17 @@ public interface GLBase {
*/
public boolean isExtensionAvailable(String glExtensionName);
+ /**
+ * Returns true if the GL context supports non power of two (NPOT) textures,
+ * otherwise false.
+ * <p>
+ * NPOT textures are supported in OpenGL >= 3, GLES2 or if the
+ * 'GL_ARB_texture_non_power_of_two' extension is available.
+ * </p>
+ * @return
+ */
+ public boolean isNPOTTextureAvailable();
+
/** Provides a platform-independent way to specify the minimum swap
interval for buffer swaps. An argument of 0 disables
sync-to-vertical-refresh completely, while an argument of 1
diff --git a/src/jogl/classes/javax/media/opengl/GLContext.java b/src/jogl/classes/javax/media/opengl/GLContext.java
index 9d99a32ff..8626400f7 100644
--- a/src/jogl/classes/javax/media/opengl/GLContext.java
+++ b/src/jogl/classes/javax/media/opengl/GLContext.java
@@ -45,9 +45,12 @@ import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.HashMap;
import java.util.HashSet;
+
import javax.media.nativewindow.AbstractGraphicsDevice;
import com.jogamp.common.util.IntObjectHashMap;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveLock;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
@@ -65,7 +68,8 @@ import jogamp.opengl.GLContextImpl;
abstraction provides a stable object which clients can use to
refer to a given context. */
public abstract class GLContext {
-
+ public static final boolean DEBUG = Debug.debug("GLContext");
+
/** Reflects property jogl.debug.DebugGL. If true, the debug pipeline is enabled at context creation. */
public final static boolean DEBUG_GL;
/** Reflects property jogl.debug.TraceGL. If true, the trace pipeline is enabled at context creation. */
@@ -105,12 +109,15 @@ public abstract class GLContext {
protected static final int CTX_IMPL_ACCEL_SOFT = 1 << 0;
/** GLContext {@link com.jogamp.gluegen.runtime.ProcAddressTable} caching related: GL hardware implementation */
protected static final int CTX_IMPL_ACCEL_HARD = 1 << 1;
-
+
private static ThreadLocal<GLContext> currentContext = new ThreadLocal<GLContext>();
private HashMap<String, Object> attachedObjectsByString = new HashMap<String, Object>();
private IntObjectHashMap attachedObjectsByInt = new IntObjectHashMap();
+ // RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock.
+ protected RecursiveLock lock = LockFactory.createRecursiveLock();
+
/** The underlying native OpenGL context */
protected long contextHandle;
@@ -293,8 +300,11 @@ public abstract class GLContext {
/**
* Destroys this OpenGL context and frees its associated
- * resources. The context should have been released before this
- * method is called.
+ * resources.
+ * <p>
+ * The context may be current w/o recursion when calling <code>destroy()</code>,
+ * in which case this method destroys the context and releases the lock.
+ * </p>
*/
public abstract void destroy();
@@ -406,6 +416,8 @@ public abstract class GLContext {
sb.append(",\n\tDrawable: ");
sb.append(getGLDrawable());
}
+ sb.append(", lock ");
+ sb.append(lock.toString());
return sb;
}
@@ -767,12 +779,12 @@ public abstract class GLContext {
/**
* @see #getDeviceVersionAvailableKey(javax.media.nativewindow.AbstractGraphicsDevice, int, int)
*/
- protected static /*final*/ HashMap/*<DeviceVersionAvailableKey, Integer>*/ deviceVersionAvailable = new HashMap();
+ protected static /*final*/ HashMap<String, Integer> deviceVersionAvailable = new HashMap<String, Integer>();
/**
* @see #getUniqueDeviceString(javax.media.nativewindow.AbstractGraphicsDevice)
*/
- private static /*final*/ HashSet/*<UniqueDeviceString>*/ deviceVersionsAvailableSet = new HashSet();
+ private static /*final*/ HashSet<String> deviceVersionsAvailableSet = new HashSet<String>();
protected static String getDeviceVersionAvailableKey(AbstractGraphicsDevice device, int major, int profile) {
return device.getUniqueID() + "-" + toHexString(compose8bit(major, profile, 0, 0));
@@ -791,16 +803,18 @@ public abstract class GLContext {
throw new InternalError("Already set: "+devKey);
}
deviceVersionsAvailableSet.add(devKey);
- if (GLContextImpl.DEBUG) {
+ if (DEBUG) {
System.err.println(getThreadName() + ": !!! createContextARB: SET mappedVersionsAvailableSet "+devKey);
// Thread.dumpStack();
}
}
}
+ /** clears the device/context mappings as well as the GL/GLX proc address tables. */
protected static void shutdown() {
deviceVersionAvailable.clear();
- deviceVersionsAvailableSet.clear();
+ deviceVersionsAvailableSet.clear();
+ GLContextImpl.shutdownImpl(); // well ..
}
/**
@@ -824,7 +838,7 @@ public abstract class GLContext {
String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
Integer val = new Integer(compose8bit(resMajor, resMinor, resCtp, 0));
synchronized(deviceVersionAvailable) {
- val = (Integer) deviceVersionAvailable.put( key, val );
+ val = deviceVersionAvailable.put( key, val );
}
return val;
}
@@ -833,7 +847,7 @@ public abstract class GLContext {
String key = getDeviceVersionAvailableKey(device, reqMajor, profile);
Integer val;
synchronized(deviceVersionAvailable) {
- val = (Integer) deviceVersionAvailable.get( key );
+ val = deviceVersionAvailable.get( key );
}
return val;
}
@@ -875,29 +889,29 @@ public abstract class GLContext {
return null != getAvailableGLVersion(device, major, profile);
}
- public static boolean isGLES1Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
- }
+ public static boolean isGLES1Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 1, GLContext.CTX_PROFILE_ES);
+ }
- public static boolean isGLES2Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
- }
+ public static boolean isGLES2Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 2, GLContext.CTX_PROFILE_ES);
+ }
- public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
- }
+ public static boolean isGL4bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_COMPAT);
+ }
- public static boolean isGL4Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
- }
+ public static boolean isGL4Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 4, CTX_PROFILE_CORE);
+ }
- public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
- }
+ public static boolean isGL3bcAvailable(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_COMPAT);
+ }
- public static boolean isGL3Available(AbstractGraphicsDevice device) {
- return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
- }
+ public static boolean isGL3Available(AbstractGraphicsDevice device) {
+ return isGLVersionAvailable(device, 3, CTX_PROFILE_CORE);
+ }
public static boolean isGL2Available(AbstractGraphicsDevice device) {
return isGLVersionAvailable(device, 2, CTX_PROFILE_COMPAT);
@@ -941,6 +955,10 @@ public abstract class GLContext {
return sb.toString();
}
+ //
+ // internal string utils
+ //
+
protected static String toString(int val, boolean hex) {
if(hex) {
return "0x" + Integer.toHexString(val);
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawable.java b/src/jogl/classes/javax/media/opengl/GLDrawable.java
index f4cd77059..2b86a04ba 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawable.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawable.java
@@ -158,6 +158,12 @@ public interface GLDrawable {
*/
public GLProfile getGLProfile();
+ /**
+ * Returns the underlying native surface which surface handle
+ * represents this OpenGL drawable's native resource.
+ *
+ * @see #getHandle()
+ */
public NativeSurface getNativeSurface();
/**
diff --git a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
index 1282eb168..3f9700436 100644
--- a/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
+++ b/src/jogl/classes/javax/media/opengl/GLDrawableFactory.java
@@ -47,12 +47,14 @@ import java.util.List;
import com.jogamp.common.JogampRuntimeException;
import jogamp.common.Debug;
+
import com.jogamp.common.util.ReflectionUtil;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
+import javax.media.opengl.GLProfile.ShutdownType;
/** <P> Provides a virtual machine- and operating system-independent
mechanism for creating {@link GLDrawable}s. </P>
@@ -87,14 +89,12 @@ import javax.media.nativewindow.ProxySurface;
property <code>opengl.factory.class.name</code> to the
fully-qualified name of the desired class. </P>
*/
-
public abstract class GLDrawableFactory {
- private static final String nativeOSType;
static final String macosxFactoryClassNameCGL = "jogamp.opengl.macosx.cgl.MacOSXCGLDrawableFactory";
static final String macosxFactoryClassNameAWTCGL = "jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLDrawableFactory";
- private static volatile boolean initialized = false;
+ private static volatile boolean isInit = false;
private static GLDrawableFactory eglFactory;
private static GLDrawableFactory nativeOSFactory;
@@ -107,16 +107,20 @@ public abstract class GLDrawableFactory {
/**
* Instantiate singleton factories if available, EGLES1, EGLES2 and the OS native ones.
*/
- static {
- nativeOSType = NativeWindowFactory.getNativeWindowType(true);
- }
-
- protected static final void initialize() {
- if(initialized) { return; }
- initialized = true;
-
+ public static final void initSingleton() {
+ if (!isInit) { // volatile: ok
+ synchronized (GLDrawableFactory.class) {
+ if (!isInit) {
+ isInit=true;
+ initSingletonImpl();
+ }
+ }
+ }
+ }
+ private static final void initSingletonImpl() {
registerFactoryShutdownHook();
+ final String nativeOSType = NativeWindowFactory.getNativeWindowType(true);
GLDrawableFactory tmp = null;
String factoryClassName = Debug.getProperty("jogl.gldrawablefactory.class.name", true, AccessController.getContext());
ClassLoader cl = GLDrawableFactory.class.getClassLoader();
@@ -165,16 +169,40 @@ public abstract class GLDrawableFactory {
eglFactory = tmp;
}
+ protected static void shutdown(ShutdownType shutdownType) {
+ if (isInit) { // volatile: ok
+ synchronized (GLDrawableFactory.class) {
+ if (isInit) {
+ isInit=false;
+ unregisterFactoryShutdownHook();
+ shutdownImpl(shutdownType);
+ }
+ }
+ }
+ }
+ private static void shutdownImpl(ShutdownType shutdownType) {
+ synchronized(glDrawableFactories) {
+ for(int i=0; i<glDrawableFactories.size(); i++) {
+ glDrawableFactories.get(i).destroy(shutdownType);
+ }
+ glDrawableFactories.clear();
+
+ // both were members of glDrawableFactories and are shutdown already
+ nativeOSFactory = null;
+ eglFactory = null;
+ }
+ }
+
private static synchronized void registerFactoryShutdownHook() {
if (factoryShutdownHookRegistered) {
return;
}
factoryShutdownHook = new Thread(new Runnable() {
public void run() {
- GLDrawableFactory.shutdownImpl();
+ GLDrawableFactory.shutdownImpl(GLProfile.ShutdownType.COMPLETE);
}
});
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
Runtime.getRuntime().addShutdownHook(factoryShutdownHook);
return null;
@@ -187,7 +215,7 @@ public abstract class GLDrawableFactory {
if (!factoryShutdownHookRegistered) {
return;
}
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
Runtime.getRuntime().removeShutdownHook(factoryShutdownHook);
return null;
@@ -196,23 +224,6 @@ public abstract class GLDrawableFactory {
factoryShutdownHookRegistered = false;
}
- private static void shutdownImpl() {
- synchronized(glDrawableFactories) {
- for(int i=0; i<glDrawableFactories.size(); i++) {
- GLDrawableFactory factory = glDrawableFactories.get(i);
- factory.shutdownInstance();
- }
- glDrawableFactories.clear();
- }
- }
-
- protected static void shutdown() {
- unregisterFactoryShutdownHook();
- shutdownImpl();
- eglFactory = null;
- nativeOSFactory = null;
- initialized = false;
- }
protected GLDrawableFactory() {
synchronized(glDrawableFactories) {
@@ -223,7 +234,7 @@ public abstract class GLDrawableFactory {
protected void enterThreadCriticalZone() {};
protected void leaveThreadCriticalZone() {};
- protected abstract void shutdownInstance();
+ protected abstract void destroy(ShutdownType shutdownType);
/**
* Retrieve the default <code>device</code> {@link AbstractGraphicsDevice#getConnection() connection},
@@ -258,34 +269,31 @@ public abstract class GLDrawableFactory {
}
/**
- * Returns true if a shared context could be created while initialization
- * of shared resources for <code>device</code> {@link AbstractGraphicsDevice#getConnection()}.<br>
- * This does not imply a shared context is mapped, but was available<br>.
- *
- * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * Validate and start the shared resource runner thread if necessary and
+ * if the implementation uses it.
+ *
+ * @return the shared resource runner thread, if implementation uses it.
*/
- public abstract boolean getWasSharedContextCreated(AbstractGraphicsDevice device);
-
+ protected abstract Thread getSharedResourceThread();
+
/**
- * Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
- * either a pre-existing or newly created, or <code>null</code> if creation failed or not supported.<br>
- * Creation of the shared context is tried only once.
+ * Create the shared resource used internally as a reference for capabilities etc.
+ * <p>
+ * Returns true if a shared resource could be created
+ * for the <code>device</code> {@link AbstractGraphicsDevice#getConnection()}.<br>
+ * This does not imply a shared resource is mapped (ie. made persistent), but is available in general<br>.
+ * </p>
*
* @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ * @return true if a shared resource could been created, otherwise false.
*/
- public final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) {
- device = validateDevice(device);
- if(null!=device) {
- return getOrCreateSharedContextImpl(device);
- }
- return null;
- }
- protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
-
+ protected abstract boolean createSharedResource(AbstractGraphicsDevice device);
+
/**
* Returns the sole GLDrawableFactory instance for the desktop (X11, WGL, ..) if exist or null
*/
public static GLDrawableFactory getDesktopFactory() {
+ GLProfile.initSingleton();
return nativeOSFactory;
}
@@ -293,6 +301,7 @@ public abstract class GLDrawableFactory {
* Returns the sole GLDrawableFactory instance for EGL if exist or null
*/
public static GLDrawableFactory getEGLFactory() {
+ GLProfile.initSingleton();
return eglFactory;
}
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 20e2f2a33..6b39fe765 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -48,6 +48,8 @@ import com.jogamp.common.os.Platform;
import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.cache.TempJarCache;
+import com.jogamp.common.util.locks.LockFactory;
+import com.jogamp.common.util.locks.RecursiveThreadGroupLock;
import com.jogamp.nativewindow.NativeWindowVersion;
import com.jogamp.opengl.JoglVersion;
@@ -74,56 +76,80 @@ public class GLProfile {
public static final boolean DEBUG = Debug.debug("GLProfile");
+ static {
+ // Also initializes TempJarCache if shall be used.
+ Platform.initSingleton();
+ }
+
/**
- * Static one time initialization of JOGL.
+ * Static initialization of JOGL.
* <p>
* The parameter <code>firstUIActionOnProcess</code> has an impact on concurrent locking,<br>
* see {@link javax.media.nativewindow.NativeWindowFactory#initSingleton(boolean) NativeWindowFactory.initSingleton(firstUIActionOnProcess)}.
* </p>
* <p>
- * Applications shall call this methods <b>ASAP</b>, before any other UI invocation.<br>
- * You may issue the call in your <code>main class</code> static block, which is the earliest point in your application/applet lifecycle,
- * or within the <code>main function</code>.<br>
- * In case applications are able to initialize JOGL before any other UI action,<br>
- * they shall invoke this method with <code>firstUIActionOnProcess=true</code> and benefit from fast native multithreading support on all platforms if possible.</P>
- * <P>
- * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL may not be able to initialize JOGL
- * before the first UI action.<br>
- * In such case you shall invoke this method with <code>firstUIActionOnProcess=false</code>.<br>
- * On some platforms, notably X11 with AWT usage, JOGL will utilize special locking mechanisms which may slow down your
- * application.</P>
+ * Applications using this method may place it's call before any other UI invocation
+ * in the <code>main class</code>'s static block or within the <code>main function</code>.
+ * In such case, applications may pass <code>firstUIActionOnProcess=true</code> to use native toolkit locking.</P>
* <P>
- * Remark: NEWT is currently not affected by this behavior, ie always uses native multithreading.</P>
+ * RCP Application (Applet's, Webstart, Netbeans, ..) using JOGL are not be able to initialize JOGL
+ * before the first UI action.
+ * In such case you shall pass <code>firstUIActionOnProcess=false</code>.</P>
* <P>
- * However, in case this method is not invoked, hence GLProfile is not initialized explicitly by the user,<br>
- * the first call to {@link #getDefault()}, {@link #get(java.lang.String)}, etc, will initialize with <code>firstUIActionOnProcess=false</code>,<br>
- * hence without the possibility to enable native multithreading.<br>
- * This is not the recommended way, since it may has a performance impact, but it allows you to run code without explicit initialization.</P>
+ * In case this method is not invoked, GLProfile is initialized implicit by
+ * the first call to {@link #getDefault()}, {@link #get(java.lang.String)} passing <code>firstUIActionOnProcess=false</code>.
* <P>
*
* @param firstUIActionOnProcess Should be <code>true</code> if called before the first UI action of the running program,
* otherwise <code>false</code>.
+ *
+ * @deprecated This method shall not need to be called for other reasons than having a defined initialization sequence.
+ * To ensure homogeneous behavior with application not calling this method, you shall pass <code>firstUIActionOnProcess=false</code>.
+ * This method is subject to be removed in future versions of JOGL.
*/
- public static synchronized void initSingleton(final boolean firstUIActionOnProcess) {
- if(!initialized) {
- initialized = true;
- // run the whole static initialization privileged to speed up,
- // since this skips checking further access
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- if(TempJarCache.isInitialized()) {
- String[] atomicNativeJarBaseNames = new String[] { "nativewindow", "jogl", null };
- if( ReflectionUtil.isClassAvailable("com.jogamp.newt.NewtFactory", GLProfile.class.getClassLoader()) ) {
- atomicNativeJarBaseNames[2] = "newt";
- }
- JNILibLoaderBase.addNativeJarLibs(GLProfile.class, "jogl.all", "jogl-all", atomicNativeJarBaseNames);
- }
- initProfilesForDefaultDevices(firstUIActionOnProcess);
- return null;
+ public static void initSingleton(final boolean firstUIActionOnProcess) {
+ initLock.lock();
+ try {
+ if(!initialized) { // volatile: ok
+ initialized = true;
+ if(DEBUG) {
+ System.err.println("GLProfile.initSingleton(firstUIActionOnProcess: "+firstUIActionOnProcess+") - thread "+Thread.currentThread().getName());
+ Thread.dumpStack();
}
- });
+
+ // run the whole static initialization privileged to speed up,
+ // since this skips checking further access
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ Platform.initSingleton();
+
+ if(TempJarCache.isInitialized()) {
+ String[] atomicNativeJarBaseNames = new String[] { "nativewindow", "jogl", null };
+ if( ReflectionUtil.isClassAvailable("com.jogamp.newt.NewtFactory", GLProfile.class.getClassLoader()) ) {
+ atomicNativeJarBaseNames[2] = "newt";
+ }
+ JNILibLoaderBase.addNativeJarLibs(GLProfile.class, "jogl-all", atomicNativeJarBaseNames);
+ }
+ initProfilesForDefaultDevices(firstUIActionOnProcess);
+ return null;
+ }
+ });
+ }
+ } finally {
+ initLock.unlock();
}
}
+
+ /**
+ * Static initialization of JOGL.
+ *
+ * <p>
+ * This method shall not need to be called for other reasons than having a defined initialization sequence.
+ * </p>
+ */
+ public static void initSingleton() {
+ GLProfile.initSingleton(false);
+ }
/**
* Trigger eager initialization of GLProfiles for the given device,
@@ -132,21 +158,50 @@ public class GLProfile {
* @throws GLException if no profile for the given device is available.
*/
public static void initProfiles(AbstractGraphicsDevice device) throws GLException {
- getProfileMap(device);
+ getProfileMap(device, true);
}
+ /**
+ * Shutdown type for {@link GLProfile#shutdown(ShutdownType)}.
+ * <p>
+ * {@link #SHARED_ONLY} For thread based resources only, suitable for eg. {@link java.applet.Applet Applet} restart.<br>
+ * {@link #COMPLETE} Everything.<br>
+ * </p>
+ */
+ public enum ShutdownType {
+ /* Shared thread based resources only, eg. for Applets */
+ SHARED_ONLY,
+ /* Everything */
+ COMPLETE;
+ }
+
/**
* Manual shutdown method, may be called after your last JOGL use
* within the running JVM.<br>
* It releases all temporary created resources, ie issues {@link javax.media.opengl.GLDrawableFactory#shutdown()}.<br>
- * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked here.<br>
- * Invoke <code>shutdown()</code> manually is recommended, due to the unreliable JVM state within the shutdown hook.<br>
+ * The shutdown implementation is called via the JVM shutdown hook, if not manually invoked.<br>
+ * <p>
+ * This method shall not need to be called for other reasons than issuing a proper shutdown of resources.
+ * </p>
+ * @param type the shutdown type, see {@link ShutdownType}.
*/
- public static synchronized void shutdown() {
- if(initialized) {
- initialized = false;
- GLDrawableFactory.shutdown();
- GLContext.shutdown();
+ public static void shutdown(ShutdownType type) {
+ initLock.lock();
+ try {
+ if(initialized) { // volatile: ok
+ initialized = false;
+ if(DEBUG) {
+ System.err.println("GLProfile.shutdown(type: "+type+") - thread "+Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ GLDrawableFactory.shutdown(type);
+ if(ShutdownType.COMPLETE == type) {
+ GLContext.shutdown();
+ }
+ NativeWindowFactory.shutdown();
+ }
+ } finally {
+ initLock.unlock();
}
}
@@ -163,12 +218,13 @@ public class GLProfile {
* @return true if the profile is available for the device, otherwise false.
*/
public static boolean isAvailable(AbstractGraphicsDevice device, String profile) {
- try {
- return null != getProfileMap(device).get(profile);
- } catch (GLException gle) { /* profiles for device n/a */ }
- return false;
+ initSingleton();
+ return isAvailableImpl(getProfileMap(device, false), profile);
}
-
+ private static boolean isAvailableImpl(HashMap<String /*GLProfile_name*/, GLProfile> map, String profile) {
+ return null != map && null != map.get(profile);
+ }
+
/**
* Returns the availability of a profile on the default device.
*
@@ -193,74 +249,71 @@ public class GLProfile {
boolean avail;
StringBuffer sb = new StringBuffer();
- validateInitialization();
-
+ initSingleton();
+
if(null==device) {
device = defaultDevice;
}
-
+ final HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device, false);
+
sb.append("GLAvailability[Native[GL4bc ");
- avail=isAvailable(device, GL4bc);
+ avail=isAvailableImpl(map, GL4bc);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL4 ");
- avail=isAvailable(device, GL4);
+ avail=isAvailableImpl(map, GL4);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 4, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL3bc ");
- avail=isAvailable(device, GL3bc);
+ avail=isAvailableImpl(map, GL3bc);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL3 ");
- avail=isAvailable(device, GL3);
+ avail=isAvailableImpl(map, GL3);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 3, GLContext.CTX_PROFILE_CORE);
}
sb.append(", GL2 ");
- avail=isAvailable(device, GL2);
+ avail=isAvailableImpl(map, GL2);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_COMPAT);
}
sb.append(", GL2ES1 ");
- sb.append(isAvailable(device, GL2ES1));
+ sb.append(isAvailableImpl(map, GL2ES1));
sb.append(", GLES1 ");
- avail=isAvailable(device, GLES1);
+ avail=isAvailableImpl(map, GLES1);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 1, GLContext.CTX_PROFILE_ES);
}
sb.append(", GL2ES2 ");
- sb.append(isAvailable(device, GL2ES2));
+ sb.append(isAvailableImpl(map, GL2ES2));
sb.append(", GLES2 ");
- avail=isAvailable(device, GLES2);
+ avail=isAvailableImpl(map, GLES2);
sb.append(avail);
if(avail) {
glAvailabilityToString(device, sb, 2, GLContext.CTX_PROFILE_ES);
}
sb.append("], Profiles[");
- HashMap<String /*GLProfile_name*/, GLProfile> profileMap = null;
- try {
- profileMap = getProfileMap(device);
- } catch (GLException gle) { /* profiles for device n/a */ }
- if(null != profileMap) {
- for(Iterator<GLProfile> i=profileMap.values().iterator(); i.hasNext(); ) {
+ if(null != map) {
+ for(Iterator<GLProfile> i=map.values().iterator(); i.hasNext(); ) {
sb.append(i.next().toString());
sb.append(", ");
}
@@ -275,7 +328,7 @@ public class GLProfile {
return sb.toString();
}
-
+
/** Uses the default device */
public static String glAvailabilityToString() {
return glAvailabilityToString(null);
@@ -596,7 +649,7 @@ public class GLProfile {
if(null==profile || profile.equals("GL")) {
profile = GL_DEFAULT;
}
- final HashMap<String /*GLProfile_name*/, GLProfile> glpMap = getProfileMap(device);
+ final HashMap<String /*GLProfile_name*/, GLProfile> glpMap = getProfileMap(device, true);
final GLProfile glp = glpMap.get(profile);
if(null == glp) {
throw new GLException("Profile "+profile+" is not available on "+device+", but: "+glpMap.values());
@@ -626,7 +679,7 @@ public class GLProfile {
public static GLProfile get(AbstractGraphicsDevice device, String[] profiles)
throws GLException
{
- HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device);
+ HashMap<String /*GLProfile_name*/, GLProfile> map = getProfileMap(device, true);
for(int i=0; i<profiles.length; i++) {
String profile = profiles[i];
GLProfile glProfile = map.get(profile);
@@ -1137,10 +1190,6 @@ public class GLProfile {
return "GLProfile[" + getName() + "/" + getImplName() + "]";
}
- static {
- Platform.initSingleton();
- }
-
private static /*final*/ boolean isAWTAvailable;
private static /*final*/ boolean hasDesktopGLFactory;
@@ -1155,7 +1204,8 @@ public class GLProfile {
private static /*final*/ AbstractGraphicsDevice defaultDesktopDevice;
private static /*final*/ AbstractGraphicsDevice defaultEGLDevice;
- static boolean initialized = false;
+ private static volatile boolean initialized = false;
+ private static RecursiveThreadGroupLock initLock = LockFactory.createRecursiveThreadGroupLock();
/**
* Tries the profiles implementation and native libraries.
@@ -1191,7 +1241,7 @@ public class GLProfile {
// - Instantiate GLDrawableFactory incl its shared dummy drawable/context,
// which will register at GLContext ..
//
- GLDrawableFactory.initialize();
+ GLDrawableFactory.initSingleton();
Throwable t=null;
// if successfull it has a shared dummy drawable and context created
@@ -1295,19 +1345,24 @@ public class GLProfile {
* @param device the device for which profiles shall be initialized
* @return true if any profile for the device exists, otherwise false
*/
- private static synchronized boolean initProfilesForDevice(AbstractGraphicsDevice device) {
+ private static boolean initProfilesForDevice(AbstractGraphicsDevice device) {
if(null == device) {
return false;
}
- GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device);
- factory.enterThreadCriticalZone();
+ initLock.lock();
try {
- return initProfilesForDeviceCritical(device);
+ GLDrawableFactory factory = GLDrawableFactory.getFactoryImpl(device);
+ factory.enterThreadCriticalZone();
+ try {
+ return initProfilesForDeviceCritical(device);
+ } finally {
+ factory.leaveThreadCriticalZone();
+ }
} finally {
- factory.leaveThreadCriticalZone();
+ initLock.unlock();
}
}
- private static synchronized boolean initProfilesForDeviceCritical(AbstractGraphicsDevice device) {
+ private static boolean initProfilesForDeviceCritical(AbstractGraphicsDevice device) {
boolean isSet = GLContext.getAvailableGLVersionsSet(device);
if(DEBUG) {
@@ -1331,11 +1386,21 @@ public class GLProfile {
// Triggers eager initialization of share context in GLDrawableFactory for the device,
// hence querying all available GLProfiles
- boolean desktopSharedCtxAvail = desktopFactory.getWasSharedContextCreated(device);
+ final Thread sharedResourceThread = desktopFactory.getSharedResourceThread();
+ if(null != sharedResourceThread) {
+ initLock.addOwner(sharedResourceThread);
+ }
+ boolean desktopSharedCtxAvail = desktopFactory.createSharedResource(device);
+ if(null != sharedResourceThread) {
+ initLock.removeOwner(sharedResourceThread);
+ }
+ if(!desktopSharedCtxAvail) {
+ hasDesktopGLFactory = false;
+ }
if (DEBUG) {
System.err.println("GLProfile.initProfilesForDevice: "+device+": desktop Shared Ctx "+desktopSharedCtxAvail);
}
- if( null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
+ if( hasDesktopGLFactory && null == GLContext.getAvailableGLVersion(device, 2, GLContext.CTX_PROFILE_COMPAT) ) {
// nobody yet set the available desktop versions, see {@link GLContextImpl#makeCurrent},
// so we have to add the usual suspect
GLContext.mapAvailableGLVersion(device,
@@ -1350,7 +1415,22 @@ public class GLProfile {
// Triggers eager initialization of share context in GLDrawableFactory for the device,
// hence querying all available GLProfiles
- boolean eglSharedCtxAvail = eglFactory.getWasSharedContextCreated(device);
+ final Thread sharedResourceThread = eglFactory.getSharedResourceThread();
+ if(null != sharedResourceThread) {
+ initLock.addOwner(sharedResourceThread);
+ }
+ boolean eglSharedCtxAvail = eglFactory.createSharedResource(device);
+ if(null != sharedResourceThread) {
+ initLock.removeOwner(sharedResourceThread);
+ }
+ if(!eglSharedCtxAvail) {
+ // Remark: On Windows there is a libEGL.dll delivered w/ Chrome 15.0.874.121m and Firefox 8.0.1
+ // but it seems even EGL.eglInitialize(eglDisplay, null, null)
+ // fails in some scenarios (eg VirtualBox 4.1.6) w/ EGL error 0x3001 (EGL_NOT_INITIALIZED).
+ hasEGLFactory = false;
+ hasGLES2Impl = false;
+ hasGLES1Impl = false;
+ }
if (DEBUG) {
System.err.println("GLProfile.initProfilesForDevice: "+device+": egl Shared Ctx "+eglSharedCtxAvail);
}
@@ -1423,30 +1503,20 @@ public class GLProfile {
}
public static AbstractGraphicsDevice getDefaultDevice() {
- validateInitialization();
+ initSingleton();
return defaultDevice;
}
public static AbstractGraphicsDevice getDefaultDesktopDevice() {
- validateInitialization();
+ initSingleton();
return defaultDesktopDevice;
}
public static AbstractGraphicsDevice getDefaultEGLDevice() {
- validateInitialization();
+ initSingleton();
return defaultEGLDevice;
}
- private static void validateInitialization() {
- if(!initialized) {
- synchronized(GLProfile.class) {
- if(!initialized) {
- initSingleton(false);
- }
- }
- }
- }
-
private static String array2String(String[] list) {
StringBuffer msg = new StringBuffer();
msg.append("[");
@@ -1608,29 +1678,38 @@ public class GLProfile {
* - initialization<br<
*
* @param device the key 'device -> GLProfiles-Map'
+ * @param throwExceptionOnZeroProfile true if <code>GLException</code> shall be thrown in case of no mapped profile, otherwise false.
* @return the GLProfile HashMap if exists, otherwise null
* @throws GLException if no profile for the given device is available.
*/
- private static HashMap<String /*GLProfile_name*/, GLProfile> getProfileMap(AbstractGraphicsDevice device) throws GLException {
- validateInitialization();
+ private static HashMap<String /*GLProfile_name*/, GLProfile> getProfileMap(AbstractGraphicsDevice device, boolean throwExceptionOnZeroProfile)
+ throws GLException
+ {
+ initSingleton();
+
if(null==device) {
device = defaultDevice;
}
String deviceKey = device.getUniqueID();
HashMap<String /*GLProfile_name*/, GLProfile> map = deviceConn2ProfileMap.get(deviceKey);
- if( null == map ) {
- if( !initProfilesForDevice(device) ) {
+ if( null != map ) {
+ return map;
+ }
+ if( !initProfilesForDevice(device) ) {
+ if( throwExceptionOnZeroProfile ) {
throw new GLException("No Profile available for "+device);
+ } else {
+ return null;
}
- if( null == deviceConn2ProfileMap.get(deviceKey) ) {
- throw new InternalError("initProfilesForDevice(..) didn't issue setProfileMap(..) on "+device);
- }
+ }
+ map = deviceConn2ProfileMap.get(deviceKey);
+ if( null == map && throwExceptionOnZeroProfile ) {
+ throw new InternalError("initProfilesForDevice(..) didn't setProfileMap(..) for "+device);
}
return map;
}
private static void setProfileMap(AbstractGraphicsDevice device, HashMap<String /*GLProfile_name*/, GLProfile> mappedProfiles) {
- validateInitialization();
synchronized ( deviceConn2ProfileMap ) {
deviceConn2ProfileMap.put(device.getUniqueID(), mappedProfiles);
}
diff --git a/src/jogl/classes/javax/media/opengl/GLUniformData.java b/src/jogl/classes/javax/media/opengl/GLUniformData.java
index 5c9388be2..475ff4546 100644
--- a/src/jogl/classes/javax/media/opengl/GLUniformData.java
+++ b/src/jogl/classes/javax/media/opengl/GLUniformData.java
@@ -107,10 +107,10 @@ public class GLUniformData {
if(data instanceof Buffer) {
final int sz = rows*columns;
final Buffer buffer = (Buffer)data;
- if(buffer.limit()<sz || 0!=buffer.limit()%sz) {
- throw new GLException("data buffer size invalid: new buffer limit: "+buffer.limit()+"\n\t"+this);
+ if(buffer.remaining()<sz || 0!=buffer.remaining()%sz) {
+ throw new GLException("remaining data buffer size invalid: buffer: "+buffer.toString()+"\n\t"+this);
}
- this.count=buffer.limit()/(rows*columns);
+ this.count=buffer.remaining()/(rows*columns);
} else {
if(isMatrix) {
throw new GLException("Atom type not allowed for matrix : "+this);
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
index ada9f5222..cd341593e 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLCanvas.java
@@ -59,8 +59,9 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
-import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.OffscreenLayerOption;
+import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.GraphicsConfigurationFactory;
@@ -92,6 +93,8 @@ import com.jogamp.opengl.JoglVersion;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
+
+import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableHelper;
@@ -136,7 +139,7 @@ import jogamp.opengl.ThreadingImpl;
*/
@SuppressWarnings("serial")
-public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol {
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol, OffscreenLayerOption {
private static final boolean DEBUG;
@@ -156,6 +159,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private GLContext shareWith;
private int additionalCtxCreationFlags = 0;
private GraphicsDevice device;
+ private boolean shallUseOffscreenLayer = false;
private AWTWindowClosingProtocol awtWindowClosingProtocol =
new AWTWindowClosingProtocol(this, new Runnable() {
@@ -250,6 +254,22 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
this.device = device;
}
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ if(null != drawable) {
+ return ((JAWTWindow)drawable.getNativeSurface()).isOffscreenLayerSurfaceEnabled();
+ }
+ return false;
+ }
+
+
/**
* Overridden to choose a GraphicsConfiguration on a parent container's
* GraphicsDevice because both devices
@@ -279,7 +299,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
* otherwise it is from an ancestor component that this Canvas is being
* added to, and we go into this block.
*/
- GraphicsConfiguration chosen = awtConfig.getGraphicsConfiguration();
+ GraphicsConfiguration chosen = awtConfig.getAWTGraphicsConfiguration();
if (gc != null && chosen != null && !chosen.equals(gc)) {
/*
@@ -308,7 +328,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
AWTGraphicsConfiguration config = chooseGraphicsConfiguration( (GLCapabilitiesImmutable)awtConfig.getChosenCapabilities(),
(GLCapabilitiesImmutable)awtConfig.getRequestedCapabilities(),
chooser, gc.getDevice());
- final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null;
+ final GraphicsConfiguration compatible = (null!=config)?config.getAWTGraphicsConfiguration():null;
boolean equalCaps = config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities());
if(DEBUG) {
Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
@@ -406,15 +426,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
private void dispose(boolean regenerate) {
drawableSync.lock();
try {
+ final GLAnimatorControl animator = getAnimator();
if(DEBUG) {
- Exception ex1 = new Exception("Info: dispose("+regenerate+") - start, hasContext " +
- (null!=context) + ", hasDrawable " + (null!=drawable));
+ Exception ex1 = new Exception("Info: dispose("+regenerate+") - START, hasContext " +
+ (null!=context) + ", hasDrawable " + (null!=drawable)+", "+animator);
ex1.printStackTrace();
}
if(null!=context) {
boolean animatorPaused = false;
- GLAnimatorControl animator = getAnimator();
if(null!=animator) {
// can't remove us from animator for recreational addNotify()
animatorPaused = animator.pause();
@@ -422,37 +442,38 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
disposeRegenerate=regenerate;
- if (Threading.isSingleThreaded() &&
- !Threading.isOpenGLThread()) {
- // Workaround for termination issues with applets --
- // sun.applet.AppletPanel should probably be performing the
- // remove() call on the EDT rather than on its own thread
- // Hint: User should run remove from EDT.
- if (ThreadingImpl.isAWTMode() &&
- Thread.holdsLock(getTreeLock())) {
- // The user really should not be invoking remove() from this
- // thread -- but since he/she is, we can not go over to the
- // EDT at this point. Try to destroy the context from here.
- if(context.isCreated()) {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ if(context.isCreated()) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ // Hint: User should run remove from EDT.
+ if (ThreadingImpl.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction);
+ } else {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else {
+ drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction);
}
- } else if(context.isCreated()) {
- Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
- }
- } else if(context.isCreated()) {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
}
if(animatorPaused) {
animator.resume();
}
}
+
if(!regenerate) {
disposeAbstractGraphicsDevice();
}
if(DEBUG) {
- System.err.println("dispose("+regenerate+") - stop");
+ System.err.println("dispose("+regenerate+") - END, "+animator);
}
} finally {
drawableSync.unlock();
@@ -532,15 +553,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
throw new GLException("Error: NULL AWTGraphicsConfiguration");
}
- if (!Beans.isDesignTime()) {
- // no lock required, since this resource ain't available yet
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
- .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setSynchronized(true);
- context.setContextCreationFlags(additionalCtxCreationFlags);
- }
-
// before native peer is valid: X11
disableBackgroundErase();
@@ -550,6 +562,10 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// after native peer is valid: Windows
disableBackgroundErase();
+ if (!Beans.isDesignTime()) {
+ createDrawableAndContext();
+ }
+
// init drawable by paint/display makes the init sequence more equal
// for all launch flavors (applet/javaws/..)
// validateGLDrawable();
@@ -562,6 +578,21 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
+ private void createDrawableAndContext() {
+ // no lock required, since this resource ain't available yet
+ final JAWTWindow jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig);
+ jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+ jawtWindow.lockSurface();
+ try {
+ drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile()).createGLDrawable(jawtWindow);
+ context = (GLContextImpl) drawable.createContext(shareWith);
+ context.setSynchronized(true);
+ context.setContextCreationFlags(additionalCtxCreationFlags);
+ } finally {
+ jawtWindow.unlockSurface();
+ }
+ }
+
private boolean validateGLDrawable() {
boolean realized = false;
if (!Beans.isDesignTime()) {
@@ -636,7 +667,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
@Override
public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
- sendReshape = true;
+ if(null != drawable && drawable.isRealized() && !drawable.getChosenGLCapabilities().isOnscreen()) {
+ dispose(true);
+ } else {
+ sendReshape = true;
+ }
}
/** <B>Overrides:</B>
@@ -800,63 +835,60 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
}
- class DisposeAction implements Runnable {
+ class PostDisposeAction implements Runnable {
public void run() {
- drawableHelper.dispose(GLCanvas.this);
-
- if(null!=context) {
- context.makeCurrent(); // implicit wait for lock ..
- context.destroy();
- context=null;
- }
-
+ context=null;
if(null!=drawable) {
+ final JAWTWindow jawtWindow = (JAWTWindow)drawable.getNativeSurface();
drawable.setRealized(false);
drawable=null;
+ if(null!=jawtWindow) {
+ jawtWindow.destroy();
+ }
}
-
+
if(disposeRegenerate) {
- // recreate GLDrawable to reflect it's new graphics configuration
- drawable = GLDrawableFactory.getFactory(capsReqUser.getGLProfile())
- .createGLDrawable(NativeWindowFactory.getNativeWindow(GLCanvas.this, awtConfig));
+ // Similar process as in addNotify()!
+
+ // Recreate GLDrawable/GLContext to reflect it's new graphics configuration
+ createDrawableAndContext();
+
if(DEBUG) {
System.err.println("GLCanvas.dispose(true): new drawable: "+drawable);
}
- drawable.setRealized(true);
- context = (GLContextImpl) drawable.createContext(shareWith);
- context.setSynchronized(true);
- sendReshape=true; // ensure a reshape is being send ..
+ validateGLDrawable(); // immediate attempt to recreate the drawable
}
}
}
private boolean disposeRegenerate;
- private DisposeAction disposeAction = new DisposeAction();
+ private PostDisposeAction postDisposeAction = new PostDisposeAction();
private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
new DisposeOnEventDispatchThreadAction();
class DisposeOnEventDispatchThreadAction implements Runnable {
public void run() {
- drawableHelper.invokeGL(drawable, context, disposeAction, null);
+ drawableHelper.disposeGL(GLCanvas.this, drawable, context, postDisposeAction);
}
}
class DisposeAbstractGraphicsDeviceAction implements Runnable {
public void run() {
- AbstractGraphicsConfiguration aconfig = (null!=awtConfig) ? awtConfig.getNativeGraphicsConfiguration() : null;
- AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
- AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null;
- if(null!=adevice) {
- String adeviceMsg=null;
+ if(null != awtConfig) {
+ final AbstractGraphicsConfiguration aconfig = awtConfig.getNativeGraphicsConfiguration();
+ final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ final String adeviceMsg;
if(DEBUG) {
adeviceMsg = adevice.toString();
+ } else {
+ adeviceMsg = null;
}
boolean closed = adevice.close();
if(DEBUG) {
System.err.println(Thread.currentThread().getName() + " - GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
}
+ awtConfig=null;
}
- awtConfig=null;
}
}
private DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction();
@@ -1001,7 +1033,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
return null;
}
- final AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final AbstractGraphicsScreen aScreen = null != device ?
+ AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT):
+ AWTGraphicsScreen.createDefault();
AWTGraphicsConfiguration config = null;
if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
@@ -1045,7 +1079,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
// System.err.println(NativeWindowVersion.getInstance());
System.err.println(JoglVersion.getInstance());
- GLProfile.initSingleton(false);
GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
List<GLCapabilitiesImmutable> availCaps = factory.getAvailableCapabilities(null);
for(int i=0; i<availCaps.size(); i++) {
@@ -1053,9 +1086,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
}
GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) );
- Frame frame = new Frame("JOGL AWT Test");
+ final Frame frame = new Frame("JOGL AWT Test");
- GLCanvas glCanvas = new GLCanvas(caps);
+ final GLCanvas glCanvas = new GLCanvas(caps);
frame.add(glCanvas);
frame.setSize(128, 128);
@@ -1064,24 +1097,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
GL gl = drawable.getGL();
System.err.println(JoglVersion.getGLInfo(gl, null));
}
-
- public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
- }
-
- public void display(GLAutoDrawable drawable) {
- }
-
- public void dispose(GLAutoDrawable drawable) {
- }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) { }
+ public void display(GLAutoDrawable drawable) { }
+ public void dispose(GLAutoDrawable drawable) { }
});
- final Frame _frame = frame;
- final GLCanvas _glCanvas = glCanvas;
-
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- _frame.setVisible(true);
+ frame.setVisible(true);
}});
} catch (Throwable t) {
t.printStackTrace();
@@ -1090,9 +1114,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosing
try {
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
- _frame.setVisible(false);
- _frame.remove(_glCanvas);
- _frame.dispose();
+ frame.dispose();
}});
} catch (Throwable t) {
t.printStackTrace();
diff --git a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
index 92be62b4d..7a87882ca 100644
--- a/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
+++ b/src/jogl/classes/javax/media/opengl/awt/GLJPanel.java
@@ -82,7 +82,10 @@ import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
import javax.media.opengl.GLRunnable;
import javax.media.opengl.Threading;
+
import com.jogamp.opengl.util.FBObject;
+import com.jogamp.opengl.util.GLBuffers;
+
import jogamp.opengl.Debug;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableFactoryImpl;
@@ -123,9 +126,9 @@ import jogamp.opengl.awt.Java2DGLContext;
* </P>
*/
+@SuppressWarnings("serial")
public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosingProtocol {
private static final boolean DEBUG = Debug.debug("GLJPanel");
- private static final boolean VERBOSE = Debug.verbose();
private GLDrawableHelper drawableHelper = new GLDrawableHelper();
private volatile boolean isInitialized;
@@ -268,70 +271,51 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
- protected void dispose(boolean regenerate) {
+ protected void dispose() {
if(DEBUG) {
- Exception ex1 = new Exception("Info: dispose("+regenerate+") - start");
- ex1.printStackTrace();
+ System.err.println("Info: dispose() - start - "+Thread.currentThread().getName());
+ Thread.dumpStack();
}
- if (backend != null) {
+ if (backend != null && backend.getContext() != null) {
boolean animatorPaused = false;
GLAnimatorControl animator = getAnimator();
if(null!=animator) {
- if(regenerate) {
- animatorPaused = animator.pause();
- }
- }
-
- disposeRegenerate=regenerate;
- disposeContext=backend.getContext();
- disposeDrawable=backend.getDrawable();
-
- if (Threading.isSingleThreaded() &&
- !Threading.isOpenGLThread()) {
- // Workaround for termination issues with applets --
- // sun.applet.AppletPanel should probably be performing the
- // remove() call on the EDT rather than on its own thread
- if (ThreadingImpl.isAWTMode() &&
- Thread.holdsLock(getTreeLock())) {
- // The user really should not be invoking remove() from this
- // thread -- but since he/she is, we can not go over to the
- // EDT at this point. Try to destroy the context from here.
- if(disposeContext.isCreated()) {
- drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
- }
- } else if(disposeContext.isCreated()) {
- Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
- }
- } else if(disposeContext.isCreated()) {
- drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ animatorPaused = animator.pause();
}
- if(!regenerate) {
- AbstractGraphicsDevice adevice = disposeDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
- String adeviceMsg=null;
- if(DEBUG) {
- adeviceMsg = adevice.toString();
- }
- // boolean closed = adevice.close();
- boolean closed = false;
- if (DEBUG) {
- System.err.println("GLJPanel.dispose(false): closed GraphicsDevice: " + adeviceMsg + ", result: " + closed);
+ if(backend.getContext().isCreated()) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ // Workaround for termination issues with applets --
+ // sun.applet.AppletPanel should probably be performing the
+ // remove() call on the EDT rather than on its own thread
+ if (ThreadingImpl.isAWTMode() &&
+ Thread.holdsLock(getTreeLock())) {
+ // The user really should not be invoking remove() from this
+ // thread -- but since he/she is, we can not go over to the
+ // EDT at this point. Try to destroy the context from here.
+ drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction);
+ } else {
+ Threading.invokeOnOpenGLThread(disposeOnEventDispatchThreadAction);
+ }
+ } else {
+ drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction);
}
}
-
- backend.setContext(disposeContext);
- if(null==disposeContext) {
- isInitialized = false;
+ if(null != backend) {
+ // not yet destroyed due to backend.isUsingOwnThreadManagment() == true
+ backend.destroy();
+ isInitialized = false;
}
if(animatorPaused) {
animator.resume();
- }
+ }
}
-
+
if(DEBUG) {
- System.err.println("dispose("+regenerate+") - stop");
+ System.err.println("dispose() - stop");
}
}
@@ -347,8 +331,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
super.paintComponent() in their paintComponent() method in order
to function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>paintComponent</CODE> in class <CODE>javax.swing.JComponent</CODE></DD></DL> */
+ @Override
protected void paintComponent(final Graphics g) {
if (Beans.isDesignTime()) {
// Make GLJPanel behave better in NetBeans GUI builder
@@ -396,8 +380,8 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
super.addNotify() in their addNotify() method in order to
function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
public void addNotify() {
super.addNotify();
if (DEBUG) {
@@ -410,26 +394,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
super.removeNotify() in their removeNotify() method in order to
function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>removeNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+ @Override
public void removeNotify() {
- if(DEBUG) {
- Exception ex1 = new Exception("Info: removeNotify - start");
- ex1.printStackTrace();
- }
-
awtWindowClosingProtocol.removeClosingListener();
- dispose(false);
- if (backend != null) {
- backend.destroy();
- backend = null;
- }
- isInitialized = false;
+ dispose();
super.removeNotify();
- if(DEBUG) {
- System.err.println("Info: removeNotify - end");
- }
}
/** Overridden to cause {@link GLDrawableHelper#reshape} to be
@@ -437,9 +408,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
which override this method must call super.reshape() in
their reshape() method in order to function properly. <P>
- <B>Overrides:</B>
<DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
- public void reshape(int x, int y, int width, int height) {
+ @SuppressWarnings("deprecation")
+ @Override
+public void reshape(int x, int y, int width, int height) {
super.reshape(x, y, width, height);
// reshapeX = x;
@@ -449,6 +421,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
handleReshape = true;
}
+ @Override
public void setOpaque(boolean opaque) {
if (backend != null) {
backend.setOpaque(opaque);
@@ -481,7 +454,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public GLContext createContext(GLContext shareWith) {
- return backend.createContext(shareWith);
+ return (null != backend) ? backend.createContext(shareWith) : null;
}
public void setRealized(boolean realized) {
@@ -690,7 +663,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return;
}
if (sendReshape) {
- if (DEBUG||VERBOSE) {
+ if (DEBUG) {
System.err.println("display: reshape(" + viewportX + "," + viewportY + " " + panelWidth + "x" + panelHeight + ")");
}
drawableHelper.reshape(GLJPanel.this, viewportX, viewportY, panelWidth, panelHeight);
@@ -713,42 +686,26 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
return "AWT-GLJPanel[ "+((null!=backend)?backend.getDrawable().getClass().getName():"null-drawable")+"]";
}
- private boolean disposeRegenerate;
- private GLContext disposeContext;
- private GLDrawable disposeDrawable;
- private DisposeAction disposeAction = new DisposeAction();
-
- class DisposeAction implements Runnable {
+ class PostDisposeAction implements Runnable {
public void run() {
- updater.dispose(GLJPanel.this);
-
- if (null != disposeContext) {
- disposeContext.destroy();
- disposeContext = null;
- }
- if (null != disposeDrawable) {
- disposeDrawable.setRealized(false);
- }
- if (null != disposeDrawable) {
- if (disposeRegenerate) {
- disposeDrawable.setRealized(true);
- disposeContext = (GLContextImpl) disposeDrawable.createContext(shareWith);
- disposeContext.setSynchronized(true);
- }
+ if (backend != null && !backend.isUsingOwnThreadManagment()) {
+ backend.destroy();
+ backend = null;
+ isInitialized = false;
}
}
}
+ private PostDisposeAction postDisposeAction = new PostDisposeAction();
private DisposeOnEventDispatchThreadAction disposeOnEventDispatchThreadAction =
new DisposeOnEventDispatchThreadAction();
class DisposeOnEventDispatchThreadAction implements Runnable {
public void run() {
- drawableHelper.invokeGL(disposeDrawable, disposeContext, disposeAction, null);
+ drawableHelper.disposeGL(GLJPanel.this, backend.getDrawable(), backend.getContext(), postDisposeAction);
}
}
-
-
+
class InitAction implements Runnable {
public void run() {
updater.init(GLJPanel.this);
@@ -776,17 +733,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
if (number == 0) {
return 2;
}
-
- if (((number-1) & number) == 0) {
- //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
- return number;
- }
- int power = 0;
- while (number > 0) {
- number = number>>1;
- power++;
- }
- return (1<<power);
+ return GLBuffers.getNextPowerOf2(number);
}
private int getGLInteger(GL gl, int which) {
@@ -803,6 +750,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// software / pixmap rendering, pbuffer-based acceleration, Java 2D
// / JOGL bridge
static interface Backend {
+ // Create, Destroy, ..
+ public boolean isUsingOwnThreadManagment();
+
// Called each time the backend needs to initialize itself
public void initialize();
@@ -862,7 +812,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
protected int readBackWidthInPixels;
protected int readBackHeightInPixels;
- private int awtFormat;
private int glFormat;
private int glType;
@@ -1031,7 +980,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private GLDrawableImpl offscreenDrawable;
private GLContextImpl offscreenContext;
+ public boolean isUsingOwnThreadManagment() { return false; }
+
public void initialize() {
+ if(DEBUG) {
+ System.err.println("SoftwareBackend: initialize() - "+Thread.currentThread().getName());
+ }
// Fall-through path: create an offscreen context instead
offscreenDrawable = (GLDrawableImpl) factory.createOffscreenDrawable(
null /* default platform device */,
@@ -1039,6 +993,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
chooser,
Math.max(1, panelWidth),
Math.max(1, panelHeight));
+ offscreenDrawable.setRealized(true);
offscreenContext = (GLContextImpl) offscreenDrawable.createContext(shareWith);
offscreenContext.setSynchronized(true);
offscreenContext.setContextCreationFlags(additionalCtxCreationFlags);
@@ -1047,18 +1002,25 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public void destroy() {
+ if(DEBUG) {
+ System.err.println("SoftwareBackend: destroy() - offscreenContext: "+(null!=offscreenContext)+" - offscreenDrawable: "+(null!=offscreenDrawable)+" - "+Thread.currentThread().getName());
+ }
if (offscreenContext != null) {
offscreenContext.destroy();
offscreenContext = null;
}
if (offscreenDrawable != null) {
+ final AbstractGraphicsDevice adevice = offscreenDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
offscreenDrawable.destroy();
offscreenDrawable = null;
+ if(null != adevice) {
+ adevice.close();
+ }
}
}
public GLContext createContext(GLContext shareWith) {
- return offscreenDrawable.createContext(shareWith);
+ return (null != offscreenDrawable) ? offscreenDrawable.createContext(shareWith) : null;
}
public void setContext(GLContext ctx) {
@@ -1117,10 +1079,15 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private int pbufferWidth = 256;
private int pbufferHeight = 256;
+ public boolean isUsingOwnThreadManagment() { return false; }
+
public void initialize() {
if (pbuffer != null) {
throw new InternalError("Creating pbuffer twice without destroying it (memory leak / correctness bug)");
}
+ if(DEBUG) {
+ System.err.println("PbufferBackend: initialize() - "+Thread.currentThread().getName());
+ }
try {
pbuffer = factory.createGLPbuffer(null /* default platform device */,
offscreenCaps,
@@ -1144,6 +1111,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public void destroy() {
+ if(DEBUG) {
+ System.err.println("PbufferBackend: destroy() - pbuffer: "+(null!=pbuffer)+" - "+Thread.currentThread().getName());
+ }
if (pbuffer != null) {
pbuffer.destroy();
pbuffer = null;
@@ -1151,7 +1121,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public GLContext createContext(GLContext shareWith) {
- return pbuffer.createContext(shareWith);
+ return (null != pbuffer) ? pbuffer.createContext(shareWith) : null;
}
public void setContext(GLContext ctx) {
@@ -1265,7 +1235,6 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
private Object j2dSurface;
// Graphics object being used during Java2D update action
// (absolutely essential to cache this)
- private Graphics cached2DGraphics;
// No-op context representing the Java2D OpenGL context
private GLContext j2dContext;
// Context associated with no-op drawable representing the JOGL
@@ -1308,7 +1277,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// comment related to Issue 274 below
private GraphicsConfiguration workaroundConfig;
+ public boolean isUsingOwnThreadManagment() { return true; }
+
public void initialize() {
+ if(DEBUG) {
+ System.err.println("J2DOGL: initialize() - "+Thread.currentThread().getName());
+ }
// No-op in this implementation; everything is done lazily
isInitialized = true;
}
@@ -1316,6 +1290,9 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
public void destroy() {
Java2D.invokeWithOGLContextCurrent(null, new Runnable() {
public void run() {
+ if(DEBUG) {
+ System.err.println("J2DOGL: destroy() - joglContext: "+(null!=joglContext)+" - joglDrawable: "+(null!=joglDrawable)+" - "+Thread.currentThread().getName());
+ }
if (joglContext != null) {
joglContext.destroy();
joglContext = null;
@@ -1334,9 +1311,10 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
public GLContext createContext(GLContext shareWith) {
- // FIXME: should implement this, but it was not properly
- // implemented before the refactoring anyway
- throw new GLException("Not yet implemented");
+ if(null != shareWith) {
+ throw new GLException("J2DOGLBackend cannot create context w/ additional shared context, since it already needs to share the context w/ J2D.");
+ }
+ return (null != joglDrawable && null != j2dContext) ? joglDrawable.createContext(j2dContext) : null;
}
public void setContext(GLContext ctx) {
@@ -1372,12 +1350,12 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
Rectangle r = Java2D.getOGLScissorBox(g);
if (r == null) {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("Java2D.getOGLScissorBox() returned null");
}
return false;
}
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: gl.glScissor(" + r.x + ", " + r.y + ", " + r.width + ", " + r.height + ")");
}
@@ -1418,14 +1396,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
// Need to do workarounds
fbObjectWorkarounds = true;
createNewDepthBuffer = true;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: ERR GL_FRAMEBUFFER_BINDING: Discovered Invalid J2D FBO("+frameBuffer[0]+"): "+FBObject.getStatusString(status) +
", frame_buffer_object workarounds to be necessary");
}
} else {
// Don't need the frameBufferTexture temporary any more
frameBufferTexture = null;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: OK GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]);
}
}
@@ -1472,7 +1450,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
fboTextureTarget,
frameBufferTexture[0],
0);
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: frameBufferDepthBuffer: " + frameBufferDepthBuffer[0]);
}
gl.glFramebufferRenderbuffer(GL.GL_FRAMEBUFFER,
@@ -1489,7 +1467,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
} else {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: Setting up drawBuffer " + drawBuffer[0] +
" and readBuffer " + readBuffer[0]);
}
@@ -1547,14 +1525,14 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
Java2D.invokeWithOGLContextCurrent(g, new Runnable() {
public void run() {
- if (DEBUG && VERBOSE) {
- System.err.println("-- In invokeWithOGLContextCurrent");
+ if (DEBUG) {
+ System.err.println("-- In invokeWithOGLContextCurrent - "+Thread.currentThread().getName());
}
// Create no-op context representing Java2D context
if (j2dContext == null) {
j2dContext = factory.createExternalGLContext();
- if (DEBUG||VERBOSE) {
+ if (DEBUG) {
System.err.println("-- Created External Context: "+j2dContext);
}
if (DEBUG) {
@@ -1595,15 +1573,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
backend = null;
oglPipelineEnabled = false;
handleReshape = true;
- j2dContext.release();
j2dContext.destroy();
j2dContext = null;
return;
}
- j2dContext.release();
+ } else {
+ j2dContext.makeCurrent();
}
-
- j2dContext.makeCurrent();
try {
captureJ2DState(j2dContext.getGL(), g);
Object curSurface = Java2D.getOGLSurfaceIdentifier(g);
@@ -1614,13 +1590,13 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
joglContext = null;
joglDrawable = null;
sendReshape = true;
- if (DEBUG||VERBOSE) {
+ if (DEBUG) {
System.err.println("Sending reshape because surface changed");
System.err.println("New surface = " + curSurface);
}
}
j2dSurface = curSurface;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.print("-- Surface type: ");
int surfaceType = Java2D.getOGLSurfaceType(g);
if (surfaceType == Java2D.UNDEFINED) {
@@ -1641,22 +1617,20 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
}
}
if (joglContext == null) {
- AbstractGraphicsDevice device = j2dContext.getGLDrawable().getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ AbstractGraphicsDevice device = j2dContext.getGLDrawable().getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
if (factory.canCreateExternalGLDrawable(device)) {
joglDrawable = factory.createExternalGLDrawable();
- // FIXME: Need to share with j2d context, due to FBO resource ..
- // - ORIG: joglContext = joglDrawable.createContext(shareWith);
joglContext = joglDrawable.createContext(j2dContext);
- if (DEBUG||VERBOSE) {
+ joglContext.setSynchronized(true);
+ if (DEBUG) {
System.err.println("-- Created External Drawable: "+joglDrawable);
System.err.println("-- Created Context: "+joglContext);
}
} else if (factory.canCreateContextOnJava2DSurface(device)) {
// Mac OS X code path
- // FIXME: Need to share with j2d context, due to FBO resource ..
- // - ORIG: joglContext = factory.createContextOnJava2DSurface(g, shareWith);
joglContext = factory.createContextOnJava2DSurface(g, j2dContext);
- if (DEBUG||VERBOSE) {
+ joglContext.setSynchronized(true);
+ if (DEBUG) {
System.err.println("-- Created Context: "+joglContext);
}
}
@@ -1694,7 +1668,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
checkedForFBObjectWorkarounds=true;
fbObjectWorkarounds = true;
createNewDepthBuffer = true;
- if (DEBUG || VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: Fetched ERR GL_FRAMEBUFFER_BINDING: "+frameBuffer[0]+" - NOT A FBO"+
", frame_buffer_object workarounds to be necessary");
}
@@ -1713,7 +1687,7 @@ public class GLJPanel extends JPanel implements AWTGLAutoDrawable, WindowClosing
GL.GL_COLOR_ATTACHMENT0,
GL.GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
frameBufferTexture, 0);
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("GLJPanel: FBO COLOR_ATTACHMENT0: " + frameBufferTexture[0]);
}
}
diff --git a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
index 2fa708404..bc9a93042 100644
--- a/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
+++ b/src/jogl/classes/jogamp/graph/curve/text/GlyphString.java
@@ -79,7 +79,7 @@ public class GlyphString {
* @param shape is not null, add all {@link GlyphShape}'s {@link Outline} to this instance.
* @param vertexFactory vertex impl factory {@link Factory}
* @param font the target {@link Font}
- * @param size font size
+ * @param fontSize font size
* @param str string text
* @return the created {@link GlyphString} instance
*/
diff --git a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
index 2d2d1c536..ff49303ca 100644
--- a/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
+++ b/src/jogl/classes/jogamp/opengl/DesktopGLDynamicLookupHelper.java
@@ -42,7 +42,7 @@ public class DesktopGLDynamicLookupHelper extends GLDynamicLookupHelper {
public synchronized boolean loadGLULibrary() {
/** hacky code .. where all platform GLU libs are tried ..*/
if(null==gluLib) {
- List/*<String>*/ gluLibNames = new ArrayList();
+ List<String> gluLibNames = new ArrayList<String>();
gluLibNames.add("/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"); // osx
gluLibNames.add("libGLU.so"); // unix
gluLibNames.add("GLU32"); // windows
diff --git a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
index 96d62fbb3..27569d210 100644
--- a/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
+++ b/src/jogl/classes/jogamp/opengl/FPSCounterImpl.java
@@ -28,6 +28,8 @@
package jogamp.opengl;
import java.io.PrintStream;
+import java.util.concurrent.TimeUnit;
+
import javax.media.opengl.FPSCounter;
/**
@@ -55,7 +57,7 @@ public class FPSCounterImpl implements FPSCounter {
public final synchronized void tickFPS() {
fpsTotalFrames++;
if(fpsUpdateFramesInterval>0 && fpsTotalFrames%fpsUpdateFramesInterval == 0) {
- final long now = System.currentTimeMillis();
+ final long now = TimeUnit.NANOSECONDS.toMillis(System.nanoTime());
fpsLastPeriod = now - fpsLastUpdateTime;
fpsLastPeriod = Math.max(fpsLastPeriod, 1); // div 0
fpsLast = ( (float)fpsUpdateFramesInterval * 1000f ) / ( (float) fpsLastPeriod ) ;
@@ -96,7 +98,7 @@ public class FPSCounterImpl implements FPSCounter {
}
public final synchronized void resetFPSCounter() {
- fpsStartTime = System.currentTimeMillis(); // overwrite startTime to real init one
+ fpsStartTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime()); // overwrite startTime to real init one
fpsLastUpdateTime = fpsStartTime;
fpsLastPeriod = 0;
fpsTotalFrames = 0;
diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
index 58f1bf1cd..e87d283eb 100644
--- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java
@@ -47,8 +47,6 @@ import java.util.Map;
import com.jogamp.common.os.DynamicLookupHelper;
import com.jogamp.common.util.ReflectionUtil;
-import com.jogamp.common.util.locks.LockFactory;
-import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.gluegen.runtime.FunctionAddressResolver;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLExtensionNames;
@@ -69,11 +67,8 @@ import javax.media.opengl.GLPipelineFactory;
import javax.media.opengl.GLProfile;
public abstract class GLContextImpl extends GLContext {
- public static final boolean DEBUG = Debug.debug("GLContext");
-
- // RecursiveLock maintains a queue of waiting Threads, ensuring the longest waiting thread will be notified at unlock.
- protected RecursiveLock lock = LockFactory.createRecursiveLock();
-
+ public static final boolean TRACE_SWITCH = Debug.isPropertyDefined("jogl.debug.GLContext.TraceSwitch", true);
+
/**
* Context full qualified name: display_type + display_connection + major + minor + ctp.
* This is the key for all cached GL ProcAddressTables, etc, to support multi display/device setups.
@@ -113,6 +108,12 @@ public abstract class GLContextImpl extends GLContext {
mappedGLXProcAddress = new HashMap<String, ProcAddressTable>();
}
+ public static void shutdownImpl() {
+ mappedExtensionAvailabilityCache.clear();
+ mappedGLProcAddress.clear();
+ mappedGLXProcAddress.clear();
+ }
+
public GLContextImpl(GLDrawableImpl drawable, GLContext shareWith) {
super();
@@ -209,74 +210,94 @@ public abstract class GLContextImpl extends GLContext {
*/
protected void drawableUpdatedNotify() throws GLException { }
- boolean lockFailFast = true;
- Object lockFailFastSync = new Object();
+ volatile boolean lockFailFast = true;
public boolean isSynchronized() {
- synchronized (lockFailFastSync) {
- return !lockFailFast;
- }
+ return !lockFailFast; // volatile: ok
}
public void setSynchronized(boolean isSynchronized) {
- synchronized (lockFailFastSync) {
- lockFailFast = !isSynchronized;
- }
+ lockFailFast = !isSynchronized; // volatile: ok
}
- private final void lockConsiderFailFast() {
- synchronized (lockFailFastSync) {
- if(lockFailFast && lock.isLockedByOtherThread()) {
- throw new GLException("Error: Attempt to make context current on thread " + Thread.currentThread() +
- " which is already current on thread " + lock.getOwner());
+ private final void lockConsiderFailFast() {
+ if( lockFailFast ) { // volatile: ok
+ try {
+ if( !lock.tryLock(0) ) { // immediate return w/ false, if lock is already held by other thread
+ throw new GLException("Error: Attempt to make context current on thread " + Thread.currentThread().getName() +
+ " which is already current on thread " + lock.getOwner().getName());
+ }
+ } catch (InterruptedException ie) {
+ throw new GLException(ie);
}
+ } else {
+ lock.lock();
}
- lock.lock();
}
public abstract Object getPlatformGLExtensions();
// Note: the surface is locked within [makeCurrent .. swap .. release]
public void release() throws GLException {
+ release(false);
+ }
+ private void release(boolean force) throws GLException {
if ( !lock.isOwner() ) {
throw new GLException("Context not current on current thread");
}
- setCurrent(null);
+ final boolean actualRelease = force || lock.getHoldCount() == 1 ;
try {
- releaseImpl();
+ if( actualRelease ) {
+ setCurrent(null);
+ if (contextHandle != 0) { // allow dbl-release
+ releaseImpl();
+ }
+ }
} finally {
- if (drawable.isSurfaceLocked()) {
- drawable.unlockSurface();
- }
+ drawable.unlockSurface();
lock.unlock();
+ if(TRACE_SWITCH) {
+ if( actualRelease ) {
+ System.err.println("GLContext.ContextSwitch: - switch - CONTEXT_RELEASE - "+Thread.currentThread().getName()+" - "+lock);
+ } else {
+ System.err.println("GLContext.ContextSwitch: - keep - CONTEXT_RELEASE - "+Thread.currentThread().getName()+" - "+lock);
+ }
+ }
}
}
protected abstract void releaseImpl() throws GLException;
public final void destroy() {
- if ( lock.isOwner() ) {
- // release current context
- if(null != glDebugHandler) {
- glDebugHandler.enable(false);
- }
- release();
- }
-
// Must hold the lock around the destroy operation to make sure we
// don't destroy the context out from under another thread rendering to it
- lockConsiderFailFast();
+ lockConsiderFailFast(); // holdCount++ -> 1 or 2
try {
+ if(lock.getHoldCount() > 2) {
+ throw new GLException("XXX: "+lock);
+ }
+ if (DEBUG || TRACE_SWITCH) {
+ System.err.println("GLContextImpl.destroy.0: " + toHexString(contextHandle) +
+ ", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
+ }
if (contextHandle != 0) {
int lockRes = drawable.lockSurface();
if (NativeSurface.LOCK_SURFACE_NOT_READY == lockRes) {
// this would be odd ..
throw new GLException("Surface not ready to lock: "+drawable);
}
- try {
- if (DEBUG) {
- System.err.println("GLContextImpl.destroy: " + toHexString(contextHandle) +
- ", isShared "+GLContextShareSet.isShared(this));
+ // release current context
+ if(null != glDebugHandler) {
+ if(lock.getHoldCount() == 1) {
+ // needs current context to disable debug handler
+ makeCurrent();
}
+ glDebugHandler.enable(false);
+ }
+ if(lock.getHoldCount() > 1) {
+ // pending release() after makeCurrent()
+ release(true);
+ }
+ try {
destroyImpl();
contextHandle = 0;
glDebugHandler = null;
@@ -290,6 +311,10 @@ public abstract class GLContextImpl extends GLContext {
}
} finally {
lock.unlock();
+ if (DEBUG || TRACE_SWITCH) {
+ System.err.println("GLContextImpl.destroy.X: " + toHexString(contextHandle) +
+ ", isShared "+GLContextShareSet.isShared(this)+" - "+lock);
+ }
}
resetStates();
@@ -321,7 +346,10 @@ public abstract class GLContextImpl extends GLContext {
//
/**
- * MakeCurrent functionality, which also issues the creation of the actual OpenGL context.<br>
+ * {@inheritDoc}
+ * <p>
+ * MakeCurrent functionality, which also issues the creation of the actual OpenGL context.
+ * </p>
* The complete callgraph for general OpenGL context creation is:<br>
* <ul>
* <li> {@link #makeCurrent} <i>GLContextImpl</i></li>
@@ -355,55 +383,75 @@ public abstract class GLContextImpl extends GLContext {
* @see #destroyContextARBImpl
*/
public int makeCurrent() throws GLException {
- // One context can only be current by one thread,
- // and one thread can only have one context current!
- GLContext current = getCurrent();
- if (current != null) {
- if (current == this) {
- // Assume we don't need to make this context current again
- // For Mac OS X, however, we need to update the context to track resizes
- drawableUpdatedNotify();
- return CONTEXT_CURRENT;
- } else {
- current.release();
- }
- }
-
- if (GLWorkerThread.isStarted() &&
- !GLWorkerThread.isWorkerThread()) {
- // Kick the GLWorkerThread off its current context
- GLWorkerThread.invokeLater(new Runnable() { public void run() {} });
- }
-
- if (!isCreated()) {
- // verify if the drawable has chosen Capabilities
- if (null == getGLDrawable().getChosenGLCapabilities()) {
- throw new GLException("drawable has no chosen GLCapabilities: "+getGLDrawable());
- }
- if(DEBUG_GL) {
- // only impacts w/ createContextARB(..)
- additionalCtxCreationFlags |= GLContext.CTX_OPTION_DEBUG ;
- }
- }
-
+ boolean unlockContextAndDrawable = false;
lockConsiderFailFast();
- int res = 0;
+ int res = CONTEXT_NOT_CURRENT;
try {
- res = makeCurrentLocking();
-
- /* FIXME: refactor dependence on Java 2D / JOGL bridge
- if ((tracker != null) &&
- (res == CONTEXT_CURRENT_NEW)) {
- // Increase reference count of GLObjectTracker
- tracker.ref();
- }
- */
- } catch (GLException e) {
- lock.unlock();
- throw(e);
+ // Note: the surface is locked within [makeCurrent .. swap .. release]
+ int lockRes = drawable.lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ try {
+ if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
+ drawable.updateHandle();
+ }
+ // One context can only be current by one thread,
+ // and one thread can only have one context current!
+ final GLContext current = getCurrent();
+ if (current != null) {
+ if (current == this) {
+ // Assume we don't need to make this context current again
+ // For Mac OS X, however, we need to update the context to track resizes
+ drawableUpdatedNotify();
+ if(TRACE_SWITCH) {
+ System.err.println("GLContext.ContextSwitch: - keep - CONTEXT_CURRENT - "+Thread.currentThread().getName()+" - "+lock);
+ }
+ return CONTEXT_CURRENT;
+ } else {
+ current.release();
+ }
+ }
+ if (GLWorkerThread.isStarted() &&
+ !GLWorkerThread.isWorkerThread()) {
+ // Kick the GLWorkerThread off its current context
+ GLWorkerThread.invokeLater(new Runnable() { public void run() {} });
+ }
+
+ if (0 == drawable.getHandle()) {
+ throw new GLException("drawable has invalid handle: "+drawable);
+ }
+ res = makeCurrentWithinLock(lockRes);
+ unlockContextAndDrawable = CONTEXT_NOT_CURRENT == res;
+
+ /**
+ * FIXME: refactor dependence on Java 2D / JOGL bridge
+ if ((tracker != null) &&
+ (res == CONTEXT_CURRENT_NEW)) {
+ // Increase reference count of GLObjectTracker
+ tracker.ref();
+ }
+ */
+ } catch (RuntimeException e) {
+ unlockContextAndDrawable = true;
+ throw e;
+ } finally {
+ if (unlockContextAndDrawable) {
+ drawable.unlockSurface();
+ }
+ }
+ } catch (RuntimeException e) {
+ unlockContextAndDrawable = true;
+ throw e;
+ } finally {
+ if (unlockContextAndDrawable) {
+ lock.unlock();
+ }
}
if (res == CONTEXT_NOT_CURRENT) {
- lock.unlock();
+ if(TRACE_SWITCH) {
+ System.err.println("GLContext.ContextSwitch: - switch - CONTEXT_NOT_CURRENT - "+Thread.currentThread().getName()+" - "+lock);
+ }
} else {
setCurrent(this);
if(res == CONTEXT_CURRENT_NEW) {
@@ -422,6 +470,11 @@ public abstract class GLContextImpl extends GLContext {
if(TRACE_GL) {
gl = gl.getContext().setGL( GLPipelineFactory.create("javax.media.opengl.Trace", null, gl, new Object[] { System.err } ) );
}
+ if(TRACE_SWITCH) {
+ System.err.println("GLContext.ContextSwitch: - switch - CONTEXT_CURRENT_NEW - "+Thread.currentThread().getName()+" - "+lock);
+ }
+ } else if(TRACE_SWITCH) {
+ System.err.println("GLContext.ContextSwitch: - switch - CONTEXT_CURRENT - "+Thread.currentThread().getName()+" - "+lock);
}
/* FIXME: refactor dependence on Java 2D / JOGL bridge
@@ -436,71 +489,76 @@ public abstract class GLContextImpl extends GLContext {
return res;
}
- // Note: the surface is locked within [makeCurrent .. swap .. release]
- protected final int makeCurrentLocking() throws GLException {
- boolean shallUnlockSurface = false;
- int lockRes = drawable.lockSurface();
- try {
- if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
- return CONTEXT_NOT_CURRENT;
- }
- try {
- if (NativeSurface.LOCK_SURFACE_CHANGED == lockRes) {
- drawable.updateHandle();
- }
- if (0 == drawable.getHandle()) {
- throw new GLException("drawable has invalid handle: "+drawable);
- }
- boolean newCreated = false;
- if (!isCreated()) {
- GLProfile.initProfiles(
- getGLDrawable().getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice());
- newCreated = createImpl(); // may throws exception if fails!
- if (DEBUG) {
- if(newCreated) {
- System.err.println(getThreadName() + ": !!! Create GL context OK: " + toHexString(contextHandle) + " for " + getClass().getName());
- } else {
- System.err.println(getThreadName() + ": !!! Create GL context FAILED for " + getClass().getName());
- }
- }
- if(!newCreated) {
- shallUnlockSurface = true;
- return CONTEXT_NOT_CURRENT;
+ private final int makeCurrentWithinLock(int surfaceLockRes) throws GLException {
+ if (!isCreated()) {
+ if(DEBUG_GL) {
+ // only impacts w/ createContextARB(..)
+ additionalCtxCreationFlags |= GLContext.CTX_OPTION_DEBUG ;
+ }
+
+ final GLContextImpl shareWith = (GLContextImpl) GLContextShareSet.getShareContext(this);
+ if (null != shareWith) {
+ shareWith.getDrawableImpl().lockSurface();
+ }
+ final boolean created;
+ try {
+ created = createImpl(shareWith); // may throws exception if fails!
+ } finally {
+ if (null != shareWith) {
+ shareWith.getDrawableImpl().unlockSurface();
+ }
+ }
+ if (DEBUG) {
+ if(created) {
+ System.err.println(getThreadName() + ": !!! Create GL context OK: " + toHexString(contextHandle) + " for " + getClass().getName());
+ } else {
+ System.err.println(getThreadName() + ": !!! Create GL context FAILED for " + getClass().getName());
}
- GLContextShareSet.contextCreated(this);
- }
- makeCurrentImpl(newCreated);
- return newCreated ? CONTEXT_CURRENT_NEW : CONTEXT_CURRENT ;
- } catch (RuntimeException e) {
- shallUnlockSurface = true;
- throw e;
- }
- } finally {
- if (shallUnlockSurface) {
- drawable.unlockSurface();
+ }
+ if(!created) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ GLContextShareSet.contextCreated(this);
+ return CONTEXT_CURRENT_NEW;
}
- }
+ makeCurrentImpl();
+ return CONTEXT_CURRENT;
}
- protected abstract void makeCurrentImpl(boolean newCreatedContext) throws GLException;
- protected abstract boolean createImpl() throws GLException ;
+ protected abstract void makeCurrentImpl() throws GLException;
+
+ /**
+ * Platform dependent entry point for context creation.<br>
+ *
+ * This method is called from {@link #makeCurrentWithinLock()} .. {@link #makeCurrent()} .<br>
+ *
+ * The implementation shall verify this context with a
+ * <code>MakeContextCurrent</code> call.<br>
+ *
+ * The implementation <b>must</b> leave the context current.<br>
+ *
+ * @param share the shared context or null
+ * @return the valid and current context if successful, or null
+ * @throws GLException
+ */
+ protected abstract boolean createImpl(GLContextImpl sharedWith) throws GLException ;
/**
* Platform dependent but harmonized implementation of the <code>ARB_create_context</code>
* mechanism to create a context.<br>
*
- * This method is called from {@link #createContextARB}.<br>
+ * This method is called from {@link #createContextARB}, {@link #createImpl(GLContextImpl)} .. {@link #makeCurrent()} .<br>
*
* The implementation shall verify this context with a
* <code>MakeContextCurrent</code> call.<br>
*
- * The implementation shall leave the context current.<br>
+ * The implementation <b>must</b> leave the context current.<br>
*
* @param share the shared context or null
* @param direct flag if direct is requested
* @param ctxOptionFlags <code>ARB_create_context</code> related, see references below
* @param major major number
* @param minor minor number
- * @return the valid context if successfull, or null
+ * @return the valid and current context if successful, or null
*
* @see #makeCurrent
* @see #CTX_PROFILE_COMPAT
@@ -548,7 +606,7 @@ public abstract class GLContextImpl extends GLContext {
*/
protected final long createContextARB(long share, boolean direct)
{
- AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
GLProfile glp = glCaps.getGLProfile();
@@ -583,7 +641,7 @@ public abstract class GLContextImpl extends GLContext {
_ctp[0] |= additionalCtxCreationFlags;
_ctx = createContextARBImpl(share, direct, _ctp[0], _major[0], _minor[0]);
if(0!=_ctx) {
- setGLFunctionAvailability(true, true, _major[0], _minor[0], _ctp[0]);
+ setGLFunctionAvailability(true, _major[0], _minor[0], _ctp[0]);
}
}
return _ctx;
@@ -654,12 +712,11 @@ public abstract class GLContextImpl extends GLContext {
}
}
if(0!=_context) {
- AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice();
+ AbstractGraphicsDevice device = drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
if( isExtensionAvailable("GL_ARB_ES2_compatibility") ) {
ctp |= CTX_PROFILE_ES2_COMPAT;
}
GLContext.mapAvailableGLVersion(device, reqMajor, reqProfile, major[0], minor[0], ctp);
- setGLFunctionAvailability(true, true, major[0], minor[0], ctp);
destroyContextARBImpl(_context);
if (DEBUG) {
System.err.println(getThreadName() + ": !!! createContextARBMapVersionsAvailable HAVE: "+
@@ -677,8 +734,9 @@ public abstract class GLContextImpl extends GLContext {
major[0]=majorMax;
minor[0]=minorMax;
long _context=0;
+ boolean ok = false;
- while ( 0==_context &&
+ while ( !ok &&
GLContext.isValidGLVersion(major[0], minor[0]) &&
( major[0]>majorMin || major[0]==majorMin && minor[0] >=minorMin ) ) {
@@ -687,15 +745,20 @@ public abstract class GLContextImpl extends GLContext {
}
_context = createContextARBImpl(share, direct, ctxOptionFlags, major[0], minor[0]);
- boolean ok = 0!=_context;
+ if(0 != _context) {
+ ok = true;
+ setGLFunctionAvailability(true, major[0], minor[0], ctxOptionFlags);
+ } else {
+ ok = false;
+ }
if(ok && major[0]>=3) {
int[] hasMajor = new int[1]; int[] hasMinor = new int[1];
- setGLFunctionAvailability(true, false, major[0], minor[0], ctxOptionFlags);
gl.glGetIntegerv(GL3.GL_MAJOR_VERSION, hasMajor, 0);
gl.glGetIntegerv(GL3.GL_MINOR_VERSION, hasMinor, 0);
ok = hasMajor[0]>major[0] || ( hasMajor[0]==major[0] && hasMinor[0]>=minor[0] ) ;
if(!ok) {
+ removeCachedVersion(major[0], minor[0], ctxOptionFlags);
destroyContextARBImpl(_context);
_context = 0;
}
@@ -703,6 +766,7 @@ public abstract class GLContextImpl extends GLContext {
System.err.println(getThreadName() + ": createContextARBVersions: version verification - expected "+major[0]+"."+minor[0]+", has "+hasMajor[0]+"."+hasMinor[0]+" == "+ok);
}
}
+
if(!ok) {
if(!GLContext.decrementGLVersion(major, minor)) break;
}
@@ -854,15 +918,15 @@ public abstract class GLContextImpl extends GLContext {
*
* @param force force the setting, even if is already being set.
* This might be useful if you change the OpenGL implementation.
- * @param cached whether this version's data shall be cached or not
* @param major OpenGL major version
* @param minor OpenGL minor version
* @param ctxProfileBits OpenGL context profile and option bits, see {@link javax.media.opengl.GLContext#CTX_OPTION_ANY}
+ *
* @see #setContextVersion
* @see javax.media.opengl.GLContext#CTX_OPTION_ANY
* @see javax.media.opengl.GLContext#CTX_PROFILE_COMPAT
*/
- protected final void setGLFunctionAvailability(boolean force, boolean cached, int major, int minor, int ctxProfileBits) {
+ protected final void setGLFunctionAvailability(boolean force, int major, int minor, int ctxProfileBits) {
if(null!=this.gl && null!=glProcAddressTable && !force) {
return; // already done and not forced
}
@@ -873,7 +937,7 @@ public abstract class GLContextImpl extends GLContext {
updateGLXProcAddressTable();
- AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final int ctxImplBits = drawable.getChosenGLCapabilities().getHardwareAccelerated() ? GLContext.CTX_IMPL_ACCEL_HARD : GLContext.CTX_IMPL_ACCEL_SOFT;
contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits, ctxImplBits);
@@ -904,12 +968,10 @@ public abstract class GLContextImpl extends GLContext {
new Object[] { new GLProcAddressResolver() } );
}
resetProcAddressTable(getGLProcAddressTable());
- if(cached) {
- synchronized(mappedContextTypeObjectLock) {
- mappedGLProcAddress.put(contextFQN, getGLProcAddressTable());
- if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+getGLProcAddressTable().hashCode());
- }
+ synchronized(mappedContextTypeObjectLock) {
+ mappedGLProcAddress.put(contextFQN, getGLProcAddressTable());
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+getGLProcAddressTable().hashCode());
}
}
}
@@ -919,34 +981,56 @@ public abstract class GLContextImpl extends GLContext {
//
setContextVersion(major, minor, ctxProfileBits);
- if(cached) {
- //
- // Update ExtensionAvailabilityCache
- //
- ExtensionAvailabilityCache eCache;
- synchronized(mappedContextTypeObjectLock) {
- eCache = mappedExtensionAvailabilityCache.get( contextFQN );
+ //
+ // Update ExtensionAvailabilityCache
+ //
+ ExtensionAvailabilityCache eCache;
+ synchronized(mappedContextTypeObjectLock) {
+ eCache = mappedExtensionAvailabilityCache.get( contextFQN );
+ }
+ if(null != eCache) {
+ extensionAvailability = eCache;
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! GLContext GL ExtensionAvailabilityCache reusing key("+contextFQN+") -> "+eCache.hashCode());
+ }
+ } else {
+ if(null==extensionAvailability) {
+ extensionAvailability = new ExtensionAvailabilityCache(this);
}
- if(null != eCache) {
- extensionAvailability = eCache;
+ extensionAvailability.reset();
+ synchronized(mappedContextTypeObjectLock) {
+ mappedExtensionAvailabilityCache.put(contextFQN, extensionAvailability);
if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GL ExtensionAvailabilityCache reusing key("+contextFQN+") -> "+eCache.hashCode());
- }
- } else {
- if(null==extensionAvailability) {
- extensionAvailability = new ExtensionAvailabilityCache(this);
- }
- extensionAvailability.reset();
- synchronized(mappedContextTypeObjectLock) {
- mappedExtensionAvailabilityCache.put(contextFQN, extensionAvailability);
- if(DEBUG) {
- System.err.println(getThreadName() + ": !!! GLContext GL ExtensionAvailabilityCache mapping key("+contextFQN+") -> "+extensionAvailability.hashCode());
- }
+ System.err.println(getThreadName() + ": !!! GLContext GL ExtensionAvailabilityCache mapping key("+contextFQN+") -> "+extensionAvailability.hashCode());
}
}
}
}
+ protected final void removeCachedVersion(int major, int minor, int ctxProfileBits) {
+ AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
+ AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
+ final int ctxImplBits = drawable.getChosenGLCapabilities().getHardwareAccelerated() ? GLContext.CTX_IMPL_ACCEL_HARD : GLContext.CTX_IMPL_ACCEL_SOFT;
+ contextFQN = getContextFQN(adevice, major, minor, ctxProfileBits, ctxImplBits);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! RM Context FQN: "+contextFQN);
+ }
+
+ synchronized(mappedContextTypeObjectLock) {
+ ProcAddressTable table = mappedGLProcAddress.remove( contextFQN );
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! RM GLContext GL ProcAddressTable mapping key("+contextFQN+") -> "+table.hashCode());
+ }
+ }
+
+ synchronized(mappedContextTypeObjectLock) {
+ ExtensionAvailabilityCache eCache = mappedExtensionAvailabilityCache.get( contextFQN );
+ if(DEBUG) {
+ System.err.println(getThreadName() + ": !!! RM GLContext GL ExtensionAvailabilityCache reusing key("+contextFQN+") -> "+eCache.hashCode());
+ }
+ }
+ }
+
/**
* Updates the platform's 'GLX' function cache
*/
diff --git a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
index 8ca0c016d..b950c2fdf 100644
--- a/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
+++ b/src/jogl/classes/jogamp/opengl/GLDebugMessageHandler.java
@@ -35,6 +35,7 @@ import javax.media.opengl.GLDebugListener;
import javax.media.opengl.GLDebugMessage;
import javax.media.opengl.GLException;
+import com.jogamp.common.os.Platform;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import jogamp.opengl.gl4.GL4bcProcAddressTable;
@@ -122,7 +123,14 @@ public class GLDebugMessageHandler {
}
return;
}
-
+ if(Platform.OS_TYPE == Platform.OSType.WINDOWS && Platform.is32Bit()) {
+ // Currently buggy, ie. throws an exception after leaving the native callback.
+ // Probably a 32bit on 64bit JVM / OpenGL-driver issue.
+ if(DEBUG) {
+ System.err.println("GLDebugMessageHandler: Windows 32bit currently not supported!");
+ }
+ return;
+ }
if( ctx.isExtensionAvailable(GL_ARB_debug_output) ) {
extName = GL_ARB_debug_output;
extType = EXT_ARB;
@@ -199,7 +207,7 @@ public class GLDebugMessageHandler {
*/
public final void setSynchronous(boolean synchronous) {
this.synchronous = synchronous;
- if(isEnabled() && isExtensionARB()) {
+ if( isEnabled() ) {
setSynchronousImpl();
}
}
@@ -227,9 +235,9 @@ public class GLDebugMessageHandler {
enableImpl(enable);
}
final void enableImpl(boolean enable) throws GLException {
- setSynchronousImpl();
if(enable) {
if(0 == handle) {
+ setSynchronousImpl();
handle = register0(glDebugMessageCallbackProcAddress, extType);
if(0 == handle) {
throw new GLException("Failed to register via \"glDebugMessageCallback*\" using "+extName);
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
index 704f71457..e5f415a87 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableFactoryImpl.java
@@ -40,11 +40,25 @@
package jogamp.opengl;
-import java.nio.*;
-import javax.media.nativewindow.*;
-import javax.media.opengl.*;
-
-import com.jogamp.common.util.VersionNumber;
+import java.nio.Buffer;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.ProxySurface;
+import javax.media.nativewindow.SurfaceChangeable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.MutableGraphicsConfiguration;
/** Extends GLDrawableFactory with a few methods for handling
typically software-accelerated offscreen rendering (Device
@@ -53,17 +67,28 @@ import com.jogamp.common.util.VersionNumber;
they may be instantiated by the GLJPanel implementation. */
public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
- public static final VersionNumber versionOneZero = new VersionNumber(1, 0, 0);
- public static final VersionNumber versionOneOne = new VersionNumber(1, 1, 0);
- public static final VersionNumber versionOneTwo = new VersionNumber(1, 2, 0);
- public static final VersionNumber versionOneThree = new VersionNumber(1, 3, 0);
- public static final VersionNumber versionOneFour = new VersionNumber(1, 4, 0);
protected GLDrawableFactoryImpl() {
super();
}
/**
+ * Returns the shared context mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
+ * either a pre-existing or newly created, or <code>null</code> if creation failed or not supported.<br>
+ * Creation of the shared context is tried only once.
+ *
+ * @param device which {@link javax.media.nativewindow.AbstractGraphicsDevice#getConnection() connection} denotes the shared the target device, may be <code>null</code> for the platform's default device.
+ */
+ public final GLContext getOrCreateSharedContext(AbstractGraphicsDevice device) {
+ device = validateDevice(device);
+ if(null!=device) {
+ return getOrCreateSharedContextImpl(device);
+ }
+ return null;
+ }
+ protected abstract GLContext getOrCreateSharedContextImpl(AbstractGraphicsDevice device);
+
+ /**
* Returns the shared device mapped to the <code>device</code> {@link AbstractGraphicsDevice#getConnection()},
* either a preexisting or newly created, or <code>null</code> if creation failed or not supported.<br>
* Creation of the shared context is tried only once.
@@ -103,24 +128,40 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final MutableGraphicsConfiguration config = (MutableGraphicsConfiguration) target.getGraphicsConfiguration();
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
AbstractGraphicsDevice adevice = config.getScreen().getDevice();
GLDrawable result = null;
adevice.lock();
try {
- if(caps.isOnscreen()) {
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(target, true);
+ if(null != ols) {
+ // layered surface -> Offscreen/PBuffer
+ final GLCapabilities chosenCapsMod = (GLCapabilities) chosenCaps.cloneMutable();
+ chosenCapsMod.setOnscreen(false);
+ chosenCapsMod.setPBuffer(canCreateGLPbuffer(adevice));
+ config.setChosenCapabilities(chosenCapsMod);
+ if(DEBUG) {
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable -> Offscreen-Layer: "+target);
+ }
+ if( ! ( target instanceof SurfaceChangeable ) ) {
+ throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen layered surface: "+target);
+ }
+ result = createOffscreenDrawableImpl(target);
+ } else if(chosenCaps.isOnscreen()) {
+ // onscreen
if(DEBUG) {
System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OnscreenDrawable: "+target);
}
result = createOnscreenDrawableImpl(target);
} else {
+ // offscreen
+ if(DEBUG) {
+ System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+chosenCaps.isPBuffer()+"): "+target);
+ }
if( ! ( target instanceof SurfaceChangeable ) ) {
throw new IllegalArgumentException("Passed NativeSurface must implement SurfaceChangeable for offscreen: "+target);
}
- if(DEBUG) {
- System.err.println("GLDrawableFactoryImpl.createGLDrawable -> OffScreenDrawable (PBuffer: "+caps.isPBuffer()+"): "+target);
- }
result = createOffscreenDrawableImpl(target);
}
} finally {
@@ -171,6 +212,9 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
device.lock();
try {
drawable = (GLDrawableImpl) createGLDrawable( createOffscreenSurfaceImpl(device, capsChosen, capsRequested, chooser, width, height) );
+ if(null != drawable) {
+ drawable.setRealized(true);
+ }
} finally {
device.unlock();
}
@@ -287,15 +331,6 @@ public abstract class GLDrawableFactoryImpl extends GLDrawableFactory {
// GLDrawableFactoryImpl details
//
- protected void maybeDoSingleThreadedWorkaround(Runnable action) {
- if (Threading.isSingleThreaded() &&
- !Threading.isOpenGLThread()) {
- Threading.invokeOnOpenGLThread(action);
- } else {
- action.run();
- }
- }
-
/**
* Returns the sole GLDrawableFactoryImpl instance.
*
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
index 151ec2e9c..509839f55 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableHelper.java
@@ -40,8 +40,16 @@
package jogamp.opengl;
-import java.util.*;
-import javax.media.opengl.*;
+import java.util.ArrayList;
+import java.util.HashSet;
+
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLRunnable;
import com.jogamp.opengl.util.Animator;
@@ -49,6 +57,9 @@ import com.jogamp.opengl.util.Animator;
methods to be able to share it between GLCanvas and GLJPanel. */
public class GLDrawableHelper {
+ /** true if property <code>jogl.debug.GLDrawable.PerfStats</code> is defined. */
+ private static final boolean PERF_STATS = Debug.isPropertyDefined("jogl.debug.GLDrawable.PerfStats", true);
+
protected static final boolean DEBUG = GLDrawableImpl.DEBUG;
private Object listenersLock = new Object();
private ArrayList<GLEventListener> listeners;
@@ -120,6 +131,10 @@ public class GLDrawableHelper {
/**
* Issues {@link javax.media.opengl.GLEventListener#dispose(javax.media.opengl.GLAutoDrawable)}
* to all listeners.
+ * <p>
+ * Please consider using {@link #disposeGL(GLAutoDrawable, GLDrawable, GLContext, Runnable)}
+ * for correctness!
+ * </p>
* @param drawable
*/
public final void dispose(GLAutoDrawable drawable) {
@@ -129,12 +144,12 @@ public class GLDrawableHelper {
}
}
}
-
+
private boolean init(GLEventListener l, GLAutoDrawable drawable, boolean sendReshape) {
if(listenersToBeInit.remove(l)) {
l.init(drawable);
if(sendReshape) {
- reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */);
+ reshape(l, drawable, 0, 0, drawable.getWidth(), drawable.getHeight(), true /* setViewport */, false);
}
return true;
}
@@ -177,7 +192,12 @@ public class GLDrawableHelper {
}
private void reshape(GLEventListener listener, GLAutoDrawable drawable,
- int x, int y, int width, int height, boolean setViewport) {
+ int x, int y, int width, int height, boolean setViewport, boolean checkInit) {
+ if(checkInit) {
+ // GLEventListener may need to be init,
+ // in case this one is added after the realization of the GLAutoDrawable
+ init( listener, drawable, false ) ;
+ }
if(setViewport) {
drawable.getGL().glViewport(x, y, width, height);
}
@@ -187,7 +207,7 @@ public class GLDrawableHelper {
public final void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
synchronized(listenersLock) {
for (int i=0; i < listeners.size(); i++) {
- reshape((GLEventListener) listeners.get(i), drawable, x, y, width, height, 0==i);
+ reshape((GLEventListener) listeners.get(i), drawable, x, y, width, height, 0==i, true);
}
}
}
@@ -294,6 +314,8 @@ public class GLDrawableHelper {
* ie. {@link Animator#getThread()}.
* @deprecated this is an experimental feature,
* intended for measuring performance in regards to GL context switch
+ * and only being used if {@link #PERF_STATS} is enabled
+ * by defining property <code>jogl.debug.GLDrawable.PerfStats</code>.
*/
public final void setSkipContextReleaseThread(Thread t) {
skipContextReleaseThread = t;
@@ -305,7 +327,7 @@ public class GLDrawableHelper {
public final Thread getSkipContextReleaseThread() {
return skipContextReleaseThread;
}
-
+
private static final ThreadLocal<Runnable> perThreadInitAction = new ThreadLocal<Runnable>();
/** Principal helper method which runs a Runnable with the context
@@ -315,8 +337,6 @@ public class GLDrawableHelper {
class helps ensure that we don't inadvertently use private
methods of the GLContext or its implementing classes.<br>
* <br>
- * Remark: In case this method is called to dispose the GLDrawable/GLAutoDrawable,
- * <code>initAction</code> shall be <code>null</code> to mark this cause.<br>
*
* @param drawable
* @param context
@@ -335,13 +355,112 @@ public class GLDrawableHelper {
return;
}
- if(null==initAction) {
- // disposal case
- if(!context.isCreated()) {
- throw new GLException(Thread.currentThread().getName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context is not created: "+context);
- }
+ if(PERF_STATS) {
+ invokeGLImplStats(drawable, context, runnable, initAction, null);
+ } else {
+ invokeGLImpl(drawable, context, runnable, initAction, null);
}
+ }
+ /**
+ * Principal helper method which runs {@link #dispose(GLAutoDrawable)} with the context
+ * made current and destroys the context afterwards while holding the lock.
+ *
+ * @param autoDrawable
+ * @param drawable
+ * @param context
+ * @param postAction
+ */
+ public final void disposeGL(GLAutoDrawable autoDrawable,
+ GLDrawable drawable,
+ GLContext context,
+ Runnable postAction) {
+ if(PERF_STATS) {
+ invokeGLImplStats(drawable, context, null, null, autoDrawable);
+ } else {
+ invokeGLImpl(drawable, context, null, null, autoDrawable);
+ }
+ if(null != postAction) {
+ postAction.run();
+ }
+ }
+
+ private final void invokeGLImpl(GLDrawable drawable,
+ GLContext context,
+ Runnable runnable,
+ Runnable initAction,
+ GLAutoDrawable disposeAutoDrawable) {
+ final Thread currentThread = Thread.currentThread();
+
+ final boolean isDisposeAction = null==initAction ;
+
+ // Support for recursive makeCurrent() calls as well as calling
+ // other drawables' display() methods from within another one's
+ GLContext lastContext = GLContext.getCurrent();
+ Runnable lastInitAction = null;
+ if (lastContext != null) {
+ if (lastContext == context) {
+ lastContext = null; // utilize recursive locking
+ } else {
+ lastInitAction = perThreadInitAction.get();
+ lastContext.release();
+ }
+ }
+ int res = GLContext.CONTEXT_NOT_CURRENT;
+
+ try {
+ res = context.makeCurrent();
+ if (res != GLContext.CONTEXT_NOT_CURRENT) {
+ if(!isDisposeAction) {
+ perThreadInitAction.set(initAction);
+ if (res == GLContext.CONTEXT_CURRENT_NEW) {
+ if (DEBUG) {
+ System.err.println("GLDrawableHelper " + this + ".invokeGL(): Running initAction");
+ }
+ initAction.run();
+ }
+ runnable.run();
+ if (autoSwapBufferMode) {
+ drawable.swapBuffers();
+ }
+ } else {
+ if(res == GLContext.CONTEXT_CURRENT_NEW) {
+ throw new GLException(currentThread.getName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context was not created (new ctx): "+context);
+ }
+ if(listeners.size()>0) {
+ dispose(disposeAutoDrawable);
+ }
+ }
+ }
+ } finally {
+ try {
+ if(isDisposeAction) {
+ context.destroy();
+ } else if( res != GLContext.CONTEXT_NOT_CURRENT ) {
+ context.release();
+ }
+ } catch (Exception e) {
+ System.err.println("Catched: "+e.getMessage());
+ e.printStackTrace();
+ }
+ if (lastContext != null) {
+ final int res2 = lastContext.makeCurrent();
+ if (null != lastInitAction && res2 == GLContext.CONTEXT_CURRENT_NEW) {
+ lastInitAction.run();
+ }
+ }
+ }
+ }
+
+ private final void invokeGLImplStats(GLDrawable drawable,
+ GLContext context,
+ Runnable runnable,
+ Runnable initAction,
+ GLAutoDrawable disposeAutoDrawable) {
+ final Thread currentThread = Thread.currentThread();
+
+ final boolean isDisposeAction = null==initAction ;
+
// Support for recursive makeCurrent() calls as well as calling
// other drawables' display() methods from within another one's
int res = GLContext.CONTEXT_NOT_CURRENT;
@@ -349,7 +468,9 @@ public class GLDrawableHelper {
Runnable lastInitAction = null;
if (lastContext != null) {
if (lastContext == context) {
- res = GLContext.CONTEXT_CURRENT;
+ if( currentThread == skipContextReleaseThread ) {
+ res = GLContext.CONTEXT_CURRENT;
+ } // else: utilize recursive locking
lastContext = null;
} else {
lastInitAction = perThreadInitAction.get();
@@ -357,20 +478,21 @@ public class GLDrawableHelper {
}
}
- /**
long t0 = System.currentTimeMillis();
- long td1 = 0; // makeCurrent
+ long tdA = 0; // makeCurrent
long tdR = 0; // render time
- long td2 = 0; // swapBuffers
- long td3 = 0; // release
- boolean scr = true; */
-
+ long tdS = 0; // swapBuffers
+ long tdX = 0; // release
+ boolean ctxClaimed = false;
+ boolean ctxReleased = false;
+ boolean ctxDestroyed = false;
try {
if (res == GLContext.CONTEXT_NOT_CURRENT) {
res = context.makeCurrent();
+ ctxClaimed = true;
}
if (res != GLContext.CONTEXT_NOT_CURRENT) {
- if(null!=initAction) {
+ if(!isDisposeAction) {
perThreadInitAction.set(initAction);
if (res == GLContext.CONTEXT_CURRENT_NEW) {
if (DEBUG) {
@@ -378,41 +500,50 @@ public class GLDrawableHelper {
}
initAction.run();
}
- }
- // tdR = System.currentTimeMillis();
- // td1 = tdR - t0; // makeCurrent
- if(null!=runnable) {
+ tdR = System.currentTimeMillis();
+ tdA = tdR - t0; // makeCurrent
runnable.run();
- // td2 = System.currentTimeMillis();
- // tdR = td2 - tdR; // render time
- if (autoSwapBufferMode && null != initAction) {
- if (drawable != null) {
+ tdS = System.currentTimeMillis();
+ tdR = tdS - tdR; // render time
+ if (autoSwapBufferMode) {
drawable.swapBuffers();
- // td3 = System.currentTimeMillis();
- // td2 = td3 - td2; // swapBuffers
- }
+ tdX = System.currentTimeMillis();
+ tdS = tdX - tdS; // swapBuffers
+ }
+ } else {
+ if(res == GLContext.CONTEXT_CURRENT_NEW) {
+ throw new GLException(currentThread.getName()+" GLDrawableHelper " + this + ".invokeGL(): Dispose case (no init action given): Native context was not created (new ctx): "+context);
+ }
+ if(listeners.size()>0) {
+ dispose(disposeAutoDrawable);
}
}
}
} finally {
- if(res != GLContext.CONTEXT_NOT_CURRENT &&
- (null == skipContextReleaseThread || Thread.currentThread()!=skipContextReleaseThread) ) {
- try {
+ try {
+ if(isDisposeAction) {
+ context.destroy();
+ ctxDestroyed = true;
+ } else if( res != GLContext.CONTEXT_NOT_CURRENT &&
+ (null == skipContextReleaseThread || currentThread != skipContextReleaseThread) ) {
context.release();
- // scr = false;
- } catch (Exception e) {
+ ctxReleased = true;
}
+ } catch (Exception e) {
+ System.err.println("Catched: "+e.getMessage());
+ e.printStackTrace();
}
- // td3 = System.currentTimeMillis() - td3; // release
+
+ tdX = System.currentTimeMillis() - tdX; // release / destroy
if (lastContext != null) {
- int res2 = lastContext.makeCurrent();
+ final int res2 = lastContext.makeCurrent();
if (null != lastInitAction && res2 == GLContext.CONTEXT_CURRENT_NEW) {
lastInitAction.run();
}
}
}
- // long td0 = System.currentTimeMillis() - t0;
- // System.err.println("td0 "+td0+"ms, fps "+(1.0/(td0/1000.0))+", td-makeCurrent: "+td1+"ms, td-render "+tdR+"ms, td-swap "+td2+"ms, td-release "+td3+"ms, skip ctx release: "+scr);
+ long td = System.currentTimeMillis() - t0;
+ System.err.println("td0 "+td+"ms, fps "+(1.0/(td/1000.0))+", td-makeCurrent: "+tdA+"ms, td-render "+tdR+"ms, td-swap "+tdS+"ms, td-release "+tdX+"ms, ctx claimed: "+ctxClaimed+", ctx release: "+ctxReleased+", ctx destroyed "+ctxDestroyed);
}
-
+
}
diff --git a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
index 58c9aaaa6..b9c216eab 100644
--- a/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLDrawableImpl.java
@@ -40,8 +40,14 @@
package jogamp.opengl;
-import javax.media.nativewindow.*;
-import javax.media.opengl.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
public abstract class GLDrawableImpl implements GLDrawable {
protected static final boolean DEBUG = Debug.debug("GLDrawable");
@@ -52,7 +58,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
this.factory = factory;
this.surface = comp;
this.realized = realized;
- this.requestedCapabilities = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getNativeGraphicsConfiguration().getRequestedCapabilities();
+ this.requestedCapabilities = (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getRequestedCapabilities();
}
/**
@@ -79,7 +85,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
}
public final void swapBuffers() throws GLException {
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)surface.getGraphicsConfiguration().getChosenCapabilities();
if ( caps.getDoubleBuffered() ) {
if(!surface.surfaceSwap()) {
int lockRes = lockSurface(); // it's recursive, so it's ok within [makeCurrent .. release]
@@ -114,7 +120,7 @@ public abstract class GLDrawableImpl implements GLDrawable {
}
public GLCapabilitiesImmutable getChosenGLCapabilities() {
- return (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ return (GLCapabilitiesImmutable) surface.getGraphicsConfiguration().getChosenCapabilities();
}
public GLCapabilitiesImmutable getRequestedGLCapabilities() {
@@ -125,7 +131,10 @@ public abstract class GLDrawableImpl implements GLDrawable {
return surface;
}
+ /** called with locked surface @ setRealized(false) */
protected void destroyHandle() {}
+
+ /** called with locked surface @ setRealized(true) or @ lockSurface(..) when surface changed */
protected void updateHandle() {}
public long getHandle() {
diff --git a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
index 318d00637..6e2b7b744 100644
--- a/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
+++ b/src/jogl/classes/jogamp/opengl/GLGraphicsConfigurationUtil.java
@@ -29,6 +29,7 @@
package jogamp.opengl;
import java.util.ArrayList;
+
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -86,6 +87,7 @@ public class GLGraphicsConfigurationUtil {
return getWinAttributeBits(caps.isOnscreen(), caps.isPBuffer());
}
+ @SuppressWarnings({ "rawtypes", "unchecked" })
public static final boolean addGLCapabilitiesPermutations(ArrayList capsBucket, GLCapabilitiesImmutable temp, int winattrbits) {
int preSize = capsBucket.size();
if( 0 != ( WINDOW_BIT & winattrbits ) ) {
@@ -138,7 +140,7 @@ public class GLGraphicsConfigurationUtil {
if( capsRequested.getDoubleBuffered() || capsRequested.isOnscreen() || !capsRequested.isPBuffer()) {
// fix caps ..
GLCapabilities caps2 = (GLCapabilities) capsRequested.cloneMutable();
- caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN
+ caps2.setDoubleBuffered(false); // FIXME DBLBUFOFFSCRN - we don't need to be single buffered ..
caps2.setOnscreen(false);
caps2.setPBuffer(true);
return caps2;
diff --git a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
index d667fa53a..10d5a3f27 100644
--- a/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
+++ b/src/jogl/classes/jogamp/opengl/GLPbufferImpl.java
@@ -42,6 +42,8 @@ package jogamp.opengl;
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GL;
import javax.media.opengl.GLAnimatorControl;
@@ -70,7 +72,7 @@ public class GLPbufferImpl implements GLPbuffer {
public GLPbufferImpl(GLDrawableImpl pbufferDrawable,
GLContext parentContext) {
GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
- pbufferDrawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ pbufferDrawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
if(caps.isOnscreen()) {
if(caps.isPBuffer()) {
throw new IllegalArgumentException("Error: Given drawable is Onscreen and Pbuffer: "+pbufferDrawable);
@@ -97,26 +99,25 @@ public class GLPbufferImpl implements GLPbuffer {
return true;
}
- class DisposeAction implements Runnable {
- public void run() {
- // Lock: Covered by DestroyAction ..
- drawableHelper.dispose(GLPbufferImpl.this);
- }
- }
- DisposeAction disposeAction = new DisposeAction();
-
public void destroy() {
if(pbufferDrawable.isRealized()) {
+ final AbstractGraphicsDevice adevice = pbufferDrawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice();
+
if (null != context && context.isCreated()) {
try {
- drawableHelper.invokeGL(pbufferDrawable, context, disposeAction, null);
+ drawableHelper.disposeGL(GLPbufferImpl.this, pbufferDrawable, context, null);
} catch (GLException gle) {
gle.printStackTrace();
}
- context.destroy();
+ context = null;
// drawableHelper.reset();
}
pbufferDrawable.destroy();
+ pbufferDrawable = null;
+
+ if(null != adevice) {
+ adevice.close();
+ }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
index 2c396e265..a33e03a1a 100644
--- a/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
+++ b/src/jogl/classes/jogamp/opengl/SharedResourceRunner.java
@@ -44,24 +44,28 @@ public class SharedResourceRunner implements Runnable {
}
public static interface Implementation {
+ /**
+ * @param connection for creation a {@link AbstractGraphicsDevice} instance.
+ * @return A new shared resource instance
+ */
Resource createSharedResource(String connection);
void releaseSharedResource(Resource shared);
void clear();
Resource mapPut(String connection, Resource resource);
Resource mapGet(String connection);
- Collection/*<Resource>*/ mapValues();
+ Collection<Resource> mapValues();
}
- Implementation impl = null;
+ final HashSet<String> devicesTried = new HashSet<String>();
+ final Implementation impl;
- boolean ready = false;
- boolean released = false;
- boolean shouldRelease = false;
- String initConnection = null;
- String releaseConnection = null;
-
- HashSet devicesTried = new HashSet();
+ Thread thread;
+ boolean ready;
+ boolean released;
+ boolean shouldRelease;
+ String initConnection;
+ String releaseConnection;
private boolean getDeviceTried(String connection) {
synchronized (devicesTried) {
@@ -81,22 +85,82 @@ public class SharedResourceRunner implements Runnable {
public SharedResourceRunner(Implementation impl) {
this.impl = impl;
+ resetState();
+ }
+
+ private void resetState() {
+ devicesTried.clear();
+ thread = null;
+ ready = false;
+ released = false;
+ shouldRelease = false;
+ initConnection = null;
+ releaseConnection = null;
}
+ /**
+ * Start the shared resource runner thread, if not running.
+ * <p>
+ * Validate the thread upfront and release all related resource if it was killed.
+ * </p>
+ *
+ * @return the shared resource runner thread.
+ */
+ public Thread start() {
+ if(null != thread && !thread.isAlive()) {
+ // thread was killed unrecognized ..
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.start() - dead-old-thread cleanup - "+Thread.currentThread().getName());
+ }
+ releaseSharedResources();
+ thread = null;
+ }
+ if(null == thread) {
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.start() - start new Thread - "+Thread.currentThread().getName());
+ }
+ resetState();
+ thread = new Thread(this, Thread.currentThread().getName()+"-SharedResourceRunner");
+ thread.setDaemon(true); // Allow JVM to exit, even if this one is running
+ thread.start();
+ }
+ return thread;
+ }
+
+ public void stop() {
+ if(null != thread) {
+ if (DEBUG) {
+ System.err.println("SharedResourceRunner.stop() - "+Thread.currentThread().getName());
+ }
+ synchronized (this) {
+ shouldRelease = true;
+ this.notifyAll();
+
+ while (!released) {
+ try {
+ this.wait();
+ } catch (InterruptedException ex) {
+ }
+ }
+ }
+ }
+ }
+
public SharedResourceRunner.Resource getOrCreateShared(AbstractGraphicsDevice device) {
SharedResourceRunner.Resource sr = null;
if(null != device) {
- String connection = device.getConnection();
+ start();
+ final String connection = device.getConnection();
sr = impl.mapGet(connection);
if (null == sr && !getDeviceTried(connection)) {
addDeviceTried(connection);
if (DEBUG) {
- System.err.println("getOrCreateShared() " + connection + ": trying");
+ System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": trying - "+Thread.currentThread().getName());
}
doAndWait(connection, null);
sr = impl.mapGet(connection);
if (DEBUG) {
- System.err.println("getOrCreateShared() " + connection + ": "+ ( ( null != sr ) ? "success" : "failed" ) );
+ System.err.println("SharedResourceRunner.getOrCreateShared() " + connection + ": "+ ( ( null != sr ) ? "success" : "failed" ) +" - "+Thread.currentThread().getName());
}
}
}
@@ -111,11 +175,11 @@ public class SharedResourceRunner implements Runnable {
if (null != sr) {
removeDeviceTried(connection);
if (DEBUG) {
- System.err.println("releaseShared() " + connection + ": trying");
+ System.err.println("SharedResourceRunner.releaseShared() " + connection + ": trying - "+Thread.currentThread().getName());
}
doAndWait(null, connection);
if (DEBUG) {
- System.err.println("releaseShared() " + connection + ": done");
+ System.err.println("SharedResourceRunner.releaseShared() " + connection + ": done - "+Thread.currentThread().getName());
}
}
}
@@ -125,9 +189,9 @@ public class SharedResourceRunner implements Runnable {
private final void doAndWait(String initConnection, String releaseConnection) {
// wait until thread becomes ready to init new device,
// pass the device and release the sync
- String threadName = Thread.currentThread().getName();
+ final String threadName = Thread.currentThread().getName();
if (DEBUG) {
- System.err.println(threadName + " doAndWait START init: " + initConnection + ", release: "+releaseConnection);
+ System.err.println("SharedResourceRunner.doAndWait() START init: " + initConnection + ", release: "+releaseConnection+" - "+threadName);
}
synchronized (this) {
while (!ready) {
@@ -137,7 +201,7 @@ public class SharedResourceRunner implements Runnable {
}
}
if (DEBUG) {
- System.err.println(threadName + " initializeAndWait set command init: " + initConnection + ", release: "+releaseConnection);
+ System.err.println("SharedResourceRunner.doAndWait() set command: " + initConnection + ", release: "+releaseConnection+" - "+threadName);
}
this.initConnection = initConnection;
this.releaseConnection = releaseConnection;
@@ -151,31 +215,17 @@ public class SharedResourceRunner implements Runnable {
}
}
if (DEBUG) {
- System.err.println(threadName + " initializeAndWait END init: " + initConnection + ", release: "+releaseConnection);
+ System.err.println("SharedResourceRunner.initializeAndWait END init: " + initConnection + ", release: "+releaseConnection+" - "+threadName);
}
}
// done
}
- public final void releaseAndWait() {
- synchronized (this) {
- shouldRelease = true;
- this.notifyAll();
-
- while (!released) {
- try {
- this.wait();
- } catch (InterruptedException ex) {
- }
- }
- }
- }
-
public final void run() {
- String threadName = Thread.currentThread().getName();
+ final String threadName = Thread.currentThread().getName();
if (DEBUG) {
- System.err.println(threadName + " STARTED");
+ System.err.println("SharedResourceRunner.run(): STARTED - " + threadName);
}
synchronized (this) {
@@ -184,21 +234,27 @@ public class SharedResourceRunner implements Runnable {
// wait for stop or init
ready = true;
if (DEBUG) {
- System.err.println(threadName + " -> ready");
+ System.err.println("SharedResourceRunner.run(): READY - " + threadName);
}
notifyAll();
this.wait();
- } catch (InterruptedException ex) { }
+ } catch (InterruptedException ex) {
+ shouldRelease = true;
+ if(DEBUG) {
+ System.err.println("SharedResourceRunner.run(): INTERRUPTED - "+Thread.currentThread().getName());
+ ex.printStackTrace();
+ }
+ }
ready = false;
if (!shouldRelease) {
if (DEBUG) {
- System.err.println(threadName + " woke up for device connection init: " + initConnection +
- ", release: " + releaseConnection);
+ System.err.println("SharedResourceRunner.run(): WOKE UP for device connection init: " + initConnection +
+ ", release: " + releaseConnection + " - " + threadName);
}
if(null != initConnection) {
if (DEBUG) {
- System.err.println(threadName + " create Shared for: " + initConnection);
+ System.err.println("SharedResourceRunner.run(): create Shared for: " + initConnection + " - " + threadName);
}
Resource sr = null;
try {
@@ -212,7 +268,7 @@ public class SharedResourceRunner implements Runnable {
}
if(null != releaseConnection) {
if (DEBUG) {
- System.err.println(threadName + " release Shared for: " + releaseConnection);
+ System.err.println("SharedResourceRunner.run(): release Shared for: " + releaseConnection + " - " + threadName);
}
Resource sr = impl.mapGet(releaseConnection);
if (null != sr) {
@@ -230,26 +286,34 @@ public class SharedResourceRunner implements Runnable {
}
if (DEBUG) {
- System.err.println(threadName + " release START");
+ System.err.println("SharedResourceRunner.run(): RELEASE START - " + threadName);
}
releaseSharedResources();
if (DEBUG) {
- System.err.println(threadName + " release END");
+ System.err.println("SharedResourceRunner.run(): RELEASE END - " + threadName);
}
+ shouldRelease = false;
released = true;
- ready = false;
+ thread = null;
notifyAll();
}
}
private void releaseSharedResources() {
- Collection/*<Resource>*/ sharedResources = impl.mapValues();
- for (Iterator iter = sharedResources.iterator(); iter.hasNext();) {
- Resource sr = (Resource) iter.next();
- impl.releaseSharedResource(sr);
+ synchronized (devicesTried) {
+ devicesTried.clear();
+ }
+ Collection<Resource> sharedResources = impl.mapValues();
+ for (Iterator<Resource> iter = sharedResources.iterator(); iter.hasNext();) {
+ try {
+ impl.releaseSharedResource(iter.next());
+ } catch (Throwable t) {
+ System.err.println("Catched Exception: "+t.getStackTrace()+" - "+Thread.currentThread().getName());
+ t.printStackTrace();
+ }
}
impl.clear();
}
diff --git a/src/jogl/classes/jogamp/opengl/awt/Java2D.java b/src/jogl/classes/jogamp/opengl/awt/Java2D.java
index e240169e1..3e4a6a147 100644
--- a/src/jogl/classes/jogamp/opengl/awt/Java2D.java
+++ b/src/jogl/classes/jogamp/opengl/awt/Java2D.java
@@ -39,23 +39,32 @@
package jogamp.opengl.awt;
-import jogamp.opengl.*;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.awt.HeadlessException;
+import java.awt.Rectangle;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.Debug;
-import java.awt.*;
-import java.awt.image.*;
-import java.lang.reflect.*;
-import java.security.*;
-
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.awt.*;
/** Defines integration with the Java2D OpenGL pipeline. This
integration is only supported in 1.6 and is highly experimental. */
public class Java2D {
private static boolean DEBUG = Debug.debug("Java2D");
- private static boolean VERBOSE = Debug.verbose();
private static boolean isHeadless;
private static boolean isOGLPipelineActive;
private static Method invokeWithOGLContextCurrentMethod;
@@ -103,9 +112,9 @@ public class Java2D {
private static Method destroyOGLContextMethod;
static {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("Checking for Java2D/OpenGL support");
}
try {
@@ -119,7 +128,7 @@ public class Java2D {
// If we get here, we aren't running in headless mode
isHeadless = false;
String name = cfg.getClass().getName();
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("Java2D support: default GraphicsConfiguration = " + name);
}
isOGLPipelineActive = (name.startsWith("sun.java2d.opengl"));
@@ -127,7 +136,7 @@ public class Java2D {
if (isOGLPipelineActive) {
try {
// Try to get methods we need to integrate
- Class utils = Class.forName("sun.java2d.opengl.OGLUtilities");
+ Class<?> utils = Class.forName("sun.java2d.opengl.OGLUtilities");
invokeWithOGLContextCurrentMethod = utils.getDeclaredMethod("invokeWithOGLContextCurrent",
new Class[] {
Graphics.class,
@@ -176,7 +185,7 @@ public class Java2D {
getOGLSurfaceTypeMethod.setAccessible(true);
} catch (Exception e) {
fbObjectSupportInitialized = false;
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
e.printStackTrace();
System.err.println("Info: Disabling Java2D/JOGL FBO support");
}
@@ -190,7 +199,7 @@ public class Java2D {
});
getOGLTextureTypeMethod.setAccessible(true);
} catch (Exception e) {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
e.printStackTrace();
System.err.println("Info: GL_ARB_texture_rectangle FBO support disabled");
}
@@ -199,11 +208,11 @@ public class Java2D {
// Try to set up APIs for enabling the bridge on OS X,
// where it isn't possible to create generalized
// external GLDrawables
- Class cglSurfaceData = null;
+ Class<?> cglSurfaceData = null;
try {
cglSurfaceData = Class.forName("sun.java2d.opengl.CGLSurfaceData");
} catch (Exception e) {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
e.printStackTrace();
System.err.println("Info: Unable to find class sun.java2d.opengl.CGLSurfaceData for OS X");
}
@@ -234,7 +243,7 @@ public class Java2D {
destroyOGLContextMethod.setAccessible(true);
}
} catch (Exception e) {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
e.printStackTrace();
System.err.println("Info: Disabling Java2D/JOGL integration");
}
@@ -513,15 +522,15 @@ public class Java2D {
}
private static int getOGLUtilitiesIntField(final String name) {
- Integer i = (Integer) AccessController.doPrivileged(new PrivilegedAction() {
- public Object run() {
+ Integer i = AccessController.doPrivileged(new PrivilegedAction<Integer>() {
+ public Integer run() {
try {
- Class utils = Class.forName("sun.java2d.opengl.OGLUtilities");
+ Class<?> utils = Class.forName("sun.java2d.opengl.OGLUtilities");
Field f = utils.getField(name);
f.setAccessible(true);
- return f.get(null);
+ return (Integer) f.get(null);
} catch (Exception e) {
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
e.printStackTrace();
}
return null;
@@ -530,7 +539,7 @@ public class Java2D {
});
if (i == null)
return 0;
- if (DEBUG && VERBOSE) {
+ if (DEBUG) {
System.err.println("OGLUtilities." + name + " = " + i.intValue());
}
return i.intValue();
diff --git a/src/jogl/classes/jogamp/opengl/awt/VersionApplet.java b/src/jogl/classes/jogamp/opengl/awt/VersionApplet.java
index 5856bf3a0..55fb3f9a2 100644
--- a/src/jogl/classes/jogamp/opengl/awt/VersionApplet.java
+++ b/src/jogl/classes/jogamp/opengl/awt/VersionApplet.java
@@ -67,6 +67,8 @@ public class VersionApplet extends Applet {
private synchronized void my_init() {
if(null != canvas) { return; }
+ setEnabled(true);
+
GLProfile glp = GLProfile.getDefault();
GLCapabilities glcaps = new GLCapabilities(glp);
@@ -120,8 +122,10 @@ public class VersionApplet extends Applet {
remove(canvas);
canvas.destroy();
canvas = null;
- remove(tareaVersion);
- tareaVersion=null;
+ remove(tareaVersion.getParent()); // remove the grid
+ tareaVersion = null;
+ tareaCaps = null;
+ setEnabled(false);
}
}
@@ -133,11 +137,13 @@ public class VersionApplet extends Applet {
public void start() {
System.err.println("VersionApplet: start() - begin");
+ canvas.setVisible(true);
System.err.println("VersionApplet: start() - end");
}
public void stop() {
System.err.println("VersionApplet: stop() - begin");
+ canvas.setVisible(false);
System.err.println("VersionApplet: stop() - end");
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
index 0ec913e31..62ee20f92 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLContext.java
@@ -35,17 +35,20 @@
package jogamp.opengl.egl;
-import javax.media.opengl.*;
+import java.nio.ByteBuffer;
+import java.util.Map;
-import jogamp.opengl.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableImpl;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
-import java.nio.*;
-import java.util.*;
-
-import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.AbstractGraphicsDevice;
public abstract class EGLContext extends GLContextImpl {
private boolean eglQueryStringInitialized;
@@ -95,7 +98,7 @@ public abstract class EGLContext extends GLContextImpl {
return true;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
if(EGL.EGL_NO_DISPLAY==((EGLDrawable)drawable).getDisplay() ) {
throw new GLException("drawable not properly initialized, NO DISPLAY: "+drawable);
}
@@ -135,12 +138,12 @@ public abstract class EGLContext extends GLContextImpl {
// FIXME
}
- protected boolean createImpl() throws GLException {
+ protected boolean createImpl(GLContextImpl shareWith) throws GLException {
long eglDisplay = ((EGLDrawable)drawable).getDisplay();
EGLGraphicsConfiguration config = ((EGLDrawable)drawable).getGraphicsConfiguration();
GLProfile glProfile = drawable.getGLProfile();
long eglConfig = config.getNativeConfig();
- long shareWith = EGL.EGL_NO_CONTEXT;
+ long shareWithHandle = EGL.EGL_NO_CONTEXT;
if (eglDisplay == 0) {
throw new GLException("Error: attempted to create an OpenGL context without a display connection");
@@ -160,10 +163,9 @@ public abstract class EGLContext extends GLContextImpl {
}
}
- EGLContext other = (EGLContext) GLContextShareSet.getShareContext(this);
- if (other != null) {
- shareWith = other.getHandle();
- if (shareWith == 0) {
+ if (shareWith != null) {
+ shareWithHandle = shareWith.getHandle();
+ if (shareWithHandle == 0) {
throw new GLException("GLContextShareSet returned an invalid OpenGL context");
}
}
@@ -179,10 +181,10 @@ public abstract class EGLContext extends GLContextImpl {
} else {
throw new GLException("Error creating OpenGL context - invalid GLProfile: "+glProfile);
}
- contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWith, contextAttrs, 0);
+ contextHandle = EGL.eglCreateContext(eglDisplay, eglConfig, shareWithHandle, contextAttrs, 0);
if (contextHandle == 0) {
throw new GLException("Error creating OpenGL context: eglDisplay "+toHexString(eglDisplay)+
- ", eglConfig "+config+", "+glProfile+", shareWith "+toHexString(shareWith)+", error "+toHexString(EGL.eglGetError()));
+ ", eglConfig "+config+", "+glProfile+", shareWith "+toHexString(shareWithHandle)+", error "+toHexString(EGL.eglGetError()));
}
if (DEBUG) {
System.err.println(getThreadName() + ": !!! Created OpenGL context 0x" +
@@ -190,7 +192,7 @@ public abstract class EGLContext extends GLContextImpl {
",\n\twrite surface 0x" + Long.toHexString(drawable.getHandle()) +
",\n\tread surface 0x" + Long.toHexString(drawableRead.getHandle())+
",\n\t"+this+
- ",\n\tsharing with 0x" + Long.toHexString(shareWith));
+ ",\n\tsharing with 0x" + Long.toHexString(shareWithHandle));
}
if (!EGL.eglMakeCurrent(((EGLDrawable)drawable).getDisplay(),
drawable.getHandle(),
@@ -207,12 +209,12 @@ public abstract class EGLContext extends GLContextImpl {
} else {
major = 1;
}
- setGLFunctionAvailability(true, true, major, 0, ctp);
+ setGLFunctionAvailability(true, major, 0, ctp);
return true;
}
protected final void updateGLXProcAddressTable() {
- final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "EGL-"+adevice.getUniqueID();
if (DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
index a9cc40335..14a0a40cd 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawable.java
@@ -99,7 +99,7 @@ public abstract class EGLDrawable extends GLDrawableImpl {
protected void setRealizedImpl() {
if (realized) {
- AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration aConfig = surface.getGraphicsConfiguration();
AbstractGraphicsDevice aDevice = aConfig.getScreen().getDevice();
if(aDevice instanceof EGLGraphicsDevice) {
if(DEBUG) {
@@ -197,6 +197,16 @@ public abstract class EGLDrawable extends GLDrawableImpl {
}
}
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!EGL.eglSwapBuffers(eglDisplay, eglSurface)) {
+ if(DEBUG) {
+ System.err.println("eglSwapBuffers failed:");
+ Thread.dumpStack();
+ }
+ }
+ }
+
public int getWidth() {
int[] tmp = new int[1];
if (!EGL.eglQuerySurface(eglDisplay, eglSurface, EGL.EGL_WIDTH, tmp, 0)) {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
index 79d96bdb6..cd6d61a22 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDrawableFactory.java
@@ -39,6 +39,7 @@ package jogamp.opengl.egl;
import javax.media.nativewindow.*;
import javax.media.nativewindow.egl.EGLGraphicsDevice;
import javax.media.opengl.*;
+import javax.media.opengl.GLProfile.ShutdownType;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.*;
@@ -50,13 +51,15 @@ import java.util.HashMap;
import java.util.List;
public class EGLDrawableFactory extends GLDrawableFactoryImpl {
- private static final GLDynamicLookupHelper eglES1DynamicLookupHelper;
- private static final GLDynamicLookupHelper eglES2DynamicLookupHelper;
-
- static {
+ private static GLDynamicLookupHelper eglES1DynamicLookupHelper = null;
+ private static GLDynamicLookupHelper eglES2DynamicLookupHelper = null;
+
+ public EGLDrawableFactory() {
+ super();
+
// Register our GraphicsConfigurationFactory implementations
// The act of constructing them causes them to be registered
- new EGLGraphicsConfigurationFactory();
+ EGLGraphicsConfigurationFactory.registerFactory();
// Check for other underlying stuff ..
if(NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
@@ -69,38 +72,69 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
// to a dynamic one, where there can be 2 instances
// for each ES profile with their own ProcAddressTable.
- GLDynamicLookupHelper tmp=null;
- try {
- tmp = new GLDynamicLookupHelper(new EGLES1DynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
+ synchronized(EGLDrawableFactory.class) {
+ if(null==eglES1DynamicLookupHelper) {
+ GLDynamicLookupHelper tmp=null;
+ try {
+ tmp = new GLDynamicLookupHelper(new EGLES1DynamicLibraryBundleInfo());
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ eglES1DynamicLookupHelper = tmp;
+ if(null!=eglES1DynamicLookupHelper && eglES1DynamicLookupHelper.isLibComplete()) {
+ EGL.resetProcAddressTable(eglES1DynamicLookupHelper);
+ }
}
}
- eglES1DynamicLookupHelper = tmp;
- if(null!=eglES1DynamicLookupHelper && eglES1DynamicLookupHelper.isLibComplete()) {
- EGL.resetProcAddressTable(eglES1DynamicLookupHelper);
- }
- tmp=null;
- try {
- tmp = new GLDynamicLookupHelper(new EGLES2DynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
+ synchronized(EGLDrawableFactory.class) {
+ if(null==eglES2DynamicLookupHelper) {
+ GLDynamicLookupHelper tmp=null;
+ try {
+ tmp = new GLDynamicLookupHelper(new EGLES2DynamicLibraryBundleInfo());
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ eglES2DynamicLookupHelper = tmp;
+ if(null!=eglES2DynamicLookupHelper && eglES2DynamicLookupHelper.isLibComplete()) {
+ EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
+ }
}
}
- eglES2DynamicLookupHelper = tmp;
- if(null!=eglES2DynamicLookupHelper && eglES2DynamicLookupHelper.isLibComplete()) {
- EGL.resetProcAddressTable(eglES2DynamicLookupHelper);
+ if(null != eglES1DynamicLookupHelper || null != eglES2DynamicLookupHelper) {
+ defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedMap = new HashMap();
}
}
- public EGLDrawableFactory() {
- super();
- defaultDevice = new EGLGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ protected final void destroy(ShutdownType shutdownType) {
+ if(null != sharedMap) {
+ sharedMap.clear();
+ sharedMap = null;
+ }
+ defaultDevice = null;
+ /**
+ * Pulling away the native library may cause havoc ..
+ *
+ if(ShutdownType.COMPLETE == shutdownType) {
+ if(null != eglES1DynamicLookupHelper) {
+ eglES1DynamicLookupHelper.destroy();
+ eglES1DynamicLookupHelper = null;
+ }
+ if(null != eglES2DynamicLookupHelper) {
+ eglES2DynamicLookupHelper.destroy();
+ eglES2DynamicLookupHelper = null;
+ }
+ } */
}
+ private HashMap/*<connection, SharedResource>*/ sharedMap;
+ private EGLGraphicsDevice defaultDevice;
+
static class SharedResource {
private EGLGraphicsDevice device;
// private EGLDrawable drawable;
@@ -125,8 +159,6 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
final boolean wasES1ContextAvailable() { return wasES1ContextCreated; }
final boolean wasES2ContextAvailable() { return wasES2ContextCreated; }
}
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- EGLGraphicsDevice defaultDevice;
public final AbstractGraphicsDevice getDefaultDevice() {
return defaultDevice;
@@ -200,10 +232,21 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
return sr;
}
- public final boolean getWasSharedContextCreated(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateEGLSharedResource(device);
- if(null!=sr) {
- return sr.wasES1ContextAvailable() || sr.wasES2ContextAvailable();
+ protected final Thread getSharedResourceThread() {
+ return null;
+ }
+
+ protected final boolean createSharedResource(AbstractGraphicsDevice device) {
+ try {
+ SharedResource sr = getOrCreateEGLSharedResource(device);
+ if(null!=sr) {
+ return sr.wasES1ContextAvailable() || sr.wasES2ContextAvailable();
+ }
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("Catched Exception while EGL Shared Resource initialization");
+ gle.printStackTrace();
+ }
}
return false;
}
@@ -236,8 +279,6 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
}
}
- protected final void shutdownInstance() {}
-
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
return EGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
}
@@ -253,7 +294,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration();
GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(!caps.isPBuffer()) {
throw new GLException("Non pbuffer not yet implemented");
@@ -268,7 +309,7 @@ public class EGLDrawableFactory extends GLDrawableFactoryImpl {
protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device, GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
WrappedSurface ns = new WrappedSurface(EGLGraphicsConfigurationFactory.createOffscreenGraphicsConfiguration(device, capsChosen, capsRequested, chooser));
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return ns;
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
index 33154b089..1f9254b49 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLDynamicLibraryBundleInfo.java
@@ -29,18 +29,11 @@
package jogamp.opengl.egl;
import com.jogamp.common.os.AndroidVersion;
-import com.jogamp.common.os.DynamicLookupHelper;
-import com.jogamp.common.os.NativeLibrary;
-import com.jogamp.common.os.Platform;
import java.util.*;
-import javax.media.nativewindow.*;
-import javax.media.opengl.*;
import jogamp.opengl.*;
-import java.security.*;
-
/**
* Abstract implementation of the DynamicLookupHelper for EGL,
* which decouples it's dependencies to EGLDrawable.
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
index 3b0fc5957..63109f445 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES1DynamicLibraryBundleInfo.java
@@ -30,10 +30,6 @@ package jogamp.opengl.egl;
import java.util.*;
-import com.jogamp.common.os.Platform;
-
-import jogamp.opengl.*;
-
public class EGLES1DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
protected EGLES1DynamicLibraryBundleInfo() {
super();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
index 28c480b0c..b0748ad10 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLES2DynamicLibraryBundleInfo.java
@@ -30,10 +30,6 @@ package jogamp.opengl.egl;
import java.util.*;
-import com.jogamp.common.os.Platform;
-
-import jogamp.opengl.*;
-
public class EGLES2DynamicLibraryBundleInfo extends EGLDynamicLibraryBundleInfo {
protected EGLES2DynamicLibraryBundleInfo() {
super();
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
index 389daa7ca..796a4311b 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLExternalContext.java
@@ -45,7 +45,7 @@ public class EGLExternalContext extends EGLContext {
public EGLExternalContext(AbstractGraphicsScreen screen) {
super(null, null);
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, true, 0, 0, CTX_IS_ARB_CREATED|CTX_PROFILE_ES|CTX_OPTION_ANY);
+ setGLFunctionAvailability(false, 0, 0, CTX_IS_ARB_CREATED|CTX_PROFILE_ES|CTX_OPTION_ANY);
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
@@ -66,7 +66,7 @@ public class EGLExternalContext extends EGLContext {
lastContext = null;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
}
protected void releaseImpl() throws GLException {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
index 4fb3dca78..ea625fb27 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfiguration.java
@@ -38,15 +38,25 @@ package jogamp.opengl.egl;
import java.nio.IntBuffer;
import java.util.ArrayList;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.egl.*;
-import javax.media.opengl.*;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.egl.EGLGraphicsDevice;
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.MutableGraphicsConfiguration;
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.nio.Buffers;
import com.jogamp.common.nio.PointerBuffer;
-import jogamp.opengl.*;
-public class EGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class EGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
public final long getNativeConfig() {
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
index 74f7d884b..ceeebe60b 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLGraphicsConfigurationFactory.java
@@ -69,9 +69,11 @@ import java.nio.IntBuffer;
public class EGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
static EGLGLCapabilities.EglCfgIDComparator EglCfgIDComparator = new EGLGLCapabilities.EglCfgIDComparator();
- EGLGraphicsConfigurationFactory() {
+ static void registerFactory() {
// become the selector for KD/EGL ..
- GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.egl.EGLGraphicsDevice.class, this);
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.egl.EGLGraphicsDevice.class, new EGLGraphicsConfigurationFactory());
+ }
+ private EGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl (
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
index 7d5e0448d..42f067b29 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLOnscreenDrawable.java
@@ -55,15 +55,5 @@ public class EGLOnscreenDrawable extends EGLDrawable {
protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
return EGL.eglCreateWindowSurface(eglDpy, eglNativeCfg, surfaceHandle, null);
}
-
- protected void swapBuffersImpl() {
- if(!EGL.eglSwapBuffers(eglDisplay, eglSurface)) {
- if(DEBUG) {
- System.err.println("eglSwapBuffers failed:");
- Thread.dumpStack();
- }
- }
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
index 5fb32e6cd..28a23d294 100644
--- a/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/egl/EGLPbufferDrawable.java
@@ -40,48 +40,39 @@
package jogamp.opengl.egl;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.SurfaceChangeable;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
-import jogamp.opengl.x11.glx.GLX;
-
public class EGLPbufferDrawable extends EGLDrawable {
private int texFormat;
protected static final boolean useTexture = false; // No yet ..
protected EGLPbufferDrawable(EGLDrawableFactory factory, NativeSurface target) {
super(factory, target);
+ }
- // get choosen ones ..
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)
- getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
+ protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
+ final AbstractGraphicsConfiguration config = getNativeSurface().getGraphicsConfiguration();
+ final GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(useTexture) {
- this.texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
+ texFormat = caps.getAlphaBits() > 0 ? EGL.EGL_TEXTURE_RGBA : EGL.EGL_TEXTURE_RGB ;
} else {
- this.texFormat = EGL.EGL_NO_TEXTURE;
+ texFormat = EGL.EGL_NO_TEXTURE;
}
if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
- }
-
- setRealized(true);
-
- if (DEBUG) {
- System.out.println("Created pbuffer: " + this);
+ System.out.println("Pbuffer config: " + config);
}
- }
-
- protected void destroyImpl() {
- setRealized(false);
- }
-
- protected long createSurface(long eglDpy, long eglNativeCfg, long surfaceHandle) {
NativeSurface nw = getNativeSurface();
int[] attrs = EGLGraphicsConfiguration.CreatePBufferSurfaceAttribList(nw.getWidth(), nw.getHeight(), texFormat);
long surf = EGL.eglCreatePbufferSurface(eglDpy, eglNativeCfg, attrs, 0);
@@ -97,11 +88,5 @@ public class EGLPbufferDrawable extends EGLDrawable {
public GLContext createContext(GLContext shareWith) {
return new EGLPbufferContext(this, shareWith);
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
index 1fe47f60b..0dd1a460e 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java
@@ -45,14 +45,15 @@ import java.util.Map;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.OffscreenLayerSurface;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
import jogamp.opengl.GLContextImpl;
-import jogamp.opengl.GLContextShareSet;
import jogamp.opengl.GLDrawableImpl;
import jogamp.opengl.GLGraphicsConfigurationUtil;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -63,7 +64,6 @@ import com.jogamp.common.util.VersionNumber;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
-
public abstract class MacOSXCGLContext extends GLContextImpl
{
// Abstract interface for implementation of this context (either
@@ -76,7 +76,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
boolean makeCurrent(long ctx);
boolean release(long ctx);
boolean setSwapInterval(int interval);
- boolean swapBuffers(boolean isOnscreen);
+ boolean swapBuffers();
}
/* package */ static final boolean isTigerOrLater;
@@ -95,7 +95,12 @@ public abstract class MacOSXCGLContext extends GLContextImpl
// We exclude 3.0, since we would map it's core to GL2. Hence we force mapping 2.1 to GL2
if(3==major && 1<=minor && minor<=2) {
// [3.1..3.2] -> GL3*
+ if(!isLionOrLater) {
+ // no GL3* on pre lion
+ return false;
+ }
if(ctBwdCompat) {
+ // no compatibility profile on OS X
return false;
}
return ctCore;
@@ -203,44 +208,43 @@ public abstract class MacOSXCGLContext extends GLContextImpl
return false;
}
- protected long createImplPreset() throws GLException {
- MacOSXCGLContext other = (MacOSXCGLContext) GLContextShareSet.getShareContext(this);
+ protected long createImplPreset(GLContextImpl shareWith) throws GLException {
long share = 0;
- if (other != null) {
+ if (shareWith != null) {
// Change our OpenGL mode to match that of any share context before we create ourselves
- setOpenGLMode(other.getOpenGLMode());
- share = other.getHandle();
+ setOpenGLMode(((MacOSXCGLContext)shareWith).getOpenGLMode());
+ share = shareWith.getHandle();
if (share == 0) {
throw new GLException("GLContextShareSet returned a NULL OpenGL context");
}
}
- MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+
+ MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
GLCapabilitiesImmutable capabilitiesChosen = (GLCapabilitiesImmutable) config.getChosenCapabilities();
- if (capabilitiesChosen.getPbufferFloatingPointBuffers() &&
- !isTigerOrLater) {
+ if (capabilitiesChosen.getPbufferFloatingPointBuffers() && !isTigerOrLater) {
throw new GLException("Floating-point pbuffers supported only on OS X 10.4 or later");
}
GLProfile glp = capabilitiesChosen.getGLProfile();
if(glp.isGLES1() || glp.isGLES2() || glp.isGL4() || glp.isGL3() && !isLionOrLater) {
throw new GLException("OpenGL profile not supported on MacOSX "+Platform.getOSVersionNumber()+": "+glp);
}
+
if (DEBUG) {
System.err.println("!!! Share context is " + toHexString(share) + " for " + this);
}
- return share;
+ return share;
}
-
- protected boolean createImpl() throws GLException {
- long share = createImplPreset();
+
+ protected boolean createImpl(GLContextImpl shareWith) throws GLException {
+ long share = createImplPreset(shareWith);
contextHandle = createContextARB(share, true);
return 0 != contextHandle;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
if (getOpenGLMode() != ((MacOSXCGLDrawable)drawable).getOpenGLMode()) {
setOpenGLMode(((MacOSXCGLDrawable)drawable).getOpenGLMode());
}
-
if (!impl.makeCurrent(contextHandle)) {
throw new GLException("Error making Context current: "+this);
}
@@ -268,9 +272,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
protected void swapBuffers() {
- DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- if(!impl.swapBuffers(caps.isOnscreen())) {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ if(!impl.swapBuffers()) {
throw new GLException("Error swapping buffers: "+this);
}
}
@@ -282,12 +285,6 @@ public abstract class MacOSXCGLContext extends GLContextImpl
if(!impl.setSwapInterval(interval)) {
throw new GLException("Error set swap-interval: "+this);
}
- if ( isNSContext() ) {
- CGL.setSwapInterval(contextHandle, interval);
- } else {
- int[] lval = new int[] { (int) interval } ;
- CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
- }
currentSwapInterval = interval ;
}
@@ -297,7 +294,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
protected final void updateGLXProcAddressTable() {
- final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "MacOSX-"+adevice.getUniqueID();
if (DEBUG) {
@@ -403,31 +400,44 @@ public abstract class MacOSXCGLContext extends GLContextImpl
// NSOpenGLContext-based implementation
class NSOpenGLImpl implements GLBackendImpl {
+ long nsOpenGLLayer = 0;
+ long nsOpenGLLayerPFmt = 0;
+
public boolean isNSContext() { return true; }
public long create(long share, int ctp, int major, int minor) {
long ctx = 0;
- MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) MacOSXCGLContext.this.drawable;
+ final NativeSurface surface = drawable.getNativeSurface();
+ final MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) surface.getGraphicsConfiguration();
+ final OffscreenLayerSurface backingLayerHost = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ final GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2NSPixelFormat(chosenCaps, ctp, major, minor);
if (pixelFormat == 0) {
throw new GLException("Unable to allocate pixel format with requested GLCapabilities");
}
config.setChosenPixelFormat(pixelFormat);
+ if(DEBUG) {
+ System.err.println("NS create OSX>=lion "+isLionOrLater);
+ System.err.println("NS create backingLayerHost: "+backingLayerHost);
+ System.err.println("NS create share: "+share);
+ System.err.println("NS create chosenCaps: "+chosenCaps);
+ System.err.println("NS create pixelFormat: "+toHexString(pixelFormat));
+ System.err.println("NS create drawable native-handle: "+toHexString(drawable.getHandle()));
+ System.err.println("NS create drawable NSView-handle: "+toHexString(drawable.getNSViewHandle()));
+ // Thread.dumpStack();
+ }
try {
int[] viewNotReady = new int[1];
// Try to allocate a context with this
ctx = CGL.createContext(share,
- drawable.getHandle(),
+ drawable.getNSViewHandle(), null!=backingLayerHost,
pixelFormat,
chosenCaps.isBackgroundOpaque(),
viewNotReady, 0);
if (0 == ctx) {
- if (viewNotReady[0] == 1) {
- if (DEBUG) {
- System.err.println("!!! View not ready for " + getClass().getName());
- }
- // View not ready at the window system level
+ if(DEBUG) {
+ System.err.println("NS create failed: viewNotReady: "+ (1 == viewNotReady[0]));
}
return 0;
}
@@ -439,22 +449,66 @@ public abstract class MacOSXCGLContext extends GLContextImpl
if(DEBUG) {
GLCapabilitiesImmutable caps0 = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(null, pixelFormat);
- System.err.println("NS created(>=lion "+isLionOrLater+"): "+caps0);
+ System.err.println("NS create pixelformat2GLCaps: "+caps0);
}
- GLCapabilitiesImmutable caps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
- caps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(caps, chosenCaps.isBackgroundOpaque());
- config.setChosenCapabilities(caps);
- if(caps.isPBuffer()) {
+ GLCapabilitiesImmutable fixedCaps = MacOSXCGLGraphicsConfiguration.NSPixelFormat2GLCapabilities(chosenCaps.getGLProfile(), pixelFormat);
+ fixedCaps = GLGraphicsConfigurationUtil.fixOpaqueGLCapabilities(fixedCaps, chosenCaps.isBackgroundOpaque());
+ config.setChosenCapabilities(fixedCaps);
+ if(DEBUG) {
+ System.err.println("NS create fixedCaps: "+fixedCaps);
+ }
+ if(fixedCaps.isPBuffer()) {
// Must now associate the pbuffer with our newly-created context
CGL.setContextPBuffer(ctx, drawable.getHandle());
- }
+ }
+ //
+ // handled layered surface
+ //
+ if(null != backingLayerHost) {
+ nsOpenGLLayerPFmt = pixelFormat;
+ pixelFormat = 0;
+ final int texWidth, texHeight;
+ if(drawable instanceof MacOSXPbufferCGLDrawable) {
+ final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
+ texWidth = osxPDrawable.getTextureWidth();
+ texHeight = osxPDrawable.getTextureHeight();
+ } else {
+ texWidth = drawable.getWidth();
+ texHeight = drawable.getHeight();
+ }
+ nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight);
+ if(0>=texWidth || 0>=texHeight || !drawable.isRealized()) {
+ throw new GLException("Drawable not realized yet or invalid texture size, texSize "+texWidth+"x"+texHeight+", "+drawable);
+ }
+ if (DEBUG) {
+ System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)+", texSize "+texWidth+"x"+texHeight+", "+drawable);
+ }
+ backingLayerHost.attachSurfaceLayer(nsOpenGLLayer);
+ }
} finally {
- CGL.deletePixelFormat(pixelFormat);
+ if(0!=pixelFormat) {
+ CGL.deletePixelFormat(pixelFormat);
+ }
}
return ctx;
}
public boolean destroy(long ctx) {
+ if(0 != nsOpenGLLayer) {
+ final NativeSurface surface = drawable.getNativeSurface();
+ if (DEBUG) {
+ System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer));
+ }
+ final OffscreenLayerSurface ols = NativeWindowFactory.getOffscreenLayerSurface(surface, true);
+ if(null == ols) {
+ throw new InternalError("XXX: "+ols);
+ }
+ CGL.releaseNSOpenGLLayer(nsOpenGLLayer);
+ ols.detachSurfaceLayer(nsOpenGLLayer);
+ CGL.deletePixelFormat(nsOpenGLLayerPFmt);
+ nsOpenGLLayerPFmt = 0;
+ nsOpenGLLayer = 0;
+ }
return CGL.deleteContext(ctx, true);
}
@@ -464,22 +518,54 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
public boolean makeCurrent(long ctx) {
- return CGL.makeCurrentContext(ctx);
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ int err = CGL.CGLLockContext(cglCtx);
+ if(CGL.kCGLNoError == err) {
+ return CGL.makeCurrentContext(ctx);
+ } else if(DEBUG) {
+ System.err.println("NSGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return false;
}
public boolean release(long ctx) {
- return CGL.clearCurrentContext(ctx);
+ gl.glFinish(); // w/o glFinish() OSX < 10.7 (NVidia driver) may freeze
+ final boolean res = CGL.clearCurrentContext(ctx);
+ final long cglCtx = CGL.getCGLContext(ctx);
+ if(0 == cglCtx) {
+ throw new InternalError("Null CGLContext for: "+this);
+ }
+ final int err = CGL.CGLUnlockContext(cglCtx);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return res && CGL.kCGLNoError == err;
}
public boolean setSwapInterval(int interval) {
- CGL.setSwapInterval(contextHandle, interval);
+ if(0 != nsOpenGLLayer) {
+ CGL.setNSOpenGLLayerSwapInterval(nsOpenGLLayer, interval);
+ }
+ CGL.setSwapInterval(contextHandle, interval);
return true;
}
- public boolean swapBuffers(boolean isOnscreen) {
- if(isOnscreen) {
- return CGL.flushBuffer(contextHandle);
- }
- return true;
+
+ public boolean swapBuffers() {
+ if(0 != nsOpenGLLayer) {
+ // sync w/ CALayer renderer - wait until next frame is required (v-sync)
+ CGL.waitUntilNSOpenGLLayerIsReady(nsOpenGLLayer, 16); // timeout 16ms -> 60Hz
+ }
+ if(CGL.flushBuffer(contextHandle)) {
+ if(0 != nsOpenGLLayer) {
+ // trigger CALayer to update
+ CGL.setNSOpenGLLayerNeedsDisplay(nsOpenGLLayer);
+ }
+ return true;
+ }
+ return false;
}
}
@@ -488,7 +574,7 @@ public abstract class MacOSXCGLContext extends GLContextImpl
public long create(long share, int ctp, int major, int minor) {
long ctx = 0;
- MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ MacOSXCGLGraphicsConfiguration config = (MacOSXCGLGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration();
GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
long pixelFormat = MacOSXCGLGraphicsConfiguration.GLCapabilities2CGLPixelFormat(chosenCaps, ctp, major, minor);
if (pixelFormat == 0) {
@@ -535,11 +621,31 @@ public abstract class MacOSXCGLContext extends GLContextImpl
}
public boolean makeCurrent(long ctx) {
- return CGL.CGLSetCurrentContext(ctx) == CGL.kCGLNoError;
+ int err = CGL.CGLLockContext(ctx);
+ if(CGL.kCGLNoError == err) {
+ err = CGL.CGLSetCurrentContext(ctx);
+ if(CGL.kCGLNoError == err) {
+ return true;
+ } else if(DEBUG) {
+ System.err.println("CGL: Could not make context current: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ } else if(DEBUG) {
+ System.err.println("CGL: Could not lock context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ return false;
}
public boolean release(long ctx) {
- return (CGL.CGLSetCurrentContext(0) == CGL.kCGLNoError);
+ gl.glFinish(); // w/o glFinish() OSX < 10.7 (NVidia driver) may freeze
+ int err = CGL.CGLSetCurrentContext(0);
+ if(DEBUG && CGL.kCGLNoError != err) {
+ System.err.println("CGL: Could not release current context: err 0x"+Integer.toHexString(err)+": "+this);
+ }
+ int err2 = CGL.CGLUnlockContext(ctx);
+ if(DEBUG && CGL.kCGLNoError != err2) {
+ System.err.println("CGL: Could not unlock context: err 0x"+Integer.toHexString(err2)+": "+this);
+ }
+ return CGL.kCGLNoError == err && CGL.kCGLNoError == err2;
}
public boolean setSwapInterval(int interval) {
@@ -547,11 +653,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl
CGL.CGLSetParameter(contextHandle, CGL.kCGLCPSwapInterval, lval, 0);
return true;
}
- public boolean swapBuffers(boolean isOnscreen) {
- if(isOnscreen) {
- return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
- }
- return true;
+ public boolean swapBuffers() {
+ return CGL.kCGLNoError == CGL.CGLFlushDrawable(contextHandle);
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
index 5a35f661d..12d480fd1 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawable.java
@@ -40,6 +40,11 @@
package jogamp.opengl.macosx.cgl;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -87,18 +92,46 @@ public abstract class MacOSXCGLDrawable extends GLDrawableImpl {
this.id = id;
}
}
-
+ private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
+
private boolean haveSetOpenGLMode = false;
private GLBackendType openGLMode = GLBackendType.NSOPENGL;
public MacOSXCGLDrawable(GLDrawableFactory factory, NativeSurface comp, boolean realized) {
super(factory, comp, realized);
- initOpenGLImpl(getOpenGLMode());
- }
-
+ initOpenGLImpl(getOpenGLMode());
+ }
+
protected void setRealizedImpl() {
}
+ protected long getNSViewHandle() {
+ return GLBackendType.NSOPENGL == openGLMode ? getHandle() : null;
+ }
+
+ protected void registerContext(MacOSXCGLContext ctx) {
+ // NOTE: we need to keep track of the created contexts in order to
+ // implement swapBuffers() because of how Mac OS X implements its
+ // OpenGL window interface
+ synchronized (createdContexts) {
+ createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx));
+ }
+ }
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ synchronized (createdContexts) {
+ for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) {
+ WeakReference<MacOSXCGLContext> ref = iter.next();
+ MacOSXCGLContext ctx = ref.get();
+ if (ctx != null) {
+ ctx.swapBuffers();
+ } else {
+ iter.remove();
+ }
+ }
+ }
+ }
+
public GLDynamicLookupHelper getGLDynamicLookupHelper() {
return getFactoryImpl().getGLDynamicLookupHelper(0);
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
index 5c726bc54..3dd7a7f08 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLDrawableFactory.java
@@ -42,6 +42,7 @@ package jogamp.opengl.macosx.cgl;
import java.nio.Buffer;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
@@ -52,6 +53,7 @@ import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindowFactory;
import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.macosx.MacOSXGraphicsDevice;
+import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesChooser;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -59,6 +61,7 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLProfile.ShutdownType;
import jogamp.nativewindow.WrappedSurface;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
@@ -70,62 +73,93 @@ import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.util.ReflectionUtil;
public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
- private static final DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper;
-
- static {
- DesktopGLDynamicLookupHelper tmp = null;
- try {
- tmp = new DesktopGLDynamicLookupHelper(new MacOSXCGLDynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
+ private static DesktopGLDynamicLookupHelper macOSXCGLDynamicLookupHelper = null;
+
+ public MacOSXCGLDrawableFactory() {
+ super();
+
+ synchronized(MacOSXCGLDrawableFactory.class) {
+ if(null==macOSXCGLDynamicLookupHelper) {
+ DesktopGLDynamicLookupHelper tmp = null;
+ try {
+ tmp = new DesktopGLDynamicLookupHelper(new MacOSXCGLDynamicLibraryBundleInfo());
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
}
+ macOSXCGLDynamicLookupHelper = tmp;
+ /** FIXME ??
+ if(null!=macOSXCGLDynamicLookupHelper) {
+ CGL.getCGLProcAddressTable().reset(macOSXCGLDynamicLookupHelper);
+ } */
+ }
+ }
+
+ if(null!=macOSXCGLDynamicLookupHelper) {
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ MacOSXCGLGraphicsConfigurationFactory.registerFactory();
+ if(GLProfile.isAWTAvailable()) {
+ try {
+ ReflectionUtil.callStaticMethod("jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory",
+ "registerFactory", null, null, getClass().getClassLoader());
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
}
- macOSXCGLDynamicLookupHelper = tmp;
- /** FIXME ??
- if(null!=macOSXCGLDynamicLookupHelper) {
- CGL.getCGLProcAddressTable().reset(macOSXCGLDynamicLookupHelper);
- } */
+
+ defaultDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedMap = new HashMap<String, SharedResource>();
+ }
+ }
+
+ protected final void destroy(ShutdownType shutdownType) {
+ if(null != sharedMap) {
+ sharedMap.clear();
+ sharedMap = null;
+ }
+ defaultDevice = null;
+ /**
+ * Pulling away the native library may cause havoc ..
+ *
+ if(ShutdownType.COMPLETE == shutdownType && null != macOSXCGLDynamicLookupHelper) {
+ macOSXCGLDynamicLookupHelper.destroy();
+ macOSXCGLDynamicLookupHelper = null;
+ } */
}
public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) {
return macOSXCGLDynamicLookupHelper;
}
- public MacOSXCGLDrawableFactory() {
- super();
-
- // Register our GraphicsConfigurationFactory implementations
- // The act of constructing them causes them to be registered
- new MacOSXCGLGraphicsConfigurationFactory();
- if(GLProfile.isAWTAvailable()) {
- try {
- ReflectionUtil.createInstance("jogamp.opengl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory",
- null, getClass().getClassLoader());
- } catch (JogampRuntimeException jre) { /* n/a .. */ }
- }
-
- defaultDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
- }
+ private HashMap<String, SharedResource> sharedMap = new HashMap<String, SharedResource>();
+ private MacOSXGraphicsDevice defaultDevice;
static class SharedResource {
// private MacOSXCGLDrawable drawable;
// private MacOSXCGLContext context;
MacOSXGraphicsDevice device;
boolean wasContextCreated;
+ boolean hasNPOTTextures;
+ boolean hasRECTTextures;
+ boolean hasAppletFloatPixels;
- SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated
+ SharedResource(MacOSXGraphicsDevice device, boolean wasContextCreated,
+ boolean hasNPOTTextures, boolean hasRECTTextures, boolean hasAppletFloatPixels
/* MacOSXCGLDrawable draw, MacOSXCGLContext ctx */) {
// drawable = draw;
// context = ctx;
this.device = device;
this.wasContextCreated = wasContextCreated;
+ this.hasNPOTTextures = hasNPOTTextures;
+ this.hasRECTTextures = hasRECTTextures;
+ this.hasAppletFloatPixels = hasAppletFloatPixels;
}
final MacOSXGraphicsDevice getDevice() { return device; }
final boolean wasContextAvailable() { return wasContextCreated; }
+ final boolean isNPOTTextureAvailable() { return hasNPOTTextures; }
+ final boolean isRECTTextureAvailable() { return hasRECTTextures; }
+ final boolean isAppletFloatPixelsAvailable() { return hasAppletFloatPixels; }
}
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
- MacOSXGraphicsDevice defaultDevice;
public final AbstractGraphicsDevice getDefaultDevice() {
return defaultDevice;
@@ -138,52 +172,79 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- private boolean isOSXContextAvailable(AbstractGraphicsDevice sharedDevice) {
- boolean madeCurrent = false;
- GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
- if (null == glp) {
- throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
- }
- final GLCapabilities caps = new GLCapabilities(glp);
- caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
- caps.setDoubleBuffered(false);
- caps.setOnscreen(false);
- caps.setPBuffer(true);
- final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
- if(null!=drawable) {
- final GLContext context = drawable.createContext(null);
- if (null != context) {
- context.setSynchronized(true);
- try {
- context.makeCurrent(); // could cause exception
- madeCurrent = context.isCurrent();
- } catch (GLException gle) {
- if (DEBUG) {
- System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent failed");
- gle.printStackTrace();
- }
- } finally {
- context.destroy();
- }
- }
- drawable.destroy();
- }
- return madeCurrent;
+ private HashSet<String> devicesTried = new HashSet<String>();
+
+ private boolean getDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ return devicesTried.contains(connection);
+ }
+ }
+ private void addDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.add(connection);
+ }
+ }
+ private void removeDeviceTried(String connection) {
+ synchronized (devicesTried) {
+ devicesTried.remove(connection);
+ }
}
/* package */ SharedResource getOrCreateOSXSharedResource(AbstractGraphicsDevice adevice) {
- String connection = adevice.getConnection();
+ final String connection = adevice.getConnection();
SharedResource sr;
synchronized(sharedMap) {
- sr = (SharedResource) sharedMap.get(connection);
+ sr = sharedMap.get(connection);
}
- if(null==sr) {
+ if(null==sr && !getDeviceTried(connection)) {
+ addDeviceTried(connection);
final MacOSXGraphicsDevice sharedDevice = new MacOSXGraphicsDevice(adevice.getUnitID());
- final boolean madeCurrent = isOSXContextAvailable(sharedDevice);
- sr = new SharedResource(sharedDevice, madeCurrent);
+ boolean madeCurrent = false;
+ boolean hasNPOTTextures = false;
+ boolean hasRECTTextures = false;
+ boolean hasAppletFloatPixels = false;
+ {
+ GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
+ if (null == glp) {
+ throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
+ }
+ final GLCapabilities caps = new GLCapabilities(glp);
+ caps.setRedBits(5); caps.setGreenBits(5); caps.setBlueBits(5); caps.setAlphaBits(0);
+ caps.setDoubleBuffered(false);
+ caps.setOnscreen(false);
+ caps.setPBuffer(true);
+ final MacOSXCGLDrawable drawable = (MacOSXCGLDrawable) createGLDrawable( createOffscreenSurfaceImpl(sharedDevice, caps, caps, null, 64, 64) );
+ if(null!=drawable) {
+ drawable.setRealized(true);
+ final GLContext context = drawable.createContext(null);
+ if (null != context) {
+ context.setSynchronized(true);
+ try {
+ context.makeCurrent(); // could cause exception
+ madeCurrent = context.isCurrent();
+ if(madeCurrent) {
+ GL gl = context.getGL();
+ hasNPOTTextures = gl.isNPOTTextureAvailable();
+ hasRECTTextures = gl.isExtensionAvailable("GL_EXT_texture_rectangle");
+ hasAppletFloatPixels = gl.isExtensionAvailable("GL_APPLE_float_pixels");
+ }
+ } catch (GLException gle) {
+ if (DEBUG) {
+ System.err.println("MacOSXCGLDrawableFactory.createShared: INFO: makeCurrent failed");
+ gle.printStackTrace();
+ }
+ } finally {
+ context.destroy();
+ }
+ }
+ drawable.destroy();
+ }
+ }
+ sr = new SharedResource(sharedDevice, madeCurrent, hasNPOTTextures, hasRECTTextures, hasAppletFloatPixels);
synchronized(sharedMap) {
sharedMap.put(connection, sr);
}
+ removeDeviceTried(connection);
if (DEBUG) {
System.err.println("MacOSXCGLDrawableFactory.createShared: device: " + sharedDevice);
System.err.println("MacOSXCGLDrawableFactory.createShared: context: " + madeCurrent);
@@ -191,11 +252,22 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
return sr;
}
-
- public final boolean getWasSharedContextCreated(AbstractGraphicsDevice device) {
- SharedResource sr = getOrCreateOSXSharedResource(device);
- if(null!=sr) {
- return sr.wasContextAvailable();
+
+ protected final Thread getSharedResourceThread() {
+ return null;
+ }
+
+ protected final boolean createSharedResource(AbstractGraphicsDevice device) {
+ try {
+ SharedResource sr = getOrCreateOSXSharedResource(device);
+ if(null!=sr) {
+ return sr.wasContextAvailable();
+ }
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("Catched Exception while MaxOSXCGL Shared Resource initialization");
+ gle.printStackTrace();
+ }
}
return false;
}
@@ -213,8 +285,6 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
return null;
}
- protected final void shutdownInstance() {}
-
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
return MacOSXCGLGraphicsConfiguration.getAvailableCapabilities(this, device);
}
@@ -227,26 +297,11 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
}
protected GLDrawableImpl createOffscreenDrawableImpl(NativeSurface target) {
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration();
GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(!caps.isPBuffer()) {
return new MacOSXOffscreenCGLDrawable(this, target);
}
-
- // PBuffer GLDrawable Creation
- /**
- * FIXME: Think about this ..
- * should not be necessary ? ..
- final List returnList = new ArrayList();
- final GLDrawableFactory factory = this;
- Runnable r = new Runnable() {
- public void run() {
- returnList.add(new MacOSXPbufferCGLDrawable(factory, target));
- }
- };
- maybeDoSingleThreadedWorkaround(r);
- return (GLDrawableImpl) returnList.get(0);
- */
return new MacOSXPbufferCGLDrawable(this, target);
}
@@ -257,7 +312,7 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl {
protected NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested, GLCapabilitiesChooser chooser, int width, int height) {
AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_MACOSX);
WrappedSurface ns = new WrappedSurface(MacOSXCGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen, true));
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return ns;
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
index a429720db..f552ab3dd 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfiguration.java
@@ -41,15 +41,16 @@ import java.util.List;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
+
import com.jogamp.common.nio.PointerBuffer;
-public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class MacOSXCGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
long pixelformat;
MacOSXCGLGraphicsConfiguration(AbstractGraphicsScreen screen,
@@ -67,10 +68,6 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
this.pixelformat=pixelformat;
}
- void setChosenCapabilities(GLCapabilitiesImmutable caps) {
- super.setChosenCapabilities(caps);
- }
-
protected static List<GLCapabilitiesImmutable> getAvailableCapabilities(MacOSXCGLDrawableFactory factory, AbstractGraphicsDevice device) {
MacOSXCGLDrawableFactory.SharedResource sharedResource = factory.getOrCreateOSXSharedResource(device);
if(null == sharedResource) {
@@ -83,6 +80,8 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
static final int[] cglInternalAttributeToken = new int[] {
CGL.kCGLPFAOpenGLProfile,
CGL.kCGLPFAColorFloat,
+ CGL.NSOpenGLPFANoRecovery,
+ CGL.NSOpenGLPFAAccelerated,
CGL.NSOpenGLPFAPixelBuffer,
CGL.NSOpenGLPFADoubleBuffer,
CGL.NSOpenGLPFAStereo,
@@ -114,6 +113,13 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
ivalues[idx] = caps.getPbufferFloatingPointBuffers() ? 1 : 0;
break;
+ case CGL.NSOpenGLPFANoRecovery:
+ ivalues[idx] = caps.getHardwareAccelerated() ? 1 : 0;
+ break;
+ case CGL.NSOpenGLPFAAccelerated:
+ ivalues[idx] = caps.getHardwareAccelerated() ? 1 : 0;
+ break;
+
case CGL.NSOpenGLPFAPixelBuffer:
ivalues[idx] = caps.isPBuffer() ? 1 : 0;
break;
@@ -222,7 +228,7 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
// Use attribute array to select pixel format
PointerBuffer fmt = PointerBuffer.allocateDirect(1);
- long[] numScreens = new long[1];
+ int[] numScreens = new int[1];
int res = CGL.CGLChoosePixelFormat(attrs, 0, fmt, numScreens, 0);
if (res != CGL.kCGLNoError) {
throw new GLException("Error code " + res + " while choosing pixel format");
@@ -285,6 +291,10 @@ public class MacOSXCGLGraphicsConfiguration extends DefaultGraphicsConfiguration
caps.setPbufferFloatingPointBuffers(ivalues[i] != 0);
break;
+ case CGL.NSOpenGLPFAAccelerated:
+ caps.setHardwareAccelerated(ivalues[i] != 0);
+ break;
+
case CGL.NSOpenGLPFAPixelBuffer:
caps.setPBuffer(ivalues[i] != 0);
break;
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
index d4526f04e..0de290c6b 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLGraphicsConfigurationFactory.java
@@ -51,8 +51,10 @@ import javax.media.opengl.GLCapabilitiesImmutable;
public class MacOSXCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = jogamp.opengl.Debug.debug("GraphicsConfiguration");
- MacOSXCGLGraphicsConfigurationFactory() {
- GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.macosx.MacOSXGraphicsDevice.class, this);
+ static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.macosx.MacOSXGraphicsDevice.class, new MacOSXCGLGraphicsConfigurationFactory());
+ }
+ private MacOSXCGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
index 08a531200..6ce2d7ba7 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXExternalCGLContext.java
@@ -48,9 +48,9 @@ import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
-import javax.media.opengl.GLProfile;
import jogamp.nativewindow.WrappedSurface;
+import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLContextShareSet;
import jogamp.opengl.macosx.cgl.MacOSXCGLDrawable.GLBackendType;
@@ -61,10 +61,10 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
private MacOSXExternalCGLContext(Drawable drawable, boolean isNSContext, long handle) {
super(drawable, null);
setOpenGLMode(isNSContext ? GLBackendType.NSOPENGL : GLBackendType.CGL );
- drawable.setExternalCGLContext(this);
+ drawable.registerContext(this);
this.contextHandle = handle;
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
@@ -118,7 +118,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
return new MacOSXExternalCGLContext(new Drawable(factory, ns), isNSContext, contextHandle);
}
- protected boolean createImpl() throws GLException {
+ protected boolean createImpl(GLContextImpl shareWith) throws GLException {
return true;
}
@@ -139,7 +139,7 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
lastContext = null;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
}
protected void releaseImpl() throws GLException {
@@ -150,16 +150,10 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
// Need to provide the display connection to extension querying APIs
static class Drawable extends MacOSXCGLDrawable {
- MacOSXExternalCGLContext extCtx;
-
Drawable(GLDrawableFactory factory, NativeSurface comp) {
super(factory, comp, true);
}
- void setExternalCGLContext(MacOSXExternalCGLContext externalContext) {
- extCtx = externalContext;
- }
-
public GLContext createContext(GLContext shareWith) {
throw new GLException("Should not call this");
}
@@ -175,11 +169,5 @@ public class MacOSXExternalCGLContext extends MacOSXCGLContext {
public void setSize(int width, int height) {
throw new GLException("Should not call this");
}
-
- protected void swapBuffersImpl() {
- if (extCtx != null) {
- extCtx.swapBuffers();
- }
- }
}
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
index bec4cf32a..f81cd725e 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOffscreenCGLDrawable.java
@@ -40,9 +40,9 @@
package jogamp.opengl.macosx.cgl;
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-import jogamp.opengl.*;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
public class MacOSXOffscreenCGLDrawable extends MacOSXPbufferCGLDrawable {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
index 97d198c92..9e051311c 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java
@@ -42,6 +42,8 @@ package jogamp.opengl.macosx.cgl;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
+import jogamp.opengl.GLContextImpl;
+
public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
public MacOSXOnscreenCGLContext(MacOSXOnscreenCGLDrawable drawable,
@@ -50,14 +52,20 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
}
@Override
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
- super.makeCurrentImpl(newCreated);
+ protected void makeCurrentImpl() throws GLException {
+ super.makeCurrentImpl();
drawableUpdatedNotify();
}
@Override
protected void drawableUpdatedNotify() throws GLException {
- if(0==updateHandle || CGL.updateContextNeedsUpdate(updateHandle)) {
+ final int w = drawable.getWidth();
+ final int h = drawable.getHeight();
+ final boolean updateContext = ( 0!=updateHandle && CGL.updateContextNeedsUpdate(updateHandle) ) ||
+ w != lastWidth || h != lastHeight;
+ if(updateContext) {
+ lastWidth = w;
+ lastHeight = h;
if (contextHandle == 0) {
throw new GLException("Context not created");
}
@@ -65,11 +73,11 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
}
}
- protected long updateHandle = 0;
-
@Override
- protected boolean createImpl() {
- boolean res = super.createImpl();
+ protected boolean createImpl(GLContextImpl sharedWith) {
+ boolean res = super.createImpl(sharedWith);
+ lastWidth = -1;
+ lastHeight = -1;
if(res && isNSContext()) {
if(0 != updateHandle) {
throw new InternalError("XXX1");
@@ -89,5 +97,8 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext {
updateHandle = 0;
}
super.destroyImpl();
- }
+ }
+
+ private long updateHandle = 0;
+ private int lastWidth, lastHeight;
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
index 24276c39e..80c54042f 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLDrawable.java
@@ -40,44 +40,20 @@
package jogamp.opengl.macosx.cgl;
-import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
public class MacOSXOnscreenCGLDrawable extends MacOSXCGLDrawable {
- private List<WeakReference<MacOSXCGLContext>> createdContexts = new ArrayList<WeakReference<MacOSXCGLContext>>();
-
+
protected MacOSXOnscreenCGLDrawable(GLDrawableFactory factory, NativeSurface component) {
super(factory, component, false);
}
public GLContext createContext(GLContext shareWith) {
- MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith);
- // NOTE: we need to keep track of the created contexts in order to
- // implement swapBuffers() because of how Mac OS X implements its
- // OpenGL window interface
- synchronized (createdContexts) {
- createdContexts.add(new WeakReference<MacOSXCGLContext>(ctx));
- }
+ final MacOSXOnscreenCGLContext ctx= new MacOSXOnscreenCGLContext(this, shareWith);
+ registerContext(ctx);
return ctx;
}
- protected void swapBuffersImpl() {
- synchronized (createdContexts) {
- for (Iterator<WeakReference<MacOSXCGLContext>> iter = createdContexts.iterator(); iter.hasNext(); ) {
- WeakReference<MacOSXCGLContext> ref = iter.next();
- MacOSXCGLContext ctx = ref.get();
- if (ctx != null) {
- ctx.swapBuffers();
- } else {
- iter.remove();
- }
- }
- }
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
index c5743b923..7ba7d2d5a 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLContext.java
@@ -33,19 +33,16 @@
package jogamp.opengl.macosx.cgl;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.opengl.GL;
-import javax.media.opengl.GL2;
-import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
+import jogamp.opengl.GLContextImpl;
public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
// State for render-to-texture and render-to-texture-rectangle support
- private int textureTarget; // e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_NV
private int texture; // actual texture object
public MacOSXPbufferCGLContext(MacOSXPbufferCGLDrawable drawable,
@@ -55,7 +52,7 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
public void bindPbufferToTexture() {
GL gl = getGL();
- gl.glBindTexture(textureTarget, texture);
+ gl.glBindTexture(((MacOSXPbufferCGLDrawable)drawable).getTextureTarget(), texture);
// FIXME: not clear whether this is really necessary, but since
// the API docs seem to imply it is and since it doesn't seem to
// impact performance, leaving it in
@@ -65,23 +62,14 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
public void releasePbufferFromTexture() {
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
- super.makeCurrentImpl(newCreated);
-
- if (newCreated) {
+ protected boolean createImpl(GLContextImpl shareWith) {
+ boolean res = super.createImpl(shareWith);
+ if(res) {
// Initialize render-to-texture support if requested
- DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- GL gl = getGL();
- boolean rect = gl.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle();
- if (rect) {
- if (!gl.isExtensionAvailable("GL_EXT_texture_rectangle")) {
- System.err.println("MacOSXPbufferCGLContext: WARNING: GL_EXT_texture_rectangle extension not " +
- "supported; skipping requested render_to_texture_rectangle support for pbuffer");
- rect = false;
- }
- }
- textureTarget = (rect ? GL2.GL_TEXTURE_RECTANGLE : GL.GL_TEXTURE_2D);
+ final GL gl = getGL();
+ final MacOSXPbufferCGLDrawable osxPDrawable = (MacOSXPbufferCGLDrawable)drawable;
+ final int textureTarget = osxPDrawable.getTextureTarget();
+
int[] tmp = new int[1];
gl.glGenTextures(1, tmp, 0);
texture = tmp[0];
@@ -90,8 +78,11 @@ public class MacOSXPbufferCGLContext extends MacOSXCGLContext {
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(textureTarget, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
- gl.glCopyTexImage2D(textureTarget, 0, GL.GL_RGB, 0, 0, drawable.getWidth(), drawable.getHeight(), 0);
+ gl.glTexImage2D(textureTarget, 0, GL.GL_RGB, osxPDrawable.getTextureWidth(), osxPDrawable.getTextureHeight(),
+ 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE, null);
+ gl.glCopyTexSubImage2D(textureTarget, 0, 0, 0, 0, 0, drawable.getWidth(), drawable.getHeight());
}
+ return res;
}
public int getFloatingPointMode() {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
index fdbfaf6d6..e02c3efec 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXPbufferCGLDrawable.java
@@ -51,14 +51,10 @@ import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
-import jogamp.opengl.Debug;
-
import com.jogamp.common.nio.PointerBuffer;
+import com.jogamp.opengl.util.GLBuffers;
-
-public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
- private static final boolean DEBUG = Debug.debug("MacOSXPbufferCGLDrawable");
-
+public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
// Abstract interface for implementation of this drawable (either
// NSOpenGL-based or CGL-based)
interface GLBackendImpl {
@@ -76,34 +72,46 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
// Note that we can not store this in the NativeSurface because the
// semantic is that contains an NSView
protected long pBuffer;
+ protected int pBufferTexTarget, pBufferTexWidth, pBufferTexHeight;
public MacOSXPbufferCGLDrawable(GLDrawableFactory factory, NativeSurface target) {
- super(factory, target, true);
-
- if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
- }
-
- createPbuffer();
-
- if (DEBUG) {
- System.err.println("Created pbuffer " + this);
- }
+ super(factory, target, false);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
createPbuffer();
} else {
- destroyImpl();
+ destroyPbuffer();
}
}
public GLContext createContext(GLContext shareWith) {
- return new MacOSXPbufferCGLContext(this, shareWith);
+ final MacOSXPbufferCGLContext ctx = new MacOSXPbufferCGLContext(this, shareWith);
+ registerContext(ctx);
+ return ctx;
}
- protected void destroyImpl() {
+ @Override
+ protected long getNSViewHandle() {
+ // pbuffer handle is NSOpenGLPixelBuffer
+ return 0;
+ }
+
+ @Override
+ public long getHandle() {
+ return pBuffer;
+ }
+
+ protected int getTextureTarget() { return pBufferTexTarget; }
+ protected int getTextureWidth() { return pBufferTexWidth; }
+ protected int getTextureHeight() { return pBufferTexHeight; }
+
+ protected void destroyPbuffer() {
if (this.pBuffer != 0) {
NativeSurface ns = getNativeSurface();
impl.destroy(pBuffer);
@@ -112,73 +120,56 @@ public class MacOSXPbufferCGLDrawable extends MacOSXCGLDrawable {
}
}
- public long getHandle() {
- return pBuffer;
- }
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ private void createPbuffer() {
+ final NativeSurface ns = getNativeSurface();
+ final DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration();
+ final GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ final GLProfile glProfile = capabilities.getGLProfile();
+ MacOSXCGLDrawableFactory.SharedResource sr = ((MacOSXCGLDrawableFactory)factory).getOrCreateOSXSharedResource(config.getScreen().getDevice());
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
}
- }
- private void createPbuffer() {
- NativeSurface ns = getNativeSurface();
- DefaultGraphicsConfiguration config = (DefaultGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- GLProfile glProfile = capabilities.getGLProfile();
- int renderTarget;
- if (glProfile.isGL2GL3() && capabilities.getPbufferRenderToTextureRectangle()) {
- renderTarget = GL2.GL_TEXTURE_RECTANGLE;
+ if ( capabilities.getPbufferRenderToTextureRectangle() && null!=sr && sr.isRECTTextureAvailable() ) {
+ pBufferTexTarget = GL2.GL_TEXTURE_RECTANGLE;
} else {
- int w = getNextPowerOf2(getWidth());
- int h = getNextPowerOf2(getHeight());
- ((SurfaceChangeable)ns).setSize(w, h);
- renderTarget = GL.GL_TEXTURE_2D;
+ pBufferTexTarget = GL.GL_TEXTURE_2D;
+ }
+ if ( GL2.GL_TEXTURE_RECTANGLE == pBufferTexTarget || ( null!=sr && sr.isNPOTTextureAvailable() ) ) {
+ pBufferTexWidth = getWidth();
+ pBufferTexHeight = getHeight();
+ } else {
+ pBufferTexWidth = GLBuffers.getNextPowerOf2(getWidth());
+ pBufferTexHeight = GLBuffers.getNextPowerOf2(getHeight());
}
int internalFormat = GL.GL_RGBA;
if (capabilities.getPbufferFloatingPointBuffers()) {
- // FIXME: want to check availability of GL_APPLE_float_pixels
- // extension, but need valid OpenGL context in order to do so --
- // in worst case would need to create dummy window / GLCanvas
- // (undesirable) -- could maybe also do this with pbuffers
- /*
- if (!gl.isExtensionAvailable("GL_APPLE_float_pixels")) {
- throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available");
- }
- */
- if(glProfile.isGL2GL3()) {
- switch (capabilities.getRedBits()) {
+ if(!glProfile.isGL2GL3() || null==sr || sr.isAppletFloatPixelsAvailable()) {
+ throw new GLException("Floating-point support (GL_APPLE_float_pixels) not available");
+ }
+ switch (capabilities.getRedBits()) {
case 16: internalFormat = GL2.GL_RGBA_FLOAT16_APPLE; break;
case 32: internalFormat = GL2.GL_RGBA_FLOAT32_APPLE; break;
default: throw new GLException("Invalid floating-point bit depth (only 16 and 32 supported)");
- }
- } else {
- internalFormat = GL.GL_RGBA;
}
}
-
- pBuffer = impl.create(renderTarget, internalFormat, getWidth(), getHeight());
+
+ pBuffer = impl.create(pBufferTexTarget, internalFormat, getWidth(), getHeight());
+ if(DEBUG) {
+ System.err.println("MacOSXPbufferCGLDrawable tex: target "+toHexString(pBufferTexTarget)+
+ ", pbufferSize "+getWidth()+"x"+getHeight()+
+ ", texSize "+pBufferTexWidth+"x"+pBufferTexHeight+
+ ", internal-fmt "+toHexString(internalFormat));
+ System.err.println("MacOSXPbufferCGLDrawable pBuffer: "+toHexString(pBuffer));
+ // Thread.dumpStack();
+ }
if (pBuffer == 0) {
throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
}
((SurfaceChangeable)ns).setSurfaceHandle(pBuffer);
-
- }
-
- private int getNextPowerOf2(int number) {
- if (((number-1) & number) == 0) {
- //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0
- return number;
- }
- int power = 0;
- while (number > 0) {
- number = number>>1;
- power++;
- }
- return (1<<power);
}
public void setOpenGLMode(GLBackendType mode) {
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
index 68e82dc19..a8c04eee4 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXAWTCGLGraphicsConfigurationFactory.java
@@ -58,8 +58,10 @@ import jogamp.opengl.macosx.cgl.MacOSXCGLGraphicsConfiguration;
public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = jogamp.opengl.Debug.debug("GraphicsConfiguration");
- public MacOSXAWTCGLGraphicsConfigurationFactory() {
- GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, new MacOSXAWTCGLGraphicsConfigurationFactory());
+ }
+ private MacOSXAWTCGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
@@ -72,7 +74,7 @@ public class MacOSXAWTCGLGraphicsConfigurationFactory extends GLGraphicsConfigur
}
if(null==absScreen) {
- absScreen = AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
+ absScreen = AWTGraphicsScreen.createDefault();
}
AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
index ae58f6811..70416d1f4 100644
--- a/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/awt/MacOSXJava2DCGLContext.java
@@ -44,6 +44,7 @@ import java.awt.Graphics;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLException;
+import jogamp.opengl.GLContextImpl;
import jogamp.opengl.awt.Java2D;
import jogamp.opengl.awt.Java2DGLContext;
import jogamp.opengl.macosx.cgl.MacOSXCGLContext;
@@ -73,20 +74,30 @@ public class MacOSXJava2DCGLContext extends MacOSXCGLContext implements Java2DGL
this.graphics = g;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
if (!Java2D.makeOGLContextCurrentOnSurface(graphics, contextHandle)) {
throw new GLException("Error making context current");
}
}
- protected boolean createImpl() {
- long share = createImplPreset();
+ protected boolean createImpl(GLContextImpl shareWith) {
+ long share = createImplPreset(shareWith);
long ctx = Java2D.createOGLContextOnSurface(graphics, share);
if (ctx == 0) {
+ if(DEBUG) {
+ System.err.println("Error creating current: "+this);
+ }
return false;
}
- setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ if (!Java2D.makeOGLContextCurrentOnSurface(graphics, contextHandle)) {
+ Java2D.destroyOGLContext(ctx);
+ if(DEBUG) {
+ System.err.println("Error making created context current: "+this);
+ }
+ return false;
+ }
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
contextHandle = ctx;
return true;
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java
new file mode 100644
index 000000000..845d749ba
--- /dev/null
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WGLUtil.java
@@ -0,0 +1,95 @@
+/**
+ * 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.opengl.windows.wgl;
+
+import java.security.AccessController;
+
+import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
+import jogamp.opengl.Debug;
+
+public class WGLUtil {
+ /**
+ * Switch to use the <code>wgl</code> variants of {@link jogamp.opengl.windows.wgl.WGL}
+ * to replace the following 5 GDI based functions (see below).
+ * <p>
+ * Disabled per default.
+ * </p>
+ * <p>
+ * You can enable it by defining the property <code>jogl.windows.useWGLVersionOf5WGLGDIFuncSet</code>.
+ * </p>
+ *
+ * @see jogamp.nativewindow.windows.GDI#ChoosePixelFormat(long, PIXELFORMATDESCRIPTOR)
+ * @see jogamp.nativewindow.windows.GDI#DescribePixelFormat(long, int, int, PIXELFORMATDESCRIPTOR)
+ * @see jogamp.nativewindow.windows.GDI#GetPixelFormat(long)
+ * @see jogamp.nativewindow.windows.GDI#SetPixelFormat(long, int, PIXELFORMATDESCRIPTOR)
+ * @see jogamp.nativewindow.windows.GDI#SwapBuffers(long)
+ */
+ public static final boolean USE_WGLVersion_Of_5WGLGDIFuncSet;
+
+ static {
+ USE_WGLVersion_Of_5WGLGDIFuncSet = Debug.isPropertyDefined("jogl.windows.useWGLVersionOf5WGLGDIFuncSet", true, AccessController.getContext());
+ System.err.println("USE_WGLVersion_Of_5WGLGDIFuncSet: "+USE_WGLVersion_Of_5WGLGDIFuncSet);
+ }
+
+ public static int ChoosePixelFormat(long hdc, PIXELFORMATDESCRIPTOR pfd) {
+ if(USE_WGLVersion_Of_5WGLGDIFuncSet) {
+ return WGL.wglChoosePixelFormat(hdc, pfd);
+ } else {
+ return GDI.ChoosePixelFormat(hdc, pfd);
+ }
+ }
+ public static int DescribePixelFormat(long hdc, int pfdid, int pfdSize, PIXELFORMATDESCRIPTOR pfd) {
+ if(USE_WGLVersion_Of_5WGLGDIFuncSet) {
+ return WGL.wglDescribePixelFormat(hdc, pfdid, pfdSize, pfd);
+ } else {
+ return GDI.DescribePixelFormat(hdc, pfdid, pfdSize, pfd);
+ }
+ }
+ public static int GetPixelFormat(long hdc) {
+ if(USE_WGLVersion_Of_5WGLGDIFuncSet) {
+ return WGL.wglGetPixelFormat(hdc);
+ } else {
+ return GDI.GetPixelFormat(hdc);
+ }
+ }
+ public static boolean SetPixelFormat(long hdc, int pfdid, PIXELFORMATDESCRIPTOR pfd) {
+ if(USE_WGLVersion_Of_5WGLGDIFuncSet) {
+ return WGL.wglSetPixelFormat(hdc, pfdid, pfd);
+ } else {
+ return GDI.SetPixelFormat(hdc, pfdid, pfd);
+ }
+ }
+ public static boolean SwapBuffers(long hdc) {
+ if(USE_WGLVersion_Of_5WGLGDIFuncSet) {
+ return WGL.wglSwapBuffers(hdc);
+ } else {
+ return GDI.SwapBuffers(hdc);
+ }
+ }
+}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
index b2c95de39..574226570 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsBitmapWGLDrawable.java
@@ -57,15 +57,18 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
private long hbitmap;
protected WindowsBitmapWGLDrawable(GLDrawableFactory factory, NativeSurface target) {
- super(factory, target, true);
- create();
+ super(factory, target, false);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
- create();
+ createBitmap();
} else {
- destroyImpl();
+ destroyBitmap();
}
}
@@ -73,13 +76,13 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
return new WindowsBitmapWGLContext(this, shareWith);
}
- private void create() {
+ private void createBitmap() {
int werr;
NativeSurface ns = getNativeSurface();
if(DEBUG) {
System.err.println("WindowsBitmapWGLDrawable (1): "+ns);
}
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
GLCapabilitiesImmutable capabilities = (GLCapabilitiesImmutable)config.getRequestedCapabilities();
int width = getWidth();
int height = getHeight();
@@ -153,7 +156,7 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
config.updateGraphicsConfiguration(getFactory(), ns, null);
}
- protected void destroyImpl() {
+ protected void destroyBitmap() {
NativeSurface ns = getNativeSurface();
if (ns.getSurfaceHandle() != 0) {
// Must destroy bitmap and device context
@@ -165,11 +168,4 @@ public class WindowsBitmapWGLDrawable extends WindowsWGLDrawable {
((SurfaceChangeable)ns).setSurfaceHandle(0);
}
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
-
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
index 3d0cce725..0bd83b923 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsDummyWGLDrawable.java
@@ -46,6 +46,8 @@ import javax.media.opengl.GLProfile;
import javax.media.nativewindow.AbstractGraphicsScreen;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLException;
@@ -63,7 +65,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
throw new GLException("WindowsDummyWGLDrawable: surface not ready (lockSurface)");
}
try {
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
config.updateGraphicsConfiguration(factory, ns, null);
if (DEBUG) {
System.err.println("!!! WindowsDummyWGLDrawable: "+config);
@@ -84,7 +86,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
GLCapabilities caps = new GLCapabilities(glp);
WindowsWGLGraphicsConfiguration cfg = WindowsWGLGraphicsConfigurationFactory.createDefaultGraphicsConfiguration(caps, absScreen);
GDISurface ns = new GDISurface(cfg, windowHandle);
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return new WindowsDummyWGLDrawable(factory, ns, handleWindowLifecycle);
}
@@ -96,7 +98,7 @@ public class WindowsDummyWGLDrawable extends WindowsWGLDrawable {
protected void destroyImpl() {
if (handleHwndLifecycle && hwnd != 0) {
GDI.ShowWindow(hwnd, GDI.SW_HIDE);
- GDI.DestroyDummyWindow(hwnd);
+ GDIUtil.DestroyDummyWindow(hwnd);
hwnd = 0;
}
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
index c3588fd48..b183ad59f 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLContext.java
@@ -65,7 +65,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
System.err.println(getThreadName() + ": !!! Created external OpenGL context " + toHexString(ctx) + " for " + this);
}
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
@@ -85,7 +85,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
}
AbstractGraphicsScreen aScreen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
WindowsWGLGraphicsConfiguration cfg;
- final int pfdID = GDI.GetPixelFormat(hdc);
+ final int pfdID = WGLUtil.GetPixelFormat(hdc);
if (0 == pfdID) {
// This could have happened if the HDC was released right after the GL ctx made current (SWT),
// WinXP-32bit will not be able to use this HDC afterwards.
@@ -122,7 +122,7 @@ public class WindowsExternalWGLContext extends WindowsWGLContext {
lastContext = null;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
}
protected void releaseImpl() throws GLException {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
index ede504735..1e5991821 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsExternalWGLDrawable.java
@@ -63,7 +63,7 @@ public class WindowsExternalWGLDrawable extends WindowsWGLDrawable {
if (0==hdc) {
throw new GLException("Error: attempted to make an external GLDrawable without a drawable current, werr " + GDI.GetLastError());
}
- int pfdID = GDI.GetPixelFormat(hdc);
+ int pfdID = WGLUtil.GetPixelFormat(hdc);
if (pfdID == 0) {
throw new GLException("Error: attempted to make an external GLContext without a valid pixelformat, werr " + GDI.GetLastError());
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java
index 4f34c946a..6ad330ccc 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsOnscreenWGLDrawable.java
@@ -42,7 +42,6 @@ package jogamp.opengl.windows.wgl;
import javax.media.nativewindow.*;
import javax.media.opengl.*;
-import jogamp.opengl.*;
public class WindowsOnscreenWGLDrawable extends WindowsWGLDrawable {
protected WindowsOnscreenWGLDrawable(GLDrawableFactory factory, NativeSurface component) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
index 97c63ea52..0f610495d 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLContext.java
@@ -42,6 +42,8 @@ package jogamp.opengl.windows.wgl;
import javax.media.opengl.*;
+import jogamp.opengl.GLContextImpl;
+
public class WindowsPbufferWGLContext extends WindowsWGLContext {
// State for render-to-texture and render-to-texture-rectangle support
private boolean rtt; // render-to-texture?
@@ -86,9 +88,9 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext {
}
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
- super.makeCurrentImpl(newCreated);
- if (newCreated) {
+ protected boolean createImpl(GLContextImpl shareWith) {
+ boolean res = super.createImpl(shareWith);
+ if(res) {
GLCapabilitiesImmutable capabilities = drawable.getChosenGLCapabilities();
// Initialize render-to-texture support if requested
@@ -135,6 +137,7 @@ public class WindowsPbufferWGLContext extends WindowsWGLContext {
}
}
}
+ return res;
}
public int getFloatingPointMode() {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
index 7be2c1ac7..0988f3eca 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsPbufferWGLDrawable.java
@@ -41,6 +41,7 @@
package jogamp.opengl.windows.wgl;
import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.SurfaceChangeable;
import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
@@ -51,6 +52,7 @@ import javax.media.opengl.GLProfile;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.windows.wgl.WindowsWGLDrawableFactory.SharedResource;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -60,27 +62,20 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
private long buffer; // pbuffer handle
private int floatMode;
-
- protected WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeSurface target,
- WindowsWGLDrawableFactory.SharedResource sharedResource) {
- super(factory, target, true);
-
- if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
- }
-
- createPbuffer(sharedResource);
-
- if (DEBUG) {
- System.err.println("Created pbuffer " + this);
- }
+
+ protected WindowsPbufferWGLDrawable(GLDrawableFactory factory, NativeSurface target) {
+ super(factory, target, false);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
- throw new GLException("Recreation via setRealized not supported.");
+ createPbuffer();
} else {
- destroyImpl();
+ destroyPbuffer();
}
}
@@ -88,7 +83,7 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
return new WindowsPbufferWGLContext(this, shareWith);
}
- protected void destroyImpl() {
+ protected void destroyPbuffer() {
NativeSurface ns = getNativeSurface();
if(0!=buffer) {
WGLExt wglExt = cachedWGLExt;
@@ -120,147 +115,154 @@ public class WindowsPbufferWGLDrawable extends WindowsWGLDrawable {
return floatMode;
}
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
+ private void createPbuffer() {
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration();
+ SharedResource sharedResource = ((WindowsWGLDrawableFactory)factory).getOrCreateSharedResource(config.getScreen().getDevice());
+ NativeSurface sharedSurface = sharedResource.getDrawable().getNativeSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= sharedSurface.lockSurface()) {
+ throw new NativeWindowException("Could not lock (sharedSurface): "+this);
}
- }
-
- private void createPbuffer(WindowsWGLDrawableFactory.SharedResource sharedResource) {
- long parentHdc = sharedResource.getDrawable().getNativeSurface().getSurfaceHandle();
- WGLExt wglExt = sharedResource.getContext().getWGLExt();
+ try {
+ long sharedHdc = sharedSurface.getSurfaceHandle();
+ WGLExt wglExt = sharedResource.getContext().getWGLExt();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
+ }
- int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
- float[] fattributes = new float[1];
- int[] floatModeTmp = new int[1];
- int niattribs = 0;
- int width, height;
-
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
- GLProfile glProfile = chosenCaps.getGLProfile();
-
- if (DEBUG) {
- System.out.println("Pbuffer parentHdc = " + toHexString(parentHdc));
- System.out.println("Pbuffer chosenCaps: " + chosenCaps);
- }
-
- if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(chosenCaps,
- iattributes, sharedResource, -1, floatModeTmp)){
- throw new GLException("Pbuffer-related extensions not supported");
- }
-
- floatMode = floatModeTmp[0];
- boolean rtt = chosenCaps.getPbufferRenderToTexture();
- boolean rect = chosenCaps.getPbufferRenderToTextureRectangle();
- boolean useFloat = chosenCaps.getPbufferFloatingPointBuffers();
- // boolean ati = false;
-
- /**
- if (useFloat) {
- ati = (floatMode == GLPbuffer.ATI_FLOAT);
- } */
-
- int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
- int nformats;
- int[] nformatsTmp = new int[1];
- if (!wglExt.wglChoosePixelFormatARB(parentHdc,
- iattributes, 0,
- fattributes, 0,
- WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
- pformats, 0,
- nformatsTmp, 0)) {
- throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed");
- }
- nformats = nformatsTmp[0];
- if (nformats <= 0) {
- throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
- }
-
- if (DEBUG) {
- System.err.println("" + nformats + " suitable pixel formats found");
- for (int i = 0; i < nformats; i++) {
- WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, parentHdc, pformats[i], glProfile, false, true);
- System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps);
- }
- }
-
- int pfdid = 0;
- long tmpBuffer = 0;
- {
- int whichFormat;
- // Loop is a workaround for bugs in NVidia's recent drivers
- for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
- int format = pformats[whichFormat];
-
- // Create the p-buffer.
- niattribs = 0;
-
- if (rtt) {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB;
- if (useFloat) {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
- } else {
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
+ int[] iattributes = new int [2*WindowsWGLGraphicsConfiguration.MAX_ATTRIBS];
+ float[] fattributes = new float[1];
+ int[] floatModeTmp = new int[1];
+ int niattribs = 0;
+ int width, height;
+
+ GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable)config.getChosenCapabilities();
+ GLProfile glProfile = chosenCaps.getGLProfile();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer parentHdc = " + toHexString(sharedHdc));
+ System.out.println("Pbuffer chosenCaps: " + chosenCaps);
+ }
+
+ if(!WindowsWGLGraphicsConfiguration.GLCapabilities2AttribList(chosenCaps,
+ iattributes, sharedResource, -1, floatModeTmp)){
+ throw new GLException("Pbuffer-related extensions not supported");
+ }
+
+ floatMode = floatModeTmp[0];
+ boolean rtt = chosenCaps.getPbufferRenderToTexture();
+ boolean rect = chosenCaps.getPbufferRenderToTextureRectangle();
+ boolean useFloat = chosenCaps.getPbufferFloatingPointBuffers();
+ // boolean ati = false;
+
+ /**
+ if (useFloat) {
+ ati = (floatMode == GLPbuffer.ATI_FLOAT);
+ } */
+
+ int[] pformats = new int[WindowsWGLGraphicsConfiguration.MAX_PFORMATS];
+ int nformats;
+ int[] nformatsTmp = new int[1];
+ if (!wglExt.wglChoosePixelFormatARB(sharedHdc,
+ iattributes, 0,
+ fattributes, 0,
+ WindowsWGLGraphicsConfiguration.MAX_PFORMATS,
+ pformats, 0,
+ nformatsTmp, 0)) {
+ throw new GLException("pbuffer creation error: wglChoosePixelFormat() failed");
+ }
+ nformats = nformatsTmp[0];
+ if (nformats <= 0) {
+ throw new GLException("pbuffer creation error: Couldn't find a suitable pixel format");
+ }
+
+ if (DEBUG) {
+ System.err.println("" + nformats + " suitable pixel formats found");
+ for (int i = 0; i < nformats; i++) {
+ WGLGLCapabilities dbgCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pformats[i], glProfile, false, true);
+ System.err.println("pixel format " + pformats[i] + " (index " + i + "): " + dbgCaps);
+ }
+ }
+
+ int pfdid = 0;
+ long tmpBuffer = 0;
+ {
+ int whichFormat;
+ // Loop is a workaround for bugs in NVidia's recent drivers
+ for (whichFormat = 0; whichFormat < nformats; whichFormat++) {
+ int format = pformats[whichFormat];
+
+ // Create the p-buffer.
+ niattribs = 0;
+
+ if (rtt) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FORMAT_ARB;
+ if (useFloat) {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_FLOAT_RGB_NV;
+ } else {
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_RGBA_ARB;
+ }
+
+ iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
+ iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
+
+ iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+
+ iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
+
+ iattributes[niattribs++] = 0;
+
+ tmpBuffer = wglExt.wglCreatePbufferARB(sharedHdc, format, getWidth(), getHeight(), iattributes, 0);
+ if (tmpBuffer != 0) {
+ // Done
+ break;
+ }
}
-
- iattributes[niattribs++] = WGLExt.WGL_TEXTURE_TARGET_ARB;
- iattributes[niattribs++] = rect ? WGLExt.WGL_TEXTURE_RECTANGLE_NV : WGLExt.WGL_TEXTURE_2D_ARB;
-
- iattributes[niattribs++] = WGLExt.WGL_MIPMAP_TEXTURE_ARB;
- iattributes[niattribs++] = GL.GL_FALSE;
-
- iattributes[niattribs++] = WGLExt.WGL_PBUFFER_LARGEST_ARB;
- iattributes[niattribs++] = GL.GL_FALSE;
+
+ if (0 == tmpBuffer) {
+ throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
+ " pixel formats, last error was: " + wglGetLastError());
+ }
+ pfdid = pformats[whichFormat];
+ }
+
+ // Get the device context.
+ long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer);
+ if (tmpHdc == 0) {
+ throw new GLException("pbuffer creation error: wglGetPbufferDC() failed");
+ }
+
+ NativeSurface ns = getNativeSurface();
+ // Set up instance variables
+ buffer = tmpBuffer;
+ ((SurfaceChangeable)ns).setSurfaceHandle(tmpHdc);
+ cachedWGLExt = wglExt;
+
+ // Re-query chosen pixel format
+ {
+ WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, sharedHdc, pfdid, glProfile, false, true);
+ if(null == newCaps) {
+ throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + GLDrawableImpl.toHexString(tmpHdc));
}
-
- iattributes[niattribs++] = 0;
-
- tmpBuffer = wglExt.wglCreatePbufferARB(parentHdc, format, getWidth(), getHeight(), iattributes, 0);
- if (tmpBuffer != 0) {
- // Done
- break;
+ if(newCaps.isOnscreen() || !newCaps.isPBuffer()) {
+ throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps);
}
+ config.setCapsPFD(newCaps);
}
-
- if (0 == tmpBuffer) {
- throw new GLException("pbuffer creation error: wglCreatePbuffer() failed: tried " + nformats +
- " pixel formats, last error was: " + wglGetLastError());
- }
- pfdid = pformats[whichFormat];
- }
-
- // Get the device context.
- long tmpHdc = wglExt.wglGetPbufferDCARB(tmpBuffer);
- if (tmpHdc == 0) {
- throw new GLException("pbuffer creation error: wglGetPbufferDC() failed");
- }
-
- NativeSurface ns = getNativeSurface();
- // Set up instance variables
- buffer = tmpBuffer;
- ((SurfaceChangeable)ns).setSurfaceHandle(tmpHdc);
- cachedWGLExt = wglExt;
-
- // Re-query chosen pixel format
- {
- WGLGLCapabilities newCaps = WindowsWGLGraphicsConfiguration.wglARBPFID2GLCapabilities(sharedResource, parentHdc, pfdid, glProfile, false, true);
- if(null == newCaps) {
- throw new GLException("pbuffer creation error: unable to re-query chosen PFD ID: " + pfdid + ", hdc " + GLDrawableImpl.toHexString(tmpHdc));
- }
- if(newCaps.isOnscreen() || !newCaps.isPBuffer()) {
- throw new GLException("Error: Selected Onscreen Caps for PBuffer: "+newCaps);
- }
- config.setCapsPFD(newCaps);
+
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
+ width = tmp[0];
+ wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
+ height = tmp[0];
+ ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
+ } finally {
+ sharedSurface.unlockSurface();
}
-
- // Determine the actual width and height we were able to create.
- int[] tmp = new int[1];
- wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_WIDTH_ARB, tmp, 0 );
- width = tmp[0];
- wglExt.wglQueryPbufferARB( buffer, WGLExt.WGL_PBUFFER_HEIGHT_ARB, tmp, 0 );
- height = tmp[0];
- ((SurfaceChangeable)ns).setSize(width, height);
}
private static String wglGetLastError() {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
index 8f2ec74af..ff59e1518 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLContext.java
@@ -55,7 +55,6 @@ import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
import jogamp.nativewindow.windows.GDI;
import jogamp.opengl.GLContextImpl;
-import jogamp.opengl.GLContextShareSet;
import jogamp.opengl.GLDrawableImpl;
public class WindowsWGLContext extends GLContextImpl {
@@ -118,7 +117,7 @@ public class WindowsWGLContext extends GLContextImpl {
public final boolean isGLReadDrawableAvailable() {
if(!wglGLReadDrawableAvailableSet && null != getWGLExtProcAddressTable()) {
WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
- AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
switch( factory.isReadDrawableAvailable(device) ) {
case 1:
@@ -257,20 +256,19 @@ public class WindowsWGLContext extends GLContextImpl {
* Creates and initializes an appropriate OpenGL context. Should only be
* called by {@link #makeCurrentImpl()}.
*/
- protected boolean createImpl() {
- WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
- AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ protected boolean createImpl(GLContextImpl shareWith) {
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
+ WindowsWGLDrawableFactory factory = (WindowsWGLDrawableFactory)drawable.getFactoryImpl();
WindowsWGLContext sharedContext = (WindowsWGLContext) factory.getOrCreateSharedContextImpl(device);
GLCapabilitiesImmutable glCaps = drawable.getChosenGLCapabilities();
isGLReadDrawableAvailable(); // trigger setup wglGLReadDrawableAvailable
// Windows can set up sharing of display lists after creation time
- WindowsWGLContext other = (WindowsWGLContext) GLContextShareSet.getShareContext(this);
long share = 0;
- if (other != null) {
- share = other.getHandle();
+ if (null != shareWith) {
+ share = shareWith.getHandle();
if (share == 0) {
throw new GLException("GLContextShareSet returned an invalid OpenGL context");
}
@@ -298,7 +296,7 @@ public class WindowsWGLContext extends GLContextImpl {
if (!WGL.wglMakeCurrent(drawable.getHandle(), temp_ctx)) {
throw new GLException("Error making temp context current: 0x" + toHexString(temp_ctx) + ", werr: "+GDI.GetLastError());
}
- setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("wglCreateContextAttribsARB");
WGL.wglMakeCurrent(0, 0); // release temp context
@@ -334,7 +332,7 @@ public class WindowsWGLContext extends GLContextImpl {
if(glCaps.getGLProfile().isGL3()) {
WGL.wglMakeCurrent(0, 0);
WGL.wglDeleteContext(temp_ctx);
- throw new GLException("WindowsWGLContext.createContext failed, but context > GL2 requested "+getGLVersion()+", ");
+ throw new GLException("WindowsWGLContext.createContext ctx !ARB, context > GL2 requested "+getGLVersion());
}
if(DEBUG) {
System.err.println("WindowsWGLContext.createContext failed, fall back to !ARB context "+getGLVersion());
@@ -347,29 +345,26 @@ public class WindowsWGLContext extends GLContextImpl {
WGL.wglDeleteContext(contextHandle);
throw new GLException("Error making old context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError());
}
+ if(0!=share) {
+ // Only utilize the classic GDI 'wglShareLists' shared context method
+ // for traditional non ARB context.
+ if (!WGL.wglShareLists(share, contextHandle)) {
+ throw new GLException("wglShareLists(" + toHexString(share) +
+ ", " + toHexString(contextHandle) + ") failed: werr " + GDI.GetLastError());
+ }
+ }
if (DEBUG) {
System.err.println(getThreadName() + ": createImpl: OK (old) share "+share);
}
}
- if(0!=share) {
- if (!WGL.wglShareLists(share, contextHandle)) {
- throw new GLException("wglShareLists(" + toHexString(share) +
- ", " + toHexString(contextHandle) + ") failed: werr " + GDI.GetLastError());
- }
- }
return true;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
if (WGL.wglGetCurrentContext() != contextHandle) {
if (!wglMakeContextCurrent(drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
throw new GLException("Error making context current: 0x" + toHexString(contextHandle) + ", werr: " + GDI.GetLastError() + ", " + this);
- } else {
- if (DEBUG && newCreated) {
- System.err.println(getThreadName() + ": wglMakeCurrent(hdc " + toHexString(drawable.getHandle()) +
- ", contextHandle " + toHexString(contextHandle) + ") succeeded");
- }
}
}
}
@@ -394,7 +389,7 @@ public class WindowsWGLContext extends GLContextImpl {
}
protected final void updateGLXProcAddressTable() {
- final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "WGL-"+adevice.getUniqueID();
if (DEBUG) {
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
index 4ed9a00c3..b96e0cd9b 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawable.java
@@ -41,6 +41,7 @@
package jogamp.opengl.windows.wgl;
import java.security.AccessController;
+
import javax.media.nativewindow.NativeSurface;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLException;
@@ -67,30 +68,31 @@ public abstract class WindowsWGLDrawable extends GLDrawableImpl {
}
NativeSurface ns = getNativeSurface();
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration)ns.getGraphicsConfiguration();
config.updateGraphicsConfiguration(getFactory(), ns, null);
if (DEBUG) {
System.err.println("!!! WindowsWGLDrawable.setRealized(true): "+config);
}
}
- protected void swapBuffersImpl() {
- long startTime = 0;
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ final long t0;
if (PROFILING) {
- startTime = System.currentTimeMillis();
+ t0 = System.currentTimeMillis();
+ } else {
+ t0 = 0;
}
- if (!GDI.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
+ if (!WGLUtil.SwapBuffers(getHandle()) && (GDI.GetLastError() != GDI.ERROR_SUCCESS)) {
throw new GLException("Error swapping buffers");
}
if (PROFILING) {
- long endTime = System.currentTimeMillis();
- profilingSwapBuffersTime += (endTime - startTime);
- int ticks = PROFILING_TICKS;
- if (++profilingSwapBuffersTicks == ticks) {
- System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + ticks + " calls (" +
- ((float) profilingSwapBuffersTime / (float) ticks) + " ms/call)");
+ profilingSwapBuffersTime += System.currentTimeMillis() - t0;
+ if (++profilingSwapBuffersTicks == PROFILING_TICKS) {
+ System.err.println("SwapBuffers calls: " + profilingSwapBuffersTime + " ms / " + PROFILING_TICKS + " calls (" +
+ ((float) profilingSwapBuffersTime / (float) PROFILING_TICKS) + " ms/call)");
profilingSwapBuffersTime = 0;
profilingSwapBuffersTicks = 0;
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
index cd22127a3..43c16240d 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLDrawableFactory.java
@@ -42,7 +42,6 @@ package jogamp.opengl.windows.wgl;
import java.nio.Buffer;
import java.nio.ShortBuffer;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -62,6 +61,7 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLProfile.ShutdownType;
import com.jogamp.common.JogampRuntimeException;
import com.jogamp.common.nio.PointerBuffer;
@@ -71,6 +71,7 @@ import com.jogamp.common.util.VersionNumber;
import jogamp.nativewindow.WrappedSurface;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
import jogamp.nativewindow.windows.GDISurface;
import jogamp.nativewindow.windows.RegisteredClassFactory;
import jogamp.opengl.DesktopGLDynamicLookupHelper;
@@ -80,60 +81,81 @@ import jogamp.opengl.GLDynamicLookupHelper;
import jogamp.opengl.SharedResourceRunner;
public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
- private static final DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper;
+ private static DesktopGLDynamicLookupHelper windowsWGLDynamicLookupHelper = null;
+
+ public WindowsWGLDrawableFactory() {
+ super();
- static {
- DesktopGLDynamicLookupHelper tmp = null;
- try {
- tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
+ synchronized(WindowsWGLDrawableFactory.class) {
+ if(null==windowsWGLDynamicLookupHelper) {
+ DesktopGLDynamicLookupHelper tmp = null;
+ try {
+ tmp = new DesktopGLDynamicLookupHelper(new WindowsWGLDynamicLibraryBundleInfo());
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ windowsWGLDynamicLookupHelper = tmp;
+ if(null!=windowsWGLDynamicLookupHelper) {
+ WGL.getWGLProcAddressTable().reset(windowsWGLDynamicLookupHelper);
+ }
}
}
- windowsWGLDynamicLookupHelper = tmp;
+
if(null!=windowsWGLDynamicLookupHelper) {
- WGL.getWGLProcAddressTable().reset(windowsWGLDynamicLookupHelper);
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ WindowsWGLGraphicsConfigurationFactory.registerFactory();
+ if(GLProfile.isAWTAvailable()) {
+ try {
+ ReflectionUtil.callStaticMethod("jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory",
+ "registerFactory", null, null, getClass().getClassLoader());
+ } catch (JogampRuntimeException jre) { /* n/a .. */ }
+ }
+
+ defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
+
+ // Init shared resources off thread
+ // Will be released via ShutdownHook
+ sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceRunner.start();
}
}
- public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) {
- return windowsWGLDynamicLookupHelper;
- }
-
- public WindowsWGLDrawableFactory() {
- super();
-
- // Register our GraphicsConfigurationFactory implementations
- // The act of constructing them causes them to be registered
- new WindowsWGLGraphicsConfigurationFactory();
- if(GLProfile.isAWTAvailable()) {
- try {
- ReflectionUtil.createInstance("jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory",
- null, getClass().getClassLoader());
- } catch (JogampRuntimeException jre) { /* n/a .. */ }
+ protected final void destroy(ShutdownType shutdownType) {
+ if(null != sharedResourceRunner) {
+ sharedResourceRunner.stop();
+ sharedResourceRunner = null;
}
+ if(null != sharedMap) {
+ sharedMap.clear();
+ sharedMap = null;
+ }
+ defaultDevice = null;
+ /**
+ * Pulling away the native library may cause havoc ..
+ *
+ if(ShutdownType.COMPLETE == shutdownType && null != windowsWGLDynamicLookupHelper) {
+ windowsWGLDynamicLookupHelper.destroy();
+ windowsWGLDynamicLookupHelper = null;
+ } */
+
+ RegisteredClassFactory.shutdownSharedClasses();
+ }
- defaultDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
-
- // Init shared resources off thread
- // Will be released via ShutdownHook
- sharedResourceImpl = new SharedResourceImplementation();
- sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl);
- sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner");
- sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running
- sharedResourceThread.start();
+ public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) {
+ return windowsWGLDynamicLookupHelper;
}
- WindowsGraphicsDevice defaultDevice;
- SharedResourceImplementation sharedResourceImpl;
- SharedResourceRunner sharedResourceRunner;
- Thread sharedResourceThread;
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+ private WindowsGraphicsDevice defaultDevice;
+ private SharedResourceRunner sharedResourceRunner;
+ private HashMap<String /*connection*/, SharedResourceRunner.Resource> sharedMap;
- long processAffinityChanges = 0;
- PointerBuffer procMask = PointerBuffer.allocateDirect(1);
- PointerBuffer sysMask = PointerBuffer.allocateDirect(1);
+ private long processAffinityChanges = 0;
+ private PointerBuffer procMask = PointerBuffer.allocateDirect(1);
+ private PointerBuffer sysMask = PointerBuffer.allocateDirect(1);
protected void enterThreadCriticalZone() {
synchronized (sysMask) {
@@ -251,15 +273,15 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
}
public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) {
synchronized(sharedMap) {
- return (SharedResourceRunner.Resource) sharedMap.put(connection, resource);
+ return sharedMap.put(connection, resource);
}
}
public SharedResourceRunner.Resource mapGet(String connection) {
synchronized(sharedMap) {
- return (SharedResourceRunner.Resource) sharedMap.get(connection);
+ return sharedMap.get(connection);
}
}
- public Collection/*<Resource>*/ mapValues() {
+ public Collection<SharedResourceRunner.Resource> mapValues() {
synchronized(sharedMap) {
return sharedMap.values();
}
@@ -270,15 +292,12 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
sharedDevice.lock();
try {
AbstractGraphicsScreen absScreen = new DefaultGraphicsScreen(sharedDevice, 0);
- if (null == absScreen) {
- throw new GLException("Couldn't create shared screen for device: "+sharedDevice+", idx 0");
- }
GLProfile glp = GLProfile.get(sharedDevice, GLProfile.GL_PROFILE_LIST_MIN_DESKTOP);
if (null == glp) {
throw new GLException("Couldn't get default GLProfile for device: "+sharedDevice);
}
final int f_dim = 64;
- long hwnd = GDI.CreateDummyWindow(0, 0, f_dim, f_dim);
+ long hwnd = GDIUtil.CreateDummyWindow(0, 0, f_dim, f_dim);
WindowsDummyWGLDrawable sharedDrawable = WindowsDummyWGLDrawable.create(WindowsWGLDrawableFactory.this, glp, absScreen, hwnd, f_dim, f_dim, true);
if (null == sharedDrawable) {
throw new GLException("Couldn't create shared drawable for screen: "+absScreen+", "+glp);
@@ -373,10 +392,21 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
final static String WGL_ARB_make_current_read = "WGL_ARB_make_current_read";
final static String wglMakeContextCurrent = "wglMakeContextCurrent";
- public final boolean getWasSharedContextCreated(AbstractGraphicsDevice device) {
- SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
- if(null!=sr) {
- return null != sr.getContext();
+ protected final Thread getSharedResourceThread() {
+ return sharedResourceRunner.start();
+ }
+
+ protected final boolean createSharedResource(AbstractGraphicsDevice device) {
+ try {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return null != sr.getContext();
+ }
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("Catched Exception while WindowsWGL Shared Resource initialization");
+ gle.printStackTrace();
+ }
}
return false;
}
@@ -409,11 +439,6 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
return (SharedResource) sharedResourceRunner.getOrCreateShared(device);
}
- protected final void shutdownInstance() {
- sharedResourceRunner.releaseAndWait();
- RegisteredClassFactory.shutdownSharedClasses();
- }
-
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
return WindowsWGLGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
}
@@ -429,40 +454,39 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration();
GLCapabilitiesImmutable chosenCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(!chosenCaps.isPBuffer()) {
return new WindowsBitmapWGLDrawable(this, target);
}
// PBuffer GLDrawable Creation
+ GLDrawableImpl pbufferDrawable;
final AbstractGraphicsDevice device = config.getScreen().getDevice();
+ /**
+ * Similar to ATI Bug https://bugzilla.mozilla.org/show_bug.cgi?id=486277,
+ * we need to have a context current on the same Display to create a PBuffer.
+ */
final SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
- if(null==sr) {
- throw new IllegalArgumentException("No shared resource for "+device);
- }
- final List returnList = new ArrayList();
- Runnable r = new Runnable() {
- public void run() {
- GLContext lastContext = GLContext.getCurrent();
- if (lastContext != null) {
+ if(null!=sr) {
+ GLContext lastContext = GLContext.getCurrent();
+ if (lastContext != null) {
lastContext.release();
- }
- sr.context.makeCurrent();
- try {
- GLDrawableImpl pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target, sr);
- returnList.add(pbufferDrawable);
- } finally {
+ }
+ sr.context.makeCurrent();
+ try {
+ pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target);
+ } finally {
sr.context.release();
if (lastContext != null) {
lastContext.makeCurrent();
}
- }
}
- };
- maybeDoSingleThreadedWorkaround(r);
- return (GLDrawableImpl) returnList.get(0);
+ } else {
+ pbufferDrawable = new WindowsPbufferWGLDrawable(WindowsWGLDrawableFactory.this, target);
+ }
+ return pbufferDrawable;
}
/**
@@ -489,7 +513,7 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl {
AbstractGraphicsScreen screen = DefaultGraphicsScreen.createDefault(NativeWindowFactory.TYPE_WINDOWS);
WrappedSurface ns = new WrappedSurface(WindowsWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(
capsChosen, capsRequested, chooser, screen) );
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
return ns;
}
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
index 989906514..d6788f1c9 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfiguration.java
@@ -37,7 +37,6 @@ import java.util.ArrayList;
import java.util.List;
import javax.media.nativewindow.AbstractGraphicsScreen;
-import javax.media.nativewindow.DefaultGraphicsConfiguration;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.opengl.GL;
@@ -48,13 +47,14 @@ import javax.media.opengl.GLException;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.GLProfile;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.windows.DWM_BLURBEHIND;
import jogamp.nativewindow.windows.GDI;
import jogamp.nativewindow.windows.MARGINS;
import jogamp.nativewindow.windows.PIXELFORMATDESCRIPTOR;
import jogamp.opengl.GLGraphicsConfigurationUtil;
-public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class WindowsWGLGraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
// Keep this under the same debug flag as the drawable factory for convenience
protected static final boolean DEBUG = jogamp.opengl.Debug.debug("GraphicsConfiguration");
@@ -149,7 +149,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
* @see #isDetermined()
*/
public final void preselectGraphicsConfiguration(GLDrawableFactory factory, int[] pfdIDs) {
- AbstractGraphicsDevice device = getNativeGraphicsConfiguration().getScreen().getDevice();
+ AbstractGraphicsDevice device = getScreen().getDevice();
WindowsWGLGraphicsConfigurationFactory.preselectGraphicsConfiguration(chooser, factory, device, this, pfdIDs);
}
@@ -161,7 +161,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
throw new GLException("Error: HDC is null");
}
- if (!GDI.SetPixelFormat(hdc, caps.getPFDID(), caps.getPFD())) {
+ if (!WGLUtil.SetPixelFormat(hdc, caps.getPFDID(), caps.getPFD())) {
throw new GLException("Unable to set pixel format " + caps +
" for device context " + toHexString(hdc) +
": error code " + GDI.GetLastError());
@@ -610,7 +610,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
}
PIXELFORMATDESCRIPTOR pfd = createPixelFormatDescriptor();
- if (GDI.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
+ if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
// remove displayable bits, since pfdID is non displayable
drawableTypeBits = drawableTypeBits & ~(GLGraphicsConfigurationUtil.WINDOW_BIT | GLGraphicsConfigurationUtil.BITMAP_BIT);
if( 0 == drawableTypeBits ) {
@@ -629,7 +629,7 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
//
static int[] wglAllGDIPFIDs(long hdc) {
- int numFormats = GDI.DescribePixelFormat(hdc, 1, 0, null);
+ int numFormats = WGLUtil.DescribePixelFormat(hdc, 1, 0, null);
if (numFormats == 0) {
throw new GLException("DescribePixelFormat: No formats - HDC 0x" + Long.toHexString(hdc) +
", LastError: " + GDI.GetLastError());
@@ -733,10 +733,10 @@ public class WindowsWGLGraphicsConfiguration extends DefaultGraphicsConfiguratio
static PIXELFORMATDESCRIPTOR createPixelFormatDescriptor(long hdc, int pfdID) {
PIXELFORMATDESCRIPTOR pfd = PIXELFORMATDESCRIPTOR.create();
- pfd.setNSize((short) pfd.size());
+ pfd.setNSize((short) PIXELFORMATDESCRIPTOR.size());
pfd.setNVersion((short) 1);
if(0 != hdc && 1 <= pfdID) {
- if (GDI.DescribePixelFormat(hdc, pfdID, pfd.size(), pfd) == 0) {
+ if (WGLUtil.DescribePixelFormat(hdc, pfdID, PIXELFORMATDESCRIPTOR.size(), pfd) == 0) {
// Accelerated pixel formats that are non displayable
if(DEBUG) {
System.err.println("Info: Non displayable pixel format " + pfdID + " of device context: error code " + GDI.GetLastError());
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
index a485f8ce8..f02520136 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/WindowsWGLGraphicsConfigurationFactory.java
@@ -67,8 +67,10 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
protected static final boolean DEBUG = jogamp.opengl.Debug.debug("GraphicsConfiguration");
static WGLGLCapabilities.PfdIDComparator PfdIDComparator = new WGLGLCapabilities.PfdIDComparator();
- WindowsWGLGraphicsConfigurationFactory() {
- GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, this);
+ static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.windows.WindowsGraphicsDevice.class, new WindowsWGLGraphicsConfigurationFactory());
+ }
+ private WindowsWGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
@@ -189,7 +191,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
if (0 == hdc) {
throw new GLException("Error: HDC is null");
}
- WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ WindowsWGLGraphicsConfiguration config = (WindowsWGLGraphicsConfiguration) ns.getGraphicsConfiguration();
if( !config.isExternal() ) {
if( !config.isDetermined() ) {
@@ -198,8 +200,8 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
// set PFD if not set yet
int pfdID = -1;
boolean set = false;
- if ( 1 > ( pfdID = GDI.GetPixelFormat(hdc) ) ) {
- if (!GDI.SetPixelFormat(hdc, config.getPixelFormatID(), config.getPixelFormat())) {
+ if ( 1 > ( pfdID = WGLUtil.GetPixelFormat(hdc) ) ) {
+ if (!WGLUtil.SetPixelFormat(hdc, config.getPixelFormatID(), config.getPixelFormat())) {
throw new GLException("Unable to set pixel format " + config.getPixelFormatID() +
" for device context " + toHexString(hdc) +
": error code " + GDI.GetLastError());
@@ -236,7 +238,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
}
if(NativeSurface.LOCK_SURFACE_NOT_READY >= sharedDrawable.lockSurface()) {
- throw new GLException("Surface not ready (lockSurface)");
+ throw new GLException("Shared Surface not ready (lockSurface): "+device+" -> "+sharedDrawable);
}
try {
long hdc = sharedDrawable.getHandle();
@@ -309,7 +311,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
- final int presetPFDID = extHDC ? -1 : GDI.GetPixelFormat(hdc) ;
+ final int presetPFDID = extHDC ? -1 : WGLUtil.GetPixelFormat(hdc) ;
if ( 1 <= presetPFDID ) {
// Pixelformat already set by either
// - a previous preselectGraphicsConfiguration() call on the same HDC,
@@ -431,7 +433,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
WGLGLCapabilities pixelFormatCaps = null; // chosen or preset PFD ID's caps
boolean pixelFormatSet = false; // indicates a preset PFD ID [caps]
- if ( !extHDC && 1 <= ( pfdID = GDI.GetPixelFormat(hdc) ) ) {
+ if ( !extHDC && 1 <= ( pfdID = WGLUtil.GetPixelFormat(hdc) ) ) {
// Pixelformat already set by either
// - a previous preselectGraphicsConfiguration() call on the same HDC,
// - the graphics driver, copying the HDC's pixelformat to the new one,
@@ -455,7 +457,7 @@ public class WindowsWGLGraphicsConfigurationFactory extends GLGraphicsConfigurat
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
PIXELFORMATDESCRIPTOR pfd = WindowsWGLGraphicsConfiguration.createPixelFormatDescriptor();
pfd = WindowsWGLGraphicsConfiguration.GLCapabilities2PFD(capsChosen, pfd);
- pfdID = GDI.ChoosePixelFormat(hdc, pfd);
+ pfdID = WGLUtil.ChoosePixelFormat(hdc, pfd);
int recommendedIndex = -1 ;
if( 1 <= pfdID ) {
// seek index ..
diff --git a/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
index 1f09180eb..0f9786f1d 100644
--- a/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/windows/wgl/awt/WindowsAWTWGLGraphicsConfigurationFactory.java
@@ -62,8 +62,10 @@ import javax.media.opengl.GLDrawableFactory;
public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
protected static final boolean DEBUG = jogamp.opengl.Debug.debug("GraphicsConfiguration");
- public WindowsAWTWGLGraphicsConfigurationFactory() {
- GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, new WindowsAWTWGLGraphicsConfigurationFactory());
+ }
+ private WindowsAWTWGLGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
@@ -76,7 +78,7 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu
}
if(null==absScreen) {
- absScreen = AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
+ absScreen = AWTGraphicsScreen.createDefault();
if(DEBUG) {
System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: creating default device: "+absScreen);
}
@@ -122,12 +124,17 @@ public class WindowsAWTWGLGraphicsConfigurationFactory extends GLGraphicsConfigu
// otherwise no hardware accelerated PFD could be achieved.
// - preselect with no constrains
// - try to create dedicated GC
- winConfig.preselectGraphicsConfiguration(drawableFactory, null);
- if ( 1 <= winConfig.getPixelFormatID() ) {
- chosenGC = Win32SunJDKReflection.graphicsConfigurationGet(device, winConfig.getPixelFormatID());
- if(DEBUG) {
- System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found new AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig);
+ try {
+ winConfig.preselectGraphicsConfiguration(drawableFactory, null);
+ if ( 1 <= winConfig.getPixelFormatID() ) {
+ chosenGC = Win32SunJDKReflection.graphicsConfigurationGet(device, winConfig.getPixelFormatID());
+ if(DEBUG) {
+ System.err.println("WindowsAWTWGLGraphicsConfigurationFactory: Found new AWT PFD ID "+winConfig.getPixelFormatID()+" -> "+winConfig);
+ }
}
+ } catch (GLException gle0) {
+ gle0.printStackTrace();
+ // go on ..
}
if( null == chosenGC ) {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
index e95c80205..33e85dd0b 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/GLXUtil.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
@@ -32,14 +33,40 @@
package jogamp.opengl.x11.glx;
-import javax.media.opengl.*;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
+import javax.media.opengl.GLException;
+import jogamp.opengl.Debug;
+
+import com.jogamp.common.util.VersionNumber;
public class GLXUtil {
- public static String getExtension(long display) {
- return GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS);
- }
+ public static final boolean DEBUG = Debug.debug("GLXUtil");
+
+ public static VersionNumber getGLXServerVersionNumber(long display) {
+ int[] major = new int[1];
+ int[] minor = new int[1];
+
+ if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+ // Work around bugs in ATI's Linux drivers where they report they
+ // only implement GLX version 1.2 on the server side
+ if (major[0] == 1 && minor[0] == 2) {
+ String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
+ try {
+ // e.g. "1.3"
+ major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
+ minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
+ } catch (Exception e) {
+ major[0] = 1;
+ minor[0] = 2;
+ }
+ }
+ return new VersionNumber(major[0], minor[0], 0);
+ }
+
public static boolean isMultisampleAvailable(String extensions) {
if (extensions != null) {
return (extensions.indexOf("GLX_ARB_multisample") >= 0);
@@ -47,16 +74,6 @@ public class GLXUtil {
return false;
}
- public static boolean isMultisampleAvailable(long display) {
- return isMultisampleAvailable(getExtension(display));
- }
-
- /** Workaround for apparent issue with ATI's proprietary drivers
- where direct contexts still send GLX tokens for GL calls */
- public static String getVendorName(long display) {
- return GLX.glXGetClientString(display, GLX.GLX_VENDOR);
- }
-
public static boolean isVendorNVIDIA(String vendor) {
return vendor != null && vendor.startsWith("NVIDIA") ;
}
@@ -65,38 +82,48 @@ public class GLXUtil {
return vendor != null && vendor.startsWith("ATI") ;
}
- public static boolean isVendorATI(long display) {
- return isVendorATI(getVendorName(display));
+ public static boolean isClientMultisampleAvailable() {
+ return clientMultisampleAvailable;
}
-
- public static boolean isVendorNVIDIA(long display) {
- return isVendorNVIDIA(getVendorName(display));
+ public static String getClientVendorName() {
+ return clientVendorName;
}
-
- public static void getGLXVersion(long display, int major[], int minor[]) {
- if(0 == display) {
- throw new GLException("null display handle");
+ public static VersionNumber getClientVersionNumber() {
+ return clientVersionNumber;
+ }
+ public static synchronized boolean initGLXClientDataSingleton(X11GraphicsDevice x11Device) {
+ if(null != clientVendorName) {
+ return false;
}
- if(major.length<1||minor.length<1) {
- throw new GLException("passed int arrays size is not >= 1");
+ if(DEBUG) {
+ System.err.println("initGLXClientDataSingleton: "+x11Device);
+ Thread.dumpStack();
}
-
- if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
- throw new GLException("glXQueryVersion failed");
+ if(null == x11Device) {
+ throw new GLException("null X11GraphicsDevice");
}
-
- // Work around bugs in ATI's Linux drivers where they report they
- // only implement GLX version 1.2 on the server side
- if (major[0] == 1 && minor[0] == 2) {
- String str = GLX.glXGetClientString(display, GLX.GLX_VERSION);
- try {
+ if(0 == x11Device.getHandle()) {
+ throw new GLException("null X11GraphicsDevice display handle");
+ }
+
+ clientMultisampleAvailable = isMultisampleAvailable(GLX.glXGetClientString(x11Device.getHandle(), GLX.GLX_EXTENSIONS));
+ clientVendorName = GLX.glXGetClientString(x11Device.getHandle(), GLX.GLX_VENDOR);
+
+ int[] major = new int[1];
+ int[] minor = new int[1];
+ final String str = GLX.glXGetClientString(x11Device.getHandle(), GLX.GLX_VERSION);
+ try {
// e.g. "1.3"
major[0] = Integer.valueOf(str.substring(0, 1)).intValue();
minor[0] = Integer.valueOf(str.substring(2, 3)).intValue();
- } catch (Exception e) {
+ } catch (Exception e) {
major[0] = 1;
minor[0] = 2;
- }
}
+ clientVersionNumber = new VersionNumber(major[0], minor[0], 0);
+ return true;
}
+ private static boolean clientMultisampleAvailable = false;
+ private static String clientVendorName = null;
+ private static VersionNumber clientVersionNumber = null;
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
index 68bdb4ab8..6be74c0e9 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11DummyGLXDrawable.java
@@ -50,16 +50,16 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
this.realized = true;
WrappedSurface ns = (WrappedSurface) getNativeSurface();
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)ns.getGraphicsConfiguration();
X11GraphicsDevice device = (X11GraphicsDevice) screen.getDevice();
long dpy = device.getHandle();
int scrn = screen.getIndex();
long visualID = config.getVisualID();
- dummyWindow = X11Util.CreateDummyWindow(dpy, scrn, visualID, f_dim, f_dim);
+ dummyWindow = X11Lib.CreateDummyWindow(dpy, scrn, visualID, f_dim, f_dim);
ns.setSurfaceHandle( dummyWindow );
- ns.setSize(f_dim, f_dim);
+ ns.surfaceSizeChanged(f_dim, f_dim);
updateHandle();
}
@@ -83,8 +83,8 @@ public class X11DummyGLXDrawable extends X11OnscreenGLXDrawable {
protected void destroyImpl() {
if(0!=dummyWindow) {
destroyHandle();
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- X11Util.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow);
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration();
+ X11Lib.DestroyDummyWindow(config.getScreen().getDevice().getHandle(), dummyWindow);
}
}
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
index d0d9929a0..4a949ea74 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXContext.java
@@ -53,7 +53,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
super(drawable, null);
this.contextHandle = ctx;
GLContextShareSet.contextCreated(this);
- setGLFunctionAvailability(false, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
+ setGLFunctionAvailability(false, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY);
getGLStateTracker().setEnabled(false); // external context usage can't track state in Java
}
@@ -72,7 +72,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
}
int[] val = new int[1];
GLX.glXQueryContext(display, ctx, GLX.GLX_SCREEN, val, 0);
- X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0], false);
GLX.glXQueryContext(display, ctx, GLX.GLX_FBCONFIG_ID, val, 0);
X11GLXGraphicsConfiguration cfg = null;
@@ -95,7 +95,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
return new X11ExternalGLXContext(new Drawable(factory, ns), ctx);
}
- protected boolean createImpl() {
+ protected boolean createImpl(GLContextImpl shareWith) {
return true;
}
@@ -116,7 +116,7 @@ public class X11ExternalGLXContext extends X11GLXContext {
lastContext = null;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
}
protected void releaseImpl() throws GLException {
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
index eb286cdf0..ca30fde3b 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11ExternalGLXDrawable.java
@@ -66,7 +66,7 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable {
}
int[] val = new int[1];
GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0);
- X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0]);
+ X11GraphicsScreen x11Screen = (X11GraphicsScreen) X11GraphicsScreen.createScreenDevice(display, val[0], false);
GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
X11GLXGraphicsConfiguration cfg = X11GLXGraphicsConfiguration.create(glp, x11Screen, val[0]);
@@ -85,7 +85,7 @@ public class X11ExternalGLXDrawable extends X11GLXDrawable {
}
WrappedSurface ns = new WrappedSurface(cfg);
ns.setSurfaceHandle(drawable);
- ns.setSize(w, h);
+ ns.surfaceSizeChanged(w, h);
return new X11ExternalGLXDrawable(factory, ns);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
index 904379058..c86001969 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXContext.java
@@ -40,28 +40,33 @@
package jogamp.opengl.x11.glx;
-import java.nio.*;
-import java.util.*;
-
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.X11GraphicsDevice;
+import java.nio.ByteBuffer;
+import java.nio.IntBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableImpl;
import com.jogamp.common.nio.Buffers;
-import com.jogamp.common.util.VersionNumber;
-import jogamp.opengl.*;
import com.jogamp.gluegen.runtime.ProcAddressTable;
import com.jogamp.gluegen.runtime.opengl.GLProcAddressResolver;
-import jogamp.nativewindow.x11.X11Util;
public abstract class X11GLXContext extends GLContextImpl {
protected static final boolean TRACE_CONTEXT_CURRENT = false; // true;
private static final Map<String, String> functionNameMap;
private static final Map<String, String> extensionNameMap;
- private VersionNumber glXVersion;
- private boolean glXVersionOneOneCapable;
- private boolean glXVersionOneThreeCapable;
private GLXExt _glXExt;
// Table that holds the addresses of the native C-language entry points for
// GLX extension functions.
@@ -91,9 +96,6 @@ public abstract class X11GLXContext extends GLContextImpl {
@Override
protected void resetStates() {
- glXVersion = null;
- glXVersionOneOneCapable = false;
- glXVersionOneThreeCapable = false;
// no inner state _glXExt=null;
glXExtProcAddressTable = null;
hasSwapIntervalSGI = 0;
@@ -125,25 +127,10 @@ public abstract class X11GLXContext extends GLContextImpl {
protected Map<String, String> getExtensionNameMap() { return extensionNameMap; }
- private final void initGLXVersion() {
- if(null == glXVersion) {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
- X11GraphicsDevice device = (X11GraphicsDevice) config.getScreen().getDevice();
-
- glXVersion = X11GLXDrawableFactory.getGLXVersion(device);
- glXVersionOneOneCapable = ( null != glXVersion ) ? glXVersion.compareTo(GLDrawableFactoryImpl.versionOneOne) >= 0 : false ;
- glXVersionOneThreeCapable = ( null != glXVersion ) ? glXVersion.compareTo(GLDrawableFactoryImpl.versionOneThree) >= 0 : false ;
- }
- }
- public final boolean isGLXVersionGreaterEqualOneOne() {
- initGLXVersion();
- return glXVersionOneOneCapable;
- }
- public final boolean isGLXVersionGreaterEqualOneThree() {
- initGLXVersion();
- return glXVersionOneThreeCapable;
+ protected final boolean isGLXVersionGreaterEqualOneThree() {
+ return ((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneThree(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice());
}
-
+
public final boolean isGLReadDrawableAvailable() {
return isGLXVersionGreaterEqualOneThree();
}
@@ -154,10 +141,10 @@ public abstract class X11GLXContext extends GLContextImpl {
try {
if(TRACE_CONTEXT_CURRENT) {
Throwable t = new Throwable(Thread.currentThread()+" - glXMakeContextCurrent("+toHexString(dpy)+", "+
- toHexString(writeDrawable)+", "+toHexString(readDrawable)+", "+toHexString(ctx)+") - GLX >= 1.3 "+ glXVersionOneThreeCapable);
+ toHexString(writeDrawable)+", "+toHexString(readDrawable)+", "+toHexString(ctx)+") - GLX >= 1.3 "+ isGLXVersionGreaterEqualOneThree());
t.printStackTrace();
}
- if ( glXVersionOneThreeCapable ) {
+ if ( isGLXVersionGreaterEqualOneThree() ) {
res = GLX.glXMakeContextCurrent(dpy, writeDrawable, readDrawable, ctx);
} else if ( writeDrawable == readDrawable ) {
res = GLX.glXMakeCurrent(dpy, writeDrawable, ctx);
@@ -179,7 +166,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
protected void destroyContextARBImpl(long ctx) {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
long display = config.getScreen().getDevice().getHandle();
glXMakeContextCurrent(display, 0, 0, 0);
@@ -239,16 +226,16 @@ public abstract class X11GLXContext extends GLContextImpl {
attribs.put(ctx_arb_attribs_idx_flags + 1, flags);
}
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
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.
- X11Util.XSync(display, false);
+ X11Lib.XSync(display, false);
ctx = _glXExt.glXCreateContextAttribsARB(display, config.getFBConfig(), share, direct, attribs);
- X11Util.XSync(display, false);
+ X11Lib.XSync(display, false);
} catch (RuntimeException re) {
if(DEBUG) {
Throwable t = new Throwable("Info: X11GLXContext.createContextARBImpl glXCreateContextAttribsARB failed with "+getGLVersion(major, minor, ctp, "@creation"), re);
@@ -274,32 +261,29 @@ public abstract class X11GLXContext extends GLContextImpl {
return ctx;
}
- protected boolean createImpl() {
+ protected boolean createImpl(GLContextImpl shareWith) {
// covers the whole context creation loop incl createContextARBImpl and destroyContextARBImpl
X11Util.setX11ErrorHandler(true, true);
try {
- return createImplRaw();
+ return createImplRaw(shareWith);
} finally {
X11Util.setX11ErrorHandler(false, false);
}
}
- private boolean createImplRaw() {
+ private boolean createImplRaw(GLContextImpl shareWith) {
boolean direct = true; // try direct always
isDirect = false; // fall back
X11GLXDrawableFactory factory = (X11GLXDrawableFactory)drawable.getFactoryImpl();
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsDevice device = config.getScreen().getDevice();
X11GLXContext sharedContext = (X11GLXContext) factory.getOrCreateSharedContextImpl(device);
long display = device.getHandle();
- isGLReadDrawableAvailable(); // trigger setup glXVersionOneThreeCapable
-
- X11GLXContext other = (X11GLXContext) GLContextShareSet.getShareContext(this);
long share = 0;
- if (other != null) {
- share = other.getHandle();
+ if (shareWith != null) {
+ share = shareWith.getHandle();
if (share == 0) {
throw new GLException("GLContextShareSet returned an invalid OpenGL context");
}
@@ -321,7 +305,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), contextHandle)) {
throw new GLException("Error making temp context(0) current: display "+toHexString(display)+", context "+toHexString(contextHandle)+", drawable "+drawable);
}
- setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
isDirect = GLX.glXIsDirect(display, contextHandle);
if (DEBUG) {
System.err.println(getThreadName() + ": createContextImpl: OK (old-1) share "+share+", direct "+isDirect+"/"+direct);
@@ -351,7 +335,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if (!glXMakeContextCurrent(display, drawable.getHandle(), drawableRead.getHandle(), temp_ctx)) {
throw new GLException("Error making temp context(1) current: display "+toHexString(display)+", context "+toHexString(temp_ctx)+", drawable "+drawable);
}
- setGLFunctionAvailability(true, true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
+ setGLFunctionAvailability(true, 0, 0, CTX_PROFILE_COMPAT|CTX_OPTION_ANY); // use GL_VERSION
boolean isCreateContextAttribsARBAvailable = isFunctionAvailable("glXCreateContextAttribsARB");
glXMakeContextCurrent(display, 0, 0, 0); // release temp context
@@ -386,7 +370,7 @@ public abstract class X11GLXContext extends GLContextImpl {
if(glp.isGL3()) {
glXMakeContextCurrent(display, 0, 0, 0);
GLX.glXDestroyContext(display, temp_ctx);
- throw new GLException("X11GLXContext.createContextImpl failed, but context > GL2 requested - requested: "+glp+", current: "+getGLVersion()+", ");
+ throw new GLException("X11GLXContext.createContextImpl ctx !ARB, context > GL2 requested - requested: "+glp+", current: "+getGLVersion()+", ");
}
if(DEBUG) {
System.err.println("X11GLXContext.createContextImpl failed, fall back to !ARB context "+getGLVersion());
@@ -410,7 +394,7 @@ public abstract class X11GLXContext extends GLContextImpl {
return true;
}
- protected void makeCurrentImpl(boolean newCreated) throws GLException {
+ protected void makeCurrentImpl() throws GLException {
long dpy = drawable.getNativeSurface().getDisplayHandle();
if (GLX.glXGetCurrentContext() != contextHandle) {
@@ -422,13 +406,6 @@ public abstract class X11GLXContext extends GLContextImpl {
} finally {
X11Util.setX11ErrorHandler(false, false);
}
- if (DEBUG && newCreated) {
- System.err.println(getThreadName() + ": glXMakeCurrent(display " +
- toHexString(dpy)+
- ", drawable " + toHexString(drawable.getHandle()) +
- ", drawableRead " + toHexString(drawableRead.getHandle()) +
- ", context " + toHexString(contextHandle) + ") succeeded");
- }
}
}
@@ -460,7 +437,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
protected final void updateGLXProcAddressTable() {
- final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ final AbstractGraphicsConfiguration aconfig = drawable.getNativeSurface().getGraphicsConfiguration();
final AbstractGraphicsDevice adevice = aconfig.getScreen().getDevice();
final String key = "GLX-"+adevice.getUniqueID();
if (DEBUG) {
@@ -493,10 +470,12 @@ public abstract class X11GLXContext extends GLContextImpl {
protected final StringBuffer getPlatformExtensionsStringImpl() {
StringBuffer sb = new StringBuffer();
if (DEBUG) {
- System.err.println("!!! GLX Version "+glXVersion);
+ System.err.println("!!! GLX Version client version "+ GLXUtil.getClientVersionNumber()+
+ ", server: "+
+ ((X11GLXDrawableFactory)drawable.getFactoryImpl()).getGLXVersionNumber(drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice()));
}
- if(isGLXVersionGreaterEqualOneOne()) {
- final NativeSurface ns = drawable.getNativeSurface();
+ final NativeSurface ns = drawable.getNativeSurface();
+ if(((X11GLXDrawableFactory)drawable.getFactoryImpl()).isGLXVersionGreaterEqualOneOne(ns.getGraphicsConfiguration().getScreen().getDevice())) {
{
final String ret = GLX.glXGetClientString(ns.getDisplayHandle(), GLX.GLX_EXTENSIONS);
if (DEBUG) {
@@ -526,14 +505,14 @@ public abstract class X11GLXContext extends GLContextImpl {
if (glExtensionName.equals("GL_ARB_pbuffer") ||
glExtensionName.equals("GL_ARB_pixel_format")) {
return getGLDrawable().getFactory().canCreateGLPbuffer(
- drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getScreen().getDevice() );
+ drawable.getNativeSurface().getGraphicsConfiguration().getScreen().getDevice() );
}
return super.isExtensionAvailable(glExtensionName);
}
@Override
protected void setSwapIntervalImpl(int interval) {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)drawable.getNativeSurface().getGraphicsConfiguration();
GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(!glCaps.isOnscreen()) return;
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
index d2ce629df..28c02cd06 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawable.java
@@ -42,6 +42,7 @@ package jogamp.opengl.x11.glx;
import javax.media.nativewindow.*;
import javax.media.opengl.*;
+
import jogamp.opengl.*;
public abstract class X11GLXDrawable extends GLDrawableImpl {
@@ -55,7 +56,7 @@ public abstract class X11GLXDrawable extends GLDrawableImpl {
protected void setRealizedImpl() {
if(realized) {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration();
config.updateGraphicsConfiguration();
if (DEBUG) {
@@ -64,9 +65,10 @@ public abstract class X11GLXDrawable extends GLDrawableImpl {
}
}
- protected void swapBuffersImpl() {
- GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
- }
+ protected final void swapBuffersImpl() {
+ // single-buffer is already filtered out @ GLDrawableImpl#swapBuffers()
+ GLX.glXSwapBuffers(getNativeSurface().getDisplayHandle(), getHandle());
+ }
//---------------------------------------------------------------------------
// Internals only below this point
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
index 51316dc77..acced638f 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXDrawableFactory.java
@@ -37,115 +37,156 @@
package jogamp.opengl.x11.glx;
+import java.nio.Buffer;
+import java.nio.ShortBuffer;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
-import java.nio.*;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
-import javax.media.opengl.*;
+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.x11.X11GraphicsDevice;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawable;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLProfile.ShutdownType;
-import jogamp.opengl.*;
-
-import com.jogamp.common.JogampRuntimeException;
-import com.jogamp.common.util.*;
import jogamp.nativewindow.WrappedSurface;
-import jogamp.nativewindow.x11.*;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
+import jogamp.opengl.DesktopGLDynamicLookupHelper;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableFactoryImpl;
+import jogamp.opengl.GLDrawableImpl;
+import jogamp.opengl.GLDynamicLookupHelper;
+import jogamp.opengl.SharedResourceRunner;
+
+import com.jogamp.common.util.VersionNumber;
public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
- private static final DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper;
+ public static final VersionNumber versionOneZero = new VersionNumber(1, 0, 0);
+ public static final VersionNumber versionOneOne = new VersionNumber(1, 1, 0);
+ public static final VersionNumber versionOneTwo = new VersionNumber(1, 2, 0);
+ public static final VersionNumber versionOneThree = new VersionNumber(1, 3, 0);
+ public static final VersionNumber versionOneFour = new VersionNumber(1, 4, 0);
- static {
- DesktopGLDynamicLookupHelper tmp = null;
- try {
- tmp = new DesktopGLDynamicLookupHelper(new X11GLXDynamicLibraryBundleInfo());
- } catch (GLException gle) {
- if(DEBUG) {
- gle.printStackTrace();
+ private static DesktopGLDynamicLookupHelper x11GLXDynamicLookupHelper = null;
+
+ public X11GLXDrawableFactory() {
+ super();
+
+ synchronized(X11GLXDrawableFactory.class) {
+ if(null==x11GLXDynamicLookupHelper) {
+ DesktopGLDynamicLookupHelper tmp = null;
+ try {
+ tmp = new DesktopGLDynamicLookupHelper(new X11GLXDynamicLibraryBundleInfo());
+ } catch (GLException gle) {
+ if(DEBUG) {
+ gle.printStackTrace();
+ }
+ }
+ x11GLXDynamicLookupHelper = tmp;
+ if(null!=x11GLXDynamicLookupHelper) {
+ GLX.getGLXProcAddressTable().reset(x11GLXDynamicLookupHelper);
+ }
}
}
- x11GLXDynamicLookupHelper = tmp;
- if(null!=x11GLXDynamicLookupHelper) {
- GLX.getGLXProcAddressTable().reset(x11GLXDynamicLookupHelper);
+
+ if(null!=x11GLXDynamicLookupHelper) {
+ // Register our GraphicsConfigurationFactory implementations
+ // The act of constructing them causes them to be registered
+ X11GLXGraphicsConfigurationFactory.registerFactory();
+
+ defaultDevice = new X11GraphicsDevice(X11Util.getNullDisplayName(), AbstractGraphicsDevice.DEFAULT_UNIT);
+ sharedMap = new HashMap<String, SharedResourceRunner.Resource>();
+
+ // Init shared resources off thread
+ // Will be released via ShutdownHook
+ sharedResourceRunner = new SharedResourceRunner(new SharedResourceImplementation());
+ sharedResourceRunner.start();
+ }
+ }
+
+ protected final void destroy(ShutdownType shutdownType) {
+ if(null != sharedResourceRunner) {
+ sharedResourceRunner.stop();
+ sharedResourceRunner = null;
}
- }
+ if(null != sharedMap) {
+ sharedMap.clear();
+ sharedMap = null;
+ }
+ defaultDevice = null;
+ /**
+ * Pulling away the native library may cause havoc ..
+ *
+ if(ShutdownType.COMPLETE == shutdownType && null != x11GLXDynamicLookupHelper) {
+ x11GLXDynamicLookupHelper.destroy();
+ x11GLXDynamicLookupHelper = null;
+ } */
- public static VersionNumber getGLXVersion(X11GraphicsDevice device) {
- int[] major = new int[1];
- int[] minor = new int[1];
- GLXUtil.getGLXVersion(device.getHandle(), major, minor);
- return new VersionNumber(major[0], minor[0], 0);
+ // Don't really close pending Display connections,
+ // since this may trigger a JVM exception
+ X11Util.shutdown( false, DEBUG );
}
public GLDynamicLookupHelper getGLDynamicLookupHelper(int profile) {
return x11GLXDynamicLookupHelper;
}
- public X11GLXDrawableFactory() {
- super();
- // Register our GraphicsConfigurationFactory implementations
- // The act of constructing them causes them to be registered
- new X11GLXGraphicsConfigurationFactory();
- if(GLProfile.isAWTAvailable()) {
- try {
- ReflectionUtil.createInstance("jogamp.opengl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory",
- null, getClass().getClassLoader());
- } catch (JogampRuntimeException jre) { /* n/a .. */ }
- }
-
- defaultDevice = new X11GraphicsDevice(X11Util.getNullDisplayName(), AbstractGraphicsDevice.DEFAULT_UNIT);
-
- // Init shared resources off thread
- // Will be released via ShutdownHook
- sharedResourceImpl = new SharedResourceImplementation();
- sharedResourceRunner = new SharedResourceRunner(sharedResourceImpl);
- sharedResourceThread = new Thread(sharedResourceRunner, Thread.currentThread().getName()+"-SharedResourceRunner");
- sharedResourceThread.setDaemon(true); // Allow JVM to exit, even if this one is running
- sharedResourceThread.start();
- }
-
- X11GraphicsDevice defaultDevice;
- SharedResourceImplementation sharedResourceImpl;
- SharedResourceRunner sharedResourceRunner;
- Thread sharedResourceThread;
- HashMap/*<connection, SharedResource>*/ sharedMap = new HashMap();
+ private X11GraphicsDevice defaultDevice;
+ private SharedResourceRunner sharedResourceRunner;
+ private HashMap<String /* connection */, SharedResourceRunner.Resource> sharedMap;
static class SharedResource implements SharedResourceRunner.Resource {
X11GraphicsDevice device;
X11GraphicsScreen screen;
X11DummyGLXDrawable drawable;
X11GLXContext context;
- String glXVendorName;
- boolean isGLXVendorATI;
- boolean isGLXVendorNVIDIA;
- VersionNumber glXVersion;
+ String glXServerVendorName;
+ boolean isGLXServerVendorATI;
+ boolean isGLXServerVendorNVIDIA;
+ VersionNumber glXServerVersion;
+ boolean glXServerVersionOneOneCapable;
+ boolean glXServerVersionOneThreeCapable;
+ boolean glXMultisampleAvailable;
SharedResource(X11GraphicsDevice dev, X11GraphicsScreen scrn,
X11DummyGLXDrawable draw, X11GLXContext ctx,
- VersionNumber glXVer, String glXVendor) {
+ VersionNumber glXServerVer, String glXServerVendor, boolean glXServerMultisampleAvail) {
device = dev;
screen = scrn;
drawable = draw;
context = ctx;
- glXVersion = glXVer;
- glXVendorName = glXVendor;
- isGLXVendorATI = GLXUtil.isVendorATI(glXVendorName);
- isGLXVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXVendorName);
+ glXServerVersion = glXServerVer;
+ glXServerVersionOneOneCapable = glXServerVersion.compareTo(versionOneOne) >= 0 ;
+ glXServerVersionOneThreeCapable = glXServerVersion.compareTo(versionOneThree) >= 0 ;
+ glXServerVendorName = glXServerVendor;
+ isGLXServerVendorATI = GLXUtil.isVendorATI(glXServerVendorName);
+ isGLXServerVendorNVIDIA = GLXUtil.isVendorNVIDIA(glXServerVendorName);
+ glXMultisampleAvailable = glXServerMultisampleAvail;
}
final public AbstractGraphicsDevice getDevice() { return device; }
final public AbstractGraphicsScreen getScreen() { return screen; }
final public GLDrawableImpl getDrawable() { return drawable; }
final public GLContextImpl getContext() { return context; }
- final String getGLXVendorName() { return glXVendorName; }
- final boolean isGLXVendorATI() { return isGLXVendorATI; }
- final boolean isGLXVendorNVIDIA() { return isGLXVendorNVIDIA; }
- final VersionNumber getGLXVersion() { return glXVersion; }
- final boolean isGLXVersionGreaterEqualOneThree() {
- return ( null != glXVersion ) ? glXVersion.compareTo(versionOneThree) >= 0 : false ;
- }
+ final String getGLXVendorName() { return glXServerVendorName; }
+ final boolean isGLXVendorATI() { return isGLXServerVendorATI; }
+ final boolean isGLXVendorNVIDIA() { return isGLXServerVendorNVIDIA; }
+ final VersionNumber getGLXVersion() { return glXServerVersion; }
+ final boolean isGLXVersionGreaterEqualOneOne() { return glXServerVersionOneOneCapable; }
+ final boolean isGLXVersionGreaterEqualOneThree() { return glXServerVersionOneThreeCapable; }
+ final boolean isGLXMultisampleAvailable() { return glXMultisampleAvailable; }
}
class SharedResourceImplementation implements SharedResourceRunner.Implementation {
@@ -156,27 +197,33 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
public SharedResourceRunner.Resource mapPut(String connection, SharedResourceRunner.Resource resource) {
synchronized(sharedMap) {
- return (SharedResourceRunner.Resource) sharedMap.put(connection, resource);
+ return sharedMap.put(connection, resource);
}
}
public SharedResourceRunner.Resource mapGet(String connection) {
synchronized(sharedMap) {
- return (SharedResourceRunner.Resource) sharedMap.get(connection);
+ return sharedMap.get(connection);
}
}
- public Collection/*<Resource>*/ mapValues() {
+ public Collection<SharedResourceRunner.Resource> mapValues() {
synchronized(sharedMap) {
return sharedMap.values();
}
}
public SharedResourceRunner.Resource createSharedResource(String connection) {
- X11GraphicsDevice sharedDevice = new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT);
- sharedDevice.setCloseDisplay(true);
+ X11GraphicsDevice sharedDevice =
+ new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
+ true); // own non-shared display connection, no locking
+ // new X11GraphicsDevice(X11Util.openDisplay(connection), AbstractGraphicsDevice.DEFAULT_UNIT,
+ // NativeWindowFactory.getNullToolkitLock(), true); // own non-shared display connection, no locking
sharedDevice.lock();
try {
- String glXVendorName = GLXUtil.getVendorName(sharedDevice.getHandle());
- if(X11Util.ATI_HAS_XCLOSEDISPLAY_BUG && GLXUtil.isVendorATI(glXVendorName)) {
+ GLXUtil.initGLXClientDataSingleton(sharedDevice);
+ final String glXServerVendorName = GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_VENDOR);
+ final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(sharedDevice.getHandle());
+ final boolean glXServerMultisampleAvailable = GLXUtil.isMultisampleAvailable(GLX.glXQueryServerString(sharedDevice.getHandle(), 0, GLX.GLX_EXTENSIONS));
+ if(X11Util.ATI_HAS_XCLOSEDISPLAY_BUG && GLXUtil.isVendorATI(glXServerVendorName)) {
X11Util.setMarkAllDisplaysUnclosable(true);
X11Util.markDisplayUncloseable(sharedDevice.getHandle());
}
@@ -195,7 +242,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
throw new GLException("Couldn't create shared context for drawable: "+sharedDrawable);
}
sharedContext.setSynchronized(true);
- VersionNumber glXVersion = getGLXVersion(sharedDevice);
boolean madeCurrent = false;
sharedContext.makeCurrent();
try {
@@ -207,11 +253,16 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
System.err.println("!!! SharedDevice: " + sharedDevice);
System.err.println("!!! SharedScreen: " + sharedScreen);
System.err.println("!!! SharedContext: " + sharedContext + ", madeCurrent " + madeCurrent);
- System.err.println("!!! GLX Vendor: " + glXVendorName);
- System.err.println("!!! GLX Version: " + glXVersion
- + " >= 1.3: " + (glXVersion.compareTo(versionOneThree) >= 0));
+ System.err.println("!!! GLX Server Vendor: " + glXServerVendorName);
+ System.err.println("!!! GLX Server Version: " + glXServerVersion);
+ System.err.println("!!! GLX Server Multisample: " + glXServerMultisampleAvailable);
+ System.err.println("!!! GLX Client Vendor: " + GLXUtil.getClientVendorName());
+ System.err.println("!!! GLX Client Version: " + GLXUtil.getClientVersionNumber());
+ System.err.println("!!! GLX Client Multisample: " + GLXUtil.isClientMultisampleAvailable());
}
- return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext, glXVersion, glXVendorName);
+ return new SharedResource(sharedDevice, sharedScreen, sharedDrawable, sharedContext,
+ glXServerVersion, glXServerVendorName,
+ glXServerMultisampleAvailable && GLXUtil.isClientMultisampleAvailable());
} catch (Throwable t) {
throw new GLException("X11GLXDrawableFactory - Could not initialize shared resources for "+connection, t);
} finally {
@@ -227,15 +278,18 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
System.err.println("!!! Screen : " + sr.screen);
System.err.println("!!! Drawable: " + sr.drawable);
System.err.println("!!! CTX : " + sr.context);
+ Thread.dumpStack();
}
if (null != sr.context) {
- // may cause JVM SIGSEGV: sharedContext.destroy();
+ // may cause JVM SIGSEGV:
+ sr.context.destroy();
sr.context = null;
}
if (null != sr.drawable) {
- // may cause JVM SIGSEGV: sharedDrawable.destroy();
+ // may cause JVM SIGSEGV:
+ sr.drawable.destroy();
sr.drawable = null;
}
@@ -244,6 +298,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
if (null != sr.device) {
+ // may cause JVM SIGSEGV:
sr.device.close();
sr.device = null;
}
@@ -261,10 +316,21 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return false;
}
- public final boolean getWasSharedContextCreated(AbstractGraphicsDevice device) {
- SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
- if(null!=sr) {
- return null != sr.getContext();
+ protected final Thread getSharedResourceThread() {
+ return sharedResourceRunner.start();
+ }
+
+ protected final boolean createSharedResource(AbstractGraphicsDevice device) {
+ try {
+ SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return null != sr.getContext();
+ }
+ } catch (GLException gle) {
+ if(DEBUG) {
+ System.err.println("Catched Exception while X11GLX Shared Resource initialization");
+ gle.printStackTrace();
+ }
}
return false;
}
@@ -297,47 +363,6 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return (SharedResource) sharedResourceRunner.getOrCreateShared(device);
}
- public final String getGLXVendorName(AbstractGraphicsDevice device) {
- if(null != device) {
- SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
- if(null!=sr) {
- return ((SharedResource)sr).getGLXVendorName();
- }
- return GLXUtil.getVendorName(device.getHandle());
- }
- return null;
- }
-
- public final boolean isGLXVendorATI(AbstractGraphicsDevice device) {
- if(null != device) {
- SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
- if(null!=sr) {
- return ((SharedResource)sr).isGLXVendorATI();
- }
- return GLXUtil.isVendorATI(device.getHandle());
- }
- return false;
- }
-
- public final boolean isGLXVendorNVIDIA(AbstractGraphicsDevice device) {
- if(null != device) {
- SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
- if(null!=sr) {
- return ((SharedResource)sr).isGLXVendorNVIDIA();
- }
- return GLXUtil.isVendorNVIDIA(device.getHandle());
- }
- return false;
- }
-
- protected final void shutdownInstance() {
- sharedResourceRunner.releaseAndWait();
-
- // Don't really close pending Display connections,
- // since this may trigger a JVM exception
- X11Util.shutdown( false, DEBUG );
- }
-
protected List<GLCapabilitiesImmutable> getAvailableCapabilitiesImpl(AbstractGraphicsDevice device) {
return X11GLXGraphicsConfigurationFactory.getAvailableCapabilities(this, device);
}
@@ -353,7 +378,7 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
if (target == null) {
throw new IllegalArgumentException("Null target");
}
- AbstractGraphicsConfiguration config = target.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration config = target.getGraphicsConfiguration();
GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
if(!caps.isPBuffer()) {
return new X11PixmapGLXDrawable(this, target);
@@ -383,6 +408,43 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return pbufferDrawable;
}
+ public final boolean isGLXMultisampleAvailable(AbstractGraphicsDevice device) {
+ if(null != device) {
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return sr.isGLXMultisampleAvailable();
+ }
+ }
+ return false;
+ }
+
+ public final VersionNumber getGLXVersionNumber(AbstractGraphicsDevice device) {
+ if(null != device) {
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return sr.getGLXVersion();
+ }
+ if( device instanceof X11GraphicsDevice ) {
+ return GLXUtil.getGLXServerVersionNumber(device.getHandle());
+ }
+ }
+ return null;
+ }
+
+ public final boolean isGLXVersionGreaterEqualOneOne(AbstractGraphicsDevice device) {
+ if(null != device) {
+ SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
+ if(null!=sr) {
+ return sr.isGLXVersionGreaterEqualOneOne();
+ }
+ if( device instanceof X11GraphicsDevice ) {
+ final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(device.getHandle());
+ return glXServerVersion.compareTo(versionOneOne) >= 0;
+ }
+ }
+ return false;
+ }
+
public final boolean isGLXVersionGreaterEqualOneThree(AbstractGraphicsDevice device) {
if(null != device) {
SharedResource sr = (SharedResource) sharedResourceRunner.getOrCreateShared(device);
@@ -390,8 +452,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return sr.isGLXVersionGreaterEqualOneThree();
}
if( device instanceof X11GraphicsDevice ) {
- VersionNumber v = getGLXVersion( (X11GraphicsDevice) device);
- return ( null != v ) ? v.compareTo(versionOneThree) >= 0 : false ;
+ final VersionNumber glXServerVersion = GLXUtil.getGLXServerVersionNumber(device.getHandle());
+ return glXServerVersion.compareTo(versionOneThree) >= 0;
}
}
return false;
@@ -407,23 +469,28 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
return isGLXVersionGreaterEqualOneThree(device);
}
- protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice device,
+ protected final NativeSurface createOffscreenSurfaceImpl(AbstractGraphicsDevice deviceReq,
GLCapabilitiesImmutable capsChosen, GLCapabilitiesImmutable capsRequested,
GLCapabilitiesChooser chooser,
int width, int height) {
- X11GraphicsScreen screen = null;
- SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(device);
- if(null!=sr) {
- screen = (X11GraphicsScreen) sr.getScreen();
+ if(null == deviceReq) {
+ throw new InternalError("deviceReq is null");
}
- if(null==screen) {
- return null;
+ final SharedResourceRunner.Resource sr = sharedResourceRunner.getOrCreateShared(deviceReq);
+ if(null==sr) {
+ throw new InternalError("No SharedResource for: "+deviceReq);
}
+ final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sr.getScreen();
+ final AbstractGraphicsDevice sharedDevice = sharedScreen.getDevice(); // should be same ..
+ // create screen/device pair - Null X11 locking, due to private non-shared Display handle
+ final X11GraphicsDevice device = new X11GraphicsDevice(X11Util.openDisplay(sharedDevice.getConnection()), AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), true);
+ final X11GraphicsScreen screen = new X11GraphicsScreen(device, sharedScreen.getIndex());
+
WrappedSurface ns = new WrappedSurface(
X11GLXGraphicsConfigurationFactory.chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, screen) );
if(ns != null) {
- ns.setSize(width, height);
+ ns.surfaceSizeChanged(width, height);
}
return ns;
}
@@ -475,8 +542,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
}
int[] size = new int[1];
- boolean res = X11Util.XF86VidModeGetGammaRampSize(display,
- X11Util.DefaultScreen(display),
+ boolean res = X11Lib.XF86VidModeGetGammaRampSize(display,
+ X11Lib.DefaultScreen(display),
size, 0);
if (!res) {
return 0;
@@ -498,8 +565,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
rampData[i] = (short) (ramp[i] * 65535);
}
- boolean res = X11Util.XF86VidModeSetGammaRamp(display,
- X11Util.DefaultScreen(display),
+ boolean res = X11Lib.XF86VidModeSetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
rampData.length,
rampData, 0,
rampData, 0,
@@ -525,8 +592,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- boolean res = X11Util.XF86VidModeGetGammaRamp(display,
- X11Util.DefaultScreen(display),
+ boolean res = X11Lib.XF86VidModeGetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
size,
redRampData,
greenRampData,
@@ -562,8 +629,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl {
rampData.limit(3 * size);
ShortBuffer blueRampData = rampData.slice();
- X11Util.XF86VidModeSetGammaRamp(display,
- X11Util.DefaultScreen(display),
+ X11Lib.XF86VidModeSetGammaRamp(display,
+ X11Lib.DefaultScreen(display),
size,
redRampData,
greenRampData,
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
index 68b8135d0..4d0c3eeca 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -35,13 +35,26 @@ package jogamp.opengl.x11.glx;
import java.util.ArrayList;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
-import javax.media.opengl.*;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.XRenderDirectFormat;
+import jogamp.nativewindow.x11.XRenderPictFormat;
+import jogamp.nativewindow.x11.XVisualInfo;
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLGraphicsConfigurationUtil;
import com.jogamp.common.nio.PointerBuffer;
-import jogamp.opengl.*;
-import jogamp.nativewindow.x11.*;
public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implements Cloneable {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
@@ -56,19 +69,20 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
static X11GLXGraphicsConfiguration create(GLProfile glp, X11GraphicsScreen x11Screen, int fbcfgID) {
- long display = x11Screen.getDevice().getHandle();
+ final long display = x11Screen.getDevice().getHandle();
if(0==display) {
throw new GLException("Display null of "+x11Screen);
}
- int screen = x11Screen.getIndex();
- long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
+ final int screen = x11Screen.getIndex();
+ final long fbcfg = glXFBConfigID2FBConfig(display, screen, fbcfgID);
if(0==fbcfg) {
throw new GLException("FBConfig null of "+toHexString(fbcfgID));
}
if(null==glp) {
glp = GLProfile.getDefault(x11Screen.getDevice());
}
- X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
+ final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+ final X11GLCapabilities caps = GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(x11Screen.getDevice()));
if(null==caps) {
throw new GLException("GLCapabilities null of "+toHexString(fbcfg));
}
@@ -100,10 +114,6 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
- private static int nonZeroOrDontCare(int value) {
- return value != 0 ? value : (int)GLX.GLX_DONT_CARE ;
- }
-
static int[] GLCapabilities2AttribList(GLCapabilitiesImmutable caps,
boolean forFBAttr,
boolean isMultisampleAvailable,
@@ -367,7 +377,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
int[] count = new int[1];
XVisualInfo template = XVisualInfo.create();
template.setVisualid(visualID);
- XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask, template, count, 0);
+ XVisualInfo[] infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask, template, count, 0);
if (infos == null || infos.length == 0) {
return null;
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 0f8b94825..a72de8cd5 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -51,7 +51,6 @@ import javax.media.opengl.GLProfile;
import com.jogamp.common.nio.PointerBuffer;
import jogamp.nativewindow.x11.X11Lib;
-import jogamp.nativewindow.x11.X11Util;
import jogamp.nativewindow.x11.XVisualInfo;
import jogamp.opengl.Debug;
import jogamp.opengl.GLGraphicsConfigurationFactory;
@@ -71,8 +70,10 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
static X11GLCapabilities.XVisualIDComparator XVisualIDComparator = new X11GLCapabilities.XVisualIDComparator();
- X11GLXGraphicsConfigurationFactory() {
- GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, this);
+ static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, new X11GLXGraphicsConfigurationFactory());
+ }
+ private X11GLXGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
@@ -101,18 +102,19 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
if(null == sharedResource) {
throw new GLException("Shared resource for device n/a: "+device);
}
- X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen();
- X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable();
- GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
- GLProfile glp = capsChosen.getGLProfile();
+ final X11GraphicsScreen sharedScreen = (X11GraphicsScreen) sharedResource.getScreen();
+ final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(sharedScreen.getDevice());
+ final X11GLXDrawable sharedDrawable = (X11GLXDrawable) sharedResource.getDrawable();
+ final GLCapabilitiesImmutable capsChosen = sharedDrawable.getChosenGLCapabilities();
+ final GLProfile glp = capsChosen.getGLProfile();
List<GLCapabilitiesImmutable> availableCaps = null;
if( sharedResource.isGLXVersionGreaterEqualOneThree() ) {
- availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp);
+ availableCaps = getAvailableGLCapabilitiesFBConfig(sharedScreen, glp, isMultisampleAvailable);
}
if( null == availableCaps || availableCaps.isEmpty() ) {
- availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp);
+ availableCaps = getAvailableGLCapabilitiesXVisual(sharedScreen, glp, isMultisampleAvailable);
}
if( null != availableCaps && availableCaps.size() > 1 ) {
Collections.sort(availableCaps, XVisualIDComparator);
@@ -120,7 +122,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
return availableCaps;
}
- static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesFBConfig(X11GraphicsScreen x11Screen, GLProfile glProfile) {
+ static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesFBConfig(X11GraphicsScreen x11Screen, GLProfile glProfile, boolean isMultisampleAvailable) {
PointerBuffer fbcfgsL = null;
// Utilizing FBConfig
@@ -129,7 +131,6 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
long display = absDevice.getHandle();
int screen = x11Screen.getIndex();
- boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] count = { -1 };
ArrayList<GLCapabilitiesImmutable> availableCaps = new ArrayList<GLCapabilitiesImmutable>();
@@ -150,17 +151,16 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
return availableCaps;
}
- static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile) {
+ static List<GLCapabilitiesImmutable> getAvailableGLCapabilitiesXVisual(X11GraphicsScreen x11Screen, GLProfile glProfile, boolean isMultisampleAvailable) {
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
int screen = x11Screen.getIndex();
- boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
int[] count = new int[1];
XVisualInfo template = XVisualInfo.create();
template.setScreen(screen);
- XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
+ XVisualInfo[] infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
if (infos == null || infos.length<1) {
throw new GLException("Error while enumerating available XVisualInfos");
}
@@ -213,18 +213,20 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
}
static X11GLXGraphicsConfiguration fetchGraphicsConfigurationFBConfig(X11GraphicsScreen x11Screen, int fbID, GLProfile glp) {
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
- int screen = x11Screen.getIndex();
+ final AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ final long display = absDevice.getHandle();
+ final int screen = x11Screen.getIndex();
- long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID);
+ final long fbcfg = X11GLXGraphicsConfiguration.glXFBConfigID2FBConfig(display, screen, fbID);
if( 0 == fbcfg || !X11GLXGraphicsConfiguration.GLXFBConfigValid( display, fbcfg ) ) {
if(DEBUG) {
System.err.println("X11GLXGraphicsConfiguration.chooseGraphicsConfigurationFBConfig: Failed - GLX FBConfig invalid: ("+x11Screen+","+toHexString(fbID)+"): fbcfg: "+toHexString(fbcfg));
}
return null;
}
- X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, GLXUtil.isMultisampleAvailable(display));
+ final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+
+ final X11GLCapabilities caps = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glp, display, fbcfg, true, true, true, factory.isGLXMultisampleAvailable(absDevice));
return new X11GLXGraphicsConfiguration(x11Screen, caps, caps, new DefaultGLCapabilitiesChooser());
}
@@ -242,9 +244,10 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
//
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
-
int screen = x11Screen.getIndex();
- boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+
+ final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+ final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, true, isMultisampleAvailable, display, screen);
int[] count = { -1 };
ArrayList/*<X11GLCapabilities>*/ availableCaps = new ArrayList();
@@ -321,9 +324,10 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
AbstractGraphicsDevice absDevice = x11Screen.getDevice();
long display = absDevice.getHandle();
-
int screen = x11Screen.getIndex();
- boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+
+ final X11GLXDrawableFactory factory = (X11GLXDrawableFactory) GLDrawableFactory.getDesktopFactory();
+ final boolean isMultisampleAvailable = factory.isGLXMultisampleAvailable(absDevice);
int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capsChosen, false, isMultisampleAvailable, display, screen);
// 1st choice: get GLCapabilities based on users GLCapabilities setting recommendedIndex as preferred choice
@@ -341,7 +345,7 @@ public class X11GLXGraphicsConfigurationFactory extends GLGraphicsConfigurationF
int[] count = new int[1];
XVisualInfo template = XVisualInfo.create();
template.setScreen(screen);
- XVisualInfo[] infos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
+ XVisualInfo[] infos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, template, count, 0);
if (infos == null || infos.length<1) {
throw new GLException("Error while enumerating available XVisualInfos");
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
index 8ef642322..333486a5f 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11OnscreenGLXDrawable.java
@@ -56,14 +56,16 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
}
@SuppressWarnings("unused")
+ @Override
public long getHandle() {
if(USE_GLXWINDOW && useGLXWindow) {
return glXWindow;
}
- return getNativeSurface().getSurfaceHandle();
+ return super.getHandle();
}
@SuppressWarnings("unused")
+ @Override
protected void destroyHandle() {
if(USE_GLXWINDOW && 0!=glXWindow) {
GLX.glXDestroyWindow(getNativeSurface().getDisplayHandle(), glXWindow);
@@ -72,10 +74,10 @@ public class X11OnscreenGLXDrawable extends X11GLXDrawable {
}
}
- /** must be locked already */
+ @Override
protected void updateHandle() {
if(USE_GLXWINDOW) {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration)getNativeSurface().getGraphicsConfiguration();
if(config.getFBConfig()>=0) {
useGLXWindow=true;
long dpy = getNativeSurface().getDisplayHandle();
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
index 8ea989267..da7b535cb 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PbufferGLXDrawable.java
@@ -48,24 +48,18 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
/* GLCapabilities caps,
GLCapabilitiesChooser chooser,
int width, int height */
- super(factory, target, true);
-
- if (DEBUG) {
- System.out.println("Pbuffer config: " + getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration());
- }
-
- createPbuffer();
-
- if (DEBUG) {
- System.err.println("Created pbuffer " + this);
- }
+ super(factory, target, false);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
createPbuffer();
} else {
- destroyImpl();
+ destroyPbuffer();
}
}
@@ -73,7 +67,7 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
return new X11PbufferGLXContext(this, shareWith);
}
- protected void destroyImpl() {
+ protected void destroyPbuffer() {
NativeSurface ns = getNativeSurface();
if (ns.getSurfaceHandle() != 0) {
GLX.glXDestroyPbuffer(ns.getDisplayHandle(), ns.getSurfaceHandle());
@@ -82,11 +76,14 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
}
private void createPbuffer() {
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) getNativeSurface().getGraphicsConfiguration();
AbstractGraphicsScreen aScreen = config.getScreen();
AbstractGraphicsDevice aDevice = aScreen.getDevice();
long display = aDevice.getHandle();
- int screen = aScreen.getIndex();
+
+ if (DEBUG) {
+ System.out.println("Pbuffer config: " + config);
+ }
if (display==0) {
throw new GLException("Null display");
@@ -129,17 +126,15 @@ public class X11PbufferGLXDrawable extends X11GLXDrawable {
int width = tmp[0];
GLX.glXQueryDrawable(display, pbuffer, GLX.GLX_HEIGHT, tmp, 0);
int height = tmp[0];
- ((SurfaceChangeable)ns).setSize(width, height);
+ ((SurfaceChangeable)ns).surfaceSizeChanged(width, height);
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + this);
+ }
}
public int getFloatingPointMode() {
// Floating-point pbuffers currently require NVidia hardware on X11
return GLPbuffer.NV_FLOAT;
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java
index ef8007de4..e19dfd1b3 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXContext.java
@@ -55,7 +55,7 @@ public class X11PixmapGLXContext extends X11GLXContext {
}
public int getOffscreenContextReadBuffer() {
- GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ GLCapabilitiesImmutable caps = (GLCapabilitiesImmutable)drawable.getNativeSurface().getGraphicsConfiguration().getChosenCapabilities();
if (caps.getDoubleBuffered()) {
return GL.GL_BACK;
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
index f5d321561..7dae20f80 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
+++ b/src/jogl/classes/jogamp/opengl/x11/glx/X11PixmapGLXDrawable.java
@@ -48,15 +48,18 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
private long pixmap;
protected X11PixmapGLXDrawable(GLDrawableFactory factory, NativeSurface target) {
- super(factory, target, true);
- create();
+ super(factory, target, false);
}
+ protected void destroyImpl() {
+ setRealized(false);
+ }
+
protected void setRealizedImpl() {
if(realized) {
- create();
+ createPixmap();
} else {
- destroyImpl();
+ destroyPixmap();
}
}
@@ -64,9 +67,9 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
return new X11PixmapGLXContext(this, shareWith);
}
- private void create() {
+ private void createPixmap() {
NativeSurface ns = getNativeSurface();
- X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) ns.getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ X11GLXGraphicsConfiguration config = (X11GLXGraphicsConfiguration) ns.getGraphicsConfiguration();
XVisualInfo vis = config.getXVisualInfo();
int bitsPerPixel = vis.getDepth();
AbstractGraphicsScreen aScreen = config.getScreen();
@@ -74,14 +77,14 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
long dpy = aDevice.getHandle();
int screen = aScreen.getIndex();
- pixmap = X11Util.XCreatePixmap(dpy, X11Util.RootWindow(dpy, screen),
+ pixmap = X11Lib.XCreatePixmap(dpy, X11Lib.RootWindow(dpy, screen),
surface.getWidth(), surface.getHeight(), bitsPerPixel);
if (pixmap == 0) {
throw new GLException("XCreatePixmap failed");
}
long drawable = GLX.glXCreateGLXPixmap(dpy, vis, pixmap);
if (drawable == 0) {
- X11Util.XFreePixmap(dpy, pixmap);
+ X11Lib.XFreePixmap(dpy, pixmap);
pixmap = 0;
throw new GLException("glXCreateGLXPixmap failed");
}
@@ -93,7 +96,7 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
}
}
- protected void destroyImpl() {
+ protected void destroyPixmap() {
if (pixmap == 0) return;
NativeSurface ns = getNativeSurface();
@@ -122,16 +125,10 @@ public class X11PixmapGLXDrawable extends X11GLXDrawable {
GLX.glXMakeCurrent(display, 0, 0);
GLX.glXDestroyGLXPixmap(display, drawable);
- X11Util.XFreePixmap(display, pixmap);
+ X11Lib.XFreePixmap(display, pixmap);
drawable = 0;
pixmap = 0;
((SurfaceChangeable)ns).setSurfaceHandle(0);
display = 0;
}
-
- protected void swapBuffersImpl() {
- if(DEBUG) {
- System.err.println("unhandled swapBuffersImpl() called for: "+this);
- }
- }
}
diff --git a/src/jogl/native/GLDebugMessageHandler.c b/src/jogl/native/GLDebugMessageHandler.c
index 509c6f695..fea9d90ce 100644
--- a/src/jogl/native/GLDebugMessageHandler.c
+++ b/src/jogl/native/GLDebugMessageHandler.c
@@ -35,21 +35,22 @@ typedef void (GLAPIENTRY* _local_GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenu
JNIEXPORT jboolean JNICALL Java_jogamp_opengl_GLDebugMessageHandler_initIDs0
(JNIEnv *env, jclass clazz)
{
+ jboolean res;
JoglCommon_init(env);
glDebugMessageARB = (*env)->GetMethodID(env, clazz, "glDebugMessageARB", "(IIIILjava/lang/String;)V");
glDebugMessageAMD = (*env)->GetMethodID(env, clazz, "glDebugMessageAMD", "(IIILjava/lang/String;)V");
- if ( NULL == glDebugMessageARB || NULL == glDebugMessageAMD ) {
- return JNI_FALSE;
- }
- return JNI_TRUE;
+ res = ( NULL != glDebugMessageARB && NULL != glDebugMessageAMD ) ? JNI_TRUE : JNI_FALSE ;
+
+ DBG_PRINT("GLDebugMessageHandler.initIDS0: OK: %d, ARB %p, AMD %p\n", res, glDebugMessageARB, glDebugMessageAMD);
+
+ return res;
}
typedef struct {
JavaVM *vm;
int version;
- JNIEnv *env;
jobject obj;
int extType;
} DebugHandlerType;
@@ -65,10 +66,12 @@ static void GLDebugMessageARBCallback(GLenum source, GLenum type, GLuint id, GLe
JNIEnv *curEnv = NULL;
JNIEnv *newEnv = NULL;
int envRes ;
- DBG_PRINT("GLDebugMessageARBCallback: 01 - %s\n", message);
+ DBG_PRINT("GLDebugMessageARBCallback: 00 - %s, vm %p, version 0x%X, jobject %p, extType %d\n",
+ message, handle->vm, handle->version, (void*)handle->obj, handle->extType);
// retrieve this thread's JNIEnv curEnv - or detect it's detached
envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ;
+ DBG_PRINT("GLDebugMessageARBCallback: 01 - JVM Env: curEnv %p, res 0x%X\n", curEnv, envRes);
if( JNI_EDETACHED == envRes ) {
// detached thread - attach to JVM
if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) {
@@ -107,9 +110,12 @@ static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severit
JNIEnv *curEnv = NULL;
JNIEnv *newEnv = NULL;
int envRes ;
+ DBG_PRINT("GLDebugMessageAMDCallback: 00 - %s, vm %p, version 0x%X, jobject %p, extType %d\n",
+ message, handle->vm, handle->version, (void*)handle->obj, handle->extType);
// retrieve this thread's JNIEnv curEnv - or detect it's detached
envRes = (*vm)->GetEnv(vm, (void **) &curEnv, version) ;
+ DBG_PRINT("GLDebugMessageAMDCallback: 01 - JVM Env: curEnv %p, res 0x%X\n", curEnv, envRes);
if( JNI_EDETACHED == envRes ) {
// detached thread - attach to JVM
if( JNI_OK != ( envRes = (*vm)->AttachCurrentThread(vm, (void**) &newEnv, NULL) ) ) {
@@ -117,6 +123,7 @@ static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severit
return;
}
curEnv = newEnv;
+ DBG_PRINT("GLDebugMessageAMDCallback: 02 - attached .. \n");
} else if( JNI_OK != envRes ) {
// oops ..
fprintf(stderr, "GLDebugMessageAMDCallback: can't GetEnv: %d\n", envRes);
@@ -128,7 +135,9 @@ static void GLDebugMessageAMDCallback(GLuint id, GLenum category, GLenum severit
if( NULL != newEnv ) {
// detached attached thread
(*vm)->DetachCurrentThread(vm);
+ DBG_PRINT("GLDebugMessageAMDCallback: 04 - detached .. \n");
}
+ DBG_PRINT("GLDebugMessageAMDCallback: 0X\n");
/**
* On Java 32bit on 64bit Windows,
* the unit test com.jogamp.opengl.test.junit.jogl.acore.TestGLDebug00NEWT crashes after this point.
@@ -152,9 +161,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_opengl_GLDebugMessageHandler_register0
}
handle->vm = vm;
handle->version = (*env)->GetVersion(env);
- handle->env = env;
handle->obj = (*env)->NewGlobalRef(env, obj);
handle->extType = extType;
+ DBG_PRINT("GLDebugMessageHandler.register0: vm %p, version 0x%X, jobject %p, extType %d\n",
+ handle->vm, handle->version, (void*)handle->obj, handle->extType);
if(jogamp_opengl_GLDebugMessageHandler_EXT_ARB == extType) {
_local_PFNGLDEBUGMESSAGECALLBACKARBPROC ptr_glDebugMessageCallbackARB;
@@ -181,9 +191,9 @@ JNIEXPORT void JNICALL Java_jogamp_opengl_GLDebugMessageHandler_unregister0
{
DebugHandlerType * handle = (DebugHandlerType*) (intptr_t) jhandle;
- if(env != handle->env) {
- JoglCommon_throwNewRuntimeException(env, "wrong handle (env doesn't match)");
- }
+ DBG_PRINT("GLDebugMessageHandler.unregister0: vm %p, version 0x%X, jobject %p, extType %d\n",
+ handle->vm, handle->version, (void*)handle->obj, handle->extType);
+
if(JNI_FALSE == (*env)->IsSameObject(env, obj, handle->obj)) {
JoglCommon_throwNewRuntimeException(env, "wrong handle (obj doesn't match)");
}
diff --git a/src/jogl/native/macosx/ContextUpdater.h b/src/jogl/native/macosx/ContextUpdater.h
index 3cf7315af..f00b2be57 100644
--- a/src/jogl/native/macosx/ContextUpdater.h
+++ b/src/jogl/native/macosx/ContextUpdater.h
@@ -25,17 +25,13 @@ This notification is sent whenever an NSView that has an attached NSSurface chan
@interface ContextUpdater : NSObject
{
@protected
+ pthread_mutex_t resourceLock;
NSView * view;
NSRect viewRect;
NSOpenGLContext *ctx;
BOOL viewUpdated;
}
-- (void) lock;
-- (void) lockInFunction:(char *)func atLine:(int)line;
-- (void) unlock;
-- (void) unlockInFunction:(char *)func atLine:(int)line;
-
- (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView;
- (void) update:(NSNotification *)notification;
diff --git a/src/jogl/native/macosx/ContextUpdater.m b/src/jogl/native/macosx/ContextUpdater.m
index 21f98ad5e..d01eaf967 100644
--- a/src/jogl/native/macosx/ContextUpdater.m
+++ b/src/jogl/native/macosx/ContextUpdater.m
@@ -1,43 +1,26 @@
#import "ContextUpdater.h"
#import <pthread.h>
-@implementation ContextUpdater
-{
-}
-
-static pthread_mutex_t resourceLock = PTHREAD_MUTEX_INITIALIZER;
-
-static void printLockDebugInfo(char *message, char *func, int line)
-{
- fprintf(stderr, "%s in function: \"%s\" at line: %d\n", message, func, line);
- fflush(NULL);
-}
-
-- (void) lock
-{
- pthread_mutex_lock(&resourceLock);
-}
+// #define VERBOSE_ON 1
-- (void) lockInFunction:(char *)func atLine:(int)line
-{
- printLockDebugInfo("locked ", func, line);
- [self lock];
-}
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
-- (void) unlock
-{
- pthread_mutex_unlock(&resourceLock);
-}
+#ifndef CGL_VERSION_1_3
+ #warning this SDK doesn't support OpenGL profile
+#endif
-- (void) unlockInFunction:(char *)func atLine:(int)line
+@implementation ContextUpdater
{
- printLockDebugInfo("unlocked", func, line);
- [self unlock];
}
- (void) update:(NSNotification *)notification
{
- [self lock];
+ pthread_mutex_lock(&resourceLock);
NSRect r = [view frame];
if(viewRect.origin.x != r.origin.x ||
@@ -47,41 +30,47 @@ static void printLockDebugInfo(char *message, char *func, int line)
viewUpdated = TRUE;
viewRect = r;
}
-
- [self unlock];
+
+ pthread_mutex_unlock(&resourceLock);
}
- (BOOL) needsUpdate
{
BOOL r;
- [self lock];
+ pthread_mutex_lock(&resourceLock);
r = viewUpdated;
viewUpdated = FALSE;
- [self unlock];
+ pthread_mutex_unlock(&resourceLock);
return r;
}
- (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView
{
+ DBG_PRINT("ContextUpdater::init.0 view %p, ctx %p\n", view, ctx);
+ pthread_mutex_init(&resourceLock, NULL); // fast non-recursive
ctx = context;
view = nsView;
[ctx retain];
[view retain];
viewRect = [view frame];
- viewUpdated = FALSE;
+ viewUpdated = TRUE;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:NSViewGlobalFrameDidChangeNotification object: view];
+ DBG_PRINT("ContextUpdater::init.X\n");
return [super init];
}
- (void) dealloc
{
+ DBG_PRINT("ContextUpdater::dealloc.0 view %p, ctx %p\n", view, ctx);
[[NSNotificationCenter defaultCenter] removeObserver:self];
[view release];
[ctx release];
+ pthread_mutex_destroy(&resourceLock);
+ DBG_PRINT("ContextUpdater::dealloc.X\n");
[super dealloc];
}
diff --git a/src/jogl/native/macosx/MacOSXCustomCGLCode.c b/src/jogl/native/macosx/MacOSXCustomCGLCode.c
index c29be889d..f8b7a800f 100644
--- a/src/jogl/native/macosx/MacOSXCustomCGLCode.c
+++ b/src/jogl/native/macosx/MacOSXCustomCGLCode.c
@@ -5,8 +5,7 @@
#include </usr/include/machine/types.h>
#include "macosx-window-system.h"
-void CGLQueryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) {
- CGLPixelFormatObj pix = (CGLPixelFormatObj) pixelFormat;
+void CGLQueryPixelFormat(CGLPixelFormatObj fmt, int* iattrs, int niattrs, int* ivalues) {
// FIXME: think about how specifying this might affect the API
int virtualScreen = 0;
@@ -14,7 +13,7 @@ void CGLQueryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalu
GLint value;
for (i = 0; i < niattrs && iattrs[i]>0; i++) {
CGLPixelFormatAttribute attr = (CGLPixelFormatAttribute) iattrs[i];
- if ( kCGLNoError == CGLDescribePixelFormat(pix, virtualScreen, attr, &value) ) {
+ if ( kCGLNoError == CGLDescribePixelFormat(fmt, virtualScreen, attr, &value) ) {
ivalues[i] = value;
} else {
ivalues[i] = 0;
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m
new file mode 100644
index 000000000..7233f40ce
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-nsview.m
@@ -0,0 +1,140 @@
+
+@interface MyNSOpenGLLayer: NSOpenGLLayer
+{
+@protected
+ NSOpenGLContext* ctxShared;
+ NSView* view;
+ NSOpenGLPixelFormat* fmt;
+@public
+ volatile BOOL shallDraw;
+}
+
+- (id) initWithContext: (NSOpenGLContext*) ctx
+ pixelFormat: (NSOpenGLPixelFormat*) pfmt
+ view: (NSView*) v
+ opaque: (Bool) opaque;
+
+@end
+
+@implementation MyNSOpenGLLayer
+
+- (id) initWithContext: (NSOpenGLContext*) _ctx
+ pixelFormat: (NSOpenGLPixelFormat*) _fmt
+ view: (NSView*) _view
+ opaque: (Bool) opaque
+{
+ self = [super init];
+ ctxShared = _ctx;
+ [ctxShared retain];
+
+ fmt = _fmt;
+ [fmt retain];
+
+ view = _view;
+ [view retain];
+ [self setView: view];
+ [view setLayer: self];
+ [view setWantsLayer: YES];
+
+ [self setAsynchronous: NO];
+ // [self setAsynchronous: YES]; // FIXME: JAU
+ [self setNeedsDisplayOnBoundsChange: NO];
+ [self setOpaque: opaque ? YES : NO];
+ shallDraw = NO;
+ textureID = 0;
+ DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, view %p, opaque %d\n", self, ctx, fmt, view, opaque);
+ return self;
+}
+
+- (void)dealloc
+{
+ [fmt release];
+ [ctxShared release];
+ [view release];
+ DBG_PRINT("MyNSOpenGLLayer::dealloc %p\n", self);
+ [super dealloc];
+}
+
+- (void) setOpenGLContext: (NSOpenGLContext*) _ctx
+{
+ DBG_PRINT("MyNSOpenGLLayer::setOpenGLContext: %p %p -> %p\n", self, [self openGLContext], _ctx);
+ [super setOpenGLContext: _ctx];
+}
+
+- (void) setOpenGLPixelFormat: (NSOpenGLPixelFormat*) _fmt
+{
+ DBG_PRINT("MyNSOpenGLLayer::setOpenGLPixelFormat %p %p -> %p\n", self, fmt, _fmt);
+ [super setOpenGLPixelFormat: fmt];
+}
+
+- (NSOpenGLPixelFormat *) openGLPixelFormat
+{
+ return fmt;
+}
+
+- (void) setView: (NSView*) v
+{
+ DBG_PRINT("MyNSOpenGLLayer::setView %p %p -> %p (ignored/propagated)\n", self, view, v);
+ [super setView: view]; // propagate
+}
+
+- (NSOpenGLPixelFormat *)openGLPixelFormatForDisplayMask:(uint32_t)mask
+{
+ DBG_PRINT("MyNSOpenGLLayer::openGLPixelFormatForDisplayMask %p %d -> %p\n", self, mask, fmt);
+ return fmt;
+}
+
+- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+{
+ NSOpenGLContext* ctx = NULL;
+ if(NULL == ctx) {
+ int viewNotReady[] = { 0 };
+ ctx = createContext(ctxShared, view, true, fmt, [self isOpaque], viewNotReady);
+ }
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat %p, fmt %p/%p, view %p, shared %p -> %p\n",
+ self, fmt, pixelFormat, view, ctxShared, ctx);
+ return ctx;
+}
+
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ DBG_PRINT("MyNSOpenGLLayer::canDrawInOpenGLContext %p: %d\n", self, self->shallDraw);
+ return self->shallDraw;
+}
+
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ self->shallDraw = NO;
+
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, ctx %p, pfmt %p\n", self, context, pixelFormat);
+
+ [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
+}
+
+@end
+
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSView* view, Bool opaque) {
+ return [[MyNSOpenGLLayer alloc] initWithContext:ctx pixelFormat: fmt view: view opaque: opaque];
+}
+
+void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ l->shallDraw = YES;
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];
+ // NSView* view = [l view];
+ // [view setNeedsDisplay: YES]; // FIXME: JAU
+ // [view performSelectorOnMainThread:@selector(setNeedsDisplay:) withObject:YES waitUntilDone:YES];
+ // [view performSelectorOnMainThread:@selector(display) withObject:nil waitUntilDone:YES];
+ DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+}
+
+void releaseNSOpenGLLayer(NSOpenGLLayer* l) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [l release];
+ [pool release];
+}
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
new file mode 100644
index 000000000..fe896cc53
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m
@@ -0,0 +1,480 @@
+#import "MacOSXWindowSystemInterface.h"
+#import <QuartzCore/QuartzCore.h>
+#import <pthread.h>
+#include "timespec.h"
+
+//
+// CADisplayLink only available on iOS >= 3.1, sad, since it's convenient.
+// Use CVDisplayLink otherwise.
+//
+// #define HAS_CADisplayLink 1
+//
+
+// lock/sync debug output
+//
+// #define DBG_SYNC 1
+//
+#ifdef DBG_SYNC
+ // #define SYNC_PRINT(...) NSLog(@ ## __VA_ARGS__)
+ #define SYNC_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define SYNC_PRINT(...)
+#endif
+
+// fps debug output
+//
+// #define DBG_PERF 1
+
+@interface MyNSOpenGLLayer: NSOpenGLLayer
+{
+@protected
+ NSOpenGLPixelBuffer* pbuffer;
+ int texWidth;
+ int texHeight;
+ GLuint textureID;
+ GLint swapInterval;
+#ifdef HAS_CADisplayLink
+ CADisplayLink* displayLink;
+#else
+ CVDisplayLinkRef displayLink;
+#endif
+ int tc;
+ struct timespec t0;
+@public
+ pthread_mutex_t renderLock;
+ pthread_cond_t renderSignal;
+ BOOL shallDraw;
+}
+
+- (id) setupWithContext: (NSOpenGLContext*) ctx
+ pixelFormat: (NSOpenGLPixelFormat*) pfmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ opaque: (Bool) opaque
+ texWidth: (int) texWidth
+ texHeight: (int) texHeight;
+
+- (void)deallocTex;
+- (void)disableAnimation;
+- (void)releaseLayer;
+- (void)dealloc;
+- (int)getSwapInterval;
+- (void)setSwapInterval:(int)interval;
+- (void)tick;
+
+@end
+
+#ifndef HAS_CADisplayLink
+
+static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink,
+ const CVTimeStamp *inNow,
+ const CVTimeStamp *inOutputTime,
+ CVOptionFlags flagsIn,
+ CVOptionFlags *flagsOut,
+ void *displayLinkContext)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*)displayLinkContext;
+ pthread_mutex_lock(&l->renderLock);
+ #ifdef DBG_PERF
+ [l tick];
+ #endif
+ pthread_cond_signal(&l->renderSignal);
+ SYNC_PRINT("-*-");
+ pthread_mutex_unlock(&l->renderLock);
+ [pool release];
+ return kCVReturnSuccess;
+}
+
+#endif
+
+@implementation MyNSOpenGLLayer
+
+- (id) setupWithContext: (NSOpenGLContext*) _ctx
+ pixelFormat: (NSOpenGLPixelFormat*) _fmt
+ pbuffer: (NSOpenGLPixelBuffer*) p
+ opaque: (Bool) opaque
+ texWidth: (int) _texWidth
+ texHeight: (int) _texHeight;
+{
+ pthread_mutexattr_t renderLockAttr;
+ pthread_mutexattr_init(&renderLockAttr);
+ pthread_mutexattr_settype(&renderLockAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
+ pthread_cond_init(&renderSignal, NULL); // no attribute
+
+ // no animations for add/remove/swap sublayers etc
+ [self removeAnimationForKey: kCAOnOrderIn];
+ [self removeAnimationForKey: kCAOnOrderOut];
+ [self removeAnimationForKey: kCATransition];
+
+ pbuffer = p;
+ [pbuffer retain];
+
+ // instantiate a deactivated displayLink
+#ifdef HAS_CADisplayLink
+ displayLink = [[CVDisplayLink displayLinkWithTarget:self selector:@selector(setNeedsDisplay)] retain];
+ [displayLink setPaused: YES];
+#else
+ CVReturn cvres;
+ {
+ int allDisplaysMask = 0;
+ int virtualScreen, accelerated, displayMask;
+ for (virtualScreen = 0; virtualScreen < [_fmt numberOfVirtualScreens]; virtualScreen++) {
+ [_fmt getValues:&displayMask forAttribute:NSOpenGLPFAScreenMask forVirtualScreen:virtualScreen];
+ [_fmt getValues:&accelerated forAttribute:NSOpenGLPFAAccelerated forVirtualScreen:virtualScreen];
+ if (accelerated) {
+ allDisplaysMask |= displayMask;
+ }
+ }
+ cvres = CVDisplayLinkCreateWithOpenGLDisplayMask(allDisplaysMask, &displayLink);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkCreateWithOpenGLDisplayMask %X failed: %d\n", self, allDisplaysMask, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [_ctx CGLContextObj], [_fmt CGLPixelFormatObj]);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
+ displayLink = NULL;
+ }
+ }
+ if(NULL != displayLink) {
+ CVDisplayLinkStop(displayLink);
+ }
+#endif
+ [self setAsynchronous: YES];
+
+ [self setNeedsDisplayOnBoundsChange: YES]; // FIXME: learn how to recreate on size change!
+ [self setOpaque: opaque ? YES : NO];
+ texWidth = _texWidth;
+ texHeight = _texHeight;
+ textureID = 0;
+ swapInterval = -1;
+ shallDraw = NO;
+
+ CGRect lRect = [self frame];
+
+ DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, frame: %lf/%lf %lfx%lf (refcnt %d)\n",
+ self, _ctx, _fmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
+ lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]);
+ return self;
+}
+
+- (void)disableAnimation
+{
+ DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink);
+ pthread_mutex_lock(&renderLock);
+ [self setAsynchronous: NO];
+ if(NULL != displayLink) {
+#ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ [displayLink release];
+#else
+ if(NULL!=displayLink) {
+ CVDisplayLinkStop(displayLink);
+ CVDisplayLinkRelease(displayLink);
+ }
+#endif
+ displayLink = NULL;
+ }
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)deallocTex
+{
+ pthread_mutex_lock(&renderLock);
+ NSOpenGLContext* context = [self openGLContext];
+ DBG_PRINT("MyNSOpenGLLayer::deallocTex %p (refcnt %d) - context %p, pbuffer %p\n", self, (int)[self retainCount], context, pbuffer);
+ if(NULL != pbuffer) {
+ if(NULL!=context) {
+ [context makeCurrentContext];
+ if(0 != textureID) {
+ glDeleteTextures(1, &textureID);
+ textureID = 0;
+ }
+ [context clearDrawable];
+ }
+ [pbuffer release];
+ pbuffer = NULL;
+ }
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)releaseLayer
+{
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ pthread_mutex_lock(&renderLock);
+ [self disableAnimation];
+ [self deallocTex];
+ [self release];
+ DBG_PRINT("MyNSOpenGLLayer::releaseLayer.X: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (void)dealloc
+{
+ DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]);
+ // NSLog(@"MyNSOpenGLLayer::dealloc: %@",[NSThread callStackSymbols]);
+
+ [self disableAnimation];
+ [self deallocTex];
+ pthread_cond_destroy(&renderSignal);
+ pthread_mutex_destroy(&renderLock);
+ [super dealloc];
+ DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self);
+}
+
+- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ // assume both methods 'canDrawInOpenGLContext' and 'drawInOpenGLContext'
+ // are called from the same thread subsequently
+ pthread_mutex_lock(&renderLock);
+ Bool res = NULL != pbuffer && YES == shallDraw;
+ if(!res) {
+ SYNC_PRINT("<0>");
+ pthread_mutex_unlock(&renderLock);
+ } else {
+ SYNC_PRINT("<");
+ }
+ return res;
+}
+
+- (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval displayTime:(const CVTimeStamp *)timeStamp
+{
+ [context makeCurrentContext];
+
+ /**
+ * v-sync doesn't works w/ NSOpenGLLayer's context .. well :(
+ * Using CVDisplayLink .. see setSwapInterval() below.
+ *
+ if(0 <= swapInterval) {
+ GLint si;
+ [context getValues: &si forParameter: NSOpenGLCPSwapInterval];
+ if(si != swapInterval) {
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p setSwapInterval: %d -> %d\n", self, si, swapInterval);
+ [context setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+ }
+ } */
+ GLenum textureTarget = [pbuffer textureTarget];
+ GLfloat tWidth, tHeight;
+ {
+ GLsizei pwidth = [pbuffer pixelsWide];
+ GLsizei pheight = [pbuffer pixelsHigh];
+ tWidth = textureTarget == GL_TEXTURE_2D ? (GLfloat)pwidth /(GLfloat)texWidth : pwidth;
+ tHeight = textureTarget == GL_TEXTURE_2D ? (GLfloat)pheight/(GLfloat)texHeight : pheight;
+ }
+ Bool texCreated = 0 == textureID;
+
+ if(texCreated) {
+ glGenTextures(1, &textureID);
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p, ctx %p, pfmt %p tex %dx%d -> %fx%f 0x%X: creating texID 0x%X\n",
+ self, context, pixelFormat, texWidth, texHeight, tWidth, tHeight, textureTarget, textureID);
+
+ CGRect lRect = [self frame];
+ DBG_PRINT("MyNSOpenGLLayer::drawInOpenGLContext %p frame0: %lf/%lf %lfx%lf\n",
+ self, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+ }
+
+ glBindTexture(textureTarget, textureID);
+
+ /**
+ if(texCreated) {
+ // proper tex size setup
+ glTexImage2D(textureTarget, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
+ } */
+
+ [context setTextureImageToPixelBuffer: pbuffer colorBuffer: GL_FRONT];
+
+ glTexParameteri(textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(textureTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glEnable(textureTarget);
+
+ static GLfloat verts[] = {
+ -1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ 1.0, -1.0
+ };
+
+ GLfloat tex[] = {
+ 0.0, 0.0,
+ 0.0, tHeight,
+ tWidth, tHeight,
+ tWidth, 0.0
+ };
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDisable(textureTarget);
+ glBindTexture(textureTarget, 0);
+
+ [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp];
+ shallDraw = NO;
+ if(0 >= swapInterval) {
+ pthread_cond_signal(&renderSignal);
+ SYNC_PRINT("*");
+ }
+ SYNC_PRINT("1>");
+ pthread_mutex_unlock(&renderLock);
+}
+
+- (int)getSwapInterval
+{
+ return swapInterval;
+}
+
+- (void)setSwapInterval:(int)interval
+{
+ DBG_PRINT("MyNSOpenGLLayer::setSwapInterval: %d\n", interval);
+ swapInterval = interval;
+ if(0 < swapInterval) {
+ tc = 0;
+ timespec_now(&t0);
+
+ [self setAsynchronous: NO];
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: NO];
+ [displayLink setFrameInterval: interval];
+ #else
+ if(NULL!=displayLink) {
+ CVDisplayLinkStart(displayLink);
+ // FIXME: doesn't support interval ..
+ }
+ #endif
+ } else {
+ #ifdef HAS_CADisplayLink
+ [displayLink setPaused: YES];
+ #else
+ if(NULL!=displayLink) {
+ CVDisplayLinkStop(displayLink);
+ }
+ #endif
+ [self setAsynchronous: YES];
+ }
+}
+
+-(void)tick
+{
+ tc++;
+ if(tc%60==0) {
+ struct timespec t1, td;
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &t0);
+ long td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "NSOpenGLLayer: %ld ms / %d frames, %ld ms / frame, %f fps\n",
+ td_ms, tc, td_ms/tc, (tc * 1000.0) / (float)td_ms );
+ fflush(NULL);
+ }
+}
+
+@end
+
+NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, Bool opaque, int texWidth, int texHeight) {
+ // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ?
+ // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO.
+ // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
+
+ return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight];
+}
+
+void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ pthread_mutex_lock(&l->renderLock);
+ [l setSwapInterval: interval];
+ pthread_mutex_unlock(&l->renderLock);
+}
+
+void waitUntilNSOpenGLLayerIsReady(NSOpenGLLayer* layer, long to_ms) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ BOOL ready = NO;
+ int wr = 0;
+ pthread_mutex_lock(&l->renderLock);
+ SYNC_PRINT("{");
+ do {
+ if([l getSwapInterval] <= 0) {
+ ready = !l->shallDraw;
+ }
+ if(NO == ready) {
+ if(0 < to_ms) {
+ struct timespec to_abs;
+ timespec_now(&to_abs);
+ timespec_addms(&to_abs, to_ms);
+ wr = pthread_cond_timedwait(&l->renderSignal, &l->renderLock, &to_abs);
+ #ifdef DBG_SYNC
+ struct timespec t1, td;
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &to_abs);
+ long td_ms = timespec_milliseconds(&td);
+ fprintf(stderr, "%ld ms", td_ms);
+ #endif
+ } else {
+ pthread_cond_wait (&l->renderSignal, &l->renderLock);
+ }
+ ready = !l->shallDraw;
+ }
+ } while (NO == ready && 0 == wr) ;
+ SYNC_PRINT("-%d}", ready);
+ pthread_mutex_unlock(&l->renderLock);
+}
+
+void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ @synchronized(l) {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ pthread_mutex_lock(&l->renderLock);
+ SYNC_PRINT("[");
+ l->shallDraw = YES;
+ if([l getSwapInterval] > 0) {
+ // only trigger update if async mode is off (swapInterval>0)
+ if ( [NSThread isMainThread] == YES ) {
+ [l setNeedsDisplay];
+ } else {
+ // can't wait, otherwise we may deadlock AWT
+ [l performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO];
+ }
+ SYNC_PRINT("1]");
+ } else {
+ SYNC_PRINT("0]");
+ }
+ pthread_mutex_unlock(&l->renderLock);
+ // DBG_PRINT("MyNSOpenGLLayer::setNSOpenGLLayerNeedsDisplay %p\n", l);
+ [pool release];
+ }
+}
+
+void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
+ MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
+
+ if ( [NSThread isMainThread] == YES ) {
+ [l releaseLayer];
+ } else {
+ [l performSelectorOnMainThread:@selector(releaseLayer) withObject:nil waitUntilDone:NO];
+ }
+
+ DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
+ [pool release];
+}
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.h b/src/jogl/native/macosx/MacOSXWindowSystemInterface.h
new file mode 100644
index 000000000..138accb22
--- /dev/null
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.h
@@ -0,0 +1,20 @@
+#import <Cocoa/Cocoa.h>
+#import <OpenGL/gl.h>
+#import <OpenGL/CGLTypes.h>
+#import <jni.h>
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+#ifndef CGL_VERSION_1_3
+ #warning this SDK doesn't support OpenGL profile
+#endif
+
+#import "macosx-window-system.h"
+
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
index 751fba9c0..b5979d53e 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m
@@ -14,19 +14,10 @@
#endif
*/
-#import <Cocoa/Cocoa.h>
-#import <OpenGL/gl.h>
-#import <OpenGL/CGLTypes.h>
-#import <jni.h>
-
-#ifndef CGL_VERSION_1_3
- #warning this SDK doesn't support OpenGL profile
-#endif
+#import "MacOSXWindowSystemInterface.h"
#import "ContextUpdater.h"
-#import "macosx-window-system.h"
-
// see MacOSXPbufferGLContext.java createPbuffer
#define USE_GL_TEXTURE_RECTANGLE_EXT
@@ -377,7 +368,7 @@ long validateParameter(NSOpenGLPixelFormatAttribute attribute, long value)
return value;
}
-void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
+NSOpenGLPixelFormat* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
getRendererInfo();
@@ -390,6 +381,18 @@ void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
for (i = 0; i < niattrs && iattrs[i]>0; i++) {
int attr = iattrs[i];
switch (attr) {
+ case NSOpenGLPFANoRecovery:
+ if (ivalues[i] != 0) {
+ attribs[idx++] = NSOpenGLPFANoRecovery;
+ }
+ break;
+
+ case NSOpenGLPFAAccelerated:
+ if (ivalues[i] != 0) {
+ attribs[idx++] = NSOpenGLPFAAccelerated;
+ }
+ break;
+
case NSOpenGLPFAPixelBuffer:
if (ivalues[i] != 0) {
attribs[idx++] = NSOpenGLPFAPixelBuffer;
@@ -451,9 +454,8 @@ void* createPixelFormat(int* iattrs, int niattrs, int* ivalues) {
return fmt;
}
-void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues) {
+void queryPixelFormat(NSOpenGLPixelFormat* fmt, int* iattrs, int niattrs, int* ivalues) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat;
GLint tmp;
// FIXME: think about how specifying this might affect the API
GLint virtualScreen = 0;
@@ -468,16 +470,43 @@ void queryPixelFormat(void* pixelFormat, int* iattrs, int niattrs, int* ivalues)
[pool release];
}
-void deletePixelFormat(void* pixelFormat) {
+void deletePixelFormat(NSOpenGLPixelFormat* fmt) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSOpenGLPixelFormat* fmt = (NSOpenGLPixelFormat*) pixelFormat;
[fmt release];
[pool release];
}
-void* createContext(void* shareContext,
- void* view,
- void* pixelFormat,
+NSOpenGLContext* getCurrentContext() {
+ NSOpenGLContext *ctx = NULL;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ ctx = [NSOpenGLContext currentContext];
+ [pool release];
+ return ctx;
+}
+
+CGLContextObj getCGLContext(NSOpenGLContext* ctx) {
+ void * cglContext = NULL;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ cglContext = [ctx CGLContextObj];
+ [pool release];
+ return cglContext;
+}
+
+NSView* getNSView(NSOpenGLContext* ctx) {
+ NSView* view = NULL;
+
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ view = [ctx view];
+ [pool release];
+ return view;
+}
+
+NSOpenGLContext* createContext(NSOpenGLContext* share,
+ NSView* view,
+ Bool isBackingLayerView,
+ NSOpenGLPixelFormat* fmt,
Bool opaque,
int* viewNotReady)
{
@@ -485,27 +514,22 @@ void* createContext(void* shareContext,
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSView *nsView = NULL;
- NSObject *nsObj = (NSObject*) view;
-
- if( nsObj != NULL && [nsObj isKindOfClass:[NSView class]] ) {
- nsView = (NSView*)nsObj;
- }
-
- if (nsView != NULL)
- {
+ if (view != NULL) {
Bool viewReady = true;
- if ([nsView lockFocusIfCanDraw] == NO)
- {
- viewReady = false;
+ if(!isBackingLayerView) {
+ if ([view lockFocusIfCanDraw] == NO) {
+ DBG_PRINT("createContext [view lockFocusIfCanDraw] failed\n");
+ viewReady = false;
+ }
}
- else
- {
- NSRect frame = [nsView frame];
- if ((frame.size.width == 0) || (frame.size.height == 0))
- {
- [nsView unlockFocus];
+ if(viewReady) {
+ NSRect frame = [view frame];
+ if ((frame.size.width == 0) || (frame.size.height == 0)) {
+ if(!isBackingLayerView) {
+ [view unlockFocus];
+ }
+ DBG_PRINT("createContext view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height);
viewReady = false;
}
}
@@ -523,126 +547,95 @@ void* createContext(void* shareContext,
}
}
- NSOpenGLContext* nsContext = [[NSOpenGLContext alloc]
- initWithFormat: (NSOpenGLPixelFormat*) pixelFormat
- shareContext: (NSOpenGLContext*) shareContext];
+ NSOpenGLContext* ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:share];
- if (nsContext != nil) {
- if (nsView != nil) {
- if(!opaque) {
- GLint zeroOpacity = 0;
- [nsContext setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
- }
- [nsContext setView:nsView];
- [nsView unlockFocus];
- }
+ if (ctx != nil) {
+ if (view != nil) {
+ if(!opaque) {
+ GLint zeroOpacity = 0;
+ [ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity];
+ }
+ [ctx setView:view];
+ if(!isBackingLayerView) {
+ [view unlockFocus];
}
+ }
+ }
[pool release];
- return nsContext;
-}
-
-void * getCurrentContext() {
- NSOpenGLContext *nsContext = NULL;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- nsContext = [NSOpenGLContext currentContext];
- [pool release];
- return nsContext;;
+ return ctx;
}
-void * getCGLContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- void * cglContext = NULL;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- cglContext = [nsContext CGLContextObj];
- [pool release];
- return cglContext;
-}
-
-void * getNSView(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- void * view = NULL;
-
+Bool makeCurrentContext(NSOpenGLContext* ctx) {
+#if 0
+ // we issue the CGL Lock from Java upfront!
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- view = [nsContext view];
+ CGLError cglError = CGLLockContext([ctx CGLContextObj]);
+ if(0 == cglError) {
+ [ctx makeCurrentContext];
+ }
[pool release];
- return view;
-}
-
-Bool makeCurrentContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+ return 0 == cglError;
+#else
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext makeCurrentContext];
+ [ctx makeCurrentContext];
[pool release];
return true;
+#endif
}
-Bool clearCurrentContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+Bool clearCurrentContext(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSOpenGLContext *currentNSContext = [NSOpenGLContext currentContext];
- if( currentNSContext != nsContext ) {
- [nsContext makeCurrentContext];
+ if( currentNSContext != ctx ) {
+ [ctx makeCurrentContext];
}
[NSOpenGLContext clearCurrentContext];
+#if 0
+ // we issue the CGL Lock from Java upfront!
+ CGLUnlockContext([ctx CGLContextObj]);
+#endif
[pool release];
return true;
}
-Bool deleteContext(void* nsJContext, Bool releaseOnMainThread) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+Bool deleteContext(NSOpenGLContext* ctx, Bool releaseOnMainThread) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext clearDrawable];
+ [ctx clearDrawable];
if(releaseOnMainThread && NO == [NSThread isMainThread]) {
- [nsContext performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:YES];
+ [ctx performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO];
} else {
// would hangs for ~10s for 1 of a shared context set or offscreen context, set releaseOnMainThread=true !
- [nsContext release];
+ [ctx release];
}
[pool release];
return true;
}
-Bool flushBuffer(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+Bool flushBuffer(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext flushBuffer];
+ [ctx flushBuffer];
[pool release];
return true;
}
-void setContextOpacity(void* nsJContext, int opacity) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
- [nsContext setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity];
+void setContextOpacity(NSOpenGLContext* ctx, int opacity) {
+ [ctx setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity];
}
-void updateContext(void* nsJContext) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
-
+void updateContext(NSOpenGLContext* ctx) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext update];
+ [ctx update];
[pool release];
}
-void copyContext(void* destContext, void* srcContext, int mask) {
- NSOpenGLContext *src = (NSOpenGLContext*) srcContext;
- NSOpenGLContext *dst = (NSOpenGLContext*) destContext;
- [dst copyAttributesFromContext: src withMask: mask];
+void copyContext(NSOpenGLContext* dest, NSOpenGLContext* src, int mask) {
+ [dest copyAttributesFromContext: src withMask: mask];
}
-void* updateContextRegister(void* nsJContext, void* nsJView) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- NSView *nsView = (NSView*)nsJView;
-
+void* updateContextRegister(NSOpenGLContext* ctx, NSView* view) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: nsContext view: nsView];
+ ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: ctx view: view];
[pool release];
return contextUpdater;
}
@@ -666,7 +659,7 @@ void updateContextUnregister(void* updater) {
[pool release];
}
-void* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
+NSOpenGLPixelBuffer* createPBuffer(int renderTarget, int internalFormat, int width, int height) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc]
initWithTextureTarget:renderTarget
@@ -678,35 +671,25 @@ void* createPBuffer(int renderTarget, int internalFormat, int width, int height)
return pBuffer;
}
-Bool destroyPBuffer(void* buffer) {
- NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
-
+Bool destroyPBuffer(NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
[pBuffer release];
[pool release];
-
return true;
}
-void setContextPBuffer(void* nsJContext, void* buffer) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
-
+void setContextPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext setPixelBuffer: pBuffer
+ [ctx setPixelBuffer: pBuffer
cubeMapFace: 0
mipMapLevel: 0
- currentVirtualScreen: [nsContext currentVirtualScreen]];
+ currentVirtualScreen: [ctx currentVirtualScreen]];
[pool release];
}
-void setContextTextureImageToPBuffer(void* nsJContext, void* buffer, int colorBuffer) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
- NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer;
-
+void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* pBuffer, GLenum colorBuffer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [nsContext setTextureImageToPixelBuffer: pBuffer
- colorBuffer: (unsigned long) colorBuffer];
+ [ctx setTextureImageToPixelBuffer: pBuffer colorBuffer: colorBuffer];
[pool release];
}
@@ -746,10 +729,9 @@ void* getProcAddress(const char *procname) {
return NULL;
}
-void setSwapInterval(void* nsJContext, int interval) {
- NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext;
+void setSwapInterval(NSOpenGLContext* ctx, int interval) {
GLint swapInterval = interval;
- [nsContext setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
+ [ctx setValues: &swapInterval forParameter: NSOpenGLCPSwapInterval];
}
Bool setGammaRamp(int tableSize, float* redRamp, float* greenRamp, float* blueRamp) {
diff --git a/src/jogl/native/timespec.c b/src/jogl/native/timespec.c
new file mode 100644
index 000000000..74c1a6901
--- /dev/null
+++ b/src/jogl/native/timespec.c
@@ -0,0 +1,63 @@
+#include "timespec.h"
+#include <sys/time.h>
+
+void timespec_now(struct timespec *ts)
+{
+ struct timeval tv;
+
+ // not using clock_gettime() [of rt library] due to portability
+ gettimeofday(&tv, NULL);
+ ts->tv_sec = tv.tv_sec;
+ ts->tv_nsec = tv.tv_usec*1000;
+}
+
+void timespec_addms(struct timespec *ts, long ms)
+{
+ int sec=ms/1000;
+ ms=ms-sec*1000;
+
+ // perform the addition
+ ts->tv_nsec+=ms*1000000;
+
+ // adjust the time
+ ts->tv_sec+=ts->tv_nsec/1000000000 + sec;
+ ts->tv_nsec=ts->tv_nsec%1000000000;
+}
+
+void timespec_addns(struct timespec *ts, long ns)
+{
+ int sec=ns/1000000000;
+ ns=ns - sec*1000000000;
+
+ // perform the addition
+ ts->tv_nsec+=ns;
+
+ // adjust the time
+ ts->tv_sec+=ts->tv_nsec/1000000000 + sec;
+ ts->tv_nsec=ts->tv_nsec%1000000000;
+
+}
+
+int timespec_compare(struct timespec *a, struct timespec *b)
+{
+ if (a->tv_sec!=b->tv_sec)
+ return a->tv_sec-b->tv_sec;
+ return a->tv_nsec-b->tv_nsec;
+}
+
+void timespec_subtract(struct timespec *r, struct timespec *a, struct timespec *b)
+{
+ r->tv_sec = a->tv_sec;
+ r->tv_nsec = a->tv_nsec - b->tv_nsec;
+ if (r->tv_nsec < 0) {
+ // borrow.
+ r->tv_nsec += 1000000000;
+ r->tv_sec --;
+ }
+ r->tv_sec = r->tv_sec - b->tv_sec;
+}
+
+long timespec_milliseconds(struct timespec *a)
+{
+ return a->tv_sec*1000 + a->tv_nsec/1000000;
+}
diff --git a/src/jogl/native/timespec.h b/src/jogl/native/timespec.h
new file mode 100644
index 000000000..671eb4716
--- /dev/null
+++ b/src/jogl/native/timespec.h
@@ -0,0 +1,19 @@
+#ifndef _timespec_h
+#define _timespec_h
+
+#include <time.h>
+
+void timespec_now(struct timespec *ts);
+void timespec_addms(struct timespec *ts, long ms);
+void timespec_addns(struct timespec *ts, long ns);
+
+/** returns 0: a==b, >0: a>b, <0: a<b */
+int timespec_compare(struct timespec *a, struct timespec *b);
+
+/** computes r = a - b */
+void timespec_subtract(struct timespec *r, struct timespec *a, struct timespec *b);
+
+/** convert the timespec into milliseconds (may overflow) */
+long timespec_milliseconds(struct timespec *a);
+
+#endif /* _timespec_h */
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java
index 784343c5a..1930bdda3 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsConfiguration.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 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
@@ -50,7 +51,7 @@ public interface AbstractGraphicsConfiguration extends Cloneable {
/**
* Return the capabilities reflecting this graphics configuration,
- * which may differ from the capabilites used to choose this configuration.
+ * which may differ from the capabilities used to choose this configuration.
*
* @return An immutable instance of the Capabilities to avoid mutation by
* the user.
@@ -61,7 +62,7 @@ public interface AbstractGraphicsConfiguration extends Cloneable {
* Return the capabilities used to choose this graphics configuration.
*
* These may be used to reconfigure the NativeWindow in case
- * the device changes in a multi screen environment.
+ * the device changes in a multiple screen environment.
*
* @return An immutable instance of the Capabilities to avoid mutation by
* the user.
@@ -69,10 +70,10 @@ public interface AbstractGraphicsConfiguration extends Cloneable {
public CapabilitiesImmutable getRequestedCapabilities();
/**
- * In case this instance already reflects a native configuration,
- * return this one.
- * Otherwise return the encapsuled native configuration,
- * as it shall be included e.g. in the AWT case.
+ * In case the implementation utilizes a delegation pattern to wrap abstract toolkits,
+ * this method shall return the native {@link AbstractGraphicsConfiguration},
+ * otherwise this instance.
+ * @see NativeSurface#getGraphicsConfiguration()
*/
public AbstractGraphicsConfiguration getNativeGraphicsConfiguration();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
index 83b437612..fa25c214f 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/AbstractGraphicsDevice.java
@@ -110,14 +110,15 @@ public interface AbstractGraphicsDevice extends Cloneable {
public void unlock();
/**
- * Optionally closing the device.<br>
- * The default implementation is a NOP operation, returning false.<br>
+ * Optionally closing the device.
+ * <p>
+ * The default implementation is a <code>NOP</code>, just setting the handle to <code>null</code>.
+ * </p>
* The specific implementing, ie {@link javax.media.nativewindow.x11.X11GraphicsDevice},
* shall have a enable/disable like {@link javax.media.nativewindow.x11.X11GraphicsDevice#setCloseDisplay(boolean, boolean)},<br>
* which shall be invoked at creation time to determine ownership/role of freeing the resource.<br>
*
- * @return true if a specialized closing operation was successfully issued, otherwise false,
- * ie no native closing operation was issued, which doesn't imply an error at all.
+ * @return true if the handle was not <code>null</code>, otherwise false.
*/
public boolean close();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
index ffa8bfae6..3eb7a6c9a 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsConfiguration.java
@@ -84,8 +84,6 @@ public class DefaultGraphicsConfiguration implements Cloneable, AbstractGraphics
* The use case for setting the Capabilities at a later time is
* a change of the graphics device in a multi-screen environment.<br>
*
- * The objects reference is being used.
- *
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
protected void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
index c2aa6fae9..187959a67 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/DefaultGraphicsDevice.java
@@ -46,7 +46,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
/**
* Create an instance with the system default {@link ToolkitLock},
- * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}.
+ * gathered via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.
* @param type
*/
public DefaultGraphicsDevice(String type, String connection, int unitID) {
@@ -55,12 +55,12 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = 0;
- setToolkitLock( NativeWindowFactory.getDefaultToolkitLock(type) );
+ this.toolkitLock = NativeWindowFactory.getDefaultToolkitLock(type);
}
/**
* Create an instance with the system default {@link ToolkitLock}.
- * gathered via {@link NativeWindowFactory#createDefaultToolkitLock()}.
+ * gathered via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
* @param type
* @param handle
*/
@@ -70,7 +70,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = handle;
- setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(type, handle) );
+ this.toolkitLock = NativeWindowFactory.createDefaultToolkitLock(type, handle);
}
/**
@@ -85,7 +85,7 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
this.unitID = unitID;
this.uniqueID = getUniqueID(type, connection, unitID);
this.handle = handle;
- setToolkitLock( locker );
+ this.toolkitLock = null != locker ? locker : NativeWindowFactoryImpl.getNullToolkitLock();
}
@Override
@@ -140,6 +140,10 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
}
public boolean close() {
+ if(0 != handle) {
+ handle = 0;
+ return true;
+ }
return false;
}
@@ -152,10 +156,21 @@ public class DefaultGraphicsDevice implements Cloneable, AbstractGraphicsDevice
* Set the internal ToolkitLock, which is used within the
* {@link #lock()} and {@link #unlock()} implementation.
*
+ * <p>
+ * The current ToolkitLock is being locked/unlocked while swapping the reference,
+ * ensuring no concurrent access can occur during the swap.
+ * </p>
+ *
* @param locker the ToolkitLock, if null, {@link jogamp.nativewindow.NullToolkitLock} is being used
*/
protected void setToolkitLock(ToolkitLock locker) {
- this.toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
+ final ToolkitLock _toolkitLock = toolkitLock;
+ _toolkitLock.lock();
+ try {
+ toolkitLock = ( null == locker ) ? NativeWindowFactoryImpl.getNullToolkitLock() : locker ;
+ } finally {
+ _toolkitLock.unlock();
+ }
}
/**
diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
index fa3923dcf..259644467 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java
@@ -40,7 +40,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-
/**
* Provides the mechanism by which the graphics configuration for a
* window can be chosen before the window is created. The graphics
@@ -60,12 +59,34 @@ import java.util.Map;
public abstract class GraphicsConfigurationFactory {
protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
- private static Map/*<Class, NativeWindowFactory>*/ registeredFactories =
- Collections.synchronizedMap(new HashMap());
- private static Class abstractGraphicsDeviceClass;
+ private static Map<Class<?>, GraphicsConfigurationFactory> registeredFactories =
+ Collections.synchronizedMap(new HashMap<Class<?>, GraphicsConfigurationFactory>());
+ private static Class<?> abstractGraphicsDeviceClass;
static {
- initialize();
+ abstractGraphicsDeviceClass = javax.media.nativewindow.AbstractGraphicsDevice.class;
+
+ // Register the default no-op factory for arbitrary
+ // AbstractGraphicsDevice implementations, including
+ // AWTGraphicsDevice instances -- the OpenGL binding will take
+ // care of handling AWTGraphicsDevices on X11 platforms (as
+ // well as X11GraphicsDevices in non-AWT situations)
+ registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl());
+
+ if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
+ try {
+ ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory",
+ "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ if(NativeWindowFactory.isAWTAvailable()) {
+ try {
+ ReflectionUtil.callStaticMethod("jogamp.nativewindow.x11.awt.X11AWTGraphicsConfigurationFactory",
+ "registerFactory", null, null, GraphicsConfigurationFactory.class.getClassLoader());
+ } catch (Exception e) { /* n/a */ }
+ }
+ }
}
protected static String getThreadName() {
@@ -85,27 +106,6 @@ public abstract class GraphicsConfigurationFactory {
protected GraphicsConfigurationFactory() {
}
- private static void initialize() {
- abstractGraphicsDeviceClass = javax.media.nativewindow.AbstractGraphicsDevice.class;
-
- if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) {
- try {
- GraphicsConfigurationFactory factory = (GraphicsConfigurationFactory)
- ReflectionUtil.createInstance("jogamp.nativewindow.x11.X11GraphicsConfigurationFactory", null,
- GraphicsConfigurationFactory.class.getClassLoader());
- registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, factory);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- // Register the default no-op factory for arbitrary
- // AbstractGraphicsDevice implementations, including
- // AWTGraphicsDevice instances -- the OpenGL binding will take
- // care of handling AWTGraphicsDevices on X11 platforms (as
- // well as X11GraphicsDevices in non-AWT situations)
- registerFactory(abstractGraphicsDeviceClass, new DefaultGraphicsConfigurationFactoryImpl());
- }
-
/** Returns the factory for use with the given type of
AbstractGraphicsDevice. */
public static GraphicsConfigurationFactory getFactory(AbstractGraphicsDevice device) {
@@ -122,7 +122,7 @@ public abstract class GraphicsConfigurationFactory {
*
* @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
*/
- public static GraphicsConfigurationFactory getFactory(Class abstractGraphicsDeviceImplementor)
+ public static GraphicsConfigurationFactory getFactory(Class<?> abstractGraphicsDeviceImplementor)
throws IllegalArgumentException, NativeWindowException
{
if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
@@ -130,10 +130,9 @@ public abstract class GraphicsConfigurationFactory {
}
GraphicsConfigurationFactory factory = null;
- Class clazz = abstractGraphicsDeviceImplementor;
+ Class<?> clazz = abstractGraphicsDeviceImplementor;
while (clazz != null) {
- factory =
- (GraphicsConfigurationFactory) registeredFactories.get(clazz);
+ factory = registeredFactories.get(clazz);
if (factory != null) {
if(DEBUG) {
System.err.println("GraphicsConfigurationFactory.getFactory() "+abstractGraphicsDeviceImplementor+" -> "+factory);
@@ -143,7 +142,7 @@ public abstract class GraphicsConfigurationFactory {
clazz = clazz.getSuperclass();
}
// Return the default
- factory = (GraphicsConfigurationFactory)registeredFactories.get(abstractGraphicsDeviceClass);
+ factory = registeredFactories.get(abstractGraphicsDeviceClass);
if(DEBUG) {
System.err.println("GraphicsConfigurationFactory.getFactory() DEFAULT "+abstractGraphicsDeviceClass+" -> "+factory);
}
@@ -157,7 +156,7 @@ public abstract class GraphicsConfigurationFactory {
*
* @throws IllegalArgumentException if the given class does not implement AbstractGraphicsDevice
*/
- protected static void registerFactory(Class abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory)
+ protected static void registerFactory(Class<?> abstractGraphicsDeviceImplementor, GraphicsConfigurationFactory factory)
throws IllegalArgumentException
{
if (!(abstractGraphicsDeviceClass.isAssignableFrom(abstractGraphicsDeviceImplementor))) {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
index e691ba8e6..e255dc051 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeSurface.java
@@ -118,6 +118,24 @@ public interface NativeSurface extends SurfaceUpdatedListener {
*/
public boolean surfaceSwap();
+ /** Appends the given {@link SurfaceUpdatedListener} to the end of the list. */
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
+ /**
+ * Inserts the given {@link SurfaceUpdatedListener} at the
+ * specified position in the list.<br>
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
+ * @param l The listener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
+
+ /** Remove the specified {@link SurfaceUpdatedListener} from the list. */
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
/**
* Returns the handle to the surface for this NativeSurface. <P>
*
@@ -149,6 +167,11 @@ public interface NativeSurface extends SurfaceUpdatedListener {
/**
* Returns the graphics configuration corresponding to this window.
+ * <p>
+ * In case the implementation utilizes a delegation pattern to wrap abstract toolkits,
+ * this method shall return the native {@link AbstractGraphicsConfiguration} via {@link AbstractGraphicsConfiguration#getNativeGraphicsConfiguration()}.
+ * </p>
+ * @see AbstractGraphicsConfiguration#getNativeGraphicsConfiguration()
* @see javax.media.nativewindow.GraphicsConfigurationFactory#chooseGraphicsConfiguration(Capabilities, CapabilitiesChooser, AbstractGraphicsScreen)
*/
public AbstractGraphicsConfiguration getGraphicsConfiguration();
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
index 76ac72953..2bc352116 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindow.java
@@ -104,20 +104,26 @@ public interface NativeWindow extends NativeSurface {
/**
* @return the current x position of the top-left corner
- * of the client area, hence excluding insets (window decorations).<br>
+ * of the client area relative to it's parent.
+ * Since the position reflects the client area, it does not include the insets.
* @see #getInsets()
*/
public int getX();
/**
* @return the current y position of the top-left corner
- * of the client area, hence excluding insets (window decorations).<br>
+ * of the client area relative to it's parent.
+ * Since the position reflects the client area, it does not include the insets.
* @see #getInsets()
*/
public int getY();
/**
- * Returns the current absolute location of this window.
+ * Returns the current position of the top-left corner
+ * of the client area in screen coordinates.
+ * <p>
+ * Since the position reflects the client area, it does not include the insets.
+ * </p>
* @param point if not null,
* {@link javax.media.nativewindow.util.Point#translate(javax.media.nativewindow.util.Point)}
* the passed {@link javax.media.nativewindow.util.Point} by this location on the screen and return it.
@@ -126,4 +132,7 @@ public interface NativeWindow extends NativeSurface {
*/
public Point getLocationOnScreen(Point point);
+ /** Returns true if this native window owns the focus, otherwise false. */
+ boolean hasFocus();
+
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index ef8876f50..c69b18b30 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -33,15 +33,20 @@
package javax.media.nativewindow;
-import java.security.*;
-import java.util.*;
-
-import com.jogamp.common.util.*;
-import com.jogamp.common.os.Platform;
-
-import jogamp.nativewindow.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NativeWindowFactoryImpl;
+
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
/** Provides a pluggable mechanism for arbitrary window toolkits to
adapt their components to the {@link NativeWindow} interface,
@@ -75,20 +80,25 @@ public abstract class NativeWindowFactory {
private static NativeWindowFactory defaultFactory;
private static Map<Class<?>, NativeWindowFactory> registeredFactories;
+
private static Class<?> nativeWindowClass;
private static String nativeWindowingTypePure;
private static String nativeWindowingTypeCustom;
private static boolean isAWTAvailable;
- public static final String AWTComponentClassName = "java.awt.Component" ;
- public static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
- public static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
- public static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
- public static final String GDIClassName = "jogamp.nativewindow.windows.GDI";
- public static final String X11JAWTToolkitLockClassName = "jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock" ;
- public static final String X11ToolkitLockClassName = "jogamp.nativewindow.x11.X11ToolkitLock" ;
+
+ private static final String JAWTUtilClassName = "jogamp.nativewindow.jawt.JAWTUtil" ;
+ private static final String X11UtilClassName = "jogamp.nativewindow.x11.X11Util";
+ private static final String OSXUtilClassName = "jogamp.nativewindow.macosx.OSXUtil";
+ private static final String GDIClassName = "jogamp.nativewindow.windows.GDIUtil";
+
private static Class<?> jawtUtilClass;
private static Method jawtUtilGetJAWTToolkitMethod;
private static Method jawtUtilInitMethod;
+
+ public static final String AWTComponentClassName = "java.awt.Component" ;
+ 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;
@@ -132,16 +142,18 @@ public abstract class NativeWindowFactory {
static boolean initialized = false;
- private static void initNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) {
+ private static void initSingletonNativeImpl(final boolean firstUIActionOnProcess, final ClassLoader cl) {
isFirstUIActionOnProcess = firstUIActionOnProcess;
-
- String clazzName = null;
+
+ final String clazzName;
if( TYPE_X11.equals(nativeWindowingTypePure) ) {
clazzName = X11UtilClassName;
} else if( TYPE_WINDOWS.equals(nativeWindowingTypePure) ) {
clazzName = GDIClassName;
} else if( TYPE_MACOSX.equals(nativeWindowingTypePure) ) {
clazzName = OSXUtilClassName;
+ } else {
+ clazzName = null;
}
if( null != clazzName ) {
ReflectionUtil.callStaticMethod(clazzName, "initSingleton",
@@ -152,7 +164,7 @@ public abstract class NativeWindowFactory {
requiresToolkitLock = res.booleanValue();
} else {
requiresToolkitLock = false;
- }
+ }
}
/**
@@ -178,6 +190,8 @@ public abstract class NativeWindowFactory {
System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.initSingleton("+firstUIActionOnProcess+")");
}
+ final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
+
// Gather the windowing OS first
AccessControlContext acc = AccessController.getContext();
nativeWindowingTypePure = _getNativeWindowingType();
@@ -188,12 +202,10 @@ public abstract class NativeWindowFactory {
nativeWindowingTypeCustom = tmp;
}
- final ClassLoader cl = NativeWindowFactory.class.getClassLoader();
-
if(firstUIActionOnProcess) {
// X11 initialization before possible AWT initialization
- initNativeImpl(true, cl);
- }
+ initSingletonNativeImpl(true, cl);
+ }
isAWTAvailable = false; // may be set to true below
if( !Debug.getBooleanProperty("java.awt.headless", true, acc) &&
@@ -203,7 +215,7 @@ public abstract class NativeWindowFactory {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
- jawtUtilClass = Class.forName(JAWTUtilClassName, false, NativeWindowFactory.class.getClassLoader());
+ jawtUtilClass = Class.forName(JAWTUtilClassName, true, NativeWindowFactory.class.getClassLoader());
jawtUtilInitMethod = jawtUtilClass.getDeclaredMethod("initSingleton", (Class[])null);
jawtUtilInitMethod.setAccessible(true);
jawtUtilGetJAWTToolkitMethod = jawtUtilClass.getDeclaredMethod("getJAWTToolkitLock", new Class[]{});
@@ -227,7 +239,7 @@ public abstract class NativeWindowFactory {
}
if(!firstUIActionOnProcess) {
// X11 initialization after possible AWT initialization
- initNativeImpl(false, cl);
+ initSingletonNativeImpl(false, cl);
}
registeredFactories = Collections.synchronizedMap(new HashMap<Class<?>, NativeWindowFactory>());
@@ -260,6 +272,21 @@ public abstract class NativeWindowFactory {
}
}
+ public static synchronized void shutdown() {
+ if(initialized) {
+ initialized = false;
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() START");
+ }
+ registeredFactories.clear();
+ registeredFactories = null;
+ // X11Util.shutdown(..) already called via GLDrawableFactory.shutdown() ..
+ if(DEBUG) {
+ System.err.println(Thread.currentThread().getName()+" - NativeWindowFactory.shutdown() END");
+ }
+ }
+ }
+
/** @return true if initialized with <b>{@link #initSingleton(boolean) initSingleton(firstUIActionOnProcess==true)}</b>,
otherwise false. */
public static boolean isFirstUIActionOnProcess() {
@@ -319,31 +346,30 @@ public abstract class NativeWindowFactory {
* <ul>
* <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
* <ul>
- * <li>If native <b>X11 type</b> with or w/o AWT</li>
- * <ul>
- * <li> If <b>AWT available</b> </li>
+ * <li>If <b>AWT-type</b> and <b>native-X11-type</b> and <b>AWT-available</b></li>
* <ul>
* <li> return {@link jogamp.nativewindow.jawt.JAWTToolkitLock} </li>
* </ul>
- * </ul>
* </ul>
* <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
public static ToolkitLock getDefaultToolkitLock(String type) {
if( requiresToolkitLock() ) {
- if( TYPE_X11 == type || TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) ) {
- if( isAWTAvailable() ) {
- return getAWTToolkitLock();
- }
+ if( TYPE_AWT == type && TYPE_X11 == getNativeWindowType(false) && isAWTAvailable() ) {
+ return getAWTToolkitLock();
}
}
return NativeWindowFactoryImpl.getNullToolkitLock();
}
- protected static ToolkitLock getAWTToolkitLock() {
+ private static ToolkitLock getAWTToolkitLock() {
Object resO = ReflectionUtil.callMethod(null, jawtUtilGetJAWTToolkitMethod);
+ if(DEBUG) {
+ System.err.println("NativeWindowFactory.getAWTToolkitLock()");
+ Thread.dumpStack();
+ }
if(resO instanceof ToolkitLock) {
return (ToolkitLock) resO;
} else {
@@ -363,26 +389,49 @@ public abstract class NativeWindowFactory {
* <ul>
* <li>If <b>X11 type</b> </li>
* <ul>
- * <li> If <b>AWT available</b> </li>
+ * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
+ * </ul>
+ * </ul>
+ * <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
+ * </ul>
+ */
+ 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 NativeWindowFactoryImpl.getNullToolkitLock();
+ }
+
+ /**
+ * Creates the default {@link ToolkitLock} for <code>type</code> and <code>deviceHandle</code>.
+ * <br>
+ * <ul>
+ * <li> If {@link #initSingleton(boolean) initSingleton( <b>firstUIActionOnProcess := false</b> )} </li>
+ * <ul>
+ * <li>If <b>X11 type</b> </li>
+ * <ul>
+ * <li> If <b>shared-AWT-type</b> and <b>AWT available</b> </li>
* <ul>
* <li> return {@link jogamp.nativewindow.jawt.x11.X11JAWTToolkitLock} </li>
* </ul>
- * <li> If <b>AWT not available</b> </li>
- * <ul>
- * <li> return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
- * </ul>
+ * <li> else return {@link jogamp.nativewindow.x11.X11ToolkitLock} </li>
* </ul>
* </ul>
* <li> Otherwise return {@link jogamp.nativewindow.NullToolkitLock} </li>
* </ul>
*/
- public static ToolkitLock createDefaultToolkitLock(String type, long deviceHandle) {
+ 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( isAWTAvailable() ) {
+ if( TYPE_AWT == sharedType && isAWTAvailable() ) {
return createX11AWTToolkitLock(deviceHandle);
}
return createX11ToolkitLock(deviceHandle);
@@ -393,6 +442,10 @@ public abstract class NativeWindowFactory {
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);
@@ -470,4 +523,37 @@ public abstract class NativeWindowFactory {
NativeWindow. Implementors of concrete NativeWindowFactory
subclasses should override this method. */
protected abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException;
+
+ /**
+ * Returns the {@link OffscreenLayerSurface} instance of this {@link NativeSurface}.
+ * <p>
+ * In case this surface is a {@link NativeWindow}, we traverse from the given surface
+ * up to root until an implementation of {@link OffscreenLayerSurface} is found.
+ * In case <code>ifEnabled</code> is true, the surface must also implement {@link OffscreenLayerOption}
+ * where {@link OffscreenLayerOption#isOffscreenLayerSurfaceEnabled()} is <code>true</code>.
+ * </p>
+ *
+ * @param surface The surface to query.
+ * @param ifEnabled If true, only return the enabled {@link OffscreenLayerSurface}, see {@link OffscreenLayerOption#isOffscreenLayerSurfaceEnabled()}.
+ * @return
+ */
+ public static OffscreenLayerSurface getOffscreenLayerSurface(NativeSurface surface, boolean ifEnabled) {
+ if(surface instanceof OffscreenLayerSurface &&
+ ( !ifEnabled || surface instanceof OffscreenLayerOption ) ) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) surface;
+ return ( !ifEnabled || ((OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ if(surface instanceof NativeWindow) {
+ NativeWindow nw = ((NativeWindow) surface).getParent();
+ while(null != nw) {
+ if(nw instanceof OffscreenLayerSurface &&
+ ( !ifEnabled || nw instanceof OffscreenLayerOption ) ) {
+ final OffscreenLayerSurface ols = (OffscreenLayerSurface) nw;
+ return ( !ifEnabled || ((OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols : null;
+ }
+ nw = nw.getParent();
+ }
+ }
+ return null;
+ }
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java
new file mode 100644
index 000000000..12d30b3cd
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerOption.java
@@ -0,0 +1,61 @@
+/**
+ * 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 javax.media.nativewindow;
+
+/**
+ * Handling requests for using an {@link OffscreenLayerSurface}
+ * within the implementation.
+ */
+public interface OffscreenLayerOption {
+ /**
+ * Request an offscreen layer, if supported.
+ * <p>
+ * Shall be called before the first {@link NativeWindow#lockSurface()},
+ * and hence before realization.
+ * </p>
+ *
+ * @see #getShallUseOffscreenLayer()
+ * @see #isOffscreenLayerSurfaceEnabled()
+ */
+ public void setShallUseOffscreenLayer(boolean v);
+
+ /** Returns the property set by {@link #setShallUseOffscreenLayer(boolean)}. */
+ public boolean getShallUseOffscreenLayer();
+
+ /**
+ * Returns true if this instance uses an offscreen layer, otherwise false.
+ * <p>
+ * This instance is an offscreen layer, if {@link #setShallUseOffscreenLayer(boolean) setShallUseOffscreenLayer(true)}
+ * has been called before it's realization and first lock and the underlying implementation supports it.
+ * </p>
+ * The return value is undefined before issuing the first {@link NativeWindow#lockSurface()}.
+ *
+ * @see #setShallUseOffscreenLayer(boolean)
+ */
+ public boolean isOffscreenLayerSurfaceEnabled();
+} \ No newline at end of file
diff --git a/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
new file mode 100644
index 000000000..dd36509ba
--- /dev/null
+++ b/src/nativewindow/classes/javax/media/nativewindow/OffscreenLayerSurface.java
@@ -0,0 +1,48 @@
+/**
+ * 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 javax.media.nativewindow;
+
+/**
+ * Interface specifying the offscreen layer surface protocol.
+ */
+public interface OffscreenLayerSurface {
+ /**
+ * Attach the offscreen layer to this offscreen layer surface.
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+ */
+ public void attachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+
+ /**
+ * Detaches a previously attached offscreen layer from this offscreen layer surface.
+ * @see #attachSurfaceLayer(long)
+ * @see #isOffscreenLayerSurfaceEnabled()
+ * @throws NativeWindowException if {@link #isOffscreenLayerSurfaceEnabled()} == false
+ */
+ public void detachSurfaceLayer(final long layerHandle) throws NativeWindowException;
+}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
index e34476228..9100beac2 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/ProxySurface.java
@@ -28,12 +28,15 @@
package javax.media.nativewindow;
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
public abstract class ProxySurface implements NativeSurface {
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+ private AbstractGraphicsConfiguration config; // control access due to delegation
protected RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
- protected AbstractGraphicsConfiguration config;
protected long displayHandle;
protected int height;
protected int scrnIndex;
@@ -42,7 +45,7 @@ public abstract class ProxySurface implements NativeSurface {
public ProxySurface(AbstractGraphicsConfiguration cfg) {
invalidate();
config = cfg;
- displayHandle=cfg.getScreen().getDevice().getHandle();
+ displayHandle=cfg.getNativeGraphicsConfiguration().getScreen().getDevice().getHandle();
}
void invalidate() {
@@ -55,12 +58,16 @@ public abstract class ProxySurface implements NativeSurface {
return displayHandle;
}
- public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ protected final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
return config;
}
+
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
+ }
public final int getScreenIndex() {
- return config.getScreen().getIndex();
+ return getGraphicsConfiguration().getScreen().getIndex();
}
public abstract long getSurfaceHandle();
@@ -73,7 +80,7 @@ public abstract class ProxySurface implements NativeSurface {
return height;
}
- public void setSize(int width, int height) {
+ public void surfaceSizeChanged(int width, int height) {
this.width = width;
this.height = height;
}
@@ -82,16 +89,29 @@ public abstract class ProxySurface implements NativeSurface {
return false;
}
- public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
+
public int lockSurface() throws NativeWindowException {
surfaceLock.lock();
int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
adevice.lock();
try {
res = lockSurfaceImpl();
@@ -113,7 +133,7 @@ public abstract class ProxySurface implements NativeSurface {
surfaceLock.validateLocked();
if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
} finally {
@@ -143,5 +163,5 @@ public abstract class ProxySurface implements NativeSurface {
return surfaceLock.getOwner();
}
- public abstract String toString();
+ public abstract String toString();
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
index fc32b57b3..956e68e61 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceChangeable.java
@@ -41,8 +41,14 @@ package javax.media.nativewindow;
public interface SurfaceChangeable {
+ /** Sets the surface handle which is created outside of this implementation */
public void setSurfaceHandle(long surfaceHandle);
- public void setSize(int width, int height);
+
+ /**
+ * The surface's size has been determined or changed.
+ * Implementation shall update the stored surface size with the given ones.
+ */
+ public void surfaceSizeChanged(int width, int height);
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
index 88e805d14..0912b5afe 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/SurfaceUpdatedListener.java
@@ -34,8 +34,12 @@
package javax.media.nativewindow;
+/**
+ * Clients may add their SurfaceUpdateListener implementation to a {@link javax.media.nativewindow.NativeSurface}
+ * allowing to get notified after the surface has been updated, eg. after a swap buffer operation.
+ */
public interface SurfaceUpdatedListener {
- /** Notification of a surface update event.
+ /** Notification of a surface update event, eg. after a swap buffer operation.
*
* @param updater is the caller object who updated the surface,
* e.g. a JOGL GLDrawable.
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
index d83a92a5b..45a3db838 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsConfiguration.java
@@ -41,11 +41,13 @@
package javax.media.nativewindow.awt;
import javax.media.nativewindow.*;
+
import java.awt.Component;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.image.ColorModel;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+
import jogamp.nativewindow.Debug;
/** A wrapper for an AWT GraphicsConfiguration allowing it to be
@@ -63,56 +65,61 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
this.encapsulated=encapsulated;
}
- public AWTGraphicsConfiguration(AWTGraphicsScreen screen, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- GraphicsConfiguration config) {
+ private AWTGraphicsConfiguration(AWTGraphicsScreen screen, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ GraphicsConfiguration config) {
super(screen, capsChosen, capsRequested);
this.config = config;
this.encapsulated=null;
}
-
+
/**
* @param capsChosen if null, <code>capsRequested</code> is copied and aligned
- * with the graphics capabilties of the AWT Component to produce the chosen Capabilties.
+ * with the graphics Capabilities of the AWT Component to produce the chosen Capabilities.
* Otherwise the <code>capsChosen</code> is used.
*/
- public static AWTGraphicsConfiguration create(Component awtComp, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested)
- {
- AWTGraphicsScreen awtScreen = null;
- AWTGraphicsDevice awtDevice = null;
- GraphicsDevice awtGraphicsDevice = null;
- GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration();
- if(null!=awtGfxConfig) {
- awtGraphicsDevice = awtGfxConfig.getDevice();
- if(null!=awtGraphicsDevice) {
- // Create Device/Screen
- awtDevice = new AWTGraphicsDevice(awtGraphicsDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
- awtScreen = new AWTGraphicsScreen(awtDevice);
- }
+ public static AWTGraphicsConfiguration create(Component awtComp, CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) {
+ final GraphicsConfiguration awtGfxConfig = awtComp.getGraphicsConfiguration();
+ if(null==awtGfxConfig) {
+ throw new NativeWindowException("AWTGraphicsConfiguration.create: Null AWT GraphicsConfiguration @ "+awtComp);
}
- if(null==awtScreen) {
- // use defaults since no native peer is available yet
- awtScreen = (AWTGraphicsScreen) AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
- awtDevice = (AWTGraphicsDevice) awtScreen.getDevice();
- awtGraphicsDevice = awtDevice.getGraphicsDevice();
+ final GraphicsDevice awtGraphicsDevice = awtGfxConfig.getDevice();
+ if(null==awtGraphicsDevice) {
+ throw new NativeWindowException("AWTGraphicsConfiguration.create: Null AWT GraphicsDevice @ "+awtGfxConfig);
}
+ // Create Device/Screen
+ final AWTGraphicsDevice awtDevice = new AWTGraphicsDevice(awtGraphicsDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final AWTGraphicsScreen awtScreen = new AWTGraphicsScreen(awtDevice);
+
if(null==capsChosen) {
GraphicsConfiguration gc = awtGraphicsDevice.getDefaultConfiguration();
- capsChosen = setupCapabilitiesRGBABits(capsChosen, gc);
+ capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsRequested, gc);
+ }
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(awtDevice);
+ final AbstractGraphicsConfiguration config = factory.chooseGraphicsConfiguration(capsChosen, capsRequested, null, awtScreen);
+ if(config instanceof AWTGraphicsConfiguration) {
+ return (AWTGraphicsConfiguration) config;
}
+ // System.err.println("Info: AWTGraphicsConfiguration.create: Expected AWTGraphicsConfiguration got: "+config.getClass()+" w/ factory "+factory.getClass()+" - Unable to encapsulate native GraphicsConfiguration.");
return new AWTGraphicsConfiguration(awtScreen, capsChosen, capsRequested, awtGfxConfig);
}
- @Override
+ // open access to superclass method
+ public void setChosenCapabilities(CapabilitiesImmutable capsChosen) {
+ super.setChosenCapabilities(capsChosen);
+ }
+
+ @Override
public Object clone() {
return super.clone();
}
- public GraphicsConfiguration getGraphicsConfiguration() {
+ /** Return the AWT {@link GraphicsConfiguration}. */
+ public GraphicsConfiguration getAWTGraphicsConfiguration() {
return config;
}
- @Override
+ @Override
public AbstractGraphicsConfiguration getNativeGraphicsConfiguration() {
return (null!=encapsulated)?encapsulated:this;
}
@@ -156,7 +163,7 @@ public class AWTGraphicsConfiguration extends DefaultGraphicsConfiguration imple
return capabilities;
}
- @Override
+ @Override
public String toString() {
return getClass().getSimpleName()+"[" + getScreen() +
",\n\tchosen " + capabilitiesChosen+
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
index 66a63bfcd..8ebe37626 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsDevice.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 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
@@ -46,26 +47,20 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
/** A wrapper for an AWT GraphicsDevice allowing it to be
handled in a toolkit-independent manner. */
-
public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
private GraphicsDevice device;
- private String subType;
- protected AWTGraphicsDevice(GraphicsDevice device, int unitID) {
+ public AWTGraphicsDevice(GraphicsDevice device, int unitID) {
super(NativeWindowFactory.TYPE_AWT, device.getIDstring(), unitID);
this.device = device;
- this.subType = null;
}
- public static AbstractGraphicsDevice createDevice(GraphicsDevice awtDevice, int unitID) {
- if(null==awtDevice) {
- awtDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
- unitID = AbstractGraphicsDevice.DEFAULT_UNIT;
- }
- return new AWTGraphicsDevice(awtDevice, unitID);
+ public static AWTGraphicsDevice createDefault() {
+ GraphicsDevice awtDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+ return new AWTGraphicsDevice(awtDevice, AbstractGraphicsDevice.DEFAULT_UNIT);
}
- @Override
+ @Override
public Object clone() {
return super.clone();
}
@@ -74,26 +69,9 @@ public class AWTGraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
return device;
}
- /**
- * In case the native handle was specified, e.g. using X11,
- * we shall be able to mark it.<br>
- * This will also set the subType, queried with {@link #getSubType()}
- * and reset the ToolkitLock type with {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}
- * and {@link #setToolkitLock(javax.media.nativewindow.ToolkitLock)}.
- */
- public void setSubType(String subType, long handle) {
- this.handle = handle;
- this.subType = subType;
- setToolkitLock( NativeWindowFactory.createDefaultToolkitLock(subType, handle) );
- }
-
- public String getSubType() {
- return subType;
- }
-
- @Override
+ @Override
public String toString() {
- return getClass().getSimpleName()+"[type "+getType()+"[subType "+getSubType()+"], connection "+getConnection()+", unitID "+getUnitID()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]";
+ return getClass().getSimpleName()+"[type "+getType()+", connection "+getConnection()+", unitID "+getUnitID()+", awtDevice "+device+", handle 0x"+Long.toHexString(getHandle())+"]";
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java
index 383dcae80..2978d7868 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/awt/AWTGraphicsScreen.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2005 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
@@ -42,7 +43,6 @@ package javax.media.nativewindow.awt;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import javax.media.nativewindow.*;
-import javax.media.nativewindow.AbstractGraphicsDevice;
/** A wrapper for an AWT GraphicsDevice (screen) allowing it to be
handled in a toolkit-independent manner. */
@@ -74,17 +74,15 @@ public class AWTGraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
}
public static AbstractGraphicsScreen createScreenDevice(GraphicsDevice awtDevice, int unitID) {
- AWTGraphicsDevice device = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(awtDevice, unitID);
- return new AWTGraphicsScreen(device);
+ return new AWTGraphicsScreen(new AWTGraphicsDevice(awtDevice, unitID));
}
public static AbstractGraphicsScreen createScreenDevice(int index, int unitID) {
- GraphicsDevice awtDevice = getScreenDevice(index);
- return createScreenDevice(awtDevice, unitID);
+ return createScreenDevice(getScreenDevice(index), unitID);
}
public static AbstractGraphicsScreen createDefault() {
- return createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
+ return new AWTGraphicsScreen(AWTGraphicsDevice.createDefault());
}
public Object clone() {
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
index 100b6b839..74439336d 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsConfiguration.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
@@ -32,8 +33,9 @@
package javax.media.nativewindow.x11;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.x11.XVisualInfo;
/** Encapsulates a graphics configuration, or OpenGL pixel format, on
@@ -42,7 +44,7 @@ import jogamp.nativewindow.x11.XVisualInfo;
GraphicsConfigurationFactory.chooseGraphicsConfiguration()} on X11
platforms when toolkits other than the AWT are being used. */
-public class X11GraphicsConfiguration extends DefaultGraphicsConfiguration implements Cloneable {
+public class X11GraphicsConfiguration extends MutableGraphicsConfiguration implements Cloneable {
private XVisualInfo info;
public X11GraphicsConfiguration(X11GraphicsScreen screen,
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
index 48fd63e3c..73c8cfd52 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsDevice.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
@@ -33,6 +34,7 @@
package javax.media.nativewindow.x11;
import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
import javax.media.nativewindow.DefaultGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
@@ -44,49 +46,49 @@ import javax.media.nativewindow.ToolkitLock;
public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneable {
public static final boolean DEBUG = Debug.debug("GraphicsDevice");
- boolean closeDisplay = false;
+ final boolean closeDisplay;
/** Constructs a new X11GraphicsDevice corresponding to the given connection and default
- * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}.<br>
+ * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#getDefaultToolkitLock(String)}.<br>
* Note that this is not an open connection, ie no native display handle exist.
* This constructor exist to setup a default device connection.
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int)
*/
public X11GraphicsDevice(String connection, int unitID) {
super(NativeWindowFactory.TYPE_X11, connection, unitID);
+ closeDisplay = false;
}
/** Constructs a new X11GraphicsDevice corresponding to the given native display handle and default
- * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(java.lang.String, long)}.
+ * {@link javax.media.nativewindow.ToolkitLock} via {@link NativeWindowFactory#createDefaultToolkitLock(String, long)}.
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long)
*/
- public X11GraphicsDevice(long display, int unitID) {
+ public X11GraphicsDevice(long display, int unitID, boolean owner) {
// FIXME: derive unitID from connection could be buggy, one DISPLAY for all screens for example..
- super(NativeWindowFactory.TYPE_X11, X11Util.XDisplayString(display), unitID, display);
+ super(NativeWindowFactory.TYPE_X11, X11Lib.XDisplayString(display), unitID, display);
if(0==display) {
throw new NativeWindowException("null display");
}
+ closeDisplay = owner;
}
/**
* @param display the Display connection
* @param locker custom {@link javax.media.nativewindow.ToolkitLock}, eg to force null locking in NEWT
+ * @see DefaultGraphicsDevice#DefaultGraphicsDevice(String, String, int, long, ToolkitLock)
*/
- public X11GraphicsDevice(long display, int unitID, ToolkitLock locker) {
- super(NativeWindowFactory.TYPE_X11, X11Util.XDisplayString(display), unitID, display, locker);
+ public X11GraphicsDevice(long display, int unitID, ToolkitLock locker, boolean owner) {
+ super(NativeWindowFactory.TYPE_X11, X11Lib.XDisplayString(display), unitID, display, locker);
if(0==display) {
throw new NativeWindowException("null display");
}
+ closeDisplay = owner;
}
public Object clone() {
return super.clone();
}
- public void setCloseDisplay(boolean close) {
- closeDisplay = close;
- if(DEBUG && close) {
- System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.setCloseDisplay(true): "+this);
- }
- }
public boolean close() {
// FIXME: shall we respect the unitID ?
if(closeDisplay && 0 != handle) {
@@ -94,10 +96,8 @@ public class X11GraphicsDevice extends DefaultGraphicsDevice implements Cloneabl
System.err.println(Thread.currentThread().getName() + " - X11GraphicsDevice.close(): "+this);
}
X11Util.closeDisplay(handle);
- handle = 0;
- return true;
}
- return false;
+ return super.close();
}
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
index ffe84cb6d..6473b9f67 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.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
@@ -33,6 +34,8 @@
package javax.media.nativewindow.x11;
import javax.media.nativewindow.*;
+
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.nativewindow.x11.X11Util;
/** Encapsulates a screen index on X11
@@ -48,22 +51,22 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
super(device, fetchScreen(device, screen));
}
- public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx) {
+ public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx, boolean owner) {
if(0==display) throw new NativeWindowException("display is null");
- return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT), screenIdx);
+ return new X11GraphicsScreen(new X11GraphicsDevice(display, AbstractGraphicsDevice.DEFAULT_UNIT, owner), screenIdx);
}
public long getDefaultVisualID() {
// It still could be an AWT hold handle ..
long display = getDevice().getHandle();
- int scrnIdx = X11Util.DefaultScreen(display);
- return X11Util.DefaultVisualID(display, scrnIdx);
+ int scrnIdx = X11Lib.DefaultScreen(display);
+ return X11Lib.DefaultVisualID(display, scrnIdx);
}
private static int fetchScreen(X11GraphicsDevice device, int screen) {
// It still could be an AWT hold handle ..
long display = device.getHandle();
- if(X11Util.XineramaEnabled(display)) {
+ if(X11Lib.XineramaEnabled(display)) {
screen = 0; // Xinerama -> 1 screen
}
return screen;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
new file mode 100644
index 000000000..ee3ab73ba
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/MutableGraphicsConfiguration.java
@@ -0,0 +1,43 @@
+/**
+ * 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.nativewindow;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.DefaultGraphicsConfiguration;
+
+public class MutableGraphicsConfiguration extends DefaultGraphicsConfiguration {
+ public MutableGraphicsConfiguration(AbstractGraphicsScreen screen,
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested) {
+ super(screen, capsChosen, capsRequested);
+ }
+
+ public void setChosenCapabilities(CapabilitiesImmutable caps) {
+ super.setChosenCapabilities(caps);
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
index 2b6d3c016..4cf8f448e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NWJNILibLoader.java
@@ -33,6 +33,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import com.jogamp.common.jvm.JNILibLoaderBase;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.cache.TempJarCache;
public class NWJNILibLoader extends JNILibLoaderBase {
@@ -40,9 +41,10 @@ public class NWJNILibLoader extends JNILibLoaderBase {
public static void loadNativeWindow(final String ossuffix) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
+ Platform.initSingleton();
final String libName = "nativewindow_"+ossuffix ;
if(TempJarCache.isInitialized() && null == TempJarCache.findLibrary(libName)) {
- addNativeJarLibs(NWJNILibLoader.class, "jogl.all", "jogl-all", new String[] { "nativewindow" } );
+ addNativeJarLibs(NWJNILibLoader.class, "jogl-all", new String[] { "nativewindow" } );
}
loadLibrary(libName, false);
return null;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
index d34d4e58f..223078ebf 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/NativeWindowFactoryImpl.java
@@ -32,11 +32,15 @@
package jogamp.nativewindow;
-import com.jogamp.common.os.Platform;
-import com.jogamp.common.util.*;
-import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
-import javax.media.nativewindow.*;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.ReflectionUtil;
public class NativeWindowFactoryImpl extends NativeWindowFactory {
private static final ToolkitLock nullToolkitLock = new NullToolkitLock();
@@ -44,13 +48,10 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
public static ToolkitLock getNullToolkitLock() {
return nullToolkitLock;
}
-
+
// This subclass of NativeWindowFactory handles the case of
// NativeWindows being passed in
protected NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config) throws IllegalArgumentException {
- if (null == winObj) {
- throw new IllegalArgumentException("winObj is null");
- }
if (winObj instanceof NativeWindow) {
// Use the NativeWindow directly
return (NativeWindow) winObj;
@@ -69,7 +70,7 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory {
"javax.media.nativewindow.NativeWindow or "+AWTComponentClassName);
}
- private Constructor nativeWindowConstructor = null;
+ private Constructor<?> nativeWindowConstructor = null;
private NativeWindow getAWTNativeWindow(Object winObj, AbstractGraphicsConfiguration config) {
if (nativeWindowConstructor == null) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
new file mode 100644
index 000000000..4877d5c4f
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceUpdatedHelper.java
@@ -0,0 +1,85 @@
+/**
+ * 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;
+
+import java.util.ArrayList;
+
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+
+public class SurfaceUpdatedHelper implements SurfaceUpdatedListener {
+ private Object surfaceUpdatedListenersLock = new Object();
+ private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
+
+ //
+ // Management Utils
+ //
+ public int size() { return surfaceUpdatedListeners.size(); }
+ public SurfaceUpdatedListener get(int i) { return surfaceUpdatedListeners.get(i); }
+
+ //
+ // Implementation of NativeSurface SurfaceUpdatedListener methods
+ //
+
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ addSurfaceUpdatedListener(-1, l);
+ }
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
+ throws IndexOutOfBoundsException
+ {
+ if(l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ if(0>index) {
+ index = surfaceUpdatedListeners.size();
+ }
+ surfaceUpdatedListeners.add(index, l);
+ }
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ if (l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners.remove(l);
+ }
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ synchronized(surfaceUpdatedListenersLock) {
+ for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ SurfaceUpdatedListener l = surfaceUpdatedListeners.get(i);
+ l.surfaceUpdated(updater, ns, when);
+ }
+ }
+ }
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
index 4c2b1c875..074fab563 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java
@@ -33,7 +33,7 @@ import javax.media.nativewindow.ProxySurface;
import javax.media.nativewindow.SurfaceChangeable;
-public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
+public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
protected long surfaceHandle;
public WrappedSurface(AbstractGraphicsConfiguration cfg) {
@@ -65,6 +65,10 @@ public class WrappedSurface extends ProxySurface implements SurfaceChangeable {
}
public String toString() {
- return "WrappedSurface[config " + config + ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) + ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) + ", size " + getWidth() + "x" + getHeight() + "]";
+ return "WrappedSurface[config " + getPrivateGraphicsConfiguration()+
+ ", displayHandle 0x" + Long.toHexString(getDisplayHandle()) +
+ ", surfaceHandle 0x" + Long.toHexString(getSurfaceHandle()) +
+ ", size " + getWidth() + "x" + getHeight() +
+ ", surfaceLock "+surfaceLock+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
index 2c8538278..354bb83e3 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTJNILibLoader.java
@@ -40,14 +40,15 @@
package jogamp.nativewindow.jawt;
import javax.media.nativewindow.NativeWindowFactory;
+
import jogamp.nativewindow.NWJNILibLoader;
import java.awt.Toolkit;
import java.security.AccessController;
import java.security.PrivilegedAction;
-public class JAWTJNILibLoader extends NWJNILibLoader {
- public static void loadAWTImpl() {
+public class JAWTJNILibLoader extends NWJNILibLoader {
+ static {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
// Make sure that awt.dll is loaded before loading jawt.dll. Otherwise
@@ -73,4 +74,9 @@ public class JAWTJNILibLoader extends NWJNILibLoader {
}
});
}
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
index c1c97eece..21e9a3e09 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java
@@ -37,24 +37,28 @@
package jogamp.nativewindow.jawt;
-import jogamp.nativewindow.*;
import java.awt.EventQueue;
-
-import javax.media.nativewindow.*;
-
-
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
-import java.lang.reflect.*;
-import java.security.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Map;
+import javax.media.nativewindow.NativeWindowException;
+
+import jogamp.nativewindow.Debug;
+
+import com.jogamp.common.os.Platform;
+
public class JAWTUtil {
protected static final boolean DEBUG = Debug.debug("JAWT");
// See whether we're running in headless mode
private static final boolean headlessMode;
+ private static final JAWT jawtLockObject;
// Java2D magic ..
private static final Method isQueueFlusherThread;
@@ -75,31 +79,67 @@ public class JAWTUtil {
boolean ok;
}
+ /**
+ * Returns true if this platform's JAWT implementation supports
+ * or uses offscreen layer.
+ */
+ public static boolean isOffscreenLayerSupported() {
+ return Platform.OS_TYPE == Platform.OSType.MACOS &&
+ Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0;
+ }
+
+ /**
+ * @param useOffscreenLayerIfAvailable
+ * @return
+ */
+ public static JAWT getJAWT(boolean useOffscreenLayerIfAvailable) {
+ int jawt_version_flags = JAWTFactory.JAWT_VERSION_1_4;
+ if(useOffscreenLayerIfAvailable) {
+ switch(Platform.OS_TYPE) {
+ case MACOS:
+ if(Platform.OS_VERSION_NUMBER.compareTo(JAWT.JAWT_MacOSXCALayerMinVersion) >= 0) {
+ jawt_version_flags |= JAWT.JAWT_MACOSX_USE_CALAYER;
+ }
+ }
+ }
+ return JAWT.getJAWT(jawt_version_flags);
+ }
+
+ public static boolean isJAWTUsingOffscreenLayer(JAWT jawt) {
+ return 0 != ( jawt.getCachedVersion() & JAWT.JAWT_MACOSX_USE_CALAYER );
+ }
+
static {
- JAWTJNILibLoader.loadAWTImpl();
+ if(DEBUG) {
+ System.err.println("JAWTUtil initialization (JAWT/JNI/...");
+ // Thread.dumpStack();
+ }
+ JAWTJNILibLoader.initSingleton();
JAWTJNILibLoader.loadNativeWindow("awt");
headlessMode = GraphicsEnvironment.isHeadless();
-
boolean ok = false;
- Class jC = null;
+ Class<?> jC = null;
Method m = null;
if (!headlessMode) {
+ jawtLockObject = getJAWT(false); // don't care for offscreen layer here
try {
jC = Class.forName("jogamp.opengl.awt.Java2D");
m = jC.getMethod("isQueueFlusherThread", (Class[])null);
ok = true;
} catch (Exception e) {
}
+ } else {
+ jawtLockObject = null; // headless !
}
isQueueFlusherThread = m;
j2dExist = ok;
- PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction() {
+ PrivilegedDataBlob1 pdb1 = (PrivilegedDataBlob1) AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
PrivilegedDataBlob1 d = new PrivilegedDataBlob1();
try {
- final Class sunToolkitClass = Class.forName("sun.awt.SunToolkit");
+ final Class<?> sunToolkitClass = Class.forName("sun.awt.SunToolkit");
d.sunToolkitAWTLockMethod = sunToolkitClass.getDeclaredMethod("awtLock", new Class[]{});
d.sunToolkitAWTLockMethod.setAccessible(true);
d.sunToolkitAWTUnlockMethod = sunToolkitClass.getDeclaredMethod("awtUnlock", new Class[]{});
@@ -129,21 +169,21 @@ public class JAWTUtil {
jawtToolkitLock = new JAWTToolkitLock();
// trigger native AWT toolkit / properties initialization
- Map desktophints = null;
+ Map<?,?> desktophints = null;
try {
if(EventQueue.isDispatchThread()) {
- desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
} else {
- final ArrayList desktophintsBucket = new ArrayList(1);
+ final ArrayList<Map<?,?>> desktophintsBucket = new ArrayList<Map<?,?>>(1);
EventQueue.invokeAndWait(new Runnable() {
public void run() {
- Map _desktophints = (Map)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
+ Map<?,?> _desktophints = (Map<?,?>)(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints"));
if(null!=_desktophints) {
desktophintsBucket.add(_desktophints);
}
}
});
- desktophints = ( desktophintsBucket.size() > 0 ) ? (Map)desktophintsBucket.get(0) : null ;
+ desktophints = ( desktophintsBucket.size() > 0 ) ? desktophintsBucket.get(0) : null ;
}
} catch (InterruptedException ex) {
ex.printStackTrace();
@@ -189,7 +229,7 @@ public class JAWTUtil {
* JAWT's native Lock() function calls SunToolkit.awtLock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtLock() {
+ private static void awtLock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTLockMethod.invoke(null, (Object[])null);
@@ -197,7 +237,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtLock failed", e);
}
} else {
- JAWT.getJAWT().Lock();
+ jawtLockObject.Lock();
}
}
@@ -207,7 +247,7 @@ public class JAWTUtil {
* JAWT's native Unlock() function calls SunToolkit.awtUnlock(),
* which just uses AWT's global ReentrantLock.<br>
*/
- public static void awtUnlock() {
+ private static void awtUnlock() {
if(hasSunToolkitAWTLock) {
try {
sunToolkitAWTUnlockMethod.invoke(null, (Object[])null);
@@ -215,7 +255,7 @@ public class JAWTUtil {
throw new NativeWindowException("SunToolkit.awtUnlock failed", e);
}
} else {
- JAWT.getJAWT().Unlock();
+ jawtLockObject.Unlock();
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
index 2c80392ad..be697b3e0 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTWindow.java
@@ -41,73 +41,190 @@ import com.jogamp.common.util.locks.LockFactory;
import com.jogamp.common.util.locks.RecursiveLock;
import java.awt.Component;
-import java.awt.Window;
+import java.awt.Container;
+import java.applet.Applet;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.OffscreenLayerOption;
+import javax.media.nativewindow.OffscreenLayerSurface;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
import javax.media.nativewindow.util.RectangleImmutable;
-public abstract class JAWTWindow implements NativeWindow {
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
+public abstract class JAWTWindow implements NativeWindow, OffscreenLayerSurface, OffscreenLayerOption {
protected static final boolean DEBUG = JAWTUtil.DEBUG;
+ // user properties
+ protected boolean shallUseOffscreenLayer = false;
+
// lifetime: forever
protected Component component;
- protected AbstractGraphicsConfiguration config;
+ private AWTGraphicsConfiguration config; // control access due to delegation
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
- // lifetime: valid after lock, forever until invalidate
+ // lifetime: valid after lock but may change with each 1st lock, purges after invalidate
+ private boolean isApplet;
+ private JAWT jawt;
+ private boolean isOffscreenLayerSurface;
protected long drawable;
protected Rectangle bounds;
-
- public JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
+ protected Insets insets;
+
+ /**
+ * Constructed by {@link jogamp.nativewindow.NativeWindowFactoryImpl#getNativeWindow(Object, AbstractGraphicsConfiguration)}
+ * via this platform's specialization (X11, OSX, Windows, ..).
+ *
+ * @param comp
+ * @param config
+ */
+ protected JAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
if (config == null) {
throw new NativeWindowException("Error: AbstractGraphicsConfiguration is null");
}
- this.config = config;
+ if(! ( config instanceof AWTGraphicsConfiguration ) ) {
+ throw new NativeWindowException("Error: AbstractGraphicsConfiguration is not an AWTGraphicsConfiguration: "+config);
+ }
+ this.config = (AWTGraphicsConfiguration) config;
init((Component)comp);
}
private void init(Component windowObject) throws NativeWindowException {
invalidate();
this.component = windowObject;
- validateNative();
+ this.isApplet = false;
}
- protected abstract void validateNative() throws NativeWindowException;
-
+
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return isOffscreenLayerSurface;
+ }
+
protected synchronized void invalidate() {
- component = null;
+ invalidateNative();
+ jawt = null;
+ isOffscreenLayerSurface = false;
drawable= 0;
bounds = new Rectangle();
+ insets = new Insets();
}
+ protected abstract void invalidateNative();
protected final void updateBounds(JAWT_Rectangle jawtBounds) {
bounds.setX(jawtBounds.getX());
bounds.setY(jawtBounds.getY());
bounds.setWidth(jawtBounds.getWidth());
bounds.setHeight(jawtBounds.getHeight());
+
+ if(component instanceof Container) {
+ java.awt.Insets contInsets = ((Container)component).getInsets();
+ insets.setLeftWidth(contInsets.left);
+ insets.setRightWidth(contInsets.right);
+ insets.setTopHeight(contInsets.top);
+ insets.setBottomHeight(contInsets.bottom);
+ }
}
/** @return the JAWT_DrawingSurfaceInfo's (JAWT_Rectangle) bounds, updated with lock */
public final RectangleImmutable getBounds() { return bounds; }
- public final InsetsImmutable getInsets() { return Insets.getZero(); }
+ public final InsetsImmutable getInsets() { return insets; }
public final Component getAWTComponent() {
return component;
}
+
+ /**
+ * Returns true if the AWT component is parented to an {@link java.applet.Applet},
+ * otherwise false. This information is valid only after {@link #lockSurface()}.
+ */
+ public final boolean isApplet() {
+ return isApplet;
+ }
+ /** Returns the underlying JAWT instance created @ {@link #lockSurface()}. */
+ public final JAWT getJAWT() {
+ return jawt;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void attachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new NativeWindowException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.attachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ attachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void attachSurfaceLayerImpl(final long layerHandle);
+
+ /**
+ * {@inheritDoc}
+ */
+ public final void detachSurfaceLayer(final long layerHandle) throws NativeWindowException {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not an offscreen layer surface");
+ }
+ int lockRes = lockSurface();
+ if (NativeSurface.LOCK_SURFACE_NOT_READY >= lockRes) {
+ throw new NativeWindowException("Could not lock (offscreen layer): "+this);
+ }
+ try {
+ if(DEBUG) {
+ System.err.println("JAWTWindow.detachSurfaceHandle(): 0x"+Long.toHexString(layerHandle));
+ }
+ detachSurfaceLayerImpl(layerHandle);
+ } finally {
+ unlockSurface();
+ }
+ }
+ protected abstract void detachSurfaceLayerImpl(final long layerHandle);
+
//
// SurfaceUpdateListener
//
- public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- // nop
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
+ }
//
// NativeSurface
@@ -115,6 +232,24 @@ public abstract class JAWTWindow implements NativeWindow {
private RecursiveLock surfaceLock = LockFactory.createRecursiveLock();
+ private void determineIfApplet() {
+ Component c = component;
+ while(!isApplet && null != c) {
+ isApplet = c instanceof Applet;
+ c = c.getParent();
+ }
+ }
+
+ /**
+ * If JAWT offscreen layer is supported,
+ * implementation shall respect {@link #getShallUseOffscreenLayer()}
+ * and may respect {@link #isApplet()}.
+ *
+ * @return The JAWT instance reflecting offscreen layer support, etc.
+ *
+ * @throws NativeWindowException
+ */
+ protected abstract JAWT fetchJAWTImpl() throws NativeWindowException;
protected abstract int lockSurfaceImpl() throws NativeWindowException;
public final int lockSurface() throws NativeWindowException {
@@ -122,10 +257,13 @@ public abstract class JAWTWindow implements NativeWindow {
int res = surfaceLock.getHoldCount() == 1 ? LOCK_SURFACE_NOT_READY : LOCK_SUCCESS; // new lock ?
if ( LOCK_SURFACE_NOT_READY == res ) {
+ determineIfApplet();
try {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
adevice.lock();
try {
+ jawt = fetchJAWTImpl();
+ isOffscreenLayerSurface = JAWTUtil.isJAWTUsingOffscreenLayer(jawt);
res = lockSurfaceImpl();
} finally {
if (LOCK_SURFACE_NOT_READY >= res) {
@@ -147,7 +285,7 @@ public abstract class JAWTWindow implements NativeWindow {
surfaceLock.validateLocked();
if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
} finally {
@@ -169,36 +307,35 @@ public abstract class JAWTWindow implements NativeWindow {
return surfaceLock.getOwner();
}
- public final boolean surfaceSwap() {
+ public boolean surfaceSwap() {
return false;
}
- public final void surfaceUpdated(Object updater, NativeWindow window, long when) { }
-
- public final long getSurfaceHandle() {
+ public long getSurfaceHandle() {
return drawable;
}
- public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+
+ public final AWTGraphicsConfiguration getPrivateGraphicsConfiguration() {
return config;
}
+
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
+ }
public final long getDisplayHandle() {
- return config.getScreen().getDevice().getHandle();
+ return getGraphicsConfiguration().getScreen().getDevice().getHandle();
}
public final int getScreenIndex() {
- return config.getScreen().getIndex();
- }
-
- public final void setSize(int width, int height) {
- component.setSize(width, height);
+ return getGraphicsConfiguration().getScreen().getIndex();
}
- public final int getWidth() {
+ public int getWidth() {
return component.getWidth();
}
- public final int getHeight() {
+ public int getHeight() {
return component.getHeight();
}
@@ -207,12 +344,8 @@ public abstract class JAWTWindow implements NativeWindow {
//
public synchronized void destroy() {
- if(null!=component) {
- if(component instanceof Window) {
- ((Window)component).dispose();
- }
- }
- invalidate();
+ invalidate();
+ component = null; // don't dispose the AWT component, since we are merely an immutable uplink
}
public final NativeWindow getParent() {
@@ -222,7 +355,7 @@ public abstract class JAWTWindow implements NativeWindow {
public long getWindowHandle() {
return drawable;
}
-
+
public final int getX() {
return component.getX();
}
@@ -230,52 +363,94 @@ public abstract class JAWTWindow implements NativeWindow {
public final int getY() {
return component.getY();
}
-
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This JAWT default implementation is currently still using
+ * a blocking implementation. It first attempts to retrieve the location
+ * via a native implementation. If this fails, it tries the blocking AWT implementation.
+ * If the latter fails due to an external AWT tree-lock, the non block
+ * implementation {@link #getLocationOnScreenNonBlocking(Point, Component)} is being used.
+ * The latter simply traverse up to the AWT component tree and sums the rel. position.
+ * We have to determine whether the latter is good enough for all cases,
+ * currently only OS X utilizes the non blocking method per default.
+ * </p>
+ */
public Point getLocationOnScreen(Point storage) {
+ Point los = getLocationOnScreenNative(storage);
+ if(null == los) {
+ if(!Thread.holdsLock(component.getTreeLock())) {
+ // avoid deadlock ..
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock: "+this);
+ Thread.dumpStack();
+ }
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ java.awt.Point awtLOS = component.getLocationOnScreen();
+ if(null!=storage) {
+ los = storage.translate(awtLOS.x, awtLOS.y);
+ } else {
+ los = new Point(awtLOS.x, awtLOS.y);
+ }
+ }
+ return los;
+ }
+
+ protected Point getLocationOnScreenNative(Point storage) {
int lockRes = lockSurface();
if(LOCK_SURFACE_NOT_READY == lockRes) {
- // FIXME: Shall we deal with already locked or unrealized surfaces ?
- System.err.println("Warning: JAWT Lock couldn't be acquired!");
- Thread.dumpStack();
+ if(DEBUG) {
+ System.err.println("Warning: JAWT Lock couldn't be acquired: "+this);
+ Thread.dumpStack();
+ }
return null;
}
try {
- Point d = getLocationOnScreenImpl(0, 0);
+ Point d = getLocationOnScreenNativeImpl(0, 0);
if(null!=d) {
if(null!=storage) {
storage.translate(d.getX(),d.getY());
return storage;
}
- return d;
- }
- // fall through intended ..
- if(!Thread.holdsLock(component.getTreeLock())) {
- // FIXME: Verify if this check is still required!
- System.err.println("Warning: JAWT Lock hold, but not the AWT tree lock!");
- Thread.dumpStack();
- return null; // avoid deadlock ..
}
- java.awt.Point awtLOS = component.getLocationOnScreen();
- int dx = (int) ( awtLOS.getX() + .5 ) ;
- int dy = (int) ( awtLOS.getY() + .5 ) ;
- if(null!=storage) {
- return storage.translate(dx, dy);
- }
- return new Point(dx, dy);
+ return d;
} finally {
unlockSurface();
+ }
+ }
+ protected abstract Point getLocationOnScreenNativeImpl(int x, int y);
+
+ protected static Point getLocationOnScreenNonBlocking(Point storage, Component comp) {
+ int x = 0;
+ int y = 0;
+ while(null != comp) {
+ x += comp.getX();
+ y += comp.getY();
+ comp = comp.getParent();
}
+ if(null!=storage) {
+ storage.translate(x, y);
+ return storage;
+ }
+ return new Point(x, y);
}
- protected abstract Point getLocationOnScreenImpl(int x, int y);
-
- @Override
+
+ public boolean hasFocus() {
+ return component.hasFocus();
+ }
+
+ @Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("JAWT-Window["+
"windowHandle 0x"+Long.toHexString(getWindowHandle())+
", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", bounds "+bounds);
+ ", bounds "+bounds+", insets "+insets+
+ ", shallUseOffscreenLayer "+shallUseOffscreenLayer+", isOffscreenLayerSurface "+isOffscreenLayerSurface);
if(null!=component) {
sb.append(", pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
", visible "+component.isVisible());
@@ -283,8 +458,9 @@ public abstract class JAWTWindow implements NativeWindow {
sb.append(", component NULL");
}
sb.append(", lockedExt "+isSurfaceLockedByOtherThread()+
- ",\n\tconfig "+config+
- ",\n\tawtComponent "+getAWTComponent()+"]");
+ ",\n\tconfig "+getPrivateGraphicsConfiguration()+
+ ",\n\tawtComponent "+getAWTComponent()+
+ ",\n\tsurfaceLock "+surfaceLock+"]");
return sb.toString();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
index d4f6a95d4..ab2986fbe 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java
@@ -40,38 +40,94 @@
package jogamp.nativewindow.jawt.macosx;
-import java.awt.Component;
+import java.nio.Buffer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.Capabilities;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.SurfaceChangeable;
import javax.media.nativewindow.util.Point;
+import jogamp.nativewindow.MutableGraphicsConfiguration;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
-// import jogamp.nativewindow.macosx.OSXUtil;
-
-public class MacOSXJAWTWindow extends JAWTWindow {
+import jogamp.nativewindow.macosx.OSXUtil;
+public class MacOSXJAWTWindow extends JAWTWindow implements SurfaceChangeable {
public MacOSXJAWTWindow(Object comp, AbstractGraphicsConfiguration config) {
super(comp, config);
+ if(DEBUG) {
+ dumpInfo();
+ }
}
- protected void validateNative() throws NativeWindowException {
+ protected void invalidateNative() {
+ surfaceHandle=0;
+ if(isOffscreenLayerSurfaceEnabled()) {
+ if(0 != drawable) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ }
+ }
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.AddCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ OSXUtil.RemoveCASublayer(rootSurfaceLayerHandle, layerHandle);
+ }
+
+ public long getSurfaceHandle() {
+ return isOffscreenLayerSurfaceEnabled() ? surfaceHandle : super.getSurfaceHandle() ;
+ }
+
+ public void setSurfaceHandle(long surfaceHandle) {
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ throw new java.lang.UnsupportedOperationException("Not using CALAYER");
+ }
+ if(DEBUG) {
+ System.err.println("MacOSXJAWTWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
+ }
+ sscSet &= 0 != surfaceHandle; // reset ssc flag if NULL surfaceHandle, ie. back to JAWT
+ this.surfaceHandle = surfaceHandle;
+ }
+
+ public void surfaceSizeChanged(int width, int height) {
+ sscSet = true;
+ sscWidth = width;
+ sscHeight = height;
+ }
+
+ public int getWidth() {
+ return sscSet ? sscWidth : super.getWidth();
+ }
+
+ public int getHeight() {
+ return sscSet ? sscHeight: super.getHeight();
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ // use offscreen if supported and [ applet or requested ]
+ return JAWTUtil.getJAWT(getShallUseOffscreenLayer() || isApplet());
+ }
protected int lockSurfaceImpl() throws NativeWindowException {
- int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
- if (ds == null) {
- // Widget not yet realized
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ int ret = NativeWindow.LOCK_SURFACE_NOT_READY;
+ if(null == ds) {
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
int res = ds.Lock();
dsLocked = ( 0 == ( res & JAWTFactory.JAWT_LOCK_ERROR ) ) ;
@@ -87,37 +143,86 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
ret = NativeWindow.LOCK_SURFACE_CHANGED;
}
- if (firstLock) {
- AccessController.doPrivileged(new PrivilegedAction<Object>() {
- public Object run() {
- dsi = ds.GetDrawingSurfaceInfo();
- return null;
- }
- });
- } else {
- dsi = ds.GetDrawingSurfaceInfo();
+ if(null == dsi) {
+ if (firstLock) {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
+ public Object run() {
+ dsi = ds.GetDrawingSurfaceInfo();
+ return null;
+ }
+ });
+ } else {
+ dsi = ds.GetDrawingSurfaceInfo();
+ }
+ if (dsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
}
- if (dsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ updateBounds(dsi.getBounds());
+ if (DEBUG && firstLock ) {
+ dumpInfo();
}
firstLock = false;
- macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo();
- if (macosxdsi == null) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
- }
- drawable = macosxdsi.getCocoaViewRef();
-
- if (drawable == 0) {
- unlockSurfaceImpl();
- return NativeWindow.LOCK_SURFACE_NOT_READY;
+ if( !isOffscreenLayerSurfaceEnabled() ) {
+ macosxdsi = (JAWT_MacOSXDrawingSurfaceInfo) dsi.platformInfo(getJAWT());
+ if (macosxdsi == null) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ }
+ drawable = macosxdsi.getCocoaViewRef();
+
+ if (drawable == 0) {
+ unlockSurfaceImpl();
+ return NativeWindow.LOCK_SURFACE_NOT_READY;
+ } else {
+ ret = NativeWindow.LOCK_SUCCESS;
+ }
} else {
- updateBounds(dsi.getBounds());
+ /**
+ * Only create a fake invisible NSWindow for the drawable handle
+ * to please frameworks requiring such (eg. NEWT).
+ *
+ * The actual surface/ca-layer shall be created/attached
+ * by the upper framework (JOGL) since they require more information.
+ */
+ if(0 == drawable) {
+ drawable = OSXUtil.CreateNSWindow(0, 0, getBounds().getWidth(), getBounds().getHeight());
+ if(0 == drawable) {
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Unable to created dummy NSWindow (layered case)");
+ }
+ // fix caps reflecting offscreen!
+ Capabilities caps = (Capabilities) getPrivateGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ getPrivateGraphicsConfiguration().setChosenCapabilities(caps);
+ caps = (Capabilities) getGraphicsConfiguration().getChosenCapabilities().cloneMutable();
+ caps.setOnscreen(false);
+ ((MutableGraphicsConfiguration)getGraphicsConfiguration()).setChosenCapabilities(caps);
+ }
+ if(0 == rootSurfaceLayerHandle) {
+ rootSurfaceLayerHandle = OSXUtil.CreateCALayer();
+ if(0 == rootSurfaceLayerHandle) {
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not create root CALayer: "+this);
+ }
+ if(!AttachJAWTSurfaceLayer(dsi, rootSurfaceLayerHandle)) {
+ OSXUtil.DestroyCALayer(rootSurfaceLayerHandle);
+ rootSurfaceLayerHandle = 0;
+ OSXUtil.DestroyNSWindow(drawable);
+ drawable = 0;
+ unlockSurfaceImpl();
+ throw new NativeWindowException("Could not attach JAWT surfaceLayerHandle: "+this);
+ }
+ }
+ ret = NativeWindow.LOCK_SUCCESS;
}
+
return ret;
}
-
+
protected void unlockSurfaceImpl() throws NativeWindowException {
if(null!=ds) {
if (null!=dsi) {
@@ -126,30 +231,65 @@ public class MacOSXJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
- macosxdsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- Component c = component;
- while(null != c) {
- x += c.getX();
- y += c.getY();
- c = c.getParent();
+ private void dumpInfo() {
+ System.err.println("MaxOSXJAWTWindow: 0x"+Integer.toHexString(this.hashCode())+" - thread: "+Thread.currentThread().getName());
+ if(null != getJAWT()) {
+ System.err.println("JAWT version: 0x"+Integer.toHexString(getJAWT().getCachedVersion())+
+ ", CA_LAYER: "+ JAWTUtil.isJAWTUsingOffscreenLayer(getJAWT())+
+ ", isLayeredSurface "+isOffscreenLayerSurfaceEnabled()+", bounds "+bounds+", insets "+insets);
+ } else {
+ System.err.println("JAWT n/a, bounds "+bounds+", insets "+insets);
}
- // return OSXUtil.GetLocationOnScreen(getWindowHandle(), x, y);
- return new Point(x, y);
+ // Thread.dumpStack();
}
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * On OS X locking the surface at this point (ie after creation and for location validation)
+ * is 'tricky' since the JVM traverses through many threads and crashes at:
+ * lockSurfaceImpl() {
+ * ..
+ * ds = getJAWT().GetDrawingSurface(component);
+ * due to a SIGSEGV.
+ *
+ * Hence we have some threading / sync issues with the native JAWT implementation.
+ * </p>
+ */
+ @Override
+ public Point getLocationOnScreen(Point storage) {
+ return getLocationOnScreenNonBlocking(storage, component);
+ }
+ protected Point getLocationOnScreenNativeImpl(final int x0, final int y0) { return null; }
+ private static boolean AttachJAWTSurfaceLayer(JAWT_DrawingSurfaceInfo dsi, long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ return AttachJAWTSurfaceLayer0(dsi.getBuffer(), caLayer);
+ }
+
+ private static native boolean AttachJAWTSurfaceLayer0(Buffer jawtDrawingSurfaceInfoBuffer, long caLayer);
+
// Variables for lockSurface/unlockSurface
private JAWT_DrawingSurface ds;
private boolean dsLocked;
private JAWT_DrawingSurfaceInfo dsi;
+
private JAWT_MacOSXDrawingSurfaceInfo macosxdsi;
-
+
+ private long rootSurfaceLayerHandle = 0; // is autoreleased, once it is attached to the JAWT_SurfaceLayer
+
+ private long surfaceHandle = 0;
+ private int sscWidth, sscHeight;
+ private boolean sscSet = false;
+
// Workaround for instance of 4796548
private boolean firstLock = true;
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
index 5ad22807f..bf5c18eaf 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/Win32SunJDKReflection.java
@@ -95,7 +95,7 @@ public class Win32SunJDKReflection {
public static int graphicsConfigurationGetPixelFormatID(AbstractGraphicsConfiguration config) {
try {
if (config instanceof AWTGraphicsConfiguration) {
- return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration());
+ return graphicsConfigurationGetPixelFormatID(((AWTGraphicsConfiguration) config).getAWTGraphicsConfiguration());
}
return 0;
} catch (Exception e) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
index 982b94888..786682b17 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/windows/WindowsJAWTWindow.java
@@ -47,10 +47,11 @@ import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
-import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
public class WindowsJAWTWindow extends JAWTWindow {
@@ -58,18 +59,24 @@ public class WindowsJAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void validateNative() throws NativeWindowException {
- }
-
- @Override
- protected synchronized void invalidate() {
- super.invalidate();
+ protected void invalidateNative() {
windowHandle = 0;
}
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -94,7 +101,8 @@ public class WindowsJAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ win32dsi = (JAWT_Win32DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (win32dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -104,14 +112,12 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (windowHandle == 0 || drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
protected void unlockSurfaceImpl() throws NativeWindowException {
- long startTime = 0;
+ drawable = 0; // invalid HDC
if(null!=ds) {
if (null!=dsi) {
ds.FreeDrawingSurfaceInfo(dsi);
@@ -119,7 +125,7 @@ public class WindowsJAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
@@ -131,8 +137,8 @@ public class WindowsJAWTWindow extends JAWTWindow {
return windowHandle;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
+ return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
index 5d4fa0dad..743d371b7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTToolkitLock.java
@@ -28,9 +28,13 @@
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)}.
@@ -41,20 +45,32 @@ import javax.media.nativewindow.ToolkitLock;
*/
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()"); }
+ if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.lock() - native: "+(null==lock)); }
JAWTUtil.lockToolkit();
- X11Util.XLockDisplay(displayHandle);
+ if(null == lock) {
+ X11Lib.XLockDisplay(displayHandle);
+ } else {
+ lock.lock();
+ }
}
public final void unlock() {
- if(TRACE_LOCK) { System.err.println("X11JAWTToolkitLock.unlock()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ 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 2319d6269..35dc2343f 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11JAWTWindow.java
@@ -38,20 +38,17 @@
package jogamp.nativewindow.jawt.x11;
import javax.media.nativewindow.AbstractGraphicsConfiguration;
-import javax.media.nativewindow.AbstractGraphicsDevice;
-import javax.media.nativewindow.AbstractGraphicsScreen;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
-import javax.media.nativewindow.NativeWindowFactory;
-import javax.media.nativewindow.awt.AWTGraphicsDevice;
import javax.media.nativewindow.util.Point;
import jogamp.nativewindow.jawt.JAWT;
import jogamp.nativewindow.jawt.JAWTFactory;
+import jogamp.nativewindow.jawt.JAWTUtil;
import jogamp.nativewindow.jawt.JAWTWindow;
import jogamp.nativewindow.jawt.JAWT_DrawingSurface;
import jogamp.nativewindow.jawt.JAWT_DrawingSurfaceInfo;
-import jogamp.nativewindow.x11.X11Util;
+import jogamp.nativewindow.x11.X11Lib;
public class X11JAWTWindow extends JAWTWindow {
@@ -59,36 +56,22 @@ public class X11JAWTWindow extends JAWTWindow {
super(comp, config);
}
- protected void validateNative() throws NativeWindowException {
- AWTGraphicsDevice awtDevice = (AWTGraphicsDevice) config.getScreen().getDevice();
+ protected void invalidateNative() { }
- if(awtDevice.getHandle() != 0) {
- // subtype and handle set already, done
- return;
- }
-
- long displayHandle = 0;
-
- // first try a pre-existing attached native configuration, ie native X11GraphicsDevice
- AbstractGraphicsConfiguration aconfig = (null!=config) ? config.getNativeGraphicsConfiguration() : null;
- AbstractGraphicsScreen ascreen = (null!=aconfig) ? aconfig.getScreen() : null;
- AbstractGraphicsDevice adevice = (null!=ascreen) ? ascreen.getDevice() : null; // X11GraphicsDevice
- if(null!=adevice) {
- displayHandle = adevice.getHandle();
- }
-
- if(0 == displayHandle) {
- displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(awtDevice.getGraphicsDevice());
- }
- if(0==displayHandle) {
- throw new InternalError("X11JAWTWindow: No X11 Display handle available");
- }
- awtDevice.setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
+ protected void attachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
}
-
+ protected void detachSurfaceLayerImpl(final long layerHandle) {
+ throw new UnsupportedOperationException("offscreen layer not supported");
+ }
+
+ protected JAWT fetchJAWTImpl() throws NativeWindowException {
+ return JAWTUtil.getJAWT(false); // no offscreen
+ }
+
protected int lockSurfaceImpl() throws NativeWindowException {
int ret = NativeWindow.LOCK_SUCCESS;
- ds = JAWT.getJAWT().GetDrawingSurface(component);
+ ds = getJAWT().GetDrawingSurface(component);
if (ds == null) {
// Widget not yet realized
unlockSurfaceImpl();
@@ -113,7 +96,8 @@ public class X11JAWTWindow extends JAWTWindow {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
}
- x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ updateBounds(dsi.getBounds());
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo(getJAWT());
if (x11dsi == null) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
@@ -122,8 +106,6 @@ public class X11JAWTWindow extends JAWTWindow {
if (drawable == 0) {
unlockSurfaceImpl();
return LOCK_SURFACE_NOT_READY;
- } else {
- updateBounds(dsi.getBounds());
}
return ret;
}
@@ -136,15 +118,15 @@ public class X11JAWTWindow extends JAWTWindow {
if (dsLocked) {
ds.Unlock();
}
- JAWT.getJAWT().FreeDrawingSurface(ds);
+ getJAWT().FreeDrawingSurface(ds);
}
ds = null;
dsi = null;
x11dsi = null;
}
- protected Point getLocationOnScreenImpl(int x, int y) {
- return X11Util.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ protected Point getLocationOnScreenNativeImpl(int x, int y) {
+ return X11Lib.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
// Variables for lockSurface/unlockSurface
diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
index b576b0c6b..08d471448 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/x11/X11SunJDKReflection.java
@@ -55,14 +55,14 @@ import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
the purposes of correctly enumerating the available visuals. */
public class X11SunJDKReflection {
- private static Class x11GraphicsDeviceClass;
- private static Method x11GraphicsDeviceGetDisplayMethod;
- private static Class x11GraphicsConfigClass;
- private static Method x11GraphicsConfigGetVisualMethod;
- private static boolean initted;
+ private static Class<?> x11GraphicsDeviceClass;
+ private static Method x11GraphicsDeviceGetDisplayMethod;
+ private static Class<?> x11GraphicsConfigClass;
+ private static Method x11GraphicsConfigGetVisualMethod;
+ private static boolean initialized;
static {
- AccessController.doPrivileged(new PrivilegedAction() {
+ AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
try {
x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice");
@@ -72,7 +72,7 @@ public class X11SunJDKReflection {
x11GraphicsConfigClass = Class.forName("sun.awt.X11GraphicsConfig");
x11GraphicsConfigGetVisualMethod = x11GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {});
x11GraphicsConfigGetVisualMethod.setAccessible(true);
- initted = true;
+ initialized = true;
} catch (Exception e) {
// Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
}
@@ -82,7 +82,7 @@ public class X11SunJDKReflection {
}
public static long graphicsDeviceGetDisplay(GraphicsDevice device) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
@@ -96,7 +96,7 @@ public class X11SunJDKReflection {
public static int graphicsConfigurationGetVisualID(AbstractGraphicsConfiguration config) {
try {
if (config instanceof AWTGraphicsConfiguration) {
- return graphicsConfigurationGetVisualID(((AWTGraphicsConfiguration) config).getGraphicsConfiguration());
+ return graphicsConfigurationGetVisualID(((AWTGraphicsConfiguration) config).getAWTGraphicsConfiguration());
}
return 0;
} catch (Exception e) {
@@ -105,7 +105,7 @@ public class X11SunJDKReflection {
}
public static int graphicsConfigurationGetVisualID(GraphicsConfiguration config) {
- if (!initted) {
+ if (!initialized) {
return 0;
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
index cd558c05d..5b1e4b0a7 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.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.nativewindow.macosx;
import javax.media.nativewindow.NativeWindowException;
@@ -34,6 +61,42 @@ public class OSXUtil {
return (Point) GetLocationOnScreen0(windowOrView, src_x, src_y);
}
+ public static long CreateNSView(int x, int y, int width, int height) {
+ return CreateNSView0(x, y, width, height);
+ }
+ public static void DestroyNSView(long nsView) {
+ DestroyNSView0(nsView);
+ }
+
+ public static long CreateNSWindow(int x, int y, int width, int height) {
+ return CreateNSWindow0(x, y, width, height);
+ }
+ public static void DestroyNSWindow(long nsWindow) {
+ DestroyNSWindow0(nsWindow);
+ }
+
+ public static long CreateCALayer() {
+ return CreateCALayer0();
+ }
+ public static void AddCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ AddCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void RemoveCASublayer(long rootCALayer, long subCALayer) {
+ if(0==rootCALayer || 0==subCALayer) {
+ throw new IllegalArgumentException("rootCALayer 0x"+Long.toHexString(rootCALayer)+", subCALayer 0x"+Long.toHexString(subCALayer));
+ }
+ RemoveCASublayer0(rootCALayer, subCALayer);
+ }
+ public static void DestroyCALayer(long caLayer) {
+ if(0==caLayer) {
+ throw new IllegalArgumentException("caLayer 0x"+Long.toHexString(caLayer));
+ }
+ DestroyCALayer0(caLayer);
+ }
+
public static void RunOnMainThread(boolean waitUntilDone, Runnable runnable) {
if(IsMainThread0()) {
runnable.run(); // don't leave the JVM
@@ -48,6 +111,14 @@ public class OSXUtil {
private static native boolean initIDs0();
private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y);
+ private static native long CreateNSView0(int x, int y, int width, int height);
+ private static native void DestroyNSView0(long nsView);
+ private static native long CreateNSWindow0(int x, int y, int width, int height);
+ private static native void DestroyNSWindow0(long nsWindow);
+ private static native long CreateCALayer0();
+ private static native void AddCASublayer0(long rootCALayer, long subCALayer);
+ private static native void RemoveCASublayer0(long rootCALayer, long subCALayer);
+ private static native void DestroyCALayer0(long caLayer);
private static native void RunOnMainThread0(boolean waitUntilDone, Runnable runnable);
private static native boolean IsMainThread0();
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
index 1ad909897..aab1556da 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/swt/SWTAccessor.java
@@ -202,7 +202,9 @@ 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);
+ // FIXME: May think about creating a private non-shared X11 Display handle, like we use to for AWT
+ // to avoid locking problems !
+ return new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
if( NativeWindowFactory.TYPE_WINDOWS == NativeWindowFactory.getNativeWindowType(false) ) {
return new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
index 68cf8af45..c8ed8e070 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDISurface.java
@@ -61,14 +61,22 @@ public class GDISurface extends ProxySurface {
throw new InternalError("surface not released");
}
surfaceHandle = GDI.GetDC(windowHandle);
+ /*
+ if(0 == surfaceHandle) {
+ System.err.println("****** DC Acquire: 0x"+Long.toHexString(windowHandle)+", isWindow "+GDI.IsWindow(windowHandle)+", isVisible "+GDI.IsWindowVisible(windowHandle)+", GDI LastError: "+GDI.GetLastError()+", 0x"+Long.toHexString(surfaceHandle)+", GDI LastError: "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
+ Thread.dumpStack();
+ }
+ */
return (0 != surfaceHandle) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
}
protected void unlockSurfaceImpl() {
if (0 == surfaceHandle) {
- throw new InternalError("surface not acquired");
+ throw new InternalError("surface not acquired: "+this+", thread: "+Thread.currentThread().getName());
+ }
+ if(0 == GDI.ReleaseDC(windowHandle, surfaceHandle)) {
+ throw new NativeWindowException("DC not released: "+this+", isWindow "+GDI.IsWindow(windowHandle)+", werr "+GDI.GetLastError()+", thread: "+Thread.currentThread().getName());
}
- GDI.ReleaseDC(windowHandle, surfaceHandle);
surfaceHandle=0;
}
@@ -77,11 +85,12 @@ public class GDISurface extends ProxySurface {
}
public String toString() {
- return "GDISurface[config "+config+
+ return "GDISurface[config "+getPrivateGraphicsConfiguration()+
", displayHandle 0x"+Long.toHexString(getDisplayHandle())+
", windowHandle 0x"+Long.toHexString(windowHandle)+
", surfaceHandle 0x"+Long.toHexString(getSurfaceHandle())+
- ", size "+getWidth()+"x"+getHeight()+"]";
+ ", size "+getWidth()+"x"+getHeight()+
+ ", surfaceLock "+surfaceLock+"]";
}
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
new file mode 100644
index 000000000..be531d9ee
--- /dev/null
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/GDIUtil.java
@@ -0,0 +1,101 @@
+/**
+ * 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.nativewindow.windows;
+
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.NativeWindowException;
+
+import jogamp.nativewindow.NWJNILibLoader;
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.x11.X11Util;
+
+public class GDIUtil {
+ private static final boolean DEBUG = Debug.debug("GDIUtil");
+
+ private static final String dummyWindowClassNameBase = "_dummyWindow_clazz" ;
+ private static RegisteredClassFactory dummyWindowClassFactory;
+ private static boolean isInit = false;
+
+ public static synchronized void initSingleton(boolean firstX11ActionOnProcess) {
+ if(!isInit) {
+ synchronized(X11Util.class) {
+ if(!isInit) {
+ isInit = true;
+ NWJNILibLoader.loadNativeWindow("win32");
+
+ if( !initIDs0() ) {
+ throw new NativeWindowException("GDI: Could not initialized native stub");
+ }
+
+ if(DEBUG) {
+ System.out.println("GDI.isFirstX11ActionOnProcess: "+firstX11ActionOnProcess);
+ }
+
+ dummyWindowClassFactory = new RegisteredClassFactory(dummyWindowClassNameBase, getDummyWndProc0());
+ }
+ }
+ }
+ }
+
+ public static boolean requiresToolkitLock() { return false; }
+
+ private static RegisteredClass dummyWindowClass = null;
+ private static Object dummyWindowSync = new Object();
+
+ public static long CreateDummyWindow(int x, int y, int width, int height) {
+ synchronized(dummyWindowSync) {
+ dummyWindowClass = dummyWindowClassFactory.getSharedClass();
+ return CreateDummyWindow0(dummyWindowClass.getHandle(), dummyWindowClass.getName(), dummyWindowClass.getName(), x, y, width, height);
+ }
+ }
+
+ public static boolean DestroyDummyWindow(long hwnd) {
+ boolean res;
+ synchronized(dummyWindowSync) {
+ if( null == dummyWindowClass ) {
+ throw new InternalError("GDI Error ("+dummyWindowClassFactory.getSharedRefCount()+"): SharedClass is null");
+ }
+ res = GDI.DestroyWindow(hwnd);
+ dummyWindowClassFactory.releaseSharedClass();
+ }
+ return res;
+ }
+
+ public static Point GetRelativeLocation(long src_win, long dest_win, int src_x, int src_y) {
+ return (Point) GetRelativeLocation0(src_win, dest_win, src_x, src_y);
+ }
+
+ public static native boolean CreateWindowClass(long hInstance, String clazzName, long wndProc);
+ public static native boolean DestroyWindowClass(long hInstance, String className);
+
+ private static native boolean initIDs0();
+ private static native long getDummyWndProc0();
+ private static native Object GetRelativeLocation0(long src_win, long dest_win, int src_x, int src_y);
+
+ static native long CreateDummyWindow0(long hInstance, String className, String windowName, int x, int y, int width, int height);
+}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
index 15e0a67cb..00bedfc8e 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/windows/RegisteredClassFactory.java
@@ -34,34 +34,44 @@ import javax.media.nativewindow.NativeWindowException;
public class RegisteredClassFactory {
static final boolean DEBUG = Debug.debug("RegisteredClass");
- private static ArrayList sharedClasses = new ArrayList();
+ private static ArrayList<RegisteredClassFactory> registeredFactories = new ArrayList<RegisteredClassFactory>();
+
private String classBaseName;
- long wndProc;
+ private long wndProc;
private RegisteredClass sharedClass = null;
private int classIter = 0;
private int sharedRefCount = 0;
- private Object sync = new Object();
+ private final Object sync = new Object();
/**
- * Intended for a JVM shutdown hook, hence little synchronization
+ * Release the {@link RegisteredClass} of all {@link RegisteredClassFactory}.
*/
public static void shutdownSharedClasses() {
- synchronized(sharedClasses) {
- for(int i=0; i<sharedClasses.size(); i++) {
- RegisteredClass sc = (RegisteredClass) sharedClasses.get(i);
- GDI.DestroyWindowClass(sc.getHandle(), sc.getName());
- if(DEBUG) {
- System.err.println("RegisteredClassFactory shutdownSharedClasses "+i+"/"+sharedClasses.size()+": "+sc);
+ synchronized(registeredFactories) {
+ for(int j=0; j<registeredFactories.size(); j++) {
+ final RegisteredClassFactory rcf = registeredFactories.get(j);
+ synchronized(rcf.sync) {
+ if(null != rcf.sharedClass) {
+ GDIUtil.DestroyWindowClass(rcf.sharedClass.getHandle(), rcf.sharedClass.getName());
+ rcf.sharedClass = null;
+ rcf.sharedRefCount = 0;
+ rcf.classIter = 0;
+ if(DEBUG) {
+ System.err.println("RegisteredClassFactory #"+j+"/"+registeredFactories.size()+" shutdownSharedClasses : "+rcf.sharedClass);
+ }
+ }
}
}
- sharedClasses.clear();
}
}
public RegisteredClassFactory(String classBaseName, long wndProc) {
this.classBaseName = classBaseName;
this.wndProc = wndProc;
+ synchronized(registeredFactories) {
+ registeredFactories.add(this);
+ }
}
public RegisteredClass getSharedClass() throws NativeWindowException {
@@ -76,19 +86,17 @@ public class RegisteredClassFactory {
}
String clazzName = null;
boolean registered = false;
- while ( !registered && Integer.MAX_VALUE >= classIter ) {
+ final int classIterMark = classIter - 1;
+ while ( !registered && classIterMark != classIter ) {
// Retry with next clazz name, this could happen if more than one JVM is running
clazzName = classBaseName + classIter;
classIter++;
- registered = GDI.CreateWindowClass(hInstance, clazzName, wndProc);
+ registered = GDIUtil.CreateWindowClass(hInstance, clazzName, wndProc);
}
if( !registered ) {
throw new NativeWindowException("Error: Could not create WindowClass: "+clazzName);
}
sharedClass = new RegisteredClass(hInstance, clazzName);
- synchronized(sharedClasses) {
- sharedClasses.add(sharedClass);
- }
if(DEBUG) {
System.err.println("RegisteredClassFactory getSharedClass ("+sharedRefCount+") initialized: "+sharedClass);
}
@@ -113,10 +121,7 @@ public class RegisteredClassFactory {
throw new InternalError("Error ("+sharedRefCount+"): SharedClass is null");
}
if( 0 == sharedRefCount ) {
- GDI.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName());
- synchronized(sharedClasses) {
- sharedClasses.remove(sharedClass);
- }
+ GDIUtil.DestroyWindowClass(sharedClass.getHandle(), sharedClass.getName());
if(DEBUG) {
System.err.println("RegisteredClassFactory releaseSharedClass ("+sharedRefCount+") released: "+sharedClass);
}
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
index b669bce75..268416266 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11GraphicsConfigurationFactory.java
@@ -33,10 +33,22 @@
package jogamp.nativewindow.x11;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, new X11GraphicsConfigurationFactory());
+ }
+ private X11GraphicsConfigurationFactory() {
+ }
+
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested, CapabilitiesChooser chooser, AbstractGraphicsScreen screen)
throws IllegalArgumentException, NativeWindowException {
@@ -55,7 +67,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
int num[] = { -1 };
long display = screen.getDevice().getHandle();
- XVisualInfo[] xvis = X11Util.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
+ XVisualInfo[] xvis = X11Lib.XGetVisualInfo(display, X11Lib.VisualIDMask|X11Lib.VisualScreenMask, xvi_temp, num, 0);
if(xvis==null || num[0]<1) {
return null;
@@ -81,7 +93,7 @@ public class X11GraphicsConfigurationFactory extends GraphicsConfigurationFactor
vinfo_template.setC_class(c_class);
long display = screen.getDevice().getHandle();
- XVisualInfo[] vinfos = X11Util.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0);
+ XVisualInfo[] vinfos = X11Lib.XGetVisualInfo(display, X11Lib.VisualScreenMask, vinfo_template, num, 0);
XVisualInfo best=null;
int rdepth = capabilities.getRedBits() + capabilities.getGreenBits() + capabilities.getBlueBits() + capabilities.getAlphaBits();
for (int i = 0; vinfos!=null && i < num[0]; i++) {
diff --git a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
index fb0aff10d..5166ef577 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11ToolkitLock.java
@@ -29,6 +29,9 @@ 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)}.
@@ -38,18 +41,30 @@ import javax.media.nativewindow.ToolkitLock;
*/
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()"); }
- X11Util.XLockDisplay(displayHandle);
+ 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()"); }
- X11Util.XUnlockDisplay(displayHandle);
+ 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 5c1839250..560130dd1 100644
--- a/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/X11Util.java
@@ -33,19 +33,18 @@
package jogamp.nativewindow.x11;
-import com.jogamp.common.util.LongObjectHashMap;
-import jogamp.nativewindow.Debug;
-import jogamp.nativewindow.NWJNILibLoader;
-
-import javax.media.nativewindow.*;
-
-import java.nio.Buffer;
-import java.nio.IntBuffer;
-import java.nio.ShortBuffer;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.List;
-import javax.media.nativewindow.util.Point;
+
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+
+import jogamp.nativewindow.Debug;
+import jogamp.nativewindow.NWJNILibLoader;
+
+import com.jogamp.common.util.LongObjectHashMap;
/**
* Contains a thread safe X11 utility to retrieve display connections.
@@ -53,54 +52,88 @@ import javax.media.nativewindow.util.Point;
public class X11Util {
/**
* See Bug 515 - https://jogamp.org/bugzilla/show_bug.cgi?id=515
- *
- * It is observed that ATI X11 drivers, eg. fglrx 8.78.6 and fglrx 11.08/8.881,
+ * <p>
+ * It is observed that ATI X11 drivers, eg.
+ * <ul>
+ * <li>fglrx 8.78.6,</li>
+ * <li>fglrx 11.08/8.881 and </li>
+ * <li>fglrx 11.11/8.911</li>
+ * </ul>
* are quite sensitive to multiple Display connections.
- * Here, closing displays shall happen in the same order as
- * they were opened, -OR- shall not be closed at all!
- * Otherwise some driver related bug appears and brings down the JVM.
+ * </p>
+ * <p>
+ * With the above drivers closing displays shall happen in the same order as
+ * they were opened, <b>or</b> shall not be closed at all!
+ * If closed, some driver related bug appears and brings down the JVM.
+ * </p>
+ * <p>
* You may test this, ie just reverse the destroy order below.
* See also native test: jogl/test/native/displayMultiple02.c
- *
- * Our current 'workaround' is to not close them at all if driver vendor is ATI.
+ * </p>
+ * <p>
+ * Workaround is to not close them at all if driver vendor is ATI.
+ * </p>
*/
public static final boolean ATI_HAS_XCLOSEDISPLAY_BUG = true;
-
- public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
+ /** Value is <code>true</code>, best 'stable' results if always using XInitThreads(). */
+ public static final boolean XINITTHREADS_ALWAYS_ENABLED = true;
+
+ /** Value is <code>true</code>, best 'stable' results if not using XLockDisplay/XUnlockDisplay at all. */
+ public static final boolean HAS_XLOCKDISPLAY_BUG = true;
+
private static final boolean DEBUG = Debug.debug("X11Util");
private static final boolean TRACE_DISPLAY_LIFECYCLE = Debug.getBooleanProperty("nativewindow.debug.X11Util.TraceDisplayLifecycle", true, AccessController.getContext());
- private static volatile String nullDisplayName = null;
- private static boolean requiresX11Lock = false;
- private static boolean isInit = false;
+ 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();
- public static synchronized void initSingleton(final boolean firstX11ActionOnProcess) {
+ @SuppressWarnings("unused")
+ public static void initSingleton(final boolean firstX11ActionOnProcess) {
if(!isInit) {
- NWJNILibLoader.loadNativeWindow("x11");
-
- /**
- * Always issue XInitThreads() since we have independent
- * off-thread created Display connections able to utilize multithreading,
- * ie NEWT (jogamp.newt.x11.X11Display.createNativeImpl()) !!
- */
- initialize0( XINITTHREADS_ALWAYS_ENABLED ? true : firstX11ActionOnProcess );
-
- requiresX11Lock = !firstX11ActionOnProcess ;
-
- if(DEBUG) {
- System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
- ", XINITTHREADS_ALWAYS_ENABLED "+XINITTHREADS_ALWAYS_ENABLED+
- ", requiresX11Lock "+requiresX11Lock);
+ synchronized(X11Util.class) {
+ if(!isInit) {
+ isInit = true;
+ NWJNILibLoader.loadNativeWindow("x11");
+
+ final boolean callXInitThreads = XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess;
+ final boolean isXInitThreadsOK = initialize0( XINITTHREADS_ALWAYS_ENABLED || firstX11ActionOnProcess );
+ isX11LockAvailable = isXInitThreadsOK && !HAS_XLOCKDISPLAY_BUG ;
+
+ final long dpy = X11Lib.XOpenDisplay(null);
+ try {
+ nullDisplayName = X11Lib.XDisplayString(dpy);
+ } finally {
+ X11Lib.XCloseDisplay(dpy);
+ }
+
+ if(DEBUG) {
+ System.err.println("X11Util firstX11ActionOnProcess: "+firstX11ActionOnProcess+
+ ", requiresX11Lock "+requiresX11Lock+
+ ", XInitThreads [called "+callXInitThreads+", OK "+isXInitThreadsOK+"]"+
+ ", isX11LockAvailable "+isX11LockAvailable+
+ ", X11 Display(NULL) <"+nullDisplayName+">");
+ // Thread.dumpStack();
+ }
+ }
}
- isInit = true;
}
}
+
+ public static synchronized boolean isNativeLockAvailable() {
+ return isX11LockAvailable;
+ }
+
+ public static synchronized boolean requiresToolkitLock() {
+ return requiresX11Lock;
+ }
public static void setX11ErrorHandler(boolean onoff, boolean quiet) {
synchronized(setX11ErrorHandlerLock) {
@@ -121,42 +154,7 @@ public class X11Util {
}
}
- public static boolean requiresToolkitLock() {
- return requiresX11Lock;
- }
-
- public static void lockDefaultToolkit(long dpyHandle) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- if(requiresX11Lock) {
- X11Util.XLockDisplay(dpyHandle);
- }
- }
-
- public static void unlockDefaultToolkit(long dpyHandle) {
- if(requiresX11Lock) {
- X11Util.XUnlockDisplay(dpyHandle);
- }
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
-
public static String getNullDisplayName() {
- if(null==nullDisplayName) { // volatile: ok
- synchronized(X11Util.class) {
- if(null==nullDisplayName) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- long dpy = X11Lib.XOpenDisplay(null);
- try {
- nullDisplayName = X11Lib.XDisplayString(dpy);
- } finally {
- X11Lib.XCloseDisplay(dpy);
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
- if(DEBUG) {
- System.out.println("X11 Display(NULL) <"+nullDisplayName+">");
- }
- }
- }
- }
return nullDisplayName;
}
@@ -224,7 +222,6 @@ public class X11Util {
public final void setUncloseable(boolean v) { unCloseable = v; }
public final boolean isUncloseable() { return unCloseable; }
-
public final Throwable getCreationStack() { return creationStack; }
@Override
@@ -238,20 +235,22 @@ public class X11Util {
}
}
- /** Returns the number of unclosed X11 Displays.
+ /**
+ * Cleanup resources.
+ * If <code>realXCloseOpenAndPendingDisplays</code> is <code>false</code>,
+ * keep alive all references (open display connection) for restart on same ClassLoader.
+ *
+ * @return number of unclosed X11 Displays.<br>
* @param realXCloseOpenAndPendingDisplays if true, {@link #closePendingDisplayConnections()} is called.
- */
+ */
public static int shutdown(boolean realXCloseOpenAndPendingDisplays, boolean verbose) {
int num=0;
if(DEBUG||verbose||pendingDisplayList.size() > 0) {
- String msg = "X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
- ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
- ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")" ;
+ System.err.println("X11Util.Display: Shutdown (close open / pending Displays: "+realXCloseOpenAndPendingDisplays+
+ ", open (no close attempt): "+openDisplayMap.size()+"/"+openDisplayList.size()+
+ ", pending (not closed, marked uncloseable): "+pendingDisplayList.size()+")");
if(DEBUG) {
- Exception e = new Exception(msg);
- e.printStackTrace();
- } else {
- System.err.println(msg);
+ Thread.dumpStack();
}
if( openDisplayList.size() > 0) {
X11Util.dumpOpenDisplayConnections();
@@ -264,10 +263,11 @@ public class X11Util {
synchronized(globalLock) {
if(realXCloseOpenAndPendingDisplays) {
closePendingDisplayConnections();
+ openDisplayList.clear();
+ pendingDisplayList.clear();
+ openDisplayMap.clear();
+ shutdown0();
}
- openDisplayList.clear();
- pendingDisplayList.clear();
- openDisplayMap.clear();
}
return num;
}
@@ -304,9 +304,9 @@ public class X11Util {
public static void dumpOpenDisplayConnections() {
synchronized(globalLock) {
System.err.println("X11Util: Open X11 Display Connections: "+openDisplayList.size());
- for(int i=0; i<pendingDisplayList.size(); i++) {
+ for(int i=0; i<openDisplayList.size(); i++) {
NamedDisplay ndpy = openDisplayList.get(i);
- System.err.println("X11Util: ["+i+"]: "+ndpy);
+ System.err.println("X11Util: Open["+i+"]: "+ndpy);
if(null!=ndpy) {
Throwable t = ndpy.getCreationStack();
if(null!=t) {
@@ -316,7 +316,7 @@ public class X11Util {
}
}
}
-
+
public static int getPendingDisplayConnectionNumber() {
synchronized(globalLock) {
return pendingDisplayList.size();
@@ -328,7 +328,7 @@ public class X11Util {
System.err.println("X11Util: Pending X11 Display Connections: "+pendingDisplayList.size());
for(int i=0; i<pendingDisplayList.size(); i++) {
NamedDisplay ndpy = (NamedDisplay) pendingDisplayList.get(i);
- System.err.println("X11Util: ["+i+"]: "+ndpy);
+ System.err.println("X11Util: Pending["+i+"]: "+ndpy);
if(null!=ndpy) {
Throwable t = ndpy.getCreationStack();
if(null!=t) {
@@ -384,8 +384,8 @@ public class X11Util {
}
}
if(DEBUG) {
- Exception e = new Exception("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
- e.printStackTrace();
+ System.err.println("X11Util.Display: openDisplay [reuse "+reused+"] "+namedDpy+". Thread "+Thread.currentThread().getName());
+ // Thread.dumpStack();
}
return namedDpy.getHandle();
}
@@ -408,10 +408,6 @@ public class X11Util {
if(!openDisplayList.remove(namedDpy)) { throw new RuntimeException("Internal: "+namedDpy); }
if(!namedDpy.isUncloseable()) {
- if(DEBUG) {
- System.err.println("X11Util.Display: XCloseDisplay "+namedDpy+". Thread "+Thread.currentThread().getName());
- Thread.dumpStack();
- }
XCloseDisplay(namedDpy.getHandle());
} else {
// for reuse
@@ -439,7 +435,7 @@ public class X11Util {
public static String validateDisplayName(String name, long handle) {
if( ( null==name || AbstractGraphicsDevice.DEFAULT_CONNECTION.equals(name) ) && 0!=handle) {
- name = XDisplayString(handle);
+ name = X11Lib.XDisplayString(handle);
}
return validateDisplayName(name);
}
@@ -455,8 +451,8 @@ public class X11Util {
try {
long handle = X11Lib.XOpenDisplay(arg0);
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XOpenDisplay("+arg0+") 0x"+Long.toHexString(handle));
+ // Thread.dumpStack();
}
return handle;
} finally {
@@ -468,8 +464,8 @@ public class X11Util {
NativeWindowFactory.getDefaultToolkitLock().lock();
try {
if(TRACE_DISPLAY_LIFECYCLE) {
- Throwable t = new Throwable(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
- t.printStackTrace();
+ System.err.println(Thread.currentThread()+" - X11Util.XCloseDisplay() 0x"+Long.toHexString(display));
+ // Thread.dumpStack();
}
int res = -1;
X11Util.setX11ErrorHandler(true, DEBUG ? false : true);
@@ -487,209 +483,7 @@ public class X11Util {
}
}
- public static int XFree(Buffer arg0) {
- NativeWindowFactory.getDefaultToolkitLock().lock();
- try {
- return X11Lib.XFree(arg0);
- } finally {
- NativeWindowFactory.getDefaultToolkitLock().unlock();
- }
- }
-
- public static int XSync(long display, boolean discard) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XSync(display, discard);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void XSynchronize(long display, boolean onoff) {
- lockDefaultToolkit(display);
- try {
- X11Lib.XSynchronize(display, onoff);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XineramaEnabled(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XineramaEnabled(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int DefaultScreen(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.DefaultScreen(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long RootWindow(long display, int screen_number) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.RootWindow(display, screen_number);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long XCreatePixmap(long display, long arg1, int arg2, int arg3, int arg4) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XCreatePixmap(display, arg1, arg2, arg3, arg4);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static String XDisplayString(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XDisplayString(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int XFlush(long display) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XFlush(display);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static int XFreePixmap(long display, long arg1) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XFreePixmap(display, arg1);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long DefaultVisualID(long display, int screen) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.DefaultVisualID(display, screen);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static long CreateDummyWindow(long display, int screen_index, long visualID, int width, int height) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.CreateDummyWindow(display, screen_index, visualID, width, height);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void DestroyDummyWindow(long display, long window) {
- lockDefaultToolkit(display);
- try {
- X11Lib.DestroyDummyWindow(display, window);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static Point GetRelativeLocation(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.GetRelativeLocation(display, screen_index, src_win, dest_win, src_x, src_y);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static XVisualInfo[] XGetVisualInfo(long display, long arg1, XVisualInfo arg2, int[] arg3, int arg3_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XGetVisualInfo(display, arg1, arg2, arg3, arg3_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, green_array, blue_array);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRampSize(long display, int screen, IntBuffer size) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeGetGammaRampSize(long display, int screen, int[] size, int size_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeGetGammaRampSize(display, screen, size, size_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, ShortBuffer red_array, ShortBuffer green_array, ShortBuffer blue_array) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, green_array, blue_array);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static boolean XF86VidModeSetGammaRamp(long display, int screen, int size, short[] red_array, int red_array_offset, short[] green_array, int green_array_offset, short[] blue_array, int blue_array_offset) {
- lockDefaultToolkit(display);
- try {
- return X11Lib.XF86VidModeSetGammaRamp(display, screen, size, red_array, red_array_offset, green_array, green_array_offset, blue_array, blue_array_offset);
- } finally {
- unlockDefaultToolkit(display);
- }
- }
-
- public static void XLockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("+++ X11 Display Lock get 0x"+Long.toHexString(handle));
- }
- X11Lib.XLockDisplay(handle);
- }
-
- public static void XUnlockDisplay(long handle) {
- if(ToolkitLock.TRACE_LOCK) {
- System.out.println("--- X11 Display Lock rel 0x"+Long.toHexString(handle));
- }
- X11Lib.XUnlockDisplay(handle);
- }
-
- private static native void initialize0(boolean firstUIActionOnProcess);
+ private static native boolean initialize0(boolean firstUIActionOnProcess);
+ private static native void shutdown0();
private static native void setX11ErrorHandler0(boolean onoff, boolean quiet);
}
diff --git a/src/jogl/classes/jogamp/opengl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
index 9ee20d8ea..efaf4728c 100644
--- a/src/jogl/classes/jogamp/opengl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
+++ b/src/nativewindow/classes/jogamp/nativewindow/x11/awt/X11AWTGraphicsConfigurationFactory.java
@@ -31,65 +31,69 @@
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
-package jogamp.opengl.x11.glx.awt;
+package jogamp.nativewindow.x11.awt;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
-import javax.media.nativewindow.awt.*;
-import javax.media.opengl.*;
-import jogamp.opengl.*;
-import jogamp.nativewindow.jawt.x11.*;
-import jogamp.nativewindow.x11.*;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.ToolkitLock;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
+import javax.media.nativewindow.awt.AWTGraphicsDevice;
+import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.x11.X11GraphicsConfiguration;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
+import javax.media.nativewindow.x11.X11GraphicsScreen;
-public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurationFactory {
- protected static final boolean DEBUG = Debug.debug("GraphicsConfiguration");
+import jogamp.nativewindow.jawt.x11.X11SunJDKReflection;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
- public X11AWTGLXGraphicsConfigurationFactory() {
- GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, this);
+public class X11AWTGraphicsConfigurationFactory extends GraphicsConfigurationFactory {
+
+ public static void registerFactory() {
+ GraphicsConfigurationFactory.registerFactory(javax.media.nativewindow.awt.AWTGraphicsDevice.class, new X11AWTGraphicsConfigurationFactory());
+ }
+ private X11AWTGraphicsConfigurationFactory() {
}
protected AbstractGraphicsConfiguration chooseGraphicsConfigurationImpl(
CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
- CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
- GraphicsDevice device = null;
+ CapabilitiesChooser chooser, AbstractGraphicsScreen absScreen) {
if (absScreen != null &&
!(absScreen instanceof AWTGraphicsScreen)) {
throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only AWTGraphicsScreen objects");
}
-
if(null==absScreen) {
- absScreen = AWTGraphicsScreen.createScreenDevice(-1, AbstractGraphicsDevice.DEFAULT_UNIT);
- }
- AWTGraphicsScreen awtScreen = (AWTGraphicsScreen) absScreen;
- device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
-
- if ( !(capsChosen instanceof GLCapabilitiesImmutable) ) {
- throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects - chosen");
- }
-
- if ( !(capsRequested instanceof GLCapabilitiesImmutable) ) {
- throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilities objects - requested");
- }
-
- if (chooser != null &&
- !(chooser instanceof GLCapabilitiesChooser)) {
- throw new IllegalArgumentException("This GraphicsConfigurationFactory accepts only GLCapabilitiesChooser objects");
+ absScreen = AWTGraphicsScreen.createDefault();
}
+ return chooseGraphicsConfigurationStatic(capsChosen, capsRequested, chooser, (AWTGraphicsScreen)absScreen);
+ }
+
+ public static AWTGraphicsConfiguration chooseGraphicsConfigurationStatic(
+ CapabilitiesImmutable capsChosen, CapabilitiesImmutable capsRequested,
+ CapabilitiesChooser chooser, AWTGraphicsScreen awtScreen) {
if(DEBUG) {
- System.err.println("X11AWTGLXGraphicsConfigurationFactory: got "+absScreen);
+ System.err.println("X11AWTGraphicsConfigurationFactory: got "+awtScreen);
}
+ final GraphicsDevice device = ((AWTGraphicsDevice)awtScreen.getDevice()).getGraphicsDevice();
+
long displayHandle = X11SunJDKReflection.graphicsDeviceGetDisplay(device);
boolean owner = false;
if(0==displayHandle) {
displayHandle = X11Util.openDisplay(null);
owner = true;
if(DEBUG) {
- System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: create local X11 display");
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGraphicsConfigurationFactory: create local X11 display");
}
} else {
/**
@@ -98,23 +102,31 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurati
* some work, but some behave erratic.
* I.e. hangs in XQueryExtension(..) via X11GraphicsScreen.
*/
- final String displayName = X11Util.XDisplayString(displayHandle);
+ final String displayName = X11Lib.XDisplayString(displayHandle);
if(DEBUG) {
- System.err.println(Thread.currentThread().getName() + " - X11AWTGLXGraphicsConfigurationFactory: create X11 display @ "+displayName+" / 0x"+Long.toHexString(displayHandle));
+ System.err.println(Thread.currentThread().getName() + " - X11AWTGraphicsConfigurationFactory: create X11 display @ "+displayName+" / 0x"+Long.toHexString(displayHandle));
}
displayHandle = X11Util.openDisplay(displayName);
owner = true;
}
- ((AWTGraphicsDevice)awtScreen.getDevice()).setSubType(NativeWindowFactory.TYPE_X11, displayHandle);
- X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT);
- x11Device.setCloseDisplay(owner);
- X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
+ 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);
+ final X11GraphicsDevice x11Device = new X11GraphicsDevice(displayHandle, AbstractGraphicsDevice.DEFAULT_UNIT, lock, owner);
+ final X11GraphicsScreen x11Screen = new X11GraphicsScreen(x11Device, awtScreen.getIndex());
if(DEBUG) {
- System.err.println("X11AWTGLXGraphicsConfigurationFactory: made "+x11Screen);
+ System.err.println("X11AWTGraphicsConfigurationFactory: made "+x11Screen);
}
- GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(x11Device);
- GraphicsConfiguration[] configs = device.getConfigurations();
-
+
+ final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(x11Device);
+ X11GraphicsConfiguration x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
+ if (x11Config == null) {
+ throw new NativeWindowException("Unable to choose a GraphicsConfiguration (1): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
+ }
+ if(DEBUG) {
+ System.err.println("X11AWTGraphicsConfigurationFactory: chosen x11Config: "+x11Config);
+ }
+
//
// Match the X11/GL Visual with AWT:
// - choose a config AWT agnostic and then
@@ -122,11 +134,8 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurati
//
// The resulting GraphicsConfiguration has to be 'forced' on the AWT native peer,
// ie. returned by GLCanvas's getGraphicsConfiguration() befor call by super.addNotify().
- //
- X11GraphicsConfiguration x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
- if (x11Config == null) {
- throw new GLException("Unable to choose a GraphicsConfiguration (1): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
- }
+ //
+ final GraphicsConfiguration[] configs = device.getConfigurations();
long visualID = x11Config.getVisualID();
for (int i = 0; i < configs.length; i++) {
GraphicsConfiguration gc = configs[i];
@@ -147,7 +156,7 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurati
capsChosen = AWTGraphicsConfiguration.setupCapabilitiesRGBABits(capsChosen, gc);
x11Config = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(capsChosen, capsRequested, chooser, x11Screen);
if (x11Config == null) {
- throw new GLException("Unable to choose a GraphicsConfiguration (2): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
+ throw new NativeWindowException("Unable to choose a GraphicsConfiguration (2): "+capsChosen+",\n\t"+chooser+"\n\t"+x11Screen);
}
visualID = x11Config.getVisualID();
for (int i = 0; i < configs.length; i++) {
@@ -173,3 +182,4 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GLGraphicsConfigurati
return new AWTGraphicsConfiguration(awtScreen, x11Config.getChosenCapabilities(), x11Config.getRequestedCapabilities(), gc, x11Config);
}
}
+
diff --git a/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c b/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c
index 470f03a49..2a6651007 100644
--- a/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c
+++ b/src/nativewindow/native/JAWT_DrawingSurfaceInfo.c
@@ -59,6 +59,13 @@ Java_jogamp_nativewindow_jawt_JAWT_1DrawingSurfaceInfo_platformInfo0(JNIEnv* env
return NULL;
}
if (dsi->platformInfo == NULL) {
+ (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"),
+ "platformInfo pointer is NULL");
+ return NULL;
+ }
+ if(0==PLATFORM_DSI_SIZE) {
+ (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"),
+ "platformInfo size is 0");
return NULL;
}
return (*env)->NewDirectByteBuffer(env, dsi->platformInfo, PLATFORM_DSI_SIZE);
diff --git a/src/nativewindow/native/macosx/OSXmisc.m b/src/nativewindow/native/macosx/OSXmisc.m
index e19d5ecf7..d64973b67 100644
--- a/src/nativewindow/native/macosx/OSXmisc.m
+++ b/src/nativewindow/native/macosx/OSXmisc.m
@@ -35,6 +35,19 @@
#include "NativewindowCommon.h"
#include "jogamp_nativewindow_macosx_OSXUtil.h"
+#include "jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow.h"
+
+#include <jawt_md.h>
+#import <JavaNativeFoundation.h>
+
+// #define VERBOSE 1
+//
+#ifdef VERBOSE
+ // #define DBG_PRINT(...) NSLog(@ ## __VA_ARGS__)
+ #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
static const char * const ClazzNameRunnable = "java/lang/Runnable";
static jmethodID runnableRunID = NULL;
@@ -81,7 +94,7 @@ Java_jogamp_nativewindow_macosx_OSXUtil_initIDs0(JNIEnv *env, jclass _unused) {
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
- * Method: getLocationOnScreenImpl0
+ * Method: getLocationOnScreen0
* Signature: (JII)Ljavax/media/nativewindow/util/Point;
*/
JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnScreen0
@@ -97,7 +110,7 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
int dest_x=-1;
int dest_y=-1;
- NSObject *nsObj = (NSObject*) ((intptr_t) winOrView);
+ NSObject *nsObj = (NSObject*) (intptr_t) winOrView;
NSWindow* win = NULL;
NSView* view = NULL;
@@ -135,6 +148,189 @@ JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_GetLocationOnS
return res;
}
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateNSView0
+ * Signature: (IIIIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSView0
+ (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSRect rect = NSMakeRect(x, y, width, height);
+ NSView * view = [[NSView alloc] initWithFrame: rect] ;
+ [view setCanDrawConcurrently: YES];
+ [pool release];
+
+ return (jlong) (intptr_t) view;
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyNSView0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSView0
+ (JNIEnv *env, jclass unused, jlong nsView)
+{
+ NSView* view = (NSView*) (intptr_t) nsView;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ [view release];
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateNSWindow0
+ * Signature: (IIIIZ)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateNSWindow0
+ (JNIEnv *env, jclass unused, jint x, jint y, jint width, jint height)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSRect rect = NSMakeRect(x, y, width, height);
+
+ // Allocate the window
+ NSWindow* myWindow = [[NSWindow alloc] initWithContentRect: rect
+ styleMask: NSBorderlessWindowMask
+ backing: NSBackingStoreBuffered
+ defer: YES];
+ [myWindow setReleasedWhenClosed: YES]; // default
+ [myWindow setPreservesContentDuringLiveResize: YES];
+
+ // invisible ..
+ [myWindow setOpaque: NO];
+ [myWindow setBackgroundColor: [NSColor clearColor]];
+
+ [pool release];
+
+ return (jlong) ((intptr_t) myWindow);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyNSWindow0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyNSWindow0
+ (JNIEnv *env, jclass unused, jlong nsWindow)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* mWin = (NSWindow*) ((intptr_t) nsWindow);
+
+ [mWin close]; // performs release!
+ [pool release];
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: CreateCALayer0
+ * Signature: (V)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_CreateCALayer0
+ (JNIEnv *env, jclass unused)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ // CALayer* layer = [[CALayer alloc] init];
+ CALayer* layer = [CALayer layer];
+
+ // no animations for add/remove/swap sublayers etc
+ [layer removeAnimationForKey: kCAOnOrderIn];
+ [layer removeAnimationForKey: kCAOnOrderOut];
+ [layer removeAnimationForKey: kCATransition];
+
+ // initial dummy size !
+ CGRect lRect = [layer frame];
+ lRect.origin.x = 0;
+ lRect.origin.y = 0;
+ lRect.size.width = 32;
+ lRect.size.height = 32;
+ [layer setFrame: lRect];
+ DBG_PRINT("CALayer::CreateCALayer0: %p %lf/%lf %lfx%lf\n", layer, lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height);
+
+ [pool release];
+
+ return (jlong) ((intptr_t) layer);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: AddCASublayer0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_AddCASublayer0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ CGRect lRectRoot = [rootLayer frame];
+ DBG_PRINT("CALayer::AddCASublayer0.0: Origin %p frame0: %lf/%lf %lfx%lf\n",
+ rootLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height);
+ if(lRectRoot.origin.x<0 || lRectRoot.origin.y<0) {
+ lRectRoot.origin.x = 0;
+ lRectRoot.origin.y = 0;
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [rootLayer setFrame: lRectRoot];
+ }];
+ DBG_PRINT("CALayer::AddCASublayer0.1: Origin %p frame*: %lf/%lf %lfx%lf\n",
+ rootLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height);
+ }
+ DBG_PRINT("CALayer::AddCASublayer0.2: %p . %p %lf/%lf %lfx%lf (refcnt %d)\n",
+ rootLayer, subLayer, lRectRoot.origin.x, lRectRoot.origin.y, lRectRoot.size.width, lRectRoot.size.height, (int)[subLayer retainCount]);
+
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ // simple 1:1 layout !
+ [subLayer setFrame:lRectRoot];
+ [rootLayer addSublayer:subLayer];
+ }];
+ DBG_PRINT("CALayer::AddCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: RemoveCASublayer0
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RemoveCASublayer0
+ (JNIEnv *env, jclass unused, jlong rootCALayer, jlong subCALayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* rootLayer = (CALayer*) ((intptr_t) rootCALayer);
+ CALayer* subLayer = (CALayer*) ((intptr_t) subCALayer);
+
+ (void)rootLayer; // no warnings
+
+ DBG_PRINT("CALayer::RemoveCASublayer0.0: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [subLayer removeFromSuperlayer];
+ }];
+ DBG_PRINT("CALayer::RemoveCASublayer0.X: %p . %p (refcnt %d)\n", rootLayer, subLayer, (int)[subLayer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class: Java_jogamp_nativewindow_macosx_OSXUtil
+ * Method: DestroyCALayer0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_DestroyCALayer0
+ (JNIEnv *env, jclass unused, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ CALayer* layer = (CALayer*) ((intptr_t) caLayer);
+
+ DBG_PRINT("CALayer::DestroyCALayer0.0: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ [layer release]; // performs release!
+ }];
+ DBG_PRINT("CALayer::DestroyCALayer0.X: %p (refcnt %d)\n", layer, (int)[layer retainCount]);
+ JNF_COCOA_EXIT(env);
+}
+
@interface MainRunnable : NSObject
{
@@ -212,10 +408,35 @@ JNIEXPORT void JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_RunOnMainThread0
/*
* Class: Java_jogamp_nativewindow_macosx_OSXUtil
* Method: RunOnMainThread0
- * Signature: (ZLjava/lang/Runnable;)V
+ * Signature: (V)V
*/
JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_macosx_OSXUtil_IsMainThread0
(JNIEnv *env, jclass unused)
{
return ( [NSThread isMainThread] == YES ) ? JNI_TRUE : JNI_FALSE ;
}
+
+/*
+ * Class: Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow
+ * Method: AttachJAWTSurfaceLayer
+ * Signature: (JJ)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_jawt_macosx_MacOSXJAWTWindow_AttachJAWTSurfaceLayer0
+ (JNIEnv *env, jclass unused, jobject jawtDrawingSurfaceInfoBuffer, jlong caLayer)
+{
+ JNF_COCOA_ENTER(env);
+ JAWT_DrawingSurfaceInfo* dsi = (JAWT_DrawingSurfaceInfo*) (*env)->GetDirectBufferAddress(env, jawtDrawingSurfaceInfoBuffer);
+ if (NULL == dsi) {
+ NativewindowCommon_throwNewRuntimeException(env, "Argument \"jawtDrawingSurfaceInfoBuffer\" was not a direct buffer");
+ return JNI_FALSE;
+ }
+ CALayer* layer = (CALayer*) (intptr_t) caLayer;
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ id <JAWT_SurfaceLayers> surfaceLayers = (id <JAWT_SurfaceLayers>)dsi->platformInfo;
+ DBG_PRINT("CALayer::attachJAWTSurfaceLayer: %p -> %p\n", surfaceLayers.layer, layer);
+ surfaceLayers.layer = [layer autorelease];
+ }];
+ JNF_COCOA_EXIT(env);
+ return JNI_TRUE;
+}
+
diff --git a/src/nativewindow/native/windows/GDImisc.c b/src/nativewindow/native/windows/GDImisc.c
index e8285008e..3ab7f9859 100644
--- a/src/nativewindow/native/windows/GDImisc.c
+++ b/src/nativewindow/native/windows/GDImisc.c
@@ -14,7 +14,7 @@
#include <stdio.h>
#include "NativewindowCommon.h"
-#include "jogamp_nativewindow_windows_GDI.h"
+#include "jogamp_nativewindow_windows_GDIUtil.h"
// #define VERBOSE_ON 1
@@ -36,12 +36,12 @@ HINSTANCE GetApplicationHandle() {
}
/* Java->C glue code:
- * Java package: jogamp.nativewindow.windows.GDI
+ * Java package: jogamp.nativewindow.windows.GDIUtil
* Java method: boolean CreateWindowClass(long hInstance, java.lang.String clazzName, long wndProc)
* C function: BOOL CreateWindowClass(HANDLE hInstance, LPCSTR clazzName, HANDLE wndProc);
*/
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_windows_GDI_CreateWindowClass
+Java_jogamp_nativewindow_windows_GDIUtil_CreateWindowClass
(JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName, jlong wndProc)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
@@ -85,12 +85,12 @@ Java_jogamp_nativewindow_windows_GDI_CreateWindowClass
}
/* Java->C glue code:
- * Java package: jogamp.nativewindow.windows.GDI
+ * Java package: jogamp.nativewindow.windows.GDIUtil
* Java method: boolean DestroyWindowClass(long hInstance, java.lang.String className)
* C function: BOOL DestroyWindowClass(HANDLE hInstance, LPCSTR className);
*/
JNIEXPORT jboolean JNICALL
-Java_jogamp_nativewindow_windows_GDI_DestroyWindowClass
+Java_jogamp_nativewindow_windows_GDIUtil_DestroyWindowClass
(JNIEnv *env, jclass _unused, jlong jHInstance, jstring jClazzName)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
@@ -116,12 +116,12 @@ Java_jogamp_nativewindow_windows_GDI_DestroyWindowClass
/* Java->C glue code:
- * Java package: jogamp.nativewindow.windows.GDI
+ * Java package: jogamp.nativewindow.windows.GDIUtil
* Java method: long CreateDummyWindow0(long hInstance, java.lang.String className, java.lang.String windowName, int x, int y, int width, int height)
* C function: HANDLE CreateDummyWindow0(HANDLE hInstance, LPCSTR className, LPCSTR windowName, int x, int y, int width, int height);
*/
JNIEXPORT jlong JNICALL
-Java_jogamp_nativewindow_windows_GDI_CreateDummyWindow0
+Java_jogamp_nativewindow_windows_GDIUtil_CreateDummyWindow0
(JNIEnv *env, jclass _unused, jlong jHInstance, jstring jWndClassName, jstring jWndName, jint x, jint y, jint width, jint height)
{
HINSTANCE hInstance = (HINSTANCE) (intptr_t) jHInstance;
@@ -162,26 +162,26 @@ Java_jogamp_nativewindow_windows_GDI_CreateDummyWindow0
/*
- * Class: jogamp_nativewindow_windows_GDI
+ * Class: jogamp_nativewindow_windows_GDIUtil
* Method: initIDs0
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDI_initIDs0
+JNIEXPORT jboolean JNICALL Java_jogamp_nativewindow_windows_GDIUtil_initIDs0
(JNIEnv *env, jclass clazz)
{
if(NativewindowCommon_init(env)) {
jclass c = (*env)->FindClass(env, ClazzNamePoint);
if(NULL==c) {
- NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't find %s", ClazzNamePoint);
+ NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't find %s", ClazzNamePoint);
}
pointClz = (jclass)(*env)->NewGlobalRef(env, c);
(*env)->DeleteLocalRef(env, c);
if(NULL==pointClz) {
- NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't use %s", ClazzNamePoint);
+ NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't use %s", ClazzNamePoint);
}
pointCstr = (*env)->GetMethodID(env, pointClz, ClazzAnyCstrName, ClazzNamePointCstrSignature);
if(NULL==pointCstr) {
- NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDI: can't fetch %s.%s %s",
+ NativewindowCommon_FatalError(env, "FatalError jogamp_nativewindow_windows_GDIUtil: can't fetch %s.%s %s",
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
}
@@ -193,22 +193,22 @@ LRESULT CALLBACK DummyWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
}
/*
- * Class: jogamp_nativewindow_windows_GDI
+ * Class: jogamp_nativewindow_windows_GDIUtil
* Method: getDummyWndProc0
* Signature: ()J
*/
-JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_windows_GDI_getDummyWndProc0
+JNIEXPORT jlong JNICALL Java_jogamp_nativewindow_windows_GDIUtil_getDummyWndProc0
(JNIEnv *env, jclass clazz)
{
return (jlong) (intptr_t) DummyWndProc;
}
/*
- * Class: jogamp_nativewindow_windows_GDI
+ * Class: jogamp_nativewindow_windows_GDIUtil
* Method: GetRelativeLocation0
* Signature: (JJII)Ljavax/media/nativewindow/util/Point;
*/
-JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_windows_GDI_GetRelativeLocation0
+JNIEXPORT jobject JNICALL Java_jogamp_nativewindow_windows_GDIUtil_GetRelativeLocation0
(JNIEnv *env, jclass unused, jlong jsrc_win, jlong jdest_win, jint src_x, jint src_y)
{
HWND src_win = (HWND) (intptr_t) jsrc_win;
diff --git a/src/nativewindow/native/x11/Xmisc.c b/src/nativewindow/native/x11/Xmisc.c
index d481343f9..d28891cda 100644
--- a/src/nativewindow/native/x11/Xmisc.c
+++ b/src/nativewindow/native/x11/Xmisc.c
@@ -293,14 +293,16 @@ static void x11IOErrorHandlerEnable(int onoff, JNIEnv * env) {
}
static int _initialized=0;
+static jboolean _xinitThreadsOK=JNI_FALSE;
-JNIEXPORT void JNICALL
+JNIEXPORT jboolean JNICALL
Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jboolean firstUIActionOnProcess) {
if(0==_initialized) {
if( JNI_TRUE == firstUIActionOnProcess ) {
if( 0 == XInitThreads() ) {
fprintf(stderr, "Warning: XInitThreads() failed\n");
} else {
+ _xinitThreadsOK=JNI_TRUE;
fprintf(stderr, "Info: XInitThreads() called for concurrent Thread support\n");
}
} else {
@@ -311,6 +313,12 @@ Java_jogamp_nativewindow_x11_X11Util_initialize0(JNIEnv *env, jclass _unused, jb
x11IOErrorHandlerEnable(1, env);
_initialized=1;
}
+ return _xinitThreadsOK;
+}
+
+JNIEXPORT void JNICALL
+Java_jogamp_nativewindow_x11_X11Util_shutdown0(JNIEnv *env, jclass _unused) {
+ x11IOErrorHandlerEnable(0, env);
}
JNIEXPORT void JNICALL
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 6a0ebe14a..7b6849a30 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -30,7 +30,6 @@ package com.jogamp.newt;
import com.jogamp.newt.util.EDTUtil;
import jogamp.newt.Debug;
-import jogamp.newt.DisplayImpl;
import java.util.*;
@@ -130,7 +129,10 @@ public abstract class Display {
public abstract int getId();
/**
- * @return this display instance name as defined at creation time
+ * @return This display connection name as defined at creation time.
+ * The display connection name is a technical platform specific detail, see {@link AbstractGraphicsDevice#getConnection()}.
+ *
+ * @see AbstractGraphicsDevice#getConnection()
*/
public abstract String getName();
@@ -198,6 +200,7 @@ public abstract class Display {
}
/** Returns the global display collection */
+ @SuppressWarnings("unchecked")
public static Collection<Display> getAllDisplays() {
ArrayList<Display> list;
synchronized(displayList) {
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index d3be098c0..4e6fa1aa5 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -34,14 +34,19 @@
package com.jogamp.newt;
-import javax.media.nativewindow.*;
-
-import com.jogamp.common.os.Platform;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
+import jogamp.newt.Debug;
import jogamp.newt.DisplayImpl;
import jogamp.newt.ScreenImpl;
import jogamp.newt.WindowImpl;
-import jogamp.newt.Debug;
+
+import com.jogamp.common.os.Platform;
public class NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
@@ -49,7 +54,6 @@ public class NewtFactory {
// Work-around for initialization order problems on Mac OS X
// between native Newt and (apparently) Fmod
static {
- Platform.initSingleton();
NativeWindowFactory.initSingleton(false); // last resort ..
WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
}
@@ -80,53 +84,124 @@ public class NewtFactory {
public static boolean useEDT() { return useEDT; }
/**
- * Create a Display entity, incl native creation
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused.
+ * </p>
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @return the new or reused Display instance
*/
public static Display createDisplay(String name) {
return createDisplay(name, true);
}
+ /**
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused
+ * <b>if</b> <code>reuse</code> is <code>true</code>, otherwise a new instance is being created.
+ * </p>
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @param reuse attempt to reuse an existing Display with same <code>name</code> if set true, otherwise create a new instance.
+ * @return the new or reused Display instance
+ */
public static Display createDisplay(String name, boolean reuse) {
return DisplayImpl.create(NativeWindowFactory.getNativeWindowType(true), name, 0, reuse);
}
/**
- * Create a Display entity using the given implementation type, incl native creation
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused.
+ * </p>
+ * @param type explicit NativeWindow type eg. {@link NativeWindowFactory#TYPE_AWT}
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @return the new or reused Display instance
*/
public static Display createDisplay(String type, String name) {
return createDisplay(type, name, true);
}
+ /**
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused
+ * <b>if</b> <code>reuse</code> is <code>true</code>, otherwise a new instance is being created.
+ * </p>
+ * @param type explicit NativeWindow type eg. {@link NativeWindowFactory#TYPE_AWT}
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @param reuse attempt to reuse an existing Display with same <code>name</code> if set true, otherwise create a new instance.
+ * @return the new or reused Display instance
+ */
public static Display createDisplay(String type, String name, boolean reuse) {
return DisplayImpl.create(type, name, 0, reuse);
}
/**
- * Create a Screen entity, incl native creation
+ * Create a Screen entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Screen#addReference()}.
+ * </p>
+ * <p>
+ * The lifecycle of this Screen's Display is handled via {@link Display#addReference()}
+ * and {@link Display#removeReference()}.
+ * </p>
*/
public static Screen createScreen(Display display, int index) {
return ScreenImpl.create(display, index);
}
/**
- * Create a top level Window entity, incl native creation.<br>
- * The Display/Screen is created and owned, ie destructed atomatically.<br>
- * A new Display is only created if no preexisting one could be found via {@link Display#getLastDisplayOf(java.lang.String, java.lang.String, int)}.
+ * Create a top level Window entity on the default Display and default Screen.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Window#setVisible(boolean)}.
+ * </p>
+ * <p>
+ * An already existing default Display will be reused.
+ * </p>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static Window createWindow(CapabilitiesImmutable caps) {
return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), caps);
}
/**
- * Create a top level Window entity, incl native creation
+ * Create a top level Window entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Window#setVisible(boolean)}.
+ * </p>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static Window createWindow(Screen screen, CapabilitiesImmutable caps) {
return createWindowImpl(screen, caps);
}
/**
- * Create a child Window entity attached to the given parent, incl native creation.<br>
- * The Screen and Display information is regenerated utilizing the parents information.<br>
+ * Create a child Window entity attached to the given parent.<br>
+ * The Screen and Display information is regenerated utilizing the parents information,
+ * while reusing an existing Display.<br>
* <p>
* In case <code>parentWindowObject</code> is a {@link com.jogamp.newt.Window} instance,<br>
* the new window is added to it's list of children.<br>
@@ -138,38 +213,41 @@ public class NewtFactory {
* In case <code>parentWindowObject</code> is a different {@link javax.media.nativewindow.NativeWindow} implementation,<br>
* you have to handle all events appropriate.<br></p>
* <p>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*
* @param parentWindowObject either a NativeWindow instance
*/
- public static Window createWindow(NativeWindow nParentWindow, CapabilitiesImmutable caps) {
+ public static Window createWindow(NativeWindow parentWindow, CapabilitiesImmutable caps) {
final String type = NativeWindowFactory.getNativeWindowType(true);
-
Screen screen = null;
- Window parentWindow = null;
+ Window newtParentWindow = null;
- if ( nParentWindow instanceof Window ) {
+ if ( parentWindow instanceof Window ) {
// use parent NEWT Windows Display/Screen
- parentWindow = (Window) nParentWindow ;
- screen = parentWindow.getScreen();
+ newtParentWindow = (Window) parentWindow ;
+ screen = newtParentWindow.getScreen();
} else {
// create a Display/Screen compatible to the NativeWindow
- AbstractGraphicsConfiguration nParentConfig = nParentWindow.getGraphicsConfiguration();
- if(null!=nParentConfig) {
- AbstractGraphicsScreen nParentScreen = nParentConfig.getScreen();
- AbstractGraphicsDevice nParentDevice = nParentScreen.getDevice();
- Display display = NewtFactory.createDisplay(type, nParentDevice.getHandle(), true);
- screen = NewtFactory.createScreen(display, nParentScreen.getIndex());
+ AbstractGraphicsConfiguration parentConfig = parentWindow.getGraphicsConfiguration();
+ if(null!=parentConfig) {
+ AbstractGraphicsScreen parentScreen = parentConfig.getScreen();
+ AbstractGraphicsDevice parentDevice = parentScreen.getDevice();
+ Display display = NewtFactory.createDisplay(type, parentDevice.getHandle(), true);
+ screen = NewtFactory.createScreen(display, parentScreen.getIndex());
} else {
Display display = NewtFactory.createDisplay(type, null, true); // local display
screen = NewtFactory.createScreen(display, 0); // screen 0
}
}
- final Window win = createWindowImpl(nParentWindow, screen, caps);
+ final Window win = createWindowImpl(parentWindow, screen, caps);
- win.setSize(nParentWindow.getWidth(), nParentWindow.getHeight());
- if ( null != parentWindow ) {
- parentWindow.addChild(win);
- win.setVisible(parentWindow.isVisible());
+ win.setSize(parentWindow.getWidth(), parentWindow.getHeight());
+ if ( null != newtParentWindow ) {
+ newtParentWindow.addChild(win);
+ win.setVisible(newtParentWindow.isVisible());
}
return win;
}
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index d25d3e7ac..26f19ad6b 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -120,12 +120,22 @@ public abstract class Screen {
public abstract int getIndex();
/**
- * @return the current screen width
+ * @return the x position of the virtual top-left origin.
+ */
+ public abstract int getX();
+
+ /**
+ * @return the y position of the virtual top-left origin.
+ */
+ public abstract int getY();
+
+ /**
+ * @return the <b>rotated</b> virtual width.
*/
public abstract int getWidth();
/**
- * @return the current screen height
+ * @return the <b>rotated</b> virtual height.
*/
public abstract int getHeight();
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index a78f81668..32024a49a 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -30,12 +30,13 @@ package com.jogamp.newt;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.MouseListener;
import jogamp.newt.Debug;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
-import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.WindowClosingProtocol;
/**
@@ -133,6 +134,11 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
boolean isVisible();
+ /**
+ * If the implementation uses delegation, return the delegated {@link Window} instance,
+ * otherwise return <code>this</code> instance. */
+ Window getDelegatedWindow();
+
//
// Child Window Management
//
@@ -310,16 +316,46 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
}
/**
- * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
+ * Sets a {@link FocusRunnable},
+ * which {@link FocusRunnable#run()} method is executed before the native focus is requested.
+ * <p>
* This allows notifying a covered window toolkit like AWT that the focus is requested,
* hence focus traversal can be made transparent.
+ * </p>
*/
void setFocusAction(FocusRunnable focusAction);
+
+ /**
+ * Sets a {@link KeyListener} allowing focus traversal with a covered window toolkit like AWT.
+ * <p>
+ * The {@link KeyListener} methods are invoked prior to all other {@link KeyListener}'s
+ * allowing to suppress the {@link KeyEvent} via the {@link InputEvent#consumedTag}.
+ * </p>
+ * @param l
+ */
+ void setKeyboardFocusHandler(KeyListener l);
+ /**
+ * Request focus for this native window
+ * <p>
+ * The request is handled on this Window EDT and blocked until finished.
+ * </p>
+ *
+ * @see #requestFocus(boolean)
+ */
void requestFocus();
- boolean hasFocus();
-
+ /**
+ * Request focus for this native window
+ * <p>
+ * The request is handled on this Window EDT.
+ * </p>
+ *
+ * @param wait true if waiting until the request is executed, otherwise false
+ * @see #requestFocus()
+ */
+ void requestFocus(boolean wait);
+
void windowRepaint(int x, int y, int width, int height);
void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event);
@@ -328,38 +364,6 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
//
- // SurfaceUpdateListener
- //
-
- /**
- * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of
- * the list.
- */
- void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
-
- /**
- *
- * Inserts the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} at the
- * specified position in the list.<br>
- *
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
- * @param l The listener object to be inserted
- * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
- */
- void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
-
- void removeAllSurfaceUpdatedListener();
-
- void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
-
- SurfaceUpdatedListener getSurfaceUpdatedListener(int index);
-
- SurfaceUpdatedListener[] getSurfaceUpdatedListeners();
-
-
- //
// WindowListener
//
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 31d42d21b..a71c6106d 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -29,42 +29,56 @@
package com.jogamp.newt.awt;
-import com.jogamp.newt.Display;
-import java.lang.reflect.*;
-import java.security.*;
-
+import java.awt.AWTKeyStroke;
import java.awt.Canvas;
-import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.KeyboardFocusManager;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Set;
import javax.media.nativewindow.NativeWindow;
-import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.OffscreenLayerOption;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+import javax.swing.MenuSelectionManager;
+
import jogamp.nativewindow.awt.AWTMisc;
+import jogamp.nativewindow.jawt.JAWTWindow;
+import jogamp.newt.Debug;
+import jogamp.newt.awt.NewtFactoryAWT;
+import jogamp.newt.awt.event.AWTParentWindowAdapter;
+import jogamp.newt.driver.DriverClearFocus;
-import com.jogamp.newt.event.awt.AWTAdapter;
-import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.Display;
import com.jogamp.newt.Window;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
-import jogamp.newt.Debug;
-import jogamp.newt.awt.event.AWTParentWindowAdapter;
-import jogamp.newt.awt.event.NewtFactoryAWT;
-
-import javax.swing.MenuSelectionManager;
+import com.jogamp.newt.event.awt.AWTAdapter;
+import com.jogamp.newt.event.awt.AWTKeyAdapter;
+import com.jogamp.newt.event.awt.AWTMouseAdapter;
@SuppressWarnings("serial")
-public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol {
+public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol, OffscreenLayerOption {
public static final boolean DEBUG = Debug.debug("Window");
- NativeWindow nativeWindow = null;
- Window newtChild = null;
- int newtChildCloseOp;
- AWTAdapter awtAdapter = null;
-
+ private JAWTWindow jawtWindow = null;
+ private boolean shallUseOffscreenLayer = false;
+ private Window newtChild = null;
+ private boolean isOnscreen = true;
+ private int newtChildCloseOp;
+ private AWTAdapter awtAdapter = null;
+ private AWTAdapter awtMouseAdapter = null;
+ private AWTAdapter awtKeyAdapter = null;
+
private AWTWindowClosingProtocol awtWindowClosingProtocol =
new AWTWindowClosingProtocol(this, new Runnable() {
public void run() {
@@ -102,53 +116,136 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
setNEWTChild(child);
}
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return jawtWindow.isOffscreenLayerSurfaceEnabled();
+ }
+
+ /**
+ * Returns true if the AWT component is parented to an {@link java.applet.Applet},
+ * otherwise false. This information is valid only after {@link #addNotify()} is issued,
+ * ie. before adding the component to the AWT tree and make it visible.
+ */
+ public boolean isApplet() {
+ return jawtWindow.isApplet();
+ }
+
class FocusAction implements Window.FocusRunnable {
public boolean run() {
- if ( EventQueue.isDispatchThread() ) {
- focusActionImpl.run();
- } else {
- try {
- EventQueue.invokeAndWait(focusActionImpl);
- } catch (Exception e) {
- throw new NativeWindowException(e);
- }
- /**
- // wait for AWT focus !
- for(long sleep = Window.TIMEOUT_NATIVEWINDOW; 0<sleep && !isFocusOwner(); sleep-=10 ) {
- try { Thread.sleep(10); } catch (InterruptedException e) { }
- } */
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusAction: "+Display.getThreadName()+", isOnscreen "+isOnscreen+", hasFocus "+hasFocus());
}
- return focusActionImpl.result;
- }
-
- class FocusActionImpl implements Runnable {
- public final boolean result = false; // NEWT shall always proceed requesting the native focus
- public void run() {
- if(DEBUG) {
- System.err.println("FocusActionImpl.run() "+Display.getThreadName());
- }
- NewtCanvasAWT.this.requestFocusAWTParent();
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ if(!hasFocus()) {
+ // Acquire the AWT focus 1st for proper AWT traversal
+ NewtCanvasAWT.super.requestFocus();
+ }
+ if(isOnscreen) {
+ // Remove the AWT focus in favor of the native NEWT focus
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
}
+ return false; // NEWT shall proceed requesting the native focus
}
- FocusActionImpl focusActionImpl = new FocusActionImpl();
}
- FocusAction focusAction = new FocusAction();
+ private FocusAction focusAction = new FocusAction();
WindowListener clearAWTMenusOnNewtFocus = new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent arg0) {
- MenuSelectionManager.defaultManager().clearSelectedPath();
+ MenuSelectionManager.defaultManager().clearSelectedPath();
}
};
- /** sets a new NEWT child, provoking reparenting on the NEWT level. */
- /*package */ NewtCanvasAWT setNEWTChild(Window child) {
+ class FocusTraversalKeyListener implements KeyListener {
+ boolean suppress = false;
+
+ public void keyPressed(KeyEvent e) {
+ handleKey(e, false);
+ }
+ public void keyReleased(KeyEvent e) {
+ handleKey(e, true);
+ }
+ public void keyTyped(KeyEvent e) {
+ if(suppress) {
+ e.setAttachment(InputEvent.consumedTag);
+ 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);
+ if(null != ks) {
+ final Set<AWTKeyStroke> fwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ final Set<AWTKeyStroke> bwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ if(fwdKeys.contains(ks)) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey (fwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ }
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ NewtCanvasAWT.this.transferFocus();
+ suppress = true;
+ } else if(bwdKeys.contains(ks)) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey (bwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ }
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ NewtCanvasAWT.this.transferFocusBackward();
+ suppress = true;
+ }
+ }
+ if(suppress) {
+ evt.setAttachment(InputEvent.consumedTag);
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey: XXX: "+ks);
+ }
+ }
+ }
+ private final FocusTraversalKeyListener newtFocusTraversalKeyListener = new FocusTraversalKeyListener();
+
+ class FocusPropertyChangeListener implements PropertyChangeListener {
+ public void propertyChange(PropertyChangeEvent evt) {
+ final Object oldF = evt.getOldValue();
+ final Object newF = evt.getNewValue();
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: "+evt.getPropertyName()+", src "+evt.getSource()+", "+oldF+" -> "+newF);
+ }
+ if(oldF == NewtCanvasAWT.this && newF == null) {
+ // focus traversal to NEWT - NOP
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: NEWT focus traversal");
+ }
+ } else if(null != newF && newF != NewtCanvasAWT.this) {
+ // focus traversal to another AWT component
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: lost focus - clear focus");
+ }
+ if(newtChild.getDelegatedWindow() instanceof DriverClearFocus) {
+ ((DriverClearFocus)newtChild.getDelegatedWindow()).clearFocus();
+ }
+ }
+ }
+ }
+ private final FocusPropertyChangeListener focusPropertyChangeListener = new FocusPropertyChangeListener();
+ private volatile KeyboardFocusManager keyboardFocusManager = null;
+
+ /** sets a new NEWT child, provoking reparenting. */
+ private NewtCanvasAWT setNEWTChild(Window child) {
if(newtChild!=child) {
newtChild = child;
- if(null!=nativeWindow) {
- java.awt.Container cont = AWTMisc.getContainer(this);
+ if(isDisplayable()) {
// reparent right away, addNotify has been called already
+ final java.awt.Container cont = AWTMisc.getContainer(this);
reparentWindow( (null!=child) ? true : false, cont );
}
}
@@ -162,8 +259,8 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
/** @return this AWT Canvas NativeWindow representation, may be null in case {@link #removeNotify()} has been called,
* or {@link #addNotify()} hasn't been called yet.*/
- public NativeWindow getNativeWindow() { return nativeWindow; }
-
+ public NativeWindow getNativeWindow() { return jawtWindow; }
+
public int getDefaultCloseOperation() {
return awtWindowClosingProtocol.getDefaultCloseOperation();
}
@@ -177,13 +274,41 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
awtAdapter.removeFrom(this);
awtAdapter=null;
}
+ if(null!=awtMouseAdapter) {
+ awtMouseAdapter.removeFrom(this);
+ awtMouseAdapter = null;
+ }
+ if(null!=awtKeyAdapter) {
+ awtKeyAdapter.removeFrom(this);
+ awtKeyAdapter = null;
+ }
+ newtChild.setKeyboardFocusHandler(null);
+ if(null != keyboardFocusManager) {
+ keyboardFocusManager.removePropertyChangeListener("focusOwner", focusPropertyChangeListener);
+ keyboardFocusManager = null;
+ }
+
if( null != newtChild ) {
if(attach) {
+ if(null == jawtWindow.getGraphicsConfiguration()) {
+ throw new InternalError("XXX");
+ }
+ isOnscreen = jawtWindow.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this);
newtChild.addWindowListener(clearAWTMenusOnNewtFocus);
newtChild.setFocusAction(focusAction); // enable AWT focus traversal
newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingProtocol.DO_NOTHING_ON_CLOSE);
awtWindowClosingProtocol.addClosingListenerOneShot();
+ keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ keyboardFocusManager.addPropertyChangeListener("focusOwner", focusPropertyChangeListener);
+ if(isOnscreen) {
+ // onscreen newt child needs to fwd AWT focus
+ newtChild.setKeyboardFocusHandler(newtFocusTraversalKeyListener);
+ } else {
+ // offscreen newt child requires AWT to fwd AWT key/mouse event
+ awtMouseAdapter = new AWTMouseAdapter(newtChild).addTo(this);
+ awtKeyAdapter = new AWTKeyAdapter(newtChild).addTo(this);
+ }
} else {
newtChild.removeWindowListener(clearAWTMenusOnNewtFocus);
newtChild.setFocusAction(null);
@@ -232,26 +357,47 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
newtChild.setFocusAction(null); // no AWT focus traversal ..
if(add) {
- nativeWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
- if(null!=nativeWindow) {
- if(DEBUG) {
- System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild);
- }
- final int w = cont.getWidth();
- final int h = cont.getHeight();
- setSize(w, h);
- newtChild.setSize(w, h);
- newtChild.reparentWindow(nativeWindow);
- newtChild.setVisible(true);
- configureNewtChild(true);
- newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
- newtChild.windowRepaint(0, 0, w, h);
+ jawtWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
+ jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.reparentWindow: newtChild: "+newtChild);
+ }
+ final int w;
+ final int h;
+ if(isPreferredSizeSet()) {
+ java.awt.Dimension d = getPreferredSize();
+ w = d.width;
+ h = d.height;
+ } else {
+ final java.awt.Dimension min;
+ if(this.isMinimumSizeSet()) {
+ min = getMinimumSize();
+ } else {
+ min = new java.awt.Dimension(0, 0);
+ }
+ java.awt.Insets ins = cont.getInsets();
+ w = Math.max(min.width, cont.getWidth() - ins.left - ins.right);
+ h = Math.max(min.height, cont.getHeight() - ins.top - ins.bottom);
}
+ setSize(w, h);
+ newtChild.setSize(w, h);
+ newtChild.reparentWindow(jawtWindow);
+ newtChild.setVisible(true);
+ configureNewtChild(true);
+ newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
+ newtChild.windowRepaint(0, 0, w, h);
+
+ // force this AWT Canvas to be focus-able,
+ // since this it is completely covered by the newtChild (z-order).
+ setFocusable(true);
} else {
- configureNewtChild(false);
- nativeWindow = null;
+ configureNewtChild(false);
newtChild.setVisible(false);
newtChild.reparentWindow(null);
+ if(null != jawtWindow) {
+ NewtFactoryAWT.destroyNativeWindow(jawtWindow);
+ jawtWindow=null;
+ }
}
}
@@ -273,7 +419,10 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont);
}
configureNewtChild(false);
- nativeWindow = null;
+ if(null!=jawtWindow) {
+ NewtFactoryAWT.destroyNativeWindow(jawtWindow);
+ jawtWindow=null;
+ }
newtChild.setVisible(false);
newtChild.reparentWindow(null);
newtChild.destroy();
@@ -282,7 +431,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
cont.remove(this);
}
}
- }
+ }
@Override
public void paint(Graphics g) {
@@ -299,14 +448,12 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
}
- final void requestFocusAWTParent() {
- super.requestFocusInWindow();
- }
-
- final void requestFocusNEWTChild() {
+ private final void requestFocusNEWTChild() {
if(null!=newtChild) {
newtChild.setFocusAction(null);
- KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ if(isOnscreen) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ }
newtChild.requestFocus();
newtChild.setFocusAction(focusAction);
}
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
index 2e86cb512..a052f6f97 100755
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
@@ -1,20 +1,48 @@
+/**
+ * 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 com.jogamp.newt.awt.applet;
-import java.applet.*;
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Button;
import java.awt.Component;
import java.awt.Container;
-import java.awt.Label;
+import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
-import java.awt.event.KeyListener;
-import javax.media.opengl.*;
+import javax.media.opengl.FPSCounter;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
-import java.awt.BorderLayout;
-
-import jogamp.newt.Debug;
/**
* Simple GLEventListener deployment as an applet using JOGL. This demo must be
@@ -62,7 +90,7 @@ import jogamp.newt.Debug;
*/
@SuppressWarnings("serial")
public class JOGLNewtApplet1Run extends Applet {
- public static final boolean DEBUG = Debug.debug("Applet");
+ public static final boolean DEBUG = JOGLNewtAppletBase.DEBUG;
GLWindow glWindow;
NewtCanvasAWT newtCanvasAWT;
@@ -72,6 +100,9 @@ public class JOGLNewtApplet1Run extends Applet {
boolean glStandalone = false;
public void init() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.init() START");
+ }
if(!(this instanceof Container)) {
throw new RuntimeException("This Applet is not a AWT Container");
}
@@ -88,6 +119,7 @@ public class JOGLNewtApplet1Run extends Applet {
int glAlphaBits=0;
int glNumMultisampleBuffer=0;
boolean glNoDefaultKeyListener = false;
+ boolean appletDebugTestBorder = false;
try {
glEventListenerClazzName = getParameter("gl_event_listener_class");
glProfileName = getParameter("gl_profile");
@@ -104,6 +136,7 @@ public class JOGLNewtApplet1Run extends Applet {
glWidth = JOGLNewtAppletBase.str2Int(getParameter("gl_width"), glWidth);
glHeight = JOGLNewtAppletBase.str2Int(getParameter("gl_height"), glHeight);
glNoDefaultKeyListener = JOGLNewtAppletBase.str2Bool(getParameter("gl_nodefaultkeyListener"), glNoDefaultKeyListener);
+ appletDebugTestBorder = JOGLNewtAppletBase.str2Bool(getParameter("appletDebugTestBorder"), appletDebugTestBorder);
} catch (Exception e) {
e.printStackTrace();
}
@@ -137,7 +170,6 @@ public class JOGLNewtApplet1Run extends Applet {
glTrace);
try {
- GLProfile.initSingleton(false);
GLCapabilities caps = new GLCapabilities(GLProfile.get(glProfileName));
caps.setAlphaBits(glAlphaBits);
if(0<glNumMultisampleBuffer) {
@@ -149,18 +181,12 @@ public class JOGLNewtApplet1Run extends Applet {
glWindow.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
glWindow.setUndecorated(glUndecorated);
glWindow.setAlwaysOnTop(glAlwaysOnTop);
- if(glStandalone) {
- newtCanvasAWT = null;
- } else {
- newtCanvasAWT = new NewtCanvasAWT(glWindow);
- container.setLayout(new BorderLayout());
- container.add(newtCanvasAWT, BorderLayout.CENTER);
- }
- if(DEBUG) {
- container.add(new Label("North"), BorderLayout.NORTH);
- container.add(new Label("South"), BorderLayout.SOUTH);
- container.add(new Label("East"), BorderLayout.EAST);
- container.add(new Label("West"), BorderLayout.WEST);
+ container.setLayout(new BorderLayout());
+ if(appletDebugTestBorder) {
+ container.add(new Button("North"), BorderLayout.NORTH);
+ container.add(new Button("South"), BorderLayout.SOUTH);
+ container.add(new Button("East"), BorderLayout.EAST);
+ container.add(new Button("West"), BorderLayout.WEST);
}
base.init(glWindow);
if(base.isValid()) {
@@ -176,12 +202,25 @@ public class JOGLNewtApplet1Run extends Applet {
addKeyListener((KeyListener)glEventListener);
}
}
+ if(glStandalone) {
+ newtCanvasAWT = null;
+ } else {
+ newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ container.add(newtCanvasAWT, BorderLayout.CENTER);
+ container.validate();
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.init() END");
+ }
}
public void start() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.start() START");
+ }
this.validate();
this.setVisible(true);
@@ -195,21 +234,35 @@ public class JOGLNewtApplet1Run extends Applet {
while (null != topC.getParent()) {
topC = topC.getParent();
}
+ System.err.println("JOGLNewtApplet1Run start:");
System.err.println("TopComponent: "+topC.getLocation()+" rel, "+topC.getLocationOnScreen()+" screen, visible "+topC.isVisible()+", "+topC);
System.err.println("Applet Pos: "+this.getLocation()+" rel, "+p0+" screen, visible "+this.isVisible()+", "+this);
if(null != newtCanvasAWT) {
System.err.println("NewtCanvasAWT Pos: "+newtCanvasAWT.getLocation()+" rel, "+newtCanvasAWT.getLocationOnScreen()+" screen, visible "+newtCanvasAWT.isVisible()+", "+newtCanvasAWT);
}
System.err.println("GLWindow Pos: "+glWindow.getX()+"/"+glWindow.getY()+" rel, "+glWindow.getLocationOnScreen(null)+" screen");
+ System.err.println("GLWindow: "+glWindow);
}
base.start();
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.start() END");
+ }
}
public void stop() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.stop() START");
+ }
base.stop();
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.stop() END");
+ }
}
public void destroy() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.destroy() START");
+ }
glWindow.setVisible(false); // hide 1st
if(!glStandalone) {
glWindow.reparentWindow(null); // get out of newtCanvasAWT
@@ -217,6 +270,9 @@ public class JOGLNewtApplet1Run extends Applet {
}
base.destroy(); // destroy glWindow unrecoverable
base=null;
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.destroy() END");
+ }
}
}
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 b1061dd14..67da50210 100755
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
@@ -1,18 +1,53 @@
+/**
+ * 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 com.jogamp.newt.awt.applet;
-import java.lang.reflect.*;
+import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.media.nativewindow.NativeWindow;
-import javax.media.opengl.*;
+import javax.media.opengl.FPSCounter;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
import jogamp.newt.Debug;
-import com.jogamp.opengl.util.*;
-
-import com.jogamp.newt.event.*;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+
/** Shows how to deploy an applet using JOGL. This demo must be
referenced from a web page via an &lt;applet&gt; tag. */
@@ -165,6 +200,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
public void start() {
if(isValid) {
glWindow.setVisible(true);
+ glWindow.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
glAnimator.start();
awtParent = glWindow.getParent();
}
diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
index 51ceccf31..d8a9235c1 100644
--- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
@@ -48,6 +48,11 @@ public abstract class InputEvent extends NEWTEvent
public static final int CONFINED_MASK = 1 << 16;
public static final int INVISIBLE_MASK = 1 << 17;
+ /** Object when attached via {@link #setAttachment(Object)} marks the event consumed,
+ * ie. stops propagating the event any further to the event listener.
+ */
+ public static final Object consumedTag = new Object();
+
protected InputEvent(int eventType, Object source, long when, int modifiers) {
super(eventType, source, when);
this.modifiers=modifiers;
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 9e4fe372b..44fcea49c 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -34,6 +34,7 @@
package com.jogamp.newt.event;
+@SuppressWarnings("serial")
public class KeyEvent extends InputEvent
{
public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
@@ -42,9 +43,12 @@ public class KeyEvent extends InputEvent
this.keyChar=keyChar;
}
+ /** Only valid if delivered via {@link KeyListener#keyPressed(KeyEvent)} */
public char getKeyChar() {
return keyChar;
}
+
+ /** Always valid. */
public int getKeyCode() {
return keyCode;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
index ccc674f1d..9bc3be1e5 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
@@ -139,6 +139,20 @@ public class MouseEvent extends InputEvent
return pressure[index];
}
+ /**
+ * <i>Usually</i> a wheel rotation of <b>&gt; 0 is up</b>,
+ * and <b>&lt; 0 is down</b>.<br>
+ * <i>However</i>, on some OS this might be flipped due to the OS <i>default</i> behavior.
+ * The latter is true for OS X 10.7 (Lion) for example.
+ * <p>
+ * The events will be send usually in steps of one, ie. <i>-1</i> and <i>1</i>.
+ * Higher values may result due to fast scrolling.
+ * </p>
+ * <p>
+ * The button number refers to the wheel number.
+ * </p>
+ * @return
+ */
public int getWheelRotation() {
return wheelRotation;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseListener.java b/src/newt/classes/com/jogamp/newt/event/MouseListener.java
index 5ec086b94..7668b755c 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseListener.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseListener.java
@@ -43,6 +43,8 @@ public interface MouseListener extends NEWTEventListener
public void mouseReleased(MouseEvent e);
public void mouseMoved(MouseEvent e);
public void mouseDragged(MouseEvent e);
+
+ /** See {@link MouseEvent#getWheelRotation() } */
public void mouseWheelMoved(MouseEvent e);
}
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
index 50aed2c8e..3f3817b91 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -46,6 +46,7 @@ package com.jogamp.newt.event;
* <li> KeyEvent <code>300..30x</code></li>
* </ul><br>
*/
+@SuppressWarnings("serial")
public class NEWTEvent extends java.util.EventObject {
private final boolean isSystemEvent;
private final int eventType;
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
index ae7474c73..69b0d0482 100644
--- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
@@ -107,6 +107,9 @@ public class AWTWindowAdapter
public void componentResized(java.awt.event.ComponentEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentResized: "+event);
+ }
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowResized(event);
} else {
@@ -116,6 +119,9 @@ public class AWTWindowAdapter
public void componentMoved(java.awt.event.ComponentEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentMoved: "+event);
+ }
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowMoved(event);
} else {
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 2cd8c2ced..92f57577d 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -41,6 +41,7 @@ import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.newt.*;
import com.jogamp.newt.event.*;
+
import jogamp.newt.WindowImpl;
import javax.media.nativewindow.*;
@@ -54,8 +55,8 @@ import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.util.Animator;
/**
- * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
- * using an aggregation of a {@link com.jogamp.newt.Window} implementation.
+ * An implementation of {@link GLAutoDrawable} and {@link Window} interface,
+ * using a delegated {@link Window} instance, which may be an aggregation (lifecycle: created and destroyed).
* <P>
* This implementation does not make the OpenGL context current<br>
* before calling the various input EventListener callbacks, ie {@link com.jogamp.newt.event.MouseListener} etc.<br>
@@ -121,12 +122,13 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
}
/**
- * Creates a new GLWindow attaching a new Window referencing a new Screen
- * with the given GLCapabilities.
- * <P>
- * The resulting GLWindow owns the Window, Screen and Device, ie it will be destructed.
- * <P>
- * The default display connection will be used and reused if already in process.
+ * Creates a new GLWindow attaching a new Window referencing a
+ * new default Screen and default Display with the given GLCapabilities.
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
+ * The default Display will be reused if already instantiated.
*/
public static GLWindow create(GLCapabilitiesImmutable caps) {
return new GLWindow(NewtFactory.createWindow(caps));
@@ -135,8 +137,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
/**
* Creates a new GLWindow attaching a new Window referencing the given Screen
* with the given GLCapabilities.
- * <P>
- * The resulting GLWindow owns the Window, ie it will be destructed.
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static GLWindow create(Screen screen, GLCapabilitiesImmutable caps) {
return new GLWindow(NewtFactory.createWindow(screen, caps));
@@ -144,8 +148,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
/**
* Creates a new GLWindow attaching the given window.
- * <P>
- * The resulting GLWindow does not own the given Window, ie it will not be destructed.
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static GLWindow create(Window window) {
return new GLWindow(window);
@@ -154,11 +160,15 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
/**
* Creates a new GLWindow attaching a new child Window
* of the given <code>parentNativeWindow</code> with the given GLCapabilities.
- * <P>
+ * <p>
* The Display/Screen will be compatible with the <code>parentNativeWindow</code>,
* or even identical in case it's a Newt Window.
- * <P>
- * The resulting GLWindow owns the Window, ie it will be destructed.
+ * An already instantiated compatible Display will be reused.
+ * </p>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilitiesImmutable caps) {
return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps));
@@ -195,8 +205,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
return window.getRequestedCapabilities();
}
- public final Window getWindow() {
- return window;
+ public final Window getDelegatedWindow() {
+ return window.getDelegatedWindow();
}
public final NativeWindow getParent() {
@@ -254,10 +264,18 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
window.setFocusAction(focusAction);
}
+ public void setKeyboardFocusHandler(KeyListener l) {
+ window.setKeyboardFocusHandler(l);
+ }
+
public final void requestFocus() {
window.requestFocus();
}
+ public final void requestFocus(boolean wait) {
+ window.requestFocus(wait);
+ }
+
public boolean hasFocus() {
return window.hasFocus();
}
@@ -288,7 +306,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
@Override
public final String toString() {
return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
- ", \n\tContext: " + context + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
+ ", \n\tContext: " + context + ", \n\tWindow: "+window+ /** ", \n\tFactory: "+factory+ */ "]";
}
public final int reparentWindow(NativeWindow newParent) {
@@ -337,14 +355,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
// Hide methods here ..
protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
- private class DisposeAction implements Runnable {
- public final void run() {
- // Lock: Covered by DestroyAction ..
- helper.dispose(GLWindow.this);
- }
- }
- DisposeAction disposeAction = new DisposeAction();
-
public synchronized void destroyActionPreLock() {
// nop
}
@@ -362,11 +372,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
// Catch dispose GLExceptions by GLEventListener, just 'print' them
// so we can continue with the destruction.
try {
- helper.invokeGL(drawable, context, disposeAction, null);
+ helper.disposeGL(GLWindow.this, drawable, context, null);
} catch (GLException gle) {
gle.printStackTrace();
}
- context.destroy();
}
drawable.setRealized(false);
}
@@ -399,11 +408,11 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
if (null == context && visible && 0 != window.getWindowHandle() && 0<getWidth()*getHeight()) {
NativeWindow nw;
if (window.getWrappedWindow() != null) {
- nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
+ nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getPrivateGraphicsConfiguration());
} else {
nw = window;
}
- GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getChosenCapabilities();
if(null==factory) {
factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
}
@@ -753,18 +762,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
window.runOnEDTIfAvail(wait, task);
}
- public final SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- return window.getSurfaceUpdatedListener(index);
- }
-
- public final SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- return window.getSurfaceUpdatedListeners();
- }
-
- public final void removeAllSurfaceUpdatedListener() {
- window.removeAllSurfaceUpdatedListener();
- }
-
public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
window.removeSurfaceUpdatedListener(l);
}
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index c7780b0d8..e71ef75ec 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -93,17 +93,21 @@ import jogamp.newt.NEWTJNILibLoader;
*/
public class MainThread {
private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.MacDisplay";
+ private static final Platform.OSType osType;
+ private static final boolean isMacOSX;
+
/** if true, use the main thread EDT, otherwise AWT's EDT */
public static final boolean HINT_USE_MAIN_THREAD;
static {
final AccessControlContext localACC = AccessController.getContext();
- Platform.initSingleton();
NativeWindowFactory.initSingleton(true);
NEWTJNILibLoader.loadNEWT();
HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() ||
- Debug.getBooleanProperty("newt.MainThread.force", true, localACC);
+ Debug.getBooleanProperty("newt.MainThread.force", true, localACC);
+ osType = Platform.getOSType();
+ isMacOSX = osType == Platform.OSType.MACOS;
}
public static boolean useMainThread = false;
@@ -132,7 +136,7 @@ public class MainThread {
try {
Class<?> mainClass = ReflectionUtil.getClass(mainClassName, true, getClass().getClassLoader());
if(null==mainClass) {
- throw new RuntimeException(new ClassNotFoundException("MainThread couldn't find main class "+mainClassName));
+ throw new RuntimeException(new ClassNotFoundException("MainAction couldn't find main class "+mainClassName));
}
try {
mainClassMain = mainClass.getDeclaredMethod("main", new Class[] { String[].class });
@@ -151,8 +155,23 @@ public class MainThread {
if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" user app fin");
if ( useMainThread ) {
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainThread fin - stop");
- System.exit(0);
+ if(isMacOSX) {
+ try {
+ if(DEBUG) {
+ System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.0");
+ }
+ ReflectionUtil.callStaticMethod(MACOSXDisplayClassName, "stopNSApplication",
+ null, null, MainThread.class.getClassLoader());
+ if(DEBUG) {
+ System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.X");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainAction fin - System.exit(0)");
+ System.exit(0);
+ }
}
}
}
@@ -164,9 +183,6 @@ public class MainThread {
useMainThread = HINT_USE_MAIN_THREAD;
- final Platform.OSType osType = Platform.getOSType();
- final boolean isMacOSX = osType == Platform.OSType.MACOS;
-
if(DEBUG) {
System.err.println("MainThread.main(): "+cur.getName()+
", useMainThread "+ useMainThread +
diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
index 5a8bf5bf2..8104f207a 100644
--- a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
+++ b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
@@ -43,8 +43,9 @@ public class MonitorMode {
int refreshRate;
public MonitorMode(SurfaceSize surfaceSize, DimensionImmutable screenSizeMM, int refreshRate) {
- if(null==surfaceSize || refreshRate<=0) {
- throw new IllegalArgumentException("surfaceSize must be set and refreshRate greater 0");
+ // 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;
diff --git a/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java b/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
index 1f5d5dd3d..78707e7cf 100644
--- a/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
+++ b/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
@@ -43,6 +43,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import com.jogamp.common.jvm.JNILibLoaderBase;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.cache.TempJarCache;
public class NEWTJNILibLoader extends JNILibLoaderBase {
@@ -50,9 +51,10 @@ public class NEWTJNILibLoader extends JNILibLoaderBase {
public static void loadNEWT() {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
+ Platform.initSingleton();
final String libName = "newt";
if(TempJarCache.isInitialized() && null == TempJarCache.findLibrary(libName)) {
- addNativeJarLibs(NEWTJNILibLoader.class, "jogl.all", "jogl-all", new String[] { "nativewindow", "newt" } );
+ addNativeJarLibs(NEWTJNILibLoader.class, "jogl-all", new String[] { "nativewindow", "newt" } );
}
loadLibrary(libName, false);
return null;
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index fa7bafe5b..050e24b6c 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -48,18 +48,16 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
static long nextWindowHandle = 0x100; // start here - a marker
protected void createNativeImpl() {
- if(0!=getParentWindowHandle()) {
- throw new NativeWindowException("OffscreenWindow does not support window parenting");
- }
if(capsRequested.isOnscreen()) {
throw new NativeWindowException("Capabilities is onscreen");
}
- AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
- config = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, aScreen);
- if (config == null) {
+ final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, aScreen);
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
synchronized(OffscreenWindow.class) {
setWindowHandle(nextWindowHandle++);
@@ -70,6 +68,10 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
// nop
}
+ public void surfaceSizeChanged(int width, int height) {
+ sizeChanged(false, width, height, false);
+ }
+
@Override
public synchronized void destroy() {
super.destroy();
@@ -89,29 +91,30 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
}
@Override
- public void setSize(int width, int height) {
- if(!isVisible()) {
- sizeChanged(false, width, height, false);
- }
- }
- @Override
public void setPosition(int x, int y) {
// nop
}
+
@Override
public boolean setFullscreen(boolean fullscreen) {
// nop
return false;
}
-
+
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
sizeChanged(false, width, height, false);
- visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
+ visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
} else {
- shouldNotCallThis();
+ /**
+ * silently ignore:
+ FLAG_CHANGE_PARENTING
+ FLAG_CHANGE_DECORATION
+ FLAG_CHANGE_FULLSCREEN
+ FLAG_CHANGE_ALWAYSONTOP
+ */
}
- return false;
+ return true;
}
@Override
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 9c51fe973..575de6112 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -34,6 +34,21 @@
package jogamp.newt;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Iterator;
+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;
+import javax.media.nativewindow.util.SurfaceSize;
+
import com.jogamp.common.util.ArrayHashSet;
import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.newt.Display;
@@ -44,14 +59,6 @@ import com.jogamp.newt.event.ScreenModeListener;
import com.jogamp.newt.util.MonitorMode;
import com.jogamp.newt.util.ScreenModeUtil;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.util.DimensionImmutable;
-import javax.media.nativewindow.util.SurfaceSize;
-
-import java.security.*;
-import java.util.ArrayList;
-import java.util.List;
-
public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true);
@@ -61,8 +68,10 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected int hashCode;
protected AbstractGraphicsScreen aScreen;
protected int refCount; // number of Screen references by Window
- protected int width=-1, height=-1; // detected values: set using setScreenSize
- protected static int usrWidth=-1, usrHeight=-1; // property values: newt.ws.swidth and newt.ws.sheight
+ protected Point vOrigin = new Point(0, 0); // virtual top-left origin
+ protected Dimension vSize = new Dimension(0, 0); // virtual rotated screen size
+ protected static Dimension usrSize = null; // property values: newt.ws.swidth and newt.ws.sheight
+ protected static volatile boolean usrSizeQueried = false;
private static AccessControlContext localACC = AccessController.getContext();
private ArrayList<ScreenModeListener> referencedScreenModeListener = new ArrayList<ScreenModeListener>();
long t0; // creationTime
@@ -100,32 +109,36 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return (Class<? extends Screen>)screenClass;
}
- public static Screen create(Display display, final int idx) {
+ public static Screen create(Display display, int idx) {
try {
- if(usrWidth<0 || usrHeight<0) {
+ if(!usrSizeQueried) {
synchronized (Screen.class) {
- if(usrWidth<0 || usrHeight<0) {
- usrWidth = Debug.getIntProperty("newt.ws.swidth", true, localACC);
- usrHeight = Debug.getIntProperty("newt.ws.sheight", true, localACC);
- if(usrWidth>0 || usrHeight>0) {
- System.err.println("User screen size "+usrWidth+"x"+usrHeight);
+ if(!usrSizeQueried) {
+ usrSizeQueried = true;
+ final int w = Debug.getIntProperty("newt.ws.swidth", true, localACC);
+ final int h = Debug.getIntProperty("newt.ws.sheight", true, localACC);
+ if(w>0 && h>0) {
+ usrSize = new Dimension(w, h);
+ System.err.println("User screen size "+usrSize);
}
}
}
}
synchronized(screenList) {
+ Class<? extends Screen> screenClass = getScreenClass(display.getType());
+ ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
+ screen.display = (DisplayImpl) display;
+ idx = screen.validateScreenIndex(idx);
{
Screen screen0 = ScreenImpl.getLastScreenOf(display, idx, -1);
if(null != screen0) {
if(DEBUG) {
System.err.println("Screen.create() REUSE: "+screen0+" "+Display.getThreadName());
}
+ screen = null;
return screen0;
}
}
- Class<? extends Screen> screenClass = getScreenClass(display.getType());
- ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
- screen.display = (DisplayImpl) display;
screen.screen_idx = idx;
screen.fqname = (display.getFQName()+idx).intern();
screen.hashCode = screen.fqname.hashCode();
@@ -176,6 +189,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
}
initScreenModeStatus();
+ updateVirtualScreenOriginAndSize();
if(DEBUG) {
System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")");
}
@@ -208,6 +222,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public synchronized final int addReference() throws NativeWindowException {
if(DEBUG) {
System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ // Thread.dumpStack();
}
if ( 0 == refCount ) {
createNative();
@@ -220,10 +235,8 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public synchronized final int removeReference() {
if(DEBUG) {
- String msg = "Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1);
- // Throwable t = new Throwable(msg);
- // t.printStackTrace();
- System.err.println(msg);
+ System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ // Thread.dumpStack();
}
refCount--; // could become < 0, in case of manual destruction without actual creation/addReference
if(0>=refCount) {
@@ -239,19 +252,37 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected abstract void createNativeImpl();
protected abstract void closeNativeImpl();
-
+
+ /**
+ * Returns the validated screen index, which is either the passed <code>idx</code>
+ * value or <code>0</code>.
+ * <p>
+ * On big-desktops this shall return always 0.
+ * </p>
+ */
+ protected abstract int validateScreenIndex(int idx);
+
+ /**
+ * Stores the virtual origin and virtual <b>rotated</b> screen size.
+ * <p>
+ * This method is called after the ScreenMode has been set,
+ * hence you may utilize it.
+ * </p>
+ * @param virtualOrigin the store for the virtual origin
+ * @param virtualSize the store for the virtual rotated size
+ */
+ protected abstract void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize);
+
public final String getFQName() {
return fqname;
}
/**
- * Set the <b>rotated</b> ScreenSize.
- * @see com.jogamp.newt.ScreenMode#getRotatedWidth()
- * @see com.jogamp.newt.ScreenMode#getRotatedHeight()
+ * Updates the <b>rotated</b> virtual ScreenSize using the native impl.
*/
- protected void setScreenSize(int w, int h) {
- System.err.println("Detected screen size "+w+"x"+h);
- width=w; height=h;
+ protected void updateVirtualScreenOriginAndSize() {
+ getVirtualScreenOriginAndSize(vOrigin, vSize);
+ System.err.println("Detected screen origin "+vOrigin+", size "+vSize);
}
public final Display getDisplay() {
@@ -270,21 +301,15 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return null != aScreen;
}
+ public int getX() { return vOrigin.getX(); }
+ public int getY() { return vOrigin.getY(); }
- /**
- * @return the <b>rotated</b> width.
- * @see com.jogamp.newt.ScreenMode#getRotatedWidth()
- */
public final int getWidth() {
- return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
+ return (null != usrSize) ? usrSize.getWidth() : vSize.getWidth();
}
- /**
- * @return the <b>rotated</b> height
- * @see com.jogamp.newt.ScreenMode#getRotatedHeight()
- */
public final int getHeight() {
- return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
+ return (null != usrSize) ? usrSize.getHeight() : vSize.getHeight();
}
@Override
@@ -347,32 +372,29 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
try {
long t0=0, t1=0;
if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.0 "+screenMode);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.0 "+smU);
t0 = System.currentTimeMillis();
}
sms.fireScreenModeChangeNotify(smU);
if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.1 "+screenMode);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.1 "+smU);
t1 = System.currentTimeMillis();
}
success = setCurrentScreenModeImpl(smU);
- if(success) {
- setScreenSize(screenMode.getRotatedWidth(), screenMode.getRotatedHeight());
- }
if(DEBUG) {
t1 = System.currentTimeMillis() - t1;
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.0 "+screenMode+", success: "+success);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.0 "+smU+", success: "+success);
}
sms.fireScreenModeChanged(smU, success);
if(DEBUG) {
t0 = System.currentTimeMillis() - t0;
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.X "+screenMode+", success: "+success+
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.X "+smU+", success: "+success+
" - dt0 "+t0+"ms, dt1 "+t1+"ms");
}
} finally {
@@ -389,7 +411,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public void screenModeChanged(ScreenMode sm, boolean success) {
if(success) {
- setScreenSize(sm.getRotatedWidth(), sm.getRotatedHeight());
+ updateVirtualScreenOriginAndSize();
}
for(int i=0; i<referencedScreenModeListener.size(); i++) {
((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChanged(sm, success);
@@ -502,11 +524,12 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
ArrayHashSet<ScreenMode> screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx);
- if(screenModes.size()==0) {
- if(DEBUG) {
- System.err.println("ScreenImpl.initScreenModeStatus: added current (last resort, collect failed): "+currentSM);
+ screenModes.getOrAdd(currentSM);
+ if(DEBUG) {
+ int i=0;
+ for(Iterator<ScreenMode> iter=screenModes.iterator(); iter.hasNext(); i++) {
+ System.err.println(i+": "+iter.next());
}
- screenModes.getOrAdd(currentSM);
}
sms = new ScreenModeStatus(screenModes, screenModesIdx2NativeIdx);
@@ -550,9 +573,18 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
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");
+ }
+
if(screenModeIdx >= 0) {
screenModesIdx2NativeId.put(screenModeIdx, nativeId);
}
+ } 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 );
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 7df326e8e..6564857e4 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -72,6 +72,8 @@ import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
public abstract class WindowImpl implements Window, NEWTEventConsumer
{
public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
@@ -85,12 +87,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private boolean screenReferenceAdded = false;
private NativeWindow parentWindow = null;
private long parentWindowHandle = 0;
- protected AbstractGraphicsConfiguration config = null;
+ private AbstractGraphicsConfiguration config = null; // control access due to delegation
protected CapabilitiesImmutable capsRequested = null;
protected CapabilitiesChooser capabilitiesChooser = null; // default null -> default
protected boolean fullscreen = false, hasFocus = false;
protected int width = 128, height = 128; // client-area size w/o insets, default: may be overwritten by user
- protected int x = -1, y = -1; // client-area pos w/o insets, default: undefined (allow WM to choose if not set by user)
+ protected int x = 64, y = 64; // client-area pos w/o insets
+ protected boolean autoPosition = true; // default: true (allow WM to choose if not set by user)
protected Insets insets = new Insets(); // insets of decoration (if top-level && decorated)
protected int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets
@@ -108,10 +111,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private RequestFocusAction requestFocusAction = new RequestFocusAction();
private FocusRunnable focusAction = null;
+ private KeyListener keyboardFocusHandler = null;
- private Object surfaceUpdatedListenersLock = new Object();
- private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
-
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+
private Object childWindowsLock = new Object();
private ArrayList<NativeWindow> childWindows = new ArrayList<NativeWindow>();
@@ -213,6 +216,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ protected final void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg) {
+ config = cfg;
+ }
+
public static interface LifecycleHook {
/**
* Reset of internal state counter, ie totalFrames, etc.
@@ -270,8 +277,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindow.lockSurface() ) {
throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
}
- if( ( 0>x || 0>y ) && ( isUndecorated() || null != parentWindow ) ) {
- // default child/undecorated window position is 0/0, if not set by user
+ if( ( 0>x || 0>y ) && null != parentWindow ) {
+ // min. child window position is 0/0
x = 0; y = 0;
}
try {
@@ -545,7 +552,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
if( isNativeValid() ) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
adevice.lock();
try {
res = lockSurfaceImpl();
@@ -570,7 +577,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowLock.validateLocked();
if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
} finally {
@@ -613,8 +620,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return false;
}
- public AbstractGraphicsConfiguration getGraphicsConfiguration() {
- return config;
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
}
public final long getDisplayHandle() {
@@ -682,6 +689,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return screen;
}
+ protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible));
+ }
final void setVisibleActionImpl(boolean visible) {
boolean nativeWindowCreated = false;
boolean madeVisible = false;
@@ -740,8 +750,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( nativeWindowCreated || madeVisible ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
- }
-
+ }
private class VisibleAction implements Runnable {
boolean visible;
@@ -752,8 +761,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public final void run() {
setVisibleActionImpl(visible);
}
- }
-
+ }
public void setVisible(boolean visible) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow));
@@ -762,59 +770,67 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
runOnEDTIfAvail(true, new VisibleAction(visible));
}
- protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
- reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible));
+ final void setSizeActionImpl(int width, int height) {
+ boolean recreate = false;
+ windowLock.lock();
+ try {
+ int visibleAction = 0; // 1 invisible, 2 visible (create)
+ if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
+ recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible+", recreate "+recreate);
+ }
+ if(recreate) {
+ // will trigger visibleAction:=2 -> create if wasVisible
+ final boolean wasVisible = WindowImpl.this.visible;
+ screen.addReference(); // retain screen
+ destroyAction.run();
+ WindowImpl.this.visible = wasVisible;
+ }
+ if ( isNativeValid() && 0>=width*height && visible ) {
+ visibleAction=1; // invisible
+ WindowImpl.this.width = 0;
+ WindowImpl.this.height = 0;
+ } else if ( !isNativeValid() && 0<width*height && visible ) {
+ visibleAction = 2; // visible (create)
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ } else if ( isNativeValid() ) {
+ // this width/height will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible()));
+ } else {
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction);
+ }
+ switch(visibleAction) {
+ case 1: setVisibleActionImpl(false); break;
+ case 2: setVisibleActionImpl(true); break;
+ }
+ }
+ } finally {
+ if(recreate) {
+ screen.removeReference(); // bring back ref-count
+ }
+ windowLock.unlock();
+ }
}
-
- private class SetSizeActionImpl implements Runnable {
+ private class SetSizeAction implements Runnable {
int width, height;
- private SetSizeActionImpl(int w, int h) {
+ private SetSizeAction(int w, int h) {
width = w;
height = h;
}
public final void run() {
- windowLock.lock();
- try {
- int visibleAction = 0; // 1 invisible, 2 visible (create)
- if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = "Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible;
- System.err.println(msg);
- }
- if ( isNativeValid() && 0>=width*height && visible ) {
- visibleAction=1; // invisible
- WindowImpl.this.width = 0;
- WindowImpl.this.height = 0;
- } else if ( !isNativeValid() && 0<width*height && visible ) {
- visibleAction = 2; // visible (create)
- WindowImpl.this.width = width;
- WindowImpl.this.height = height;
- } else if ( isNativeValid() ) {
- // this width/height will be set by windowChanged, called by the native implementation
- reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible()));
- } else {
- WindowImpl.this.width = width;
- WindowImpl.this.height = height;
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction);
- }
- switch(visibleAction) {
- case 1: setVisibleActionImpl(false); break;
- case 2: setVisibleActionImpl(true); break;
- }
- }
- } finally {
- windowLock.unlock();
- }
+ setSizeActionImpl(width, height);
}
- }
-
+ }
public void setSize(int width, int height) {
- runOnEDTIfAvail(true, new SetSizeActionImpl(width, height));
- }
-
+ runOnEDTIfAvail(true, new SetSizeAction(width, height));
+ }
public void setTopLevelSize(int width, int height) {
setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight());
}
@@ -911,6 +927,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
runOnEDTIfAvail(true, destroyAction);
}
+ /**
+ * @param cWin child window, must not be null
+ * @param pWin parent window, may be null
+ * @return true if at least one of both window's configurations is offscreen
+ */
+ protected static boolean isOffscreenInstance(NativeWindow cWin, NativeWindow pWin) {
+ boolean ofs = false;
+ if( null != cWin.getGraphicsConfiguration() ) {
+ ofs = !cWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ }
+ if( !ofs && null != pWin && null != pWin.getGraphicsConfiguration() ) {
+ ofs |= !pWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ }
+ return ofs;
+ }
+
private class ReparentActionImpl implements Runnable, ReparentAction {
NativeWindow newParentWindow;
boolean forceDestroyCreate;
@@ -918,7 +950,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private ReparentActionImpl(NativeWindow newParentWindow, boolean forceDestroyCreate) {
this.newParentWindow = newParentWindow;
- this.forceDestroyCreate = forceDestroyCreate;
+ this.forceDestroyCreate = forceDestroyCreate | DEBUG_TEST_REPARENT_INCOMPATIBLE;
this.reparentAction = -1; // ensure it's set
}
@@ -927,10 +959,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private void setScreen(ScreenImpl newScreen) { // never null !
- WindowImpl.this.removeScreenReference();
+ removeScreenReference();
screen = newScreen;
}
-
+
public final void run() {
boolean animatorPaused = false;
if(null!=lifecycleHook) {
@@ -952,6 +984,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowLock.lock();
try {
+ if(isNativeValid()) {
+ // force recreation if offscreen, since it may become onscreen
+ forceDestroyCreate |= isOffscreenInstance(WindowImpl.this, newParentWindow);
+ }
+
wasVisible = isVisible();
Window newParentWindowNEWT = null;
@@ -962,7 +999,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
long newParentWindowHandle = 0 ;
if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE+" "+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+", "+x+"/"+y+" "+width+"x"+height);
}
if(null!=lifecycleHook) {
@@ -1013,8 +1050,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else {
reparentAction = ACTION_NATIVE_CREATION_PENDING;
}
- } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ||
- !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
+ } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
// Destroy this window, may create a new compatible Screen/Display,
// and mark it for creation.
destroy();
@@ -1045,7 +1081,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( 0 == parentWindowHandle ) {
// Already Top Window
reparentAction = ACTION_UNCHANGED;
- } else if( !isNativeValid() || DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) {
+ } else if( !isNativeValid() || forceDestroyCreate ) {
// Destroy this window and mark it for [pending] creation.
destroy();
if( 0<width*height ) {
@@ -1138,7 +1174,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW);
}
if(ok) {
- requestFocusImpl(true);
+ requestFocusInt(true);
display.dispatchMessagesNative(); // status up2date
}
}
@@ -1208,7 +1244,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
- ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
+ final ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
runOnEDTIfAvail(true, reparentAction);
return reparentAction.getStrategy();
}
@@ -1220,7 +1256,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public final CapabilitiesImmutable getChosenCapabilities() {
- return config.getNativeGraphicsConfiguration().getChosenCapabilities();
+ return getGraphicsConfiguration().getChosenCapabilities();
}
public final CapabilitiesImmutable getRequestedCapabilities() {
@@ -1385,14 +1421,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void requestFocus() {
- enqueueRequestFocus(true);
- }
-
- public final boolean hasFocus() {
- return hasFocus;
- }
-
public final InsetsImmutable getInsets() {
if(isUndecorated()) {
return Insets.getZero();
@@ -1452,7 +1480,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public Object getWrappedWindow() {
return null;
}
-
+
+ public final Window getDelegatedWindow() {
+ return this;
+ }
+
/**
* If set to true, the default value, this NEWT Window implementation will
* handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br>
@@ -1466,6 +1498,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// WindowImpl
//
+ /**
+ * Returns the non delegated {@link AbstractGraphicsConfiguration},
+ * see {@link #getGraphicsConfiguration()}. */
+ public final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
+ return config;
+ }
+
protected final long getParentWindowHandle() {
return isFullscreen() ? 0 : parentWindowHandle;
}
@@ -1487,9 +1526,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
"\n, WrappedWindow "+getWrappedWindow()+
"\n, ChildWindows "+childWindows.size());
- sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" [");
- for (int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
- sb.append(surfaceUpdatedListeners.get(i)+", ");
+ sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedHelper.size()+" [");
+ for (int i = 0; i < surfaceUpdatedHelper.size(); i++ ) {
+ sb.append(surfaceUpdatedHelper.get(i)+", ");
}
sb.append("], WindowListeners num "+windowListeners.size()+" [");
for (int i = 0; i < windowListeners.size(); i++ ) {
@@ -1503,7 +1542,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
for (int i = 0; i < keyListeners.size(); i++ ) {
sb.append(keyListeners.get(i)+", ");
}
- sb.append("] ]");
+ sb.append("], surfaceLock "+surfaceLock);
+ sb.append(", windowLock "+windowLock+"]");
return sb.toString();
}
@@ -1529,21 +1569,32 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- protected void enqueueRequestFocus(boolean wait) {
- runOnEDTIfAvail(wait, requestFocusAction);
+ public final boolean hasFocus() {
+ return hasFocus;
}
- /**
- * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
- * This allows notifying a covered window toolkit like AWT that the focus is requested,
- * hence focus traversal can be made transparent.
- */
+ public void requestFocus() {
+ requestFocus(true);
+ }
+
+ public void requestFocus(boolean wait) {
+ if(isNativeValid() && !focusAction()) {
+ runOnEDTIfAvail(wait, requestFocusAction);
+ }
+ }
+
+ /** Internal request focus on current thread */
+ private void requestFocusInt(boolean force) {
+ if(!focusAction()) {
+ requestFocusImpl(force);
+ }
+ }
+
public void setFocusAction(FocusRunnable focusAction) {
this.focusAction = focusAction;
}
-
- /** Called by native requestFocusImpl() */
- protected boolean focusAction() {
+
+ private boolean focusAction() {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.focusAction() START - "+getThreadName()+", focusAction: "+focusAction+" - windowHandle "+toHexString(getWindowHandle()));
}
@@ -1558,7 +1609,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
return res;
}
-
+
+ public void setKeyboardFocusHandler(KeyListener l) {
+ keyboardFocusHandler = l;
+ }
+
private class SetPositionActionImpl implements Runnable {
int x, y;
@@ -1590,6 +1645,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public void setPosition(int x, int y) {
+ autoPosition = false;
runOnEDTIfAvail(true, new SetPositionActionImpl(x, y));
}
@@ -1622,7 +1678,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
nfs_y = WindowImpl.this.y;
nfs_width = WindowImpl.this.width;
nfs_height = WindowImpl.this.height;
- x = 0; y = 0;
+ x = screen.getX();
+ y = screen.getY();
w = screen.getWidth();
h = screen.getHeight();
} else {
@@ -1680,7 +1737,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
display.dispatchMessagesNative(); // status up2date
WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW);
display.dispatchMessagesNative(); // status up2date
- requestFocusImpl(true);
+ requestFocusInt(true);
display.dispatchMessagesNative(); // status up2date
if(DEBUG_IMPLEMENTATION) {
@@ -1800,8 +1857,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// queue event in case window is locked, ie in operation
if( isWindowLocked() ) {
if(DEBUG_IMPLEMENTATION) {
- // System.err.println("Window.consumeEvent: queued "+e);
- // Thread.dumpStack(); // JAU
+ System.err.println("Window.consumeEvent: queued "+e);
+ // Thread.dumpStack();
}
return false;
}
@@ -1824,62 +1881,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
// SurfaceUpdatedListener Support
//
-
public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- addSurfaceUpdatedListener(-1, l);
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(l);
}
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
- throws IndexOutOfBoundsException
- {
- if(l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size();
- }
- surfaceUpdatedListeners.add(index, l);
- }
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
}
public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- if (l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners.remove(l);
- }
- }
-
- public void removeAllSurfaceUpdatedListener() {
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
- }
- }
-
- public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size()-1;
- }
- return surfaceUpdatedListeners.get(index);
- }
- }
-
- public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- synchronized(surfaceUpdatedListenersLock) {
- return (SurfaceUpdatedListener[]) surfaceUpdatedListeners.toArray();
- }
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
}
public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- synchronized(surfaceUpdatedListenersLock) {
- for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
- SurfaceUpdatedListener l = surfaceUpdatedListeners.get(i);
- l.surfaceUpdated(updater, ns, when);
- }
- }
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
}
//
@@ -1893,8 +1908,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
int x, int y, int button, int rotation) {
doMouseEvent(true, wait, eventType, modifiers, x, y, button, rotation);
}
- private void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
- int x, int y, int button, int rotation) {
+
+ protected void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
if(eventType == MouseEvent.EVENT_MOUSE_ENTERED ||
eventType == MouseEvent.EVENT_MOUSE_EXITED) {
if(eventType == MouseEvent.EVENT_MOUSE_EXITED && x==-1 && y==-1) {
@@ -2026,15 +2042,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public MouseListener[] getMouseListeners() {
- return (MouseListener[]) mouseListeners.toArray();
+ return mouseListeners.toArray(new MouseListener[mouseListeners.size()]);
}
protected void consumeMouseEvent(MouseEvent e) {
if(DEBUG_MOUSE_EVENT) {
System.err.println("consumeMouseEvent: event: "+e);
}
-
- for(int i = 0; i < mouseListeners.size(); i++ ) {
+ boolean consumed = false;
+ for(int i = 0; !consumed && i < mouseListeners.size(); i++ ) {
MouseListener l = mouseListeners.get(i);
switch(e.getEventType()) {
case MouseEvent.EVENT_MOUSE_CLICKED:
@@ -2064,13 +2080,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
default:
throw new NativeWindowException("Unexpected mouse event type " + e.getEventType());
}
+ consumed = InputEvent.consumedTag == e.getAttachment();
}
}
//
// KeyListener/Event Support
//
-
public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
}
@@ -2116,29 +2132,42 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public KeyListener[] getKeyListeners() {
- return (KeyListener[]) keyListeners.toArray();
+ return keyListeners.toArray(new KeyListener[keyListeners.size()]);
}
- protected void consumeKeyEvent(KeyEvent e) {
- if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e);
+ private final boolean propagateKeyEvent(KeyEvent e, KeyListener l) {
+ switch(e.getEventType()) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ l.keyPressed(e);
+ break;
+ 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());
}
- for(int i = 0; i < keyListeners.size(); i++ ) {
- KeyListener l = keyListeners.get(i);
- switch(e.getEventType()) {
- case KeyEvent.EVENT_KEY_PRESSED:
- l.keyPressed(e);
- break;
- 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 InputEvent.consumedTag == e.getAttachment();
+ }
+
+ protected void consumeKeyEvent(KeyEvent e) {
+ boolean consumed;
+ if(null != keyboardFocusHandler) {
+ consumed = propagateKeyEvent(e, keyboardFocusHandler);
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumed);
+ }
+ } else {
+ consumed = false;
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e);
}
}
+ for(int i = 0; !consumed && i < keyListeners.size(); i++ ) {
+ consumed = propagateKeyEvent(e, keyListeners.get(i));
+ }
}
//
@@ -2191,7 +2220,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public WindowListener[] getWindowListeners() {
- return (WindowListener[]) windowListeners.toArray();
+ return windowListeners.toArray(new WindowListener[windowListeners.size()]);
}
protected void consumeWindowEvent(WindowEvent e) {
@@ -2324,6 +2353,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
/** Triggered by implementation's WM events to update the position. */
protected void positionChanged(boolean defer, int newX, int newY) {
+ autoPosition = false;
if ( x != newX || y != newY ) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.positionChanged: ("+getThreadName()+"): (defer: "+defer+") "+x+"/"+y+" -> "+newX+"/"+newY+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
@@ -2389,8 +2419,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
* Triggered by implementation's WM events to update the content
*/
protected void windowRepaint(boolean defer, int x, int y, int width, int height) {
- x = ( 0 > x ) ? this.x : x;
- y = ( 0 > y ) ? this.y : y;
width = ( 0 >= width ) ? this.width : width;
height = ( 0 >= height ) ? this.height : height;
if(DEBUG_IMPLEMENTATION) {
diff --git a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
index aa98d3a37..2ca3d2cfd 100644
--- a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java
+++ b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
@@ -26,15 +26,19 @@
* or implied, of JogAmp Community.
*/
+package jogamp.newt.awt;
-package jogamp.newt.awt.event;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
-
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.awt.*;
+import jogamp.nativewindow.jawt.JAWTWindow;
+import jogamp.newt.Debug;
import com.jogamp.newt.NewtFactory;
-import jogamp.newt.Debug;
public class NewtFactoryAWT extends NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
@@ -51,7 +55,7 @@ public class NewtFactoryAWT extends NewtFactory {
*
* @param awtCompObject must be of type java.awt.Component
*/
- public static NativeWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) {
+ public static JAWTWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) {
if(null==awtCompObject) {
throw new NativeWindowException("Null AWT Component");
}
@@ -61,13 +65,23 @@ public class NewtFactoryAWT extends NewtFactory {
return getNativeWindow( (java.awt.Component) awtCompObject, capsRequested );
}
- public static NativeWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) {
- DefaultGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, capsRequested, capsRequested);
- NativeWindow awtNative = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ public static JAWTWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) {
+ AWTGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, null, capsRequested);
+ NativeWindow nw = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ if(! ( nw instanceof JAWTWindow ) ) {
+ throw new NativeWindowException("Not an AWT NativeWindow: "+nw);
+ }
if(DEBUG_IMPLEMENTATION) {
- System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+awtNative);
+ System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+nw);
}
- return awtNative;
+ return (JAWTWindow)nw;
+ }
+
+ public static void destroyNativeWindow(JAWTWindow jawtWindow) {
+ final AbstractGraphicsConfiguration config = jawtWindow.getGraphicsConfiguration();
+ jawtWindow.destroy();
+ config.getScreen().getDevice().close();
}
+
}
diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
index 358864547..8e9c028d4 100644
--- a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
+++ b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
@@ -28,6 +28,10 @@
package jogamp.newt.awt.event;
+import java.awt.KeyboardFocusManager;
+
+import jogamp.newt.driver.DriverUpdatePosition;
+
import com.jogamp.newt.event.awt.AWTAdapter;
import com.jogamp.newt.event.awt.AWTWindowAdapter;
@@ -54,9 +58,16 @@ public class AWTParentWindowAdapter
}
public void focusGained(java.awt.event.FocusEvent e) {
+ // forward focus to NEWT child
+ final com.jogamp.newt.Window newtChild = getNewtWindow();
+ final boolean isOnscreen = newtChild.isNativeValid() && newtChild.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("AWT: focusGained: "+ e);
+ System.err.println("AWT: focusGained: onscreen "+ isOnscreen+", "+e);
+ }
+ if(isOnscreen) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
}
+ newtChild.requestFocus(false);
}
public void focusLost(java.awt.event.FocusEvent e) {
@@ -90,7 +101,12 @@ public class AWTParentWindowAdapter
}
public void componentMoved(java.awt.event.ComponentEvent e) {
- // no propagation to NEWT child window
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentMoved: "+e);
+ }
+ if(getNewtWindow().getDelegatedWindow() instanceof DriverUpdatePosition) {
+ ((DriverUpdatePosition)getNewtWindow().getDelegatedWindow()).updatePosition();
+ }
}
public void windowActivated(java.awt.event.WindowEvent e) {
@@ -104,11 +120,11 @@ public class AWTParentWindowAdapter
public void hierarchyChanged(java.awt.event.HierarchyEvent e) {
if( null == getNewtEventListener() ) {
long bits = e.getChangeFlags();
- final java.awt.Component changed = e.getChanged();
+ final java.awt.Component changed = e.getChanged();
if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) {
final boolean showing = changed.isShowing();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed);
+ System.err.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed+", source "+e.getComponent());
}
getNewtWindow().runOnEDTIfAvail(false, new Runnable() {
public void run() {
diff --git a/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java b/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java
new file mode 100644
index 000000000..0a824e83b
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java
@@ -0,0 +1,12 @@
+package jogamp.newt.driver;
+
+/**
+ * Interface tagging driver requirement of clearing the focus.
+ * <p>
+ * Some drivers require a programmatic {@link #clearFocus()} when traversing the focus.
+ * </p>
+ */
+public interface DriverClearFocus {
+ /** Programmatic clear the focus */
+ void clearFocus();
+}
diff --git a/src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java b/src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java
new file mode 100644
index 000000000..bb846c081
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java
@@ -0,0 +1,9 @@
+package jogamp.newt.driver;
+
+/**
+ * Interface tagging driver requirement of absolute positioning, ie. depend on parent position.
+ */
+public interface DriverUpdatePosition {
+ /** Programmatic update the position */
+ void updatePosition();
+}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java b/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
index ce6a9c594..e108ed0bb 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
@@ -29,6 +29,8 @@
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;
@@ -74,6 +76,18 @@ public class AndroidScreen extends jogamp.newt.ScreenImpl {
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
//
@@ -91,7 +105,7 @@ public class AndroidScreen extends jogamp.newt.ScreenImpl {
if (ScreenMode.ROTATE_90 == nrot || ScreenMode.ROTATE_270 == nrot) {
props[offset++] = outMetrics.heightPixels;
props[offset++] = outMetrics.widthPixels;
- } else {
+ } else {
props[offset++] = outMetrics.widthPixels;
props[offset++] = outMetrics.heightPixels;
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
index 9cefa8163..6348cf19e 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
@@ -239,7 +239,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
}
// propagate data ..
- config = eglConfig;
+ setGraphicsConfiguration(eglConfig);
setWindowHandle(surfaceHandle);
Log.d(MD.TAG, "createNativeImpl X");
}
@@ -343,7 +343,9 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
surfaceHandle = 0;
surface=null;
}
- getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event
+ if(getScreen().isNativeValid()) {
+ getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event
+ }
if(0>x || 0>y) {
x = 0;
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
index bb678935a..f7c05cd45 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
@@ -27,10 +27,7 @@
*/
package jogamp.newt.driver.android;
-import javax.media.opengl.GLProfile;
-
import com.jogamp.newt.Window;
-import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import jogamp.newt.driver.android.AndroidWindow;
@@ -63,9 +60,7 @@ public class NewtBaseActivity extends Activity {
}
public void setContentView(android.view.Window androidWindow, Window newtWindow) {
- if(newtWindow instanceof GLWindow) {
- newtWindow = ((GLWindow)newtWindow).getWindow();
- }
+ newtWindow = newtWindow.getDelegatedWindow();
if(newtWindow instanceof AndroidWindow) {
this.newtWindow = (AndroidWindow)newtWindow;
this.newtWindow.setAndroidWindow(androidWindow);
@@ -103,9 +98,6 @@ public class NewtBaseActivity extends Activity {
jogamp.common.os.android.StaticContext.setContext(extActivity.getApplicationContext());
}
extActivity.getWindow();
-
- // init GLProfile
- GLProfile.initSingleton(true);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index 0729f02ab..b63e433f6 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -99,7 +99,7 @@ public class AWTCanvas extends Canvas {
if(null==awtConfig) {
throw new NativeWindowException("Error: NULL AWTGraphicsConfiguration");
}
- chosen = awtConfig.getGraphicsConfiguration();
+ chosen = awtConfig.getAWTGraphicsConfiguration();
// before native peer is valid: X11
disableBackgroundErase();
@@ -192,7 +192,7 @@ public class AWTCanvas extends Canvas {
*/
AWTGraphicsConfiguration config = chooseGraphicsConfiguration(
awtConfig.getChosenCapabilities(), awtConfig.getRequestedCapabilities(), chooser, gc.getDevice());
- final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null;
+ final GraphicsConfiguration compatible = (null!=config)?config.getAWTGraphicsConfiguration():null;
if(Window.DEBUG_IMPLEMENTATION) {
Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
e.printStackTrace();
@@ -246,7 +246,9 @@ public class AWTCanvas extends Canvas {
CapabilitiesImmutable capsRequested,
CapabilitiesChooser chooser,
GraphicsDevice device) {
- AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final AbstractGraphicsScreen aScreen = null != device ?
+ AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT):
+ AWTGraphicsScreen.createDefault();
AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
capsRequested,
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java b/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
index 64c741464..f22ec6fad 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.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
@@ -33,7 +34,6 @@
package jogamp.newt.driver.awt;
-import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.newt.NewtFactory;
import jogamp.newt.DisplayImpl;
@@ -43,7 +43,7 @@ public class AWTDisplay extends DisplayImpl {
}
protected void createNativeImpl() {
- aDevice = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(null, AbstractGraphicsDevice.DEFAULT_UNIT); // default
+ aDevice = AWTGraphicsDevice.createDefault();
}
protected void setAWTGraphicsDevice(AWTGraphicsDevice d) {
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java b/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
index 644c96391..9eed930b6 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
@@ -38,6 +38,8 @@ import java.awt.DisplayMode;
import jogamp.newt.ScreenImpl;
import javax.media.nativewindow.awt.AWTGraphicsDevice;
import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
public class AWTScreen extends ScreenImpl {
public AWTScreen() {
@@ -45,21 +47,34 @@ public class AWTScreen extends ScreenImpl {
protected void createNativeImpl() {
aScreen = new AWTGraphicsScreen((AWTGraphicsDevice)display.getGraphicsDevice());
-
- final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode();
- if(null != mode) {
- setScreenSize(mode.getWidth(), mode.getHeight());
- }
}
protected void setAWTGraphicsScreen(AWTGraphicsScreen s) {
aScreen = s;
}
- // done by AWTWindow ..
- protected void setScreenSize(int w, int h) {
- super.setScreenSize(w, h);
+ /**
+ * 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
index 9aaa82fec..e9e3ec0ba 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
@@ -36,10 +36,11 @@ package jogamp.newt.driver.awt;
import java.awt.BorderLayout;
import java.awt.Container;
-import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.Insets;
+
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.awt.AWTGraphicsDevice;
import javax.media.nativewindow.awt.AWTGraphicsScreen;
import javax.media.nativewindow.util.Point;
@@ -145,27 +146,21 @@ public class AWTWindow extends WindowImpl {
public boolean hasDeviceChanged() {
boolean res = canvas.hasDeviceChanged();
if(res) {
- config = canvas.getAWTGraphicsConfiguration();
- if (config == null) {
+ final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration();
+ if (null == cfg) {
throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this);
}
- updateDeviceData();
+ setGraphicsConfiguration(cfg);
+
+ // propagate new info ..
+ ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen());
+ ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice());
+
+ ((AWTScreen)getScreen()).updateVirtualScreenOriginAndSize();
}
return res;
}
- private void updateDeviceData() {
- // propagate new info ..
- ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)config.getScreen());
- ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)config.getScreen().getDevice());
-
- final DisplayMode mode = ((AWTGraphicsDevice)config.getScreen().getDevice()).getGraphicsDevice().getDisplayMode();
- if(null != mode) {
- ((AWTScreen)getScreen()).setScreenSize(mode.getWidth(), mode.getHeight());
- }
-
- }
-
protected void updateInsetsImpl(javax.media.nativewindow.util.Insets insets) {
Insets contInsets = container.getInsets();
insets.setLeftWidth(contInsets.left);
@@ -189,11 +184,6 @@ public class AWTWindow extends WindowImpl {
container.setVisible(0 != ( FLAG_IS_VISIBLE & flags));
}
- x=(x>=0)?x:AWTWindow.this.x;
- y=(x>=0)?y:AWTWindow.this.y;
- width=(width>0)?width:AWTWindow.this.width;
- height=(height>0)?height:AWTWindow.this.height;
-
container.setLocation(x, y);
Insets insets = container.getInsets();
container.setSize(width + insets.left + insets.right,
@@ -202,11 +192,12 @@ public class AWTWindow extends WindowImpl {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
if( 0 != ( FLAG_IS_VISIBLE & flags ) ) {
if( !hasDeviceChanged() ) {
- // oops ??
- config = canvas.getAWTGraphicsConfiguration();
- if(null == config) {
+ // 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));
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
index 0a8453701..11b8dfcf9 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
@@ -34,6 +34,8 @@
package jogamp.newt.driver.broadcom.egl;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
public class Screen extends jogamp.newt.ScreenImpl {
@@ -47,16 +49,26 @@ public class Screen extends jogamp.newt.ScreenImpl {
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
- setScreenSize(fixedWidth, fixedHeight);
}
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;
- static final int fixedHeight = 1080;
+ static final int fixedWidth = 1920; // FIXME
+ static final int fixedHeight = 1080; // FIXME
}
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
index 7df293c0d..6f66eedd3 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
@@ -35,6 +35,7 @@ package jogamp.newt.driver.broadcom.egl;
import jogamp.opengl.egl.*;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -51,13 +52,14 @@ public class Window extends jogamp.newt.WindowImpl {
if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
- // query a good configuration .. even thought we drop this one
- // and reuse the EGLUtil choosen one later.
- config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ // 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()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
setSizeImpl(getScreen().getWidth(), getScreen().getHeight());
setWindowHandle(realizeWindow(true, width, height));
@@ -139,7 +141,7 @@ public class Window extends jogamp.newt.WindowImpl {
private long realizeWindow(boolean chromaKey, int width, int height) {
if(DEBUG_IMPLEMENTATION) {
- System.err.println("BCEGL Window.realizeWindow() with: chroma "+chromaKey+", "+width+"x"+height+", "+config);
+ System.err.println("BCEGL Window.realizeWindow() with: chroma "+chromaKey+", "+width+"x"+height+", "+getGraphicsConfiguration());
}
long handle = CreateWindow(getDisplayHandle(), chromaKey, width, height);
if (0 == handle) {
@@ -152,13 +154,14 @@ public class Window extends jogamp.newt.WindowImpl {
private void windowCreated(int cfgID, int width, int height) {
this.width = width;
this.height = height;
- GLCapabilitiesImmutable capsReq = (GLCapabilitiesImmutable) config.getRequestedCapabilities();
- config = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID);
- if (config == null) {
+ 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+", "+config);
+ System.err.println("BCEGL Window.windowCreated(): "+toHexString(cfgID)+", "+width+"x"+height+", "+cfg);
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
index 26b7120a9..66ad1c691 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
@@ -33,8 +33,10 @@
package jogamp.newt.driver.intel.gdl;
-import jogamp.newt.*;
-import javax.media.nativewindow.*;
+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 {
@@ -53,6 +55,17 @@ public class Screen extends jogamp.newt.ScreenImpl {
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
//
@@ -62,7 +75,11 @@ public class Screen extends jogamp.newt.ScreenImpl {
// called by GetScreenInfo() ..
private void screenCreated(int width, int height) {
- setScreenSize(width, 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
index ab3e95e7e..873d0a0c1 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
@@ -51,14 +51,15 @@ public class Window extends jogamp.newt.WindowImpl {
if(0!=getParentWindowHandle()) {
throw new NativeWindowException("GDL Window does not support window parenting");
}
- AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
- AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
+ final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ final AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
- config = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, aScreen);
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
synchronized(Window.class) {
setWindowHandle(nextWindowHandle++); // just a marker
@@ -83,11 +84,6 @@ public class Window extends jogamp.newt.WindowImpl {
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
Screen screen = (Screen) getScreen();
- x=(x>=0)?x:this.x;
- y=(x>=0)?y:this.y;
- width=(width>0)?width:this.width;
- height=(height>0)?height:this.height;
-
if(width>screen.getWidth()) {
width=screen.getWidth();
}
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java b/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
index a11b08b5c..6b6aecb20 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
@@ -35,6 +35,8 @@ package jogamp.newt.driver.kd;
import jogamp.newt.ScreenImpl;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
public class KDScreen extends ScreenImpl {
static {
@@ -50,8 +52,22 @@ public class KDScreen extends ScreenImpl {
protected void closeNativeImpl() { }
- // elevate access to this package ..
- protected void setScreenSize(int w, int h) {
- super.setScreenSize(w, h);
+ 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/KDWindow.java b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
index 10a75a017..92f8251bc 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
@@ -55,18 +55,19 @@ public class KDWindow extends WindowImpl {
if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
- config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
- GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) cfg.getChosenCapabilities();
int[] eglAttribs = EGLGraphicsConfiguration.GLCapabilities2AttribList(eglCaps);
eglWindowHandle = CreateWindow(getDisplayHandle(), eglAttribs);
if (eglWindowHandle == 0) {
- throw new NativeWindowException("Error creating egl window: "+config);
+ throw new NativeWindowException("Error creating egl window: "+cfg);
}
setVisible0(eglWindowHandle, false);
setWindowHandle(RealizeWindow(eglWindowHandle));
@@ -145,7 +146,7 @@ public class KDWindow extends WindowImpl {
@Override
protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
if(fullscreen) {
- ((KDScreen)getScreen()).setScreenSize(width, height);
+ ((KDScreen)getScreen()).sizeChanged(width, height);
}
super.sizeChanged(defer, newWidth, newHeight, force);
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
index 527fdac6d..2ac98f255 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
@@ -72,8 +72,12 @@ public class MacDisplay extends DisplayImpl {
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
new file mode 100644
index 000000000..46625f7a9
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
@@ -0,0 +1,262 @@
+package jogamp.newt.driver.macosx;
+
+import com.jogamp.newt.event.KeyEvent;
+
+public class MacKeyUtil {
+
+ // KeyCodes (independent)
+ private static final int kVK_Return = 0x24;
+ private static final int kVK_Tab = 0x30;
+ private static final int kVK_Space = 0x31;
+ private static final int kVK_Delete = 0x33;
+ private static final int kVK_Escape = 0x35;
+ private static final int kVK_Command = 0x37;
+ private static final int kVK_Shift = 0x38;
+ private static final int kVK_CapsLock = 0x39;
+ private static final int kVK_Option = 0x3A;
+ private static final int kVK_Control = 0x3B;
+ private static final int kVK_RightShift = 0x3C;
+ private static final int kVK_RightOption = 0x3D;
+ private static final int kVK_RightControl = 0x3E;
+ private static final int kVK_Function = 0x3F;
+ private static final int kVK_F17 = 0x40;
+ private static final int kVK_VolumeUp = 0x48;
+ private static final int kVK_VolumeDown = 0x49;
+ private static final int kVK_Mute = 0x4A;
+ private static final int kVK_F18 = 0x4F;
+ private static final int kVK_F19 = 0x50;
+ private static final int kVK_F20 = 0x5A;
+ private static final int kVK_F5 = 0x60;
+ private static final int kVK_F6 = 0x61;
+ private static final int kVK_F7 = 0x62;
+ private static final int kVK_F3 = 0x63;
+ private static final int kVK_F8 = 0x64;
+ private static final int kVK_F9 = 0x65;
+ private static final int kVK_F11 = 0x67;
+ private static final int kVK_F13 = 0x69;
+ private static final int kVK_F16 = 0x6A;
+ private static final int kVK_F14 = 0x6B;
+ private static final int kVK_F10 = 0x6D;
+ private static final int kVK_F12 = 0x6F;
+ private static final int kVK_F15 = 0x71;
+ private static final int kVK_Help = 0x72;
+ private static final int kVK_Home = 0x73;
+ private static final int kVK_PageUp = 0x74;
+ private static final int kVK_ForwardDelete = 0x75;
+ private static final int kVK_F4 = 0x76;
+ private static final int kVK_End = 0x77;
+ private static final int kVK_F2 = 0x78;
+ private static final int kVK_PageDown = 0x79;
+ private static final int kVK_F1 = 0x7A;
+ private static final int kVK_LeftArrow = 0x7B;
+ private static final int kVK_RightArrow = 0x7C;
+ private static final int kVK_DownArrow = 0x7D;
+ private static final int kVK_UpArrow = 0x7E;
+
+ // Key constants handled differently on Mac OS X than other platforms
+ private static final char NSUpArrowFunctionKey = 0xF700;
+ private static final char NSDownArrowFunctionKey = 0xF701;
+ private static final char NSLeftArrowFunctionKey = 0xF702;
+ private static final char NSRightArrowFunctionKey = 0xF703;
+ private static final char NSF1FunctionKey = 0xF704;
+ private static final char NSF2FunctionKey = 0xF705;
+ private static final char NSF3FunctionKey = 0xF706;
+ private static final char NSF4FunctionKey = 0xF707;
+ private static final char NSF5FunctionKey = 0xF708;
+ private static final char NSF6FunctionKey = 0xF709;
+ private static final char NSF7FunctionKey = 0xF70A;
+ private static final char NSF8FunctionKey = 0xF70B;
+ private static final char NSF9FunctionKey = 0xF70C;
+ private static final char NSF10FunctionKey = 0xF70D;
+ private static final char NSF11FunctionKey = 0xF70E;
+ private static final char NSF12FunctionKey = 0xF70F;
+ private static final char NSF13FunctionKey = 0xF710;
+ private static final char NSF14FunctionKey = 0xF711;
+ private static final char NSF15FunctionKey = 0xF712;
+ private static final char NSF16FunctionKey = 0xF713;
+ private static final char NSF17FunctionKey = 0xF714;
+ private static final char NSF18FunctionKey = 0xF715;
+ private static final char NSF19FunctionKey = 0xF716;
+ private static final char NSF20FunctionKey = 0xF717;
+ private static final char NSF21FunctionKey = 0xF718;
+ private static final char NSF22FunctionKey = 0xF719;
+ private static final char NSF23FunctionKey = 0xF71A;
+ private static final char NSF24FunctionKey = 0xF71B;
+ private static final char NSF25FunctionKey = 0xF71C;
+ private static final char NSF26FunctionKey = 0xF71D;
+ private static final char NSF27FunctionKey = 0xF71E;
+ private static final char NSF28FunctionKey = 0xF71F;
+ private static final char NSF29FunctionKey = 0xF720;
+ private static final char NSF30FunctionKey = 0xF721;
+ private static final char NSF31FunctionKey = 0xF722;
+ private static final char NSF32FunctionKey = 0xF723;
+ private static final char NSF33FunctionKey = 0xF724;
+ private static final char NSF34FunctionKey = 0xF725;
+ private static final char NSF35FunctionKey = 0xF726;
+ private static final char NSInsertFunctionKey = 0xF727;
+ private static final char NSDeleteFunctionKey = 0xF728;
+ private static final char NSHomeFunctionKey = 0xF729;
+ private static final char NSBeginFunctionKey = 0xF72A;
+ private static final char NSEndFunctionKey = 0xF72B;
+ private static final char NSPageUpFunctionKey = 0xF72C;
+ private static final char NSPageDownFunctionKey = 0xF72D;
+ private static final char NSPrintScreenFunctionKey = 0xF72E;
+ private static final char NSScrollLockFunctionKey = 0xF72F;
+ private static final char NSPauseFunctionKey = 0xF730;
+ private static final char NSSysReqFunctionKey = 0xF731;
+ private static final char NSBreakFunctionKey = 0xF732;
+ private static final char NSResetFunctionKey = 0xF733;
+ private static final char NSStopFunctionKey = 0xF734;
+ private static final char NSMenuFunctionKey = 0xF735;
+ private static final char NSUserFunctionKey = 0xF736;
+ private static final char NSSystemFunctionKey = 0xF737;
+ private static final char NSPrintFunctionKey = 0xF738;
+ private static final char NSClearLineFunctionKey = 0xF739;
+ private static final char NSClearDisplayFunctionKey = 0xF73A;
+ private static final char NSInsertLineFunctionKey = 0xF73B;
+ private static final char NSDeleteLineFunctionKey = 0xF73C;
+ private static final char NSInsertCharFunctionKey = 0xF73D;
+ private static final char NSDeleteCharFunctionKey = 0xF73E;
+ private static final char NSPrevFunctionKey = 0xF73F;
+ private static final char NSNextFunctionKey = 0xF740;
+ private static final char NSSelectFunctionKey = 0xF741;
+ private static final char NSExecuteFunctionKey = 0xF742;
+ private static final char NSUndoFunctionKey = 0xF743;
+ private static final char NSRedoFunctionKey = 0xF744;
+ private static final char NSFindFunctionKey = 0xF745;
+ private static final char NSHelpFunctionKey = 0xF746;
+ private static final char NSModeSwitchFunctionKey = 0xF747;
+
+ static int validateKeyCode(int keyCode, char keyChar) {
+ // OS X Virtual Keycodes
+ switch(keyCode) {
+ case kVK_Return: return KeyEvent.VK_ENTER;
+ case kVK_Tab: return KeyEvent.VK_TAB;
+ case kVK_Space: return KeyEvent.VK_SPACE;
+ case kVK_Delete: return KeyEvent.VK_BACK_SPACE;
+ case kVK_Escape: return KeyEvent.VK_ESCAPE;
+ case kVK_Command: return KeyEvent.VK_ALT;
+ case kVK_Shift: return KeyEvent.VK_SHIFT;
+ case kVK_CapsLock: return KeyEvent.VK_CAPS_LOCK;
+ case kVK_Option: return KeyEvent.VK_WINDOWS;
+ case kVK_Control: return KeyEvent.VK_CONTROL;
+ case kVK_RightShift: return KeyEvent.VK_SHIFT;
+ case kVK_RightOption: return KeyEvent.VK_WINDOWS;
+ case kVK_RightControl: return KeyEvent.VK_CONTROL;
+ // case kVK_Function: return KeyEvent.VK_F;
+ case kVK_F17: return KeyEvent.VK_F17;
+ // case kVK_VolumeUp:
+ // case kVK_VolumeDown:
+ // case kVK_Mute:
+ case kVK_F18: return KeyEvent.VK_F18;
+ case kVK_F19: return KeyEvent.VK_F19;
+ case kVK_F20: return KeyEvent.VK_F20;
+ case kVK_F5: return KeyEvent.VK_F5;
+ case kVK_F6: return KeyEvent.VK_F6;
+ case kVK_F7: return KeyEvent.VK_F7;
+ case kVK_F3: return KeyEvent.VK_F3;
+ case kVK_F8: return KeyEvent.VK_F8;
+ case kVK_F9: return KeyEvent.VK_F9;
+ case kVK_F11: return KeyEvent.VK_F11;
+ case kVK_F13: return KeyEvent.VK_F13;
+ case kVK_F16: return KeyEvent.VK_F16;
+ case kVK_F14: return KeyEvent.VK_F14;
+ case kVK_F10: return KeyEvent.VK_F10;
+ case kVK_F12: return KeyEvent.VK_F12;
+ case kVK_F15: return KeyEvent.VK_F15;
+ case kVK_Help: return KeyEvent.VK_HELP;
+ case kVK_Home: return KeyEvent.VK_HOME;
+ case kVK_PageUp: return KeyEvent.VK_PAGE_UP;
+ case kVK_ForwardDelete: return KeyEvent.VK_DELETE;
+ case kVK_F4: return KeyEvent.VK_F4;
+ case kVK_End: return KeyEvent.VK_END;
+ case kVK_F2: return KeyEvent.VK_F2;
+ case kVK_PageDown: return KeyEvent.VK_PAGE_DOWN;
+ case kVK_F1: return KeyEvent.VK_F1;
+ case kVK_LeftArrow: return KeyEvent.VK_LEFT;
+ case kVK_RightArrow: return KeyEvent.VK_RIGHT;
+ case kVK_DownArrow: return KeyEvent.VK_DOWN;
+ case kVK_UpArrow: return KeyEvent.VK_UP;
+ }
+
+ if (keyChar == '\r') {
+ // Turn these into \n
+ return KeyEvent.VK_ENTER;
+ }
+
+ if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
+ switch (keyChar) {
+ case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
+ case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
+ case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
+ case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
+ case NSF1FunctionKey: return KeyEvent.VK_F1;
+ case NSF2FunctionKey: return KeyEvent.VK_F2;
+ case NSF3FunctionKey: return KeyEvent.VK_F3;
+ case NSF4FunctionKey: return KeyEvent.VK_F4;
+ case NSF5FunctionKey: return KeyEvent.VK_F5;
+ case NSF6FunctionKey: return KeyEvent.VK_F6;
+ case NSF7FunctionKey: return KeyEvent.VK_F7;
+ case NSF8FunctionKey: return KeyEvent.VK_F8;
+ case NSF9FunctionKey: return KeyEvent.VK_F9;
+ case NSF10FunctionKey: return KeyEvent.VK_F10;
+ case NSF11FunctionKey: return KeyEvent.VK_F11;
+ case NSF12FunctionKey: return KeyEvent.VK_F12;
+ case NSF13FunctionKey: return KeyEvent.VK_F13;
+ case NSF14FunctionKey: return KeyEvent.VK_F14;
+ case NSF15FunctionKey: return KeyEvent.VK_F15;
+ case NSF16FunctionKey: return KeyEvent.VK_F16;
+ case NSF17FunctionKey: return KeyEvent.VK_F17;
+ case NSF18FunctionKey: return KeyEvent.VK_F18;
+ case NSF19FunctionKey: return KeyEvent.VK_F19;
+ case NSF20FunctionKey: return KeyEvent.VK_F20;
+ case NSF21FunctionKey: return KeyEvent.VK_F21;
+ case NSF22FunctionKey: return KeyEvent.VK_F22;
+ case NSF23FunctionKey: return KeyEvent.VK_F23;
+ case NSF24FunctionKey: return KeyEvent.VK_F24;
+ case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
+ case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
+ case NSHomeFunctionKey: return KeyEvent.VK_HOME;
+ case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
+ case NSEndFunctionKey: return KeyEvent.VK_END;
+ case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
+ case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
+ case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
+ case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
+ case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
+ // Not handled:
+ // NSSysReqFunctionKey
+ // NSBreakFunctionKey
+ // NSResetFunctionKey
+ case NSStopFunctionKey: return KeyEvent.VK_STOP;
+ // Not handled:
+ // NSMenuFunctionKey
+ // NSUserFunctionKey
+ // NSSystemFunctionKey
+ // NSPrintFunctionKey
+ // NSClearLineFunctionKey
+ // NSClearDisplayFunctionKey
+ // NSInsertLineFunctionKey
+ // NSDeleteLineFunctionKey
+ // NSInsertCharFunctionKey
+ // NSDeleteCharFunctionKey
+ // NSPrevFunctionKey
+ // NSNextFunctionKey
+ // NSSelectFunctionKey
+ // NSExecuteFunctionKey
+ // NSUndoFunctionKey
+ // NSRedoFunctionKey
+ // NSFindFunctionKey
+ // NSHelpFunctionKey
+ // NSModeSwitchFunctionKey
+ default: break;
+ }
+ }
+
+ if ('a' <= keyChar && keyChar <= 'z') {
+ return KeyEvent.VK_A + ( keyChar - 'a' ) ;
+ }
+
+ return (int) keyChar; // let's hope for the best (compatibility of keyChar/keyCode's)
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java b/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
index 67a3f8e92..3204982be 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
@@ -1,5 +1,6 @@
/*
* 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
@@ -33,9 +34,16 @@
package jogamp.newt.driver.macosx;
-import com.jogamp.newt.*;
+import java.util.List;
+
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
+
import jogamp.newt.ScreenImpl;
-import javax.media.nativewindow.*;
+
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.util.ScreenModeUtil;
public class MacScreen extends ScreenImpl {
static {
@@ -47,11 +55,69 @@ public class MacScreen extends ScreenImpl {
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
- setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(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) {
+ 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(final ScreenMode screenMode) {
+ final List<ScreenMode> 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[] getScreenMode0(int screen_index, int mode_index);
+ 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
index d09ac72ba..75a3cf6d5 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -34,108 +34,24 @@
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.SurfaceChangeable;
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 {
+public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverClearFocus, DriverUpdatePosition {
- // 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;
-
- // Key constants handled differently on Mac OS X than other platforms
- private static final int NSUpArrowFunctionKey = 0xF700;
- private static final int NSDownArrowFunctionKey = 0xF701;
- private static final int NSLeftArrowFunctionKey = 0xF702;
- private static final int NSRightArrowFunctionKey = 0xF703;
- private static final int NSF1FunctionKey = 0xF704;
- private static final int NSF2FunctionKey = 0xF705;
- private static final int NSF3FunctionKey = 0xF706;
- private static final int NSF4FunctionKey = 0xF707;
- private static final int NSF5FunctionKey = 0xF708;
- private static final int NSF6FunctionKey = 0xF709;
- private static final int NSF7FunctionKey = 0xF70A;
- private static final int NSF8FunctionKey = 0xF70B;
- private static final int NSF9FunctionKey = 0xF70C;
- private static final int NSF10FunctionKey = 0xF70D;
- private static final int NSF11FunctionKey = 0xF70E;
- private static final int NSF12FunctionKey = 0xF70F;
- private static final int NSF13FunctionKey = 0xF710;
- private static final int NSF14FunctionKey = 0xF711;
- private static final int NSF15FunctionKey = 0xF712;
- private static final int NSF16FunctionKey = 0xF713;
- private static final int NSF17FunctionKey = 0xF714;
- private static final int NSF18FunctionKey = 0xF715;
- private static final int NSF19FunctionKey = 0xF716;
- private static final int NSF20FunctionKey = 0xF717;
- private static final int NSF21FunctionKey = 0xF718;
- private static final int NSF22FunctionKey = 0xF719;
- private static final int NSF23FunctionKey = 0xF71A;
- private static final int NSF24FunctionKey = 0xF71B;
- private static final int NSF25FunctionKey = 0xF71C;
- private static final int NSF26FunctionKey = 0xF71D;
- private static final int NSF27FunctionKey = 0xF71E;
- private static final int NSF28FunctionKey = 0xF71F;
- private static final int NSF29FunctionKey = 0xF720;
- private static final int NSF30FunctionKey = 0xF721;
- private static final int NSF31FunctionKey = 0xF722;
- private static final int NSF32FunctionKey = 0xF723;
- private static final int NSF33FunctionKey = 0xF724;
- private static final int NSF34FunctionKey = 0xF725;
- private static final int NSF35FunctionKey = 0xF726;
- private static final int NSInsertFunctionKey = 0xF727;
- private static final int NSDeleteFunctionKey = 0xF728;
- private static final int NSHomeFunctionKey = 0xF729;
- private static final int NSBeginFunctionKey = 0xF72A;
- private static final int NSEndFunctionKey = 0xF72B;
- private static final int NSPageUpFunctionKey = 0xF72C;
- private static final int NSPageDownFunctionKey = 0xF72D;
- private static final int NSPrintScreenFunctionKey = 0xF72E;
- private static final int NSScrollLockFunctionKey = 0xF72F;
- private static final int NSPauseFunctionKey = 0xF730;
- private static final int NSSysReqFunctionKey = 0xF731;
- private static final int NSBreakFunctionKey = 0xF732;
- private static final int NSResetFunctionKey = 0xF733;
- private static final int NSStopFunctionKey = 0xF734;
- private static final int NSMenuFunctionKey = 0xF735;
- private static final int NSUserFunctionKey = 0xF736;
- private static final int NSSystemFunctionKey = 0xF737;
- private static final int NSPrintFunctionKey = 0xF738;
- private static final int NSClearLineFunctionKey = 0xF739;
- private static final int NSClearDisplayFunctionKey = 0xF73A;
- private static final int NSInsertLineFunctionKey = 0xF73B;
- private static final int NSDeleteLineFunctionKey = 0xF73C;
- private static final int NSInsertCharFunctionKey = 0xF73D;
- private static final int NSDeleteCharFunctionKey = 0xF73E;
- private static final int NSPrevFunctionKey = 0xF73F;
- private static final int NSNextFunctionKey = 0xF740;
- private static final int NSSelectFunctionKey = 0xF741;
- private static final int NSExecuteFunctionKey = 0xF742;
- private static final int NSUndoFunctionKey = 0xF743;
- private static final int NSRedoFunctionKey = 0xF744;
- private static final int NSFindFunctionKey = 0xF745;
- private static final int NSHelpFunctionKey = 0xF746;
- private static final int NSModeSwitchFunctionKey = 0xF747;
-
- private volatile long surfaceHandle;
-
static {
MacDisplay.initSingleton();
}
@@ -143,18 +59,21 @@ public class MacWindow extends WindowImpl {
public MacWindow() {
}
+ @Override
protected void createNativeImpl() {
- config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
reconfigureWindowImpl(x, y, width, height, 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()); }
@@ -168,81 +87,158 @@ public class MacWindow extends WindowImpl {
}
} finally {
setWindowHandle(0);
+ surfaceHandle = 0;
+ sscSurfaceHandle = 0;
+ isOffscreenInstance = false;
}
}
@Override
protected int lockSurfaceImpl() {
- return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
+ if(!isOffscreenInstance) {
+ return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
+ }
+ return LOCK_SUCCESS;
}
@Override
protected void unlockSurfaceImpl() {
- unlockSurface0(getWindowHandle());
+ if(!isOffscreenInstance) {
+ unlockSurface0(getWindowHandle());
+ }
}
@Override
public final long getSurfaceHandle() {
- return surfaceHandle;
+ 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() );
+ } */
+ }
}
+ public void surfaceSizeChanged(int width, int height) {
+ sizeChanged(false, width, height, false);
+ }
+
@Override
protected void setTitleImpl(final String title) {
setTitle0(getWindowHandle(), title);
}
protected void requestFocusImpl(boolean force) {
- requestFocus0(getWindowHandle(), 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) {
+ requestFocusParent0(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 PointImmutable pS = position2TopLevel(new Point(x, y));
+ 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+", "+
- getReconfigureFlagsAsString(null, flags));
+ System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+
+ ", offscreenInstance "+isOffscreenInstance+
+ ", "+getReconfigureFlagsAsString(null, flags));
}
- if( getWindowHandle() == 0 ) {
- if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
- createWindow(false, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- // no native event ..
- visibleChanged(true, true);
- } /* else { ?? } */
- } else {
- if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
+ if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
+ if ( !isOffscreenInstance ) {
orderOut0(getWindowHandle());
- // no native event ..
- visibleChanged(true, false);
- }
- if( 0 != ( FLAG_CHANGE_DECORATION & flags) ||
- 0 != ( FLAG_CHANGE_PARENTING & flags) ||
- 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
- createWindow(true, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; }
- }
- if(x>=0 && y>=0) {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
- // no native event (fullscreen, some reparenting)
- positionChanged(true, getLocationOnScreenImpl(0, 0)); // incl. validation
}
- if(width>0 && height>0) {
+ // 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);
- // 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) ) {
+ } // 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);
- }
+ }
+ // no native event ..
+ visibleChanged(true, true);
+ }
+ if( !isOffscreenInstance ) {
setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
}
return true;
}
protected Point getLocationOnScreenImpl(int x, int y) {
- return (Point) getLocationOnScreen0(getWindowHandle(), x, 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) {
@@ -252,138 +248,76 @@ public class MacWindow extends WindowImpl {
@Override
protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
if(width != newWidth || height != newHeight) {
- final Point p0S = position2TopLevel(new Point(x, y));
+ final Point p0S = getTopLevelLocationOnScreen(x, y);
setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), p0S.getX(), p0S.getY());
}
super.sizeChanged(defer, newWidth, newHeight, force);
}
@Override
- protected void positionChanged(boolean defer, int newX, int newY) {
- positionChanged(defer, new Point(newX, newY));
+ 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) {
- return setPointerVisible0(getWindowHandle(), pointerVisible);
+ if( !isOffscreenInstance ) {
+ return setPointerVisible0(getWindowHandle(), pointerVisible);
+ } // else may need offscreen solution ? FIXME
+ return false;
}
@Override
protected boolean confinePointerImpl(final boolean confine) {
- return confinePointer0(getWindowHandle(), 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) {
- warpPointer0(getWindowHandle(), x, 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) {
- final int key = convertKeyChar(keyChar);
- if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName());
// 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
- super.sendKeyEvent(eventType, modifiers, key, keyChar);
+ final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
+ 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));
+ // 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) {
- final int key = convertKeyChar(keyChar);
- if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName());
// 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
- super.enqueueKeyEvent(wait, eventType, modifiers, key, keyChar);
+ final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
+ 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));
+ // 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);
}
//----------------------------------------------------------------------
// Internals only
//
- private char convertKeyChar(char keyChar) {
- if (keyChar == '\r') {
- // Turn these into \n
- return '\n';
- }
-
- if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
- switch (keyChar) {
- case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
- case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
- case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
- case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
- case NSF1FunctionKey: return KeyEvent.VK_F1;
- case NSF2FunctionKey: return KeyEvent.VK_F2;
- case NSF3FunctionKey: return KeyEvent.VK_F3;
- case NSF4FunctionKey: return KeyEvent.VK_F4;
- case NSF5FunctionKey: return KeyEvent.VK_F5;
- case NSF6FunctionKey: return KeyEvent.VK_F6;
- case NSF7FunctionKey: return KeyEvent.VK_F7;
- case NSF8FunctionKey: return KeyEvent.VK_F8;
- case NSF9FunctionKey: return KeyEvent.VK_F9;
- case NSF10FunctionKey: return KeyEvent.VK_F10;
- case NSF11FunctionKey: return KeyEvent.VK_F11;
- case NSF12FunctionKey: return KeyEvent.VK_F12;
- case NSF13FunctionKey: return KeyEvent.VK_F13;
- case NSF14FunctionKey: return KeyEvent.VK_F14;
- case NSF15FunctionKey: return KeyEvent.VK_F15;
- case NSF16FunctionKey: return KeyEvent.VK_F16;
- case NSF17FunctionKey: return KeyEvent.VK_F17;
- case NSF18FunctionKey: return KeyEvent.VK_F18;
- case NSF19FunctionKey: return KeyEvent.VK_F19;
- case NSF20FunctionKey: return KeyEvent.VK_F20;
- case NSF21FunctionKey: return KeyEvent.VK_F21;
- case NSF22FunctionKey: return KeyEvent.VK_F22;
- case NSF23FunctionKey: return KeyEvent.VK_F23;
- case NSF24FunctionKey: return KeyEvent.VK_F24;
- case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
- case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
- case NSHomeFunctionKey: return KeyEvent.VK_HOME;
- case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
- case NSEndFunctionKey: return KeyEvent.VK_END;
- case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
- case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
- case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
- case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
- case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
- // Not handled:
- // NSSysReqFunctionKey
- // NSBreakFunctionKey
- // NSResetFunctionKey
- case NSStopFunctionKey: return KeyEvent.VK_STOP;
- // Not handled:
- // NSMenuFunctionKey
- // NSUserFunctionKey
- // NSSystemFunctionKey
- // NSPrintFunctionKey
- // NSClearLineFunctionKey
- // NSClearDisplayFunctionKey
- // NSInsertLineFunctionKey
- // NSDeleteLineFunctionKey
- // NSInsertCharFunctionKey
- // NSDeleteCharFunctionKey
- // NSPrevFunctionKey
- // NSNextFunctionKey
- // NSSelectFunctionKey
- // NSExecuteFunctionKey
- // NSUndoFunctionKey
- // NSRedoFunctionKey
- // NSFindFunctionKey
- // NSHelpFunctionKey
- // NSModeSwitchFunctionKey
- default: break;
- }
- }
-
- // NSEvent's charactersIgnoringModifiers doesn't ignore the shift key
- if (keyChar >= 'a' && keyChar <= 'z') {
- return Character.toUpperCase(keyChar);
- }
-
- return keyChar;
- }
-
- private void createWindow(final boolean recreate,
+ private void createWindow(final boolean offscreenInstance, final boolean recreate,
final PointImmutable pS, final int width, final int height,
final boolean fullscreen) {
@@ -406,59 +340,27 @@ public class MacWindow extends WindowImpl {
}
setWindowHandle(createWindow0(getParentWindowHandle(),
pS.getX(), pS.getY(), width, height,
- config.getChosenCapabilities().isBackgroundOpaque(),
+ (getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance),
fullscreen,
- (isUndecorated() ?
- NSBorderlessWindowMask :
- NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
+ ((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());
- setTitle0(getWindowHandle(), getTitle());
- // need to revalidate real position
- positionChanged(true, getLocationOnScreenImpl(0, 0)); // incl. validation
+ if( offscreenInstance ) {
+ orderOut0(0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle());
+ } else {
+ setTitle0(getWindowHandle(), getTitle());
+ }
} catch (Exception ie) {
ie.printStackTrace();
}
}
- private void positionChanged(boolean defer, Point absPos) {
- if(getWindowHandle()!=0) {
- position2ClientSpace(absPos);
- super.positionChanged(defer, absPos.getX(), absPos.getY());
- }
- }
-
- private Point position2ClientSpace(Point absPos) {
- final NativeWindow parent = getParent();
- if(null != parent) {
- return absPos.translate( parent.getLocationOnScreen(null).scale(-1, -1) );
- }
- return absPos;
- }
-
- private Point position2TopLevel(Point clientPos) {
- if(0<=clientPos.getX() && 0<=clientPos.getY()) {
- final InsetsImmutable _insets = getInsets(); // zero if undecorated
- // client position -> top-level window position
- clientPos.setX(clientPos.getX() - _insets.getLeftWidth()) ;
- clientPos.setY(clientPos.getY() - _insets.getTopHeight()) ;
- }
- // min val is 0
- clientPos.setX(Math.max(clientPos.getX(), 0));
- clientPos.setY(Math.max(clientPos.getY(), 0));
- // On MacOSX the absolute position is required to position
- // a window - even a child window!
- final NativeWindow parent = getParent();
- if( null != parent && 0 != parent.getWindowHandle() ) {
- clientPos.translate(parent.getLocationOnScreen(null));
- }
- return clientPos;
- }
-
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,
@@ -467,6 +369,7 @@ public class MacWindow extends WindowImpl {
private native boolean lockSurface0(long window);
private native void unlockSurface0(long window);
private native void requestFocus0(long window, boolean force);
+ private native void requestFocusParent0(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);
@@ -481,4 +384,21 @@ public class MacWindow extends WindowImpl {
private static native boolean setPointerVisible0(long windowHandle, 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/WindowsScreen.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
index f2e457a0f..f8bce9da3 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.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
@@ -32,17 +33,15 @@
*/
package jogamp.newt.driver.windows;
-import com.jogamp.common.util.ArrayHashSet;
-import java.util.ArrayList;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
-import com.jogamp.newt.*;
import jogamp.newt.ScreenImpl;
+
import com.jogamp.newt.ScreenMode;
-import jogamp.newt.ScreenModeStatus;
import com.jogamp.newt.util.ScreenModeUtil;
-import javax.media.nativewindow.*;
-
public class WindowsScreen extends ScreenImpl {
static {
@@ -54,9 +53,8 @@ public class WindowsScreen extends ScreenImpl {
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
- setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
}
-
+
protected void closeNativeImpl() {
}
@@ -104,9 +102,21 @@ public class WindowsScreen extends ScreenImpl {
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);
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
index cd5909d42..ff3bd5ef6 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
@@ -35,13 +35,17 @@
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.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;
@@ -100,17 +104,18 @@ public class WindowsWindow extends WindowImpl {
}
protected void createNativeImpl() {
- WindowsScreen screen = (WindowsScreen) getScreen();
- WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
- config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(
+ final WindowsScreen screen = (WindowsScreen) getScreen();
+ final WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
- if (config == null) {
+ 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(), x, y, width, height, flags));
+ getParentWindowHandle(), x, y, width, height, autoPosition, flags));
if (getWindowHandle() == 0) {
throw new NativeWindowException("Error creating window");
}
@@ -169,12 +174,8 @@ public class WindowsWindow extends WindowImpl {
final InsetsImmutable i = getInsets();
// client position -> top-level window position
- if(0<=x && 0<=y) {
- x -= i.getLeftWidth() ;
- y -= i.getTopHeight() ;
- if( 0 > x ) { x = 0; }
- if( 0 > y ) { y = 0; }
- }
+ x -= i.getLeftWidth() ;
+ y -= i.getTopHeight() ;
if(0<width && 0<height) {
// client size -> top-level window size
@@ -237,13 +238,43 @@ public class WindowsWindow extends WindowImpl {
}
protected Point getLocationOnScreenImpl(int x, int y) {
- return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, 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
//
@@ -252,7 +283,7 @@ public class WindowsWindow extends WindowImpl {
private native long CreateWindow0(long hInstance, String wndClassName, String wndName,
long parentWindowHandle,
- int x, int y, int width, int height, int flags);
+ 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);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java b/src/newt/classes/jogamp/newt/driver/x11/X11Display.java
index b9a32c7de..b3bc6e475 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Display.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
@@ -33,10 +34,14 @@
package jogamp.newt.driver.x11;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
-import jogamp.newt.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
+
import jogamp.nativewindow.x11.X11Util;
+import jogamp.newt.DisplayImpl;
+import jogamp.newt.NEWTJNILibLoader;
public class X11Display extends DisplayImpl {
@@ -64,6 +69,20 @@ public class X11Display extends DisplayImpl {
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.
+ * <p>
+ * 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.
+ * </p>
+ * <p>
+ * 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)}.
+ * </p>
+ */
+ @SuppressWarnings("unused")
protected void createNativeImpl() {
long handle = X11Util.openDisplay(name);
if( 0 == handle ) {
@@ -85,12 +104,11 @@ public class X11Display extends DisplayImpl {
throw e;
}
- if(X11Util.XINITTHREADS_ALWAYS_ENABLED) {
- // Hack: Force non X11Display locking, even w/ AWT and w/o isFirstUIActionOnProcess()
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock());
+ // see API doc above!
+ if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) {
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false);
} else {
- // Proper: Use AWT/X11Display locking w/ AWT and X11Display locking only w/o isFirstUIActionOnProcess()
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT);
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
index 5c9c326d7..ed5ebc04e 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.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
@@ -32,6 +33,8 @@
*/
package jogamp.newt.driver.x11;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.ScreenImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
@@ -40,6 +43,8 @@ import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.util.ScreenModeUtil;
import java.util.List;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.x11.*;
public class X11Screen extends ScreenImpl {
@@ -55,11 +60,7 @@ public class X11Screen extends ScreenImpl {
// validate screen index
Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Long>() {
public Long run(long dpy) {
- long handle = GetScreen0(dpy, screen_idx);
- if(0 != handle) {
- setScreenSize(getWidth0(dpy, screen_idx), getHeight0(dpy, screen_idx));
- }
- return new Long(handle);
+ return new Long(GetScreen0(dpy, screen_idx));
} } );
if (handle.longValue() == 0) {
throw new RuntimeException("Error creating screen: " + screen_idx);
@@ -245,35 +246,64 @@ public class X11Screen extends ScreenImpl {
}
}).booleanValue();
- if(DEBUG && done) {
+ if(DEBUG || !done) {
System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
- (System.currentTimeMillis()-t0)+"ms");
+ (System.currentTimeMillis()-t0)+"ms; Current: "+getCurrentScreenMode()+"; Desired: "+screenMode);
}
return done;
}
+ private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable<Boolean> {
+ public Boolean run(long dpy) {
+ return new Boolean(X11Lib.XineramaEnabled(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<Object>() {
+ 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> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
return display.runWithLockedDisplayHandle(action);
// return runWithTempDisplayHandle(action);
+ // return runWithoutLock(action);
}
- /** just here for testing some X11 RANDR bugs .. etc ..
- private final Object runWithTempDisplayHandle(DisplayRunnable action) {
- long dpy = X11Util.openDisplay(null);
- if(0 == dpy) {
+ private final <T> T runWithTempDisplayHandle(DisplayRunnable<T> action) {
+ final long displayHandle = X11Util.openDisplay(display.getName());
+ if(0 == displayHandle) {
throw new RuntimeException("null device");
}
- Object res;
+ T res;
try {
- res = action.run(dpy);
+ res = action.run(displayHandle);
} finally {
- X11Util.closeDisplay(dpy);
+ X11Util.closeDisplay(displayHandle);
}
return res;
- } */
+ }
+ private final <T> T runWithoutLock(DisplayRunnable<T> 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/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
index 2b6bac215..33b541c34 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Window.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
@@ -33,7 +34,7 @@
package jogamp.newt.driver.x11;
-import jogamp.nativewindow.x11.X11Util;
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.newt.DisplayImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.WindowImpl;
@@ -43,9 +44,15 @@ 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();
}
@@ -57,22 +64,22 @@ public class X11Window extends WindowImpl {
final X11Screen screen = (X11Screen) getScreen();
final X11Display display = (X11Display) screen.getDisplay();
final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice());
- config = factory.chooseGraphicsConfiguration(
+ final X11GraphicsConfiguration cfg = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
if(DEBUG_IMPLEMENTATION) {
- System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+config);
+ System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
}
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
- X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config;
- final long visualID = x11config.getVisualID();
+ setGraphicsConfiguration(cfg);
+ final long visualID = cfg.getVisualID();
final int flags = getReconfigureFlags(0, true) &
( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
setWindowHandle(CreateWindow0(getParentWindowHandle(),
display.getEDTHandle(), screen.getIndex(), visualID,
display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
- x, y, width, height, flags));
+ x, y, width, height, autoPosition, flags));
windowHandleClose = getWindowHandle();
if (0 == windowHandleClose) {
throw new NativeWindowException("Error creating window");
@@ -101,14 +108,12 @@ public class X11Window extends WindowImpl {
System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
getReconfigureFlagsAsString(null, flags));
}
- if(0 == ( FLAG_IS_UNDECORATED & flags) && 0<=x && 0<=y) {
+ if(0 == ( FLAG_IS_UNDECORATED & flags)) {
final InsetsImmutable i = getInsets();
// client position -> top-level window position
x -= i.getLeftWidth() ;
y -= i.getTopHeight() ;
- if( 0 > x ) { x = 0; }
- if( 0 > y ) { y = 0; }
}
reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), getParentWindowHandle(), getWindowHandle(),
x, y, width, height, flags);
@@ -167,13 +172,55 @@ public class X11Window extends WindowImpl {
protected Point getLocationOnScreenImpl(final int x, final int y) {
// X11Util.GetRelativeLocation: locks display already !
- return X11Util.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ 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
//
@@ -190,7 +237,7 @@ public class X11Window extends WindowImpl {
private native long CreateWindow0(long parentWindowHandle, long display, int screen_index,
long visualID, long javaObjectAtom, long windowDeleteAtom,
- int x, int y, int width, int height, int flags);
+ 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,
int x, int y, int width, int height, int flags);
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 5f1affed1..e6bc7952e 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -256,7 +256,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_RealizeWindow
jint res = kdRealizeWindow(w, &nativeWindow);
if(res) {
fprintf(stderr, "[RealizeWindow] failed: 0x%X, 0x%X\n", res, kdGetError());
- nativeWindow = NULL;
+ nativeWindow = 0;
}
DBG_PRINT( "[RealizeWindow] ok: %p\n", nativeWindow);
return (jlong) (intptr_t) nativeWindow;
diff --git a/src/newt/native/KeyEvent.h b/src/newt/native/KeyEvent.h
index 1ead0f5e8..0f7b1606b 100644
--- a/src/newt/native/KeyEvent.h
+++ b/src/newt/native/KeyEvent.h
@@ -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.
+ */
#ifndef _KEY_EVENT_H_
#define _KEY_EVENT_H_
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index a13ffaf31..ddd59f0a1 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -38,6 +38,7 @@
#import "MouseEvent.h"
#import "KeyEvent.h"
+#import "ScreenMode.h"
#import <ApplicationServices/ApplicationServices.h>
@@ -48,7 +49,6 @@ static const char * const ClazzAnyCstrName = "<init>";
static const char * const ClazzNamePointCstrSignature = "(II)V";
static jclass pointClz = NULL;
static jmethodID pointCstr = NULL;
-static jmethodID focusActionID = NULL;
static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
{
@@ -192,13 +192,57 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSAppli
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplication0
(JNIEnv *env, jclass clazz)
{
- // NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
DBG_PRINT( "\nrunNSApplication0.0\n");
[NSApp run];
DBG_PRINT( "\nrunNSApplication0.X\n");
- // [pool release];
+ [pool release];
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacDisplay
+ * Method: stopNSApplication0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_stopNSApplication0
+ (JNIEnv *env, jclass clazz)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT( "\nstopNSApplication0.0 nsApp.running %d\n", (NSApp && [NSApp isRunning]));
+
+ if(NSApp && [NSApp isRunning]) {
+ [NSApp performSelectorOnMainThread:@selector(stop:) withObject:nil waitUntilDone:YES];
+ // [NSApp stop: nil];
+ NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
+ location: NSMakePoint(0,0)
+ modifierFlags: 0
+ timestamp: 0.0
+ windowNumber: 0
+ context: nil
+ subtype: 0
+ data1: 0
+ data2: 0];
+ DBG_PRINT( "\nstopNSApplication0.1\n");
+ [NSApp postEvent: event atStart: true];
+ }
+ /**
+ DBG_PRINT( "\nstopNSApplication0.2\n");
+ if(NSApp && [NSApp isRunning]) {
+ DBG_PRINT( "\nstopNSApplication0.3\n");
+ [NSApp terminate:nil];
+ } */
+
+ DBG_PRINT( "\nstopNSApplication0.X\n");
+ [pool release];
+}
+
+static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
+ NSArray *screens = [NSScreen screens];
+ if(screen_idx<0) screen_idx=0;
+ if(screen_idx>=[screens count]) screen_idx=0;
+ return (NSScreen *) [screens objectAtIndex: screen_idx];
}
/*
@@ -211,10 +255,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
NSRect rect = [screen frame];
[pool release];
@@ -232,10 +273,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
NSRect rect = [screen frame];
[pool release];
@@ -243,6 +281,175 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
return (jint) (rect.size.height);
}
+static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
+ // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
+ NSDictionary * dict = [screen deviceDescription];
+ NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
+ // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
+ return (CGDirectDisplayID) [val integerValue];
+}
+
+/**
+ * Only in >= 10.6:
+ * CGDisplayModeGetWidth(mode)
+ * CGDisplayModeGetRefreshRate(mode)
+ * CGDisplayModeGetHeight(mode)
+ */
+static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
+{
+ long value = 0;
+ CFNumberRef numRef;
+ numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
+ if (numRef != NULL)
+ CFNumberGetValue(numRef, kCFNumberLongType, &value);
+ return value;
+}
+#define CGDDGetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth)
+#define CGDDGetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight)
+#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
+#define CGDDGetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel)
+
+// Duplicate each Mode by all possible rotations (4):
+// For each real-mode: [mode, 0], [mode, 90], [mode, 180], [mode, 270]
+#define ROTMODES_PER_REALMODE 4
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacScreen
+ * Method: getScreenMode0
+ * Signature: (II)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMode0
+ (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL;
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+
+ CFArrayRef availableModes = CGDisplayAvailableModes(display);
+ CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
+ CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
+ CFDictionaryRef mode = NULL;
+ int currentCCWRot = (int)CGDisplayRotation(display);
+ jint ccwRot = 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);
+ }
+#endif
+
+ if(numberOfAvailableModesRots<=mode_idx) {
+ // n/a - end of modes
+ 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);
+ } 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);
+ ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
+ } else {
+ // current mode
+ mode = CGDisplayCurrentMode(display);
+ ccwRot = currentCCWRot;
+ }
+ // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
+
+ CGSize screenDim = CGDisplayScreenSize(display);
+ int mWidth = CGDDGetModeWidth(mode);
+ int mHeight = CGDDGetModeHeight(mode);
+
+ // swap width and height, since OSX reflects rotated dimension, we don't
+ if ( 90 == currentCCWRot || 270 == currentCCWRot ) {
+ int tempWidth = mWidth;
+ mWidth = mHeight;
+ mHeight = tempWidth;
+ }
+
+ jint prop[ prop_num ];
+ int propIndex = 0;
+ int propIndexRes = 0;
+
+ if( -1 < mode_idx ) {
+ prop[propIndex++] = mode_idx;
+ }
+ prop[propIndex++] = 0; // set later for verification of iterator
+ propIndexRes = propIndex;
+ prop[propIndex++] = mWidth;
+ prop[propIndex++] = mHeight;
+ prop[propIndex++] = CGDDGetModeBitsPerPixel(mode);
+ prop[propIndex++] = (jint) screenDim.width;
+ prop[propIndex++] = (jint) screenDim.height;
+ prop[propIndex++] = CGDDGetModeRefreshRate(mode);
+ 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 Hz, 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], (int)prop[propIndexRes+6]);
+
+ jintArray properties = (*env)->NewIntArray(env, prop_num);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num);
+ }
+ (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop);
+
+ // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
+ [pool release];
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacScreen
+ * Method: setScreenMode0
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMode0
+ (JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx)
+{
+ jboolean res = JNI_TRUE;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+
+ CFArrayRef availableModes = CGDisplayAvailableModes(display);
+ CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
+ CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
+
+ 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);
+
+ if(ccwRot!=0) {
+ // 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;
+ }
+ if(JNI_TRUE == res) {
+ CGError err = CGDisplaySwitchToMode(display, mode);
+ if(kCGErrorSuccess != err) {
+ DBG_PRINT( "setScreenMode0: SetMode failed: %d\n", (int)err);
+ res = JNI_FALSE;
+ }
+ }
+
+ // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
+ [pool release];
+
+ return res;
+}
+
/*
* Class: jogamp_newt_driver_macosx_MacWindow
* Method: initIDs
@@ -272,11 +479,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
- if(NULL==focusActionID) {
- NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch method focusAction()Z");
- }
-
// Need this when debugging, as it is necessary to attach gdb to
// the running java process -- "gdb java" doesn't work
// printf("Going to sleep for 10 seconds\n");
@@ -449,8 +651,9 @@ NS_DURING
if([mView isInFullScreenMode]) {
[mView exitFullScreenModeWithOptions: NULL];
}
- [mWin setContentView: nil];
- [mView release];
+ // Note: mWin's release will also release it's mView!
+ // [mWin setContentView: nil];
+ // [mView release];
}
NS_HANDLER
NS_ENDHANDLER
@@ -463,7 +666,11 @@ NS_ENDHANDLER
DBG_PRINT( "windowClose.1 - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
- [mWin close]; // performs release!
+ // '[mWin close]' causes a crash at exit.
+ // This probably happens b/c it sends events to the main loop
+ // but our resources are gone ?!
+ // However, issuing a simple release seems to work quite well.
+ [mWin release];
DBG_PRINT( "windowClose.X - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
@@ -510,26 +717,44 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
(JNIEnv *env, jobject window, jlong w, jboolean force)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) w);
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
#ifdef VERBOSE_ON
- BOOL hasFocus = [win isKeyWindow];
+ BOOL hasFocus = [mWin isKeyWindow];
#endif
- DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", win, force, hasFocus);
-
- // Even if we already own the focus, we need the 'focusAction()' call
- // and the other probably redundant NS calls to force proper focus traversal
- // of the parent TK (AWT doesn't do it properly on OSX).
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "makeKeyWindow win %p\n", win);
- // [win performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
- // [win performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
- [win orderFrontRegardless];
- [win makeKeyWindow];
- [win makeFirstResponder: nil];
- }
+ DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
+
+ [mWin makeFirstResponder: nil];
+ // [mWin performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
+ // [mWin performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
+ [mWin orderFrontRegardless];
+ [mWin makeKeyWindow];
+
+ DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force);
+
+ [pool release];
+}
- DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", win, force);
+/*
+ * Class: jogamp_newt_driver_macosx_MacWindow
+ * Method: requestFocusParent0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocusParent0
+ (JNIEnv *env, jobject window, jlong w)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ NSWindow* pWin = [mWin parentWindow];
+#ifdef VERBOSE_ON
+ BOOL hasFocus = [mWin isKeyWindow];
+#endif
+
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
+ if(NULL != pWin) {
+ [pWin makeKeyWindow];
+ }
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p (END)\n", mWin, pWin);
[pool release];
}
diff --git a/src/newt/native/MouseEvent.h b/src/newt/native/MouseEvent.h
index e9c0476ef..59d63cecf 100644
--- a/src/newt/native/MouseEvent.h
+++ b/src/newt/native/MouseEvent.h
@@ -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.
+ */
#ifndef _MOUSE_EVENT_H_
#define _MOUSE_EVENT_H_
diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index 91fceb310..33aba64ae 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -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.
+ */
#ifndef NEWT_COMMON_H
#define NEWT_COMMON_H 1
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index cb256e71f..3ba89de1e 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 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
@@ -40,7 +41,8 @@
// #define VERBOSE_ON 1
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
#else
#define DBG_PRINT(...)
#endif
@@ -53,8 +55,8 @@
JavaVM *jvmHandle;
int jvmVersion;
- BOOL destroyNotifySent;
- BOOL softLocked;
+ volatile BOOL destroyNotifySent;
+ volatile BOOL softLocked;
pthread_mutex_t softLockSync;
NSTrackingRectTag ptrTrackingTag;
@@ -88,7 +90,7 @@
- (BOOL) needsDisplay;
- (void) displayIfNeeded;
-- (void) viewWillDraw;
+- (void) display;
- (void) drawRect:(NSRect)dirtyRect;
- (void) viewDidHide;
- (void) viewDidUnhide;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 1f74742ec..ce41673c4 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -44,15 +44,17 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
// mouse pad case
deltaY =
CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
+ // fprintf(stderr, "WHEEL/PAD: %lf\n", (double)deltaY);
} else {
// traditional mouse wheel case
deltaY = [event deltaY];
+ // fprintf(stderr, "WHEEL/TRAD: %lf\n", (double)deltaY);
if (deltaY == 0.0 && (javaMods & EVENT_SHIFT_MASK) != 0) {
// shift+vertical wheel scroll produces horizontal scroll
// we convert it to vertical
deltaY = [event deltaX];
}
- if (deltaY < 1.0 && deltaY > -1.0) {
+ if (-1.0 < deltaY && deltaY < 1.0) {
deltaY *= 10.0;
} else {
if (deltaY < 0.0) {
@@ -62,21 +64,15 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
}
}
}
-
- if (deltaY > 0) {
- return (NSInteger)deltaY;
- } else if (deltaY < 0) {
- return -(NSInteger)deltaY;
- }
-
- return 0;
+ // fprintf(stderr, "WHEEL/res: %d\n", (int)deltaY);
+ return (jint) deltaY;
}
static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
@@ -104,7 +100,11 @@ static jmethodID windowRepaintID = NULL;
jvmVersion = 0;
destroyNotifySent = NO;
softLocked = NO;
- pthread_mutex_init(&softLockSync, NULL); // fast non-recursive
+
+ pthread_mutexattr_t softLockSyncAttr;
+ pthread_mutexattr_init(&softLockSyncAttr);
+ pthread_mutexattr_settype(&softLockSyncAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&softLockSync, &softLockSyncAttr); // recursive
ptrTrackingTag = 0;
@@ -122,7 +122,7 @@ static jmethodID windowRepaintID = NULL;
- (void) dealloc
{
if(softLocked) {
- fprintf(stderr, "*** Warning: softLock still hold @ dealloc!\n"); fflush(NULL);
+ NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
}
pthread_mutex_destroy(&softLockSync);
[super dealloc];
@@ -193,72 +193,61 @@ static jmethodID windowRepaintID = NULL;
return destroyNotifySent;
}
-#define SOFT_LOCK_BLOCKING 1
-
- (BOOL) softLock
{
+ // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self());
+ // NSLog(@"NewtView::softLock: %@",[NSThread callStackSymbols]);
pthread_mutex_lock(&softLockSync);
softLocked = YES;
-#ifndef SOFT_LOCK_BLOCKING
- pthread_mutex_unlock(&softLockSync);
-#endif
+ // DBG_PRINT("*************** softLock.X: %p\n", (void*)pthread_self());
return softLocked;
}
- (void) softUnlock
{
-#ifndef SOFT_LOCK_BLOCKING
- pthread_mutex_lock(&softLockSync);
-#endif
+ // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self());
softLocked = NO;
pthread_mutex_unlock(&softLockSync);
}
- (BOOL) needsDisplay
{
-#ifndef SOFT_LOCK_BLOCKING
- return NO == softLocked && NO == destroyNotifySent && [super needsDisplay];
-#else
return NO == destroyNotifySent && [super needsDisplay];
-#endif
}
- (void) displayIfNeeded
{
-#ifndef SOFT_LOCK_BLOCKING
- if( NO == softLocked && NO == destroyNotifySent ) {
+ if( YES == [self needsDisplay] ) {
+ [self softLock];
[super displayIfNeeded];
+ [self softUnlock];
}
-#else
- [self softLock];
- if( NO == destroyNotifySent ) {
- [super displayIfNeeded];
- }
- [self softUnlock];
-#endif
}
-- (void) viewWillDraw
+- (void) display
{
- DBG_PRINT("*************** viewWillDraw: 0x%p\n", javaWindowObject);
- [super viewWillDraw];
+ if( NO == destroyNotifySent ) {
+ [self softLock];
+ [super display];
+ [self softUnlock];
+ }
}
- (void) drawRect:(NSRect)dirtyRect
{
- DBG_PRINT("*************** dirtyRect: 0x%p %lf/%lf %lfx%lf\n",
+ DBG_PRINT("*************** dirtyRect: %p %lf/%lf %lfx%lf\n",
javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height);
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
NSRect viewFrame = [self frame];
- (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_FALSE,
+ (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE, // defer ..
dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y,
dirtyRect.size.width, dirtyRect.size.height);
@@ -272,7 +261,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -290,7 +279,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -325,9 +314,9 @@ static jmethodID windowRepaintID = NULL;
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (enqueueMouseEventID && sendMouseEventID && enqueueKeyEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
- positionChangedID && focusChangedID && windowDestroyNotifyID && enqueueRequestFocusID && windowRepaintID)
+ positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
return YES;
}
@@ -512,14 +501,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendKeyEvent: null javaWindowObject");
+ DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendKeyEvent: null JNIEnv");
+ DBG_PRINT("sendKeyEvent: null JNIEnv\n");
return;
}
@@ -533,6 +522,8 @@ static jint mods2JavaMods(NSUInteger mods)
// Note: the key code in the NSEvent does not map to anything we can use
jchar keyChar = (jchar) [chars characterAtIndex: i];
+ DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
evType, javaMods, keyCode, keyChar);
@@ -567,14 +558,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendMouseEvent: null javaWindowObject");
+ DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendMouseEvent: null JNIEnv");
+ DBG_PRINT("sendMouseEvent: null JNIEnv\n");
return;
}
jint javaMods = mods2JavaMods([event modifierFlags]);
@@ -586,6 +577,7 @@ static jint mods2JavaMods(NSUInteger mods)
switch ([event type]) {
case NSScrollWheel: {
scrollDeltaY = GetDeltaY(event, javaMods);
+ javaButtonNum = 1;
break;
}
case NSLeftMouseDown:
@@ -603,9 +595,6 @@ static jint mods2JavaMods(NSUInteger mods)
case NSOtherMouseDragged:
javaButtonNum = 2;
break;
- default:
- javaButtonNum = 0;
- break;
}
if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) {
@@ -613,7 +602,7 @@ static jint mods2JavaMods(NSUInteger mods)
return;
}
if (evType == EVENT_MOUSE_PRESSED) {
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE);
}
NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
@@ -770,14 +759,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidResize: null javaWindowObject");
+ DBG_PRINT("windowDidResize: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidResize: null JNIEnv");
+ DBG_PRINT("windowDidResize: null JNIEnv\n");
return;
}
@@ -805,14 +794,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidMove: null javaWindowObject");
+ DBG_PRINT("windowDidMove: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidMove: null JNIEnv");
+ DBG_PRINT("windowDidMove: null JNIEnv\n");
return;
}
@@ -839,16 +828,16 @@ static jint mods2JavaMods(NSUInteger mods)
if( false == [view getDestroyNotifySent] ) {
jobject javaWindowObject = [view getJavaWindowObject];
- DBG_PRINT( "*************** windowWillClose.0: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject);
if (javaWindowObject == NULL) {
- NSLog(@"windowWillClose: null javaWindowObject");
+ DBG_PRINT("windowWillClose: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowWillClose: null JNIEnv");
+ DBG_PRINT("windowWillClose: null JNIEnv\n");
return;
}
@@ -863,7 +852,7 @@ static jint mods2JavaMods(NSUInteger mods)
if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
}
- DBG_PRINT( "*************** windowWillClose.X: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ DBG_PRINT( "*************** windowWillClose.X: %p\n", (void *)(intptr_t)javaWindowObject);
} else {
DBG_PRINT( "*************** windowWillClose (skip)\n");
}
@@ -916,14 +905,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"focusChanged: null javaWindowObject");
+ DBG_PRINT("focusChanged: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"focusChanged: null JNIEnv");
+ DBG_PRINT("focusChanged: null JNIEnv\n");
return;
}
diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h
index 0a760d54a..bb782910e 100644
--- a/src/newt/native/ScreenMode.h
+++ b/src/newt/native/ScreenMode.h
@@ -1,4 +1,32 @@
/**
+ * 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.
+ */
+
+/**
* WARNING: must be synced with com.jogamp.newt.util.ScreenModeUtil#streamIn*(int[])
*/
diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h
index 865746b91..4755c4fc5 100644
--- a/src/newt/native/Window.h
+++ b/src/newt/native/Window.h
@@ -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.
+ */
#ifndef _WINDOW_H_
#define _WINDOW_H_
diff --git a/src/newt/native/WindowEvent.h b/src/newt/native/WindowEvent.h
index 05491b43c..3dc6ba97e 100644
--- a/src/newt/native/WindowEvent.h
+++ b/src/newt/native/WindowEvent.h
@@ -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.
+ */
#ifndef _WINDOW_EVENT_H_
#define _WINDOW_EVENT_H_
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index d60c40496..97fe6f28d 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -115,8 +115,7 @@ static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID focusActionID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
@@ -602,18 +601,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jb
(void*) pHwnd, (void*)hwnd, current==hwnd);
if( JNI_TRUE==force || current!=hwnd) {
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
- SetForegroundWindow(hwnd); // Slightly Higher Priority
- SetFocus(hwnd);// Sets Keyboard Focus To Window
- if(NULL!=pHwnd) {
- SetActiveWindow(hwnd);
- }
- DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
- } else {
- DBG_PRINT("*** WindowsWindow: requestFocus.X0\n");
+ UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ SetForegroundWindow(hwnd); // Slightly Higher Priority
+ SetFocus(hwnd);// Sets Keyboard Focus To Window
+ if(NULL!=pHwnd) {
+ SetActiveWindow(hwnd);
}
+ DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
}
DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
@@ -870,11 +865,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_LBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: LBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
break;
@@ -883,18 +878,18 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
break;
case WM_MBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: MBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
break;
@@ -903,18 +898,18 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
break;
case WM_RBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: RBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
break;
@@ -923,7 +918,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
break;
@@ -932,7 +927,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_MOVED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 0, (jint) 0);
useDefWindowProc = 1;
break;
@@ -958,7 +953,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(jint) EVENT_MOUSE_WHEEL_MOVED,
GetModifiers(),
(jint) eventPt.x, (jint) eventPt.y,
- (jint) 0, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
+ (jint) 1, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
useDefWindowProc = 1;
break;
}
@@ -978,8 +973,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_MOVE:
- DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, (int)LOWORD(lParam), (int)HIWORD(lParam));
- (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)LOWORD(lParam), (jint)HIWORD(lParam));
+ DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)GET_X_LPARAM(lParam), (jint)GET_Y_LPARAM(lParam));
useDefWindowProc = 1;
break;
@@ -1046,13 +1041,47 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe
/*
* Class: jogamp_newt_driver_windows_WindowsScreen
+ * Method: getOriginX0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ if( GetSystemMetrics( SM_CMONITORS) > 1) {
+ return (jint)GetSystemMetrics(SM_XVIRTUALSCREEN);
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Method: getOriginY0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ if( GetSystemMetrics( SM_CMONITORS ) > 1) {
+ return (jint)GetSystemMetrics(SM_YVIRTUALSCREEN);
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowsScreen
* Method: getWidthImpl
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
- return (jint)GetSystemMetrics(SM_CXSCREEN);
+ if( GetSystemMetrics( SM_CMONITORS) > 1) {
+ return (jint)GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ } else {
+ return (jint)GetSystemMetrics(SM_CXSCREEN);
+ }
}
/*
@@ -1063,7 +1092,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImp
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getHeightImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
- return (jint)GetSystemMetrics(SM_CYSCREEN);
+ if( GetSystemMetrics( SM_CMONITORS ) > 1) {
+ return (jint)GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ } else {
+ return (jint)GetSystemMetrics(SM_CYSCREEN);
+ }
}
static int NewtScreen_RotationNativeCCW2NewtCCW(JNIEnv *env, int native) {
@@ -1270,8 +1303,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (insetsChangedID == NULL ||
sizeChangedID == NULL ||
@@ -1284,8 +1316,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID == NULL ||
enqueueKeyEventID == NULL ||
sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
+ requestFocusID == NULL) {
return JNI_FALSE;
}
BuildDynamicKeyMapTable();
@@ -1317,9 +1348,6 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
} else {
flags = SWP_NOACTIVATE | SWP_NOZORDER;
}
- if(0>x || 0>y) {
- flags |= SWP_NOMOVE;
- }
if(0>=width || 0>=height ) {
flags |= SWP_NOSIZE;
}
@@ -1345,7 +1373,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
(JNIEnv *env, jobject obj,
jlong hInstance, jstring jWndClassName, jstring jWndName,
jlong parent,
- jint jx, jint jy, jint defaultWidth, jint defaultHeight, jint flags)
+ jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags)
{
HWND parentWindow = (HWND) (intptr_t) parent;
const TCHAR* wndClassName = NULL;
@@ -1374,7 +1402,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
} else {
windowStyle |= WS_OVERLAPPEDWINDOW;
- if(0>_x || 0>_y) {
+ if(JNI_TRUE == autoPosition) {
// user didn't requested specific position, use WM default
_x = CW_USEDEFAULT;
_y = 0;
@@ -1387,9 +1415,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
(HINSTANCE) (intptr_t) hInstance,
NULL);
- DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d\n",
+ DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
(int)GetCurrentThreadId(), parentWindow, window, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags));
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
if (NULL == window) {
int lastError = (int) GetLastError();
@@ -1409,7 +1437,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
{
RECT rc;
RECT * insets;
- BOOL userPos = 0<=x && 0<=y ;
ShowWindow(window, SW_SHOW);
@@ -1417,12 +1444,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
insets = UpdateInsets(env, wud->jinstance, window);
(*env)->CallVoidMethod(env, wud->jinstance, visibleChangedID, JNI_FALSE, JNI_TRUE);
- if(!userPos) {
+ if(JNI_TRUE == autoPosition) {
GetWindowRect(window, &rc);
x = rc.left + insets->left; // client coords
y = rc.top + insets->top; // client coords
}
- DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (is user-pos %d)\n", x, y, width, height, userPos);
+ DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
x -= insets->left; // top-level
y -= insets->top; // top-level
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
new file mode 100644
index 000000000..cefef690f
--- /dev/null
+++ b/src/newt/native/X11Common.h
@@ -0,0 +1,80 @@
+/**
+ * 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.
+ */
+
+#ifndef _X11COMMON_H_
+#define _X11COMMON_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <gluegen_stdint.h>
+
+#include <unistd.h>
+#include <errno.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+
+#include <X11/extensions/Xrandr.h>
+
+#include "jogamp_newt_driver_x11_X11Screen.h"
+#include "jogamp_newt_driver_x11_X11Display.h"
+#include "jogamp_newt_driver_x11_X11Window.h"
+
+#include "Window.h"
+#include "MouseEvent.h"
+#include "InputEvent.h"
+#include "KeyEvent.h"
+#include "WindowEvent.h"
+#include "ScreenMode.h"
+
+#include "NewtCommon.h"
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+extern jclass X11NewtWindowClazz;
+extern jmethodID insetsChangedID;
+extern jmethodID visibleChangedID;
+
+jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
+
+void NewtDisplay_displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env);
+Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
+Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom);
+
+#endif /* _X11COMMON_H_ */
+
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
new file mode 100644
index 000000000..283636040
--- /dev/null
+++ b/src/newt/native/X11Display.c
@@ -0,0 +1,660 @@
+/**
+ * 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.
+ */
+
+#include "X11Common.h"
+
+#define USE_SENDIO_DIRECT 1
+
+jclass X11NewtWindowClazz = NULL;
+jmethodID insetsChangedID = NULL;
+jmethodID visibleChangedID = NULL;
+
+static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window";
+
+static jmethodID displayCompletedID = NULL;
+
+static jmethodID sizeChangedID = NULL;
+static jmethodID positionChangedID = NULL;
+static jmethodID focusChangedID = NULL;
+static jmethodID reparentNotifyID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID windowRepaintID = NULL;
+static jmethodID enqueueMouseEventID = NULL;
+static jmethodID sendMouseEventID = NULL;
+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 displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
+{
+ fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno));
+
+ if (e->error_code == BadAtom) {
+ fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", (void*)e->resourceid);
+ } else if (e->error_code == BadWindow) {
+ fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid);
+ } else {
+ int shallBeDetached = 0;
+ JNIEnv *jniEnv = NULL;
+ const char * errStr = strerror(errno);
+
+ fprintf(stderr, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
+
+ jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL==jniEnv) {
+ fprintf(stderr, "NEWT X11 Error: null JNIEnv");
+ return;
+ }
+
+ NewtCommon_throwNewRuntimeException(jniEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
+ dpy, e->error_code, errStr);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
+ }
+
+ return 0;
+}
+
+void NewtDisplay_displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) {
+ if(onoff) {
+ if(NULL==origErrorHandler) {
+ setupJVMVars(env);
+ origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler);
+ }
+ } else {
+ if(NULL!=origErrorHandler) {
+ XSetErrorHandler(origErrorHandler);
+ origErrorHandler = NULL;
+ }
+ }
+}
+
+/**
+ * Keycode
+ */
+
+#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
+
+static jint X11KeySym2NewtVKey(KeySym keySym) {
+ if(IS_WITHIN(keySym,XK_F1,XK_F12))
+ return (keySym-XK_F1)+J_VK_F1;
+ if(IS_WITHIN(keySym,XK_KP_0,XK_KP_9))
+ return (keySym-XK_KP_0)+J_VK_NUMPAD0;
+
+ switch(keySym) {
+ case XK_Return:
+ case XK_KP_Enter:
+ return J_VK_ENTER;
+ case XK_BackSpace:
+ return J_VK_BACK_SPACE;
+ case XK_Tab:
+ case XK_KP_Tab:
+ case XK_ISO_Left_Tab:
+ return J_VK_TAB;
+ case XK_Cancel:
+ return J_VK_CANCEL;
+ case XK_Clear:
+ return J_VK_CLEAR;
+ case XK_Shift_L:
+ case XK_Shift_R:
+ return J_VK_SHIFT;
+ case XK_Control_L:
+ case XK_Control_R:
+ return J_VK_CONTROL;
+ case XK_Alt_L:
+ case XK_Alt_R:
+ return J_VK_ALT;
+ case XK_Pause:
+ return J_VK_PAUSE;
+ case XK_Caps_Lock:
+ return J_VK_CAPS_LOCK;
+ case XK_Escape:
+ return J_VK_ESCAPE;
+ case XK_space:
+ case XK_KP_Space:
+ return J_VK_SPACE;
+ case XK_Page_Up:
+ case XK_KP_Page_Up:
+ return J_VK_PAGE_UP;
+ case XK_Page_Down:
+ case XK_KP_Page_Down:
+ return J_VK_PAGE_DOWN;
+ case XK_End:
+ case XK_KP_End:
+ return J_VK_END;
+ case XK_Home:
+ case XK_KP_Home:
+ return J_VK_HOME;
+ case XK_Left:
+ case XK_KP_Left:
+ return J_VK_LEFT;
+ case XK_Up:
+ case XK_KP_Up:
+ return J_VK_UP;
+ case XK_Right:
+ case XK_KP_Right:
+ return J_VK_RIGHT;
+ case XK_Down:
+ case XK_KP_Down:
+ return J_VK_DOWN;
+ case XK_KP_Multiply:
+ return J_VK_MULTIPLY;
+ case XK_KP_Add:
+ return J_VK_ADD;
+ case XK_KP_Separator:
+ return J_VK_SEPARATOR;
+ case XK_KP_Subtract:
+ return J_VK_SUBTRACT;
+ case XK_KP_Decimal:
+ return J_VK_DECIMAL;
+ case XK_KP_Divide:
+ return J_VK_DIVIDE;
+ case XK_Delete:
+ case XK_KP_Delete:
+ return J_VK_DELETE;
+ case XK_Num_Lock:
+ return J_VK_NUM_LOCK;
+ case XK_Scroll_Lock:
+ return J_VK_SCROLL_LOCK;
+ case XK_Print:
+ return J_VK_PRINTSCREEN;
+ case XK_Insert:
+ case XK_KP_Insert:
+ return J_VK_INSERT;
+ case XK_Help:
+ return J_VK_HELP;
+ }
+ return keySym;
+}
+
+static jint X11InputState2NewtModifiers(unsigned int xstate) {
+ jint modifiers = 0;
+ if ((ControlMask & xstate) != 0) {
+ modifiers |= EVENT_CTRL_MASK;
+ }
+ if ((ShiftMask & xstate) != 0) {
+ modifiers |= EVENT_SHIFT_MASK;
+ }
+ if ((Mod1Mask & xstate) != 0) {
+ modifiers |= EVENT_ALT_MASK;
+ }
+ if ((Button1Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON1_MASK;
+ }
+ if ((Button2Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON2_MASK;
+ }
+ if ((Button3Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON3_MASK;
+ }
+
+ return modifiers;
+}
+
+
+/**
+ * Keycode
+ */
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: initIDs
+ * Signature: (Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
+ (JNIEnv *env, jclass clazz)
+{
+ jclass c;
+
+ NewtCommon_init(env);
+
+ if(NULL==X11NewtWindowClazz) {
+ c = (*env)->FindClass(env, ClazzNameX11NewtWindow);
+ if(NULL==c) {
+ NewtCommon_FatalError(env, "NEWT X11Window: 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);
+ }
+ }
+
+ displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
+ insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V");
+ sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZIIZ)V");
+ positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V");
+ focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V");
+ reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "()V");
+ windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
+ enqueueMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueMouseEvent", "(ZIIIIII)V");
+ sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(IIIIII)V");
+ enqueueKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueKeyEvent", "(ZIIIC)V");
+ sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(IIIC)V");
+ requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
+
+ if (displayCompletedID == NULL ||
+ insetsChangedID == NULL ||
+ sizeChangedID == NULL ||
+ positionChangedID == NULL ||
+ focusChangedID == NULL ||
+ visibleChangedID == NULL ||
+ reparentNotifyID == NULL ||
+ windowDestroyNotifyID == NULL ||
+ windowRepaintID == NULL ||
+ enqueueMouseEventID == NULL ||
+ sendMouseEventID == NULL ||
+ enqueueKeyEventID == NULL ||
+ sendKeyEventID == NULL ||
+ requestFocusID == NULL) {
+ return JNI_FALSE;
+ }
+
+
+ return JNI_TRUE;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: CompleteDisplay
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
+ (JNIEnv *env, jobject obj, jlong display)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ jlong javaObjectAtom;
+ jlong windowDeleteAtom;
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
+ if(None==javaObjectAtom) {
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
+ return;
+ }
+
+ windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ if(None==windowDeleteAtom) {
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
+ return;
+ }
+
+ // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
+
+ DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
+
+ (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: DisplayRelease0
+ * Signature: (JJJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Atom wm_javaobject_atom = (Atom)javaObjectAtom;
+ Atom wm_delete_atom = (Atom)windowDeleteAtom;
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ // nothing to do to free the atoms !
+ (void) wm_javaobject_atom;
+ (void) wm_delete_atom;
+
+ XSync(dpy, True); // discard all pending events
+ DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: DispatchMessages
+ * Signature: (JIJJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ Atom wm_delete_atom = (Atom)windowDeleteAtom;
+ int num_events = 100;
+
+ if ( NULL == dpy ) {
+ return;
+ }
+
+ // Periodically take a break
+ while( num_events > 0 ) {
+ jobject jwindow = NULL;
+ XEvent evt;
+ KeySym keySym = 0;
+ jint modifiers = 0;
+ char keyChar = 0;
+ char text[255];
+
+ // XEventsQueued(dpy, X):
+ // QueuedAlready : 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) ) {
+ // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
+ return;
+ }
+
+ XNextEvent(dpy, &evt);
+ num_events--;
+
+ if( 0==evt.xany.window ) {
+ NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
+ return ;
+ }
+
+ if(dpy!=evt.xany.display) {
+ NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
+ return ;
+ }
+
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
+
+ NewtDisplay_displayDispatchErrorHandlerEnable(1, env);
+
+ jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
+ #ifdef VERBOSE_ON
+ True
+ #else
+ False
+ #endif
+ );
+
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
+
+ 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);
+ continue;
+ }
+
+ switch(evt.type) {
+ case KeyRelease:
+ case KeyPress:
+ if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
+ KeySym lower_return = 0, upper_return = 0;
+ keyChar=text[0];
+ XConvertCase(keySym, &lower_return, &upper_return);
+ // always return upper case, set modifier masks (SHIFT, ..)
+ keySym = X11KeySym2NewtVKey(upper_return);
+ } else {
+ keyChar=0;
+ keySym = X11KeySym2NewtVKey(keySym);
+ }
+ modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
+ break;
+
+ default:
+ break;
+ }
+
+ switch(evt.type) {
+ case ButtonPress:
+ (*env)->CallVoidMethod(env, jwindow, requestFocusID, JNI_FALSE);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
+ break;
+ case ButtonRelease:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
+ break;
+ case MotionNotify:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case EnterNotify:
+ DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_ENTERED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_ENTERED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case LeaveNotify:
+ DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_EXITED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_EXITED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case KeyPress:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
+ modifiers, keySym, (jchar) -1);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
+ modifiers, keySym, (jchar) -1);
+ #endif
+
+ break;
+ case KeyRelease:
+ #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;
+ case DestroyNotify:
+ DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
+ (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
+ if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
+ // ignore child destroy notification
+ }
+ break;
+ case CreateNotify:
+ DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n",
+ (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
+ break;
+ case ConfigureNotify:
+ DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n",
+ (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
+ evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height,
+ evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
+ if ( evt.xconfigure.window == evt.xconfigure.event ) {
+ // ignore child window change notification
+ {
+ // update insets
+ int left, right, top, bottom;
+ NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
+ }
+ (*env)->CallVoidMethod(env, jwindow, sizeChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
+ (*env)->CallVoidMethod(env, jwindow, positionChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ }
+ break;
+ case ClientMessage:
+ if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
+ DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n",
+ (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
+ (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
+ // Called by Window.java: CloseWindow();
+ num_events = 0; // end loop in case of destroyed display
+ }
+ break;
+
+ case FocusIn:
+ DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
+ (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_TRUE);
+ break;
+
+ case FocusOut:
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
+ (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_FALSE);
+ break;
+
+ case Expose:
+ DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
+
+ if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
+ (*env)->CallVoidMethod(env, jwindow, windowRepaintID, JNI_FALSE,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ }
+ break;
+
+ case MapNotify:
+ DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
+ (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect,
+ evt.xmap.event!=evt.xmap.window);
+ if( evt.xmap.event == evt.xmap.window ) {
+ // ignore child window notification
+ {
+ // update insets
+ int left, right, top, bottom;
+ NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
+ }
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
+ }
+ break;
+
+ case UnmapNotify:
+ DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n",
+ (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure,
+ evt.xunmap.event!=evt.xunmap.window);
+ if( evt.xunmap.event == evt.xunmap.window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_FALSE);
+ }
+ break;
+
+ case ReparentNotify:
+ {
+ jlong parentResult; // 0 if root, otherwise proper value
+ Window winRoot, winTopParent;
+ #ifdef VERBOSE_ON
+ Window oldParentRoot, oldParentTopParent;
+ Window parentRoot, parentTopParent;
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
+ oldParentRoot=0; oldParentTopParent = 0;
+ }
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
+ parentRoot=0; parentTopParent = 0;
+ }
+ #endif
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
+ winRoot=0; winTopParent = 0;
+ }
+ if(evt.xreparent.parent == winRoot) {
+ parentResult = 0; // our java indicator for root window
+ } else {
+ parentResult = (jlong) (intptr_t) evt.xreparent.parent;
+ }
+ #ifdef VERBOSE_ON
+ DBG_PRINT( "X11: event . ReparentNotify: call %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
+ evt.xreparent.x, evt.xreparent.y,
+ (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
+ (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
+ (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
+ #endif
+ (*env)->CallVoidMethod(env, jwindow, reparentNotifyID, (jlong)evt.xreparent.parent);
+ }
+ break;
+
+ // unhandled events .. yet ..
+
+ default:
+ DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window);
+ }
+ }
+}
+
+
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c
new file mode 100644
index 000000000..1b7fea770
--- /dev/null
+++ b/src/newt/native/X11Screen.c
@@ -0,0 +1,469 @@
+/**
+ * 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.
+ */
+
+#include "X11Common.h"
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: GetScreen
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Screen * scrn= NULL;
+
+ DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ scrn = ScreenOfDisplay(dpy, screen_index);
+ if(scrn==NULL) {
+ fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
+ }
+ DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
+ return (jlong) (intptr_t) scrn;
+}
+
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_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
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ return (jint) DisplayHeight( dpy, scrn_idx);
+}
+
+static int showedRandRVersion = 0;
+
+static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
+ if( 0 == XRRQueryVersion(dpy, major, minor) ) {
+ return False;
+ }
+ if(0 == showedRandRVersion) {
+ fprintf(stderr, "X11 RandR Version %d.%d\n", *major, *minor);
+ showedRandRVersion = 1;
+ }
+ return True;
+}
+
+static Bool NewtScreen_hasRANDR(Display *dpy) {
+ int major, minor;
+ return NewtScreen_getRANDRVersion(dpy, &major, &minor);
+}
+
+static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
+ int rot;
+ if(xrotation == RR_Rotate_0) {
+ rot = 0;
+ }
+ else if(xrotation == RR_Rotate_90) {
+ rot = 90;
+ }
+ else if(xrotation == RR_Rotate_180) {
+ rot = 180;
+ }
+ else if(xrotation == RR_Rotate_270) {
+ rot = 270;
+ } else {
+ NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
+ }
+ return rot;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getAvailableScreenModeRotations0
+ * Signature: (JI)I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_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;
+
+ if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
+ fprintf(stderr, "RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
+
+ if(0 != (rotations_supported & RR_Rotate_0)) {
+ rotations[num_rotations++] = 0;
+ }
+ if(0 != (rotations_supported & RR_Rotate_90)) {
+ rotations[num_rotations++] = 90;
+ }
+ if(0 != (rotations_supported & RR_Rotate_180)) {
+ rotations[num_rotations++] = 180;
+ }
+ if(0 != (rotations_supported & RR_Rotate_270)) {
+ rotations[num_rotations++] = 270;
+ }
+
+ jintArray properties = NULL;
+
+ if(num_rotations>0) {
+ properties = (*env)->NewIntArray(env, num_rotations);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
+ }
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getNumScreenModeResolution0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
+ return 0;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
+
+ return num_sizes;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getScreenModeResolutions0
+ * Signature: (JII)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_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");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ // Fill the properties in temp jint array
+ 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);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getScreenModeRates0
+ * Signature: (JII)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_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");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ int num_rates;
+ short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
+
+ jint prop[num_rates];
+ int i;
+ for(i=0; i<num_rates; i++) {
+ prop[i] = (int) rates[i];
+ /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
+ }
+
+ jintArray properties = (*env)->NewIntArray(env, num_rates);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenRate0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
+ return -1;
+ }
+
+ // get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+ short original_rate = XRRConfigCurrentRate(conf);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
+
+ return (jint) original_rate;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenRotation0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
+ return -1;
+ }
+
+ //get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+
+ Rotation rotation;
+ XRRConfigCurrentConfiguration(conf, &rotation);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ return NewtScreen_XRotation2Degree(env, rotation);
+}
+
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenResolutionIndex0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
+ return -1;
+ }
+
+ // 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;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: setCurrentScreenModeStart0
+ * Signature: (JIIII)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)screen_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0: RANDR not available\n");
+ return 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);
+ }
+
+ conf = XRRGetScreenInfo(dpy, root);
+
+ 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);
+
+ XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
+
+ XSync(dpy, False);
+ XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
+ XSync(dpy, False);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+ XSync(dpy, False);
+
+ return JNI_TRUE;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: setCurrentScreenModePollEnd0
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ int randr_event_base, randr_error_base;
+ XEvent evt;
+ XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
+ return 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);
+ }
+
+ 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);
+
+}
+
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index f14138a0a..0a7e1cf77 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -32,40 +32,9 @@
*
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include <gluegen_stdint.h>
-
-#include <unistd.h>
-#include <errno.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-
-#include <X11/extensions/Xrandr.h>
-
-#include "jogamp_newt_driver_x11_X11Screen.h"
-#include "jogamp_newt_driver_x11_X11Display.h"
-#include "jogamp_newt_driver_x11_X11Window.h"
-
-#include "Window.h"
-#include "MouseEvent.h"
-#include "InputEvent.h"
-#include "KeyEvent.h"
-#include "WindowEvent.h"
-#include "ScreenMode.h"
-
-#include "NewtCommon.h"
-
-// #define VERBOSE_ON 1
+#include "X11Common.h"
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-
#define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b))
static void _dumpVisualInfo(const char * msg, XVisualInfo *pVisualQuery) {
@@ -90,259 +59,12 @@
#else
- #define DBG_PRINT(...)
-
#define DUMP_VISUAL_INFO(a,b)
#endif
-/**
- * Keycode
- */
-
-#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
-
-static jint X11KeySym2NewtVKey(KeySym keySym) {
- if(IS_WITHIN(keySym,XK_F1,XK_F12))
- return (keySym-XK_F1)+J_VK_F1;
-
- switch(keySym) {
- case XK_Alt_L:
- case XK_Alt_R:
- return J_VK_ALT;
-
- case XK_Left:
- return J_VK_LEFT;
- case XK_Right:
- return J_VK_RIGHT;
- case XK_Up:
- return J_VK_UP;
- case XK_Down:
- return J_VK_DOWN;
- case XK_Page_Up:
- return J_VK_PAGE_UP;
- case XK_Page_Down:
- return J_VK_PAGE_DOWN;
- case XK_Shift_L:
- case XK_Shift_R:
- return J_VK_SHIFT;
- case XK_Control_L:
- case XK_Control_R:
- return J_VK_CONTROL;
- case XK_Escape:
- return J_VK_ESCAPE;
- case XK_Delete:
- return J_VK_DELETE;
- }
- return keySym;
-}
-
-static jint X11InputState2NewtModifiers(unsigned int xstate) {
- jint modifiers = 0;
- if ((ControlMask & xstate) != 0) {
- modifiers |= EVENT_CTRL_MASK;
- }
- if ((ShiftMask & xstate) != 0) {
- modifiers |= EVENT_SHIFT_MASK;
- }
- if ((Mod1Mask & xstate) != 0) {
- modifiers |= EVENT_ALT_MASK;
- }
- if ((Button1Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON1_MASK;
- }
- if ((Button2Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON2_MASK;
- }
- if ((Button3Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON3_MASK;
- }
-
- return modifiers;
-}
-
#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask)
-static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window";
-
-static jclass newtWindowClz=NULL;
-
-static jmethodID insetsChangedID = NULL;
-static jmethodID sizeChangedID = NULL;
-static jmethodID positionChangedID = NULL;
-static jmethodID focusChangedID = NULL;
-static jmethodID visibleChangedID = NULL;
-static jmethodID reparentNotifyID = NULL;
-static jmethodID windowDestroyNotifyID = NULL;
-static jmethodID windowRepaintID = NULL;
-static jmethodID enqueueMouseEventID = NULL;
-static jmethodID sendMouseEventID = NULL;
-static jmethodID enqueueKeyEventID = NULL;
-static jmethodID sendKeyEventID = NULL;
-static jmethodID focusActionID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
-
-static jmethodID displayCompletedID = NULL;
-
-
-/**
- * Display
- */
-
-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 displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
-{
- fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno));
-
- if (e->error_code == BadAtom) {
- fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", (void*)e->resourceid);
- } else if (e->error_code == BadWindow) {
- fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid);
- } else {
- int shallBeDetached = 0;
- JNIEnv *jniEnv = NULL;
- const char * errStr = strerror(errno);
-
- fprintf(stderr, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
-
- jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
- if(NULL==jniEnv) {
- fprintf(stderr, "NEWT X11 Error: null JNIEnv");
- return;
- }
-
- NewtCommon_throwNewRuntimeException(jniEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
- dpy, e->error_code, errStr);
-
- if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
- }
-
- return 0;
-}
-
-static void displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) {
- if(onoff) {
- if(NULL==origErrorHandler) {
- setupJVMVars(env);
- origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler);
- }
- } else {
- if(NULL!=origErrorHandler) {
- XSetErrorHandler(origErrorHandler);
- origErrorHandler = NULL;
- }
- }
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: initIDs
- * Signature: (Z)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
- (JNIEnv *env, jclass clazz)
-{
- jclass c;
-
- NewtCommon_init(env);
-
- displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
- if (displayCompletedID == NULL) {
- return JNI_FALSE;
- }
-
- if(NULL==newtWindowClz) {
- c = (*env)->FindClass(env, ClazzNameNewtWindow);
- if(NULL==c) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameNewtWindow);
- }
- newtWindowClz = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==newtWindowClz) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameNewtWindow);
- }
- }
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: CompleteDisplay
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
- (JNIEnv *env, jobject obj, jlong display)
-{
- Display * dpy = (Display *)(intptr_t)display;
- jlong javaObjectAtom;
- jlong windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
- if(None==javaObjectAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
- return;
- }
-
- windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- if(None==windowDeleteAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
- return;
- }
-
- // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
-
- DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
-
- (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DisplayRelease0
- * Signature: (JJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Atom wm_javaobject_atom = (Atom)javaObjectAtom;
- Atom wm_delete_atom = (Atom)windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- // nothing to do to free the atoms !
- (void) wm_javaobject_atom;
- (void) wm_delete_atom;
-
- XSync(dpy, True); // discard all pending events
- DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
-}
-
-
-/**
- * Window
- */
-
static int putPtrIn32Long(unsigned long * dst, uintptr_t src) {
int i=0;
dst[i++] = (unsigned long) ( ( src >> 0 ) & 0xFFFFFFFF ) ;
@@ -375,7 +97,7 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon
(unsigned char *)&jogl_java_object_data, nitems_32);
}
-static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) {
+jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) {
Atom actual_type;
int actual_format;
int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ;
@@ -413,7 +135,7 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
XFree(jogl_java_object_data_pp);
#ifdef VERBOSE_ON
- if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, newtWindowClz)) {
+ if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, X11NewtWindowClazz)) {
NewtCommon_throwNewRuntimeException(env, "fetched Atom NEWT_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !", jwindow);
}
#endif
@@ -421,7 +143,7 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
}
/** @return zero if fails, non zero if OK */
-static Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
+Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
Window *children_return=NULL;
unsigned int nchildren_return=0;
@@ -502,7 +224,7 @@ static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left
return 1; // Ok
}
-static Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
+Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
if(0 != NewtWindows_getFrameExtends(dpy, window, left, right, top, bottom)) {
DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n",
*left, *right, *top, *bottom);
@@ -535,16 +257,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
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( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
- XRaiseWindow(dpy, w);
- NewtWindows_setCWAbove(dpy, w);
- // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
- XGetWindowAttributes(dpy, w, &xwa);
- if(xwa.map_state == IsViewable) {
- DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
- XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
- }
+ DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
+ XRaiseWindow(dpy, w);
+ NewtWindows_setCWAbove(dpy, w);
+ // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
+ XGetWindowAttributes(dpy, w, &xwa);
+ if(xwa.map_state == IsViewable) {
+ DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
+ XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
}
}
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force);
@@ -710,752 +430,6 @@ static Bool NewtWindows_setFullscreenEWMH (Display *dpy, Window root, Window w,
return res;
}
-#define USE_SENDIO_DIRECT 1
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DispatchMessages
- * Signature: (JIJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Atom wm_delete_atom = (Atom)windowDeleteAtom;
- int num_events = 100;
-
- if ( NULL == dpy ) {
- return;
- }
-
- // Periodically take a break
- while( num_events > 0 ) {
- jobject jwindow = NULL;
- XEvent evt;
- KeySym keySym = 0;
- jint modifiers = 0;
- char keyChar = 0;
- char text[255];
-
- // XEventsQueued(dpy, X):
- // QueuedAlready : 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) ) {
- // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
- return;
- }
-
- XNextEvent(dpy, &evt);
- num_events--;
-
- if( 0==evt.xany.window ) {
- NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
- return ;
- }
-
- if(dpy!=evt.xany.display) {
- NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
- return ;
- }
-
- // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
-
- displayDispatchErrorHandlerEnable(1, env);
-
- jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
- #ifdef VERBOSE_ON
- True
- #else
- False
- #endif
- );
-
- displayDispatchErrorHandlerEnable(0, env);
-
- 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);
- continue;
- }
-
- switch(evt.type) {
- case KeyRelease:
- case KeyPress:
- if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
- KeySym lower_return = 0, upper_return = 0;
- keyChar=text[0];
- XConvertCase(keySym, &lower_return, &upper_return);
- // always return upper case, set modifier masks (SHIFT, ..)
- keySym = upper_return;
- modifiers = X11InputState2NewtModifiers(evt.xkey.state);
- } else {
- keyChar=0;
- }
- break;
-
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
- break;
-
- default:
- break;
- }
-
- switch(evt.type) {
- case ButtonPress:
- (*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #endif
- break;
- case ButtonRelease:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #endif
- break;
- case MotionNotify:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
- modifiers,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED,
- modifiers,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
- #endif
- break;
- case EnterNotify:
- DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #endif
- break;
- case LeaveNotify:
- DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #endif
- break;
- case KeyPress:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
- #endif
-
- break;
- case KeyRelease:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
- modifiers, X11KeySym2NewtVKey(keySym), (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(keySym), (jchar) keyChar);
-
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
- modifiers, (jint) -1, (jchar) keyChar);
- #endif
-
- break;
- case DestroyNotify:
- DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
- (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
- if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
- // ignore child destroy notification
- }
- break;
- case CreateNotify:
- DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n",
- (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
- break;
- case ConfigureNotify:
- DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n",
- (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
- evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height,
- evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
- if ( evt.xconfigure.window == evt.xconfigure.event ) {
- // ignore child window change notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
- }
- (*env)->CallVoidMethod(env, jwindow, sizeChangedID, JNI_FALSE,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
- (*env)->CallVoidMethod(env, jwindow, positionChangedID, JNI_FALSE,
- (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
- }
- break;
- case ClientMessage:
- if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
- DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n",
- (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
- (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
- // Called by Window.java: CloseWindow();
- num_events = 0; // end loop in case of destroyed display
- }
- break;
-
- case FocusIn:
- DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_TRUE);
- break;
-
- case FocusOut:
- DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_FALSE);
- break;
-
- case Expose:
- DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
-
- if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
- (*env)->CallVoidMethod(env, jwindow, windowRepaintID, JNI_FALSE,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
- }
- break;
-
- case MapNotify:
- DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
- (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect,
- evt.xmap.event!=evt.xmap.window);
- if( evt.xmap.event == evt.xmap.window ) {
- // ignore child window notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
- }
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
- }
- break;
-
- case UnmapNotify:
- DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n",
- (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure,
- evt.xunmap.event!=evt.xunmap.window);
- if( evt.xunmap.event == evt.xunmap.window ) {
- // ignore child window notification
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_FALSE);
- }
- break;
-
- case ReparentNotify:
- {
- jlong parentResult; // 0 if root, otherwise proper value
- Window winRoot, winTopParent;
- #ifdef VERBOSE_ON
- Window oldParentRoot, oldParentTopParent;
- Window parentRoot, parentTopParent;
- if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
- oldParentRoot=0; oldParentTopParent = 0;
- }
- if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
- parentRoot=0; parentTopParent = 0;
- }
- #endif
- if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
- winRoot=0; winTopParent = 0;
- }
- if(evt.xreparent.parent == winRoot) {
- parentResult = 0; // our java indicator for root window
- } else {
- parentResult = (jlong) (intptr_t) evt.xreparent.parent;
- }
- #ifdef VERBOSE_ON
- DBG_PRINT( "X11: event . ReparentNotify: call %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
- evt.xreparent.x, evt.xreparent.y,
- (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
- (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
- (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
- #endif
- (*env)->CallVoidMethod(env, jwindow, reparentNotifyID, (jlong)evt.xreparent.parent);
- }
- break;
-
- // unhandled events .. yet ..
-
- default:
- DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window);
- }
- }
-}
-
-
-/**
- * Screen
- */
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: GetScreen
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Screen * scrn= NULL;
-
- DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- scrn = ScreenOfDisplay(dpy, screen_index);
- if(scrn==NULL) {
- fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
- }
- DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
- return (jlong) (intptr_t) scrn;
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) XDisplayWidth( dpy, scrn_idx);
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) XDisplayHeight( dpy, scrn_idx);
-}
-
-
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
- if( 0 == XRRQueryVersion(dpy, major, minor) ) {
- return False;
- }
- return True;
-}
-
-static Bool NewtScreen_hasRANDR(Display *dpy) {
- int major, minor;
- return NewtScreen_getRANDRVersion(dpy, &major, &minor);
-}
-
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
- int rot;
- if(xrotation == RR_Rotate_0) {
- rot = 0;
- }
- else if(xrotation == RR_Rotate_90) {
- rot = 90;
- }
- else if(xrotation == RR_Rotate_180) {
- rot = 180;
- }
- else if(xrotation == RR_Rotate_270) {
- rot = 270;
- } else {
- NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
- }
- return rot;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getAvailableScreenModeRotations0
- * Signature: (JI)I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_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;
-
- if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
- fprintf(stderr, "RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
-
- if(0 != (rotations_supported & RR_Rotate_0)) {
- rotations[num_rotations++] = 0;
- }
- if(0 != (rotations_supported & RR_Rotate_90)) {
- rotations[num_rotations++] = 90;
- }
- if(0 != (rotations_supported & RR_Rotate_180)) {
- rotations[num_rotations++] = 180;
- }
- if(0 != (rotations_supported & RR_Rotate_270)) {
- rotations[num_rotations++] = 270;
- }
-
- jintArray properties = NULL;
-
- if(num_rotations>0) {
- properties = (*env)->NewIntArray(env, num_rotations);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
- }
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
- return 0;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
-
- return num_sizes;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeResolutions0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- // Fill the properties in temp jint array
- 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);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeRates0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- int num_rates;
- short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
-
- jint prop[num_rates];
- int i;
- for(i=0; i<num_rates; i++) {
- prop[i] = (int) rates[i];
- /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
- }
-
- jintArray properties = (*env)->NewIntArray(env, num_rates);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRate0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
- return -1;
- }
-
- // get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
-
- return (jint) original_rate;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRotation0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
- return -1;
- }
-
- //get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-
- Rotation rotation;
- XRRConfigCurrentConfiguration(conf, &rotation);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- return NewtScreen_XRotation2Degree(env, rotation);
-}
-
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenResolutionIndex0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
- return -1;
- }
-
- // 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;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModeStart0
- * Signature: (JIIII)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)screen_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0: RANDR not available\n");
- return 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);
- }
-
- conf = XRRGetScreenInfo(dpy, root);
-
- 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);
-
- XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
-
- XSync(dpy, False);
- XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
- XSync(dpy, False);
-
- //free
- XRRFreeScreenConfigInfo(conf);
- XSync(dpy, False);
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModePollEnd0
- * Signature: (J)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- int randr_event_base, randr_error_base;
- XEvent evt;
- XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
- return 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);
- }
-
- 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);
-
-}
-
/**
* Window
*/
@@ -1468,37 +442,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
(JNIEnv *env, jclass clazz)
{
- insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
- focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
- reparentNotifyID = (*env)->GetMethodID(env, clazz, "reparentNotify", "(J)V");
- windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
- windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
-
- if (insetsChangedID == NULL ||
- sizeChangedID == NULL ||
- positionChangedID == NULL ||
- focusChangedID == NULL ||
- visibleChangedID == NULL ||
- reparentNotifyID == NULL ||
- windowDestroyNotifyID == NULL ||
- windowRepaintID == NULL ||
- enqueueMouseEventID == NULL ||
- sendMouseEventID == NULL ||
- enqueueKeyEventID == NULL ||
- sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
- return JNI_FALSE;
- }
return JNI_TRUE;
}
@@ -1513,14 +456,12 @@ static Bool WaitForUnmapNotify( Display *dpy, XEvent *event, XPointer arg ) {
static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) {
if(width>0 && height>0 || x>=0 && y>=0) { // resize/position if requested
XWindowChanges xwc;
- int flags = 0;
+ int flags = CWX | CWY;
memset(&xwc, 0, sizeof(XWindowChanges));
- if(0<=x && 0<=y) {
- flags |= CWX | CWY;
- xwc.x=x;
- xwc.y=y;
- }
+ xwc.x=x;
+ xwc.y=y;
+
if(0<width && 0<height) {
flags |= CWWidth | CWHeight;
xwc.width=width;
@@ -1534,13 +475,12 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint
/*
* Class: jogamp_newt_driver_x11_X11Window
* Method: CreateWindow
- * Signature: (JJIJIIII)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
(JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index,
jlong visualID,
jlong javaObjectAtom, jlong windowDeleteAtom,
- jint x, jint y, jint width, jint height, int flags)
+ jint x, jint y, jint width, jint height, jboolean autoPosition, int flags)
{
Display * dpy = (Display *)(intptr_t)display;
Atom wm_delete_atom = (Atom)windowDeleteAtom;
@@ -1576,9 +516,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
if(0==windowParent) {
windowParent = root;
}
- DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d, alwaysOnTop %d\n",
+ DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
(void*)dpy, (void*)windowParent, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags));
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -1628,7 +568,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
{
int _x = x, _y = y; // pos for CreateWindow, might be tweaked
- if(0>_x || 0>_y) {
+ if(JNI_TRUE == autoPosition) {
// user didn't requested specific position, use WM default
_x = 0;
_y = 0;
@@ -1662,7 +602,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
{
XEvent event;
int left, right, top, bottom;
- Bool userPos = 0<=x && 0<=y ;
XMapWindow(dpy, window);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values
@@ -1671,19 +610,17 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom);
(*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
- if(!userPos) {
+ if(JNI_TRUE == autoPosition) {
// get position from WM
int dest_x, dest_y;
Window child;
XTranslateCoordinates(dpy, window, windowParent, 0, 0, &dest_x, &dest_y, &child);
x = (int)dest_x; y = (int)dest_y;
}
- DBG_PRINT("X11: [CreateWindow]: client: %d/%d %dx%d (is user-pos %d)\n", x, y, width, height, userPos);
+ DBG_PRINT("X11: [CreateWindow]: client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
x -= left; // top-level
y -= top; // top-level
- if(0>x) { x = 0; }
- if(0>y) { y = 0; }
DBG_PRINT("X11: [CreateWindow]: top-level: %d/%d\n", x, y);
NewtWindows_setPosSize(dpy, window, x, y, width, height);
@@ -1774,7 +711,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
fsEWMHFlags |= _NET_WM_ABOVE; // toggle above only
}
- displayDispatchErrorHandlerEnable(1, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(1, env);
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,
@@ -1792,7 +729,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) ) {
- displayDispatchErrorHandlerEnable(0, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
return;
}
}
@@ -1856,7 +793,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, True);
}
- displayDispatchErrorHandlerEnable(0, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
DBG_PRINT( "X11: reconfigureWindow0 X\n");
}
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java
index 21eb8af2d..74419e564 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTElektronActivity.java
@@ -62,7 +62,7 @@ public class NEWTElektronActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new ElektronenMultiplizierer());
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java
index 337dafc71..ba861d012 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES1Activity.java
@@ -62,7 +62,7 @@ public class NEWTGearsES1Activity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GearsES1(1));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
index 6abb0b354..89ecf4cb9 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2Activity.java
@@ -65,7 +65,7 @@ public class NEWTGearsES2Activity extends NewtBaseActivity {
GearsES2 demo = new GearsES2(0);
// demo.enableAndroidTrace(true);
glWindow.addGLEventListener(demo);
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java
index 691151ef3..d6b7507a3 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGearsES2TransActivity.java
@@ -61,7 +61,7 @@ public class NEWTGearsES2TransActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GearsES2(1));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java
index 83f35879b..1efedcd6d 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI1pActivity.java
@@ -61,7 +61,7 @@ public class NEWTGraphUI1pActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GPUUISceneGLListener0A(0));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java
index 17924d43d..39fb5e2cc 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTGraphUI2pActivity.java
@@ -62,7 +62,7 @@ public class NEWTGraphUI2pActivity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new GPUUISceneGLListener0A(Region.VBAA_RENDERING_BIT));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java
index 24b4eaf0c..99d7fd723 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES1Activity.java
@@ -61,7 +61,7 @@ public class NEWTRedSquareES1Activity extends NewtBaseActivity {
setContentView(getWindow(), glWindow);
glWindow.addGLEventListener(new RedSquareES1(1));
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java
index 51cddd523..804e627a5 100644
--- a/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java
+++ b/src/test/com/jogamp/opengl/test/android/NEWTRedSquareES2Activity.java
@@ -64,7 +64,7 @@ public class NEWTRedSquareES2Activity extends NewtBaseActivity {
final RedSquareES2 demo = new RedSquareES2(0);
// demo.enableAndroidTrace(true);
glWindow.addGLEventListener(demo);
- glWindow.getWindow().getScreen().addScreenModeListener(new ScreenModeListener() {
+ glWindow.getScreen().addScreenModeListener(new ScreenModeListener() {
public void screenModeChangeNotify(ScreenMode sm) { }
public void screenModeChanged(ScreenMode sm, boolean success) {
System.err.println("ScreenMode Changed: "+sm);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
index 55d3371c9..b6c3cc7fe 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestRegionRendererNEWT01.java
@@ -32,11 +32,6 @@ public class TestRegionRendererNEWT01 extends UITestCase {
org.junit.runner.JUnitCore.main(tstname);
}
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
static void destroyWindow(GLWindow window) {
if(null!=window) {
window.destroy();
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
index 9fd0c05e7..8f03af7c9 100755
--- a/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/TestTextRendererNEWT01.java
@@ -35,11 +35,6 @@ public class TestTextRendererNEWT01 extends UITestCase {
org.junit.runner.JUnitCore.main(tstname);
}
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
static void destroyWindow(GLWindow window) {
if(null!=window) {
window.destroy();
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java
index 5e0c266e6..160dc0ffe 100755
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo01.java
@@ -55,7 +55,6 @@ public class GPURegionNewtDemo01 {
static final boolean TRACE = false;
public static void main(String[] args) {
- GLProfile.initSingleton(true);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java
index f1db1ccdd..e7b5c73c5 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPURegionNewtDemo02.java
@@ -52,7 +52,6 @@ public class GPURegionNewtDemo02 {
static final boolean TRACE = false;
public static void main(String[] args) {
- GLProfile.initSingleton(true);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java
index bcd60d441..d257f78fc 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo01.java
@@ -49,7 +49,6 @@ public class GPUTextNewtDemo01 {
static final boolean TRACE = false;
public static void main(String[] args) {
- GLProfile.initSingleton(true);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java
index 5981e7971..1b71cd781 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUTextNewtDemo02.java
@@ -57,7 +57,6 @@ public class GPUTextNewtDemo02 {
static final boolean TRACE = false;
public static void main(String[] args) {
- GLProfile.initSingleton(true);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java
index 91f66875b..0563ab2cf 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo01.java
@@ -16,7 +16,6 @@ public class GPUUISceneNewtDemo01 {
static final boolean TRACE = false;
public static void main(String[] args) {
- GLProfile.initSingleton(true);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java
index a6cd770d1..4c8da139e 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/GPUUISceneNewtDemo02.java
@@ -17,7 +17,6 @@ public class GPUUISceneNewtDemo02 {
static final boolean TRACE = false;
public static void main(String[] args) {
- GLProfile.initSingleton(true);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
diff --git a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UINewtDemo01.java b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UINewtDemo01.java
index 27b7ecc13..0577c5ff0 100644
--- a/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UINewtDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/graph/demos/ui/UINewtDemo01.java
@@ -54,7 +54,6 @@ public class UINewtDemo01 {
static final boolean TRACE = false;
public static void main(String[] args) {
- GLProfile.initSingleton(true);
GLProfile glp = GLProfile.getGL2ES2();
GLCapabilities caps = new GLCapabilities(glp);
caps.setAlphaBits(4);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java
index a42247b12..62e74466f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug00NEWT.java
@@ -55,11 +55,6 @@ public class TestGLDebug00NEWT extends UITestCase {
static String dbgTstMsg0 = "Hello World";
static int dbgTstId0 = 42;
- @BeforeClass
- public static void initClass() {
- // GLProfile.initSingleton(true);
- }
-
public class WindowContext {
public final Window window;
public final GLContext context;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java
index 6ab6714dc..f9b566c25 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLDebug01NEWT.java
@@ -41,7 +41,6 @@ import javax.media.opengl.GLRunnable;
import org.junit.Assert;
import org.junit.Test;
-import org.junit.BeforeClass;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -51,11 +50,6 @@ public class TestGLDebug01NEWT extends UITestCase {
static String dbgTstMsg0 = "Hello World";
static int dbgTstId0 = 42;
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
GLWindow createWindow(GLProfile glp, boolean debugGL) {
GLCapabilities caps = new GLCapabilities(glp);
//
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
index 5af526364..e4245ef11 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLExtensionQueryOffscreen.java
@@ -42,6 +42,8 @@ import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLProfile;
+import jogamp.opengl.GLDrawableFactoryImpl;
+
import org.junit.Test;
public class TestGLExtensionQueryOffscreen {
@@ -52,9 +54,12 @@ public class TestGLExtensionQueryOffscreen {
instance.testJogl2ExtensionCheck2();
}
+ /**
+ * @deprecated This test uses a non public API in jogamp.opengl.* and hence is not recommended
+ */
@Test
public void testJogl2ExtensionCheck1() {
- GLDrawableFactory factory = GLDrawableFactory.getDesktopFactory();
+ GLDrawableFactoryImpl factory = (GLDrawableFactoryImpl) GLDrawableFactory.getDesktopFactory();
GLContext sharedContext = factory.getOrCreateSharedContext(null);
sharedContext.makeCurrent();
String extensions;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
index 7813482e1..6a5f76ff9 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestGLProfile01NEWT.java
@@ -137,17 +137,6 @@ public class TestGLProfile01NEWT extends UITestCase {
dumpVersion(glp);
}
- @Test
- public void test06GLProfileShutdownRecreate() throws InterruptedException {
- GLProfile.shutdown();
- GLProfile.initSingleton(true);
- System.out.println("GLProfile.getDefault(): "+GLProfile.getDefault());
- System.out.println("GLProfile.getDefaultDesktopDevice(): "+GLProfile.getDefaultDesktopDevice());
- System.out.println("GLProfile.getDefaultEGLDevice(): "+GLProfile.getDefaultEGLDevice());
- System.out.println("GLProfile.getDefaultDevice(): "+GLProfile.getDefaultDevice());
- }
-
-
protected void dumpVersion(GLProfile glp) throws InterruptedException {
GLCapabilities caps = new GLCapabilities(glp);
GLWindow glWindow = GLWindow.create(caps);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java
new file mode 100644
index 000000000..fc025d023
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestInitConcurrentNEWT.java
@@ -0,0 +1,230 @@
+/**
+ * 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 java.io.IOException;
+
+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 org.junit.Test;
+
+import com.jogamp.newt.NewtFactory;
+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;
+
+public class TestInitConcurrentNEWT 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 int id;
+ private Object postSync;
+ private boolean done = false;
+
+ public JOGLTask(Object postSync, int id) {
+ this.postSync = postSync;
+ this.id = id;
+ }
+ 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+" - "+Thread.currentThread().getName());
+ GLWindow glWindow = GLWindow.create(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);
+ 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()<duration) {
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ animator.stop();
+ glWindow.destroy();
+
+ System.err.println("JOGLTask "+id+": DONE/SYNC: "+Thread.currentThread().getName());
+ synchronized (postSync) {
+ done = true;
+ System.err.println("JOGLTask "+id+": END: "+Thread.currentThread().getName());
+ postSync.notifyAll();
+ }
+ }
+
+ public boolean done() { return done; }
+ }
+
+ protected static boolean done(JOGLTask[] tasks) {
+ for(int i=tasks.length-1; i>=0; i--) {
+ if(!tasks[i].done()) {
+ return false;
+ }
+ }
+ return true;
+ }
+ protected static String doneDump(JOGLTask[] tasks) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ for(int i=0; i<tasks.length; i++) {
+ if(i>0) {
+ 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) {
+ StringBuffer sb = new StringBuffer();
+ sb.append("[");
+ for(int i=0; i<threads.length; i++) {
+ if(i>0) {
+ 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<num; i++) {
+ tasks[i] = new JOGLTask(sync, i);
+ threads[i] = new Thread(tasks[i], currentThreadName+"-jt"+i);
+ }
+ for(i=0; i<num; i++) {
+ threads[i].start();
+ }
+ synchronized (sync) {
+ while(!done(tasks)) {
+ try {
+ sync.wait();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ Assert.assertTrue("Tasks are incomplete. Complete: "+doneDump(tasks), done(tasks));
+ i=0;
+ while(i<30 && !isDead(threads)) {
+ Thread.sleep(100);
+ i++;
+ }
+ Assert.assertTrue("Threads are still alive after 3s. Alive: "+isAliveDump(threads), isDead(threads));
+ }
+
+ @Test
+ public void test01OneThread() throws InterruptedException {
+ runJOGLTasks(1);
+ }
+
+ @Test
+ public void test02TwoThreads() throws InterruptedException {
+ runJOGLTasks(2);
+ }
+
+ @Test
+ public void test16SixteenThreads() throws InterruptedException {
+ runJOGLTasks(16);
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ String tstname = TestInitConcurrentNEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLCanvasAWT.java
new file mode 100644
index 000000000..5523ce5ce
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLCanvasAWT.java
@@ -0,0 +1,52 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+
+import javax.media.opengl.awt.GLCanvas;
+
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestMainVersionGLCanvasAWT extends UITestCase {
+
+ @Test
+ public void testMain() throws InterruptedException {
+ GLCanvas.main(null);
+ }
+
+
+ public static void main(String args[]) throws IOException {
+ String tstname = TestMainVersionGLCanvasAWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLWindowNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLWindowNEWT.java
new file mode 100644
index 000000000..d178e34f4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestMainVersionGLWindowNEWT.java
@@ -0,0 +1,50 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.io.IOException;
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestMainVersionGLWindowNEWT extends UITestCase {
+
+ @Test
+ public void testMain() throws InterruptedException {
+ GLWindow.main(null);
+ }
+
+
+ public static void main(String args[]) throws IOException {
+ String tstname = TestMainVersionGLWindowNEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNVSwapGroupNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNVSwapGroupNEWT.java
index 0f64738de..05f122bb4 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNVSwapGroupNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestNVSwapGroupNEWT.java
@@ -52,7 +52,6 @@ public class TestNVSwapGroupNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
caps = new GLCapabilities(glp);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
new file mode 100644
index 000000000..5f04ed616
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestPBufferDeadlockAWT.java
@@ -0,0 +1,127 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.DefaultGLCapabilitiesChooser;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.common.util.RunnableTask;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+public class TestPBufferDeadlockAWT extends UITestCase {
+ static GLProfile glp;
+ static int width, height;
+
+ @BeforeClass
+ public static void initClass() {
+ glp = GLProfile.getDefault();
+ Assert.assertNotNull( glp );
+ width = 512;
+ height = 512;
+ }
+
+ protected void runTestGL( GLCapabilities caps ) throws InterruptedException, InvocationTargetException {
+ final GLPbuffer pbuffer = GLDrawableFactory.getFactory( GLProfile.get( "GL2" ) ).createGLPbuffer(
+ null,
+ caps, new DefaultGLCapabilitiesChooser(),
+ 512, 512,
+ null
+ );
+
+ final boolean[] done = {false};
+ final Runnable pbufferCreationAction = new Runnable() {
+ public void run() {
+ System.err.println("AA.1");
+ pbuffer.display();
+ done[ 0 ] = true;
+ System.err.println("AA.X");
+ }
+ };
+
+ EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ Assert.assertTrue(EventQueue.isDispatchThread());
+ JAWTUtil.lockToolkit();
+ try {
+ final RunnableTask rTask = new RunnableTask(pbufferCreationAction, new Object(), false);
+ System.err.println("BB.0: "+rTask.getSyncObject());
+ synchronized (rTask.getSyncObject()) {
+ System.err.println("BB.1: "+rTask.getSyncObject());
+ new Thread(rTask, Thread.currentThread().getName()+"-Pbuffer_Creation").start();
+ try {
+ System.err.println("BB.2");
+ rTask.getSyncObject().wait();
+ System.err.println("BB.3");
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ System.err.println("BB.X");
+ }
+ } finally {
+ JAWTUtil.unlockToolkit();
+ }
+ }
+ });
+ Assert.assertTrue(done[0]);
+ }
+
+ @Test(timeout = 2000) // 2s timeout
+ public void testDeadlock() throws InterruptedException, InvocationTargetException {
+ GLCapabilities caps = new GLCapabilities( glp );
+ runTestGL( caps );
+ }
+
+ static long duration = 500; // ms
+
+ public static void main( String args[] ) {
+ for ( int i = 0; i < args.length; i++ ) {
+ if ( args[ i ].equals( "-time" ) ) {
+ i++;
+ try {
+ duration = Integer.parseInt( args[ i ] );
+ }
+ catch ( Exception ex ) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ org.junit.runner.JUnitCore.main( TestPBufferDeadlockAWT.class.getName() );
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
index f8f835c3b..308094720 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT.java
@@ -56,7 +56,6 @@ public class TestSharedContextListNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
caps = new GLCapabilities(glp);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
new file mode 100644
index 000000000..4281572d7
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextListNEWT2.java
@@ -0,0 +1,156 @@
+/**
+ * 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 java.io.IOException;
+
+import com.jogamp.newt.opengl.GLWindow;
+
+import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import com.jogamp.opengl.util.Animator;
+
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestSharedContextListNEWT2 extends UITestCase {
+ static GLProfile glp;
+ static GLCapabilities caps;
+ static int width, height;
+ GLWindow sharedDrawable;
+ Gears sharedGears;
+
+ @BeforeClass
+ public static void initClass() {
+ glp = GLProfile.get(GLProfile.GL2);
+ Assert.assertNotNull(glp);
+ caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ width = 256;
+ height = 256;
+ }
+
+ private void initShared() {
+ sharedDrawable = GLWindow.create(caps);
+ Assert.assertNotNull(sharedDrawable);
+ sharedGears = new Gears(0);
+ Assert.assertNotNull(sharedGears);
+ sharedDrawable.addGLEventListener(sharedGears);
+ sharedDrawable.setSize(width, height);
+ sharedDrawable.setVisible(true);
+ // init and render one frame, which will setup the Gears display lists
+ sharedDrawable.display();
+ }
+
+ private void releaseShared() {
+ Assert.assertNotNull(sharedDrawable);
+ sharedDrawable.destroy();
+ sharedDrawable = null;
+ }
+
+ protected GLWindow runTestGL(Animator animator, int x, int y, boolean useShared, boolean vsync) throws InterruptedException {
+ GLWindow glWindow = GLWindow.create(caps);
+
+ Assert.assertNotNull(glWindow);
+ glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared "+useShared);
+ if(useShared) {
+ glWindow.setSharedContext(sharedDrawable.getContext());
+ }
+
+ glWindow.setSize(width, height);
+
+ Gears gears = new Gears(vsync ? 1 : 0);
+ if(useShared) {
+ gears.setGears(sharedGears.getGear1(), sharedGears.getGear2(), sharedGears.getGear3());
+ }
+ glWindow.addGLEventListener(gears);
+
+ animator.add(glWindow);
+ animator.start();
+ glWindow.setVisible(true);
+
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow, true));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow, true));
+ glWindow.setPosition(x, y);
+
+ return glWindow;
+ }
+
+ @Test
+ public void test01() throws InterruptedException {
+ initShared();
+ GLWindow f1 = runTestGL(new Animator(), 0, 0, true, false);
+ InsetsImmutable insets = f1.getInsets();
+ GLWindow f2 = runTestGL(new Animator(), f1.getX()+width+insets.getTotalWidth(),
+ f1.getY()+0, true, false);
+ GLWindow f3 = runTestGL(new Animator(), f1.getX()+0,
+ f1.getY()+height+insets.getTotalHeight(), true, false);
+
+ try {
+ Thread.sleep(duration);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ // here we go again: On AMD/X11 the create/destroy sequence must be the same
+ // even though this is against the chicken/egg logic here ..
+ releaseShared();
+
+ f1.destroy();
+ f2.destroy();
+ f3.destroy();
+
+ // see above ..
+ // releaseShared();
+ }
+
+ static long duration = 2000; // ms
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ /**
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ System.err.println(stdin.readLine()); */
+ org.junit.runner.JUnitCore.main(TestSharedContextListNEWT2.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
new file mode 100644
index 000000000..60f46fe9e
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextNewtAWTBug523.java
@@ -0,0 +1,778 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.jogl.acore;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+import javax.media.opengl.GL2;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLContext;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPbuffer;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.media.opengl.glu.GLU;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.common.nio.Buffers;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.opengl.util.GLBuffers;
+
+
+/**
+ * TestSharedContextNewtAWTBug523
+ *
+ * Opens a single JFrame with two OpenGL windows and sliders to adjust the view orientation.
+ *
+ * Each window renders a red triangle and a blue triangle.
+ * The red triangle is rendered using glBegin / glVertex / glEnd.
+ * The blue triangle is rendered using vertex buffer objects bound to a vertex array object.
+ *
+ * If static useNewt is true, then those windows are GLWindow objects in a NewtCanvasAWT.
+ * If static useNewt is false, then those windows are GLCanvas objects.
+ *
+ * If shareContext is true, then the two OpenGL windows are initialized with a shared context,
+ * so that they share the vertex buffer and array objects and display lists.
+ * If shareContext is false, then the two OpenGL windows each have their own context, and the blue
+ * triangle fails to render in one of the windows.
+ *
+ * The four test cases run through the four combinations of useNewt and shareContext.
+ *
+ * Similar test cases are {@link TestSharedContextListNEWT}, {@link TestSharedContextListAWT},
+ * {@link TestSharedContextVBOES2NEWT} and {@link TestSharedContextVBOES1NEWT}.
+ *
+ */
+public class TestSharedContextNewtAWTBug523 extends UITestCase {
+
+ static long durationPerTest = 1000;
+
+ // counters for instances of event listener TwoTriangles
+ // private static int instanceCounter;
+ private static int initializationCounter;
+
+ // This semaphore is released once each time a GLEventListener destroy method is called.
+ // The main thread waits twice on this semaphore to ensure both canvases have finished cleaning up.
+ private static Semaphore disposalCompleteSemaphore = new Semaphore(0);
+
+ // Buffer objects can be shared across shared OpenGL context.
+ // If we run with sharedContext, then the tests will use these shared buffer objects,
+ // otherwise each event listener allocates its own buffer objects.
+ private static int [] sharedVertexBufferObjects = {0};
+ private static int [] sharedIndexBufferObjects = {0};
+ private static FloatBuffer sharedVertexBuffer;
+ private static IntBuffer sharedIndexBuffer;
+
+ static private GLPbuffer initShared(GLCapabilities caps) {
+ GLPbuffer sharedDrawable = GLDrawableFactory.getFactory(caps.getGLProfile()).createGLPbuffer(null, caps, null, 64, 64, null);
+ Assert.assertNotNull(sharedDrawable);
+ // init and render one frame, which will setup the Gears display lists
+ sharedDrawable.display();
+ return sharedDrawable;
+ }
+
+ static private void releaseShared(GLPbuffer sharedDrawable) {
+ if(null != sharedDrawable) {
+ sharedDrawable.destroy();
+ }
+ }
+
+ // inner class that implements the event listener
+ static class TwoTriangles implements GLEventListener {
+
+ boolean useShared;
+ int canvasWidth;
+ int canvasHeight;
+ private float boundsRadius = 2f;
+ private float viewDistance;
+ private float viewDistanceFactor = 1.0f;
+ private float xAxisRotation;
+ private float yAxisRotation;
+ private float viewFovDegrees = 15f;
+
+ // vertex array objects cannot be shared across open gl canvases;
+ //
+ // However, display lists can be shared across GLCanvas instances (if those canvases are initialized with the same GLContext),
+ // including a display list created in one context that uses a VAO.
+ private int [] vertexArrayObjects = {0};
+
+ // Buffer objects can be shared across canvas instances, if those canvases are initialized with the same GLContext.
+ // If we run with sharedBufferObjects true, then the tests will use these shared buffer objects.
+ // If we run with sharedBufferObjects false, then each event listener allocates its own buffer objects.
+ private int [] privateVertexBufferObjects = {0};
+ private int [] privateIndexBufferObjects = {0};
+ private FloatBuffer privateVertexBuffer;
+ private IntBuffer privateIndexBuffer;
+
+ TwoTriangles (int canvasWidth, int canvasHeight, boolean useShared) {
+ // instanceNum = instanceCounter++;
+ this.canvasWidth = canvasWidth;
+ this.canvasHeight = canvasHeight;
+ this.useShared = useShared;
+ }
+
+ public void setXAxisRotation(float xRot) {
+ xAxisRotation = xRot;
+ }
+
+ public void setYAxisRotation(float yRot) {
+ yAxisRotation = yRot;
+ }
+
+ public void setViewDistanceFactor(float factor) {
+ viewDistanceFactor = factor;
+ }
+
+
+ public void init(GLAutoDrawable drawable) {
+ GL2 gl2 = drawable.getGL().getGL2();
+
+ System.err.println("INIT GL IS: " + gl2.getClass().getName());
+
+ // Disable VSync
+ gl2.setSwapInterval(0);
+
+ // Setup the drawing area and shading mode
+ gl2.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+
+ // the first instance of TwoTriangles initializes the shared buffer objects;
+ // synchronizing to deal with potential liveness issues if the data is intialized from one thread and used on another
+ synchronized (this) {
+ gl2.glGenVertexArrays(1, vertexArrayObjects, 0);
+
+ gl2.glBindVertexArray(vertexArrayObjects[0]);
+
+ // use either the shared or private vertex buffers, as
+ int [] vertexBufferObjects;
+ int [] indexBufferObjects;
+ FloatBuffer vertexBuffer;
+ IntBuffer indexBuffer;
+ //
+ if (useShared) {
+ vertexBufferObjects = sharedVertexBufferObjects;
+ indexBufferObjects = sharedIndexBufferObjects;
+ vertexBuffer = sharedVertexBuffer;
+ indexBuffer = sharedIndexBuffer;
+ } else {
+ vertexBufferObjects = privateVertexBufferObjects;
+ indexBufferObjects = privateIndexBufferObjects;
+ vertexBuffer = privateVertexBuffer;
+ indexBuffer = privateIndexBuffer;
+ }
+
+ // if buffer sharing is enabled, then the first of the two event listeners to be
+ // initialized will allocate the buffers, and the other will re-use the allocated one
+ if (vertexBufferObjects[0] == 0) {
+ vertexBuffer = GLBuffers.newDirectFloatBuffer(18);
+ vertexBuffer.put(new float[]{
+ 1.0f, -0.5f, 0f, // vertex 1
+ 0f, 0f, 1f, // normal 1
+ 1.5f, -0.5f, 0f, // vertex 2
+ 0f, 0f, 1f, // normal 2
+ 1.0f, 0.5f, 0f, // vertex 3
+ 0f, 0f, 1f // normal 3
+ });
+ vertexBuffer.position(0);
+
+ gl2.glGenBuffers(1, vertexBufferObjects, 0);
+ gl2.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertexBufferObjects[0]);
+ gl2.glBufferData(GL2.GL_ARRAY_BUFFER, vertexBuffer.capacity() * Buffers.SIZEOF_FLOAT, vertexBuffer, GL2.GL_STATIC_DRAW);
+ }
+
+ // A check in the case that buffer sharing is enabled but context sharing is not enabled -- in that
+ // case, the buffer objects are not shareable, and the blue triangle cannot be rendereds.
+ // Furthermore, although the calls to bind and draw elements do not cause an error from glGetError
+ // when this check is removed, true blue triangle is not rendered anyways, and more importantly,
+ // I found that with my system glDrawElements causes a runtime exception 50% of the time. Executing the binds
+ // to unshareable buffers sets up glDrawElements for unpredictable crashes -- sometimes it does, sometimes not.
+ if (gl2.glIsBuffer(vertexBufferObjects[0])) {
+ gl2.glBindBuffer(GL2.GL_ARRAY_BUFFER, vertexBufferObjects[0]);
+ //
+ gl2.glEnableClientState(GL2.GL_VERTEX_ARRAY);
+ gl2.glVertexPointer(3, GL2.GL_FLOAT, 6 * GLBuffers.SIZEOF_FLOAT, 0);
+ //
+ gl2.glEnableClientState(GL2.GL_NORMAL_ARRAY);
+ gl2.glNormalPointer(GL2.GL_FLOAT, 6 * GLBuffers.SIZEOF_FLOAT, 3 * GLBuffers.SIZEOF_FLOAT);
+ }
+
+ if (indexBufferObjects[0] == 0) {
+ indexBuffer = GLBuffers.newDirectIntBuffer(3);
+ indexBuffer.put(new int[]{0, 1, 2});
+ indexBuffer.position(0);
+
+ gl2.glGenBuffers(1, indexBufferObjects, 0);
+ gl2.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, indexBufferObjects[0]);
+ gl2.glBufferData(GL2.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.capacity() * Buffers.SIZEOF_INT, indexBuffer, GL2.GL_STATIC_DRAW);
+ }
+
+ // again, a check in the case that buffer sharing is enabled but context sharing is not enabled
+ if (gl2.glIsBuffer(indexBufferObjects[0])) {
+ gl2.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, indexBufferObjects[0]);
+ }
+
+ gl2.glBindVertexArray(0);
+ gl2.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
+ gl2.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);
+ gl2.glDisableClientState(GL2.GL_VERTEX_ARRAY);
+ gl2.glDisableClientState(GL2.GL_NORMAL_ARRAY);
+
+ initializationCounter++;
+ } // synchronized (this)
+
+
+ viewDistance = setupViewFrustum(gl2, canvasWidth, canvasHeight, boundsRadius, 1.0f, viewFovDegrees);
+
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+
+ synchronized (this) {
+ initializationCounter--;
+
+ GL2 gl2 = drawable.getGL().getGL2();
+
+ gl2.glDeleteVertexArrays(1, vertexArrayObjects, 0);
+ vertexArrayObjects[0] = 0;
+ logAnyErrorCodes(gl2, "display");
+
+ // release shared resources
+ if (initializationCounter == 0 || !useShared) {
+ // use either the shared or private vertex buffers, as
+ int [] vertexBufferObjects;
+ int [] indexBufferObjects;
+ if (useShared) {
+ vertexBufferObjects = sharedVertexBufferObjects;
+ indexBufferObjects = sharedIndexBufferObjects;
+ } else {
+ vertexBufferObjects = privateVertexBufferObjects;
+ indexBufferObjects = privateIndexBufferObjects;
+ }
+
+ gl2.glDeleteBuffers(1, vertexBufferObjects, 0);
+ gl2.glDeleteBuffers(1, indexBufferObjects, 0);
+ vertexBufferObjects[0] = 0;
+ indexBufferObjects[0] = 0;
+ logAnyErrorCodes(gl2, "display");
+ }
+
+ // release the main thread once for each disposal
+ disposalCompleteSemaphore.release();
+ } // synchronized (this)
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ }
+
+ public void display(GLAutoDrawable drawable) {
+
+ // wait until all instances are initialized before attempting to draw using the
+ // vertex array object, because the buffers are allocated in init and when the
+ // buffers are shared, we need to ensure that they are allocated before trying to use thems
+ synchronized (this) {
+ if (initializationCounter != 2) {
+ return;
+ }
+ }
+
+ GL2 gl2 = drawable.getGL().getGL2();
+ GLU glu = new GLU();
+
+ // Clear the drawing area
+ gl2.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
+
+ gl2.glViewport(0, 0, canvasWidth, canvasHeight);
+ gl2.glMatrixMode(GL2.GL_PROJECTION);
+ gl2.glLoadIdentity();
+ glu.gluPerspective(viewFovDegrees, (float)canvasWidth/(float)canvasHeight,
+ viewDistance*viewDistanceFactor-boundsRadius, viewDistance*viewDistanceFactor+boundsRadius);
+
+ // Reset the current matrix to the "identity"
+ gl2.glMatrixMode(GL2.GL_MODELVIEW);
+ gl2.glLoadIdentity();
+
+ // draw the scene
+ gl2.glPushAttrib(GL2.GL_ALL_ATTRIB_BITS);
+ gl2.glPushMatrix();
+
+ glu.gluLookAt(0, 0, 0 + viewDistance*viewDistanceFactor, 0, 0, 0, 0, 1, 0);
+ gl2.glRotatef(xAxisRotation, 1, 0, 0);
+ gl2.glRotatef(yAxisRotation, 0, 1, 0);
+
+ gl2.glDisable(GL2.GL_CULL_FACE);
+ gl2.glEnable(GL2.GL_DEPTH_TEST);
+
+ // draw the triangles
+ drawTwoTriangles(gl2);
+
+ gl2.glPopMatrix();
+ gl2.glPopAttrib();
+
+ // Flush all drawing operations to the graphics card
+ gl2.glFlush();
+
+ logAnyErrorCodes(gl2, "display");
+ }
+
+ public void drawTwoTriangles(GL2 gl2) {
+
+ // draw a red triangle the old fashioned way
+ gl2.glColor3f(1f, 0f, 0f);
+ gl2.glBegin(GL2.GL_TRIANGLES);
+ gl2.glVertex3d(-1.5, -0.5, 0);
+ gl2.glNormal3d(0, 0, 1);
+ gl2.glVertex3d(-0.5, -0.5, 0);
+ gl2.glNormal3d(0, 0, 1);
+ gl2.glVertex3d(-0.75, 0.5, 0);
+ gl2.glNormal3d(0, 0, 1);
+ gl2.glEnd();
+
+ // draw the blue triangle using a vertex array object, sharing the vertex and index buffer objects across
+ // contexts; if context sharing is not initialized, then one window will simply have to live without a blue triangle
+ //
+ // synchronizing to deal with potential liveness issues if the data is intialized from one
+ // thread and used on another
+ boolean vaoBound = false;
+ // use either the shared or private vertex buffers, as
+ int [] vertexBufferObjects;
+ int [] indexBufferObjects;
+ synchronized (this) {
+ if (useShared) {
+ vertexBufferObjects = sharedVertexBufferObjects;
+ indexBufferObjects = sharedIndexBufferObjects;
+ } else {
+ vertexBufferObjects = privateVertexBufferObjects;
+ indexBufferObjects = privateIndexBufferObjects;
+ }
+ } // synchronized (this)
+
+ // A check in the case that buffer sharing is enabled but context sharing is not enabled -- in that
+ // case, the buffer objects are not shareable, and the blue triangle cannot be rendereds.
+ // Furthermore, although the calls to bind and draw elements do not cause an error from glGetError
+ // when this check is removed, true blue triangle is not rendered anyways, and more importantly,
+ // I found that with my system glDrawElements causes a runtime exception 50% of the time. Executing the binds
+ // to unshareable buffers sets up glDrawElements for unpredictable crashes -- sometimes it does, sometimes not.
+ if (gl2.glIsVertexArray(vertexArrayObjects[0]) &&
+ gl2.glIsBuffer(indexBufferObjects[0]) && gl2.glIsBuffer(vertexBufferObjects[0])) {
+ gl2.glBindVertexArray(vertexArrayObjects[0]);
+ gl2.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, indexBufferObjects[0]);
+ vaoBound = true;
+ }
+
+ logAnyErrorCodes(gl2, "drawTwoTriangles");
+
+ if (vaoBound) {
+ gl2.glColor3f(0f, 0f, 1f);
+ gl2.glDrawElements(GL2.GL_TRIANGLES, 3, GL2.GL_UNSIGNED_INT, 0);
+ gl2.glBindVertexArray(0);
+ gl2.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+ }
+
+ public void displayChanged(GLAutoDrawable drawable, boolean modeChanged, boolean deviceChanged) {
+ }
+
+ } // inner class TwoTriangles
+
+ public static void logAnyErrorCodes(GL2 gl2, String prefix) {
+ int glError = gl2.glGetError();
+ while (glError != GL2.GL_NO_ERROR) {
+ System.err.println(prefix + ", OpenGL error: 0x" + Integer.toHexString(glError));
+ glError = gl2.glGetError();
+ }
+ int status = gl2.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER);
+ if (status != GL2.GL_FRAMEBUFFER_COMPLETE) {
+ System.err.println(prefix + ", glCheckFramebufferStatus: 0x" + Integer.toHexString(status));
+ }
+ }
+
+ /**
+ * Sets the OpenGL projection matrix and front and back clipping planes for
+ * a viewport and returns the distance the camera should be placed from
+ * the center of the scene's bounding sphere such that the geometry is
+ * centered in the view frustum.
+ *
+ * @param gl2 current OpenGL context
+ * @param width width of GLDrawable
+ * @param height height of GLDrawable
+ * @param boundsRadius radius of a minimal bounding sphere of objects to be
+ * rendered in the viewport
+ * @param zoomFactor affects how far away the camera is placed from the scene; changing the
+ * zoom from 1.0 to 0.5 would make the scene appear half the size
+ * @param viewFovDegrees the desired field of vision for the viewport,
+ * higher is more fish-eye
+ * @return the distance the camera should be from the center of the scenes
+ * bounding sphere
+ */
+ public static float setupViewFrustum(GL2 gl2, int width, int height, float boundsRadius, float zoomFactor, float viewFovDegrees) {
+ assert boundsRadius > 0.0f;
+ assert zoomFactor > 0.0f;
+ assert viewFovDegrees > 0.0f;
+
+ GLU glu = new GLU();
+
+ final float aspectRatio = (float) width / (float) height;
+ final float boundRadiusAdjusted = boundsRadius / zoomFactor;
+ final float lowestFov = aspectRatio > 1.0f ? viewFovDegrees : aspectRatio * viewFovDegrees;
+ final float viewDist = (float) (boundRadiusAdjusted / Math.sin( (lowestFov / 2.0) * (Math.PI / 180.0) ));
+
+ gl2.glMatrixMode(GL2.GL_PROJECTION);
+ gl2.glLoadIdentity();
+ glu.gluPerspective(viewFovDegrees, aspectRatio, 0.1*viewDist, viewDist + boundRadiusAdjusted);
+
+ return viewDist;
+ }
+
+ @Test
+ public void testContextSharingCreateVisibleDestroy1() throws InterruptedException, InvocationTargetException {
+ testContextSharingCreateVisibleDestroy(false, false);
+ }
+
+ @Test
+ public void testContextSharingCreateVisibleDestroy2() throws InterruptedException, InvocationTargetException {
+ testContextSharingCreateVisibleDestroy(false, true);
+ }
+
+ @Test
+ public void testContextSharingCreateVisibleDestroy3() throws InterruptedException, InvocationTargetException {
+ testContextSharingCreateVisibleDestroy(true, false);
+ }
+
+ @Test
+ public void testContextSharingCreateVisibleDestroy4() throws InterruptedException, InvocationTargetException {
+ testContextSharingCreateVisibleDestroy(true, true);
+ }
+
+ /**
+ * Assemble the user interface and start the animator.
+ * It waits until the window is closed an then attempts orderly shutdown and resource deallocation.
+ */
+ public void testContextSharingCreateVisibleDestroy(final boolean useNewt, final boolean shareContext) throws InterruptedException, InvocationTargetException {
+ final JFrame frame = new JFrame("Simple JOGL App for testing context sharing");
+ //
+ // GLDrawableFactory factory = GLDrawableFactory.getFactory(GLProfile.get(GLProfile.GL2));
+ // GLContext sharedContext = factory.getOrCreateSharedContext(factory.getDefaultDevice());
+ //
+ GLCapabilities glCapabilities = new GLCapabilities(GLProfile.get(GLProfile.GL2));
+ glCapabilities.setSampleBuffers(true);
+ glCapabilities.setNumSamples(4);
+
+ final GLPbuffer sharedDrawable;
+ final GLContext sharedContext;
+ if(shareContext) {
+ sharedDrawable = initShared(glCapabilities);
+ sharedContext = sharedDrawable.getContext();
+ } else {
+ sharedDrawable = null;
+ sharedContext = null;
+ }
+
+ final TwoTriangles eventListener1 = new TwoTriangles(640, 480, shareContext);
+ final TwoTriangles eventListener2 = new TwoTriangles(320, 480, shareContext);
+
+ final Component openGLComponent1;
+ final Component openGLComponent2;
+ final GLAutoDrawable openGLAutoDrawable1;
+ final GLAutoDrawable openGLAutoDrawable2;
+
+ if (useNewt) {
+ GLWindow glWindow1 = GLWindow.create(glCapabilities);
+ glWindow1.setSharedContext(sharedContext);
+ NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
+ newtCanvasAWT1.setPreferredSize(new Dimension(eventListener1.canvasWidth, eventListener1.canvasHeight));
+ glWindow1.addGLEventListener(eventListener1);
+ //
+ GLWindow glWindow2 = GLWindow.create(glCapabilities);
+ NewtCanvasAWT newtCanvasAWT2 = new NewtCanvasAWT(glWindow2);
+ newtCanvasAWT2.setPreferredSize(new Dimension(eventListener2.canvasWidth, eventListener2.canvasHeight));
+ glWindow2.addGLEventListener(eventListener2);
+
+ openGLComponent1 = newtCanvasAWT1;
+ openGLComponent2 = newtCanvasAWT2;
+ openGLAutoDrawable1 = glWindow1;
+ openGLAutoDrawable2 = glWindow2;
+ } else {
+ // Implementation using two GLCanvas instances; for GLCanvas context sharing to work, you must pass it in
+ // through the constructor; if you set it after it has no effect -- it does no harm if you initialized the ctor
+ // with the shared context, but if you didn't, it also doesn't trigger sharing
+ final GLCanvas canvas1;
+ final GLCanvas canvas2;
+
+ if (shareContext) {
+ canvas1 = new GLCanvas(glCapabilities, sharedContext);
+ canvas2 = new GLCanvas(glCapabilities, sharedContext);
+ } else {
+ canvas1 = new GLCanvas(glCapabilities);
+ canvas2 = new GLCanvas(glCapabilities);
+ }
+
+ canvas1.setSize(eventListener1.canvasWidth, eventListener1.canvasHeight);
+ canvas1.addGLEventListener(eventListener1);
+ //
+ canvas2.setSize(eventListener2.canvasWidth, eventListener2.canvasHeight);
+ canvas2.addGLEventListener(eventListener2);
+
+ openGLComponent1 = canvas1;
+ openGLComponent2 = canvas2;
+ openGLAutoDrawable1 = canvas1;
+ openGLAutoDrawable2 = canvas2;
+ }
+
+ // Create slider for x rotation.
+ // The vertically oriented slider rotates around the x axis
+ final JSlider xAxisRotationSlider = new JSlider(JSlider.VERTICAL, -180, 180, 1);
+ xAxisRotationSlider.setPaintTicks(false);
+ xAxisRotationSlider.setPaintLabels(false);
+ xAxisRotationSlider.setSnapToTicks(false);
+ xAxisRotationSlider.addChangeListener(new ChangeListener() {
+
+ public void stateChanged(ChangeEvent e) {
+ eventListener1.setXAxisRotation(xAxisRotationSlider.getValue());
+ eventListener2.setXAxisRotation(xAxisRotationSlider.getValue());
+ }
+ });
+ JLabel xAxisRotationLabel = new JLabel("X-Axis Rotation");
+
+ // Create slider for y rotation.
+ // The horizontally oriented slider rotates around the y axis
+ final JSlider yAxisRotationSlider = new JSlider(JSlider.HORIZONTAL, -180, 180, 1);
+ yAxisRotationSlider.setPaintTicks(false);
+ yAxisRotationSlider.setPaintLabels(false);
+ yAxisRotationSlider.setSnapToTicks(false);
+ yAxisRotationSlider.addChangeListener(new ChangeListener() {
+
+ public void stateChanged(ChangeEvent e) {
+ eventListener1.setYAxisRotation(yAxisRotationSlider.getValue());
+ eventListener2.setYAxisRotation(yAxisRotationSlider.getValue());
+ }
+ });
+ JLabel yAxisRotationLabel = new JLabel("Y-Axis Rotation");
+
+ // Create slider for view distance factor.
+ // We want a range of 0.0 to 10.0 with 0.1 increments (so we can scale down using 0.0 to 1.0).
+ // So, set JSlider to 0 to 100 and divide by 10.0 in stateChanged
+ final JSlider viewDistanceFactorSlider = new JSlider(JSlider.HORIZONTAL, 0, 100, 10);
+ viewDistanceFactorSlider.setPaintTicks(false);
+ viewDistanceFactorSlider.setPaintLabels(false);
+ viewDistanceFactorSlider.setSnapToTicks(false);
+ viewDistanceFactorSlider.addChangeListener(new ChangeListener() {
+
+ public void stateChanged(ChangeEvent e) {
+ eventListener1.setViewDistanceFactor((float) viewDistanceFactorSlider.getValue() / 10.0f);
+ eventListener2.setViewDistanceFactor((float) viewDistanceFactorSlider.getValue() / 10.0f);
+ }
+ });
+ JLabel viewDistanceFactorLabel = new JLabel("View Distance Factor");
+
+ // group the view distance and label into a vertical panel
+ JPanel viewDistancePanel = new JPanel();
+ viewDistancePanel.setLayout(new BoxLayout(viewDistancePanel, BoxLayout.PAGE_AXIS));
+ viewDistancePanel.add(Box.createVerticalGlue());
+ viewDistancePanel.add(viewDistanceFactorSlider);
+ viewDistancePanel.add(viewDistanceFactorLabel);
+ viewDistancePanel.add(Box.createVerticalGlue());
+
+ // group both OpenGL canvases / windows into a horizontal panel
+ JPanel openGLPanel = new JPanel();
+ openGLPanel.setLayout(new BoxLayout(openGLPanel, BoxLayout.LINE_AXIS));
+ openGLPanel.add(openGLComponent1);
+ openGLPanel.add(Box.createHorizontalStrut(5));
+ openGLPanel.add(openGLComponent2);
+
+ // group the open GL panel and the y-axis rotation slider into a vertical panel.
+ JPanel canvasAndYAxisPanel = new JPanel();
+ canvasAndYAxisPanel.setLayout(new BoxLayout(canvasAndYAxisPanel, BoxLayout.PAGE_AXIS));
+ canvasAndYAxisPanel.add(openGLPanel);
+ canvasAndYAxisPanel.add(Box.createVerticalGlue());
+ canvasAndYAxisPanel.add(yAxisRotationSlider);
+ canvasAndYAxisPanel.add(yAxisRotationLabel);
+
+ // group the X-axis rotation slider and label into a horizontal panel.
+ JPanel xAxisPanel = new JPanel();
+ xAxisPanel.setLayout(new BoxLayout(xAxisPanel, BoxLayout.LINE_AXIS));
+ xAxisPanel.add(xAxisRotationSlider);
+ xAxisPanel.add(xAxisRotationLabel);
+
+ JPanel mainPanel = (JPanel) frame.getContentPane();
+ mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.LINE_AXIS));
+ mainPanel.add(viewDistancePanel);
+ mainPanel.add(Box.createHorizontalGlue());
+ mainPanel.add(canvasAndYAxisPanel);
+ mainPanel.add(Box.createHorizontalGlue());
+ mainPanel.add(xAxisPanel);
+
+ final Animator animator = new Animator(Thread.currentThread().getThreadGroup());
+ animator.setUpdateFPSFrames(1, null);
+ animator.add(openGLAutoDrawable1);
+ animator.add(openGLAutoDrawable2);
+
+ final Semaphore windowOpenSemaphore = new Semaphore(0);
+ final Semaphore closingSemaphore = new Semaphore(0);
+
+ // signal the main thread when the frame is closed
+ frame.addWindowListener(new WindowAdapter() {
+
+ @Override
+ public void windowClosing(WindowEvent e) {
+ closingSemaphore.release();
+ }
+ });
+
+ // make the window visible using the EDT
+ SwingUtilities.invokeLater( new Runnable() {
+ public void run() {
+ frame.pack();
+ frame.setVisible(true);
+ windowOpenSemaphore.release();
+ }
+ });
+
+ // wait for the window to be visible and start the animation
+ try {
+ boolean windowOpened = windowOpenSemaphore.tryAcquire(5000, TimeUnit.MILLISECONDS);
+ Assert.assertEquals(true, windowOpened);
+ } catch (InterruptedException e) {
+ System.err.println("Closing wait interrupted: " + e.getMessage());
+ }
+ animator.start();
+
+ // sleep for test duration, then request the window to close, wait for the window to close,s and stop the animation
+ try {
+ while(animator.isAnimating() && animator.getTotalFPSDuration() < durationPerTest) {
+ Thread.sleep(100);
+ }
+ AWTRobotUtil.closeWindow(frame, true);
+ boolean windowClosed = closingSemaphore.tryAcquire(5000, TimeUnit.MILLISECONDS);
+ Assert.assertEquals(true, windowClosed);
+ } catch (InterruptedException e) {
+ System.err.println("Closing wait interrupted: " + e.getMessage());
+ }
+ animator.stop();
+
+ // ask the EDT to dispose of the frame;
+ // if using newt, explicitly dispose of the canvases because otherwise it seems our destroy methods are not called
+ SwingUtilities.invokeLater( new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.dispose();
+ if (useNewt) {
+ ((NewtCanvasAWT)openGLComponent1).destroy();
+ ((NewtCanvasAWT)openGLComponent2).destroy();
+ }
+ closingSemaphore.release();
+ }
+ });
+
+ // wait for orderly destruction; it seems that if we share a GLContext across newt windows, bad things happen;
+ // I must be doing something wrong but I haven't figured it out yet
+ try {
+ boolean windowsDisposed = closingSemaphore.tryAcquire(5000, TimeUnit.MILLISECONDS);
+ Assert.assertEquals(true, windowsDisposed);
+ } catch (InterruptedException e) {
+ System.err.println("Closing wait interrupted: " + e.getMessage());
+ }
+
+ // ensure that the two OpenGL canvas' destroy methods completed successfully and released resources before we move on
+ int disposalSuccesses = 0;
+ try {
+ boolean acquired;
+ acquired = disposalCompleteSemaphore.tryAcquire(5000, TimeUnit.MILLISECONDS);
+ if (acquired){
+ disposalSuccesses++;
+ }
+ acquired = disposalCompleteSemaphore.tryAcquire(5000, TimeUnit.MILLISECONDS);
+ if (acquired){
+ disposalSuccesses++;
+ }
+ } catch (InterruptedException e) {
+ System.err.println("Clean exit interrupted: " + e.getMessage());
+ }
+
+ Assert.assertEquals(true, disposalSuccesses == 2);
+
+ releaseShared(sharedDrawable);
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String[] args) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ if (++i < args.length) {
+ durationPerTest = atoi(args[i]);
+ }
+ }
+ }
+
+ String testname = TestSharedContextNewtAWTBug523.class.getName();
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ testname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+testname+".xml" } );
+ }
+
+}
+
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
index 5d76702ea..6e48e44fe 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES1NEWT.java
@@ -54,7 +54,6 @@ public class TestSharedContextVBOES1NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
caps = new GLCapabilities(glp);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
index dd3e1f347..022ef2142 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT.java
@@ -54,7 +54,6 @@ public class TestSharedContextVBOES2NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
caps = new GLCapabilities(glp);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
new file mode 100644
index 000000000..5b2cb25b3
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestSharedContextVBOES2NEWT2.java
@@ -0,0 +1,157 @@
+/**
+ * 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 java.io.IOException;
+
+import com.jogamp.newt.opengl.GLWindow;
+
+import javax.media.nativewindow.util.InsetsImmutable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import com.jogamp.opengl.util.Animator;
+
+import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class TestSharedContextVBOES2NEWT2 extends UITestCase {
+ static GLProfile glp;
+ static GLCapabilities caps;
+ static int width, height;
+ GLWindow sharedDrawable;
+ GearsES2 sharedGears;
+
+ @BeforeClass
+ public static void initClass() {
+ glp = GLProfile.get(GLProfile.GL2);
+ Assert.assertNotNull(glp);
+ caps = new GLCapabilities(glp);
+ Assert.assertNotNull(caps);
+ width = 256;
+ height = 256;
+ }
+
+ private void initShared() {
+ sharedDrawable = GLWindow.create(caps);
+ Assert.assertNotNull(sharedDrawable);
+ // sharedGears = new Gears(0);
+ sharedGears = new GearsES2(0);
+ Assert.assertNotNull(sharedGears);
+ sharedDrawable.addGLEventListener(sharedGears);
+ sharedDrawable.setSize(width, height);
+ sharedDrawable.setVisible(true);
+ // init and render one frame, which will setup the Gears display lists
+ sharedDrawable.display();
+ }
+
+ private void releaseShared() {
+ Assert.assertNotNull(sharedDrawable);
+ sharedDrawable.destroy();
+ sharedDrawable = null;
+ }
+
+ protected GLWindow runTestGL(Animator animator, int x, int y, boolean useShared, boolean vsync) throws InterruptedException {
+ GLWindow glWindow = GLWindow.create(caps);
+
+ Assert.assertNotNull(glWindow);
+ glWindow.setTitle("Shared Gears NEWT Test: "+x+"/"+y+" shared "+useShared);
+ if(useShared) {
+ glWindow.setSharedContext(sharedDrawable.getContext());
+ }
+
+ glWindow.setSize(width, height);
+
+ GearsES2 gears = new GearsES2(vsync ? 1 : 0);
+ if(useShared) {
+ gears.setGears(sharedGears.getGear1(), sharedGears.getGear2(), sharedGears.getGear3());
+ }
+ glWindow.addGLEventListener(gears);
+
+ animator.add(glWindow);
+ animator.start();
+ glWindow.setVisible(true);
+
+ Assert.assertTrue(AWTRobotUtil.waitForRealized(glWindow, true));
+ Assert.assertTrue(AWTRobotUtil.waitForVisible(glWindow, true));
+ glWindow.setPosition(x, y);
+
+ return glWindow;
+ }
+
+ @Test
+ public void test01() throws InterruptedException {
+ initShared();
+ GLWindow f1 = runTestGL(new Animator(), 0, 0, true, false);
+ InsetsImmutable insets = f1.getInsets();
+ GLWindow f2 = runTestGL(new Animator(), f1.getX()+width+insets.getTotalWidth(),
+ f1.getY()+0, true, false);
+ GLWindow f3 = runTestGL(new Animator(), f1.getX()+0,
+ f1.getY()+height+insets.getTotalHeight(), true, false);
+
+ try {
+ Thread.sleep(duration);
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+
+ // here we go again: On AMD/X11 the create/destroy sequence must be the same
+ // even though this is against the chicken/egg logic here ..
+ releaseShared();
+
+ f1.destroy();
+ f2.destroy();
+ f3.destroy();
+
+ // see above ..
+ // releaseShared();
+ }
+
+ static long duration = 2000; // ms
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ /**
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ System.err.println(stdin.readLine()); */
+ org.junit.runner.JUnitCore.main(TestSharedContextVBOES2NEWT2.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
new file mode 100644
index 000000000..322ce36c4
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteAWT.java
@@ -0,0 +1,125 @@
+/**
+ * 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 java.awt.Frame;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestShutdownCompleteAWT extends UITestCase {
+
+ static long duration = 300; // ms
+
+ protected void runTestGL() throws InterruptedException, InvocationTargetException {
+ final Frame frame = new Frame("Gears AWT Test");
+ Assert.assertNotNull(frame);
+
+ final GLCanvas glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getDefault()));
+ Assert.assertNotNull(glCanvas);
+ frame.add(glCanvas);
+ frame.setSize(256, 256);
+
+ glCanvas.addGLEventListener(new Gears(1));
+
+ Animator animator = new Animator(glCanvas);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(true);
+ }});
+
+ animator.setUpdateFPSFrames(60, System.err);
+ animator.start();
+ Assert.assertEquals(true, animator.isAnimating());
+ Assert.assertEquals(true, glCanvas.isVisible());
+ Assert.assertEquals(true, glCanvas.isDisplayable());
+
+ while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+ Assert.assertEquals(true, glCanvas.isRealized());
+
+ animator.stop();
+ Assert.assertEquals(false, animator.isAnimating());
+ frame.setVisible(false);
+ Assert.assertEquals(false, frame.isVisible());
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.remove(glCanvas);
+ frame.dispose();
+ }});
+ }
+
+ protected void oneLife() throws InterruptedException, InvocationTargetException {
+ long t0 = System.nanoTime();
+ GLProfile.initSingleton();
+ long t1 = System.nanoTime();
+ runTestGL();
+ long t2 = System.nanoTime();
+ GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);
+ long t3 = System.nanoTime();
+ System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
+ System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
+ System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
+ System.err.println(" GLProfile.shutdown(COMPLETE): "+ (t3-t2)/1e6 +"ms");
+ }
+
+ @Test
+ public void test01OneLife() throws InterruptedException, InvocationTargetException {
+ oneLife();
+ }
+
+ @Test
+ public void test01AnotherLife() throws InterruptedException, InvocationTargetException {
+ oneLife();
+ }
+
+ @Test
+ public void test01TwoLifes() throws InterruptedException, InvocationTargetException {
+ oneLife();
+ oneLife();
+ }
+
+ public static void main(String args[]) throws IOException {
+ String tstname = TestShutdownCompleteAWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
new file mode 100644
index 000000000..1abac1094
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownCompleteNEWT.java
@@ -0,0 +1,144 @@
+/**
+ * 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 java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestShutdownCompleteNEWT extends UITestCase {
+
+ static long duration = 300; // ms
+
+ protected void runTestGL() throws InterruptedException {
+ GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getDefault()));
+ Assert.assertNotNull(glWindow);
+ glWindow.setTitle("Gears NEWT Test");
+
+ glWindow.addGLEventListener(new Gears());
+
+ Animator animator = new Animator(glWindow);
+
+ glWindow.setSize(256, 256);
+ glWindow.setVisible(true);
+ animator.setUpdateFPSFrames(60, System.err);
+ animator.start();
+ Assert.assertEquals(true, animator.isAnimating());
+ Assert.assertEquals(true, glWindow.isVisible());
+ Assert.assertEquals(true, glWindow.isNativeValid());
+ Assert.assertEquals(true, glWindow.isRealized());
+
+ while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+
+ animator.stop();
+ glWindow.destroy();
+ }
+
+ protected void oneLife() throws InterruptedException {
+ if(waitForEach) {
+ waitForEnter();
+ }
+ long t0 = System.nanoTime();
+ GLProfile.initSingleton();
+ long t1 = System.nanoTime();
+ if(!initOnly) {
+ runTestGL();
+ }
+ long t2 = System.nanoTime();
+ GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);
+ long t3 = System.nanoTime();
+ System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
+ System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
+ System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
+ System.err.println(" GLProfile.shutdown(COMPLETE): "+ (t3-t2)/1e6 +"ms");
+ }
+
+ @Test
+ public void test01OneLife() throws InterruptedException {
+ oneLife();
+ }
+
+ @Test
+ public void test01AnotherLife() throws InterruptedException {
+ oneLife();
+ }
+
+ @Test
+ public void test01TwoLifes() throws InterruptedException {
+ oneLife();
+ oneLife();
+ }
+
+ static boolean initOnly = false;
+ static boolean waitForEach = false;
+
+ static void waitForEnter() {
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ try {
+ System.err.println(stdin.readLine());
+ } catch (IOException e) { }
+ }
+
+ public static void main(String args[]) throws IOException {
+ boolean waitForKey = false;
+
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-wait")) {
+ waitForKey = true;
+ } else if(args[i].equals("-waitForEach")) {
+ waitForEach = true;
+ waitForKey = true;
+ } else if(args[i].equals("-initOnly")) {
+ initOnly = true;
+ }
+ }
+
+ if(waitForKey) {
+ waitForEnter();
+ }
+
+ String tstname = TestShutdownCompleteNEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java
new file mode 100644
index 000000000..a12ef2327
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedAWT.java
@@ -0,0 +1,124 @@
+/**
+ * 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 java.awt.Frame;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestShutdownSharedAWT extends UITestCase {
+
+ static long duration = 300; // ms
+
+ protected void runTestGL() throws InterruptedException, InvocationTargetException {
+ final Frame frame = new Frame("Gears AWT Test");
+ Assert.assertNotNull(frame);
+
+ final GLCanvas glCanvas = new GLCanvas(new GLCapabilities(GLProfile.getDefault()));
+ Assert.assertNotNull(glCanvas);
+ frame.add(glCanvas);
+ frame.setSize(256, 256);
+
+ glCanvas.addGLEventListener(new Gears(1));
+
+ Animator animator = new Animator(glCanvas);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(true);
+ }});
+ animator.setUpdateFPSFrames(60, System.err);
+ animator.start();
+ Assert.assertEquals(true, animator.isAnimating());
+ Assert.assertEquals(true, glCanvas.isVisible());
+ Assert.assertEquals(true, glCanvas.isDisplayable());
+
+ while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+ Assert.assertEquals(true, glCanvas.isRealized());
+
+ animator.stop();
+ Assert.assertEquals(false, animator.isAnimating());
+ frame.setVisible(false);
+ Assert.assertEquals(false, frame.isVisible());
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.remove(glCanvas);
+ frame.dispose();
+ }});
+ }
+
+ protected void oneLife() throws InterruptedException, InvocationTargetException {
+ long t0 = System.nanoTime();
+ GLProfile.initSingleton();
+ long t1 = System.nanoTime();
+ runTestGL();
+ long t2 = System.nanoTime();
+ GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY);
+ long t3 = System.nanoTime();
+ System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
+ System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
+ System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
+ System.err.println(" GLProfile.shutdown(SHARED): "+ (t3-t2)/1e6 +"ms");
+ }
+
+ @Test
+ public void test01OneLife() throws InterruptedException, InvocationTargetException {
+ oneLife();
+ }
+
+ @Test
+ public void test01AnotherLife() throws InterruptedException, InvocationTargetException {
+ oneLife();
+ }
+
+ @Test
+ public void test01TwoLifes() throws InterruptedException, InvocationTargetException {
+ oneLife();
+ oneLife();
+ }
+
+ public static void main(String args[]) throws IOException {
+ String tstname = TestShutdownSharedAWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java
new file mode 100644
index 000000000..99b5a6c48
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/TestShutdownSharedNEWT.java
@@ -0,0 +1,127 @@
+/**
+ * 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 java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestShutdownSharedNEWT extends UITestCase {
+
+ static long duration = 300; // ms
+
+ protected void runTestGL() throws InterruptedException {
+ GLWindow glWindow = GLWindow.create(new GLCapabilities(GLProfile.getDefault()));
+ Assert.assertNotNull(glWindow);
+ glWindow.setTitle("Gears NEWT Test");
+
+ glWindow.addGLEventListener(new Gears());
+
+ Animator animator = new Animator(glWindow);
+
+ glWindow.setSize(256, 256);
+ glWindow.setVisible(true);
+ animator.setUpdateFPSFrames(60, System.err);
+ animator.start();
+ Assert.assertEquals(true, animator.isAnimating());
+ Assert.assertEquals(true, glWindow.isVisible());
+ Assert.assertEquals(true, glWindow.isNativeValid());
+ Assert.assertEquals(true, glWindow.isRealized());
+
+ while(animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+
+ animator.stop();
+ glWindow.destroy();
+ }
+
+ protected void oneLife() throws InterruptedException {
+ long t0 = System.nanoTime();
+ GLProfile.initSingleton();
+ long t1 = System.nanoTime();
+ runTestGL();
+ long t2 = System.nanoTime();
+ GLProfile.shutdown(GLProfile.ShutdownType.SHARED_ONLY);
+ long t3 = System.nanoTime();
+ System.err.println("Total: "+ (t3-t0)/1e6 +"ms");
+ System.err.println(" GLProfile.initSingleton(): "+ (t1-t0)/1e6 +"ms");
+ System.err.println(" Demo Code: "+ (t2-t1)/1e6 +"ms");
+ System.err.println(" GLProfile.shutdown(SHARED): "+ (t3-t2)/1e6 +"ms");
+ }
+
+ @Test
+ public void test01OneLife() throws InterruptedException {
+ oneLife();
+ }
+
+ @Test
+ public void test01AnotherLife() throws InterruptedException {
+ oneLife();
+ }
+
+ @Test
+ public void test01TwoLifes() throws InterruptedException {
+ oneLife();
+ oneLife();
+ }
+
+ public static void main(String args[]) throws IOException {
+ boolean waitForKey = false;
+
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-wait")) {
+ waitForKey = true;
+ }
+ }
+
+ if(waitForKey) {
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ try {
+ System.err.println(stdin.readLine());
+ } catch (IOException e) { }
+ }
+
+ String tstname = TestShutdownSharedNEWT.class.getName();
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWTCardLayoutAnimatorStartStopBug532.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWTCardLayoutAnimatorStartStopBug532.java
new file mode 100644
index 000000000..5415ad159
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestAWTCardLayoutAnimatorStartStopBug532.java
@@ -0,0 +1,229 @@
+package com.jogamp.opengl.test.junit.jogl.awt;
+
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.Dimension;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.nativewindow.NativeWindow;
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import jogamp.nativewindow.windows.GDI;
+
+import org.junit.Test;
+
+import com.jogamp.common.os.Platform;
+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 com.jogamp.opengl.util.FPSAnimator;
+
+public class TestAWTCardLayoutAnimatorStartStopBug532 extends UITestCase {
+ static final String LABEL = "Label";
+ static final String CANVAS = "GLCanvas";
+
+ public enum AnimatorControlBehavior {
+ StartStop, PauseResume, Continue;
+ }
+
+ static long durationPerTest = 200*4; // ms
+ static boolean manual = false;
+ static volatile boolean shouldStop = false;
+
+ private String selected = LABEL;
+
+ @Test
+ public void testFPSAnimatorStartStop() throws InterruptedException, InvocationTargetException {
+ testImpl(AnimatorControlBehavior.StartStop, true);
+ }
+
+ @Test
+ public void testFPSAnimatorResumePause() throws InterruptedException, InvocationTargetException {
+ testImpl(AnimatorControlBehavior.PauseResume, true);
+ }
+
+ @Test
+ public void testFPSAnimatorContinue() throws InterruptedException, InvocationTargetException {
+ testImpl(AnimatorControlBehavior.Continue, true);
+ }
+
+ @Test
+ public void testAnimatorStartStop() throws InterruptedException, InvocationTargetException {
+ testImpl(AnimatorControlBehavior.StartStop, false);
+ }
+
+ @Test
+ public void testAnimatorResumePause() throws InterruptedException, InvocationTargetException {
+ testImpl(AnimatorControlBehavior.PauseResume, false);
+ }
+
+ @Test
+ public void testAnimatorContinue() throws InterruptedException, InvocationTargetException {
+ testImpl(AnimatorControlBehavior.Continue, false);
+ }
+
+ void testImpl(final AnimatorControlBehavior animCtrl, boolean useFPSAnimator) throws InterruptedException, InvocationTargetException {
+ final GLProfile glp = GLProfile.get(GLProfile.GL2);
+ final GLCapabilities caps = new GLCapabilities(glp);
+ final GLCanvas canvas = new GLCanvas(caps);
+ canvas.setPreferredSize(new Dimension(640, 480));
+
+ final GLAnimatorControl animatorCtrl = useFPSAnimator ? new FPSAnimator(canvas, 60) : new Animator(canvas);
+ animatorCtrl.setUpdateFPSFrames(60, System.err);
+ switch (animCtrl) {
+ case PauseResume:
+ animatorCtrl.start();
+ animatorCtrl.pause();
+ break;
+ case Continue:
+ animatorCtrl.start();
+ break;
+ }
+
+ canvas.addGLEventListener(new GearsES2(1));
+ /* if(Platform.OS_TYPE == Platform.OSType.WINDOWS) {
+ canvas.addGLEventListener(new GLEventListener() {
+ public void init(GLAutoDrawable drawable) { }
+ public void dispose(GLAutoDrawable drawable) { }
+ public void display(GLAutoDrawable drawable) {
+ final NativeWindow win = (NativeWindow) drawable.getNativeSurface();
+ long hdc = win.getSurfaceHandle();
+ long hdw = win.getWindowHandle();
+ long hdw_hdc = GDI.WindowFromDC(hdc);
+ System.err.println("*** hdc 0x"+Long.toHexString(hdc)+", hdw(hdc) 0x"+Long.toHexString(hdw_hdc)+", hdw 0x"+Long.toHexString(hdw) + " - " + Thread.currentThread().getName() + ", " + animatorCtrl);
+ // System.err.println(drawable.getNativeSurface().toString());
+ }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width,
+ int height) { }
+ });
+ } */
+
+ final JFrame frame = new JFrame();
+ frame.setTitle(getSimpleTestName());
+ frame.addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ animatorCtrl.stop();
+ shouldStop = true;
+ }
+ });
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+ final JPanel cards = new JPanel(new CardLayout());
+ final JPanel comboBoxPanel = new JPanel(); // nicer look ..
+ final JComboBox comboBox = new JComboBox(new String[] { LABEL, CANVAS });
+ comboBox.setEditable(false);
+ comboBox.addItemListener(new ItemListener() {
+ public void itemStateChanged(final ItemEvent evt) {
+ final CardLayout cl = (CardLayout)(cards.getLayout());
+ final String newSelection = (String)evt.getItem();
+ if(!newSelection.equals(selected)) {
+ final String oldSelected = selected;
+ if(newSelection.equals(CANVAS)) {
+ cl.show(cards, CANVAS);
+ switch (animCtrl) {
+ case StartStop:
+ animatorCtrl.start();
+ break;
+ case PauseResume:
+ animatorCtrl.resume();
+ break;
+ }
+ selected = CANVAS;
+ } else if(newSelection.equals(LABEL)) {
+ switch (animCtrl) {
+ case StartStop:
+ animatorCtrl.stop();
+ break;
+ case PauseResume:
+ animatorCtrl.pause();
+ break;
+ }
+ cl.show(cards, LABEL);
+ selected = LABEL;
+ } else {
+ throw new RuntimeException("oops .. unexpected item: "+evt);
+ }
+ System.err.println("Item Change: "+oldSelected+" -> "+selected+", "+animatorCtrl);
+ } else {
+ System.err.println("Item Stays: "+selected+", "+animatorCtrl);
+ }
+ }
+ });
+ comboBoxPanel.add(comboBox);
+
+ cards.add(new JLabel("A label to cover the canvas"), LABEL);
+ cards.add(canvas, CANVAS);
+
+ frame.add(comboBoxPanel, BorderLayout.PAGE_START);
+ frame.add(cards, BorderLayout.CENTER);
+
+ frame.pack();
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(true);
+ }});
+
+ if(manual) {
+ for(long w=durationPerTest; !shouldStop && w>0; w-=100) {
+ Thread.sleep(100);
+ }
+ } else {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ comboBox.setSelectedItem(LABEL);
+ }});
+ Thread.sleep(durationPerTest/4);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ comboBox.setSelectedItem(CANVAS);
+ }});
+ Thread.sleep(durationPerTest/4);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ comboBox.setSelectedItem(LABEL);
+ }});
+ Thread.sleep(durationPerTest/4);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ comboBox.setSelectedItem(CANVAS);
+ }});
+ Thread.sleep(durationPerTest/4);
+ }
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.dispose();
+ }});
+
+ }
+
+ public static void main(String args[]) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest);
+ } else if(args[i].equals("-manual")) {
+ manual = true;
+ }
+ }
+ org.junit.runner.JUnitCore.main(TestAWTCardLayoutAnimatorStartStopBug532.class.getName());
+ }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
index 55c9c6812..284122be3 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/awt/TestBug461OffscreenSupersamplingSwingAWT.java
@@ -30,35 +30,9 @@ package com.jogamp.opengl.test.junit.jogl.awt;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
-/**
- * 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.
- */
import java.awt.image.BufferedImage;
+import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
@@ -123,12 +97,19 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
/* @Override */
public void dispose(GLAutoDrawable drawable) {
- jframe.setVisible(false);
- jframe.dispose();
+ try {
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jframe.setVisible(false);
+ jframe.dispose();
+ }});
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
}
@Test
- public void testOffscreenSupersampling() {
+ public void testOffscreenSupersampling() throws InterruptedException, InvocationTargetException {
jframe = new JFrame("Offscreen Supersampling");
Assert.assertNotNull(jframe);
jframe.setSize( 300, 300);
@@ -163,7 +144,10 @@ public class TestBug461OffscreenSupersamplingSwingAWT extends UITestCase impleme
Assert.assertNotNull(offScreenBuffer);
offScreenBuffer.addGLEventListener(this);
offScreenBuffer.display();
- jframe.setVisible( true );
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jframe.setVisible(true);
+ }});
}
public static void main(String args[]) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemo01.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemo01.java
index b41501a9b..ab0171cb8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemo01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/MultisampleDemo01.java
@@ -63,7 +63,7 @@ class MultisampleDemo01 implements GLEventListener {
}
public void init(GLAutoDrawable drawable) {
- AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration().getNativeGraphicsConfiguration();
+ AbstractGraphicsConfiguration config = drawable.getNativeSurface().getGraphicsConfiguration();
System.err.println();
System.err.println("Info: " + config);
System.err.println();
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java
index e22163847..8e720965c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/caps/TestTranslucencyAWT.java
@@ -51,6 +51,7 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
+import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.util.Animator;
@@ -80,8 +81,15 @@ public class TestTranslucencyAWT extends UITestCase {
boolean capable1 = ( null != tcm ) ? tcm.getTransparency() == Transparency.TRANSLUCENT : false;
boolean capable2 = false;
try {
- capable2 = com.sun.awt.AWTUtilities.isTranslucencyCapable(config);
- } catch (Exception e) {}
+ capable2 = ((Boolean)ReflectionUtil.callStaticMethod(
+ "com.sun.awt.AWTUtilities", "isTranslucencyCapable",
+ new Class<?>[] { GraphicsConfiguration.class },
+ new Object[] { config } ,
+ GraphicsConfiguration.class.getClassLoader())).booleanValue();
+ System.err.println("com.sun.awt.AWTUtilities.isTranslucencyCapable(config) passed: "+capable2);
+ } catch (RuntimeException re) {
+ System.err.println("com.sun.awt.AWTUtilities.isTranslucencyCapable(config) failed: "+re.getMessage());
+ }
System.err.println(i+":"+j+" "+config+", "+tcm+", capable "+capable1+"/"+capable2);
if(capable1&&capable2) {
gc=configs[j];
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 a01cb593b..67e8524a3 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
@@ -52,7 +52,6 @@ public class TestTranslucencyNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
/*if(GLProfile.isAvailable(GLProfile.getDefaultEGLDevice(), GLProfile.GLES2)) {
// exact match
glp = GLProfile.get(GLProfile.getDefaultEGLDevice(), GLProfile.GLES2);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
index 8d579ce5d..b5a729e02 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es1/GearsES1.java
@@ -21,6 +21,7 @@
package com.jogamp.opengl.test.junit.jogl.demos.es1;
+import javax.media.nativewindow.NativeWindow;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES1;
import javax.media.opengl.GLAutoDrawable;
@@ -181,8 +182,18 @@ public class GearsES1 implements GLEventListener {
// Get the GL corresponding to the drawable we are animating
GL2ES1 gl = drawable.getGL().getGL2ES1();
- gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
+ final boolean hasFocus;
+ if(drawable.getNativeSurface() instanceof NativeWindow) {
+ hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+ } else {
+ hasFocus = true;
+ }
+ if(hasFocus) {
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ } else {
+ gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+ }
+
// Special handling for the case where the GLJPanel is translucent
// and wants to be composited with other Java 2D content
if (GLProfile.isAWTAvailable() &&
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 86f63cb2d..8b41141f1 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
@@ -52,7 +52,6 @@ public class TestGearsES1NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
/* if(GLProfile.isAvailable(GLProfile.getDefaultEGLDevice(), GLProfile.GLES1)) {
// exact match
glp = GLProfile.get(GLProfile.getDefaultEGLDevice(), GLProfile.GLES1);
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 e73be50d6..13aafe48f 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
@@ -52,7 +52,6 @@ public class TestRedSquareES1NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
/* if(GLProfile.isAvailable(GLProfile.getDefaultEGLDevice(), GLProfile.GLES1)) {
// exact match
glp = GLProfile.get(GLProfile.getDefaultEGLDevice(), GLProfile.GLES1);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
index 3fa61bf1d..51bc7d137 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/GearsES2.java
@@ -34,6 +34,8 @@ import com.jogamp.opengl.util.glsl.ShaderCode;
import com.jogamp.opengl.util.glsl.ShaderProgram;
import com.jogamp.opengl.util.glsl.ShaderState;
import java.nio.FloatBuffer;
+
+import javax.media.nativewindow.NativeWindow;
import javax.media.opengl.GL;
import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLAutoDrawable;
@@ -244,8 +246,18 @@ public class GearsES2 implements GLEventListener {
// Get the GL corresponding to the drawable we are animating
GL2ES2 gl = drawable.getGL().getGL2ES2();
- gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
+ final boolean hasFocus;
+ if(drawable.getNativeSurface() instanceof NativeWindow) {
+ hasFocus = ((NativeWindow)drawable.getNativeSurface()).hasFocus();
+ } else {
+ hasFocus = true;
+ }
+ if(hasFocus) {
+ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ } else {
+ gl.glClearColor(0.2f, 0.2f, 0.2f, 0.0f);
+ }
+
// Special handling for the case where the GLJPanel is translucent
// and wants to be composited with other Java 2D content
if (GLProfile.isAWTAvailable() &&
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
index 01790de10..d645fb9f8 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java
@@ -205,7 +205,7 @@ public class RedSquareES2 implements GLEventListener {
class MyMouseAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
System.err.println(e);
- if(null != glWindow && e.getSource() == glWindow.getWindow()) {
+ if(null != glWindow && e.getSource() == glWindow.getDelegatedWindow()) {
if(e.getX() < glWindow.getWidth()/2) {
glWindow.setFullscreen(!glWindow.isFullscreen());
System.err.println("setFullscreen: "+glWindow.isFullscreen());
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 d9cee4fdf..fb6359093 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
@@ -65,11 +65,6 @@ public class TestElektronenMultipliziererNEWT extends UITestCase {
static int startFrame = 1700;
static long duration = 5000; // ms
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
@AfterClass
public static void releaseClass() {
}
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 18a5a5d31..faa7eb311 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
@@ -32,8 +32,13 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
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.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
@@ -42,6 +47,11 @@ import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+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;
@@ -55,11 +65,25 @@ import org.junit.Test;
public class TestGearsES2NEWT extends UITestCase {
static GLProfile glp;
- static int width, height;
+
+ static int screenIdx = 0;
+ static PointImmutable wpos;
+ static DimensionImmutable wsize;
+ static long duration = 500; // ms
+ static boolean opaque = true;
+ static boolean undecorated = false;
+ static boolean alwaysOnTop = false;
+ static boolean fullscreen = false;
+ static boolean pmvUseBackingArray = true;
+ static boolean vsync = false;
+ static boolean waitForKey = false;
+ static boolean mouseVisible = true;
+ static boolean mouseConfined = false;
+ static boolean showFPS = false;
+
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
/*if(GLProfile.isAvailable(GLProfile.getDefaultEGLDevice(), GLProfile.GLES2)) {
// exact match
glp = GLProfile.get(GLProfile.getDefaultEGLDevice(), GLProfile.GLES2);
@@ -68,10 +92,9 @@ public class TestGearsES2NEWT extends UITestCase {
glp = GLProfile.getGL2ES2();
}
Assert.assertNotNull(glp);
- // width = 512;
- // height = 512;
- width = 200;
- height = 200;
+ if(null == wsize) {
+ wsize = new Dimension(200, 200);
+ }
}
@AfterClass
@@ -80,11 +103,15 @@ public class TestGearsES2NEWT extends UITestCase {
protected void runTestGL(GLCapabilities caps, boolean undecorated) throws InterruptedException {
System.err.println("requested: "+caps);
- final GLWindow glWindow = GLWindow.create(caps);
+ Display dpy = NewtFactory.createDisplay(null);
+ Screen screen = NewtFactory.createScreen(dpy, screenIdx);
+ final GLWindow glWindow = GLWindow.create(screen, caps);
Assert.assertNotNull(glWindow);
- glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+")");
- glWindow.setSize(width, height);
- glWindow.setPosition(100, 100);
+ glWindow.setTitle("Gears NEWT Test (translucent "+!caps.isBackgroundOpaque()+"), size "+wsize+", pos "+wpos);
+ glWindow.setSize(wsize.getWidth(), wsize.getHeight());
+ if(null != wpos) {
+ glWindow.setPosition(wpos.getX(), wpos.getY());
+ }
glWindow.setUndecorated(undecorated);
glWindow.setAlwaysOnTop(alwaysOnTop);
glWindow.setFullscreen(fullscreen);
@@ -123,6 +150,15 @@ public class TestGearsES2NEWT extends UITestCase {
glWindow.addKeyListener(quitAdapter);
glWindow.addWindowListener(quitAdapter);
+ glWindow.addWindowListener(new WindowAdapter() {
+ public void windowResized(WindowEvent e) {
+ System.err.println("window resized: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+ }
+ public void windowMoved(WindowEvent e) {
+ System.err.println("window moved: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight());
+ }
+ });
+
glWindow.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if(e.getKeyChar()=='f') {
@@ -189,14 +225,14 @@ public class TestGearsES2NEWT extends UITestCase {
}
});
- animator.setUpdateFPSFrames(60, System.err);
+ animator.setUpdateFPSFrames(60, showFPS ? System.err : null);
animator.start();
// glWindow.setSkipContextReleaseThread(animator.getThread());
glWindow.setVisible(true);
- System.err.println("size/pos: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
System.err.println("chosen: "+glWindow.getChosenCapabilities());
+ System.err.println("window pos/siz: "+glWindow.getX()+"/"+glWindow.getY()+" "+glWindow.getWidth()+"x"+glWindow.getHeight()+", "+glWindow.getInsets());
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
Thread.sleep(100);
@@ -213,25 +249,22 @@ public class TestGearsES2NEWT extends UITestCase {
runTestGL(caps, undecorated);
}
- static long duration = 500; // ms
- static boolean opaque = true;
- static boolean undecorated = false;
- static boolean alwaysOnTop = false;
- static boolean fullscreen = false;
- static boolean pmvUseBackingArray = true;
- static boolean vsync = false;
- static boolean waitForKey = false;
- static boolean mouseVisible = true;
- static boolean mouseConfined = false;
-
+ static int atoi(String a) {
+ try {
+ return Integer.parseInt(a);
+ } catch (Exception ex) { throw new RuntimeException(ex); }
+ }
+
public static void main(String args[]) throws IOException {
+ int x=0, y=0, w=200, h=200;
+ boolean useSize = false;
+ boolean usePos = false;
+
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
i++;
- try {
- duration = Integer.parseInt(args[i]);
- } catch (Exception ex) { ex.printStackTrace(); }
+ duration = atoi(args[i]);
} else if(args[i].equals("-translucent")) {
opaque = false;
} else if(args[i].equals("-undecorated")) {
@@ -250,8 +283,38 @@ public class TestGearsES2NEWT extends UITestCase {
mouseVisible = false;
} else if(args[i].equals("-mouseConfine")) {
mouseConfined = true;
+ } else if(args[i].equals("-showFPS")) {
+ showFPS = true;
+ } else if(args[i].equals("-width")) {
+ i++;
+ w = atoi(args[i]);
+ useSize = true;
+ } else if(args[i].equals("-height")) {
+ i++;
+ h = atoi(args[i]);
+ useSize = true;
+ } else if(args[i].equals("-x")) {
+ i++;
+ x = atoi(args[i]);
+ usePos = true;
+ } else if(args[i].equals("-y")) {
+ i++;
+ y = atoi(args[i]);
+ usePos = true;
+ } else if(args[i].equals("-screen")) {
+ i++;
+ screenIdx = atoi(args[i]);
}
}
+ if(useSize) {
+ wsize = new Dimension(w, h);
+ }
+ if(usePos) {
+ wpos = new Point(x, y);
+ }
+ System.err.println("position "+wpos);
+ System.err.println("size "+wsize);
+ System.err.println("screen "+screenIdx);
System.err.println("translucent "+(!opaque));
System.err.println("undecorated "+undecorated);
System.err.println("atop "+alwaysOnTop);
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 63ec215fc..f3bad286b 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
@@ -52,7 +52,6 @@ public class TestRedSquareES2NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
/* if(GLProfile.isAvailable(GLProfile.getDefaultEGLDevice(), GLProfile.GLES1)) {
// exact match
glp = GLProfile.get(GLProfile.getDefaultEGLDevice(), GLProfile.GLES1);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java
index 8ab641267..f03269614 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWT.java
@@ -41,6 +41,7 @@ import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
import com.jogamp.opengl.test.junit.util.UITestCase;
import com.jogamp.opengl.test.junit.util.QuitAdapter;
import java.awt.Frame;
+import java.lang.reflect.InvocationTargetException;
import org.junit.Assert;
import org.junit.BeforeClass;
@@ -50,6 +51,7 @@ import org.junit.Test;
public class TestGearsAWT extends UITestCase {
static GLProfile glp;
static int width, height;
+ static boolean firstUIActionOnProcess = false;
@BeforeClass
public static void initClass() {
@@ -63,16 +65,16 @@ public class TestGearsAWT extends UITestCase {
public static void releaseClass() {
}
- protected void runTestGL(GLCapabilities caps) throws InterruptedException {
- Frame frame = new Frame("Gears AWT Test");
+ protected void runTestGL(GLCapabilities caps) throws InterruptedException, InvocationTargetException {
+ final Frame frame = new Frame("Gears AWT Test");
Assert.assertNotNull(frame);
- GLCanvas glCanvas = new GLCanvas(caps);
+ final GLCanvas glCanvas = new GLCanvas(caps);
Assert.assertNotNull(glCanvas);
frame.add(glCanvas);
frame.setSize(512, 512);
- glCanvas.addGLEventListener(new Gears());
+ glCanvas.addGLEventListener(new Gears(1));
Animator animator = new Animator(glCanvas);
QuitAdapter quitAdapter = new QuitAdapter();
@@ -80,8 +82,11 @@ public class TestGearsAWT extends UITestCase {
new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter)).addTo(glCanvas);
new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter)).addTo(frame);
- frame.setVisible(true);
- animator.setUpdateFPSFrames(1, null);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(true);
+ }});
+ animator.setUpdateFPSFrames(60, System.err);
animator.start();
while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
@@ -96,14 +101,15 @@ public class TestGearsAWT extends UITestCase {
Assert.assertEquals(false, animator.isAnimating());
frame.setVisible(false);
Assert.assertEquals(false, frame.isVisible());
- frame.remove(glCanvas);
- frame.dispose();
- frame=null;
- glCanvas=null;
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.remove(glCanvas);
+ frame.dispose();
+ }});
}
@Test
- public void test01() throws InterruptedException {
+ public void test01() throws InterruptedException, InvocationTargetException {
GLCapabilities caps = new GLCapabilities(glp);
runTestGL(caps);
}
@@ -117,6 +123,8 @@ public class TestGearsAWT extends UITestCase {
try {
duration = Integer.parseInt(args[i]);
} catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-firstUIAction")) {
+ firstUIActionOnProcess = true;
}
}
org.junit.runner.JUnitCore.main(TestGearsAWT.class.getName());
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWTAnalyzeBug455.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWTAnalyzeBug455.java
new file mode 100644
index 000000000..4b670f0e1
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/awt/TestGearsAWTAnalyzeBug455.java
@@ -0,0 +1,171 @@
+/**
+ * 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.demos.gl2.awt;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.util.Animator;
+import javax.media.opengl.awt.GLCanvas;
+import com.jogamp.newt.event.awt.AWTKeyAdapter;
+import com.jogamp.newt.event.awt.AWTWindowAdapter;
+import com.jogamp.newt.event.TraceKeyAdapter;
+import com.jogamp.newt.event.TraceWindowAdapter;
+
+import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.test.junit.util.QuitAdapter;
+import java.awt.Frame;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import org.junit.Test;
+
+public class TestGearsAWTAnalyzeBug455 extends UITestCase {
+ static long duration = 500; // ms
+ static boolean waitForKey = false; // for manual profiling
+ static boolean altSwap = true; // using alternate GL swap method (copy pixel) no [auto-]swap
+
+ static GLProfile glp;
+ static int width, height;
+
+ @BeforeClass
+ public static void initClass() {
+ glp = GLProfile.getDefault();
+ Assert.assertNotNull(glp);
+ width = 512;
+ height = 512;
+ }
+
+ @AfterClass
+ public static void releaseClass() {
+ }
+
+ static class Swapper implements GLEventListener {
+ public void init(GLAutoDrawable drawable) {
+ System.err.println("auto-swap: "+drawable.getAutoSwapBufferMode());
+ }
+ public void dispose(GLAutoDrawable drawable) {
+ }
+ public void display(GLAutoDrawable drawable) {
+ if(!drawable.getAutoSwapBufferMode()) {
+ GL2 gl = drawable.getGL().getGL2();
+ // copy the colored content of the back buffer into the front buffer
+ // gl.glPushAttrib(GL.GL_COLOR_BUFFER_BIT);
+ gl.glReadBuffer(GL.GL_BACK); // def. in dbl buff mode: GL_BACK
+ gl.glDrawBuffer(GL.GL_FRONT); // def. in dbl buff mode: GL_BACK
+ gl.glCopyPixels(0, 0, drawable.getWidth(), drawable.getHeight(), GL2.GL_COLOR);
+ // gl.glPopAttrib();
+ gl.glDrawBuffer(GL.GL_BACK); // def. in dbl buff mode: GL_BACK
+ }
+ }
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width,
+ int height) {
+ }
+ }
+ protected void runTestGL(GLCapabilities caps) throws InterruptedException, InvocationTargetException {
+ final Frame frame = new Frame("Gears AWT Test");
+ Assert.assertNotNull(frame);
+
+ final GLCanvas glCanvas = new GLCanvas(caps);
+ Assert.assertNotNull(glCanvas);
+ glCanvas.setAutoSwapBufferMode(!altSwap);
+ frame.add(glCanvas);
+ frame.setSize(512, 512);
+
+ glCanvas.addGLEventListener(new Gears(0));
+ glCanvas.addGLEventListener(new Swapper());
+
+ Animator animator = new Animator(glCanvas);
+ QuitAdapter quitAdapter = new QuitAdapter();
+
+ new AWTKeyAdapter(new TraceKeyAdapter(quitAdapter)).addTo(glCanvas);
+ new AWTWindowAdapter(new TraceWindowAdapter(quitAdapter)).addTo(frame);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(true);
+ }});
+ animator.setUpdateFPSFrames(60, System.err);
+ animator.start();
+
+ while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) {
+ Thread.sleep(100);
+ }
+
+ Assert.assertNotNull(frame);
+ Assert.assertNotNull(glCanvas);
+ Assert.assertNotNull(animator);
+
+ animator.stop();
+ Assert.assertEquals(false, animator.isAnimating());
+ frame.setVisible(false);
+ Assert.assertEquals(false, frame.isVisible());
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.remove(glCanvas);
+ frame.dispose();
+ }});
+ }
+
+ @Test
+ public void test01() throws InterruptedException, InvocationTargetException {
+ GLCapabilities caps = new GLCapabilities(glp);
+ caps.setDoubleBuffered(true); // code assumes dbl buffer setup
+ runTestGL(caps);
+ }
+
+ public static void main(String args[]) {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ i++;
+ try {
+ duration = Integer.parseInt(args[i]);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(args[i].equals("-wait")) {
+ waitForKey = true;
+ } else if(args[i].equals("-autoswap")) {
+ altSwap = false;
+ }
+ }
+ System.err.println("altSwap "+altSwap);
+ if(waitForKey) {
+ BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
+ System.err.println("Press enter to continue");
+ try {
+ System.err.println(stdin.readLine());
+ } catch (IOException e) { }
+ }
+ org.junit.runner.JUnitCore.main(TestGearsAWTAnalyzeBug455.class.getName());
+ }
+}
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 4b6f7999a..f410baf9d 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
@@ -55,7 +55,6 @@ public class TestGearsNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
width = 512;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java
index 5568b42f7..731f7c867 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/drawable/TestDrawable01NEWT.java
@@ -52,7 +52,6 @@ public class TestDrawable01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glp = GLProfile.getDefault();
Assert.assertNotNull(glp);
factory = GLDrawableFactory.getFactory(glp);
@@ -99,7 +98,7 @@ public class TestDrawable01NEWT extends UITestCase {
// Create native OpenGL resources .. XGL/WGL/CGL ..
// equivalent to GLAutoDrawable methods: setVisible(true)
//
- GLCapabilities glCaps = (GLCapabilities) window.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ GLCapabilities glCaps = (GLCapabilities) window.getGraphicsConfiguration().getChosenCapabilities();
Assert.assertNotNull(glCaps);
Assert.assertTrue(glCaps.getGreenBits()>5);
Assert.assertTrue(glCaps.getBlueBits()>5);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
index ae08b640c..297cbbb90 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/GLSLMiscHelper.java
@@ -37,8 +37,8 @@ import javax.media.opengl.GLDrawable;
import org.junit.Assert;
public class GLSLMiscHelper {
- public static final int frames_perftest = 10000; // frames
- public static final int frames_warmup = 500; // frames
+ public static final int frames_perftest = 600; // frames
+ public static final int frames_warmup = 100; // frames
public static void validateGLArrayDataServerState(GL2ES2 gl, GLArrayDataServer data) {
final ShaderState st = ShaderState.getShaderState(gl);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java
index 50d65e985..aca1e6607 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestFBOMRTNEWT01.java
@@ -56,11 +56,6 @@ import org.junit.BeforeClass;
public class TestFBOMRTNEWT01 extends UITestCase {
static long durationPerTest = 10; // ms
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
@Test
public void test01() throws InterruptedException {
// preset ..
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
index 672938310..ea290693c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState01NEWT.java
@@ -54,15 +54,11 @@ import org.junit.BeforeClass;
*/
public class TestGLSLShaderState01NEWT extends UITestCase {
static long durationPerTest = 10; // ms
+ static boolean firstUIActionOnProcess = false;
static final int vertices0_loc = 0; // FIXME: AMD needs this to be location 0 ? hu ?
static final int colors0_loc = 1;
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
@Test
public void testShaderState01Validation() throws InterruptedException {
// preset ..
@@ -181,11 +177,11 @@ public class TestGLSLShaderState01NEWT extends UITestCase {
NEWTGLContext.destroyWindow(winctx);
}
- @Test(timeout=120000)
+ @Test(timeout=240000)
public void testShaderState00PerformanceSingleKeepEnabled() throws InterruptedException {
testShaderState00PerformanceSingle(false);
}
- @Test(timeout=120000)
+ @Test(timeout=240000)
public void testShaderState00PerformanceSingleToggleEnable() throws InterruptedException {
testShaderState00PerformanceSingle(true);
}
@@ -278,7 +274,7 @@ public class TestGLSLShaderState01NEWT extends UITestCase {
NEWTGLContext.destroyWindow(winctx);
}
- @Test(timeout=120000)
+ @Test(timeout=240000)
public void testShaderState01PerformanceDouble() throws InterruptedException {
// preset ..
final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(GLProfile.getGL2ES2(), 480, 480, false);
@@ -386,9 +382,10 @@ public class TestGLSLShaderState01NEWT extends UITestCase {
for(int i=0; i<args.length; i++) {
if(args[i].equals("-time")) {
durationPerTest = MiscUtils.atoi(args[++i], (int)durationPerTest);
- }
- if(args[i].equals("-wait")) {
+ } else if(args[i].equals("-wait")) {
wait = true;
+ } else if(args[i].equals("-firstUIAction")) {
+ firstUIActionOnProcess = true;
}
}
if(wait) {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
index 2bb825649..fb52ff04b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLShaderState02NEWT.java
@@ -58,11 +58,6 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
static final int vertices0_loc = 0; // FIXME: AMD needs this to be location 0 ? hu ?
static final int colors0_loc = 5;
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
@Test
public void testShaderState01ValidationSP1Linked() throws InterruptedException {
testShaderState01Validation(true);
@@ -236,7 +231,7 @@ public class TestGLSLShaderState02NEWT extends UITestCase {
NEWTGLContext.destroyWindow(winctx);
}
- @Test(timeout=120000)
+ @Test(timeout=240000)
public void testShaderState01PerformanceDouble() throws InterruptedException {
// preset ..
final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(GLProfile.getGL2ES2(), 480, 480, false);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java
index b683cb2e7..672193946 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestGLSLSimple01NEWT.java
@@ -54,19 +54,6 @@ import org.junit.AfterClass;
public class TestGLSLSimple01NEWT extends UITestCase {
static long durationPerTest = 100; // ms
- @BeforeClass
- public static void initClass() {
- System.err.println("class init");
- GLProfile.initSingleton(true);
- }
-
- @AfterClass
- public static void tearDownClass() {
- System.err.println("class tear down ..");
- GLProfile.shutdown();
- System.err.println("class tear down end");
- }
-
@Test(timeout=60000)
public void testGLSLCompilation01() {
GLProfile glp = GLProfile.get(GLProfile.GL2ES2);
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 fe1149f86..13780a7e5 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
@@ -57,13 +57,11 @@ import org.junit.BeforeClass;
public class TestRulerNEWT01 extends UITestCase {
static long durationPerTest = 10; // ms
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
@Test
public void test01() throws InterruptedException {
+ long t0 = System.nanoTime();
+ GLProfile.initSingleton();
+ long t1 = System.nanoTime();
// preset ..
final NEWTGLContext.WindowContext winctx = NEWTGLContext.createOnscreenWindow(GLProfile.getGL2ES2(), 640, 480, true);
final GLDrawable drawable = winctx.context.getGLDrawable();
@@ -161,7 +159,15 @@ public class TestRulerNEWT01 extends UITestCase {
Thread.sleep(durationPerTest/10);
}
+ long t2 = System.nanoTime();
+
NEWTGLContext.destroyWindow(winctx);
+
+ long t3 = System.nanoTime();
+
+ System.err.println("t1-t0: "+ (t1-t0)/1e6 +"ms");
+ System.err.println("t3-t0: "+ (t3-t0)/1e6 +"ms");
+ System.err.println("t3-t2: "+ (t3-t2)/1e6 +"ms");
}
public static void main(String args[]) throws IOException {
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java
index a6d04cf24..a3059baae 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/glsl/TestTransformFeedbackVaryingsBug407NEWT.java
@@ -29,16 +29,6 @@ public class TestTransformFeedbackVaryingsBug407NEWT extends UITestCase {
private String VERTEX_SHADER_TEXT;
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- }
-
- @AfterClass
- public static void tearDownClass() {
- GLProfile.shutdown();
- }
-
class MyShader {
int shaderProgram;
int vertShader;
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java b/src/test/com/jogamp/opengl/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java
index 2809a138c..213d3ad05 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/newt/TestSwingAWTRobotUsageBeforeJOGLInitBug411.java
@@ -112,9 +112,6 @@ public class TestSwingAWTRobotUsageBeforeJOGLInitBug411 extends UITestCase {
public static void setup() throws InterruptedException, InvocationTargetException, AWTException {
System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.setup(): Start Pre-JOGL-Swing");
- // GLProfile.initSingleton(false);
- // GLProfile.initSingleton(true);
-
// simulate AWT usage before JOGL's initialization of X11 threading
windowClosing=false;
border = BorderFactory.createLineBorder (Color.yellow, 2);
@@ -166,8 +163,7 @@ public class TestSwingAWTRobotUsageBeforeJOGLInitBug411 extends UITestCase {
System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.setup(): Before JOGL init");
// just to trigger JOGL initialization at a well defined point ..
- // ofc it's not the first UI command
- GLProfile.initSingleton(false);
+ GLProfile.initSingleton();
System.err.println("TestSwingAWTRobotUsageBeforeJOGLInitBug411.setup(): End Pre-JOGL-Swing");
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen01GLPBufferNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen01GLPBufferNEWT.java
index 561819485..3f1fd144f 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen01GLPBufferNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen01GLPBufferNEWT.java
@@ -56,7 +56,6 @@ public class TestOffscreen01GLPBufferNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glpDefault = GLProfile.getDefault();
Assert.assertNotNull(glpDefault);
glDrawableFactory = GLDrawableFactory.getFactory(glpDefault);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java
index 1b43940cd..e2ce78b9b 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/TestOffscreen02BitmapNEWT.java
@@ -61,7 +61,6 @@ public class TestOffscreen02BitmapNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
glpDefault = GLProfile.getDefault();
Assert.assertNotNull(glpDefault);
glDrawableFactory = GLDrawableFactory.getFactory(glpDefault);
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java
index 199b094f2..1d1ee1e0c 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/offscreen/WindowUtilNEWT.java
@@ -103,7 +103,7 @@ public class WindowUtilNEWT {
while ( windowOffScreen.getTotalFPSFrames() < frames) {
windowOffScreen.display();
}
- windowOffScreen.removeAllSurfaceUpdatedListener();
+ windowOffScreen.removeSurfaceUpdatedListener(ul);
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java
index e6d937d0c..d302c3903 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT01GLn.java
@@ -73,7 +73,6 @@ public class TestSWT01GLn extends UITestCase {
@BeforeClass
public static void startup() {
- GLProfile.initSingleton(true);
System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
}
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java
index 3e153214b..b8e45dfe1 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWT02GLn.java
@@ -38,7 +38,6 @@ import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
-import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
@@ -78,7 +77,6 @@ public class TestSWT02GLn extends UITestCase {
@BeforeClass
public static void startup() {
- GLProfile.initSingleton( true );
System.out.println( "GLProfile " + GLProfile.glAvailabilityToString() );
}
@@ -156,7 +154,7 @@ public class TestSWT02GLn extends UITestCase {
ProxySurface proxySurface = factory.createProxySurface(device, nativeWindowHandle, caps, null);
Assert.assertNotNull( proxySurface );
- proxySurface.setSize( 640, 480 );
+ proxySurface.surfaceSizeChanged( 640, 480 );
System.err.println("*** ProxySurface: " + proxySurface);
final GLDrawable drawable = factory.createGLDrawable(proxySurface);
Assert.assertNotNull( drawable );
diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java
index 595e6fb31..6139d816a 100644
--- a/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java
+++ b/src/test/com/jogamp/opengl/test/junit/jogl/swt/TestSWTAWT01GLn.java
@@ -29,6 +29,7 @@
package com.jogamp.opengl.test.junit.jogl.swt;
import java.awt.Frame;
+import java.lang.reflect.InvocationTargetException;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
@@ -37,6 +38,8 @@ import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
+import jogamp.nativewindow.swt.SWTAccessor;
+
import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.graphics.Rectangle;
@@ -76,46 +79,47 @@ public class TestSWTAWT01GLn extends UITestCase {
}
@Before
- public void init() {
- display = new Display();
- Assert.assertNotNull( display );
- shell = new Shell( display );
- Assert.assertNotNull( shell );
- shell.setLayout( new FillLayout() );
- composite = new Composite( shell, SWT.EMBEDDED | SWT.NO_BACKGROUND );
- composite.setLayout( new FillLayout() );
- Assert.assertNotNull( composite );
- frame = SWT_AWT.new_Frame( composite );
- Assert.assertNotNull( frame );
+ public void init() throws InterruptedException, InvocationTargetException {
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ display = new Display();
+ Assert.assertNotNull( display );
+ shell = new Shell( display );
+ Assert.assertNotNull( shell );
+ shell.setLayout( new FillLayout() );
+ composite = new Composite( shell, SWT.EMBEDDED | SWT.NO_BACKGROUND );
+ composite.setLayout( new FillLayout() );
+ Assert.assertNotNull( composite );
+ frame = SWT_AWT.new_Frame( composite );
+ Assert.assertNotNull( frame );
+ }});
}
@After
- public void release() {
+ public void release() throws InterruptedException, InvocationTargetException {
Assert.assertNotNull( display );
Assert.assertNotNull( shell );
Assert.assertNotNull( composite );
Assert.assertNotNull( glcanvas );
- try {
- javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame.setVisible(false);
- frame.remove(glcanvas);
- frame.dispose();
- }});
- composite.dispose();
- shell.close();
- shell.dispose();
- display.dispose();
- }
- catch( Throwable throwable ) {
- throwable.printStackTrace();
- Assume.assumeNoException( throwable );
- }
- display = null;
- shell = null;
- composite = null;
- frame = null;
- glcanvas = null;
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(false);
+ frame.remove(glcanvas);
+ frame.dispose();
+ frame = null;
+ glcanvas = null;
+ }});
+
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ composite.dispose();
+ shell.close();
+ shell.dispose();
+ display.dispose();
+ display = null;
+ shell = null;
+ composite = null;
+ }});
}
protected void runTestGL( GLProfile glprofile ) throws InterruptedException {
@@ -148,18 +152,26 @@ public class TestSWTAWT01GLn extends UITestCase {
}
});
- shell.setText( getClass().getName() );
- shell.setSize( 640, 480 );
- shell.open();
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ shell.setText( getClass().getName() );
+ shell.setSize( 640, 480 );
+ shell.open();
+ }});
long lStartTime = System.currentTimeMillis();
long lEndTime = lStartTime + duration;
try {
while( (System.currentTimeMillis() < lEndTime) && !composite.isDisposed() ) {
- if( !display.readAndDispatch() ) {
- // blocks on linux .. display.sleep();
- Thread.sleep(10);
- }
+ SWTAccessor.invoke(true, new Runnable() {
+ public void run() {
+ if( !display.readAndDispatch() ) {
+ // blocks on linux .. display.sleep();
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) { }
+ }
+ }});
}
}
catch( Throwable throwable ) {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
index adc885191..4ebb7dddd 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestCloseNewtAWT.java
@@ -39,10 +39,9 @@ import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
+
import com.jogamp.newt.Window;
import com.jogamp.newt.awt.NewtCanvasAWT;
-import com.jogamp.newt.event.WindowAdapter;
-import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.test.junit.util.AWTRobotUtil;
import com.jogamp.opengl.test.junit.util.UITestCase;
@@ -53,6 +52,7 @@ public class TestCloseNewtAWT extends UITestCase {
NewtCanvasAWT newtCanvas = null;
JFrame frame = null;
+ @SuppressWarnings("serial")
class MyCanvas extends NewtCanvasAWT {
public MyCanvas(Window window) {
super(window);
@@ -78,7 +78,7 @@ public class TestCloseNewtAWT extends UITestCase {
NativeWindow nw = MyCanvas.this.getNativeWindow();
if(null != nw) {
Point p = nw.getLocationOnScreen(null);
- System.err.println("MyCanvas On NEWT-EDT: position: "+p);
+ System.err.println("MyCanvas On NEWT-EDT: position: "+p);
} else {
System.err.println("MyCanvas On NEWT-EDT: position n/a, null NativeWindow");
}
@@ -110,8 +110,6 @@ public class TestCloseNewtAWT extends UITestCase {
Thread.sleep(500);
Assert.assertEquals(true, AWTRobotUtil.closeWindow(frame, true));
-
- GLProfile.shutdown();
}
public static void main(String[] args) {
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java
index d027460db..c9450c2d6 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle01NEWT.java
@@ -51,7 +51,6 @@ public class TestDisplayLifecycle01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 640;
height = 480;
glp = GLProfile.getDefault();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle02NEWT.java
index 4b3c5d506..bf509124b 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestDisplayLifecycle02NEWT.java
@@ -51,7 +51,6 @@ public class TestDisplayLifecycle02NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 640;
height = 480;
glp = GLProfile.getDefault();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
index 13653b907..fe7fef09f 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus01SwingAWTRobot.java
@@ -35,6 +35,7 @@ import org.junit.Assume;
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Button;
+import java.awt.Color;
import java.awt.Robot;
import java.lang.reflect.InvocationTargetException;
@@ -119,7 +120,7 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
AWTFocusAdapter frame1FA = new AWTFocusAdapter("frame1");
frame1.addFocusListener(frame1FA);
frame1.getContentPane().add(newtCanvasAWT, BorderLayout.CENTER);
- Button button = new Button("Click me ..");
+ final Button button = new Button("Click me ..");
AWTFocusAdapter buttonFA = new AWTFocusAdapter("Button");
button.addFocusListener(buttonFA);
AWTKeyAdapter buttonKA = new AWTKeyAdapter("Button");
@@ -127,7 +128,10 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
eventCountAdapters.add(buttonKA);
frame1.getContentPane().add(button, BorderLayout.NORTH);
frame1.setSize(width, height);
- frame1.setVisible(true);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setVisible(true);
+ } } );
Assert.assertTrue(AWTRobotUtil.toFront(robot, frame1));
Thread.sleep(durationPerTest); // manual testing
@@ -162,7 +166,6 @@ public class TestFocus01SwingAWTRobot extends UITestCase {
System.err.println("FOCUS NEWT Canvas/GLWindow request");
EventCountAdapterUtil.reset(eventCountAdapters);
AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonFA);
- Assert.assertTrue(AWTRobotUtil.waitForFocusCount(false, newtCanvasAWTFA));
Assert.assertEquals(true, glWindow1FA.focusGained());
Assert.assertEquals(false, buttonFA.focusGained());
Assert.assertEquals(true, buttonFA.focusLost());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
index 56b08b52a..b9eb748b7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestFocus02SwingAWTRobot.java
@@ -145,14 +145,17 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
jPanel1.add(new Button("west"), BorderLayout.WEST);
jPanel1.add(container1, BorderLayout.CENTER);
- JFrame jFrame1 = new JFrame("Swing Parent JFrame");
+ final JFrame jFrame1 = new JFrame("Swing Parent JFrame");
AWTFocusAdapter jFrame1FA = new AWTFocusAdapter("JFrame1");
jFrame1.addFocusListener(jFrame1FA);
// jFrame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame1.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); // equivalent to Frame, use windowClosing event!
jFrame1.setContentPane(jPanel1);
jFrame1.setSize(width, height);
- jFrame1.setVisible(true); // from here on, we need to run modifications on EDT
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ jFrame1.setVisible(true);
+ } } );
Assert.assertTrue(AWTRobotUtil.toFront(robot, jFrame1));
int wait=0;
@@ -192,7 +195,6 @@ public class TestFocus02SwingAWTRobot extends UITestCase {
System.err.println("FOCUS NEWT Canvas/GLWindow request");
EventCountAdapterUtil.reset(eventCountAdapters);
AWTRobotUtil.assertRequestFocusAndWait(robot, newtCanvasAWT, newtCanvasAWT.getNEWTChild(), glWindow1FA, buttonNorthOuterFA);
- Assert.assertTrue(AWTRobotUtil.waitForFocusCount(false, newtCanvasAWTFA));
Assert.assertEquals(true, glWindow1FA.focusGained());
Assert.assertEquals(false, buttonNorthOuterFA.focusGained());
Assert.assertEquals(true, buttonNorthOuterFA.focusLost());
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java
index 5c42f2b16..309d7c7cb 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows00NEWT.java
@@ -50,8 +50,6 @@ public class TestGLWindows00NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
- // GLProfile.initSingleton(false);
width = 640;
height = 480;
glp = GLProfile.getDefault();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java
index 45a0b0b13..0c6f60b5f 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows01NEWT.java
@@ -50,8 +50,6 @@ public class TestGLWindows01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
- // GLProfile.initSingleton(false);
width = 640;
height = 480;
glp = GLProfile.getDefault();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows02NEWTAnimated.java b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows02NEWTAnimated.java
index 3176d59e5..6f4ced53c 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows02NEWTAnimated.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestGLWindows02NEWTAnimated.java
@@ -52,7 +52,6 @@ public class TestGLWindows02NEWTAnimated extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 640;
height = 480;
glp = GLProfile.getDefault();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java
index 15151fa2c..fa7f0f915 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestListenerCom01AWT.java
@@ -42,6 +42,7 @@ import com.jogamp.newt.opengl.*;
import com.jogamp.newt.awt.NewtCanvasAWT;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import com.jogamp.opengl.test.junit.util.*;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
@@ -58,7 +59,7 @@ public class TestListenerCom01AWT extends UITestCase {
}
@Test
- public void testListenerStringPassingAndOrder() throws InterruptedException {
+ public void testListenerStringPassingAndOrder() throws InterruptedException, InvocationTargetException {
// setup NEWT GLWindow ..
GLWindow glWindow = GLWindow.create(new GLCapabilities(null));
Assert.assertNotNull(glWindow);
@@ -88,10 +89,13 @@ public class TestListenerCom01AWT extends UITestCase {
// attach NEWT GLWindow to AWT Canvas
NewtCanvasAWT newtCanvasAWT = new NewtCanvasAWT(glWindow);
- Frame frame = new Frame("AWT Parent Frame");
+ final Frame frame = new Frame("AWT Parent Frame");
frame.add(newtCanvasAWT);
frame.setSize(width, height);
- frame.setVisible(true);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.setVisible(true);
+ }});
Animator animator1 = new Animator(glWindow);
animator1.setUpdateFPSFrames(1, null);
@@ -104,14 +108,17 @@ public class TestListenerCom01AWT extends UITestCase {
animator1.stop();
Assert.assertEquals(false, animator1.isAnimating());
- frame.dispose();
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame.dispose();
+ }});
glWindow.destroy();
}
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
index ee21a8ded..35e24403f 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteGLWindows01NEWT.java
@@ -48,17 +48,9 @@ import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindowException;
public class TestRemoteGLWindows01NEWT extends UITestCase {
- static int width, height;
+ static int width = 640, height = 480;
static long durationPerTest = 100; // ms
- static String remoteDisplay = "nowhere:0.0";
-
- @BeforeClass
- public static void initClass() {
- GLProfile.initSingleton(true);
- // GLProfile.initSingleton(false);
- width = 640;
- height = 480;
- }
+ static String remoteDisplay = "localhost:0.0";
static GLWindow createWindow(Screen screen, GLCapabilities caps, GLEventListener demo)
throws InterruptedException
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
index 9c44545f2..eb652584c 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestRemoteWindow01NEWT.java
@@ -43,7 +43,7 @@ import com.jogamp.opengl.test.junit.util.UITestCase;
public class TestRemoteWindow01NEWT extends UITestCase {
static int width, height;
- static String remoteDisplay = "nowhere:0.0";
+ static String remoteDisplay = "localhost:0.0";
@BeforeClass
public static void initClass() {
@@ -77,7 +77,7 @@ public class TestRemoteWindow01NEWT extends UITestCase {
// Create native OpenGL resources .. XGL/WGL/CGL ..
// equivalent to GLAutoDrawable methods: setVisible(true)
//
- CapabilitiesImmutable chosenCapabilities = window.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ CapabilitiesImmutable chosenCapabilities = window.getGraphicsConfiguration().getChosenCapabilities();
Assert.assertNotNull(chosenCapabilities);
Assert.assertTrue(chosenCapabilities.getGreenBits()>5);
Assert.assertTrue(chosenCapabilities.getBlueBits()>5);
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 985affa92..a5b7a76e7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00NEWT.java
@@ -35,21 +35,21 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
+import com.jogamp.newt.Display;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
-import com.jogamp.newt.Window;
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.Capabilities;
import javax.media.nativewindow.util.Dimension;
import javax.media.nativewindow.util.DimensionImmutable;
import javax.media.nativewindow.util.SurfaceSize;
public class TestScreenMode00NEWT extends UITestCase {
+ static int screenIdx = 0;
static int width, height;
static int waitTimeShort = 4; //1 sec
@@ -95,12 +95,12 @@ public class TestScreenMode00NEWT extends UITestCase {
@Test
public void testScreenModeInfo01() throws InterruptedException {
- Capabilities caps = new Capabilities();
- Window window = NewtFactory.createWindow(caps);
- window.setSize(width, height);
- window.setVisible(true);
-
- Screen screen = window.getScreen();
+ Display dpy = NewtFactory.createDisplay(null);
+ Screen screen = NewtFactory.createScreen(dpy, screenIdx);
+ screen.addReference();
+ Assert.assertEquals(true,screen.isNativeValid());
+ Assert.assertEquals(true,screen.getDisplay().isNativeValid());
+ System.err.println("Screen: "+screen.toString());
List<ScreenMode> screenModes = screen.getScreenModes();
Assert.assertTrue(screenModes.size()>0);
@@ -116,18 +116,26 @@ public class TestScreenMode00NEWT extends UITestCase {
System.err.println("curr SM: "+sm_c);
System.err.println("curr sz: "+screen.getWidth()+"x"+screen.getHeight());
Assert.assertEquals(sm_o, sm_c);
- Assert.assertEquals(sm_c.getRotatedWidth(), screen.getWidth());
- Assert.assertEquals(sm_c.getRotatedHeight(), screen.getHeight());
- window.destroy();
+ screen.removeReference();
- Assert.assertEquals(false,window.isVisible());
- Assert.assertEquals(false,window.isNativeValid());
Assert.assertEquals(false,screen.isNativeValid());
Assert.assertEquals(false,screen.getDisplay().isNativeValid());
}
+ static int atoi(String a) {
+ try {
+ return Integer.parseInt(a);
+ } catch (Exception ex) { throw new RuntimeException(ex); }
+ }
+
public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-screen")) {
+ i++;
+ screenIdx = atoi(args[i]);
+ }
+ }
String tstname = TestScreenMode00NEWT.class.getName();
org.junit.runner.JUnitCore.main(tstname);
}
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 41bdfdfd7..e9e66da2c 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode00bNEWT.java
@@ -95,10 +95,10 @@ public class TestScreenMode00bNEWT extends UITestCase {
System.err.println("orig: "+sm_o);
System.err.println("curr: "+sm_c);
- for(i=0; i<100; i++) {
+ for(i=0; i<50; i++) {
sm_c = screen.getCurrentScreenMode();
Assert.assertNotNull(sm_c);
- System.err.print(".");
+ 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 5f14fc466..c3c68e46c 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01NEWT.java
@@ -68,7 +68,6 @@ public class TestScreenMode01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 640;
height = 480;
glp = GLProfile.getDefault();
@@ -112,8 +111,8 @@ public class TestScreenMode01NEWT extends UITestCase {
*/
@After
public void cleanupGL() throws InterruptedException {
- GLProfile.shutdown();
- GLProfile.initSingleton(true);
+ GLProfile.shutdown(GLProfile.ShutdownType.COMPLETE);
+ GLProfile.initSingleton();
}
static GLWindow createWindow(Screen screen, GLCapabilities caps, int width, int height, boolean onscreen, boolean undecorated) {
@@ -201,8 +200,6 @@ public class TestScreenMode01NEWT extends UITestCase {
Assert.assertNotNull(smOrig);
Assert.assertEquals(smCurrent, smOrig);
System.err.println("[0] current/orig: "+smCurrent);
- Assert.assertEquals(smCurrent.getRotatedWidth(), screen.getWidth());
- Assert.assertEquals(smCurrent.getRotatedHeight(), screen.getHeight());
screenModes = ScreenModeUtil.filterByRate(screenModes, smOrig.getMonitorMode().getRefreshRate());
Assert.assertNotNull(screenModes);
@@ -223,8 +220,6 @@ public class TestScreenMode01NEWT extends UITestCase {
screen.setCurrentScreenMode(sm);
Assert.assertEquals(sm, screen.getCurrentScreenMode());
Assert.assertNotSame(smOrig, screen.getCurrentScreenMode());
- Assert.assertEquals(sm.getRotatedWidth(), screen.getWidth());
- Assert.assertEquals(sm.getRotatedHeight(), screen.getHeight());
Thread.sleep(waitTimeLong);
@@ -254,8 +249,6 @@ public class TestScreenMode01NEWT extends UITestCase {
Assert.assertNotNull(smCurrent);
Assert.assertEquals(smCurrent, smOrig);
- Assert.assertEquals(smCurrent.getRotatedWidth(), screen.getWidth());
- Assert.assertEquals(smCurrent.getRotatedHeight(), screen.getHeight());
screen.destroy();
@@ -289,8 +282,6 @@ public class TestScreenMode01NEWT extends UITestCase {
Assert.assertNotNull(smOrig);
Assert.assertEquals(smCurrent, smOrig);
System.err.println("[0] current/orig: "+smCurrent);
- Assert.assertEquals(smCurrent.getRotatedWidth(), screen.getWidth());
- Assert.assertEquals(smCurrent.getRotatedHeight(), screen.getHeight());
List<ScreenMode> screenModes = screen.getScreenModes();
if(screenModes.size()==1) {
@@ -317,8 +308,6 @@ public class TestScreenMode01NEWT extends UITestCase {
System.err.println("[0] set current: "+screenMode);
screen.setCurrentScreenMode(screenMode);
- Assert.assertEquals(screenMode.getRotatedWidth(), screen.getWidth());
- Assert.assertEquals(screenMode.getRotatedHeight(), screen.getHeight());
if(!preFS) {
System.err.println("[0] set FS post 0: "+window.isFullscreen());
@@ -355,8 +344,6 @@ public class TestScreenMode01NEWT extends UITestCase {
Assert.assertNotNull(smCurrent);
Assert.assertEquals(smCurrent, smOrig);
- Assert.assertEquals(smCurrent.getRotatedWidth(), screen.getWidth());
- Assert.assertEquals(smCurrent.getRotatedHeight(), screen.getHeight());
screen.destroy();
}
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 4d7769669..38612faa8 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01bNEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode01bNEWT.java
@@ -65,7 +65,6 @@ public class TestScreenMode01bNEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 100;
height = 100;
glp = GLProfile.getDefault();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode02NEWT.java
index 8c7f75e2b..1c9cb91f3 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestScreenMode02NEWT.java
@@ -60,7 +60,6 @@ public class TestScreenMode02NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 640;
height = 480;
glp = GLProfile.getDefault();
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
index 827dd09fb..a99edfadb 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/TestWindows01NEWT.java
@@ -90,7 +90,7 @@ public class TestWindows01NEWT extends UITestCase {
Assert.assertEquals(y, window.getY());
} */
- CapabilitiesImmutable chosenCapabilities = window.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ CapabilitiesImmutable chosenCapabilities = window.getGraphicsConfiguration().getChosenCapabilities();
Assert.assertNotNull(chosenCapabilities);
Assert.assertTrue(chosenCapabilities.getGreenBits()>=5);
Assert.assertTrue(chosenCapabilities.getBlueBits()>=5);
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 46748cb52..473f2f584 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
@@ -51,7 +51,11 @@ class NewtAWTReparentingKeyAdapter extends KeyAdapter {
if(e.getKeyChar()=='d') {
glWindow.setUndecorated(!glWindow.isUndecorated());
} else if(e.getKeyChar()=='f') {
- glWindow.setFullscreen(!glWindow.isFullscreen());
+ glWindow.setFullscreen(!glWindow.isFullscreen());
+ } else if(e.getKeyChar()=='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') {
new Thread() {
public void run() {
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 7f97be649..256868c6c 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
@@ -53,7 +53,6 @@ public class TestParenting01NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 640;
height = 480;
glCaps = new GLCapabilities(null);
@@ -654,7 +653,7 @@ public class TestParenting01NEWT extends UITestCase {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
}
- if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getWindow())) {
+ if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getDelegatedWindow())) {
MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java
index 674cf4a06..2040fb9b6 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01aAWT.java
@@ -467,7 +467,7 @@ public class TestParenting01aAWT extends UITestCase {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
}
- if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getWindow())) {
+ if(!MiscUtils.setFieldIfExists(demo, "window", glWindow.getDelegatedWindow())) {
MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
}
}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java
index 8571609a8..d98a540ec 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01bAWT.java
@@ -173,7 +173,7 @@ public class TestParenting01bAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java
index 3b40554d2..dfd0787e7 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cAWT.java
@@ -228,7 +228,7 @@ public class TestParenting01cAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
index f505547d4..22ed7c6fd 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting01cSwingAWT.java
@@ -319,7 +319,7 @@ public class TestParenting01cSwingAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java
index f01468c2a..da689cea6 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02AWT.java
@@ -118,7 +118,8 @@ public class TestParenting02AWT extends UITestCase {
}
}
- frame.setSize(width, height);
+ // frame.setSize(width, height);
+ frame.setBounds(100, 100, width, height);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
@@ -233,7 +234,7 @@ public class TestParenting02AWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
index 13aad0c25..bc3988338 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParenting02NEWT.java
@@ -54,7 +54,6 @@ public class TestParenting02NEWT extends UITestCase {
@BeforeClass
public static void initClass() {
- GLProfile.initSingleton(true);
width = 640;
height = 480;
}
@@ -120,7 +119,7 @@ public class TestParenting02NEWT extends UITestCase {
// glWindow1.addGLEventListener(demo1);
glWindow1.setVisible(true);
- CapabilitiesImmutable capsChosen = glWindow1.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ CapabilitiesImmutable capsChosen = glWindow1.getGraphicsConfiguration().getChosenCapabilities();
Assert.assertNotNull(capsChosen);
Assert.assertTrue(capsChosen.isOnscreen()==true);
@@ -142,7 +141,7 @@ public class TestParenting02NEWT extends UITestCase {
// glWindow2.addGLEventListener(demo2);
glWindow2.setVisible(true);
- capsChosen = glWindow2.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ capsChosen = glWindow2.getGraphicsConfiguration().getChosenCapabilities();
Assert.assertNotNull(capsChosen);
Assert.assertTrue(capsChosen.isOnscreen()==true);
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 aded8f163..b33a40fae 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
@@ -35,10 +35,10 @@ import org.junit.BeforeClass;
import org.junit.Test;
import java.awt.BorderLayout;
+import java.awt.Button;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
-import java.awt.Label;
import javax.media.opengl.*;
@@ -53,28 +53,34 @@ import com.jogamp.opengl.test.junit.util.*;
import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
public class TestParenting03AWT extends UITestCase {
- static Dimension size;
- static long durationPerTest = 800;
+ static Dimension glSize, fSize;
+ static long durationPerTest = 1100;
static long waitAdd2nd = 500;
static GLCapabilities glCaps;
@BeforeClass
public static void initClass() {
- size = new Dimension(400,200);
+ glSize = new Dimension(400,200);
+ fSize = new Dimension(3*400,2*200);
glCaps = new GLCapabilities(null);
}
@Test
- public void testWindowParenting1AWTTwoNewtChilds01() throws InterruptedException, InvocationTargetException {
- testWindowParenting1AWTTwoNewtChilds();
+ public void testWindowParenting1AWTOneNewtChilds01() throws InterruptedException, InvocationTargetException {
+ testWindowParenting1AWT(false);
}
- public void testWindowParenting1AWTTwoNewtChilds() throws InterruptedException, InvocationTargetException {
+ @Test
+ public void testWindowParenting1AWTTwoNewtChilds01() throws InterruptedException, InvocationTargetException {
+ testWindowParenting1AWT(true);
+ }
+
+ public void testWindowParenting1AWT(boolean use2nd) throws InterruptedException, InvocationTargetException {
final Frame frame1 = new Frame("AWT Parent Frame");
GLWindow glWindow1 = GLWindow.create(glCaps);
glWindow1.setUpdateFPSFrames(1, null);
final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
- newtCanvasAWT1.setPreferredSize(size);
+ newtCanvasAWT1.setPreferredSize(glSize);
GLEventListener demo1 = new GearsES2(1);
setDemoFields(demo1, glWindow1, false);
@@ -83,7 +89,6 @@ public class TestParenting03AWT extends UITestCase {
GLAnimatorControl animator1 = new Animator(glWindow1);
animator1.start();
- final boolean use2nd = true;
GLWindow glWindow2 = null;
NewtCanvasAWT newtCanvasAWT2 = null;
GLAnimatorControl animator2 = null;
@@ -91,7 +96,7 @@ public class TestParenting03AWT extends UITestCase {
glWindow2 = GLWindow.create(glCaps);
glWindow2.setUpdateFPSFrames(1, null);
newtCanvasAWT2 = new NewtCanvasAWT(glWindow2);
- newtCanvasAWT2.setPreferredSize(size);
+ newtCanvasAWT2.setPreferredSize(glSize);
GLEventListener demo2 = new GearsES2(1);
setDemoFields(demo2, glWindow2, false);
@@ -103,10 +108,10 @@ public class TestParenting03AWT extends UITestCase {
final Container cont1 = new Container();
cont1.setLayout(new BorderLayout());
- cont1.add(new Label("iNORTH"), BorderLayout.NORTH);
- cont1.add(new Label("iSOUTH"), BorderLayout.SOUTH);
- cont1.add(new Label("iEAST"), BorderLayout.EAST);
- cont1.add(new Label("iWEST"), BorderLayout.WEST);
+ cont1.add(new Button("NORTH"), BorderLayout.NORTH);
+ cont1.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ cont1.add(new Button("EAST"), BorderLayout.EAST);
+ cont1.add(new Button("WEST"), BorderLayout.WEST);
cont1.add(newtCanvasAWT1, BorderLayout.CENTER);
System.err.println("******* Cont1 setVisible");
cont1.setVisible(true);
@@ -114,34 +119,31 @@ public class TestParenting03AWT extends UITestCase {
final Container cont2 = new Container();
cont2.setLayout(new BorderLayout());
if(use2nd) {
- cont2.add(new Label("iNORTH"), BorderLayout.NORTH);
- cont2.add(new Label("iSOUTH"), BorderLayout.SOUTH);
- cont2.add(new Label("iEAST"), BorderLayout.EAST);
- cont2.add(new Label("iWEST"), BorderLayout.WEST);
+ cont2.add(new Button("north"), BorderLayout.NORTH);
+ cont2.add(new Button("sourth"), BorderLayout.SOUTH);
+ cont2.add(new Button("east"), BorderLayout.EAST);
+ cont2.add(new Button("west"), BorderLayout.WEST);
cont2.add(newtCanvasAWT2, BorderLayout.CENTER);
}
System.err.println("******* Cont2 setVisible");
cont2.setVisible(true);
frame1.setLayout(new BorderLayout());
- frame1.add(new Label("NORTH"), BorderLayout.NORTH);
- frame1.add(new Label("CENTER"), BorderLayout.CENTER);
- frame1.add(new Label("SOUTH"), BorderLayout.SOUTH);
+ frame1.add(new Button("NORTH"), BorderLayout.NORTH);
+ frame1.add(new Button("CENTER"), BorderLayout.CENTER);
+ frame1.add(new Button("SOUTH"), BorderLayout.SOUTH);
frame1.add(cont1, BorderLayout.EAST);
frame1.setLocation(0, 0);
- frame1.setSize((int)size.getWidth()*3, (int)size.getHeight()*2);
+ frame1.setSize(fSize);
javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
System.err.println("******* Frame setVisible");
+ frame1.validate();
frame1.setVisible(true);
}});
Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
- if(use2nd) {
- Assert.assertEquals(newtCanvasAWT2.getNativeWindow(),glWindow2.getParent());
- }
-
Assert.assertEquals(true, animator1.isAnimating());
Assert.assertEquals(false, animator1.isPaused());
Assert.assertNotNull(animator1.getThread());
@@ -150,15 +152,17 @@ public class TestParenting03AWT extends UITestCase {
Assert.assertEquals(true, animator2.isAnimating());
Assert.assertEquals(false, animator2.isPaused());
Assert.assertNotNull(animator2.getThread());
- }
- Thread.sleep(waitAdd2nd);
+ Thread.sleep(waitAdd2nd);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.add(cont2, BorderLayout.WEST);
+ frame1.validate();
+ }});
+ Assert.assertEquals(newtCanvasAWT2.getNativeWindow(),glWindow2.getParent());
+ }
- javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
- public void run() {
- frame1.add(cont2, BorderLayout.WEST);
- frame1.validate();
- }});
Thread.sleep(durationPerTest);
@@ -187,7 +191,7 @@ public class TestParenting03AWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
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
new file mode 100644
index 000000000..b23c17022
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingFocusTraversal01AWT.java
@@ -0,0 +1,334 @@
+/**
+ * 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.parenting;
+
+import java.lang.reflect.*;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.awt.AWTException;
+import java.awt.AWTKeyStroke;
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.KeyboardFocusManager;
+import java.awt.Robot;
+
+import javax.media.opengl.*;
+
+import com.jogamp.opengl.util.Animator;
+import com.jogamp.newt.*;
+import com.jogamp.newt.opengl.*;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.event.KeyAdapter;
+import com.jogamp.newt.event.KeyEvent;
+
+import java.io.IOException;
+
+import jogamp.newt.driver.DriverClearFocus;
+
+import com.jogamp.opengl.test.junit.util.*;
+import com.jogamp.opengl.test.junit.jogl.demos.es2.GearsES2;
+
+public class TestParentingFocusTraversal01AWT extends UITestCase {
+ static Dimension glSize, fSize;
+ static int numFocus = 8;
+ static long durationPerTest = numFocus * 100;
+ static GLCapabilities glCaps;
+ static boolean manual = false;
+
+ @BeforeClass
+ public static void initClass() {
+ glSize = new Dimension(200,200);
+ fSize = new Dimension(300,300);
+ glCaps = new GLCapabilities(null);
+ }
+
+ @Test
+ public void testWindowParentingAWTFocusTraversal01Onscreen() throws InterruptedException, InvocationTargetException, AWTException {
+ testWindowParentingAWTFocusTraversal(true);
+ }
+
+ @Test
+ public void testWindowParentingAWTFocusTraversal02Offscreen() throws InterruptedException, InvocationTargetException, AWTException {
+ testWindowParentingAWTFocusTraversal(false);
+ }
+
+ public void testWindowParentingAWTFocusTraversal(boolean onscreen) throws InterruptedException, InvocationTargetException, AWTException {
+ Robot robot = new Robot();
+
+ // Bug 4908075 - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4908075
+ // Bug 6463168 - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6463168
+ {
+ final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ final Set<AWTKeyStroke> bwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ final AWTKeyStroke newBack = AWTKeyStroke.getAWTKeyStroke(java.awt.event.KeyEvent.VK_BACK_SPACE, 0, false);
+ Assert.assertNotNull(newBack);
+ final Set<AWTKeyStroke> bwdKeys2 = new HashSet<AWTKeyStroke>(bwdKeys);
+ bwdKeys2.add(newBack);
+ kfm.setDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, bwdKeys2);
+ }
+ {
+ final KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ final Set<AWTKeyStroke> fwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ final Set<AWTKeyStroke> bwdKeys = kfm.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ Iterator<AWTKeyStroke> iter;
+ for(iter = fwdKeys.iterator(); iter.hasNext(); ) {
+ System.err.println("FTKL.fwd-keys: "+iter.next());
+ }
+ for(iter = bwdKeys.iterator(); iter.hasNext(); ) {
+ System.err.println("FTKL.bwd-keys: "+iter.next());
+ }
+ }
+
+ final Frame frame1 = new Frame("AWT Parent Frame");
+ final Button cWest = new Button("WEST");
+ final Button cEast = new Button("EAST");
+ final GLWindow glWindow1 = GLWindow.create(glCaps);
+ glWindow1.setUpdateFPSFrames(1, null);
+ final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
+ newtCanvasAWT1.setPreferredSize(glSize);
+ newtCanvasAWT1.setShallUseOffscreenLayer(!onscreen);
+ newtCanvasAWT1.setFocusable(true);
+
+ // Test FocusAdapter
+ NEWTFocusAdapter glWindow1FA = new NEWTFocusAdapter("GLWindow1");
+ glWindow1.addWindowListener(glWindow1FA);
+ AWTFocusAdapter bWestFA = new AWTFocusAdapter("WEST");
+ cWest.addFocusListener(bWestFA);
+ AWTFocusAdapter bEastFA = new AWTFocusAdapter("EAST");
+ cEast.addFocusListener(bEastFA);
+
+ // Test KeyAdapter
+ NEWTKeyAdapter glWindow1KA = new NEWTKeyAdapter("GLWindow1");
+ glWindow1.addKeyListener(glWindow1KA);
+ AWTKeyAdapter bWestKA = new AWTKeyAdapter("West");
+ cWest.addKeyListener(bWestKA);
+ AWTKeyAdapter bEastKA = new AWTKeyAdapter("East");
+ cEast.addKeyListener(bEastKA);
+
+ // demo ..
+ GLEventListener demo1 = new GearsES2(1);
+ setDemoFields(demo1, glWindow1, false);
+ glWindow1.addGLEventListener(demo1);
+ glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
+ glWindow1.addKeyListener(new KeyAdapter() {
+ public void keyTyped(KeyEvent e) {
+ if(e.getKeyChar()=='c') {
+ System.err.println("Focus Clear");
+ if(glWindow1.getDelegatedWindow() instanceof DriverClearFocus) {
+ ((DriverClearFocus)glWindow1.getDelegatedWindow()).clearFocus();
+ }
+ } else if(e.getKeyChar()=='e') {
+ System.err.println("Focus East");
+ try {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ cEast.requestFocusInWindow();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ } else if(e.getKeyChar()=='w') {
+ System.err.println("Focus West");
+ try {
+ java.awt.EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ cWest.requestFocusInWindow();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ }
+ }
+ });
+ GLAnimatorControl animator1 = new Animator(glWindow1);
+ animator1.start();
+
+ // make frame
+ frame1.setLayout(new BorderLayout());
+ frame1.setLayout(new BorderLayout());
+ frame1.add(cWest, BorderLayout.WEST);
+ frame1.add(newtCanvasAWT1, BorderLayout.CENTER);
+ frame1.add(cEast, BorderLayout.EAST);
+
+ frame1.setLocation(0, 0);
+ frame1.setSize(fSize);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.validate();
+ frame1.setVisible(true);
+ }});
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true));
+ Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
+
+ Assert.assertEquals(true, animator1.isAnimating());
+ Assert.assertEquals(false, animator1.isPaused());
+ Assert.assertNotNull(animator1.getThread());
+
+ if(manual) {
+ Thread.sleep(durationPerTest);
+ } else {
+ //
+ // initial focus on bWest
+ //
+ AWTRobotUtil.assertRequestFocusAndWait(robot, cWest, cWest, bWestFA, null);
+ Assert.assertEquals(true, bWestFA.focusGained());
+ Thread.sleep(durationPerTest/numFocus);
+
+ //
+ // forth
+ //
+
+ // bWest -> glWin
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_TAB, cWest, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bWestFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // glWin -> bEast
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_TAB, glWindow1, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cEast, bEastFA, glWindow1FA));
+ Assert.assertEquals(true, bEastFA.focusGained());
+ Assert.assertEquals(true, glWindow1FA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ //
+ // back (using custom back traversal key 'backspace')
+ //
+ // bEast -> glWin
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_BACK_SPACE, cEast, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bEastFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bEastFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ AWTRobotUtil.keyType(0, robot, java.awt.event.KeyEvent.VK_BACK_SPACE, glWindow1, null);
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cWest, bWestFA, glWindow1FA));
+ Assert.assertEquals(true, bWestFA.focusGained());
+ Assert.assertEquals(true, glWindow1FA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // direct AWT request focus
+ try {
+ java.awt.EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ newtCanvasAWT1.requestFocus();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bWestFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // direct AWT request focus
+ try {
+ java.awt.EventQueue.invokeAndWait(new Runnable() {
+ public void run() {
+ cWest.requestFocus();
+ }
+ });
+ } catch (Exception ex) { ex.printStackTrace(); }
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(cWest, bWestFA, glWindow1FA));
+ Assert.assertEquals(true, bWestFA.focusGained());
+ Assert.assertEquals(true, glWindow1FA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+
+ // direct NEWT request focus
+ glWindow1.requestFocus();
+ Assert.assertTrue("Did not gain focus", AWTRobotUtil.waitForFocus(glWindow1, glWindow1FA, bWestFA));
+ Assert.assertEquals(true, glWindow1FA.focusGained());
+ Assert.assertEquals(true, bWestFA.focusLost());
+ Thread.sleep(durationPerTest/numFocus);
+ }
+
+ animator1.stop();
+ Assert.assertEquals(false, animator1.isAnimating());
+ Assert.assertEquals(false, animator1.isPaused());
+ Assert.assertEquals(null, animator1.getThread());
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.dispose();
+ } } );
+ glWindow1.destroy();
+ }
+
+ public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
+ Assert.assertNotNull(demo);
+ Assert.assertNotNull(glWindow);
+ Window window = glWindow.getDelegatedWindow();
+ if(debug) {
+ MiscUtils.setFieldIfExists(demo, "glDebug", true);
+ MiscUtils.setFieldIfExists(demo, "glTrace", true);
+ }
+ if(!MiscUtils.setFieldIfExists(demo, "window", window)) {
+ MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
+ }
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = atoi(args[++i]);
+ } else if(args[i].equals("-manual")) {
+ manual = true;
+ }
+ }
+ String tstname = TestParentingFocusTraversal01AWT.class.getName();
+ /*
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ tstname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java
new file mode 100644
index 000000000..1367a27dd
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer01GLCanvasAWT.java
@@ -0,0 +1,205 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.newt.parenting;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.awt.GLCanvas;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+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.AWTRobotUtil;
+import com.jogamp.opengl.test.junit.util.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestParentingOffscreenLayer01GLCanvasAWT extends UITestCase {
+ static Dimension frameSize0;
+ static Dimension frameSize1;
+ static Dimension preferredGLSize;
+ static Dimension minGLSize;
+ static long durationPerTest = 1000;
+
+ @BeforeClass
+ public static void initClass() {
+ frameSize0 = new Dimension(500,300);
+ frameSize1 = new Dimension(800,600);
+ preferredGLSize = new Dimension(400,200);
+ minGLSize = new Dimension(200,100);
+ }
+
+ private void setupFrameAndShow(final Frame f, java.awt.Component comp) throws InterruptedException, InvocationTargetException {
+
+ Container c = new Container();
+ c.setLayout(new BorderLayout());
+ c.add(new Button("north"), BorderLayout.NORTH);
+ c.add(new Button("south"), BorderLayout.SOUTH);
+ c.add(new Button("east"), BorderLayout.EAST);
+ c.add(new Button("west"), BorderLayout.WEST);
+ c.add(comp, BorderLayout.CENTER);
+
+ f.setLayout(new BorderLayout());
+ f.add(new Button("NORTH"), BorderLayout.NORTH);
+ f.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ f.add(new Button("EAST"), BorderLayout.EAST);
+ f.add(new Button("WEST"), BorderLayout.WEST);
+ f.add(c, BorderLayout.CENTER);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ f.validate();
+ f.setVisible(true);
+ }});
+ }
+ private void end(GLAnimatorControl actrl, final Frame f, Window w) throws InterruptedException, InvocationTargetException {
+ actrl.stop();
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ f.dispose();
+ } } );
+ if(null != w) {
+ w.destroy();
+ }
+ }
+
+ @Test
+ public void testOnscreenLayerGLCanvas_Onscreen() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerGLCanvas_Impl(false, false);
+ }
+
+ /** We have no GLCanvas OffscreenWindow as we have for NEWT .. test disabled.
+ @Test
+ public void testOffscreenLayerGLCanvas_OffscreenLayerWithOffscreenClass() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerGLCanvas_Impl(true, true);
+ } */
+
+ @Test
+ public void testOffscreenLayerGLCanvas_OffscreenLayerWithOnscreenClass() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerGLCanvas_Impl(true, false);
+ }
+
+ private void testOffscreenLayerGLCanvas_Impl(boolean offscreenLayer, boolean offscreenClass) throws InterruptedException, InvocationTargetException {
+ final Frame frame1 = new Frame("AWT Parent Frame");
+
+ GLCapabilities glCaps = new GLCapabilities(null);
+ if(offscreenClass) {
+ glCaps.setOnscreen(false);
+ glCaps.setPBuffer(true);
+ }
+
+ final GLCanvas glc = new GLCanvas(glCaps);
+ glc.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+ glc.setPreferredSize(preferredGLSize);
+ glc.setMinimumSize(minGLSize);
+
+ GLEventListener demo1 = new GearsES2(1);
+ glc.addGLEventListener(demo1);
+
+ frame1.setSize(frameSize0);
+ setupFrameAndShow(frame1, glc);
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glc, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glc, true));
+ Assert.assertEquals(JAWTUtil.isOffscreenLayerSupported() && offscreenLayer,
+ glc.isOffscreenLayerSurfaceEnabled());
+
+ GLAnimatorControl animator1 = new Animator(glc);
+ animator1.start();
+
+ Thread.sleep(durationPerTest/2);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setSize(frameSize1);
+ frame1.validate();
+ }});
+
+ Thread.sleep(durationPerTest/2);
+
+ end(animator1, frame1, null);
+ }
+
+ public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
+ Assert.assertNotNull(demo);
+ Assert.assertNotNull(glWindow);
+ Window window = glWindow.getDelegatedWindow();
+ if(debug) {
+ MiscUtils.setFieldIfExists(demo, "glDebug", true);
+ MiscUtils.setFieldIfExists(demo, "glTrace", true);
+ }
+ if(!MiscUtils.setFieldIfExists(demo, "window", window)) {
+ MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
+ }
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = atoi(args[++i]);
+ }
+ }
+ String tstname = TestParentingOffscreenLayer01GLCanvasAWT.class.getName();
+ /*
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ tstname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java
new file mode 100644
index 000000000..bc59c7378
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestParentingOffscreenLayer02NewtCanvasAWT.java
@@ -0,0 +1,209 @@
+/**
+ * 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 com.jogamp.opengl.test.junit.newt.parenting;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+
+import jogamp.nativewindow.jawt.JAWTUtil;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.jogamp.newt.Window;
+import com.jogamp.newt.awt.NewtCanvasAWT;
+import com.jogamp.newt.opengl.GLWindow;
+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.MiscUtils;
+import com.jogamp.opengl.test.junit.util.UITestCase;
+import com.jogamp.opengl.util.Animator;
+
+public class TestParentingOffscreenLayer02NewtCanvasAWT extends UITestCase {
+ static Dimension frameSize0;
+ static Dimension frameSize1;
+ static Dimension preferredGLSize;
+ static Dimension minGLSize;
+ static long durationPerTest = 1000;
+
+ @BeforeClass
+ public static void initClass() {
+ frameSize0 = new Dimension(500,300);
+ frameSize1 = new Dimension(800,600);
+ preferredGLSize = new Dimension(400,200);
+ minGLSize = new Dimension(200,100);
+ }
+
+ private void setupFrameAndShow(final Frame f, java.awt.Component comp) throws InterruptedException, InvocationTargetException {
+
+ Container c = new Container();
+ c.setLayout(new BorderLayout());
+ c.add(new Button("north"), BorderLayout.NORTH);
+ c.add(new Button("south"), BorderLayout.SOUTH);
+ c.add(new Button("east"), BorderLayout.EAST);
+ c.add(new Button("west"), BorderLayout.WEST);
+ c.add(comp, BorderLayout.CENTER);
+
+ f.setLayout(new BorderLayout());
+ f.add(new Button("NORTH"), BorderLayout.NORTH);
+ f.add(new Button("SOUTH"), BorderLayout.SOUTH);
+ f.add(new Button("EAST"), BorderLayout.EAST);
+ f.add(new Button("WEST"), BorderLayout.WEST);
+ f.add(c, BorderLayout.CENTER);
+
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ f.validate();
+ f.setVisible(true);
+ }});
+ }
+ private void end(GLAnimatorControl actrl, final Frame f, Window w) throws InterruptedException, InvocationTargetException {
+ actrl.stop();
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ f.dispose();
+ } } );
+ if(null != w) {
+ w.destroy();
+ }
+ }
+
+ @Test
+ public void testOnscreenLayerNewtCanvas_Onscreen() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerNewtCanvas_Impl(false, false);
+ }
+
+ @Test
+ public void testOffscreenLayerNewtCanvas_OffscreenLayerWithOffscreenClass() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerNewtCanvas_Impl(true, true);
+ }
+
+ @Test
+ public void testOffscreenLayerNewtCanvas_OffscreenLayerWithOnscreenClass() throws InterruptedException, InvocationTargetException {
+ testOffscreenLayerNewtCanvas_Impl(true, false);
+ }
+
+ private void testOffscreenLayerNewtCanvas_Impl(boolean offscreenLayer, boolean offscreenClass) throws InterruptedException, InvocationTargetException {
+ final Frame frame1 = new Frame("AWT Parent Frame");
+
+ GLCapabilities glCaps = new GLCapabilities(null);
+ if(offscreenClass) {
+ glCaps.setOnscreen(false);
+ glCaps.setPBuffer(true);
+ }
+
+ GLWindow glWindow1 = GLWindow.create(glCaps);
+
+ final NewtCanvasAWT newtCanvasAWT1 = new NewtCanvasAWT(glWindow1);
+ newtCanvasAWT1.setShallUseOffscreenLayer(offscreenLayer); // trigger offscreen layer - if supported
+ newtCanvasAWT1.setPreferredSize(preferredGLSize);
+ newtCanvasAWT1.setMinimumSize(minGLSize);
+
+ GLEventListener demo1 = new GearsES2(1);
+ setDemoFields(demo1, glWindow1, false);
+ glWindow1.addGLEventListener(demo1);
+ glWindow1.addKeyListener(new NewtAWTReparentingKeyAdapter(frame1, newtCanvasAWT1, glWindow1));
+
+ frame1.setSize(frameSize0);
+ setupFrameAndShow(frame1, newtCanvasAWT1);
+ Assert.assertEquals(true, AWTRobotUtil.waitForRealized(glWindow1, true));
+ Assert.assertEquals(true, AWTRobotUtil.waitForVisible(glWindow1, true));
+ Assert.assertEquals(newtCanvasAWT1.getNativeWindow(),glWindow1.getParent());
+ Assert.assertEquals(JAWTUtil.isOffscreenLayerSupported() && offscreenLayer,
+ newtCanvasAWT1.isOffscreenLayerSurfaceEnabled());
+
+ GLAnimatorControl animator1 = new Animator(glWindow1);
+ animator1.start();
+
+ Thread.sleep(durationPerTest/2);
+ javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ frame1.setSize(frameSize1);
+ frame1.validate();
+ }});
+
+ Thread.sleep(durationPerTest/2);
+
+ end(animator1, frame1, glWindow1);
+ }
+
+ public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
+ Assert.assertNotNull(demo);
+ Assert.assertNotNull(glWindow);
+ Window window = glWindow.getDelegatedWindow();
+ if(debug) {
+ MiscUtils.setFieldIfExists(demo, "glDebug", true);
+ MiscUtils.setFieldIfExists(demo, "glTrace", true);
+ }
+ if(!MiscUtils.setFieldIfExists(demo, "window", window)) {
+ MiscUtils.setFieldIfExists(demo, "glWindow", glWindow);
+ }
+ }
+
+ static int atoi(String a) {
+ int i=0;
+ try {
+ i = Integer.parseInt(a);
+ } catch (Exception ex) { ex.printStackTrace(); }
+ return i;
+ }
+
+ public static void main(String args[]) throws IOException {
+ for(int i=0; i<args.length; i++) {
+ if(args[i].equals("-time")) {
+ durationPerTest = atoi(args[++i]);
+ }
+ }
+ String tstname = TestParentingOffscreenLayer02NewtCanvasAWT.class.getName();
+ /*
+ org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(new String[] {
+ tstname,
+ "filtertrace=true",
+ "haltOnError=false",
+ "haltOnFailure=false",
+ "showoutput=true",
+ "outputtoformatters=true",
+ "logfailedtests=true",
+ "logtestlistenerevents=true",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter",
+ "formatter=org.apache.tools.ant.taskdefs.optional.junit.XMLJUnitResultFormatter,TEST-"+tstname+".xml" } ); */
+ org.junit.runner.JUnitCore.main(tstname);
+ }
+
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
index be812e6aa..57b8517a6 100644
--- a/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
+++ b/src/test/com/jogamp/opengl/test/junit/newt/parenting/TestTranslucentParentingAWT.java
@@ -50,6 +50,7 @@ import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
+import com.jogamp.common.util.ReflectionUtil;
import com.jogamp.newt.Window;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
@@ -89,8 +90,15 @@ public class TestTranslucentParentingAWT extends UITestCase {
boolean capable1 = ( null != tcm ) ? tcm.getTransparency() == Transparency.TRANSLUCENT : false;
boolean capable2 = false;
try {
- capable2 = com.sun.awt.AWTUtilities.isTranslucencyCapable(config);
- } catch (Exception e) {}
+ capable2 = ((Boolean)ReflectionUtil.callStaticMethod(
+ "com.sun.awt.AWTUtilities", "isTranslucencyCapable",
+ new Class<?>[] { GraphicsConfiguration.class },
+ new Object[] { config } ,
+ GraphicsConfiguration.class.getClassLoader())).booleanValue();
+ System.err.println("com.sun.awt.AWTUtilities.isTranslucencyCapable(config) passed: "+capable2);
+ } catch (RuntimeException re) {
+ System.err.println("com.sun.awt.AWTUtilities.isTranslucencyCapable(config) failed: "+re.getMessage());
+ }
System.err.println(i+":"+j+" "+config+", "+tcm+", capable "+capable1+"/"+capable2);
if(capable1&&capable2) {
gc=configs[j];
@@ -157,7 +165,7 @@ public class TestTranslucentParentingAWT extends UITestCase {
public static void setDemoFields(GLEventListener demo, GLWindow glWindow, boolean debug) {
Assert.assertNotNull(demo);
Assert.assertNotNull(glWindow);
- Window window = glWindow.getWindow();
+ Window window = glWindow.getDelegatedWindow();
if(debug) {
MiscUtils.setFieldIfExists(demo, "glDebug", true);
MiscUtils.setFieldIfExists(demo, "glTrace", true);
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
index 7df8645de..a27bdd7a2 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTRobotUtil.java
@@ -67,7 +67,7 @@ public class AWTRobotUtil {
int x0, y0;
if(null!=comp) {
- java.awt.Point p0 = comp.getLocationOnScreen();
+ java.awt.Point p0 = comp.getLocationOnScreen();
java.awt.Rectangle r0 = comp.getBounds();
if( onTitleBarIfWindow && comp instanceof java.awt.Window) {
java.awt.Window window = (java.awt.Window) comp;
@@ -78,7 +78,7 @@ public class AWTRobotUtil {
}
x0 = (int) ( p0.getX() + r0.getWidth() / 2.0 + .5 ) ;
} else {
- javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null);
+ javax.media.nativewindow.util.Point p0 = win.getLocationOnScreen(null);
if( onTitleBarIfWindow ) {
javax.media.nativewindow.util.InsetsImmutable insets = win.getInsets();
p0.translate(win.getWidth()/2, insets.getTopHeight()/2);
@@ -102,6 +102,9 @@ public class AWTRobotUtil {
public static boolean toFront(Robot robot, final java.awt.Window window)
throws AWTException, InterruptedException, InvocationTargetException {
+ AWTWindowFocusAdapter winFA = new AWTWindowFocusAdapter("window");
+ window.addWindowFocusListener(winFA);
+
if(null == robot) {
robot = new Robot();
robot.setAutoWaitForIdle(true);
@@ -119,11 +122,11 @@ public class AWTRobotUtil {
}});
robot.delay(ROBOT_DELAY);
- KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
int wait;
- for (wait=0; wait<POLL_DIVIDER && window != kfm.getFocusedWindow(); wait++) {
+ for (wait=0; wait<POLL_DIVIDER && !winFA.focusGained(); wait++) {
Thread.sleep(TIME_SLICE);
}
+ window.removeWindowFocusListener(winFA);
return wait<POLL_DIVIDER;
}
@@ -280,8 +283,8 @@ public class AWTRobotUtil {
Assert.assertTrue("Did not gain focus", hasFocus);
}
- static int keyType(int i, Robot robot, int keyCode,
- Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException
+ public static int keyType(int i, Robot robot, int keyCode,
+ Object obj, InputEventCountAdapter counter) throws InterruptedException, AWTException, InvocationTargetException
{
int tc = 0;
int j;
@@ -293,13 +296,13 @@ public class AWTRobotUtil {
if(DEBUG) { System.err.println(i+":"+j+" KC1.0: "+counter+" - regain focus"); }
requestFocus(null, obj);
}
- final int c0 = counter.getCount();
+ final int c0 = null!=counter ? counter.getCount() : 0;
if(DEBUG) { System.err.println(i+":"+j+" KC1.1: "+counter); }
robot.waitForIdle();
robot.keyPress(keyCode);
robot.keyRelease(keyCode);
if(DEBUG) { System.err.println(i+":"+j+" KC1.2: "+counter); }
- tc = counter.getCount() - c0;
+ tc = ( null!=counter ? counter.getCount() : 1 ) - c0;
for (int wait=0; wait<POLL_DIVIDER && 1 > tc; wait++) {
robot.delay(TIME_SLICE);
tc = counter.getCount() - c0;
@@ -355,13 +358,13 @@ public class AWTRobotUtil {
if(DEBUG) { System.err.println(i+":"+j+" MC1.0: "+counter+" - regain focus"); }
requestFocus(null, obj);
}
- final int c0 = counter.getCount();
+ final int c0 = null != counter ? counter.getCount() : 0;
if(DEBUG) { System.err.println(i+":"+j+" MC1.1: "+counter); }
robot.waitForIdle();
robot.mousePress(mouseButton);
robot.mouseRelease(mouseButton);
if(DEBUG) { System.err.println(i+":"+j+" MC1.2: "+counter); }
- tc = counter.getCount() - c0;
+ tc = ( null != counter ? counter.getCount() : 1 ) - c0;
for (int wait=0; wait<POLL_DIVIDER && 1 > tc; wait++) {
robot.delay(TIME_SLICE);
tc = counter.getCount() - c0;
diff --git a/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
new file mode 100644
index 000000000..16aacd2fd
--- /dev/null
+++ b/src/test/com/jogamp/opengl/test/junit/util/AWTWindowFocusAdapter.java
@@ -0,0 +1,71 @@
+/**
+ * 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.util;
+
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowFocusListener;
+
+public class AWTWindowFocusAdapter implements FocusEventCountAdapter, WindowFocusListener {
+
+ String prefix;
+ int focusCount;
+
+ public AWTWindowFocusAdapter(String prefix) {
+ this.prefix = prefix;
+ reset();
+ }
+
+ public boolean focusLost() {
+ return focusCount<0;
+ }
+
+ public boolean focusGained() {
+ return focusCount>0;
+ }
+
+ public void reset() {
+ focusCount = 0;
+ }
+
+ /* @Override */
+ public void windowGainedFocus(WindowEvent e) {
+ if(focusCount<0) { focusCount=0; }
+ focusCount++;
+ System.err.println("FOCUS AWT GAINED (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ }
+
+ /* @Override */
+ public void windowLostFocus(WindowEvent e) {
+ if(focusCount>0) { focusCount=0; }
+ focusCount--;
+ System.err.println("FOCUS AWT LOST (Window) [fc "+focusCount+"]: "+prefix+", "+e);
+ }
+
+ public String toString() { return prefix+"[focusCount "+focusCount +"]"; }
+}
diff --git a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
index 6a6cf390f..c74d2eaa7 100644
--- a/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
+++ b/src/test/com/jogamp/opengl/test/junit/util/NEWTGLContext.java
@@ -78,6 +78,7 @@ public class NEWTGLContext {
Assert.assertNotNull(drawable);
drawable.setRealized(true);
+ Assert.assertTrue(drawable.isRealized());
GLContext context = drawable.createContext(null);
Assert.assertNotNull(context);
diff --git a/src/test/jogamp/newt/WindowImplAccess.java b/src/test/jogamp/newt/WindowImplAccess.java
index 76d0dc050..e8be5f68a 100644
--- a/src/test/jogamp/newt/WindowImplAccess.java
+++ b/src/test/jogamp/newt/WindowImplAccess.java
@@ -29,26 +29,16 @@
package jogamp.newt;
import com.jogamp.newt.Window;
-import com.jogamp.newt.opengl.GLWindow;
/**
* Allows access to protected methods of WindowImpl
*/
public class WindowImplAccess {
public static final void windowDestroyNotify(Window win) {
- WindowImpl winImpl = null;
- if(win instanceof GLWindow) {
- GLWindow glwin = (GLWindow) win;
- winImpl = (WindowImpl) glwin.getWindow();
- } else if(win instanceof WindowImpl) {
- winImpl = (WindowImpl) win;
- } else {
- throw new RuntimeException("Given Window not a GLWindow, not WindowImpl, but "+win.getClass());
- }
- final WindowImpl winImplF = winImpl;
- winImplF.runOnEDTIfAvail(true, new Runnable() {
+ final WindowImpl winImpl = (WindowImpl) win.getDelegatedWindow();
+ winImpl.runOnEDTIfAvail(true, new Runnable() {
public void run() {
- winImplF.windowDestroyNotify();
+ winImpl.windowDestroyNotify();
}
});
}
diff --git a/src/test/native/displayMultiple02.c b/src/test/native/displayMultiple02.c
index 1bfe95b95..df6666aff 100644
--- a/src/test/native/displayMultiple02.c
+++ b/src/test/native/displayMultiple02.c
@@ -11,7 +11,21 @@
static void testOrder(int reverseDestroyOrder, const char * msg);
+static int useXLockDisplay = 0;
+
int main(int nargs, char **vargs) {
+ int arg=1;
+ while(arg<nargs) {
+ if(0 == strcmp(vargs[arg], "-xlock")) {
+ useXLockDisplay = 1;
+ }
+ arg++;
+ }
+ fprintf(stderr, "-xlock (XLockDisplay): %d\n", useXLockDisplay);
+
+ if( useXLockDisplay ) {
+ XInitThreads();
+ }
testOrder(0, "Normal order");
testOrder(1, "Reverse order");
return 0;
@@ -20,6 +34,17 @@ int main(int nargs, char **vargs) {
static void createGLWin(Display *dpy, int width, int height, Window *rWin, GLXContext *rCtx);
static void useGL(Display *dpy, Window win, GLXContext ctx, int width, int height);
+static void XLOCKDISPLAY(Display *dpy) {
+ if( useXLockDisplay ) {
+ XLockDisplay(dpy);
+ }
+}
+static void XUNLOCKDISPLAY(Display *dpy) {
+ if( useXLockDisplay ) {
+ XUnlockDisplay(dpy);
+ }
+}
+
void testOrder(int reverseDestroyOrder, const char * msg) {
int major, minor;
Display *disp1;
@@ -32,35 +57,58 @@ void testOrder(int reverseDestroyOrder, const char * msg) {
fprintf(stderr, "%s: Create #1\n", msg);
disp1 = XOpenDisplay(NULL);
- createGLWin(disp1, 200, 200, &win1, &ctx1);
- useGL(disp1, win1, ctx1, 200, 200);
+ XLOCKDISPLAY(disp1);
+ createGLWin(disp1, 200, 200, &win1, &ctx1);
+ useGL(disp1, win1, ctx1, 200, 200);
+ XUNLOCKDISPLAY(disp1);
fprintf(stderr, "%s: Create #2\n", msg);
disp2 = XOpenDisplay(NULL);
- createGLWin(disp2, 300, 300, &win2, &ctx2);
- useGL(disp2, win2, ctx2, 300, 300);
+ XLOCKDISPLAY(disp2);
+ createGLWin(disp2, 300, 300, &win2, &ctx2);
+ useGL(disp2, win2, ctx2, 300, 300);
+ XUNLOCKDISPLAY(disp2);
if(reverseDestroyOrder) {
- fprintf(stderr, "%s: Destroy #2\n", msg);
- glXMakeCurrent(disp2, 0, 0);
- glXDestroyContext(disp2, ctx2);
+ fprintf(stderr, "%s: Destroy #2.0\n", msg);
+ XLOCKDISPLAY(disp2);
+ glXMakeCurrent(disp2, 0, 0);
+ glXDestroyContext(disp2, ctx2);
+ XUNLOCKDISPLAY(disp2);
XCloseDisplay(disp2);
-
- fprintf(stderr, "%s: Destroy #1\n", msg);
- glXMakeCurrent(disp1, 0, 0);
- glXDestroyContext(disp1, ctx1);
+ fprintf(stderr, "%s: Destroy #2.X\n", msg);
+
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ XLOCKDISPLAY(disp1);
+ fprintf(stderr, "%s: Destroy #1.1\n", msg);
+ glXMakeCurrent(disp1, 0, 0);
+ fprintf(stderr, "%s: Destroy #1.2\n", msg);
+ glXDestroyContext(disp1, ctx1);
+ fprintf(stderr, "%s: Destroy #1.3\n", msg);
+ XUNLOCKDISPLAY(disp1);
+ fprintf(stderr, "%s: Destroy #1.4\n", msg);
XCloseDisplay(disp1);
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
} else {
- fprintf(stderr, "%s: Destroy #1\n", msg);
- glXMakeCurrent(disp1, 0, 0);
- glXDestroyContext(disp1, ctx1);
+ fprintf(stderr, "%s: Destroy #1.0\n", msg);
+ XLOCKDISPLAY(disp1);
+ glXMakeCurrent(disp1, 0, 0);
+ glXDestroyContext(disp1, ctx1);
+ XUNLOCKDISPLAY(disp1);
XCloseDisplay(disp1);
-
- fprintf(stderr, "%s: Destroy #2\n", msg);
- glXMakeCurrent(disp2, 0, 0);
- glXDestroyContext(disp2, ctx2);
+ fprintf(stderr, "%s: Destroy #1.X\n", msg);
+
+ fprintf(stderr, "%s: Destroy #2.0\n", msg);
+ XLOCKDISPLAY(disp2);
+ fprintf(stderr, "%s: Destroy #2.1\n", msg);
+ glXMakeCurrent(disp2, 0, 0);
+ fprintf(stderr, "%s: Destroy #2.2\n", msg);
+ glXDestroyContext(disp2, ctx2);
+ fprintf(stderr, "%s: Destroy #2.3\n", msg);
+ XUNLOCKDISPLAY(disp2);
+ fprintf(stderr, "%s: Destroy #2.4\n", msg);
XCloseDisplay(disp2);
-
+ fprintf(stderr, "%s: Destroy #2.X\n", msg);
}
fprintf(stderr, "%s: Success - no bug\n", msg);