Jogamp
NativeWindow/X11: Simple cleanup/generalization ..
[jogl.git] / src / newt / classes / com / jogamp / newt / opengl / GLWindow.java
CommitLineData
a959c53b
KR
1/*
2 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
0feca163 3 * Copyright (c) 2010 JogAmp Community. All rights reserved.
a959c53b
KR
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
2d57c252 35package com.jogamp.newt.opengl;
a959c53b 36
ea819ff7 37import java.io.PrintStream;
8adc0478
SG
38import java.util.List;
39
dac35658 40import com.jogamp.common.GlueGenVersion;
8c9f3bb3 41import com.jogamp.common.util.VersionUtil;
dac35658 42import com.jogamp.nativewindow.NativeWindowVersion;
2d57c252 43import com.jogamp.newt.*;
1ad8c39d 44import com.jogamp.newt.event.*;
360b6716 45import jogamp.newt.WindowImpl;
8adc0478 46
a959c53b 47import javax.media.nativewindow.*;
018c7e86 48import javax.media.nativewindow.util.Point;
8adc0478 49import javax.media.nativewindow.util.Insets;
a959c53b 50import javax.media.opengl.*;
8adc0478 51
ea819ff7 52import jogamp.opengl.FPSCounterImpl;
360b6716 53import jogamp.opengl.GLDrawableHelper;
dac35658 54import com.jogamp.opengl.JoglVersion;
a959c53b
KR
55
56/**
0feca163
SG
57 * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
58 * using an aggregation of a {@link com.jogamp.newt.Window} implementation.
2268a6ce
SG
59 * <P>
60 * This implementation does not make the OpenGL context current<br>
0feca163
SG
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>
2268a6ce 67 * <p>
a959c53b 68 */
ea819ff7 69public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter {
0feca163 70 private WindowImpl window;
a959c53b 71
476d1d75
MB
72 /**
73 * Constructor. Do not call this directly -- use {@link #create()} instead.
74 */
811bd23e 75 protected GLWindow(Window window) {
ea819ff7 76 resetFPSCounter();
0feca163
SG
77 this.window = (WindowImpl) window;
78 ((WindowImpl)this.window).setHandleDestroyNotify(false);
1ad8c39d 79 window.addWindowListener(new WindowAdapter() {
10c696f7 80 @Override
969e4276 81 public void windowRepaint(WindowUpdateEvent e) {
e587f2a7 82 if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
969e4276
SG
83 display();
84 }
85 }
86
10c696f7 87 @Override
a959c53b
KR
88 public void windowResized(WindowEvent e) {
89 sendReshape = true;
e587f2a7 90 if( !GLWindow.this.window.isWindowLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
969e4276
SG
91 display();
92 }
a959c53b
KR
93 }
94
10c696f7 95 @Override
a959c53b 96 public void windowDestroyNotify(WindowEvent e) {
2cbab63b
SG
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 }
e587f2a7
SG
107 } else if (GLWindow.this.window.isWindowLockedByOtherThread()) {
108 // Window is locked by another thread
2cbab63b
SG
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 ();
4c3e9e25 116 }
5ece52d5 117 }
a959c53b
KR
118 }
119 });
0feca163 120 this.window.setLifecycleHook(new GLLifecycleHook());
a959c53b
KR
121 }
122
0feca163
SG
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 */
29e3b223 129 public static GLWindow create(GLCapabilitiesImmutable caps) {
0feca163 130 return new GLWindow(NewtFactory.createWindow(caps));
a959c53b
KR
131 }
132
0feca163
SG
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 */
29e3b223 139 public static GLWindow create(Screen screen, GLCapabilitiesImmutable caps) {
0feca163 140 return new GLWindow(NewtFactory.createWindow(screen, caps));
a959c53b
KR
141 }
142
0feca163
SG
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) {
811bd23e 149 return new GLWindow(window);
a959c53b 150 }
6e599a26 151
0feca163
SG
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 */
29e3b223 161 public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilitiesImmutable caps) {
0feca163 162 return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps));
a959c53b 163 }
a959c53b 164
0feca163 165 //----------------------------------------------------------------------
2cbab63b
SG
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 //----------------------------------------------------------------------
0feca163
SG
177 // Window Access
178 //
a959c53b 179
7c159772
SG
180 public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
181 return window.setCapabilitiesChooser(chooser);
182 }
183
e4913066 184 public final CapabilitiesImmutable getChosenCapabilities() {
0feca163
SG
185 if (drawable == null) {
186 return window.getChosenCapabilities();
811bd23e 187 }
811bd23e 188
0feca163 189 return drawable.getChosenGLCapabilities();
a959c53b
KR
190 }
191
e4913066 192 public final CapabilitiesImmutable getRequestedCapabilities() {
0feca163 193 return window.getRequestedCapabilities();
811bd23e
SG
194 }
195
0feca163
SG
196 public final Window getWindow() {
197 return window;
811bd23e
SG
198 }
199
018c7e86
SG
200 public final NativeWindow getParent() {
201 return window.getParent();
811bd23e
SG
202 }
203
0feca163 204 public final Screen getScreen() {
a959c53b
KR
205 return window.getScreen();
206 }
207
0feca163 208 public final void setTitle(String title) {
a959c53b
KR
209 window.setTitle(title);
210 }
211
0feca163 212 public final String getTitle() {
a959c53b
KR
213 return window.getTitle();
214 }
215
0feca163 216 public final void setUndecorated(boolean value) {
a959c53b
KR
217 window.setUndecorated(value);
218 }
219
0feca163 220 public final boolean isUndecorated() {
a959c53b
KR
221 return window.isUndecorated();
222 }
223
0feca163 224 public final void setFocusAction(FocusRunnable focusAction) {
a4b16ad5
SG
225 window.setFocusAction(focusAction);
226 }
0feca163
SG
227
228 public final void requestFocus() {
229 window.requestFocus();
811bd23e
SG
230 }
231
609e3083
SG
232 public boolean hasFocus() {
233 return window.hasFocus();
234 }
235
0feca163
SG
236 public final Insets getInsets() {
237 return window.getInsets();
811bd23e 238 }
a959c53b 239
0feca163 240 public final void setPosition(int x, int y) {
a959c53b
KR
241 window.setPosition(x, y);
242 }
7bed517f 243
0feca163 244 public final boolean setFullscreen(boolean fullscreen) {
a959c53b
KR
245 return window.setFullscreen(fullscreen);
246 }
0feca163
SG
247
248 public final boolean isFullscreen() {
249 return window.isFullscreen();
811bd23e 250 }
a959c53b 251
0feca163 252 public final boolean isVisible() {
a959c53b
KR
253 return window.isVisible();
254 }
255
10c696f7 256 @Override
0feca163
SG
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+ */ "]";
a959c53b
KR
260 }
261
0feca163
SG
262 public final int reparentWindow(NativeWindow newParent) {
263 return window.reparentWindow(newParent);
a959c53b
KR
264 }
265
0feca163
SG
266 public final int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
267 return window.reparentWindow(newParent, forceDestroyCreate);
a959c53b
KR
268 }
269
0feca163
SG
270 public final void removeChild(NativeWindow win) {
271 window.removeChild(win);
a959c53b
KR
272 }
273
0feca163
SG
274 public final void addChild(NativeWindow win) {
275 window.addChild(win);
a959c53b 276 }
2aa29677 277
0feca163
SG
278 //----------------------------------------------------------------------
279 // Window.LifecycleHook Implementation
280 //
969e4276 281
db4d7d19
SG
282 public final void destroy() {
283 window.destroy();
bf584fba
SG
284 }
285
0feca163
SG
286 public final void setVisible(boolean visible) {
287 window.setVisible(visible);
a959c53b
KR
288 }
289
0feca163
SG
290 public final void setSize(int width, int height) {
291 window.setSize(width, height);
a959c53b
KR
292 }
293
0feca163
SG
294 public final boolean isValid() {
295 return window.isValid();
969e4276 296 }
a959c53b 297
0feca163
SG
298 public final boolean isNativeValid() {
299 return window.isNativeValid();
a959c53b
KR
300 }
301
018c7e86
SG
302 public Point getLocationOnScreen(Point storage) {
303 return window.getLocationOnScreen(storage);
304 }
305
0feca163
SG
306 // Hide methods here ..
307 protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
308
3747f6a6
SG
309 private class DisposeAction implements Runnable {
310 public final void run() {
0feca163
SG
311 // Lock: Covered by DestroyAction ..
312 helper.dispose(GLWindow.this);
313 }
314 }
315 DisposeAction disposeAction = new DisposeAction();
316
db4d7d19
SG
317 public synchronized void destroyActionPreLock() {
318 // nop
e6225fce
SG
319 }
320
db4d7d19 321 public synchronized void destroyActionInLock() {
0feca163 322 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 323 String msg = "GLWindow.destroy() "+Thread.currentThread()+", start";
0feca163
SG
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
db4d7d19
SG
345 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
346 System.err.println("GLWindow.destroy() "+Thread.currentThread()+", fin");
0feca163 347 }
db4d7d19 348 }
0feca163 349
db4d7d19 350 public synchronized void invalidate(boolean unrecoverable) {
0feca163 351 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 352 String msg = "GLWindow.invalidate("+unrecoverable+") "+Thread.currentThread()+", start";
db4d7d19
SG
353 System.err.println(msg);
354 //Exception e1 = new Exception(msg);
355 //e1.printStackTrace();
356 }
357 if(unrecoverable) {
358 GLAnimatorControl ctrl = GLWindow.this.getAnimator();
2aa29677
SG
359 if ( null!=ctrl ) {
360 ctrl.remove(GLWindow.this);
db4d7d19
SG
361 }
362 helper=null;
0feca163
SG
363 }
364 }
365
2c1a870f 366 public synchronized void resetCounter() {
0feca163 367 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
2c1a870f
SG
368 System.err.println("GLWindow.resetCounter() "+Thread.currentThread());
369 }
ea819ff7 370 GLWindow.this.resetFPSCounter();
2c1a870f
SG
371 }
372
373 public synchronized void setVisibleActionPost(boolean visible, boolean nativeWindowCreated) {
374 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 375 String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", start";
0feca163
SG
376 System.err.println(msg);
377 // Exception e1 = new Exception(msg);
378 // e1.printStackTrace();
379 }
380
381 /* if (nativeWindowCreated && null != context) {
382 throw new GLException("InternalError: Native Windows has been just created, but context wasn't destroyed (is not null)");
383 } */
384 if (null == context && visible && 0 != window.getWindowHandle() && 0<getWidth()*getHeight()) {
385 NativeWindow nw;
386 if (window.getWrappedWindow() != null) {
387 nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
388 } else {
389 nw = window;
390 }
29e3b223 391 GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
0feca163
SG
392 if(null==factory) {
393 factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
394 }
395 if(null==drawable) {
396 drawable = factory.createGLDrawable(nw);
397 }
398 drawable.setRealized(true);
fd0d3f15 399 context = drawable.createContext(sharedContext);
6c0ad949 400 context.setContextCreationFlags(additionalCtxCreationFlags);
0feca163
SG
401 }
402 if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
10c696f7 403 String msg = "GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", fin";
0feca163
SG
404 System.err.println(msg);
405 //Exception e1 = new Exception(msg);
406 //e1.printStackTrace();
407 }
408 }
2aa29677
SG
409
410 public synchronized boolean pauseRenderingAction() {
411 boolean animatorPaused = false;
0feca163 412 GLAnimatorControl ctrl = GLWindow.this.getAnimator();
4c3e9e25
SG
413 if ( null!=ctrl ) {
414 animatorPaused = ctrl.pause();
0feca163 415 }
2aa29677 416 return animatorPaused;
0feca163
SG
417 }
418
a0e9d6c8 419 public synchronized void resumeRenderingAction() {
0feca163 420 GLAnimatorControl ctrl = GLWindow.this.getAnimator();
2aa29677 421 if ( null!=ctrl && ctrl.isPaused() ) {
0feca163
SG
422 ctrl.resume();
423 }
424 }
425 }
a0e9d6c8 426
a959c53b
KR
427 //----------------------------------------------------------------------
428 // OpenGL-related methods and state
429 //
430
fd0d3f15 431 private GLContext sharedContext = null;
6c0ad949 432 private int additionalCtxCreationFlags = 0;
a959c53b
KR
433 private GLDrawableFactory factory;
434 private GLDrawable drawable;
435 private GLContext context;
436 private GLDrawableHelper helper = new GLDrawableHelper();
437 // To make reshape events be sent immediately before a display event
438 private boolean sendReshape=false;
439 private boolean sendDestroy=false;
ea819ff7 440 private FPSCounterImpl fpsCounter = new FPSCounterImpl();
0feca163 441
a959c53b
KR
442 public GLDrawableFactory getFactory() {
443 return factory;
444 }
445
fd0d3f15
SG
446 /**
447 * Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.<br>
448 * At native creation, {@link #setVisible(boolean) setVisible(true)},
449 * a {@link javax.media.opengl.GLDrawable drawable} and {@link javax.media.opengl.GLContext context} is created besides the native Window itself,<br>
450 * hence you shall set the shared context before.
451 *
452 * @param sharedContext The OpenGL context shared by this GLWindow's one
453 */
454 public void setSharedContext(GLContext sharedContext) {
455 this.sharedContext = sharedContext;
456 }
457
a959c53b
KR
458 public void setContext(GLContext newCtx) {
459 context = newCtx;
6c0ad949
SG
460 if(null != context) {
461 context.setContextCreationFlags(additionalCtxCreationFlags);
462 }
a959c53b
KR
463 }
464
465 public GLContext getContext() {
466 return context;
467 }
468
469 public GL getGL() {
470 if (context == null) {
471 return null;
472 }
473 return context.getGL();
474 }
475
4e0a5af0 476 public GL setGL(GL gl) {
a959c53b
KR
477 if (context != null) {
478 context.setGL(gl);
4e0a5af0 479 return gl;
a959c53b 480 }
4e0a5af0 481 return null;
a959c53b
KR
482 }
483
484 public void addGLEventListener(GLEventListener listener) {
77413854
SG
485 if(null!=helper) {
486 helper.addGLEventListener(listener);
487 }
a959c53b
KR
488 }
489
302f183c 490 public void addGLEventListener(int index, GLEventListener listener) {
77413854
SG
491 if(null!=helper) {
492 helper.addGLEventListener(index, listener);
493 }
302f183c
SG
494 }
495
a959c53b 496 public void removeGLEventListener(GLEventListener listener) {
77413854
SG
497 if(null!=helper) {
498 helper.removeGLEventListener(listener);
499 }
a959c53b
KR
500 }
501
0feca163 502 public void setAnimator(GLAnimatorControl animatorControl) {
77413854
SG
503 if(null!=helper) {
504 helper.setAnimator(animatorControl);
505 }
969e4276
SG
506 }
507
0feca163 508 public GLAnimatorControl getAnimator() {
77413854
SG
509 if(null!=helper) {
510 return helper.getAnimator();
511 }
512 return null;
969e4276
SG
513 }
514
0d24458c 515 public void invoke(boolean wait, GLRunnable glRunnable) {
77413854
SG
516 if(null!=helper) {
517 helper.invoke(this, wait, glRunnable);
518 }
0d24458c
SG
519 }
520
a959c53b 521 public void display() {
cf4c4037
SG
522 display(false);
523 }
524
525 public void display(boolean forceReshape) {
6e599a26
SG
526 if( null == window ) { return; }
527
969e4276 528 if(sendDestroy || ( null!=window && window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) ) {
63be4a40
SG
529 sendDestroy=false;
530 destroy();
531 return;
532 }
969e4276 533
5e1a67c9 534 if( null == context && isVisible() && 0<getWidth()*getHeight() ) {
6e599a26
SG
535 // retry native window and drawable/context creation
536 setVisible(true);
537 }
538
2aa29677
SG
539 if(forceReshape) {
540 sendReshape = true;
541 }
542
543 if( isVisible() && null != context ) {
c8a9c59e 544 if( NativeSurface.LOCK_SURFACE_NOT_READY < lockSurface() ) {
1d265b51 545 try {
c8a9c59e
SG
546 helper.invokeGL(drawable, context, displayAction, initAction);
547 } finally {
548 unlockSurface();
549 }
a959c53b
KR
550 }
551 }
552 }
6c0ad949 553
a92906bc 554 /** This implementation uses a static value */
a959c53b 555 public void setAutoSwapBufferMode(boolean onOrOff) {
77413854
SG
556 if(null!=helper) {
557 helper.setAutoSwapBufferMode(onOrOff);
558 }
a959c53b
KR
559 }
560
a92906bc 561 /** This implementation uses a static value */
a959c53b 562 public boolean getAutoSwapBufferMode() {
77413854
SG
563 if(null!=helper) {
564 return helper.getAutoSwapBufferMode();
565 }
566 return false;
a959c53b 567 }
6c0ad949 568
a959c53b 569 public void swapBuffers() {
2268a6ce 570 if(drawable!=null && context != null) {
d72745fa 571 drawable.swapBuffers();
a959c53b
KR
572 }
573 }
574
6c0ad949
SG
575 public void setContextCreationFlags(int flags) {
576 additionalCtxCreationFlags = flags;
577 }
578
579 public int getContextCreationFlags() {
580 return additionalCtxCreationFlags;
581 }
582
3747f6a6
SG
583 private class InitAction implements Runnable {
584 public final void run() {
1d333a77 585 // Lock: Locked Surface/Window by MakeCurrent/Release
a959c53b 586 helper.init(GLWindow.this);
ea819ff7 587 resetFPSCounter();
a959c53b
KR
588 }
589 }
590 private InitAction initAction = new InitAction();
591
3747f6a6
SG
592 private class DisplayAction implements Runnable {
593 public final void run() {
1d333a77 594 // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release
a959c53b 595 if (sendReshape) {
969e4276 596 helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight());
a959c53b
KR
597 sendReshape = false;
598 }
599
600 helper.display(GLWindow.this);
601
ea819ff7 602 fpsCounter.tickFPS();
a959c53b
KR
603 }
604 }
a92906bc 605 private DisplayAction displayAction = new DisplayAction();
a959c53b 606
ea819ff7
SG
607 public final void setUpdateFPSFrames(int frames, PrintStream out) {
608 fpsCounter.setUpdateFPSFrames(frames, out);
609 }
610
611 public final void resetFPSCounter() {
612 fpsCounter.resetFPSCounter();
0feca163 613 }
a959c53b 614
ea819ff7
SG
615 public final int getUpdateFPSFrames() {
616 return fpsCounter.getUpdateFPSFrames();
617 }
618
619 public final long getFPSStartTime() {
620 return fpsCounter.getFPSStartTime();
0feca163
SG
621 }
622
ea819ff7
SG
623 public final long getLastFPSUpdateTime() {
624 return fpsCounter.getLastFPSUpdateTime();
0feca163
SG
625 }
626
ea819ff7
SG
627 public final long getLastFPSPeriod() {
628 return fpsCounter.getLastFPSPeriod();
629 }
630
631 public final float getLastFPS() {
632 return fpsCounter.getLastFPS();
633 }
634
635 public final int getTotalFPSFrames() {
636 return fpsCounter.getTotalFPSFrames();
018c7e86
SG
637 }
638
ea819ff7
SG
639 public final long getTotalFPSDuration() {
640 return fpsCounter.getTotalFPSDuration();
0feca163 641 }
ea819ff7
SG
642
643 public final float getTotalFPS() {
644 return fpsCounter.getTotalFPS();
645 }
a959c53b 646
3747f6a6
SG
647 private class SwapBuffersAction implements Runnable {
648 public final void run() {
a959c53b
KR
649 drawable.swapBuffers();
650 }
651 }
a959c53b
KR
652 private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
653
654 //----------------------------------------------------------------------
0feca163 655 // GLDrawable methods
a959c53b
KR
656 //
657
018c7e86
SG
658 public final NativeSurface getNativeSurface() {
659 return null!=drawable ? drawable.getNativeSurface() : null;
a959c53b
KR
660 }
661
0feca163
SG
662 public final long getHandle() {
663 return null!=drawable ? drawable.getHandle() : 0;
8883fa88 664 }
665
0feca163
SG
666 public final int getX() {
667 return window.getX();
6e599a26
SG
668 }
669
0feca163
SG
670 public final int getY() {
671 return window.getY();
6e599a26
SG
672 }
673
0feca163
SG
674 public final int getWidth() {
675 return window.getWidth();
a959c53b
KR
676 }
677
0feca163
SG
678 public final int getHeight() {
679 return window.getHeight();
1d333a77
SG
680 }
681
a959c53b
KR
682 //----------------------------------------------------------------------
683 // GLDrawable methods that are not really needed
684 //
685
0feca163 686 public final GLContext createContext(GLContext shareWith) {
a959c53b
KR
687 return drawable.createContext(shareWith);
688 }
689
0feca163 690 public final void setRealized(boolean realized) {
a959c53b
KR
691 }
692
0feca163 693 public final boolean isRealized() {
811bd23e
SG
694 return ( null != drawable ) ? drawable.isRealized() : false;
695 }
696
29e3b223 697 public final GLCapabilitiesImmutable getChosenGLCapabilities() {
a959c53b
KR
698 if (drawable == null) {
699 throw new GLException("No drawable yet");
700 }
701
702 return drawable.getChosenGLCapabilities();
703 }
704
0feca163 705 public final GLProfile getGLProfile() {
a959c53b
KR
706 if (drawable == null) {
707 throw new GLException("No drawable yet");
708 }
709
710 return drawable.getGLProfile();
711 }
0feca163
SG
712
713 //----------------------------------------------------------------------
1b7b5d34
SG
714 // NEWTEventConsumer
715 //
716 public boolean consumeEvent(NEWTEvent event) {
717 return window.consumeEvent(event);
718 }
719
720 //----------------------------------------------------------------------
0feca163
SG
721 // Window completion
722 //
723 public final void windowRepaint(int x, int y, int width, int height) {
724 window.windowRepaint(x, y, width, height);
725 }
726
727 public final void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
728 window.enqueueEvent(wait, event);
729 }
730
731 public final void runOnEDTIfAvail(boolean wait, final Runnable task) {
732 window.runOnEDTIfAvail(wait, task);
733 }
734
735 public final SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
736 return window.getSurfaceUpdatedListener(index);
737 }
738
739 public final SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
740 return window.getSurfaceUpdatedListeners();
741 }
742
743 public final void removeAllSurfaceUpdatedListener() {
744 window.removeAllSurfaceUpdatedListener();
745 }
746
747 public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
748 window.removeSurfaceUpdatedListener(l);
749 }
750
751 public final void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
752 window.addSurfaceUpdatedListener(l);
753 }
754
755 public final void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
756 window.addSurfaceUpdatedListener(index, l);
757 }
758
759 public void sendWindowEvent(int eventType) {
760 window.sendWindowEvent(eventType);
761 }
762
763 public final WindowListener getWindowListener(int index) {
764 return window.getWindowListener(index);
765 }
766
767 public final WindowListener[] getWindowListeners() {
768 return window.getWindowListeners();
769 }
770
771 public final void removeWindowListener(WindowListener l) {
772 window.removeWindowListener(l);
773 }
774
775 public final void addWindowListener(WindowListener l) {
776 window.addWindowListener(l);
777 }
778
779 public final void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException {
780 window.addWindowListener(index, l);
781 }
782
783 public final void addKeyListener(KeyListener l) {
784 window.addKeyListener(l);
785 }
786
787 public final void addKeyListener(int index, KeyListener l) {
788 window.addKeyListener(index, l);
789 }
790
791 public final void removeKeyListener(KeyListener l) {
792 window.removeKeyListener(l);
793 }
794
795 public final KeyListener getKeyListener(int index) {
796 return window.getKeyListener(index);
797 }
798
799 public final KeyListener[] getKeyListeners() {
800 return window.getKeyListeners();
801 }
802
803 public final void addMouseListener(MouseListener l) {
804 window.addMouseListener(l);
805 }
806
807 public final void addMouseListener(int index, MouseListener l) {
808 window.addMouseListener(index, l);
809 }
810
811 public final void removeMouseListener(MouseListener l) {
812 window.removeMouseListener(l);
813 }
814
815 public final MouseListener getMouseListener(int index) {
816 return window.getMouseListener(index);
817 }
818
819 public final MouseListener[] getMouseListeners() {
820 return window.getMouseListeners();
821 }
822
823 //----------------------------------------------------------------------
824 // NativeWindow completion
825 //
826
827 public final int lockSurface() {
828 return window.lockSurface();
829 }
830
831 public final void unlockSurface() throws NativeWindowException {
832 window.unlockSurface();
833 }
834
835 public final boolean isSurfaceLockedByOtherThread() {
836 return window.isSurfaceLockedByOtherThread();
837 }
838
839 public final boolean isSurfaceLocked() {
840 return window.isSurfaceLocked();
841 }
842
843 public final Thread getSurfaceLockOwner() {
844 return window.getSurfaceLockOwner();
845
846 }
847
0feca163
SG
848 public final boolean surfaceSwap() {
849 return window.surfaceSwap();
850 }
851
852 public final void invalidate() {
853 window.invalidate();
854 }
855
856 public final long getWindowHandle() {
857 return window.getWindowHandle();
858
859 }
860
861 public final long getSurfaceHandle() {
862 return window.getSurfaceHandle();
863
864 }
865
866 public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
867 return window.getGraphicsConfiguration();
868 }
869
870 public final long getDisplayHandle() {
871 return window.getDisplayHandle();
872 }
873
874 public final int getScreenIndex() {
875 return window.getScreenIndex();
876 }
877
018c7e86
SG
878 public final void surfaceUpdated(Object updater, NativeSurface ns, long when) {
879 window.surfaceUpdated(updater, ns, when);
0feca163 880 }
597d10f5
SG
881
882 /**
883 * A most simple JOGL AWT test entry
884 */
885 public static void main(String args[]) {
8c9f3bb3 886 System.err.println(VersionUtil.getPlatformInfo());
6ea02e25
SG
887 System.err.println(GlueGenVersion.getInstance());
888 System.err.println(NativeWindowVersion.getInstance());
2aa90676 889 System.err.println(JoglVersion.getInstance());
6ea02e25 890 System.err.println(NewtVersion.getInstance());
8adc0478
SG
891
892 GLProfile glp = GLProfile.getDefault();
893 GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
894 List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null);
895 for(int i=0; i<availCaps.size(); i++) {
896 System.err.println(availCaps.get(i));
897 }
898 GLCapabilitiesImmutable caps = new GLCapabilities( glp );
597d10f5
SG
899
900 GLWindow glWindow = GLWindow.create(caps);
901 glWindow.setSize(128, 128);
902
903 glWindow.addGLEventListener(new GLEventListener() {
904 public void init(GLAutoDrawable drawable) {
905 GL gl = drawable.getGL();
10c696f7 906 System.err.println(JoglVersion.getGLInfo(gl, null));
597d10f5
SG
907 }
908
909 public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
910 }
911
912 public void display(GLAutoDrawable drawable) {
913 }
914
915 public void dispose(GLAutoDrawable drawable) {
916 }
917 });
918
919 glWindow.setVisible(true);
db4d7d19 920 glWindow.invalidate();
597d10f5
SG
921 }
922
a959c53b 923}
http://JogAmp.org git info: FAQ, tutorial and man pages.