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