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