Jogamp
Add unified support for GL_ARB_debug_output and GL_AMD_debug_output.
[jogl.git] / src / newt / classes / com / jogamp / newt / opengl / GLWindow.java
1 /*
2  * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
3  * Copyright (c) 2010 JogAmp Community. All rights reserved.
4  * 
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  * 
9  * - Redistribution of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  * 
12  * - Redistribution in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  * 
16  * Neither the name of Sun Microsystems, Inc. or the names of
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  * 
20  * This software is provided "AS IS," without a warranty of any kind. ALL
21  * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22  * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23  * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24  * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27  * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28  * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29  * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30  * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31  * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
32  * 
33  */
34
35 package com.jogamp.newt.opengl;
36
37 import java.io.PrintStream;
38 import java.util.List;
39
40 import com.jogamp.common.GlueGenVersion;
41 import com.jogamp.common.util.VersionUtil;
42 import com.jogamp.nativewindow.NativeWindowVersion;
43 import com.jogamp.newt.*;
44 import com.jogamp.newt.event.*;
45 import jogamp.newt.WindowImpl;
46
47 import javax.media.nativewindow.*;
48 import javax.media.nativewindow.util.Point;
49 import javax.media.nativewindow.util.Insets;
50 import javax.media.opengl.*;
51
52 import jogamp.opengl.FPSCounterImpl;
53 import jogamp.opengl.GLDrawableHelper;
54 import com.jogamp.opengl.JoglVersion;
55
56 /**
57  * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
58  * using an aggregation of a {@link com.jogamp.newt.Window} implementation.
59  * <P>
60  * This implementation does not make the OpenGL context current<br>
61  * before calling the various input EventListener callbacks, ie {@link com.jogamp.newt.event.MouseListener} etc.<br>
62  * This design decision is made in favor of a more performant and simplified
63  * implementation. Also the event dispatcher shall be implemented OpenGL agnostic.<br>
64  * To be able to use OpenGL commands from within such input {@link com.jogamp.newt.event.NEWTEventListener},<br>
65  * you can inject {@link javax.media.opengl.GLRunnable} objects
66  * via {@link #invoke(boolean, javax.media.opengl.GLRunnable)} to the OpenGL command stream.<br>
67  * <p>
68  */
69 public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter {
70     private WindowImpl window;
71
72     /**
73      * Constructor. Do not call this directly -- use {@link #create()} instead.
74      */
75     protected GLWindow(Window window) {
76         resetFPSCounter();
77         this.window = (WindowImpl) window;
78         ((WindowImpl)this.window).setHandleDestroyNotify(false);
79         window.addWindowListener(new WindowAdapter() {
80                 @Override
81                 public void windowRepaint(WindowUpdateEvent e) {
82                     if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
83                         display();
84                     }
85                 }
86
87                 @Override
88                 public void windowResized(WindowEvent e) {
89                     sendReshape = true;
90                     if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
91                         display();
92                     }
93                 }
94
95                 @Override
96                 public void windowDestroyNotify(WindowEvent e) {
97                     if( DISPOSE_ON_CLOSE == GLWindow.this.getDefaultCloseOperation() ) {
98                         // Is an animator thread perform rendering?
99                         if (GLWindow.this.helper.isExternalAnimatorRunning()) {
100                             // Pause animations before initiating safe destroy.
101                             GLAnimatorControl ctrl = GLWindow.this.helper.getAnimator();
102                             boolean isPaused = ctrl.pause();
103                             destroy();
104                             if(isPaused) {
105                                 ctrl.resume();
106                             }
107                         } else if (GLWindow.this.window.isWindowLockedByOtherThread()) {
108                             // Window is locked by another thread
109                             // Flag that destroy should be performed on the next
110                             // attempt to display.
111                             sendDestroy = true;
112                         } else {
113                             // Without an external thread animating or locking the
114                             // surface, we are safe.
115                             destroy ();
116                         }
117                     }
118                 }
119             });
120         this.window.setLifecycleHook(new GLLifecycleHook());
121     }
122
123     /**
124      * Creates a new GLWindow attaching a new Window referencing a new Screen
125      * with the given GLCapabilities.
126      * <P>
127      * The resulting GLWindow owns the Window, Screen and Device, ie it will be destructed.
128      */
129     public static GLWindow create(GLCapabilitiesImmutable caps) {
130         return new GLWindow(NewtFactory.createWindow(caps));
131     }
132
133     /**
134      * Creates a new GLWindow attaching a new Window referencing the given Screen
135      * with the given GLCapabilities.
136      * <P>
137      * The resulting GLWindow owns the Window, ie it will be destructed.
138      */
139     public static GLWindow create(Screen screen, GLCapabilitiesImmutable caps) {
140         return new GLWindow(NewtFactory.createWindow(screen, caps));
141     }
142
143     /** 
144      * Creates a new GLWindow attaching the given window.
145      * <P>
146      * The resulting GLWindow does not own the given Window, ie it will not be destructed. 
147      */
148     public static GLWindow create(Window window) {
149         return new GLWindow(window);
150     }
151
152     /** 
153      * Creates a new GLWindow attaching a new child Window 
154      * of the given <code>parentNativeWindow</code> with the given GLCapabilities.
155      * <P>
156      * The Display/Screen will be compatible with the <code>parentNativeWindow</code>,
157      * or even identical in case it's a Newt Window.
158      * <P>
159      * The resulting GLWindow owns the Window, ie it will be destructed. 
160      */
161     public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilitiesImmutable caps) {
162         return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps));
163     }
164
165     //----------------------------------------------------------------------
166     // WindowClosingProtocol implementation
167     //
168     public int getDefaultCloseOperation() {
169         return window.getDefaultCloseOperation();
170     }
171
172     public int setDefaultCloseOperation(int op) {
173         return window.setDefaultCloseOperation(op);
174     }
175
176     //----------------------------------------------------------------------
177     // Window Access
178     //
179
180     public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
181         return window.setCapabilitiesChooser(chooser);
182     }
183
184     public final CapabilitiesImmutable getChosenCapabilities() {
185         if (drawable == null) {
186             return window.getChosenCapabilities();
187         }
188
189         return drawable.getChosenGLCapabilities();
190     }
191
192     public final CapabilitiesImmutable getRequestedCapabilities() {
193         return window.getRequestedCapabilities();
194     }
195
196     public final Window getWindow() {
197         return window;
198     }
199
200     public final NativeWindow getParent() {
201         return window.getParent();
202     }
203
204     public final Screen getScreen() {
205         return window.getScreen();
206     }
207
208     public final void setTitle(String title) {
209         window.setTitle(title);
210     }
211
212     public final String getTitle() {
213         return window.getTitle();
214     }
215
216     public final void setUndecorated(boolean value) {
217         window.setUndecorated(value);
218     }
219
220     public final boolean isUndecorated() {
221         return window.isUndecorated();
222     }
223
224     public final void setFocusAction(FocusRunnable focusAction) {
225         window.setFocusAction(focusAction);
226     }
227     
228     public final void requestFocus() {
229         window.requestFocus();
230     }
231
232     public boolean hasFocus() {
233         return window.hasFocus();
234     }
235
236     public final Insets getInsets() {
237         return window.getInsets();
238     }
239
240     public final void setPosition(int x, int y) {
241         window.setPosition(x, y);
242     }
243
244     public final boolean setFullscreen(boolean fullscreen) {
245         return window.setFullscreen(fullscreen);
246     }
247
248     public final boolean isFullscreen() {
249         return window.isFullscreen();
250     }
251
252     public final boolean isVisible() {
253         return window.isVisible();
254     }
255
256     @Override
257     public final String toString() {
258         return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable + 
259                ", \n\tContext: " + context + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
260     }
261
262     public final int reparentWindow(NativeWindow newParent) {
263         return window.reparentWindow(newParent);
264     }
265
266     public final int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
267         return window.reparentWindow(newParent, forceDestroyCreate);
268     }
269
270     public final void removeChild(NativeWindow win) {
271         window.removeChild(win);
272     }
273
274     public final void addChild(NativeWindow win) {
275         window.addChild(win);
276     }
277     
278     //----------------------------------------------------------------------
279     // Window.LifecycleHook Implementation
280     //
281
282     public final void destroy() {
283         window.destroy();
284     }
285
286     public final void setVisible(boolean visible) {
287         window.setVisible(visible);
288     }
289
290     public final void setSize(int width, int height) {
291         window.setSize(width, height);
292     }
293
294     public final boolean isValid() {
295         return window.isValid();
296     }
297
298     public final boolean isNativeValid() {
299         return window.isNativeValid();
300     }
301
302     public Point getLocationOnScreen(Point storage) {
303         return window.getLocationOnScreen(storage);
304     }
305
306     // Hide methods here ..
307     protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
308
309         private class DisposeAction implements Runnable {
310             public final void run() {
311                 // Lock: Covered by DestroyAction ..
312                 helper.dispose(GLWindow.this);
313             }
314         }
315         DisposeAction disposeAction = new DisposeAction();
316
317         public synchronized void destroyActionPreLock() {
318             // nop
319         }
320
321         public synchronized void destroyActionInLock() {
322             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
323                 String msg = "GLWindow.destroy() "+Thread.currentThread()+", start";
324                 System.err.println(msg);
325                 //Exception e1 = new Exception(msg);
326                 //e1.printStackTrace();
327             }
328
329             if( window.isNativeValid() && null != drawable && drawable.isRealized() ) {
330                 if( null != context && context.isCreated() ) {
331                     // Catch dispose GLExceptions by GLEventListener, just 'print' them
332                     // so we can continue with the destruction.
333                     try {
334                         helper.invokeGL(drawable, context, disposeAction, null);
335                     } catch (GLException gle) {
336                         gle.printStackTrace();
337                     }
338                     context.destroy();
339                 }
340                 drawable.setRealized(false);
341             }
342             context = null;
343             drawable = null;
344
345             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
346                 System.err.println("GLWindow.destroy() "+Thread.currentThread()+", fin");
347             }
348         }
349
350         public synchronized void invalidate(boolean unrecoverable) {
351             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
352                 String msg = "GLWindow.invalidate("+unrecoverable+") "+Thread.currentThread()+", start";
353                 System.err.println(msg);
354                 //Exception e1 = new Exception(msg);
355                 //e1.printStackTrace();
356             }
357             if(unrecoverable) {
358                 GLAnimatorControl ctrl = GLWindow.this.getAnimator();
359                 if ( null!=ctrl ) {
360                     ctrl.remove(GLWindow.this);
361                 }
362                 helper=null;
363             }
364         }
365
366         public synchronized void resetCounter() {
367             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
368                 System.err.println("GLWindow.resetCounter() "+Thread.currentThread());
369             }
370             GLWindow.this.resetFPSCounter();
371         }
372
373         public synchronized void setVisibleActionPost(boolean visible, boolean nativeWindowCreated) {
374             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
375                 String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", start";
376                 System.err.println(msg);
377                 // Exception e1 = new Exception(msg);
378                 // e1.printStackTrace();
379             }
380
381             /* if (nativeWindowCreated && null != context) {
382                 throw new GLException("InternalError: Native Windows has been just created, but context wasn't destroyed (is not null)");
383             } */
384             if (null == context && visible && 0 != window.getWindowHandle() && 0<getWidth()*getHeight()) {
385                 NativeWindow nw;
386                 if (window.getWrappedWindow() != null) {
387                     nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
388                 } else {
389                     nw = window;
390                 }
391                 GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
392                 if(null==factory) {
393                     factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
394                 }
395                 if(null==drawable) {
396                     drawable = factory.createGLDrawable(nw);
397                 }
398                 drawable.setRealized(true);
399                 context = drawable.createContext(sharedContext);
400                 context.setContextCreationFlags(additionalCtxCreationFlags);                
401             }
402             if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
403                 String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", fin";
404                 System.err.println(msg);
405                 //Exception e1 = new Exception(msg);
406                 //e1.printStackTrace();
407             }
408         }
409         
410         public synchronized boolean pauseRenderingAction() {
411             boolean animatorPaused = false;
412             GLAnimatorControl ctrl = GLWindow.this.getAnimator();
413             if ( null!=ctrl ) {
414                 animatorPaused = ctrl.pause();
415             }
416             return animatorPaused;
417         }
418
419         public synchronized void resumeRenderingAction() {
420             GLAnimatorControl ctrl = GLWindow.this.getAnimator();
421             if ( null!=ctrl && ctrl.isPaused() ) {
422                 ctrl.resume();
423             }
424         }
425     }
426
427     //----------------------------------------------------------------------
428     // OpenGL-related methods and state
429     //
430
431     private GLContext sharedContext = null;
432     private int additionalCtxCreationFlags = 0;
433     private GLDrawableFactory factory;
434     private GLDrawable drawable;
435     private GLContext context;
436     private GLDrawableHelper helper = new GLDrawableHelper();
437     // To make reshape events be sent immediately before a display event
438     private boolean sendReshape=false;
439     private boolean sendDestroy=false;
440     private FPSCounterImpl fpsCounter = new FPSCounterImpl();    
441
442     public GLDrawableFactory getFactory() {
443         return factory;
444     }
445
446     /**
447      * Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.<br>
448      * At native creation, {@link #setVisible(boolean) setVisible(true)},
449      * a {@link javax.media.opengl.GLDrawable drawable} and {@link javax.media.opengl.GLContext context} is created besides the native Window itself,<br>
450      * hence you shall set the shared context before.
451      *
452      * @param sharedContext The OpenGL context shared by this GLWindow's one
453      */
454     public void setSharedContext(GLContext sharedContext) {
455         this.sharedContext = sharedContext;
456     }
457
458     public void setContext(GLContext newCtx) {
459         context = newCtx;
460         if(null != context) {
461             context.setContextCreationFlags(additionalCtxCreationFlags);
462         }        
463     }
464
465     public GLContext getContext() {
466         return context;
467     }
468
469     public GL getGL() {
470         if (context == null) {
471             return null;
472         }
473         return context.getGL();
474     }
475
476     public GL setGL(GL gl) {
477         if (context != null) {
478             context.setGL(gl);
479             return gl;
480         }
481         return null;
482     }
483
484     public void addGLEventListener(GLEventListener listener) {
485         if(null!=helper) {
486             helper.addGLEventListener(listener);
487         }
488     }
489
490     public void addGLEventListener(int index, GLEventListener listener) {
491         if(null!=helper) {
492             helper.addGLEventListener(index, listener);
493         }
494     }
495
496     public void removeGLEventListener(GLEventListener listener) {
497         if(null!=helper) {
498             helper.removeGLEventListener(listener);
499         }
500     }
501
502     public void setAnimator(GLAnimatorControl animatorControl) {
503         if(null!=helper) {
504             helper.setAnimator(animatorControl);
505         }
506     }
507
508     public GLAnimatorControl getAnimator() {
509         if(null!=helper) {
510             return helper.getAnimator();
511         }
512         return null;
513     }
514
515     public void invoke(boolean wait, GLRunnable glRunnable) {
516         if(null!=helper) {
517             helper.invoke(this, wait, glRunnable);
518         }
519     }
520
521     public void display() {
522         display(false);
523     }
524
525     public void display(boolean forceReshape) {
526         if( null == window ) { return; }
527
528         if(sendDestroy || ( null!=window && window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) ) {
529             sendDestroy=false;
530             destroy();
531             return;
532         }
533
534         if( null == context && isVisible() && 0<getWidth()*getHeight() ) {
535             // retry native window and drawable/context creation 
536             setVisible(true);
537         }
538
539         if(forceReshape) {
540             sendReshape = true;
541         }
542         
543         if( isVisible() && null != context ) {
544             if( NativeSurface.LOCK_SURFACE_NOT_READY < lockSurface() ) {
545                 try {
546                     helper.invokeGL(drawable, context, displayAction, initAction);
547                 } finally {
548                     unlockSurface();
549                 }
550             }
551         }
552     }
553     
554     /** This implementation uses a static value */
555     public void setAutoSwapBufferMode(boolean onOrOff) {
556         if(null!=helper) {
557             helper.setAutoSwapBufferMode(onOrOff);
558         }
559     }
560
561     /** This implementation uses a static value */
562     public boolean getAutoSwapBufferMode() {
563         if(null!=helper) {
564             return helper.getAutoSwapBufferMode();
565         }
566         return false;
567     }
568     
569     public void swapBuffers() {
570         if(drawable!=null && context != null) {
571             drawable.swapBuffers();
572         }
573     }
574
575     public void setContextCreationFlags(int flags) {
576         additionalCtxCreationFlags = flags;
577     }
578       
579     public int getContextCreationFlags() {
580         return additionalCtxCreationFlags;                
581     }
582         
583     private class InitAction implements Runnable {
584         public final void run() {
585             // Lock: Locked Surface/Window by MakeCurrent/Release
586             helper.init(GLWindow.this);
587             resetFPSCounter();
588         }
589     }
590     private InitAction initAction = new InitAction();
591
592     private class DisplayAction implements Runnable {
593         public final void run() {
594             // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release
595             if (sendReshape) {
596                 helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight());
597                 sendReshape = false;
598             }
599
600             helper.display(GLWindow.this);
601
602             fpsCounter.tickFPS();
603         }
604     }
605     private DisplayAction displayAction = new DisplayAction();
606
607     public final void setUpdateFPSFrames(int frames, PrintStream out) {
608         fpsCounter.setUpdateFPSFrames(frames, out);
609     }
610     
611     public final void resetFPSCounter() {
612         fpsCounter.resetFPSCounter();
613     }
614
615     public final int getUpdateFPSFrames() {
616         return fpsCounter.getUpdateFPSFrames();
617     }
618     
619     public final long getFPSStartTime()   {
620         return fpsCounter.getFPSStartTime();
621     }
622
623     public final long getLastFPSUpdateTime() {
624         return fpsCounter.getLastFPSUpdateTime();
625     }
626
627     public final long getLastFPSPeriod() {
628         return fpsCounter.getLastFPSPeriod();
629     }
630     
631     public final float getLastFPS() {
632         return fpsCounter.getLastFPS();
633     }
634     
635     public final int getTotalFPSFrames() {
636         return fpsCounter.getTotalFPSFrames();
637     }
638
639     public final long getTotalFPSDuration() {
640         return fpsCounter.getTotalFPSDuration();
641     }
642     
643     public final float getTotalFPS() {
644         return fpsCounter.getTotalFPS();
645     }        
646
647     private class SwapBuffersAction implements Runnable {
648         public final void run() {
649             drawable.swapBuffers();
650         }
651     }
652     private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
653
654     //----------------------------------------------------------------------
655     // GLDrawable methods
656     //
657
658     public final NativeSurface getNativeSurface() {
659         return null!=drawable ? drawable.getNativeSurface() : null;
660     }
661
662     public final long getHandle() {
663         return null!=drawable ? drawable.getHandle() : 0;
664     }
665
666     public final int getX() {
667         return window.getX();
668     }
669
670     public final int getY() {
671         return window.getY();
672     }
673
674     public final int getWidth() {
675         return window.getWidth();
676     }
677
678     public final int getHeight() {
679         return window.getHeight();
680     }
681
682     //----------------------------------------------------------------------
683     // GLDrawable methods that are not really needed
684     //
685
686     public final GLContext createContext(GLContext shareWith) {
687         return drawable.createContext(shareWith);
688     }
689
690     public final void setRealized(boolean realized) {
691     }
692
693     public final boolean isRealized() {
694         return ( null != drawable ) ? drawable.isRealized() : false;
695     }
696
697     public final GLCapabilitiesImmutable getChosenGLCapabilities() {
698         if (drawable == null) {
699             throw new GLException("No drawable yet");
700         }
701
702         return drawable.getChosenGLCapabilities();
703     }
704
705     public final GLProfile getGLProfile() {
706         if (drawable == null) {
707             throw new GLException("No drawable yet");
708         }
709
710         return drawable.getGLProfile();
711     }
712
713     //----------------------------------------------------------------------
714     // NEWTEventConsumer 
715     //
716     public boolean consumeEvent(NEWTEvent event) {
717         return window.consumeEvent(event);
718     }
719
720     //----------------------------------------------------------------------
721     // Window completion
722     //
723     public final void windowRepaint(int x, int y, int width, int height) {
724         window.windowRepaint(x, y, width, height);
725     }
726
727     public final void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
728         window.enqueueEvent(wait, event);
729     }
730
731     public final void runOnEDTIfAvail(boolean wait, final Runnable task) {
732         window.runOnEDTIfAvail(wait, task);
733     }
734
735     public final SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
736         return window.getSurfaceUpdatedListener(index);
737     }
738
739     public final SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
740         return window.getSurfaceUpdatedListeners();
741     }
742
743     public final void removeAllSurfaceUpdatedListener() {
744         window.removeAllSurfaceUpdatedListener();
745     }
746
747     public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
748         window.removeSurfaceUpdatedListener(l);
749     }
750
751     public final void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
752         window.addSurfaceUpdatedListener(l);
753     }
754
755     public final void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
756         window.addSurfaceUpdatedListener(index, l);
757     }
758
759     public void sendWindowEvent(int eventType) {
760         window.sendWindowEvent(eventType);
761     }
762
763     public final WindowListener getWindowListener(int index) {
764         return window.getWindowListener(index);
765     }
766
767     public final WindowListener[] getWindowListeners() {
768         return window.getWindowListeners();
769     }
770
771     public final void removeWindowListener(WindowListener l) {
772         window.removeWindowListener(l);
773     }
774
775     public final void addWindowListener(WindowListener l) {
776         window.addWindowListener(l);
777     }
778
779     public final void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException {
780         window.addWindowListener(index, l);
781     }
782
783     public final void addKeyListener(KeyListener l) {
784         window.addKeyListener(l);
785     }
786
787     public final void addKeyListener(int index, KeyListener l) {
788         window.addKeyListener(index, l);
789     }
790
791     public final void removeKeyListener(KeyListener l) {
792         window.removeKeyListener(l);
793     }
794
795     public final KeyListener getKeyListener(int index) {
796         return window.getKeyListener(index);
797     }
798
799     public final KeyListener[] getKeyListeners() {
800         return window.getKeyListeners();
801     }
802
803     public final void addMouseListener(MouseListener l) {
804         window.addMouseListener(l);
805     }
806
807     public final void addMouseListener(int index, MouseListener l) {
808         window.addMouseListener(index, l);
809     }
810
811     public final void removeMouseListener(MouseListener l) {
812         window.removeMouseListener(l);
813     }
814
815     public final MouseListener getMouseListener(int index) {
816         return window.getMouseListener(index);
817     }
818
819     public final MouseListener[] getMouseListeners() {
820         return window.getMouseListeners();
821     }
822
823     //----------------------------------------------------------------------
824     // NativeWindow completion
825     //
826
827     public final int lockSurface() {
828         return window.lockSurface();
829     }
830
831     public final void unlockSurface() throws NativeWindowException {
832         window.unlockSurface();
833     }
834
835     public final boolean isSurfaceLockedByOtherThread() {
836         return window.isSurfaceLockedByOtherThread();
837     }
838
839     public final boolean isSurfaceLocked() {
840         return window.isSurfaceLocked();
841     }
842
843     public final Thread getSurfaceLockOwner() {
844         return window.getSurfaceLockOwner();
845
846     }
847
848     public final boolean surfaceSwap() {
849         return window.surfaceSwap();
850     }
851
852     public final void invalidate() {
853         window.invalidate();
854     }
855     
856     public final long getWindowHandle() {
857         return window.getWindowHandle();
858
859     }
860
861     public final long getSurfaceHandle() {
862         return window.getSurfaceHandle();
863
864     }
865
866     public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
867         return window.getGraphicsConfiguration();
868     }
869
870     public final long getDisplayHandle() {
871         return window.getDisplayHandle();
872     }
873
874     public final int  getScreenIndex() {
875         return window.getScreenIndex();
876     }
877
878     public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
879         window.surfaceUpdated(updater, ns, when);
880     }
881
882     /**
883      * A most simple JOGL AWT test entry
884      */
885     public static void main(String args[]) {
886         System.err.println(VersionUtil.getPlatformInfo());
887         System.err.println(GlueGenVersion.getInstance());
888         System.err.println(NativeWindowVersion.getInstance());
889         System.err.println(JoglVersion.getInstance());
890         System.err.println(NewtVersion.getInstance());
891
892         GLProfile glp = GLProfile.getDefault();
893         GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
894         List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null);
895         for(int i=0; i<availCaps.size(); i++) {
896             System.err.println(availCaps.get(i));
897         }
898         GLCapabilitiesImmutable caps = new GLCapabilities( glp );
899
900         GLWindow glWindow = GLWindow.create(caps);
901         glWindow.setSize(128, 128);
902
903         glWindow.addGLEventListener(new GLEventListener() {
904             public void init(GLAutoDrawable drawable) {
905                 GL gl = drawable.getGL();
906                 System.err.println(JoglVersion.getGLInfo(gl, null));
907             }
908
909             public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
910             }
911
912             public void display(GLAutoDrawable drawable) {
913             }
914
915             public void dispose(GLAutoDrawable drawable) {
916             }
917         });
918
919         glWindow.setVisible(true);
920         glWindow.invalidate();
921     }
922
923 }
http://JogAmp.org git info: FAQ, tutorial and man pages.