Jogamp
NewtVersionActivity: Remove 'gears' test; Version Info: Drop NativeWindow/Newt Versio...
[jogl.git] / src / jogl / classes / javax / media / opengl / awt / GLCanvas.java
index 1329977..d861bd7 100644 (file)
 
 package javax.media.opengl.awt;
 
-import com.jogamp.common.GlueGenVersion;
-import com.jogamp.common.util.VersionUtil;
-import com.jogamp.common.util.locks.RecursiveLock;
-import com.jogamp.nativewindow.NativeWindowVersion;
-import javax.media.opengl.*;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.awt.*;
-
-import com.jogamp.opengl.impl.*;
-import com.jogamp.opengl.JoglVersion;
+import java.beans.Beans;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
 import java.awt.Canvas;
 import java.awt.Color;
-import java.awt.Component;
 import java.awt.FontMetrics;
 import java.awt.Frame;
 import java.awt.Graphics;
 import java.awt.GraphicsConfiguration;
 import java.awt.GraphicsDevice;
-import java.awt.Window;
-import java.awt.event.WindowEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.geom.*;
-import java.beans.*;
-import java.lang.reflect.*;
-import java.security.*;
+import java.awt.geom.Rectangle2D;
+
+import java.awt.EventQueue;
+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.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
+import javax.media.nativewindow.awt.AWTGraphicsDevice;
+import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAnimatorControl;
+import javax.media.opengl.GLAutoDrawable;
+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.GLEventListener;
+import javax.media.opengl.GLException;
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.GLRunnable;
+import javax.media.opengl.Threading;
+
+import com.jogamp.nativewindow.NativeWindowVersion;
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.opengl.JoglVersion;
+
+import com.jogamp.common.util.locks.RecursiveLock;
+import jogamp.opengl.Debug;
+import jogamp.opengl.GLContextImpl;
+import jogamp.opengl.GLDrawableHelper;
+import jogamp.opengl.ThreadingImpl;
 
 // FIXME: Subclasses need to call resetGLFunctionAvailability() on their
 // context whenever the displayChanged() function is called on our
@@ -105,14 +135,12 @@ import java.security.*;
  * </ul>
  */
 
-public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
+public class GLCanvas extends Canvas implements AWTGLAutoDrawable, WindowClosingProtocol {
 
   private static final boolean DEBUG;
-  private static final GLProfile defaultGLProfile;
 
   static {
       DEBUG = Debug.debug("GLCanvas");
-      defaultGLProfile = GLProfile.getDefault(GLProfile.getDefaultDesktopDevice());
   }
 
   private GLDrawableHelper drawableHelper = new GLDrawableHelper();
@@ -124,22 +152,33 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
   // copy of the cstr args, mainly for recreation
   private GLCapabilitiesImmutable capsReqUser;
   private GLCapabilitiesChooser chooser;
-  private GLContext shareWith;  
+  private GLContext shareWith;
+  private int additionalCtxCreationFlags = 0;  
   private GraphicsDevice device;
 
+  private AWTWindowClosingProtocol awtWindowClosingProtocol =
+          new AWTWindowClosingProtocol(this, new Runnable() {
+                public void run() {
+                    GLCanvas.this.destroy();
+                }
+            });
+
   /** Creates a new GLCanvas component with a default set of OpenGL
       capabilities, using the default OpenGL capabilities selection
-      mechanism, on the default screen device. */
-  public GLCanvas() {
+      mechanism, on the default screen device. 
+   * @throws GLException if no default profile is available for the default desktop device.
+   */
+  public GLCanvas() throws GLException {
     this(null);
   }
 
   /** Creates a new GLCanvas component with the requested set of
       OpenGL capabilities, using the default OpenGL capabilities
       selection mechanism, on the default screen device. 
+   * @throws GLException if no GLCapabilities are given and no default profile is available for the default desktop device.
    * @see GLCanvas#GLCanvas(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, javax.media.opengl.GLContext, java.awt.GraphicsDevice)
    */
-  public GLCanvas(GLCapabilitiesImmutable capsReqUser) {
+  public GLCanvas(GLCapabilitiesImmutable capsReqUser) throws GLException {
     this(capsReqUser, null, null, null);
   }
 
@@ -148,9 +187,12 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
       selection mechanism, on the default screen device.
    *  This constructor variant also supports using a shared GLContext.
    *
+   * @throws GLException if no GLCapabilities are given and no default profile is available for the default desktop device.
    * @see GLCanvas#GLCanvas(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, javax.media.opengl.GLContext, java.awt.GraphicsDevice)
    */
-  public GLCanvas(GLCapabilitiesImmutable capsReqUser, GLContext shareWith) {
+  public GLCanvas(GLCapabilitiesImmutable capsReqUser, GLContext shareWith) 
+          throws GLException 
+  {
     this(capsReqUser, null, shareWith, null);
   }
 
@@ -168,11 +210,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
       sharing</a>. The passed GraphicsDevice indicates the screen on
       which to create the GLCanvas; the GLDrawableFactory uses the
       default screen device of the local GraphicsEnvironment if null
-      is passed for this argument. */
+      is passed for this argument. 
+   * @throws GLException if no GLCapabilities are given and no default profile is available for the default desktop device.
+   */
   public GLCanvas(GLCapabilitiesImmutable capsReqUser,
                   GLCapabilitiesChooser chooser,
                   GLContext shareWith,
-                  GraphicsDevice device) {
+                  GraphicsDevice device) 
+      throws GLException 
+  {
     /*
      * Determination of the native window is made in 'super.addNotify()',
      * which creates the native peer using AWT's GraphicsConfiguration.
@@ -183,7 +229,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
     super();
 
     if(null==capsReqUser) {
-        capsReqUser = new GLCapabilities(defaultGLProfile);
+        capsReqUser = new GLCapabilities(GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()));
     } else {
         // don't allow the user to change data
         capsReqUser = (GLCapabilitiesImmutable) capsReqUser.cloneMutable();
@@ -203,37 +249,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
     this.device = device;
   }
 
-  protected interface DestroyMethod {
-    public void destroyMethod();
-  }
-
-  /* package private */ final static Object addClosingListener(Component c, final DestroyMethod d) {
-    WindowAdapter cl = null;
-    Window w = getWindow(c);
-    if(null!=w) {
-        cl = new WindowAdapter() {
-                public void windowClosing(WindowEvent e) {
-                  // we have to issue this call rigth away,
-                  // otherwise the window gets destroyed
-                  d.destroyMethod();
-                }
-            };
-        w.addWindowListener(cl);
-    }
-    return cl;
-  }
-
-  private final static Window getWindow(Component c) {
-    while ( c!=null && ! ( c instanceof Window ) ) {
-        c = c.getParent();
-    }
-    return (Window)c;
-  }
-
   /**
    * Overridden to choose a GraphicsConfiguration on a parent container's
    * GraphicsDevice because both devices
    */
+    @Override
   public GraphicsConfiguration getGraphicsConfiguration() {
     /*
      * Workaround for problems with Xinerama and java.awt.Component.checkGD
@@ -341,40 +361,53 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
   }
   
   public GLContext createContext(GLContext shareWith) {
-    return drawable.createContext(shareWith);
+      drawableSync.lock();
+      try {
+        return (null != drawable) ? drawable.createContext(shareWith) : null;
+      } finally {
+        drawableSync.unlock();
+      }
   }
 
   public void setRealized(boolean realized) {
   }
 
   public boolean isRealized() {
-    return ( null != drawable ) ? drawable.isRealized() : false;
+      drawableSync.lock();
+      try {
+        return ( null != drawable ) ? drawable.isRealized() : false;
+      } finally {
+        drawableSync.unlock();
+      }
+  }
+
+  public int getDefaultCloseOperation() {
+      return awtWindowClosingProtocol.getDefaultCloseOperation();
   }
 
-  private Object closingListener = null;
-  private Object closingListenerLock = new Object();
+  public int setDefaultCloseOperation(int op) {
+      return awtWindowClosingProtocol.setDefaultCloseOperation(op);
+  }
 
   public void display() {
     if( !validateGLDrawable() ) {
+        if(DEBUG) {
+            System.err.println("Info: GLCanvas display - skipped GL render, drawable not valid yet");
+        }
         return; // not yet available ..
     }
     maybeDoSingleThreadedWorkaround(displayOnEventDispatchThreadAction,
                                     displayAction);
-    if(null==closingListener) {
-      synchronized(closingListenerLock) {
-        if(null==closingListener) {
-            closingListener=addClosingListener(this, new DestroyMethod() { 
-                        public void destroyMethod() { destroy(); } });
-        }
-      }
-    }
+
+    awtWindowClosingProtocol.addClosingListenerOneShot();
   }
 
   private void dispose(boolean regenerate) {
     drawableSync.lock();
     try {
         if(DEBUG) {
-            Exception ex1 = new Exception("Info: dispose("+regenerate+") - start");
+            Exception ex1 = new Exception("Info: dispose("+regenerate+") - start, hasContext " +
+                    (null!=context) + ", hasDrawable " + (null!=drawable));
             ex1.printStackTrace();
         }
 
@@ -414,7 +447,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
             }
         }
         if(!regenerate) {
-            disposeAbstractGraphicsDeviceAction.run();
+            disposeAbstractGraphicsDevice();
         }
 
         if(DEBUG) {
@@ -439,6 +472,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
 
       <B>Overrides:</B>
       <DL><DD><CODE>paint</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+    @Override
   public void paint(Graphics g) {
     if (Beans.isDesignTime()) {
       // Make GLCanvas behave better in NetBeans GUI builder
@@ -474,6 +508,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
 
       <B>Overrides:</B>
       <DL><DD><CODE>addNotify</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+    @Override
   public void addNotify() {
     if(DEBUG) {
         Exception ex1 = new Exception(Thread.currentThread().getName()+" - Info: addNotify - start, bounds: "+this.getBounds());
@@ -501,6 +536,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
                            .createGLDrawable(NativeWindowFactory.getNativeWindow(this, awtConfig));
             context = (GLContextImpl) drawable.createContext(shareWith);
             context.setSynchronized(true);
+            context.setContextCreationFlags(additionalCtxCreationFlags);            
         }
 
         // before native peer is valid: X11
@@ -558,12 +594,15 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
       about this.</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(Thread.currentThread().getName()+" - Info: removeNotify - start");
         ex1.printStackTrace();
     }
 
+    awtWindowClosingProtocol.removeClosingListener();
+
     if (Beans.isDesignTime()) {
       super.removeNotify();
     } else {
@@ -571,6 +610,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
       try {
         dispose(false);
       } finally {
+        context=null;
         drawable=null;
         awtConfig=null;
         super.removeNotify();
@@ -589,6 +629,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
 
       <B>Overrides:</B>
       <DL><DD><CODE>reshape</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
+    @Override
   public void reshape(int x, int y, int width, int height) {
     super.reshape(x, y, width, height);
     sendReshape = true;
@@ -596,8 +637,11 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
 
   /** <B>Overrides:</B>
       <DL><DD><CODE>update</CODE> in class <CODE>java.awt.Component</CODE></DD></DL> */
-  // Overridden from Canvas to prevent the AWT's clearing of the
-  // canvas from interfering with the OpenGL rendering.
+  /** 
+   * Overridden from Canvas to prevent the AWT's clearing of the
+   * canvas from interfering with the OpenGL rendering.
+   */
+    @Override
   public void update(Graphics g) {
     paint(g);
   }
@@ -628,6 +672,9 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
 
   public void setContext(GLContext ctx) {
     context=(GLContextImpl)ctx;
+    if(null != context) {
+        context.setContextCreationFlags(additionalCtxCreationFlags);
+    }
   }
 
   public GLContext getContext() {
@@ -638,14 +685,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
     if (Beans.isDesignTime()) {
       return null;
     }
-    GLContext context = getContext();
-    return (context == null) ? null : context.getGL();
+    GLContext ctx = getContext();
+    return (ctx == null) ? null : ctx.getGL();
   }
 
   public GL setGL(GL gl) {
-    GLContext context = getContext();
-    if (context != null) {
-      context.setGL(gl);
+    GLContext ctx = getContext();
+    if (ctx != null) {
+      ctx.setGL(gl);
       return gl;
     }
     return null;
@@ -664,6 +711,14 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
     maybeDoSingleThreadedWorkaround(swapBuffersOnEventDispatchThreadAction, swapBuffersAction);
   }
 
+  public void setContextCreationFlags(int flags) {
+    additionalCtxCreationFlags = flags;
+  }
+      
+  public int getContextCreationFlags() {
+    return additionalCtxCreationFlags;                
+  }
+          
   public GLProfile getGLProfile() {
     return capsReqUser.getGLProfile();
   }
@@ -678,28 +733,55 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
 
   public GLCapabilitiesImmutable getRequestedGLCapabilities() {
     if (awtConfig == null) {
-        throw new GLException("No AWTGraphicsConfiguration: "+this);
+        return capsReqUser;
     }
 
     return (GLCapabilitiesImmutable)awtConfig.getRequestedCapabilities();
   }
 
   public NativeSurface getNativeSurface() {
-    return drawable.getNativeSurface();
+      drawableSync.lock();
+      try {
+        return (null != drawable) ? drawable.getNativeSurface() : null;
+      } finally {
+        drawableSync.unlock();
+      }
   }
 
   public long getHandle() {
-    return drawable.getHandle();
+      drawableSync.lock();
+      try {
+        return (null != drawable) ? drawable.getHandle() : 0;
+      } finally {
+        drawableSync.unlock();
+      }
   }
 
   public GLDrawableFactory getFactory() {
-    return drawable.getFactory();
+      drawableSync.lock();
+      try {
+        return (null != drawable) ? drawable.getFactory() : null;
+      } finally {
+        drawableSync.unlock();
+      }
   }
 
+  @Override
   public String toString() {
-    return "AWT-GLCanvas[ "+awtConfig+", "+((null!=drawable)?drawable.getClass().getName():"null-drawable")+"]";
+    final int dw = (null!=drawable) ? drawable.getWidth() : -1;
+    final int dh = (null!=drawable) ? drawable.getHeight() : -1;
+    
+    return "AWT-GLCanvas[Realized "+isRealized()+
+                          ",\n\t"+((null!=drawable)?drawable.getClass().getName():"null-drawable")+                         
+                          ",\n\tRealized "+isRealized()+
+                          ",\n\tFactory   "+getFactory()+
+                          ",\n\thandle    0x"+Long.toHexString(getHandle())+
+                          ",\n\tDrawable size "+dw+"x"+dh+
+                          ",\n\tAWT pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
+                          ",\n\tvisible "+isVisible()+
+                          ",\n\t"+awtConfig+"]";
   }
-
+  
   //----------------------------------------------------------------------
   // Internals only below this point
   //
@@ -726,6 +808,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
 
       if(null!=drawable) {
           drawable.setRealized(false);
+          drawable=null;
       }
 
       if(disposeRegenerate) {
@@ -766,13 +849,34 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
           }
           boolean closed = adevice.close();
           if(DEBUG) {
-            System.err.println("GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+            System.err.println(Thread.currentThread().getName() + " - GLCanvas.dispose(false): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
           }
       }
+      awtConfig=null;
     }
   }
   private DisposeAbstractGraphicsDeviceAction disposeAbstractGraphicsDeviceAction = new DisposeAbstractGraphicsDeviceAction();
 
+  /**
+   * Disposes the AbstractGraphicsDevice within EDT,
+   * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+   *
+   * @see #chooseGraphicsConfiguration(javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesImmutable, javax.media.opengl.GLCapabilitiesChooser, java.awt.GraphicsDevice)
+   */
+  void disposeAbstractGraphicsDevice()  {
+    if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
+        disposeAbstractGraphicsDeviceAction.run();
+    } else {
+        try {
+            EventQueue.invokeAndWait(disposeAbstractGraphicsDeviceAction);
+        } catch (InvocationTargetException e) {
+            throw new GLException(e.getTargetException());
+        } catch (InterruptedException e) {
+            throw new GLException(e);
+        }
+    }
+  }
+
   class InitAction implements Runnable {
     public void run() {
       drawableHelper.init(GLCanvas.this);
@@ -864,8 +968,6 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
       try {
         disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this });
       } catch (Exception e) {
-        // FIXME: workaround for 6504460 (incorrect backport of 6333613 in 5.0u10)
-        // throw new GLException(e);
         t = e;
       }
       if(DEBUG) {
@@ -874,20 +976,55 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
     }
   }
 
-  private static AWTGraphicsConfiguration chooseGraphicsConfiguration(GLCapabilitiesImmutable capsChosen,
-                                                                      GLCapabilitiesImmutable capsRequested,
-                                                                      GLCapabilitiesChooser chooser,
-                                                                      GraphicsDevice device) {
+  /**
+   * Issues the GraphicsConfigurationFactory's choosing facility within EDT,
+   * since resources created (X11: Display), must be destroyed in the same thread, where they have been created.
+   *
+   * @param capsChosen
+   * @param capsRequested
+   * @param chooser
+   * @param device
+   * @return the chosen AWTGraphicsConfiguration
+   *
+   * @see #disposeAbstractGraphicsDevice()
+   */
+  private AWTGraphicsConfiguration chooseGraphicsConfiguration(final GLCapabilitiesImmutable capsChosen,
+                                                               final GLCapabilitiesImmutable capsRequested,
+                                                               final GLCapabilitiesChooser chooser,
+                                                               final GraphicsDevice device) {
     // Make GLCanvas behave better in NetBeans GUI builder
     if (Beans.isDesignTime()) {
       return null;
     }
 
-    AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
-    AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
-          GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
-                                                                                                       capsRequested,
-                                                                                                       chooser, aScreen);
+    final AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+    AWTGraphicsConfiguration config = null;
+
+    if( EventQueue.isDispatchThread() || Thread.holdsLock(getTreeLock()) ) {
+        config = (AWTGraphicsConfiguration)
+                GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+                                                                                                             capsRequested,
+                                                                                                             chooser, aScreen);
+    } else {
+        try {
+            final ArrayList bucket = new ArrayList(1);
+            EventQueue.invokeAndWait(new Runnable() {
+                public void run() {
+                    AWTGraphicsConfiguration c = (AWTGraphicsConfiguration)
+                            GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+                                                                                                                         capsRequested,
+                                                                                                                         chooser, aScreen);
+                    bucket.add(c);
+                }
+            });
+            config = ( bucket.size() > 0 ) ? (AWTGraphicsConfiguration)bucket.get(0) : null ;
+        } catch (InvocationTargetException e) {
+            throw new GLException(e.getTargetException());
+        } catch (InterruptedException e) {
+            throw new GLException(e);
+        }
+    }
+
     if (config == null) {
       throw new GLException("Error: Couldn't fetch AWTGraphicsConfiguration");
     }
@@ -901,9 +1038,16 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
   public static void main(String args[]) {
     System.err.println(VersionUtil.getPlatformInfo());
     System.err.println(GlueGenVersion.getInstance());
-    System.err.println(NativeWindowVersion.getInstance());
+    // 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++) {
+        System.err.println(availCaps.get(i));
+    }
+
     GLCapabilitiesImmutable caps = new GLCapabilities( GLProfile.getDefault(GLProfile.getDefaultDesktopDevice()) );
     Frame frame = new Frame("JOGL AWT Test");
 
@@ -914,7 +1058,7 @@ public class GLCanvas extends Canvas implements AWTGLAutoDrawable {
     glCanvas.addGLEventListener(new GLEventListener() {
         public void init(GLAutoDrawable drawable) {
             GL gl = drawable.getGL();
-            System.err.println(JoglVersion.getInstance().getGLInfo(gl, null));
+            System.err.println(JoglVersion.getGLInfo(gl, null));
         }
 
         public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
http://JogAmp.org git info: FAQ, tutorial and man pages.