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