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