34package com.jogamp.nativewindow;
37import java.lang.reflect.Method;
38import java.security.PrivilegedAction;
39import java.util.ArrayList;
40import java.util.Collections;
41import java.util.HashMap;
45import com.jogamp.nativewindow.util.Point;
47import jogamp.common.os.PlatformPropsImpl;
48import jogamp.nativewindow.BcmVCArtifacts;
49import jogamp.nativewindow.Debug;
50import jogamp.nativewindow.NativeWindowFactoryImpl;
51import jogamp.nativewindow.ResourceToolkitLock;
52import jogamp.nativewindow.ToolkitProperties;
53import jogamp.nativewindow.WrappedWindow;
55import com.jogamp.common.os.Platform;
56import com.jogamp.common.util.InterruptSource;
57import com.jogamp.common.util.PropertyAccess;
58import com.jogamp.common.util.ReflectionUtil;
59import com.jogamp.common.util.SecurityUtil;
71 protected static final boolean DEBUG;
106 private static final String nativeWindowingTypeNative;
107 private static final String nativeWindowingTypeCustom;
112 private static Class<?> nativeWindowClass;
113 private static boolean isAWTAvailable;
115 private static final String JAWTUtilClassName =
"jogamp.nativewindow.jawt.JAWTUtil" ;
117 private static final String X11UtilClassName =
"jogamp.nativewindow.x11.X11Util";
119 private static final String DRMUtilClassName =
"jogamp.nativewindow.drm.DRMUtil";
121 private static final String OSXUtilClassName =
"jogamp.nativewindow.macosx.OSXUtil";
123 private static final String IOSUtilClassName =
"jogamp.nativewindow.ios.IOSUtil";
125 private static final String GDIClassName =
"jogamp.nativewindow.windows.GDIUtil";
127 private static ToolkitLock jawtUtilJAWTToolkitLock;
129 private static boolean requiresToolkitLock;
130 private static boolean desktopHasThreadingIssues;
133 private static volatile boolean isJVMShuttingDown =
false;
134 private static final List<Runnable> customShutdownHooks =
new ArrayList<Runnable>();
141 private static String _getNativeWindowingType(
final boolean debug) {
142 switch(PlatformPropsImpl.OS_TYPE) {
162 BcmVCArtifacts.guessVCIVUsed(
true);
164 if( BcmVCArtifacts.guessVCIVUsed(
false) ) {
178 if( guessX(
false) ) {
181 if( guessWayland(
false) ) {
185 if( guessGBM(
false) ) {
192 private static boolean guessX(
final boolean debug) {
193 final String s = System.getenv(
"DISPLAY");
195 System.err.println(
"guessX: <"+s+
"> isSet "+(
null!=s));
200 private static boolean guessWayland(
final boolean debug) {
202 final String s = System.getenv(
"WAYLAND_DISPLAY");
204 System.err.println(
"guessWayland: <"+s+
"> isSet "+(
null!=s));
209 private static boolean guessGBM(
final boolean debug) {
211 final File f =
new File(
"/dev/dri/card0" );
213 System.err.println(
"guessGBM: <"+f.toString()+
"> exists "+f.exists());
219 final boolean[] _DEBUG =
new boolean[] {
false };
220 final String[] _tmp =
new String[] {
null };
221 final String[] _nativeWindowingTypeNative =
new String[] {
null };
223 SecurityUtil.doPrivileged(
new PrivilegedAction<Object>() {
225 public Object run() {
226 Platform.initSingleton();
227 _DEBUG[0] = Debug.debug(
"NativeWindow");
228 _tmp[0] = PropertyAccess.getProperty(
"nativewindow.ws.name",
true);
229 _nativeWindowingTypeNative[0] = _getNativeWindowingType(_DEBUG[0]);
230 Runtime.getRuntime().addShutdownHook(
231 new InterruptSource.Thread(
null,
new Runnable() {
235 } },
"NativeWindowFactory_ShutdownHook" ) ) ;
241 nativeWindowingTypeNative = _nativeWindowingTypeNative[0];
242 if(
null==_tmp[0] || _tmp[0].length()==0) {
243 nativeWindowingTypeCustom = nativeWindowingTypeNative;
245 nativeWindowingTypeCustom = _tmp[0].intern();
248 System.err.println(Thread.currentThread().getName()+
" - Info: NativeWindowFactory.<init>: Type "+nativeWindowingTypeCustom+
" custom / "+nativeWindowingTypeNative+
" native");
253 private static boolean initialized =
false;
255 private static String getNativeWindowingTypeClassName() {
256 final String clazzName;
257 switch( nativeWindowingTypeNative ) {
259 clazzName = X11UtilClassName;
262 clazzName = DRMUtilClassName;
265 clazzName = GDIClassName;
268 clazzName = OSXUtilClassName;
271 clazzName = IOSUtilClassName;
278 private static void initSingletonNativeImpl(
final ClassLoader cl) {
279 final String clazzName = getNativeWindowingTypeClassName();
280 if(
null != clazzName ) {
281 ReflectionUtil.callStaticMethod(clazzName,
"initSingleton",
null,
null, cl );
283 final Boolean res1 = (Boolean) ReflectionUtil.callStaticMethod(clazzName,
"requiresToolkitLock",
null,
null, cl);
284 requiresToolkitLock = res1.booleanValue();
285 final Boolean res2 = (Boolean) ReflectionUtil.callStaticMethod(clazzName,
"hasThreadingIssues",
null,
null, cl);
286 desktopHasThreadingIssues = res2.booleanValue();
288 requiresToolkitLock =
false;
289 desktopHasThreadingIssues =
false;
303 synchronized( customShutdownHooks ) {
304 if( !customShutdownHooks.contains( runnable ) ) {
306 customShutdownHooks.add(0, runnable);
308 customShutdownHooks.add( runnable );
317 public static synchronized void shutdown(
final boolean _isJVMShuttingDown) {
318 isJVMShuttingDown = _isJVMShuttingDown;
320 System.err.println(
"NativeWindowFactory.shutdown() START: JVM Shutdown "+isJVMShuttingDown+
", on thread "+Thread.currentThread().getName());
322 synchronized(customShutdownHooks) {
323 final int cshCount = customShutdownHooks.size();
324 for(
int i=0; i < cshCount; i++) {
327 System.err.println(
"NativeWindowFactory.shutdown - customShutdownHook #"+(i+1)+
"/"+cshCount);
329 customShutdownHooks.get(i).run();
330 }
catch(
final Throwable t) {
331 System.err.println(
"NativeWindowFactory.shutdown: Caught "+t.getClass().getName()+
" during customShutdownHook #"+(i+1)+
"/"+cshCount);
337 customShutdownHooks.clear();
340 System.err.println(
"NativeWindowFactory.shutdown(): Post customShutdownHook");
345 if(
null != registeredFactories) {
346 registeredFactories.clear();
347 registeredFactories =
null;
355 System.err.println(Thread.currentThread().getName()+
" - NativeWindowFactory.shutdown() END JVM Shutdown "+isJVMShuttingDown);
359 private static void shutdownNativeImpl(
final ClassLoader cl) {
360 final String clazzName = getNativeWindowingTypeClassName();
361 if(
null != clazzName ) {
362 ReflectionUtil.callStaticMethod(clazzName,
"shutdown",
null,
null, cl );
378 System.err.println(Thread.currentThread().getName()+
" - NativeWindowFactory.initSingleton()");
383 isAWTAvailable =
false;
385 if( Platform.AWT_AVAILABLE &&
386 ReflectionUtil.isClassAvailable(
"com.jogamp.nativewindow.awt.AWTGraphicsDevice", cl) ) {
388 final Method[] jawtUtilMethods = SecurityUtil.doPrivileged(
new PrivilegedAction<Method[]>() {
390 public Method[] run() {
392 final Class<?> _jawtUtilClass = Class.forName(JAWTUtilClassName,
true,
NativeWindowFactory.class.getClassLoader());
393 final Method jawtUtilIsHeadlessMethod = _jawtUtilClass.getDeclaredMethod(
"isHeadlessMode", (Class[])
null);
394 jawtUtilIsHeadlessMethod.setAccessible(
true);
395 final Method jawtUtilInitMethod = _jawtUtilClass.getDeclaredMethod(
"initSingleton", (Class[])
null);
396 jawtUtilInitMethod.setAccessible(
true);
397 final Method jawtUtilGetJAWTToolkitLockMethod = _jawtUtilClass.getDeclaredMethod(
"getJAWTToolkitLock",
new Class[]{});
398 jawtUtilGetJAWTToolkitLockMethod.setAccessible(
true);
399 return new Method[] { jawtUtilInitMethod, jawtUtilIsHeadlessMethod, jawtUtilGetJAWTToolkitLockMethod };
400 }
catch (
final Exception e) {
408 if(
null != jawtUtilMethods) {
409 final Method jawtUtilInitMethod = jawtUtilMethods[0];
410 final Method jawtUtilIsHeadlessMethod = jawtUtilMethods[1];
411 final Method jawtUtilGetJAWTToolkitLockMethod = jawtUtilMethods[2];
413 ReflectionUtil.callMethod(
null, jawtUtilInitMethod);
415 Object resO = ReflectionUtil.callMethod(
null, jawtUtilIsHeadlessMethod);
416 if(resO instanceof Boolean) {
419 isAWTAvailable = ((Boolean)resO).equals(Boolean.FALSE);
421 throw new RuntimeException(
"JAWTUtil.isHeadlessMode() didn't return a Boolean");
423 resO = ReflectionUtil.callMethod(
null, jawtUtilGetJAWTToolkitLockMethod);
427 throw new RuntimeException(
"JAWTUtil.getJAWTToolkitLock() didn't return a ToolkitLock");
436 initSingletonNativeImpl(cl);
438 registeredFactories = Collections.synchronizedMap(
new HashMap<Class<?>,
NativeWindowFactory>());
442 nativeWindowClass = com.jogamp.nativewindow.NativeWindow.class;
444 defaultFactory = factory;
446 if ( isAWTAvailable ) {
448 registerFactory(ReflectionUtil.getClass(ReflectionUtil.AWTNames.ComponentClass,
false, cl), factory);
452 System.err.println(
"NativeWindowFactory requiresToolkitLock "+requiresToolkitLock+
", desktopHasThreadingIssues "+desktopHasThreadingIssues);
453 System.err.println(
"NativeWindowFactory isAWTAvailable "+isAWTAvailable+
", defaultFactory "+factory);
462 return requiresToolkitLock;
474 return useCustom?nativeWindowingTypeCustom:nativeWindowingTypeNative;
494 defaultFactory = factory;
499 return defaultFactory;
510 return jawtUtilJAWTToolkitLock;
514 return NativeWindowFactoryImpl.getNullToolkitLock();
535 if( requiresToolkitLock ) {
536 if(
TYPE_AWT == type && isAWTAvailable() ) {
539 return ResourceToolkitLock.create();
541 return NativeWindowFactoryImpl.getNullToolkitLock();
550 final String type = device.
getType();
556 return new com.jogamp.nativewindow.x11.X11GraphicsScreen(x11Device, screen);
563 return new com.jogamp.nativewindow.awt.AWTGraphicsScreen(awtDevice);
575 if (nativeWindowClass.isAssignableFrom(windowClass)) {
576 return registeredFactories.get(nativeWindowClass);
578 Class<?> clazz = windowClass;
579 while (clazz !=
null) {
581 if (factory !=
null) {
584 clazz = clazz.getSuperclass();
586 throw new IllegalArgumentException(
"No registered NativeWindowFactory for class " + windowClass.getName());
594 System.err.println(
"NativeWindowFactory.registerFactory() "+windowClass+
" -> "+factory);
596 registeredFactories.put(windowClass, factory);
619 if (winObj ==
null) {
620 throw new IllegalArgumentException(
"Null window object");
648 return ( !ifEnabled || ((
OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols :
null;
656 return ( !ifEnabled || ((
OffscreenLayerOption)ols).isOffscreenLayerSurfaceEnabled() ) ? ols :
null;
680 VisualIDHolder.VID_UNDEFINED != visualID ;
688 return jogamp.nativewindow.x11.X11Util.getNullDisplayName();
729 return new com.jogamp.nativewindow.x11.X11GraphicsDevice(displayConnection, unitID,
null );
731 return new com.jogamp.nativewindow.x11.X11GraphicsDevice(displayConnection, unitID);
734 return new com.jogamp.nativewindow.windows.WindowsGraphicsDevice(unitID);
736 return new com.jogamp.nativewindow.macosx.MacOSXGraphicsDevice(unitID);
738 return new com.jogamp.nativewindow.ios.IOSGraphicsDevice(unitID);
745 odev = ReflectionUtil.callStaticMethod(
"jogamp.opengl.egl.EGLDisplayUtil",
"eglCreateEGLGraphicsDevice",
746 new Class<?>[] { Long.class, String.class, Integer.class},
749 }
catch (
final Exception e) {
752 if( odev instanceof com.jogamp.nativewindow.egl.EGLGraphicsDevice ) {
753 device = (com.jogamp.nativewindow.egl.EGLGraphicsDevice)odev;
759 device =
new com.jogamp.nativewindow.egl.EGLGraphicsDevice(0 , displayConnection, unitID);
763 throw new UnsupportedOperationException(
"n/a for windowing system: "+nwt);
786 return new WrappedWindow(config, surfaceHandle, hook,
true, windowHandle);
801 return jogamp.nativewindow.windows.GDIUtil.GetRelativeLocation(nw.
getWindowHandle(), 0, 0, 0);
803 return jogamp.nativewindow.macosx.OSXUtil.GetLocationOnScreen(nw.
getWindowHandle(), 0, 0);
805 return jogamp.nativewindow.ios.IOSUtil.GetLocationOnScreen(nw.
getWindowHandle(), 0, 0);
815 throw new UnsupportedOperationException(
"n/a for windowing system: "+nwt);
Specifies a set of capabilities that a window's rendering context must support, such as color depth p...
static String getDefaultDisplayConnection()
Return the default display connection for the given windowing toolkit type gathered via NativeWindowF...
Provides the mechanism by which the graphics configuration for a window can be chosen before the wind...
static synchronized void shutdown()
static synchronized void initSingleton()
A generic exception for OpenGL errors used throughout the binding as a substitute for RuntimeExceptio...
Provides a pluggable mechanism for arbitrary window toolkits to adapt their components to the NativeW...
static final String TYPE_EGL
OpenKODE/EGL type, as retrieved with getNativeWindowType(boolean).
static final String TYPE_WINDOWS
Microsoft Windows type, as retrieved with getNativeWindowType(boolean).
static AbstractGraphicsDevice createDevice(final String nwt, final String displayConnection, final int unitID, final boolean own)
Creates a native device type, following the given native-window-type.
static AbstractGraphicsDevice createDevice(final String nwt, final String displayConnection, final boolean own)
Creates a native device type, following the given native-window-type.
static final String TYPE_DEFAULT
Generic DEFAULT type, where platform implementation don't care, as retrieved with getNativeWindowType...
static ToolkitLock getDefaultToolkitLock()
Provides the system default ToolkitLock for the default system windowing type.
static final String TYPE_DRM_GBM
DRM/GBM type, as retrieved with getNativeWindowType(boolean).
static ToolkitLock getDefaultToolkitLock(final String type)
Provides the default ToolkitLock for type.
static final String TYPE_WAYLAND
Wayland/EGL type, as retrieved with getNativeWindowType(boolean).
static void registerFactory(final Class<?> windowClass, final NativeWindowFactory factory)
Registers a NativeWindowFactory handling window objects of the given class.
static boolean isNativeVisualIDValidForProcessing(final int visualID)
Returns true if the given visualID is valid for further processing, i.e.
static final String TYPE_X11
X11 type, as retrieved with getNativeWindowType(boolean).
static final String TYPE_IOS
iOS type, as retrieved with getNativeWindowType(boolean).
static final String TYPE_MACOSX
Mac OS X type, as retrieved with getNativeWindowType(boolean).
static final boolean isJVMShuttingDown()
Returns true if the JVM is shutting down, otherwise false.
static final String TYPE_BCM_VC_IV
Broadcom VC IV/EGL type, as retrieved with getNativeWindowType(boolean).
static NativeWindowFactory getFactory(final Class<?> windowClass)
Returns the appropriate NativeWindowFactory to handle window objects of the given type.
static String getDefaultDisplayConnection()
static final String TYPE_AWT
Generic AWT type, as retrieved with getNativeWindowType(boolean).
static ToolkitLock getAWTToolkitLock()
Returns the AWT ToolkitLock (JAWT based) if isAWTAvailable, otherwise null.
static boolean requiresToolkitLock()
static synchronized void initSingleton()
Static one time initialization of this factory.
static Point getLocationOnScreen(final NativeWindow nw)
static AbstractGraphicsDevice createDevice(final String displayConnection, final boolean own)
Creates a native device type, following getNativeWindowType(true).
static boolean isAWTAvailable()
NativeWindowFactory()
Creates a new NativeWindowFactory instance.
static OffscreenLayerSurface getOffscreenLayerSurface(final NativeSurface surface, final boolean ifEnabled)
Returns the OffscreenLayerSurface instance of this NativeSurface.
static NativeWindow createWrappedWindow(final AbstractGraphicsScreen aScreen, final long surfaceHandle, final long windowHandle, final UpstreamWindowHookMutableSizePos hook)
Creates a wrapped NativeWindow with given native handles and AbstractGraphicsScreen.
static String getNativeWindowType(final boolean useCustom)
static String getDefaultDisplayConnection(final String nwt)
static synchronized void shutdown(final boolean _isJVMShuttingDown)
Cleanup resources at JVM shutdown.
static NativeWindowFactory getDefaultFactory()
Gets the default NativeWindowFactory.
static AbstractGraphicsScreen createScreen(final AbstractGraphicsDevice device, int screen)
static final String TYPE_ANDROID
Android/EGL type, as retrieved with getNativeWindowType(boolean).
static final boolean DEBUG
static NativeWindow getNativeWindow(final Object winObj, final AbstractGraphicsConfiguration config)
Converts the given window object and it's AbstractGraphicsConfiguration into a NativeWindow which can...
static void addCustomShutdownHook(final boolean head, final Runnable runnable)
Add a custom shutdown hook to be performed at JVM shutdown before shutting down NativeWindowFactory i...
abstract NativeWindow getNativeWindowImpl(Object winObj, AbstractGraphicsConfiguration config)
Performs the conversion from a toolkit's window object to a NativeWindow.
static void setDefaultFactory(final NativeWindowFactory factory)
Don't know if we shall add this factory here .
static synchronized boolean isInitialized()
Returns true if initSingleton() has been called w/o subsequent shutdown(boolean).
static ToolkitLock getNullToolkitLock()
A wrapper for an AWT GraphicsDevice allowing it to be handled in a toolkit-independent manner.
Encapsulates a graphics device on EGL platforms.
boolean open()
Opens the EGL device if handle is null and it's EGLDisplayLifecycleCallback is valid.
Encapsulates a graphics device on X11 platforms.
int getDefaultScreen()
Returns the default screen number as referenced by the display connection, i.e.
A marker interface describing a graphics configuration, visual, or pixel format in a toolkit-independ...
A interface describing a graphics device in a toolkit-independent manner.
String getType()
Returns the type of the underlying subsystem, ie NativeWindowFactory.TYPE_KD, NativeWindowFactory....
static int DEFAULT_UNIT
Default unit id for the 1st device: 0.
static String DEFAULT_CONNECTION
Dummy connection value for a default connection where no native support for multiple devices is avail...
A interface describing a graphics screen in a toolkit-independent manner.
Specifies an immutable set of capabilities that a window's rendering context must support,...
Provides low-level information required for hardware-accelerated rendering using a surface in a platf...
long getDisplayHandle()
Convenience: Get display handle from AbstractGraphicsConfiguration .
int getScreenIndex()
Convenience: Get display handle from AbstractGraphicsConfiguration .
Extend the NativeSurface interface with windowing information such as window-handle,...
long getWindowHandle()
Returns the window handle for this NativeWindow.
Handling requests for using an OffscreenLayerSurface within the implementation.
Interface specifying the offscreen layer surface protocol.