summaryrefslogtreecommitdiffstats
path: root/src/newt/classes/jogamp
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2011-02-08 06:20:35 +0100
committerSven Gothel <[email protected]>2011-02-08 06:20:35 +0100
commit4cda4b70dbcd21cf57e1e253ddba32b88bcaec18 (patch)
tree6f16d211cb80ebf5dcc8cab6424c70079a38ea7f /src/newt/classes/jogamp
parenteb7986963c87bc6f33e7f18bb90ddf898b7dd63a (diff)
Move implementation private files from com.jogamp.<module>.impl. to jogamp.<module> (1/2) - rename task
- com.jogamp.opengl.impl -> jogamp.opengl - com.jogamp.opengl.util.glsl.fixedfunc.impl -> jogamp.opengl.util.glsl.fixedfunc - com.jogamp.nativewindow.impl -> jogamp.nativewindow - com.jogamp.newt.impl -> jogamp.newt This sorts implementation details from the top level, ie skipping the public 'com', allowing a better seperation of public classes and implementation details and also reduces strings. This approach of public/private seperation is also used in the OpenJDK.
Diffstat (limited to 'src/newt/classes/jogamp')
-rw-r--r--src/newt/classes/jogamp/newt/Debug.java140
-rw-r--r--src/newt/classes/jogamp/newt/DefaultEDTUtil.java330
-rw-r--r--src/newt/classes/jogamp/newt/DisplayImpl.java416
-rw-r--r--src/newt/classes/jogamp/newt/NEWTJNILibLoader.java62
-rw-r--r--src/newt/classes/jogamp/newt/OffscreenWindow.java128
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java505
-rw-r--r--src/newt/classes/jogamp/newt/ScreenModeStatus.java207
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java2230
-rw-r--r--src/newt/classes/jogamp/newt/awt/AWTCanvas.java289
-rw-r--r--src/newt/classes/jogamp/newt/awt/AWTDisplay.java63
-rw-r--r--src/newt/classes/jogamp/newt/awt/AWTScreen.java65
-rw-r--r--src/newt/classes/jogamp/newt/awt/AWTWindow.java289
-rw-r--r--src/newt/classes/jogamp/newt/awt/opengl/VersionApplet.java174
-rw-r--r--src/newt/classes/jogamp/newt/event/NEWTEventTask.java56
-rw-r--r--src/newt/classes/jogamp/newt/intel/gdl/Display.java104
-rw-r--r--src/newt/classes/jogamp/newt/intel/gdl/Screen.java68
-rw-r--r--src/newt/classes/jogamp/newt/intel/gdl/Window.java147
-rw-r--r--src/newt/classes/jogamp/newt/macosx/MacDisplay.java101
-rw-r--r--src/newt/classes/jogamp/newt/macosx/MacScreen.java57
-rw-r--r--src/newt/classes/jogamp/newt/macosx/MacWindow.java433
-rw-r--r--src/newt/classes/jogamp/newt/opengl/broadcom/egl/Display.java81
-rw-r--r--src/newt/classes/jogamp/newt/opengl/broadcom/egl/Screen.java62
-rw-r--r--src/newt/classes/jogamp/newt/opengl/broadcom/egl/Window.java164
-rw-r--r--src/newt/classes/jogamp/newt/opengl/kd/KDDisplay.java84
-rw-r--r--src/newt/classes/jogamp/newt/opengl/kd/KDScreen.java58
-rw-r--r--src/newt/classes/jogamp/newt/opengl/kd/KDWindow.java147
-rw-r--r--src/newt/classes/jogamp/newt/windows/WindowsDisplay.java94
-rw-r--r--src/newt/classes/jogamp/newt/windows/WindowsScreen.java114
-rw-r--r--src/newt/classes/jogamp/newt/windows/WindowsWindow.java201
-rw-r--r--src/newt/classes/jogamp/newt/x11/X11Display.java114
-rw-r--r--src/newt/classes/jogamp/newt/x11/X11Screen.java270
-rw-r--r--src/newt/classes/jogamp/newt/x11/X11Window.java145
32 files changed, 7398 insertions, 0 deletions
diff --git a/src/newt/classes/jogamp/newt/Debug.java b/src/newt/classes/jogamp/newt/Debug.java
new file mode 100644
index 000000000..62c261d2e
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/Debug.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.newt.impl;
+
+import java.security.*;
+
+/** Helper routines for logging and debugging. */
+
+public class Debug {
+ // Some common properties
+ private static boolean verbose;
+ private static boolean debugAll;
+ private static AccessControlContext localACC;
+
+ static {
+ localACC=AccessController.getContext();
+ verbose = isPropertyDefined("newt.verbose", true);
+ debugAll = isPropertyDefined("newt.debug", true);
+ if (verbose) {
+ Package p = Package.getPackage("com.jogamp.newt");
+ System.err.println("NEWT specification version " + p.getSpecificationVersion());
+ System.err.println("NEWT implementation version " + p.getImplementationVersion());
+ System.err.println("NEWT implementation vendor " + p.getImplementationVendor());
+ }
+ }
+
+ static int getIntProperty(final String property, final boolean jnlpAlias) {
+ return getIntProperty(property, jnlpAlias, localACC);
+ }
+
+ public static int getIntProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ int i=0;
+ try {
+ Integer iv = Integer.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ i = iv.intValue();
+ } catch (NumberFormatException nfe) {}
+ return i;
+ }
+
+ static boolean getBooleanProperty(final String property, final boolean jnlpAlias) {
+ return getBooleanProperty(property, jnlpAlias, localACC);
+ }
+
+ public static boolean getBooleanProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ Boolean b = Boolean.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ return b.booleanValue();
+ }
+
+ static boolean isPropertyDefined(final String property, final boolean jnlpAlias) {
+ return isPropertyDefined(property, jnlpAlias, localACC);
+ }
+
+ public static boolean isPropertyDefined(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ return (Debug.getProperty(property, jnlpAlias, acc) != null) ? true : false;
+ }
+
+ static String getProperty(final String property, final boolean jnlpAlias) {
+ return getProperty(property, jnlpAlias, localACC);
+ }
+
+ public static String getProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ String s=null;
+ if(null!=acc && acc.equals(localACC)) {
+ s = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String val=null;
+ try {
+ val = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==val && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ val = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ return val;
+ }
+ });
+ } else {
+ try {
+ s = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==s && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ s = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ }
+ return s;
+ }
+ public static final String jnlp_prefix = "jnlp." ;
+
+ public static boolean verbose() {
+ return verbose;
+ }
+
+ public static boolean debugAll() {
+ return debugAll;
+ }
+
+ public static boolean debug(String subcomponent) {
+ return debugAll() || isPropertyDefined("newt.debug." + subcomponent, true);
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/DefaultEDTUtil.java b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
new file mode 100644
index 000000000..7a2a0c9bd
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/DefaultEDTUtil.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.common.util.RunnableTask;
+import com.jogamp.newt.util.EDTUtil;
+import java.util.*;
+import javax.media.nativewindow.NativeWindowException;
+
+public class DefaultEDTUtil implements EDTUtil {
+ public static final boolean DEBUG = Debug.debug("EDT");
+
+ private ThreadGroup threadGroup;
+ private EventDispatchThread edt = null;
+ private Object edtLock = new Object(); // locking the EDT start/stop state
+ private String name;
+ int start_iter=0;
+ private Runnable dispatchMessages;
+
+ public DefaultEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
+ this.threadGroup = tg;
+ this.name=new String(Thread.currentThread().getName()+"-"+name+"-EDT-");
+ this.dispatchMessages=dispatchMessages;
+ this.edt = new EventDispatchThread(threadGroup, name);
+ this.edt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+
+ public final void reset() {
+ synchronized(edtLock) {
+ waitUntilStopped();
+ if(DEBUG) {
+ if(edt.tasks.size()>0) {
+ String msg = Thread.currentThread()+": EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ }
+ System.err.println(Thread.currentThread()+": EDT reset - edt: "+edt);
+ }
+ this.edt = new EventDispatchThread(threadGroup, name);
+ this.edt.setDaemon(true); // don't stop JVM from shutdown ..
+ }
+ }
+
+ public final void start() {
+ synchronized(edtLock) {
+ if(!edt.isRunning() && !edt.shouldStop) {
+ if(edt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
+ }
+ start_iter++;
+ edt.setName(name+start_iter);
+ edt.shouldStop = false;
+ if(DEBUG) {
+ String msg = Thread.currentThread()+": EDT START - edt: "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ }
+ edt.start();
+ }
+ }
+ }
+
+ public final boolean isCurrentThreadEDT() {
+ return edt == Thread.currentThread();
+ }
+
+ public final boolean isRunning() {
+ return edt.isRunning() ;
+ }
+
+ public final void invokeStop(Runnable task) {
+ invokeImpl(true, task, true);
+ }
+
+ public final void invoke(boolean wait, Runnable task) {
+ invokeImpl(wait, task, false);
+ }
+
+ private final void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ if(task == null) {
+ throw new RuntimeException("Null Runnable");
+ }
+ Throwable throwable = null;
+ RunnableTask rTask = null;
+ Object rTaskLock = new Object();
+ synchronized(rTaskLock) { // lock the optional task execution
+ synchronized(edtLock) { // lock the EDT status
+ if( edt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ Throwable t = new Throwable("Warning: EDT about (1) to stop, won't enqueue new task: "+edt);
+ t.printStackTrace();
+ }
+ return;
+ }
+ // Exception ee = new Exception("XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // ee.printStackTrace();
+ if(stop) {
+ edt.shouldStop = true;
+ if(DEBUG) {
+ String msg = Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - edt: "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ }
+ }
+ if( isCurrentThreadEDT() ) {
+ task.run();
+ wait = false; // running in same thread (EDT) -> no wait
+ if(stop && edt.tasks.size()>0) {
+ String msg = "Warning: EDT about (2) to stop, having remaining tasks: "+edt.tasks.size()+" - "+edt;
+ if(DEBUG) {
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ } else {
+ System.err.println(msg);
+ }
+ }
+ } else {
+ synchronized(edt.tasks) {
+ start(); // start if not started yet and !shouldStop
+ wait = wait && edt.isRunning();
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */);
+ if(stop) {
+ rTask.setAttachment(new Boolean(true)); // mark final task
+ }
+ // append task ..
+ edt.tasks.add(rTask);
+ edt.tasks.notifyAll();
+ }
+ }
+ }
+ if( wait ) {
+ try {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ if(throwable instanceof NativeWindowException) {
+ throw (NativeWindowException)throwable;
+ }
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
+ if(DEBUG && stop) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP X edt: "+edt);
+ }
+ }
+
+ public void waitUntilIdle() {
+ if(edt.isRunning() && edt != Thread.currentThread()) {
+ synchronized(edt.tasks) {
+ while(edt.isRunning() && edt.tasks.size()>0) {
+ try {
+ edt.tasks.notifyAll();
+ edt.tasks.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ public void waitUntilStopped() {
+ if(edt.isRunning() && edt != Thread.currentThread() ) {
+ synchronized(edtLock) {
+ if(edt.isRunning() && edt != Thread.currentThread() ) {
+ while(edt.isRunning()) {
+ try {
+ edtLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ class EventDispatchThread extends Thread {
+ volatile boolean shouldStop = false;
+ volatile boolean isRunning = false;
+ ArrayList tasks = new ArrayList(); // one shot tasks
+
+ public EventDispatchThread(ThreadGroup tg, String name) {
+ super(tg, name);
+ }
+
+ public final boolean isRunning() {
+ return isRunning;
+ }
+
+ public void start() throws IllegalThreadStateException {
+ isRunning = true;
+ super.start();
+ }
+
+ /**
+ * Utilizing locking only on tasks and its execution,
+ * not for event dispatching.
+ */
+ public void run() {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() START "+ getName());
+ }
+ RuntimeException error = null;
+ try {
+ do {
+ // event dispatch
+ if(!shouldStop) {
+ dispatchMessages.run();
+ }
+ // wait and work on tasks
+ RunnableTask task = null;
+ synchronized(tasks) {
+ // wait for tasks
+ if(!shouldStop && tasks.size()==0) {
+ try {
+ tasks.wait(defaultEDTPollGranularity);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ // execute one task, if available
+ if(tasks.size()>0) {
+ task = (RunnableTask) tasks.remove(0);
+ tasks.notifyAll();
+ }
+ }
+ if(null!=task) {
+ // Exceptions are always catched, see RunnableTask creation above
+ task.run();
+ }
+ } while(!shouldStop) ;
+ } catch (Throwable t) {
+ // handle errors ..
+ shouldStop = true;
+ if(t instanceof RuntimeException) {
+ error = (RuntimeException) t;
+ } else {
+ error = new RuntimeException("Within EDT", t);
+ }
+ } finally {
+ if(DEBUG) {
+ RunnableTask rt = ( tasks.size() > 0 ) ? (RunnableTask) tasks.get(0) : null ;
+ System.err.println(getName()+": EDT run() END "+ getName()+", tasks: "+tasks.size()+", "+rt+", "+error);
+ }
+ synchronized(edtLock) {
+ if(null==error) {
+ synchronized(tasks) {
+ // drain remaining tasks (stop not on EDT),
+ // while having tasks and no previous-task, or previous-task is non final
+ RunnableTask task = null;
+ while ( ( null == task || task.getAttachment() == null ) && tasks.size() > 0 ) {
+ task = ( RunnableTask ) tasks.remove(0);
+ task.run();
+ tasks.notifyAll();
+ }
+ if(DEBUG) {
+ if(null!=task && task.getAttachment()==null) {
+ Throwable t = new Throwable("Warning: EDT exit: Last task Not Final: "+tasks.size()+", "+task+" - "+edt);
+ t.printStackTrace();
+ } else if(tasks.size()>0) {
+ Throwable t = new Throwable("Warning: EDT exit: Remaining tasks Post Final: "+tasks.size());
+ t.printStackTrace();
+ }
+ }
+ }
+ }
+ isRunning = !shouldStop;
+ if(!isRunning) {
+ edtLock.notifyAll();
+ }
+ }
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() EXIT "+ getName()+", "+error);
+ }
+ if(null!=error) {
+ throw error;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/newt/classes/jogamp/newt/DisplayImpl.java b/src/newt/classes/jogamp/newt/DisplayImpl.java
new file mode 100644
index 000000000..2af01c217
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/DisplayImpl.java
@@ -0,0 +1,416 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.event.NEWTEvent;
+import com.jogamp.newt.event.NEWTEventConsumer;
+import com.jogamp.newt.impl.event.NEWTEventTask;
+import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.newt.util.MainThread;
+import java.util.ArrayList;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+
+public abstract class DisplayImpl extends Display {
+ public static final boolean DEBUG_TEST_EDT_MAINTHREAD = Debug.isPropertyDefined("newt.test.EDTMainThread", true); // JAU EDT Test ..
+
+ private static int serialno = 1;
+
+ private static Class getDisplayClass(String type)
+ throws ClassNotFoundException
+ {
+ Class displayClass = NewtFactory.getCustomClass(type, "Display");
+ if(null==displayClass) {
+ if (NativeWindowFactory.TYPE_EGL.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDDisplay");
+ } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.windows.WindowsDisplay");
+ } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.macosx.MacDisplay");
+ } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.x11.X11Display");
+ } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.awt.AWTDisplay");
+ } else {
+ throw new RuntimeException("Unknown display type \"" + type + "\"");
+ }
+ }
+ return displayClass;
+ }
+
+ /** Make sure to reuse a Display with the same name */
+ public static Display create(String type, String name, final long handle, boolean reuse) {
+ try {
+ Class displayClass = getDisplayClass(type);
+ DisplayImpl display = (DisplayImpl) displayClass.newInstance();
+ name = display.validateDisplayName(name, handle);
+ synchronized(displayList) {
+ if(reuse) {
+ Display display0 = Display.getLastDisplayOf(type, name, -1);
+ if(null != display0) {
+ if(DEBUG) {
+ System.err.println("Display.create() REUSE: "+display0+" "+getThreadName());
+ }
+ return display0;
+ }
+ }
+ display.name = name;
+ display.type=type;
+ display.destroyWhenUnused=false;
+ display.refCount=0;
+ display.id = serialno++;
+ display.fqname = getFQName(display.type, display.name, display.id);
+ display.hashCode = display.fqname.hashCode();
+ displayList.add(display);
+ }
+ display.createEDTUtil();
+ if(DEBUG) {
+ System.err.println("Display.create() NEW: "+display+" "+getThreadName());
+ }
+ return display;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ public synchronized final void createNative()
+ throws NativeWindowException
+ {
+ if(null==aDevice) {
+ if(DEBUG) {
+ System.err.println("Display.createNative() START ("+getThreadName()+", "+this+")");
+ }
+ final DisplayImpl f_dpy = this;
+ try {
+ runOnEDTIfAvail(true, new Runnable() {
+ public void run() {
+ f_dpy.createNativeImpl();
+ }});
+ } catch (Throwable t) {
+ throw new NativeWindowException(t);
+ }
+ if(null==aDevice) {
+ throw new NativeWindowException("Display.createNative() failed to instanciate an AbstractGraphicsDevice");
+ }
+ if(DEBUG) {
+ System.err.println("Display.createNative() END ("+getThreadName()+", "+this+")");
+ }
+ synchronized(displayList) {
+ displaysActive++;
+ }
+ }
+ }
+
+ protected boolean shallRunOnEDT() {
+ return true;
+ }
+
+ protected void createEDTUtil() {
+ if(NewtFactory.useEDT()) {
+ if ( ! DEBUG_TEST_EDT_MAINTHREAD ) {
+ Thread current = Thread.currentThread();
+ edtUtil = new DefaultEDTUtil(current.getThreadGroup(), "Display-"+getFQName(), dispatchMessagesRunnable);
+ } else {
+ // Begin JAU EDT Test ..
+ MainThread.addPumpMessage(this, dispatchMessagesRunnable);
+ edtUtil = MainThread.getSingleton();
+ // End JAU EDT Test ..
+ }
+ if(DEBUG) {
+ System.err.println("Display.createNative("+getFQName()+") Create EDTUtil: "+edtUtil.getClass().getName());
+ }
+ }
+ }
+
+ public final EDTUtil getEDTUtil() {
+ return edtUtil;
+ }
+
+ private void stopEDT(final Runnable task) {
+ if( shallRunOnEDT() && null!=edtUtil ) {
+ edtUtil.invokeStop(task);
+ } else {
+ task.run();
+ }
+ }
+
+ public void runOnEDTIfAvail(boolean wait, final Runnable task) {
+ if( shallRunOnEDT() && null!=edtUtil ) {
+ edtUtil.invoke(wait, task);
+ } else {
+ task.run();
+ }
+ }
+
+ public boolean validateEDT() {
+ if(0==refCount && null==aDevice && null != edtUtil && edtUtil.isRunning()) {
+ stopEDT( new Runnable() {
+ public void run() {
+ // nop
+ }
+ } );
+ edtUtil.waitUntilStopped();
+ edtUtil.reset();
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized final void destroy() {
+ if(DEBUG) {
+ dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
+ }
+ synchronized(displayList) {
+ displayList.remove(this);
+ if(0 < displaysActive) {
+ displaysActive--;
+ }
+ }
+ if(DEBUG) {
+ System.err.println("Display.destroy(): "+this+" "+getThreadName());
+ }
+ final AbstractGraphicsDevice f_aDevice = aDevice;
+ final DisplayImpl f_dpy = this;
+ stopEDT( new Runnable() {
+ public void run() {
+ if ( null != f_aDevice ) {
+ f_dpy.closeNativeImpl();
+ }
+ }
+ } );
+ if(null!=edtUtil) {
+ if ( DEBUG_TEST_EDT_MAINTHREAD ) {
+ MainThread.removePumpMessage(this); // JAU EDT Test ..
+ }
+ edtUtil.waitUntilStopped();
+ edtUtil.reset();
+ }
+ aDevice = null;
+ refCount=0;
+ if(DEBUG) {
+ dumpDisplayList("Display.destroy("+getFQName()+") END");
+ }
+ }
+
+ public synchronized final int addReference() {
+ if(DEBUG) {
+ System.err.println("Display.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ }
+ if ( 0 == refCount ) {
+ createNative();
+ }
+ if(null == aDevice) {
+ throw new NativeWindowException ("Display.addReference() (refCount "+refCount+") null AbstractGraphicsDevice");
+ }
+ return refCount++;
+ }
+
+
+ public synchronized final int removeReference() {
+ if(DEBUG) {
+ System.err.println("Display.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ }
+ refCount--; // could become < 0, in case of manual destruction without actual creation/addReference
+ if(0>=refCount) {
+ destroy();
+ refCount=0; // fix < 0
+ }
+ return refCount;
+ }
+
+ public synchronized final int getReferenceCount() {
+ return refCount;
+ }
+
+ protected abstract void createNativeImpl();
+ protected abstract void closeNativeImpl();
+
+ public final int getId() {
+ return id;
+ }
+
+ public final String getType() {
+ return type;
+ }
+
+ public final String getName() {
+ return name;
+ }
+
+ public final String getFQName() {
+ return fqname;
+ }
+
+ public static final String nilString = "nil" ;
+
+ public String validateDisplayName(String name, long handle) {
+ if(null==name && 0!=handle) {
+ name="wrapping-"+toHexString(handle);
+ }
+ return ( null == name ) ? nilString : name ;
+ }
+
+ private static final String getFQName(String type, String name, int id) {
+ if(null==type) type=nilString;
+ if(null==name) name=nilString;
+ StringBuffer sb = new StringBuffer();
+ sb.append(type);
+ sb.append("_");
+ sb.append(name);
+ sb.append("-");
+ sb.append(id);
+ return sb.toString().intern();
+ }
+
+ public final long getHandle() {
+ if(null!=aDevice) {
+ return aDevice.getHandle();
+ }
+ return 0;
+ }
+
+ public final AbstractGraphicsDevice getGraphicsDevice() {
+ return aDevice;
+ }
+
+ public final boolean isNativeValid() {
+ return null != aDevice;
+ }
+
+ public boolean isEDTRunning() {
+ if(null!=edtUtil) {
+ return edtUtil.isRunning();
+ }
+ return false;
+ }
+
+ public String toString() {
+ return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
+ }
+
+ protected abstract void dispatchMessagesNative();
+
+ private Object eventsLock = new Object();
+ private ArrayList/*<NEWTEvent>*/ events = new ArrayList();
+
+ class DispatchMessagesRunnable implements Runnable {
+ public void run() {
+ DisplayImpl.this.dispatchMessages();
+ }
+ }
+ DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
+
+ public void dispatchMessages() {
+ // System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName());
+ if(0==refCount) return; // no screens
+ if(null==getGraphicsDevice()) return; // no native device
+
+ ArrayList/*<NEWTEvent>*/ _events = null;
+
+ if(events.size()>0) {
+ // swap events list to free ASAP
+ synchronized(eventsLock) {
+ if(events.size()>0) {
+ _events = events;
+ events = new ArrayList();
+ }
+ eventsLock.notifyAll();
+ }
+ if( null != _events ) {
+ for (int i=0; i < _events.size(); i++) {
+ NEWTEventTask eventTask = (NEWTEventTask) _events.get(i);
+ NEWTEvent event = eventTask.get();
+ Object source = event.getSource();
+ if(source instanceof NEWTEventConsumer) {
+ NEWTEventConsumer consumer = (NEWTEventConsumer) source ;
+ if(!consumer.consumeEvent(event)) {
+ enqueueEvent(false, event);
+ }
+ } else {
+ throw new RuntimeException("Event source not NEWT: "+source.getClass().getName()+", "+source);
+ }
+ eventTask.notifyIssuer();
+ }
+ }
+ }
+
+ // System.err.println("Display.dispatchMessages() NATIVE "+this+" "+getThreadName());
+ dispatchMessagesNative();
+ }
+
+ public void enqueueEvent(boolean wait, NEWTEvent e) {
+ if(!isEDTRunning()) {
+ // oops .. we are already dead
+ if(DEBUG) {
+ Throwable t = new Throwable("Warning: EDT already stopped: wait:="+wait+", "+e);
+ t.printStackTrace();
+ }
+ return;
+ }
+ Object lock = new Object();
+ NEWTEventTask eTask = new NEWTEventTask(e, wait?lock:null);
+ synchronized(lock) {
+ synchronized(eventsLock) {
+ events.add(eTask);
+ eventsLock.notifyAll();
+ }
+ if( wait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throw new RuntimeException(ie);
+ }
+ }
+ }
+ }
+
+ protected EDTUtil edtUtil = null;
+ protected int id;
+ protected String name;
+ protected String type;
+ protected String fqname;
+ protected int hashCode;
+ protected int refCount; // number of Display references by Screen
+ protected boolean destroyWhenUnused;
+ protected AbstractGraphicsDevice aDevice;
+}
+
diff --git a/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java b/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
new file mode 100644
index 000000000..a4d234fd5
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.newt.impl;
+
+// FIXME: refactor Java SE dependencies
+//import java.awt.Toolkit;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashSet;
+import com.jogamp.common.jvm.JNILibLoaderBase;
+
+public class NEWTJNILibLoader extends JNILibLoaderBase {
+
+ public static void loadNEWT() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("newt", null, true);
+ return null;
+ }
+ });
+ }
+
+}
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
new file mode 100644
index 000000000..44aa9b440
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Point;
+
+public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
+
+ long surfaceHandle = 0;
+
+ public OffscreenWindow() {
+ }
+
+ static long nextWindowHandle = 0x100; // start here - a marker
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new NativeWindowException("OffscreenWindow does not support window parenting");
+ }
+ if(capsRequested.isOnscreen()) {
+ throw new NativeWindowException("Capabilities is onscreen");
+ }
+ AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ config = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, aScreen);
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ synchronized(OffscreenWindow.class) {
+ setWindowHandle(nextWindowHandle++);
+ }
+ }
+
+ protected void closeNativeImpl() {
+ // nop
+ }
+
+ protected void invalidate(boolean unrecoverable) {
+ super.invalidate(unrecoverable);
+ surfaceHandle = 0;
+ }
+
+ public synchronized void destroy() {
+ super.destroy();
+ surfaceHandle = 0;
+ }
+
+ public void setSurfaceHandle(long handle) {
+ surfaceHandle = handle ;
+ }
+
+ public long getSurfaceHandle() {
+ return surfaceHandle;
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ sizeChanged(width, height, false);
+ visibleChanged(visible);
+ }
+
+ protected void requestFocusImpl(boolean reparented) {
+ }
+
+ public void setSize(int width, int height) {
+ if(!visible) {
+ sizeChanged(width, height, false);
+ }
+ }
+ public void setPosition(int x, int y) {
+ // nop
+ }
+ public boolean setFullscreen(boolean fullscreen) {
+ // nop
+ return false;
+ }
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
+ shouldNotCallThis();
+ return false;
+ }
+
+ public Point getLocationOnScreen(Point storage) {
+ if(null!=storage) {
+ storage.setX(0);
+ storage.setY(0);
+ return storage;
+ }
+ return new Point(0,0);
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+}
+
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
new file mode 100644
index 000000000..071122a68
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -0,0 +1,505 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.util.ScreenModeUtil;
+
+import javax.media.nativewindow.*;
+
+import java.security.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class ScreenImpl extends Screen implements ScreenModeListener {
+ protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true);
+
+ protected DisplayImpl display;
+ protected int screen_idx;
+ protected String fqname;
+ protected int hashCode;
+ protected AbstractGraphicsScreen aScreen;
+ protected int refCount; // number of Screen references by Window
+ protected int width=-1, height=-1; // detected values: set using setScreenSize
+ protected static int usrWidth=-1, usrHeight=-1; // property values: newt.ws.swidth and newt.ws.sheight
+ private static AccessControlContext localACC = AccessController.getContext();
+ private List/*<ScreenModeListener>*/ referencedScreenModeListener = new ArrayList();
+ long t0; // creationTime
+
+ private static Class getScreenClass(String type)
+ throws ClassNotFoundException
+ {
+ Class screenClass = NewtFactory.getCustomClass(type, "Screen");
+ if(null==screenClass) {
+ if (NativeWindowFactory.TYPE_EGL.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDScreen");
+ } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.windows.WindowsScreen");
+ } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.macosx.MacScreen");
+ } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.x11.X11Screen");
+ } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.awt.AWTScreen");
+ } else {
+ throw new RuntimeException("Unknown window type \"" + type + "\"");
+ }
+ }
+ return screenClass;
+ }
+
+ public static Screen create(Display display, final int idx) {
+ try {
+ if(usrWidth<0 || usrHeight<0) {
+ synchronized (Screen.class) {
+ if(usrWidth<0 || usrHeight<0) {
+ usrWidth = Debug.getIntProperty("newt.ws.swidth", true, localACC);
+ usrHeight = Debug.getIntProperty("newt.ws.sheight", true, localACC);
+ if(usrWidth>0 || usrHeight>0) {
+ System.err.println("User screen size "+usrWidth+"x"+usrHeight);
+ }
+ }
+ }
+ }
+ synchronized(screenList) {
+ {
+ Screen screen0 = ScreenImpl.getLastScreenOf(display, idx, -1);
+ if(null != screen0) {
+ if(DEBUG) {
+ System.err.println("Screen.create() REUSE: "+screen0+" "+Display.getThreadName());
+ }
+ return screen0;
+ }
+ }
+ Class screenClass = getScreenClass(display.getType());
+ ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
+ screen.display = (DisplayImpl) display;
+ screen.screen_idx = idx;
+ screen.fqname = (display.getFQName()+idx).intern();
+ screen.hashCode = screen.fqname.hashCode();
+ screenList.add(screen);
+ if(DEBUG) {
+ System.err.println("Screen.create() NEW: "+screen+" "+Display.getThreadName());
+ }
+ return screen;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ public synchronized final void createNative()
+ throws NativeWindowException
+ {
+ if(null == aScreen) {
+ if(DEBUG) {
+ System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ t0 = System.currentTimeMillis();
+ display.addReference();
+ createNativeImpl();
+ if(null == aScreen) {
+ throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
+ }
+ if(DEBUG) {
+ System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ synchronized(screenList) {
+ screensActive++;
+ }
+ }
+ initScreenModeStatus();
+ }
+
+ public synchronized final void destroy() {
+ releaseScreenModeStatus();
+
+ synchronized(screenList) {
+ screenList.remove(this);
+ if(0 < screensActive) {
+ screensActive--;
+ }
+ }
+
+ if ( null != aScreen ) {
+ closeNativeImpl();
+ aScreen = null;
+ }
+ refCount = 0;
+ display.removeReference();
+ }
+
+ public synchronized final int addReference() throws NativeWindowException {
+ if(DEBUG) {
+ System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ }
+ if ( 0 == refCount ) {
+ createNative();
+ }
+ if(null == aScreen) {
+ throw new NativeWindowException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen");
+ }
+ return ++refCount;
+ }
+
+ public synchronized final int removeReference() {
+ if(DEBUG) {
+ String msg = "Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ System.err.println(msg);
+ }
+ refCount--; // could become < 0, in case of manual destruction without actual creation/addReference
+ if(0>=refCount) {
+ destroy();
+ refCount=0; // fix < 0
+ }
+ return refCount;
+ }
+
+ public synchronized final int getReferenceCount() {
+ return refCount;
+ }
+
+ protected abstract void createNativeImpl();
+ protected abstract void closeNativeImpl();
+
+ public final String getFQName() {
+ return fqname;
+ }
+
+ protected void setScreenSize(int w, int h) {
+ System.err.println("Detected screen size "+w+"x"+h);
+ width=w; height=h;
+ }
+
+ public final Display getDisplay() {
+ return display;
+ }
+
+ public final int getIndex() {
+ return screen_idx;
+ }
+
+ public final AbstractGraphicsScreen getGraphicsScreen() {
+ return aScreen;
+ }
+
+ public final boolean isNativeValid() {
+ return null != aScreen;
+ }
+
+ public final int getWidth() {
+ return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
+ }
+
+ public final int getHeight() {
+ return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
+ }
+
+ public String toString() {
+ return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]";
+ }
+
+ public final List/*<ScreenMode>*/ getScreenModes() {
+ ArrayHashSet screenModes = getScreenModesOrig();
+ if(null != screenModes && 0 < screenModes.size()) {
+ return screenModes.toArrayList();
+ }
+ return null;
+ }
+
+ public ScreenMode getOriginalScreenMode() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ return ( null != sms ) ? sms.getOriginalScreenMode() : null ;
+ }
+
+ public ScreenMode getCurrentScreenMode() {
+ ScreenMode smU = null;
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null != sms) {
+ ScreenMode sm0 = ( DEBUG_TEST_SCREENMODE_DISABLED ) ? null : getCurrentScreenModeImpl();
+ if(null == sm0) {
+ return null;
+ }
+ sms.lock();
+ try {
+ smU = (ScreenMode) sms.getScreenModes().get(sm0); // unify via value hash
+ if(null == smU) {
+ throw new RuntimeException(sm0+" could not be hashed from ScreenMode list");
+ }
+
+ // if mode has changed somehow, update it ..
+ if( sms.getCurrentScreenMode().hashCode() != smU.hashCode() ) {
+ sms.fireScreenModeChanged(smU, true);
+ }
+ } finally {
+ sms.unlock();
+ }
+ }
+ return smU;
+ }
+
+ public boolean setCurrentScreenMode(ScreenMode screenMode) {
+ ScreenMode smU = (ScreenMode) getScreenModesOrig().get(screenMode); // unify via value hash
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ sms.lock();
+ try {
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.0 "+screenMode);
+ }
+
+ sms.fireScreenModeChangeNotify(smU);
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.1 "+screenMode);
+ }
+
+ boolean success = setCurrentScreenModeImpl(smU);
+ if(success) {
+ setScreenSize(screenMode.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
+ screenMode.getMonitorMode().getSurfaceSize().getResolution().getHeight());
+ }
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.0 "+screenMode+", success: "+success);
+ }
+
+ sms.fireScreenModeChanged(smU, success);
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.X "+screenMode+", success: "+success);
+ }
+
+ return success;
+ } finally {
+ sms.unlock();
+ }
+ }
+ return false;
+ }
+
+ public void screenModeChangeNotify(ScreenMode sm) {
+ for(int i=0; i<referencedScreenModeListener.size(); i++) {
+ ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChangeNotify(sm);
+ }
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ for(int i=0; i<referencedScreenModeListener.size(); i++) {
+ ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChanged(sm, success);
+ }
+ }
+
+ public synchronized final void addScreenModeListener(ScreenModeListener sml) {
+ referencedScreenModeListener.add(sml);
+ }
+
+ public synchronized final void removeScreenModeListener(ScreenModeListener sml) {
+ referencedScreenModeListener.remove(sml);
+ }
+
+ /** ScreenModeStatus bridge to native implementation */
+ protected final ArrayHashSet getScreenModesOrig() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ return sms.getScreenModes();
+ }
+ return null;
+ }
+
+ /** ScreenModeStatus bridge to native implementation */
+ protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ return sms.getScreenModesIdx2NativeIdx();
+ }
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
+ * <br>
+ * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
+ * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
+ * <br>
+ * <b>Note</b>: Additional 1st element is native mode id.
+ */
+ protected int[] getScreenModeFirstImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
+ * <br>
+ * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
+ * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
+ * <br>
+ * <b>Note</b>: Additional 1st element is native mode id.
+ */
+ protected int[] getScreenModeNextImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ */
+ protected ScreenMode getCurrentScreenModeImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ */
+ protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) {
+ return false;
+ }
+
+ private void initScreenModeStatus() {
+ ScreenModeStatus sms;
+ ScreenModeStatus.lockScreenModeStatus();
+ try {
+ sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null==sms) {
+ IntIntHashMap screenModesIdx2NativeIdx = new IntIntHashMap();
+
+ ArrayHashSet screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx);
+ sms = new ScreenModeStatus(screenModes, screenModesIdx2NativeIdx);
+ if(null!=screenModes && screenModes.size()>0) {
+ ScreenMode originalScreenMode = ( DEBUG_TEST_SCREENMODE_DISABLED ) ? null : getCurrentScreenModeImpl();
+ if(null != originalScreenMode) {
+ ScreenMode originalScreenMode0 = (ScreenMode) screenModes.get(originalScreenMode); // unify via value hash
+ if(null == originalScreenMode0) {
+ throw new RuntimeException(originalScreenMode+" could not be hashed from ScreenMode list");
+ }
+ sms.setOriginalScreenMode(originalScreenMode0);
+ }
+ }
+ ScreenModeStatus.mapScreenModeStatus(this.getFQName(), sms);
+ }
+ sms.addListener(this);
+ } finally {
+ ScreenModeStatus.unlockScreenModeStatus();
+ }
+ }
+
+ /** ignores bpp < 15 */
+ private ArrayHashSet collectNativeScreenModes(IntIntHashMap screenModesIdx2NativeId) {
+ ArrayHashSet resolutionPool = new ArrayHashSet();
+ ArrayHashSet surfaceSizePool = new ArrayHashSet();
+ ArrayHashSet screenSizeMMPool = new ArrayHashSet();
+ ArrayHashSet monitorModePool = new ArrayHashSet();
+ ArrayHashSet screenModePool = null;
+
+ screenModePool = new ArrayHashSet();
+
+ int[] smProps = null;
+ int num = 0;
+ final int idxBpp = 1 // native mode
+ + 1 // count
+ + ScreenModeUtil.NUM_RESOLUTION_PROPERTIES
+ + ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES
+ - 1 ; // index 0 based
+ do {
+ if(DEBUG_TEST_SCREENMODE_DISABLED) {
+ smProps = null;
+ } else if(0 == num) {
+ smProps = getScreenModeFirstImpl();
+ } else {
+ smProps = getScreenModeNextImpl();
+ }
+ if(null != smProps && 0 < smProps.length && smProps[idxBpp] >= 15) {
+ int nativeId = smProps[0];
+ int screenModeIdx = ScreenModeUtil.streamIn(resolutionPool, surfaceSizePool, screenSizeMMPool,
+ monitorModePool, screenModePool, smProps, 1);
+ if(screenModeIdx >= 0) {
+ screenModesIdx2NativeId.put(screenModeIdx, nativeId);
+ }
+ }
+ num++;
+ } while ( null != smProps && 0 < smProps.length );
+
+ if(DEBUG) {
+ System.err.println("ScreenImpl.collectNativeScreenModes: ScreenMode number : "+screenModePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: MonitorMode number : "+monitorModePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: ScreenSizeMM number: "+screenSizeMMPool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: SurfaceSize number : "+surfaceSizePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: Resolution number : "+resolutionPool.size());
+ }
+
+ return screenModePool;
+ }
+
+ private void releaseScreenModeStatus() {
+ ScreenModeStatus sms;
+ ScreenModeStatus.lockScreenModeStatus();
+ try {
+ sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null != sms) {
+ sms.lock();
+ try {
+ if(0 == sms.removeListener(this)) {
+ if(!sms.isOriginalMode()) {
+ setCurrentScreenMode(sms.getOriginalScreenMode());
+ }
+ ScreenModeStatus.unmapScreenModeStatus(this.getFQName());
+ }
+ } finally {
+ sms.unlock();
+ }
+ }
+ } finally {
+ ScreenModeStatus.unlockScreenModeStatus();
+ }
+ }
+}
+
diff --git a/src/newt/classes/jogamp/newt/ScreenModeStatus.java b/src/newt/classes/jogamp/newt/ScreenModeStatus.java
new file mode 100644
index 000000000..3ca9b638b
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/ScreenModeStatus.java
@@ -0,0 +1,207 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.ScreenModeListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class ScreenModeStatus {
+ private static boolean DEBUG = Screen.DEBUG;
+
+ private RecursiveLock lock = new RecursiveLock();
+ private ArrayHashSet/*<ScreenMode>*/ screenModes;
+ private IntIntHashMap screenModesIdx2NativeIdx;
+ private ScreenMode currentScreenMode;
+ private ScreenMode originalScreenMode;
+ private ArrayList/*<ScreenModeChangeListener>*/ listener = new ArrayList();
+
+ private static HashMap screenFQN2ScreenModeStatus = new HashMap();
+ private static RecursiveLock screen2ScreenModeStatusLock = new RecursiveLock();
+
+ protected static void mapScreenModeStatus(String screenFQN, ScreenModeStatus sms) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ ScreenModeStatus _sms = (ScreenModeStatus) screenFQN2ScreenModeStatus.get(screenFQN);
+ if( null != _sms ) {
+ throw new RuntimeException("ScreenModeStatus "+_sms+" already mapped to "+screenFQN);
+ }
+ screenFQN2ScreenModeStatus.put(screenFQN, sms);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.map "+screenFQN+" -> "+sms);
+ }
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ /**
+ * @param screen the prev user
+ * @return true if mapping is empty, ie no more usage of the mapped ScreenModeStatus
+ */
+ protected static void unmapScreenModeStatus(String screenFQN) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ ScreenModeStatus sms = (ScreenModeStatus) screenFQN2ScreenModeStatus.remove(screenFQN);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.unmap "+screenFQN+" -> "+sms);
+ }
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ protected static ScreenModeStatus getScreenModeStatus(String screenFQN) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ return (ScreenModeStatus) screenFQN2ScreenModeStatus.get(screenFQN);
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ protected static void lockScreenModeStatus() {
+ screen2ScreenModeStatusLock.lock();
+ }
+
+ protected static void unlockScreenModeStatus() {
+ screen2ScreenModeStatusLock.unlock();
+ }
+
+ public ScreenModeStatus(ArrayHashSet/*<ScreenMode>*/ screenModes,
+ IntIntHashMap screenModesIdx2NativeIdx) {
+ this.screenModes = screenModes;
+ this.screenModesIdx2NativeIdx = screenModesIdx2NativeIdx;
+ }
+
+ protected final void setOriginalScreenMode(ScreenMode originalScreenMode) {
+ this.originalScreenMode = originalScreenMode;
+ this.currentScreenMode = originalScreenMode;
+ }
+
+ public final ScreenMode getOriginalScreenMode() {
+ return originalScreenMode;
+ }
+
+ public final ScreenMode getCurrentScreenMode() {
+ lock();
+ try {
+ return currentScreenMode;
+ } finally {
+ unlock();
+ }
+ }
+
+ public final boolean isOriginalMode() {
+ lock();
+ try {
+ if(null != currentScreenMode && null != originalScreenMode) {
+ return currentScreenMode.hashCode() == originalScreenMode.hashCode();
+ }
+ return true;
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final ArrayHashSet/*<ScreenMode>*/ getScreenModes() {
+ return screenModes;
+ }
+
+ protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
+ return screenModesIdx2NativeIdx;
+ }
+
+ protected final int addListener(ScreenModeListener l) {
+ lock();
+ try {
+ listener.add(l);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.addListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final int removeListener(ScreenModeListener l) {
+ lock();
+ try {
+ if(!listener.remove(l)) {
+ throw new RuntimeException("ScreenModeListener "+l+" not contained");
+ }
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.removeListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final void fireScreenModeChangeNotify(ScreenMode desiredScreenMode) {
+ lock();
+ try {
+ for(int i=0; i<listener.size(); i++) {
+ ((ScreenModeListener)listener.get(i)).screenModeChangeNotify(desiredScreenMode);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected void fireScreenModeChanged(ScreenMode currentScreenMode, boolean success) {
+ lock();
+ try {
+ if(success) {
+ this.currentScreenMode = currentScreenMode;
+ }
+ for(int i=0; i<listener.size(); i++) {
+ ((ScreenModeListener)listener.get(i)).screenModeChanged(currentScreenMode, success);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final void lock() throws RuntimeException {
+ lock.lock();
+ }
+
+ protected final void unlock() throws RuntimeException {
+ lock.unlock();
+ }
+
+}
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
new file mode 100644
index 000000000..74186f70f
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -0,0 +1,2230 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import java.util.ArrayList;
+import java.lang.reflect.Method;
+
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.Window;
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.NEWTEvent;
+import com.jogamp.newt.event.NEWTEventConsumer;
+import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
+import com.jogamp.newt.event.WindowUpdateEvent;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.CapabilitiesChooser;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.util.DimensionReadOnly;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Rectangle;
+
+public abstract class WindowImpl implements Window, NEWTEventConsumer
+{
+ public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
+
+ private RecursiveLock windowLock = new RecursiveLock();
+ private long windowHandle;
+ private ScreenImpl screen;
+ private boolean screenReferenceAdded = false;
+ private NativeWindow parentWindow;
+ private long parentWindowHandle;
+ protected AbstractGraphicsConfiguration config;
+ protected CapabilitiesImmutable capsRequested;
+ protected CapabilitiesChooser capabilitiesChooser = null; // default null -> default
+ protected boolean fullscreen, visible, hasFocus;
+ protected int width, height, x, y;
+ protected int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen dimensions ..
+ protected String title = "Newt Window";
+ protected boolean undecorated = false;
+ private LifecycleHook lifecycleHook = null;
+
+ private DestroyAction destroyAction = new DestroyAction();
+ private boolean handleDestroyNotify = true;
+
+ private ReparentActionRecreate reparentActionRecreate = new ReparentActionRecreate();
+
+ private RequestFocusAction requestFocusAction = new RequestFocusAction();
+ private FocusRunnable focusAction = null;
+
+ private Object surfaceUpdatedListenersLock = new Object();
+ private ArrayList surfaceUpdatedListeners;
+
+ private Object childWindowsLock = new Object();
+ private ArrayList childWindows;
+
+ private ArrayList mouseListeners;
+ private int mouseButtonPressed; // current pressed mouse button number
+ private long lastMousePressed; // last time when a mouse button was pressed
+ private int lastMouseClickCount; // last mouse button click count
+
+ private ArrayList keyListeners;
+
+ private ArrayList windowListeners;
+ private boolean repaintQueued = false;
+
+ ScreenModeListenerImpl screenModeListenerImpl = new ScreenModeListenerImpl();
+
+ private void initializeStates() {
+ invalidate(true);
+
+ childWindows = new ArrayList();
+ surfaceUpdatedListeners = new ArrayList();
+ windowListeners = new ArrayList();
+ mouseListeners = new ArrayList();
+
+ mouseButtonPressed = 0; // current pressed mouse button number
+ lastMousePressed = 0; // last time when a mouse button was pressed
+ lastMouseClickCount = 0; // last mouse button click count
+ keyListeners = new ArrayList();
+ }
+
+ // Workaround for initialization order problems on Mac OS X
+ // between native Newt and (apparently) Fmod -- if Fmod is
+ // initialized first then the connection to the window server
+ // breaks, leading to errors from deep within the AppKit
+ public static void init(String type) {
+ if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
+ try {
+ getWindowClass(type);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ //
+ // Construction Methods
+ //
+
+ private static Class getWindowClass(String type)
+ throws ClassNotFoundException
+ {
+ Class windowClass = NewtFactory.getCustomClass(type, "Window");
+ if(null==windowClass) {
+ if (NativeWindowFactory.TYPE_EGL.equals(type)) {
+ windowClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDWindow");
+ } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
+ windowClass = Class.forName("com.jogamp.newt.impl.windows.WindowsWindow");
+ } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
+ windowClass = Class.forName("com.jogamp.newt.impl.macosx.MacWindow");
+ } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
+ windowClass = Class.forName("com.jogamp.newt.impl.x11.X11Window");
+ } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
+ windowClass = Class.forName("com.jogamp.newt.impl.awt.AWTWindow");
+ } else {
+ throw new NativeWindowException("Unknown window type \"" + type + "\"");
+ }
+ }
+ return windowClass;
+ }
+
+ public static WindowImpl create(NativeWindow parentWindow, long parentWindowHandle, Screen screen, CapabilitiesImmutable caps) {
+ try {
+ Class windowClass;
+ if(caps.isOnscreen()) {
+ windowClass = getWindowClass(screen.getDisplay().getType());
+ } else {
+ windowClass = OffscreenWindow.class;
+ }
+ WindowImpl window = (WindowImpl) windowClass.newInstance();
+ window.initializeStates();
+ window.parentWindow = parentWindow;
+ window.parentWindowHandle = parentWindowHandle;
+ window.screen = (ScreenImpl) screen;
+ window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
+ window.setUndecorated(0!=parentWindowHandle);
+ return window;
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw new NativeWindowException(t);
+ }
+ }
+
+ public static WindowImpl create(Object[] cstrArguments, Screen screen, CapabilitiesImmutable caps) {
+ try {
+ Class windowClass = getWindowClass(screen.getDisplay().getType());
+ Class[] cstrArgumentTypes = getCustomConstructorArgumentTypes(windowClass);
+ if(null==cstrArgumentTypes) {
+ throw new NativeWindowException("WindowClass "+windowClass+" doesn't support custom arguments in constructor");
+ }
+ int argsChecked = verifyConstructorArgumentTypes(cstrArgumentTypes, cstrArguments);
+ if ( argsChecked < cstrArguments.length ) {
+ throw new NativeWindowException("WindowClass "+windowClass+" constructor mismatch at argument #"+argsChecked+"; Constructor: "+getTypeStrList(cstrArgumentTypes)+", arguments: "+getArgsStrList(cstrArguments));
+ }
+ WindowImpl window = (WindowImpl) ReflectionUtil.createInstance( windowClass, cstrArgumentTypes, cstrArguments ) ;
+ window.initializeStates();
+ window.screen = (ScreenImpl) screen;
+ window.capsRequested = (CapabilitiesImmutable) caps.cloneMutable();
+ return window;
+ } catch (Throwable t) {
+ throw new NativeWindowException(t);
+ }
+ }
+
+ public static interface LifecycleHook {
+ /**
+ * Reset of internal state counter, ie totalFrames, etc.
+ * Called from EDT while window is locked.
+ */
+ public abstract void resetCounter();
+
+ /**
+ * Invoked after Window setVisible,
+ * allows allocating resources depending on the native Window.
+ * Called from EDT while window is locked.
+ */
+ void setVisibleActionPost(boolean visible, boolean nativeWindowCreated);
+
+ /**
+ * Invoked before Window destroy action,
+ * allows releasing of resources depending on the native Window.<br>
+ * Surface not locked yet.<br>
+ * Called not necessarily from EDT.
+ */
+ void destroyActionPreLock();
+
+ /**
+ * Invoked before Window destroy action,
+ * allows releasing of resources depending on the native Window.<br>
+ * Surface locked.<br>
+ * Called from EDT while window is locked.
+ */
+ void destroyActionInLock();
+
+ /**
+ * Invoked after destruction from Window's invalidate method.<br>
+ * Called while window is locked.
+ * @param unrecoverable
+ */
+ void invalidate(boolean unrecoverable);
+
+ /**
+ * Invoked for expensive modifications, ie while reparenting and ScreenMode change.<br>
+ * No lock is hold when invoked.<br>
+ *
+ * @return true is paused, otherwise false. If true {@link #resumeRenderingAction()} shall be issued.
+ *
+ * @see #resumeRenderingAction()
+ */
+ boolean pauseRenderingAction();
+
+ /**
+ * Invoked for expensive modifications, ie while reparenting and ScreenMode change.
+ * No lock is hold when invoked.<br>
+ *
+ * @see #pauseRenderingAction()
+ */
+ void resumeRenderingAction();
+ }
+
+ private boolean createNative() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")");
+ }
+ if( null != parentWindow &&
+ NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindow.lockSurface() ) {
+ throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
+ }
+ try {
+ if(validateParentWindowHandle()) {
+ if(screenReferenceAdded) {
+ throw new InternalError("XXX");
+ }
+ screen.addReference();
+ screenReferenceAdded = true;
+ createNativeImpl();
+ setVisibleImpl(true, x, y, width, height);
+ screen.addScreenModeListener(screenModeListenerImpl);
+ setTitleImpl(title);
+ }
+ } finally {
+ if(null!=parentWindow) {
+ parentWindow.unlockSurface();
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.createNative() END ("+getThreadName()+", "+this+")");
+ }
+ return 0 != windowHandle ;
+ }
+
+ private void removeScreenReference() {
+ if(screenReferenceAdded) {
+ // be nice, probably already called recursive via
+ // closeAndInvalidate() -> closeNativeIml() -> .. -> windowDestroyed() -> closeAndInvalidate() !
+ // or via reparentWindow .. etc
+ screenReferenceAdded = false;
+ screen.removeReference();
+ }
+ }
+
+ private void closeAndInvalidate() {
+ windowLock.lock();
+ try {
+ if( null != screen ) {
+ if( 0 != windowHandle ) {
+ screen.removeScreenModeListener(screenModeListenerImpl);
+ closeNativeImpl();
+ removeScreenReference();
+ }
+ Display dpy = screen.getDisplay();
+ if(null != dpy) {
+ dpy.validateEDT();
+ }
+ }
+ invalidate(false);
+ } finally {
+ windowLock.unlock();
+ }
+ }
+
+ private boolean validateParentWindowHandle() {
+ if(null!=parentWindow) {
+ parentWindowHandle = getNativeWindowHandle(parentWindow);
+ return 0 != parentWindowHandle ;
+ }
+ return true;
+ }
+
+ private static long getNativeWindowHandle(NativeWindow nativeWindow) {
+ long handle = 0;
+ if(null!=nativeWindow) {
+ boolean wasLocked = false;
+ if( NativeSurface.LOCK_SURFACE_NOT_READY < nativeWindow.lockSurface() ) {
+ wasLocked = true;
+ try {
+ handle = nativeWindow.getWindowHandle();
+ if(0==handle) {
+ throw new NativeWindowException("Parent native window handle is NULL, after succesful locking: "+nativeWindow);
+ }
+ } catch (NativeWindowException nwe) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.getNativeWindowHandle: not successful yet: "+nwe);
+ }
+ } finally {
+ nativeWindow.unlockSurface();
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.getNativeWindowHandle: locked "+wasLocked+", "+nativeWindow);
+ }
+ }
+ return handle;
+ }
+
+
+ //----------------------------------------------------------------------
+ // NativeSurface: Native implementation
+ //
+
+ protected int lockSurfaceImpl() { return LOCK_SUCCESS; }
+
+ protected void unlockSurfaceImpl() { }
+
+ //----------------------------------------------------------------------
+ // WindowClosingProtocol implementation
+ //
+ private Object closingListenerLock = new Object();
+ private int defaultCloseOperation = DISPOSE_ON_CLOSE;
+
+ public int getDefaultCloseOperation() {
+ synchronized (closingListenerLock) {
+ return defaultCloseOperation;
+ }
+ }
+
+ public int setDefaultCloseOperation(int op) {
+ synchronized (closingListenerLock) {
+ int _op = defaultCloseOperation;
+ defaultCloseOperation = op;
+ return _op;
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Window: Native implementation
+ //
+
+ /**
+ * The native implementation must set the native windowHandle.<br>
+ *
+ * The implementation should invoke the referenced java state callbacks
+ * to notify this Java object of state changes.
+ *
+ * @see #windowDestroyNotify()
+ * @see #focusChanged(boolean)
+ * @see #visibleChanged(boolean)
+ * @see #sizeChanged(int,int)
+ * @see #positionChanged(int,int)
+ * @see #windowDestroyNotify()
+ */
+ protected abstract void createNativeImpl();
+
+ protected abstract void closeNativeImpl();
+
+ /**
+ * The native implementation must invoke {@link #focusChanged(boolean)}
+ * to change the focus state, if <code>force == false</code>.
+ * This may happen asynchronous within {@link #TIMEOUT_NATIVEWINDOW}.
+ *
+ * @param force if true, bypass {@link #focusChanged(boolean)} and force focus request
+ */
+ protected abstract void requestFocusImpl(boolean force);
+
+ /**
+ * The native implementation must invoke {@link #visibleChanged(boolean)}
+ * to change the visibility state. This may happen asynchronous within
+ * {@link #TIMEOUT_NATIVEWINDOW}.
+ */
+ protected abstract void setVisibleImpl(boolean visible, int x, int y, int width, int height);
+
+ /**
+ * The native implementation should invoke the referenced java state callbacks
+ * to notify this Java object of state changes.
+ *
+ * @param x -1 if no position change requested, otherwise greater than zero
+ * @param y -1 if no position change requested, otherwise greater than zero
+ * @param width -1 if no size change requested, otherwise greater than zero
+ * @param height -1 if no size change requested, otherwise greater than zero
+ * @param parentChange true if reparenting requested, otherwise false
+ * @param fullScreenChange 0 if unchanged, -1 fullscreen off, 1 fullscreen on
+ * @param decorationChange 0 if unchanged, -1 undecorated, 1 decorated
+ *
+ * @see #sizeChanged(int,int)
+ * @see #positionChanged(int,int)
+ */
+ protected abstract boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange);
+
+ protected void setTitleImpl(String title) {}
+
+ /**
+ * Return screen coordinates of the given coordinates
+ * or null, in which case a NativeWindow traversal shall being used
+ * as demonstrated in {@link #getLocationOnScreen(javax.media.nativewindow.util.Point)}.
+ *
+ * @return if not null, the screen location of the given coordinates
+ */
+ protected abstract Point getLocationOnScreenImpl(int x, int y);
+
+ //----------------------------------------------------------------------
+ // NativeSurface
+ //
+
+ public final int lockSurface() {
+ int res = LOCK_SURFACE_NOT_READY;
+ windowLock.lock();
+
+ if(isNativeValid()) {
+ AbstractGraphicsDevice adevice = screen.getDisplay().getGraphicsDevice();
+ adevice.lock();
+ try {
+ res = lockSurfaceImpl();
+ } finally {
+ if( LOCK_SURFACE_NOT_READY == res ) {
+ adevice.unlock();
+ }
+ }
+ }
+ if( LOCK_SURFACE_NOT_READY == res ) {
+ windowLock.unlock();
+ }
+
+ return res;
+ }
+
+ public final void unlockSurface() {
+ // may throw RuntimeException if not locked
+ windowLock.validateLocked();
+ AbstractGraphicsDevice adevice = screen.getDisplay().getGraphicsDevice();
+
+ try {
+ unlockSurfaceImpl();
+ } finally {
+ adevice.unlock();
+ }
+ windowLock.unlock();
+ }
+
+ public final boolean isSurfaceLockedByOtherThread() {
+ return windowLock.isLockedByOtherThread();
+ }
+
+ public final boolean isSurfaceLocked() {
+ return windowLock.isLocked();
+ }
+
+ public final Thread getSurfaceLockOwner() {
+ return windowLock.getOwner();
+ }
+
+ public long getSurfaceHandle() {
+ return windowHandle; // default: return window handle
+ }
+
+ public boolean surfaceSwap() {
+ return false;
+ }
+
+ public AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config;
+ }
+
+ public final long getDisplayHandle() {
+ return getScreen().getDisplay().getHandle();
+ }
+
+ public final int getScreenIndex() {
+ return getScreen().getIndex();
+ }
+
+ //----------------------------------------------------------------------
+ // NativeWindow
+ //
+
+ // public final void destroy() - see below
+
+ public final NativeWindow getParent() {
+ return parentWindow;
+ }
+
+ public final long getWindowHandle() {
+ return windowHandle;
+ }
+
+ public Point getLocationOnScreen(Point storage) {
+ if(isNativeValid()) {
+ Point d;
+ windowLock.lock();
+ try {
+ d = getLocationOnScreenImpl(0, 0);
+ } finally {
+ windowLock.unlock();
+ }
+ if(null!=d) {
+ if(null!=storage) {
+ storage.translate(d.getX(),d.getY());
+ return storage;
+ }
+ return d;
+ }
+ // fall through intended ..
+ }
+
+ if(null!=storage) {
+ storage.translate(getX(),getY());
+ } else {
+ storage = new Point(getX(),getY());
+ }
+ if(null!=parentWindow) {
+ // traverse through parent list ..
+ parentWindow.getLocationOnScreen(storage);
+ }
+ return storage;
+ }
+
+ //----------------------------------------------------------------------
+ // Window
+ //
+
+ public final boolean isNativeValid() {
+ return null != getScreen() && 0 != getWindowHandle() ;
+ }
+
+ public final boolean isValid() {
+ return null != getScreen() ;
+ }
+
+ public final Screen getScreen() {
+ return screen;
+ }
+
+ class VisibleAction implements Runnable {
+ boolean visible;
+ boolean nativeWindowCreated;
+ boolean madeVisible;
+
+ public VisibleAction (boolean visible) {
+ this.visible = visible;
+ this.nativeWindowCreated = false;
+ this.madeVisible = false;
+ }
+
+ public final boolean getNativeWindowCreated() { return nativeWindowCreated; }
+ public final boolean getBecameVisible() { return madeVisible; }
+ public final boolean getChanged() { return nativeWindowCreated || madeVisible; }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(null!=lifecycleHook) {
+ lifecycleHook.resetCounter();
+ }
+
+ if(!visible && null!=childWindows && childWindows.size()>0) {
+ synchronized(childWindowsLock) {
+ for(int i = 0; i < childWindows.size(); i++ ) {
+ NativeWindow nw = (NativeWindow) childWindows.get(i);
+ if(nw instanceof WindowImpl) {
+ ((WindowImpl)nw).setVisible(false);
+ }
+ }
+ }
+ }
+ if(0==windowHandle && visible) {
+ if( 0<width*height ) {
+ nativeWindowCreated = createNative();
+ WindowImpl.this.waitForVisible(visible, true);
+ madeVisible = visible;
+ }
+ } else if(WindowImpl.this.visible != visible) {
+ if(0 != windowHandle) {
+ setVisibleImpl(visible, x, y, width, height);
+ WindowImpl.this.waitForVisible(visible, true);
+ madeVisible = visible;
+ }
+ }
+
+ if(null!=lifecycleHook) {
+ lifecycleHook.setVisibleActionPost(visible, nativeWindowCreated);
+ }
+
+ if(0!=windowHandle && visible && null!=childWindows && childWindows.size()>0) {
+ synchronized(childWindowsLock) {
+ for(int i = 0; i < childWindows.size(); i++ ) {
+ NativeWindow nw = (NativeWindow) childWindows.get(i);
+ if(nw instanceof WindowImpl) {
+ ((WindowImpl)nw).setVisible(true);
+ }
+ }
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+", nativeWindowCreated: "+nativeWindowCreated+", madeVisible: "+madeVisible);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ if( getChanged() ) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ if(isValid()) {
+ if( 0==windowHandle && visible && 0>=width*height ) {
+ // fast-path: not realized yet, make visible, but zero size
+ return;
+ }
+
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow)/*+", "+this*/);
+ System.err.println(msg);
+ Thread.dumpStack();
+ }
+ VisibleAction visibleAction = new VisibleAction(visible);
+ runOnEDTIfAvail(true, visibleAction);
+ }
+ }
+
+ class SetSizeActionImpl implements Runnable {
+ int visibleAction = 0; // 1 invisible, 2 visible (create)
+ int width, height;
+
+ public int getVisibleAction() {
+ return visibleAction;
+ }
+ public SetSizeActionImpl(int w, int h) {
+ width = w;
+ height = h;
+ }
+ public void run() {
+ windowLock.lock();
+ try {
+ if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
+ System.err.println(msg);
+ }
+ if ( 0 != windowHandle && 0>=width*height && visible ) {
+ visibleAction=1; // invisible
+ WindowImpl.this.width = 0;
+ WindowImpl.this.height = 0;
+ } else if ( 0 == windowHandle && 0<width*height && visible ) {
+ visibleAction = 2; // visible (create)
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ } else if ( 0 != windowHandle ) {
+ // this width/height will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ } else {
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction);
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void setSize(int width, int height) {
+ if(isValid()) {
+ SetSizeActionImpl setSizeAction = new SetSizeActionImpl(width, height);
+ runOnEDTIfAvail(true, setSizeAction);
+ switch(setSizeAction.getVisibleAction()) {
+ case 1: setVisible(false); break;
+ case 2: setVisible(true); break;
+ }
+ }
+ }
+
+ class DestroyAction implements Runnable {
+ public void run() {
+ windowLock.lock();
+ try {
+ if( !isValid() ) {
+ return; // nop
+ }
+
+ // Childs first ..
+ synchronized(childWindowsLock) {
+ if(childWindows.size()>0) {
+ // avoid ConcurrentModificationException: parent -> child -> parent.removeChild(this)
+ ArrayList clonedChildWindows = (ArrayList) childWindows.clone();
+ while( clonedChildWindows.size() > 0 ) {
+ NativeWindow nw = (NativeWindow) clonedChildWindows.remove(0);
+ if(nw instanceof WindowImpl) {
+ ((WindowImpl)nw).sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
+ ((WindowImpl)nw).destroy();
+ } else {
+ nw.destroy();
+ }
+ }
+ }
+ }
+
+ if(null!=lifecycleHook) {
+ // send synced destroy notification for proper cleanup, eg GLWindow/OpenGL
+ lifecycleHook.destroyActionInLock();
+ }
+
+ closeAndInvalidate();
+
+ // send synced destroyed notification
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROYED);
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.destroy() END "+getThreadName()/*+", "+WindowImpl.this*/);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void destroy() {
+ if( isValid() ) {
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window.destroy() START "+getThreadName()/*+", "+this*/);
+ System.err.println(msg);
+ //Exception ee = new Exception(msg);
+ //ee.printStackTrace();
+ }
+ boolean animatorPaused = false;
+ if(null!=lifecycleHook) {
+ animatorPaused = lifecycleHook.pauseRenderingAction();
+ }
+ if(null!=lifecycleHook) {
+ lifecycleHook.destroyActionPreLock();
+ }
+ runOnEDTIfAvail(true, destroyAction);
+ if(animatorPaused) {
+ lifecycleHook.resumeRenderingAction();
+ }
+ }
+ }
+
+ public final void invalidate() {
+ destroy();
+ invalidate(true);
+ }
+
+ /**
+ * @param unrecoverable If true, all states, size, position, parent handles,
+ * reference to it's Screen are reset.
+ * Otherwise you can recreate the window, via <code>setVisible(true)</code>.
+ * @see #invalidate()
+ * @see #destroy()
+ * @see #destroy(boolean)
+ */
+ protected void invalidate(boolean unrecoverable) {
+ windowLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ String msg = new String("!!! Window Invalidate(unrecoverable: "+unrecoverable+") "+getThreadName());
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ }
+
+ // Childs first ..
+ synchronized(childWindowsLock) {
+ // avoid ConcurrentModificationException: parent -> child -> parent.removeChild(this)
+ if(null!=childWindows && childWindows.size()>0) {
+ ArrayList clonedChildWindows = (ArrayList) childWindows.clone();
+ while( clonedChildWindows.size() > 0 ) {
+ NativeWindow nw = (NativeWindow) clonedChildWindows.remove(0);
+ if(nw instanceof WindowImpl) {
+ ((WindowImpl)nw).invalidate(unrecoverable);
+ }
+ }
+ }
+ }
+
+ if(null!=lifecycleHook) {
+ lifecycleHook.invalidate(unrecoverable);
+ }
+
+ windowHandle = 0;
+ visible = false;
+ fullscreen = false;
+ hasFocus = false;
+
+ if(unrecoverable) {
+ if(null!=parentWindow && parentWindow instanceof Window) {
+ ((Window)parentWindow).removeChild(WindowImpl.this);
+ }
+ screen = null;
+
+ synchronized(childWindowsLock) {
+ childWindows = null;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners = null;
+ }
+ windowListeners = null;
+ mouseListeners = null;
+ keyListeners = null;
+
+ parentWindowHandle = 0;
+ parentWindow = null;
+ capsRequested = null;
+ lifecycleHook = null;
+
+ // Default position and dimension will be re-set immediately by user
+ width = 128;
+ height = 128;
+ x=0;
+ y=0;
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+
+ class ReparentActionImpl implements Runnable, ReparentAction {
+ NativeWindow newParentWindow;
+ boolean forceDestroyCreate;
+ int reparentAction;
+
+ public ReparentActionImpl(NativeWindow newParentWindow, boolean forceDestroyCreate) {
+ this.newParentWindow = newParentWindow;
+ this.forceDestroyCreate = forceDestroyCreate;
+ this.reparentAction = -1; // ensure it's set
+ }
+
+ public final int getStrategy() {
+ return reparentAction;
+ }
+
+ private final void setScreen(ScreenImpl newScreen) {
+ WindowImpl.this.removeScreenReference();
+ screen = newScreen;
+ }
+
+ public void run() {
+ boolean wasVisible;
+
+ // mirror pos/size so native change notification can get overwritten
+ int x = WindowImpl.this.x;
+ int y = WindowImpl.this.y;
+ int width = WindowImpl.this.width;
+ int height = WindowImpl.this.height;
+
+ windowLock.lock();
+ try {
+ wasVisible = isVisible();
+
+ Window newParentWindowNEWT = null;
+ if(newParentWindow instanceof Window) {
+ newParentWindowNEWT = (Window) newParentWindow;
+ }
+
+ long newParentWindowHandle = 0 ;
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE+" "+x+"/"+y+" "+width+"x"+height);
+ }
+
+ if(null!=lifecycleHook) {
+ lifecycleHook.resetCounter();
+ }
+
+ if(null!=newParentWindow) {
+ // reset position to 0/0 within parent space
+ x = 0;
+ y = 0;
+
+ // refit if size is bigger than parent
+ if( width > newParentWindow.getWidth() ) {
+ width = newParentWindow.getWidth();
+ }
+ if( height > newParentWindow.getHeight() ) {
+ height = newParentWindow.getHeight();
+ }
+
+ // Case: Child Window
+ newParentWindowHandle = getNativeWindowHandle(newParentWindow);
+ if(0 == newParentWindowHandle) {
+ // Case: Parent's native window not realized yet
+ if(null==newParentWindowNEWT) {
+ throw new NativeWindowException("Reparenting with non NEWT Window type only available after it's realized: "+newParentWindow);
+ }
+ // Destroy this window and use parent's Screen.
+ // It may be created properly when the parent is made visible.
+ destroy();
+ setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
+ reparentAction = ACTION_NATIVE_CREATION_PENDING;
+ } else if(newParentWindow != getParent()) {
+ // Case: Parent's native window realized and changed
+ if( !isNativeValid() ) {
+ // May create a new compatible Screen/Display and
+ // mark it for creation.
+ if(null!=newParentWindowNEWT) {
+ setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
+ } else {
+ Screen newScreen = NewtFactory.createCompatibleScreen(newParentWindow, getScreen());
+ if( getScreen() != newScreen ) {
+ // auto destroy on-the-fly created Screen/Display
+ setScreen( (ScreenImpl) newScreen );
+ }
+ }
+ if( 0<width*height ) {
+ reparentAction = ACTION_NATIVE_CREATION;
+ } else {
+ reparentAction = ACTION_NATIVE_CREATION_PENDING;
+ }
+ } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ||
+ !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
+ // Destroy this window, may create a new compatible Screen/Display,
+ // and mark it for creation.
+ destroy();
+ if(null!=newParentWindowNEWT) {
+ setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
+ } else {
+ setScreen( (ScreenImpl) NewtFactory.createCompatibleScreen(newParentWindow, getScreen()) );
+ }
+ reparentAction = ACTION_NATIVE_CREATION;
+ } else {
+ // Mark it for native reparenting
+ reparentAction = ACTION_NATIVE_REPARENTING;
+ }
+ } else {
+ // Case: Parent's native window realized and not changed
+ reparentAction = ACTION_UNCHANGED;
+ }
+ } else {
+ if( null != parentWindow ) {
+ // child -> top
+ // put client to current parent+child position
+ Point p = getLocationOnScreen(null);
+ x = p.getX();
+ y = p.getY();
+ }
+
+ // Case: Top Window
+ if( 0 == getParentWindowHandle() ) {
+ // Already Top Window
+ reparentAction = ACTION_UNCHANGED;
+ } else if( !isNativeValid() || DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) {
+ // Destroy this window and mark it for [pending] creation.
+ destroy();
+ if( 0<width*height ) {
+ reparentAction = ACTION_NATIVE_CREATION;
+ } else {
+ reparentAction = ACTION_NATIVE_CREATION_PENDING;
+ }
+ } else {
+ // Mark it for native reparenting
+ reparentAction = ACTION_NATIVE_REPARENTING;
+ }
+ }
+ parentWindowHandle = newParentWindowHandle;
+
+ if ( ACTION_UNCHANGED > reparentAction ) {
+ throw new NativeWindowException("Internal Error: reparentAction not set");
+ }
+
+ if( ACTION_UNCHANGED == reparentAction ) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: NO CHANGE ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", visible "+wasVisible);
+ }
+ return;
+ }
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: ACTION ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", reparentAction "+reparentAction+", visible "+wasVisible);
+ }
+
+ // rearrange window tree
+ if(null!=parentWindow && parentWindow instanceof Window) {
+ ((Window)parentWindow).removeChild(WindowImpl.this);
+ }
+ parentWindow = newParentWindow;
+ if(parentWindow instanceof Window) {
+ ((Window)parentWindow).addChild(WindowImpl.this);
+ }
+
+ if( ACTION_NATIVE_CREATION_PENDING == reparentAction ) {
+ return;
+ }
+
+ if( ACTION_NATIVE_REPARENTING == reparentAction ) {
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
+ if(wasVisible) {
+ setVisibleImpl(false, x, y, width, height);
+ WindowImpl.this.waitForVisible(false, true);
+ }
+
+ // Lock parentWindow only during reparenting (attempt)
+ NativeWindow parentWindowLocked = null;
+ if( null != parentWindow ) {
+ parentWindowLocked = parentWindow;
+ if( NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) {
+ throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
+ }
+ }
+ boolean ok = false;
+ try {
+ // write back mirrored values, to be able to detect satisfaction
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ ok = reconfigureWindowImpl(x, y, width, height, true, 0, isUndecorated()?-1:1);
+ } finally {
+ if(null!=parentWindowLocked) {
+ parentWindowLocked.unlockSurface();
+ }
+ }
+
+ // set visible again, and revalidate 'ok',
+ // since it has been experience that in some cases the reparented window gets hidden
+ if(ok) {
+ display.dispatchMessagesNative(); // status up2date
+ if(wasVisible) {
+ setVisibleImpl(true, x, y, width, height);
+ ok = WindowImpl.this.waitForVisible(true, false);
+ display.dispatchMessagesNative(); // status up2date
+ if( ok &&
+ ( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != width ||
+ WindowImpl.this.height != height ) )
+ {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent (reconfig)");
+ }
+ // reset pos/size .. due to some native impl flakyness
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ display.dispatchMessagesNative(); // status up2date
+ WindowImpl.this.waitForVisible(true, false);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ }
+ }
+
+ if(ok) {
+ if(wasVisible) {
+ requestFocusImpl(true);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ } else {
+ // native reparent failed -> try creation
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: native reparenting failed ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentWindowHandle)+" - Trying recreation");
+ }
+ destroy();
+ reparentAction = ACTION_NATIVE_CREATION ;
+ }
+ }
+
+ // write back mirrored values, ensuring persitence
+ // and not relying on native messaging
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+x+"/"+y+" "+width+"x"+height);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+
+ if(wasVisible) {
+ switch (reparentAction) {
+ case ACTION_NATIVE_REPARENTING:
+ // trigger a resize/relayout and repaint to listener
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
+ break;
+
+ case ACTION_NATIVE_CREATION:
+ // This may run on the Display/Screen connection,
+ // hence a new EDT task
+ runOnEDTIfAvail(true, reparentActionRecreate);
+ break;
+ }
+ }
+ }
+ }
+
+ class ReparentActionRecreate implements Runnable {
+ public void run() {
+ windowLock.lock();
+ try {
+ visible = true;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparentWindow: ReparentActionRecreate ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+Display.hashCodeNullSafe(parentWindow));
+ }
+ setVisible(true); // native creation
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public final int reparentWindow(NativeWindow newParent) {
+ return reparentWindow(newParent, false);
+ }
+
+ public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
+ int reparentActionStrategy = ReparentAction.ACTION_INVALID;
+ if(isValid()) {
+ boolean animatorPaused = false;
+ if(null!=lifecycleHook) {
+ animatorPaused = lifecycleHook.pauseRenderingAction();
+ }
+ try {
+ ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
+ runOnEDTIfAvail(true, reparentAction);
+ reparentActionStrategy = reparentAction.getStrategy();
+ } finally {
+ if(animatorPaused) {
+ lifecycleHook.resumeRenderingAction();
+ }
+ }
+ }
+ return reparentActionStrategy;
+ }
+
+ public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) {
+ CapabilitiesChooser old = this.capabilitiesChooser;
+ this.capabilitiesChooser = chooser;
+ return old;
+ }
+
+ public final CapabilitiesImmutable getChosenCapabilities() {
+ return config.getNativeGraphicsConfiguration().getChosenCapabilities();
+ }
+
+ public final CapabilitiesImmutable getRequestedCapabilities() {
+ return capsRequested;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ if (title == null) {
+ title = "";
+ }
+ this.title = title;
+ if(0 != getWindowHandle()) {
+ setTitleImpl(title);
+ }
+ }
+
+ class DecorationActionImpl implements Runnable {
+ boolean undecorated;
+
+ public DecorationActionImpl(boolean undecorated) {
+ this.undecorated = undecorated;
+ }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(!fullscreen && isNativeValid() && WindowImpl.this.undecorated != undecorated) {
+ WindowImpl.this.undecorated = undecorated;
+ // mirror pos/size so native change notification can get overwritten
+ int x = WindowImpl.this.x;
+ int y = WindowImpl.this.y;
+ int width = WindowImpl.this.width;
+ int height = WindowImpl.this.height;
+
+ if( 0 != windowHandle ) {
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
+ boolean wasVisible = isVisible();
+ setVisibleImpl(false, x, y, width, height);
+ WindowImpl.this.waitForVisible(false, true);
+ display.dispatchMessagesNative(); // status up2date
+ reconfigureWindowImpl(x, y, width, height, false, 0, undecorated?-1:1);
+ display.dispatchMessagesNative(); // status up2date
+ if(wasVisible) {
+ setVisibleImpl(true, x, y, width, height);
+ WindowImpl.this.waitForVisible(true, true);
+ display.dispatchMessagesNative(); // status up2date
+ if( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != width ||
+ WindowImpl.this.height != height )
+ {
+ // reset pos/size .. due to some native impl flakyness
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ requestFocusImpl(true);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void setUndecorated(boolean value) {
+ if(isValid()) {
+ DecorationActionImpl decorationAction = new DecorationActionImpl(value);
+ runOnEDTIfAvail(true, decorationAction);
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+
+ public boolean isUndecorated() {
+ return 0 != parentWindowHandle || undecorated || fullscreen ;
+ }
+
+ public void requestFocus() {
+ enqueueRequestFocus(true);
+ }
+
+ public boolean hasFocus() {
+ return hasFocus;
+ }
+
+ public Insets getInsets() {
+ return new Insets(0,0,0,0);
+ }
+
+ public final int getWidth() {
+ return width;
+ }
+
+ public final int getHeight() {
+ return height;
+ }
+
+ public final int getX() {
+ return x;
+ }
+
+ public final int getY() {
+ return y;
+ }
+
+ public final boolean isVisible() {
+ return visible;
+ }
+
+ public final boolean isFullscreen() {
+ return fullscreen;
+ }
+
+
+ //----------------------------------------------------------------------
+ // Window
+ //
+
+ /**
+ * If the implementation is capable of detecting a device change
+ * return true and clear the status/reason of the change.
+ */
+ public boolean hasDeviceChanged() {
+ return false;
+ }
+
+ public LifecycleHook getLifecycleHook() {
+ return lifecycleHook;
+ }
+
+ public LifecycleHook setLifecycleHook(LifecycleHook hook) {
+ LifecycleHook old = lifecycleHook;
+ lifecycleHook = hook;
+ return old;
+ }
+
+ /** If this Window actually wraps one from another toolkit such as
+ the AWT, this will return a non-null value. */
+ public Object getWrappedWindow() {
+ return null;
+ }
+
+ /**
+ * If set to true, the default value, this NEWT Window implementation will
+ * handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br>
+ * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify()}.
+ */
+ public void setHandleDestroyNotify(boolean b) {
+ handleDestroyNotify = b;
+ }
+
+ //----------------------------------------------------------------------
+ // WindowImpl
+ //
+
+ protected final long getParentWindowHandle() {
+ return parentWindowHandle;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(getClass().getName()+"[Config "+config+
+ "\n, "+screen+
+ "\n, ParentWindow "+parentWindow+
+ "\n, ParentWindowHandle "+toHexString(parentWindowHandle)+
+ "\n, WindowHandle "+toHexString(getWindowHandle())+
+ "\n, SurfaceHandle "+toHexString(getSurfaceHandle())+ " (lockedExt "+isSurfaceLockedByOtherThread()+")"+
+ "\n, Pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
+ "\n, Visible "+isVisible()+
+ "\n, Undecorated "+undecorated+
+ "\n, Fullscreen "+fullscreen+
+ "\n, WrappedWindow "+getWrappedWindow()+
+ "\n, ChildWindows "+childWindows.size());
+
+ sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" [");
+ for (int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ sb.append(surfaceUpdatedListeners.get(i)+", ");
+ }
+ sb.append("], WindowListeners num "+windowListeners.size()+" [");
+ for (int i = 0; i < windowListeners.size(); i++ ) {
+ sb.append(windowListeners.get(i)+", ");
+ }
+ sb.append("], MouseListeners num "+mouseListeners.size()+" [");
+ for (int i = 0; i < mouseListeners.size(); i++ ) {
+ sb.append(mouseListeners.get(i)+", ");
+ }
+ sb.append("], KeyListeners num "+keyListeners.size()+" [");
+ for (int i = 0; i < keyListeners.size(); i++ ) {
+ sb.append(keyListeners.get(i)+", ");
+ }
+ sb.append("] ]");
+ return sb.toString();
+ }
+
+ protected final void setWindowHandle(long handle) {
+ windowHandle = handle;
+ }
+
+ public void runOnEDTIfAvail(boolean wait, final Runnable task) {
+ Screen screen = getScreen();
+ if(null==screen) {
+ throw new RuntimeException("Null screen of inner class: "+this);
+ }
+ DisplayImpl d = (DisplayImpl) screen.getDisplay();
+ d.runOnEDTIfAvail(wait, task);
+ }
+
+ class RequestFocusAction implements Runnable {
+ public void run() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.RequestFocusAction: ("+getThreadName()+"): "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ WindowImpl.this.requestFocusImpl(false);
+ }
+ }
+
+ protected void enqueueRequestFocus(boolean wait) {
+ runOnEDTIfAvail(wait, requestFocusAction);
+ }
+
+ /**
+ * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
+ * This allows notifying a covered window toolkit like AWT that the focus is requested,
+ * hence focus traversal can be made transparent.
+ */
+ public void setFocusAction(FocusRunnable focusAction) {
+ this.focusAction = focusAction;
+ }
+ protected boolean focusAction() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.focusAction() START - "+getThreadName()+", focusAction: "+focusAction+" - windowHandle "+toHexString(getWindowHandle()));
+ }
+ boolean res;
+ if(null!=focusAction) {
+ res = focusAction.run();
+ } else {
+ res = false;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.focusAction() END - "+getThreadName()+", focusAction: "+focusAction+" - windowHandle "+toHexString(getWindowHandle())+", res: "+res);
+ }
+ return res;
+ }
+
+ class SetPositionActionImpl implements Runnable {
+ int x, y;
+
+ public SetPositionActionImpl(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ public void run() {
+ windowLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setPosition: "+WindowImpl.this.x+"/"+WindowImpl.this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
+ }
+ if ( WindowImpl.this.x != x || WindowImpl.this.y != y ) {
+ if(!fullscreen) {
+ if(0!=windowHandle) {
+ // this.x/this.y will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, -1, -1, false, 0, 0);
+ } else {
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void setPosition(int x, int y) {
+ if(isValid()) {
+ SetPositionActionImpl setPositionAction = new SetPositionActionImpl(x, y);
+ runOnEDTIfAvail(true, setPositionAction);
+ }
+ }
+
+ class FullScreenActionImpl implements Runnable {
+ boolean fullscreen;
+
+ public FullScreenActionImpl (boolean fullscreen) {
+ this.fullscreen = fullscreen;
+ }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(isNativeValid() && WindowImpl.this.fullscreen != fullscreen) {
+ int x,y,w,h;
+ WindowImpl.this.fullscreen = fullscreen;
+ if(fullscreen) {
+ x = 0; y = 0;
+ w = screen.getWidth();
+ h = screen.getHeight();
+ nfs_width = width;
+ nfs_height = height;
+ nfs_x = x;
+ nfs_y = y;
+ } else {
+ x = nfs_x;
+ y = nfs_y;
+ w = nfs_width;
+ h = nfs_height;
+ }
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
+ }
+
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
+ boolean wasVisible = isVisible();
+ setVisibleImpl(false, x, y, width, height);
+ WindowImpl.this.waitForVisible(false, true);
+ display.dispatchMessagesNative(); // status up2date
+
+ // write back mirrored values, to be able to detect satisfaction
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = w;
+ WindowImpl.this.height = h;
+ reconfigureWindowImpl(x, y, w, h, getParentWindowHandle()!=0, fullscreen?1:-1, isUndecorated()?-1:1);
+ display.dispatchMessagesNative(); // status up2date
+
+ if(wasVisible) {
+ setVisibleImpl(true, x, y, width, height);
+ boolean ok = WindowImpl.this.waitForVisible(true, true, Screen.SCREEN_MODE_CHANGE_TIMEOUT);
+ display.dispatchMessagesNative(); // status up2date
+ if( ok &&
+ ( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != w ||
+ WindowImpl.this.height != h ) )
+ {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs (reconfig): "+x+"/"+y+" "+w+"x"+h+", "+screen);
+ }
+ // reset pos/size .. due to some native impl flakyness
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ requestFocusImpl(true);
+ display.dispatchMessagesNative(); // status up2date
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs done");
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public boolean setFullscreen(boolean fullscreen) {
+ if(isValid()) {
+ FullScreenActionImpl fullScreenAction = new FullScreenActionImpl(fullscreen);
+ runOnEDTIfAvail(true, fullScreenAction);
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ return this.fullscreen;
+ }
+
+ class ScreenModeListenerImpl implements ScreenModeListener {
+ boolean animatorPaused = false;
+
+ public void screenModeChangeNotify(ScreenMode sm) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window.screenModeChangeNotify: "+sm);
+ }
+
+ if(null!=lifecycleHook) {
+ animatorPaused = lifecycleHook.pauseRenderingAction();
+ }
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window.screenModeChanged: "+sm+", success: "+success);
+ }
+
+ if(success) {
+ DimensionReadOnly screenSize = sm.getMonitorMode().getSurfaceSize().getResolution();
+ if ( getHeight() > screenSize.getHeight() ||
+ getWidth() > screenSize.getWidth() ) {
+ setSize(screenSize.getWidth(), screenSize.getHeight());
+ }
+ }
+
+ if(animatorPaused) {
+ lifecycleHook.resumeRenderingAction();
+ }
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Child Window Management
+ //
+
+ public final void removeChild(NativeWindow win) {
+ synchronized(childWindowsLock) {
+ childWindows.remove(win);
+ }
+ }
+
+ public final void addChild(NativeWindow win) {
+ if (win == null) {
+ return;
+ }
+ synchronized(childWindowsLock) {
+ childWindows.add(win);
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // Generic Event Support
+ //
+ private void doEvent(boolean enqueue, boolean wait, com.jogamp.newt.event.NEWTEvent event) {
+ boolean done = false;
+
+ if(!enqueue) {
+ done = consumeEvent(event);
+ wait = done; // don't wait if event can't be consumed now
+ }
+
+ if(!done) {
+ enqueueEvent(wait, event);
+ }
+ }
+
+ public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
+ if(isValid()) {
+ ((DisplayImpl)getScreen().getDisplay()).enqueueEvent(wait, event);
+ }
+ }
+
+ public boolean consumeEvent(NEWTEvent e) {
+ switch(e.getEventType()) {
+ // special repaint treatment
+ case WindowEvent.EVENT_WINDOW_REPAINT:
+ // queue repaint event in case surface is locked, ie in operation
+ if( isSurfaceLocked() ) {
+ // make sure only one repaint event is queued
+ if(!repaintQueued) {
+ repaintQueued=true;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.consumeEvent: queued "+e);
+ // Exception ee = new Exception("Window.windowRepaint: "+e);
+ // ee.printStackTrace();
+ }
+ return false;
+ }
+ return true;
+ }
+ repaintQueued=false; // no repaint event queued
+ break;
+
+ // common treatment
+ case WindowEvent.EVENT_WINDOW_RESIZED:
+ // queue event in case surface is locked, ie in operation
+ if( isSurfaceLocked() ) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.consumeEvent: queued "+e);
+ // Exception ee = new Exception("Window.windowRepaint: "+e);
+ // ee.printStackTrace();
+ }
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ if(e instanceof WindowEvent) {
+ consumeWindowEvent((WindowEvent)e);
+ } else if(e instanceof KeyEvent) {
+ consumeKeyEvent((KeyEvent)e);
+ } else if(e instanceof MouseEvent) {
+ consumeMouseEvent((MouseEvent)e);
+ } else {
+ throw new NativeWindowException("Unexpected NEWTEvent type " + e);
+ }
+ return true;
+ }
+
+ //
+ // SurfaceUpdatedListener Support
+ //
+
+ public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ addSurfaceUpdatedListener(-1, l);
+ }
+
+ public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
+ throws IndexOutOfBoundsException
+ {
+ if(l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ if(0>index) {
+ index = surfaceUpdatedListeners.size();
+ }
+ surfaceUpdatedListeners.add(index, l);
+ }
+ }
+
+ public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ if (l == null) {
+ return;
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners.remove(l);
+ }
+ }
+
+ public void removeAllSurfaceUpdatedListener() {
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners = new ArrayList();
+ }
+ }
+
+ public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
+ synchronized(surfaceUpdatedListenersLock) {
+ if(0>index) {
+ index = surfaceUpdatedListeners.size()-1;
+ }
+ return (SurfaceUpdatedListener) surfaceUpdatedListeners.get(index);
+ }
+ }
+
+ public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
+ synchronized(surfaceUpdatedListenersLock) {
+ return (SurfaceUpdatedListener[]) surfaceUpdatedListeners.toArray();
+ }
+ }
+
+ public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
+ synchronized(surfaceUpdatedListenersLock) {
+ for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ SurfaceUpdatedListener l = (SurfaceUpdatedListener) surfaceUpdatedListeners.get(i);
+ l.surfaceUpdated(updater, ns, when);
+ }
+ }
+ }
+
+ //
+ // MouseListener/Event Support
+ //
+ public void sendMouseEvent(int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ doMouseEvent(false, false, eventType, modifiers, x, y, button, rotation);
+ }
+ public void enqueueMouseEvent(boolean wait, int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ doMouseEvent(true, wait, eventType, modifiers, x, y, button, rotation);
+ }
+ private void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ if(x<0||y<0||x>=width||y>=height) {
+ return; // .. invalid ..
+ }
+ if(DEBUG_MOUSE_EVENT) {
+ System.err.println("doMouseEvent: enqueue"+enqueue+", wait "+wait+", "+MouseEvent.getEventTypeString(eventType)+
+ ", mod "+modifiers+", pos "+x+"/"+y+", button "+button);
+ }
+ if(button<0||button>MouseEvent.BUTTON_NUMBER) {
+ throw new NativeWindowException("Invalid mouse button number" + button);
+ }
+ long when = System.currentTimeMillis();
+ MouseEvent eClicked = null;
+ MouseEvent e = null;
+
+ if(MouseEvent.EVENT_MOUSE_PRESSED==eventType) {
+ if(when-lastMousePressed<MouseEvent.getClickTimeout()) {
+ lastMouseClickCount++;
+ } else {
+ lastMouseClickCount=1;
+ }
+ lastMousePressed=when;
+ mouseButtonPressed=button;
+ e = new MouseEvent(eventType, this, when,
+ modifiers, x, y, lastMouseClickCount, button, 0);
+ } else if(MouseEvent.EVENT_MOUSE_RELEASED==eventType) {
+ e = new MouseEvent(eventType, this, when,
+ modifiers, x, y, lastMouseClickCount, button, 0);
+ if(when-lastMousePressed<MouseEvent.getClickTimeout()) {
+ eClicked = new MouseEvent(MouseEvent.EVENT_MOUSE_CLICKED, this, when,
+ modifiers, x, y, lastMouseClickCount, button, 0);
+ } else {
+ lastMouseClickCount=0;
+ lastMousePressed=0;
+ }
+ mouseButtonPressed=0;
+ } else if(MouseEvent.EVENT_MOUSE_MOVED==eventType) {
+ if (mouseButtonPressed>0) {
+ e = new MouseEvent(MouseEvent.EVENT_MOUSE_DRAGGED, this, when,
+ modifiers, x, y, 1, mouseButtonPressed, 0);
+ } else {
+ e = new MouseEvent(eventType, this, when,
+ modifiers, x, y, 0, button, 0);
+ }
+ } else if(MouseEvent.EVENT_MOUSE_WHEEL_MOVED==eventType) {
+ e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, rotation);
+ } else {
+ e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, 0);
+ }
+ doEvent(enqueue, wait, e);
+ if(null!=eClicked) {
+ if(DEBUG_MOUSE_EVENT) {
+ System.err.println("doMouseEvent: synthesized MOUSE_CLICKED event");
+ }
+ doEvent(enqueue, wait, eClicked);
+ }
+ }
+
+
+ public void addMouseListener(MouseListener l) {
+ addMouseListener(-1, l);
+ }
+
+ public void addMouseListener(int index, MouseListener l) {
+ if(l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size();
+ }
+ clonedListeners.add(index, l);
+ mouseListeners = clonedListeners;
+ }
+
+ public void removeMouseListener(MouseListener l) {
+ if (l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
+ clonedListeners.remove(l);
+ mouseListeners = clonedListeners;
+ }
+
+ public MouseListener getMouseListener(int index) {
+ ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size()-1;
+ }
+ return (MouseListener) clonedListeners.get(index);
+ }
+
+ public MouseListener[] getMouseListeners() {
+ return (MouseListener[]) mouseListeners.toArray();
+ }
+
+ protected void consumeMouseEvent(MouseEvent e) {
+ if(DEBUG_MOUSE_EVENT) {
+ System.err.println("consumeMouseEvent: event: "+e);
+ }
+
+ for(int i = 0; i < mouseListeners.size(); i++ ) {
+ MouseListener l = (MouseListener) mouseListeners.get(i);
+ switch(e.getEventType()) {
+ case MouseEvent.EVENT_MOUSE_CLICKED:
+ l.mouseClicked(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_ENTERED:
+ l.mouseEntered(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_EXITED:
+ l.mouseExited(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_PRESSED:
+ l.mousePressed(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_RELEASED:
+ l.mouseReleased(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_MOVED:
+ l.mouseMoved(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_DRAGGED:
+ l.mouseDragged(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_WHEEL_MOVED:
+ l.mouseWheelMoved(e);
+ break;
+ default:
+ throw new NativeWindowException("Unexpected mouse event type " + e.getEventType());
+ }
+ }
+ }
+
+ //
+ // KeyListener/Event Support
+ //
+
+ public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
+ }
+
+ public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ enqueueEvent(wait, new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
+ }
+
+ public void addKeyListener(KeyListener l) {
+ addKeyListener(-1, l);
+ }
+
+ public void addKeyListener(int index, KeyListener l) {
+ if(l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) keyListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size();
+ }
+ clonedListeners.add(index, l);
+ keyListeners = clonedListeners;
+ }
+
+ public void removeKeyListener(KeyListener l) {
+ if (l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) keyListeners.clone();
+ clonedListeners.remove(l);
+ keyListeners = clonedListeners;
+ }
+
+ public KeyListener getKeyListener(int index) {
+ ArrayList clonedListeners = (ArrayList) keyListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size()-1;
+ }
+ return (KeyListener) clonedListeners.get(index);
+ }
+
+ public KeyListener[] getKeyListeners() {
+ return (KeyListener[]) keyListeners.toArray();
+ }
+
+ protected void consumeKeyEvent(KeyEvent e) {
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e);
+ }
+ for(int i = 0; i < keyListeners.size(); i++ ) {
+ KeyListener l = (KeyListener) keyListeners.get(i);
+ switch(e.getEventType()) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ l.keyPressed(e);
+ break;
+ case KeyEvent.EVENT_KEY_RELEASED:
+ l.keyReleased(e);
+ break;
+ case KeyEvent.EVENT_KEY_TYPED:
+ l.keyTyped(e);
+ break;
+ default:
+ throw new NativeWindowException("Unexpected key event type " + e.getEventType());
+ }
+ }
+ }
+
+ //
+ // WindowListener/Event Support
+ //
+ public void sendWindowEvent(int eventType) {
+ consumeWindowEvent( new WindowEvent(eventType, this, System.currentTimeMillis()) );
+ }
+
+ public void enqueueWindowEvent(boolean wait, int eventType) {
+ enqueueEvent( wait, new WindowEvent(eventType, this, System.currentTimeMillis()) );
+ }
+
+ public void addWindowListener(WindowListener l) {
+ addWindowListener(-1, l);
+ }
+
+ public void addWindowListener(int index, WindowListener l)
+ throws IndexOutOfBoundsException
+ {
+ if(l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) windowListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size();
+ }
+ clonedListeners.add(index, l);
+ windowListeners = clonedListeners;
+ }
+
+ public final void removeWindowListener(WindowListener l) {
+ if (l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) windowListeners.clone();
+ clonedListeners.remove(l);
+ windowListeners = clonedListeners;
+ }
+
+ public WindowListener getWindowListener(int index) {
+ ArrayList clonedListeners = (ArrayList) windowListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size()-1;
+ }
+ return (WindowListener) clonedListeners.get(index);
+ }
+
+ public WindowListener[] getWindowListeners() {
+ return (WindowListener[]) windowListeners.toArray();
+ }
+
+ protected void consumeWindowEvent(WindowEvent e) {
+ if(DEBUG_WINDOW_EVENT) {
+ System.err.println("consumeWindowEvent: "+e+", visible "+isVisible()+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight());
+ }
+ for(int i = 0; i < windowListeners.size(); i++ ) {
+ WindowListener l = (WindowListener) windowListeners.get(i);
+ switch(e.getEventType()) {
+ case WindowEvent.EVENT_WINDOW_RESIZED:
+ l.windowResized(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_MOVED:
+ l.windowMoved(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY:
+ l.windowDestroyNotify(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_DESTROYED:
+ l.windowDestroyed(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_GAINED_FOCUS:
+ l.windowGainedFocus(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_LOST_FOCUS:
+ l.windowLostFocus(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_REPAINT:
+ l.windowRepaint((WindowUpdateEvent)e);
+ break;
+ default:
+ throw
+ new NativeWindowException("Unexpected window event type "
+ + e.getEventType());
+ }
+ }
+ }
+
+ /**
+ * @param focusGained
+ */
+ protected void focusChanged(boolean focusGained) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.focusChanged: ("+getThreadName()+"): "+this.hasFocus+" -> "+focusGained+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ hasFocus = focusGained;
+ if (focusGained) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ } else {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS);
+ }
+ }
+
+ protected void visibleChanged(boolean visible) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ this.visible = visible ;
+ }
+
+ private boolean waitForVisible(boolean visible, boolean failFast) {
+ return waitForVisible(visible, failFast, TIMEOUT_NATIVEWINDOW);
+ }
+
+ private boolean waitForVisible(boolean visible, boolean failFast, long timeOut) {
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ for(long sleep = timeOut; 0<sleep && this.visible != visible; sleep-=10 ) {
+ display.dispatchMessagesNative(); // status up2date
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ie) {}
+ sleep -=10;
+ }
+ if(this.visible != visible) {
+ if(failFast) {
+ throw new NativeWindowException("Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible);
+ } else if (DEBUG_IMPLEMENTATION) {
+ System.err.println("******* Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible);
+ }
+ }
+ return this.visible == visible;
+ }
+
+ protected void sizeChanged(int newWidth, int newHeight, boolean force) {
+ if(force || width != newWidth || height != newHeight) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.sizeChanged: ("+getThreadName()+"): force "+force+", "+width+"x"+height+" -> "+newWidth+"x"+newHeight+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ width = newWidth;
+ height = newHeight;
+ if(isNativeValid()) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
+ }
+ }
+ }
+
+ protected void positionChanged(int newX, int newY) {
+ if( 0==parentWindowHandle && ( x != newX || y != newY ) ) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.positionChanged: ("+getThreadName()+"): "+x+"/"+y+" -> "+newX+"/"+newY+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ x = newX;
+ y = newY;
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
+ }
+ }
+
+ protected void windowDestroyNotify() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.windowDestroyNotify START "+getThreadName());
+ }
+
+ // send synced destroy notifications
+ enqueueWindowEvent(true, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
+
+ if(handleDestroyNotify && DISPOSE_ON_CLOSE == defaultCloseOperation && isValid()) {
+ destroy();
+ }
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.windowDestroyeNotify END "+getThreadName());
+ }
+ }
+
+ public void windowRepaint(int x, int y, int width, int height) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.windowRepaint "+getThreadName()+" - "+x+"/"+y+" "+width+"x"+height);
+ // Exception ee = new Exception("Window.windowRepaint: "+" - "+x+"/"+y+" "+width+"x"+height);
+ // ee.printStackTrace();
+ }
+
+ if(isNativeValid()) {
+ if(0>width) {
+ width=this.width;
+ }
+ if(0>height) {
+ height=this.height;
+ }
+
+ NEWTEvent e = new WindowUpdateEvent(WindowEvent.EVENT_WINDOW_REPAINT, this, System.currentTimeMillis(),
+ new Rectangle(x, y, width, height));
+ doEvent(false, false, e);
+ }
+ }
+
+ protected int getWindowLockRecursionCount() {
+ return windowLock.getRecursionCount();
+ }
+
+ //
+ // Reflection helper ..
+ //
+
+ private static Class[] getCustomConstructorArgumentTypes(Class windowClass) {
+ Class[] argTypes = null;
+ try {
+ Method m = windowClass.getDeclaredMethod("getCustomConstructorArgumentTypes", new Class[] {});
+ argTypes = (Class[]) m.invoke(null, null);
+ } catch (Throwable t) {}
+ return argTypes;
+ }
+
+ private static int verifyConstructorArgumentTypes(Class[] types, Object[] args) {
+ if(types.length != args.length) {
+ return -1;
+ }
+ for(int i=0; i<args.length; i++) {
+ if(!types[i].isInstance(args[i])) {
+ return i;
+ }
+ }
+ return args.length;
+ }
+
+ private static String getArgsStrList(Object[] args) {
+ StringBuffer sb = new StringBuffer();
+ for(int i=0; i<args.length; i++) {
+ sb.append(args[i].getClass());
+ if(i<args.length) {
+ sb.append(", ");
+ }
+ }
+ return sb.toString();
+ }
+
+ private static String getTypeStrList(Class[] types) {
+ StringBuffer sb = new StringBuffer();
+ for(int i=0; i<types.length; i++) {
+ sb.append(types[i]);
+ if(i<types.length) {
+ sb.append(", ");
+ }
+ }
+ return sb.toString();
+ }
+
+ protected final void shouldNotCallThis() {
+ throw new NativeWindowException("Should not call this");
+ }
+
+ public static String getThreadName() {
+ return Display.getThreadName();
+ }
+
+ public static String toHexString(int hex) {
+ return Display.toHexString(hex);
+ }
+
+ public static String toHexString(long hex) {
+ return Display.toHexString(hex);
+ }
+}
+
diff --git a/src/newt/classes/jogamp/newt/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/awt/AWTCanvas.java
new file mode 100644
index 000000000..f17e530d5
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/awt/AWTCanvas.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import com.jogamp.newt.Window;
+
+import java.awt.Canvas;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsConfiguration;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class AWTCanvas extends Canvas {
+ private GraphicsDevice device;
+ private GraphicsConfiguration chosen;
+ private AWTGraphicsConfiguration awtConfig;
+
+ private CapabilitiesChooser chooser=null;
+ private CapabilitiesImmutable capabilities;
+
+ private boolean displayConfigChanged=false;
+
+ public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) {
+ super();
+
+ if(null==capabilities) {
+ throw new NativeWindowException("Capabilities null");
+ }
+ this.capabilities=capabilities;
+ this.chooser=chooser;
+ }
+
+ public AWTGraphicsConfiguration getAWTGraphicsConfiguration() {
+ return awtConfig;
+ }
+
+ public boolean hasDeviceChanged() {
+ boolean res = displayConfigChanged;
+ displayConfigChanged=false;
+ return res;
+ }
+
+ public void addNotify() {
+ super.addNotify();
+
+ disableBackgroundErase();
+
+ GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ if(null!=gc) {
+ device = gc.getDevice();
+ }
+
+ /*
+ * Save the chosen capabilities for use in getGraphicsConfiguration().
+ */
+ awtConfig = chooseGraphicsConfiguration(capabilities, capabilities, chooser, device);
+ if(Window.DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Info: Created Config: "+awtConfig);
+ e.printStackTrace();
+ }
+ if(null!=awtConfig) {
+ // update ..
+ chosen = awtConfig.getGraphicsConfiguration();
+ }
+ if(null==awtConfig) {
+ throw new NativeWindowException("Error: AWTGraphicsConfiguration is null");
+ }
+ }
+
+ public void removeNotify() {
+ try {
+ dispose();
+ } finally {
+ super.removeNotify();
+ }
+ }
+
+ private void dispose() {
+ if(null != awtConfig) {
+ AbstractGraphicsDevice adevice = awtConfig.getNativeGraphicsConfiguration().getScreen().getDevice();
+ String adeviceMsg=null;
+ if(Window.DEBUG_IMPLEMENTATION) {
+ adeviceMsg = adevice.toString();
+ }
+ boolean closed = adevice.close();
+ if(Window.DEBUG_IMPLEMENTATION) {
+ System.err.println("AWTCanvas.dispose(): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ }
+ }
+ }
+
+ /**
+ * Overridden to choose a GraphicsConfiguration on a parent container's
+ * GraphicsDevice because both devices
+ */
+ public GraphicsConfiguration getGraphicsConfiguration() {
+ /*
+ * Workaround for problems with Xinerama and java.awt.Component.checkGD
+ * when adding to a container on a different graphics device than the
+ * one that this Canvas is associated with.
+ *
+ * GC will be null unless:
+ * - A native peer has assigned it. This means we have a native
+ * peer, and are already comitted to a graphics configuration.
+ * - This canvas has been added to a component hierarchy and has
+ * an ancestor with a non-null GC, but the native peer has not
+ * yet been created. This means we can still choose the GC on
+ * all platforms since the peer hasn't been created.
+ */
+ final GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ /*
+ * chosen is only non-null on platforms where the GLDrawableFactory
+ * returns a non-null GraphicsConfiguration (in the GLCanvas
+ * constructor).
+ *
+ * if gc is from this Canvas' native peer then it should equal chosen,
+ * otherwise it is from an ancestor component that this Canvas is being
+ * added to, and we go into this block.
+ */
+ if (gc != null && chosen != null && !chosen.equals(gc)) {
+ /*
+ * Check for compatibility with gc. If they differ by only the
+ * device then return a new GCconfig with the super-class' GDevice
+ * (and presumably the same visual ID in Xinerama).
+ *
+ */
+ if (!chosen.getDevice().getIDstring().equals(gc.getDevice().getIDstring())) {
+ /*
+ * Here we select a GraphicsConfiguration on the alternate
+ * device that is presumably identical to the chosen
+ * configuration, but on the other device.
+ *
+ * Should really check to ensure that we select a configuration
+ * with the same X visual ID for Xinerama screens, otherwise the
+ * GLDrawable may have the wrong visual ID (I don't think this
+ * ever gets updated). May need to add a method to
+ * X11GLDrawableFactory to do this in a platform specific
+ * manner.
+ *
+ * However, on platforms where we can actually get into this
+ * block, both devices should have the same visual list, and the
+ * same configuration should be selected here.
+ */
+ AWTGraphicsConfiguration config = chooseGraphicsConfiguration(
+ awtConfig.getChosenCapabilities(), awtConfig.getRequestedCapabilities(), chooser, gc.getDevice());
+ final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null;
+ if(Window.DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
+ e.printStackTrace();
+ System.err.println("!!! Created Config (n): HAVE GC "+chosen);
+ System.err.println("!!! Created Config (n): THIS GC "+gc);
+ System.err.println("!!! Created Config (n): Choosen GC "+compatible);
+ System.err.println("!!! Created Config (n): HAVE CF "+awtConfig);
+ System.err.println("!!! Created Config (n): Choosen CF "+config);
+ System.err.println("!!! Created Config (n): EQUALS CAPS "+config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities()));
+ }
+
+ if (compatible != null) {
+ /*
+ * Save the new GC for equals test above, and to return to
+ * any outside callers of this method.
+ */
+ chosen = compatible;
+ if( !config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities())) {
+ displayConfigChanged=true;
+ }
+ awtConfig = config;
+ }
+ }
+
+ /*
+ * If a compatible GC was not found in the block above, this will
+ * return the GC that was selected in the constructor (and might
+ * cause an exception in Component.checkGD when adding to a
+ * container, but in this case that would be the desired behavior).
+ *
+ */
+ return chosen;
+ } else if (gc == null) {
+ /*
+ * The GC is null, which means we have no native peer, and are not
+ * part of a (realized) component hierarchy. So we return the
+ * desired visual that was selected in the constructor (possibly
+ * null).
+ */
+ return chosen;
+ }
+
+ /*
+ * Otherwise we have not explicitly selected a GC in the constructor, so
+ * just return what Canvas would have.
+ */
+ return gc;
+ }
+
+ private static AWTGraphicsConfiguration chooseGraphicsConfiguration(CapabilitiesImmutable capsChosen,
+ CapabilitiesImmutable capsRequested,
+ CapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+ AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
+ capsRequested,
+ chooser, aScreen);
+ if (config == null) {
+ throw new NativeWindowException("Error: Couldn't fetch AWTGraphicsConfiguration");
+ }
+
+ return config;
+ }
+
+ // Disables the AWT's erasing of this Canvas's background on Windows
+ // in Java SE 6. This internal API is not available in previous
+ // releases, but the system property
+ // -Dsun.awt.noerasebackground=true can be specified to get similar
+ // results globally in previous releases.
+ private static boolean disableBackgroundEraseInitialized;
+ private static Method disableBackgroundEraseMethod;
+ private void disableBackgroundErase() {
+ if (!disableBackgroundEraseInitialized) {
+ try {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class clazz = getToolkit().getClass();
+ while (clazz != null && disableBackgroundEraseMethod == null) {
+ try {
+ disableBackgroundEraseMethod =
+ clazz.getDeclaredMethod("disableBackgroundErase",
+ new Class[] { Canvas.class });
+ disableBackgroundEraseMethod.setAccessible(true);
+ } catch (Exception e) {
+ clazz = clazz.getSuperclass();
+ }
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ }
+ disableBackgroundEraseInitialized = true;
+ }
+ if (disableBackgroundEraseMethod != null) {
+ try {
+ disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this });
+ } catch (Exception e) {
+ // FIXME: workaround for 6504460 (incorrect backport of 6333613 in 5.0u10)
+ // throw new GLException(e);
+ }
+ }
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/awt/AWTDisplay.java b/src/newt/classes/jogamp/newt/awt/AWTDisplay.java
new file mode 100644
index 000000000..6f0b23210
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/awt/AWTDisplay.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import java.awt.event.*;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.impl.DisplayImpl;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+import java.util.*;
+
+public class AWTDisplay extends DisplayImpl {
+ public AWTDisplay() {
+ }
+
+ protected void createNativeImpl() {
+ aDevice = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(null, AbstractGraphicsDevice.DEFAULT_UNIT); // default
+ }
+
+ protected void setAWTGraphicsDevice(AWTGraphicsDevice d) {
+ aDevice = d;
+ }
+
+ protected void closeNativeImpl() { }
+
+ protected boolean shallRunOnEDT() {
+ return false;
+ }
+ protected void dispatchMessagesNative() { /* nop */ }
+}
+
diff --git a/src/newt/classes/jogamp/newt/awt/AWTScreen.java b/src/newt/classes/jogamp/newt/awt/AWTScreen.java
new file mode 100644
index 000000000..5e097fdc3
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/awt/AWTScreen.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import java.awt.DisplayMode;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+
+public class AWTScreen extends ScreenImpl {
+ public AWTScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new AWTGraphicsScreen((AWTGraphicsDevice)display.getGraphicsDevice());
+
+ DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode();
+ int w = mode.getWidth();
+ int h = mode.getHeight();
+ setScreenSize(w, h);
+ }
+
+ protected void setAWTGraphicsScreen(AWTGraphicsScreen s) {
+ aScreen = s;
+ }
+
+ // done by AWTWindow ..
+ protected void setScreenSize(int w, int h) {
+ super.setScreenSize(w, h);
+ }
+
+ protected void closeNativeImpl() { }
+}
diff --git a/src/newt/classes/jogamp/newt/awt/AWTWindow.java b/src/newt/classes/jogamp/newt/awt/AWTWindow.java
new file mode 100644
index 000000000..ec1ae1c8a
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/awt/AWTWindow.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import com.jogamp.newt.event.awt.*;
+import com.jogamp.newt.util.EDTUtil;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.DisplayMode;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import com.jogamp.newt.impl.WindowImpl;
+import java.awt.Insets;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.nativewindow.util.Point;
+
+/** An implementation of the Newt Window class built using the
+ AWT. This is provided for convenience of porting to platforms
+ supporting Java SE. */
+
+public class AWTWindow extends WindowImpl {
+
+ public AWTWindow() {
+ this(null);
+ }
+
+ public static Class[] getCustomConstructorArgumentTypes() {
+ return new Class[] { Container.class } ;
+ }
+
+ public AWTWindow(Container container) {
+ super();
+ title = "AWT NewtWindow";
+ this.container = container;
+ if(container instanceof Frame) {
+ frame = (Frame) container;
+ }
+ }
+
+ private boolean owningFrame;
+ private Container container = null;
+ private Frame frame = null; // same instance as container, just for impl. convenience
+ private AWTCanvas canvas;
+
+ protected void requestFocusImpl(boolean reparented) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ container.requestFocus();
+ }
+ });
+ }
+
+ protected void setTitleImpl(final String title) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ if (frame != null) {
+ frame.setTitle(title);
+ }
+ }
+ });
+ }
+
+ protected void createNativeImpl() {
+
+ if(0!=getParentWindowHandle()) {
+ throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
+ }
+
+ final AWTWindow awtWindow = this;
+
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ if(null==container) {
+ frame = new Frame();
+ container = frame;
+ owningFrame=true;
+ } else {
+ owningFrame=false;
+ width = container.getWidth();
+ height = container.getHeight();
+ x = container.getX();
+ y = container.getY();
+ }
+ if(null!=frame) {
+ frame.setTitle(getTitle());
+ }
+ container.setLayout(new BorderLayout());
+ canvas = new AWTCanvas(capsRequested, AWTWindow.this.capabilitiesChooser);
+
+ addWindowListener(new LocalWindowListener());
+
+ new AWTMouseAdapter(awtWindow).addTo(canvas); // fwd all AWT Mouse events to here
+ new AWTKeyAdapter(awtWindow).addTo(canvas); // fwd all AWT Key events to here
+
+ // canvas.addComponentListener(listener);
+ container.add(canvas, BorderLayout.CENTER);
+ container.setSize(width, height);
+ container.setLocation(x, y);
+ new AWTWindowAdapter(awtWindow).addTo(container); // fwd all AWT Window events to here
+
+ if(null!=frame) {
+ frame.setUndecorated(undecorated||fullscreen);
+ }
+ }
+ });
+ setWindowHandle(1); // just a marker ..
+ }
+
+ protected void closeNativeImpl() {
+ setWindowHandle(0); // just a marker ..
+ if(null!=container) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ container.setVisible(false);
+ container.remove(canvas);
+ container.setEnabled(false);
+ canvas.setEnabled(false);
+ }
+ });
+ }
+ if(owningFrame && null!=frame) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ frame.dispose();
+ owningFrame=false;
+ frame = null;
+ }
+ });
+ }
+ }
+
+ public boolean hasDeviceChanged() {
+ boolean res = canvas.hasDeviceChanged();
+ if(res) {
+ config = canvas.getAWTGraphicsConfiguration();
+ if (config == null) {
+ throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this);
+ }
+ updateDeviceData();
+ }
+ return res;
+ }
+
+ protected void setVisibleImpl(final boolean visible, int x, int y, int width, int height) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ container.setVisible(visible);
+ }
+ });
+
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ config = canvas.getAWTGraphicsConfiguration();
+
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ updateDeviceData();
+ visibleChanged(visible);
+ }
+
+ private void updateDeviceData() {
+ // propagate new info ..
+ ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)config.getScreen());
+ ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)config.getScreen().getDevice());
+
+ DisplayMode mode = ((AWTGraphicsDevice)config.getScreen().getDevice()).getGraphicsDevice().getDisplayMode();
+ int w = mode.getWidth();
+ int h = mode.getHeight();
+ ((AWTScreen)getScreen()).setScreenSize(w, h);
+ }
+
+ public javax.media.nativewindow.util.Insets getInsets() {
+ final int insets[] = new int[] { 0, 0, 0, 0 };
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ Insets contInsets = container.getInsets();
+ insets[0] = contInsets.top;
+ insets[1] = contInsets.left;
+ insets[2] = contInsets.bottom;
+ insets[3] = contInsets.right;
+ }
+ });
+ return new javax.media.nativewindow.util.Insets(insets[0],insets[1],insets[2],insets[3]);
+ }
+
+ protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final boolean parentChange, final int fullScreenChange, final int decorationChange) {
+ /** An AWT event on setSize() would bring us in a deadlock situation, hence invokeLater() */
+ runOnEDT(false, new Runnable() {
+ public void run() {
+ if(decorationChange!=0 && null!=frame) {
+ if(!container.isDisplayable()) {
+ frame.setUndecorated(isUndecorated());
+ } else {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("AWTWindow can't undecorate already created frame");
+ }
+ }
+ }
+ int _x=(x>=0)?x:AWTWindow.this.x;
+ int _y=(x>=0)?y:AWTWindow.this.y;
+ int _w=(width>0)?width:AWTWindow.this.width;
+ int _h=(height>0)?height:AWTWindow.this.height;
+
+ container.setLocation(_x, _y);
+ Insets insets = container.getInsets();
+ container.setSize(_w + insets.left + insets.right,
+ _h + insets.top + insets.bottom);
+ }
+ });
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ java.awt.Point ap = canvas.getLocationOnScreen();
+ ap.translate(x, y);
+ return new Point((int)(ap.getX()+0.5),(int)(ap.getY()+0.5));
+ }
+
+ public Object getWrappedWindow() {
+ return canvas;
+ }
+
+ private void runOnEDT(boolean wait, Runnable r) {
+ EDTUtil edtUtil = getScreen().getDisplay().getEDTUtil();
+ if ( ( null != edtUtil && edtUtil.isCurrentThreadEDT() ) || EventQueue.isDispatchThread() ) {
+ r.run();
+ } else {
+ try {
+ if(wait) {
+ EventQueue.invokeAndWait(r);
+ } else {
+ EventQueue.invokeLater(r);
+ }
+ } catch (Exception e) {
+ throw new NativeWindowException(e);
+ }
+ }
+ }
+
+ class LocalWindowListener extends com.jogamp.newt.event.WindowAdapter {
+ public void windowMoved(com.jogamp.newt.event.WindowEvent e) {
+ if(null!=container) {
+ x = container.getX();
+ y = container.getY();
+ }
+ }
+ public void windowResized(com.jogamp.newt.event.WindowEvent e) {
+ if(null!=canvas) {
+ width = canvas.getWidth();
+ height = canvas.getHeight();
+ }
+ }
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/awt/opengl/VersionApplet.java b/src/newt/classes/jogamp/newt/awt/opengl/VersionApplet.java
new file mode 100644
index 000000000..f31d1bc0f
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/awt/opengl/VersionApplet.java
@@ -0,0 +1,174 @@
+package com.jogamp.newt.impl.awt.opengl;
+
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.TextArea;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import java.util.List;
+
+import javax.media.opengl.GLProfile;
+import javax.media.opengl.awt.GLCanvas;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLCapabilitiesImmutable;
+import javax.media.opengl.GLDrawableFactory;
+import javax.media.opengl.GLEventListener;
+
+import com.jogamp.common.GlueGenVersion;
+import com.jogamp.common.os.Platform;
+import com.jogamp.common.util.VersionUtil;
+import com.jogamp.nativewindow.NativeWindowVersion;
+import com.jogamp.newt.NewtVersion;
+import com.jogamp.opengl.JoglVersion;
+
+public class VersionApplet extends Applet {
+ static {
+ GLProfile.initSingleton(false);
+ }
+ TextArea tareaVersion;
+ TextArea tareaCaps;
+ GLCanvas canvas;
+
+ public static void main(String[] args) {
+ Frame frame = new Frame("JOGL Version Applet");
+ frame.setSize(800, 600);
+ frame.setLayout(new BorderLayout());
+
+ VersionApplet va = new VersionApplet();
+ frame.addWindowListener(new ClosingWindowAdapter(frame, va));
+
+ va.init();
+ frame.add(va, BorderLayout.CENTER);
+ frame.validate();
+
+ frame.setVisible(true);
+ va.start();
+ }
+
+ static class ClosingWindowAdapter extends WindowAdapter {
+ Frame f;
+ VersionApplet va;
+ public ClosingWindowAdapter(Frame f, VersionApplet va) {
+ this.f = f;
+ this.va = va;
+ }
+ public void windowClosing(WindowEvent ev) {
+ f.setVisible(false);
+ va.stop();
+ va.destroy();
+ f.remove(va);
+ f.dispose();
+ System.exit(0);
+ }
+ }
+
+ private synchronized void my_init() {
+ if(null != canvas) { return; }
+
+ GLProfile glp = GLProfile.getDefault();
+ GLCapabilities glcaps = new GLCapabilities(glp);
+
+ setLayout(new BorderLayout());
+ String s;
+
+ tareaVersion = new TextArea(120, 60);
+ s = VersionUtil.getPlatformInfo().toString();
+ System.err.println(s);
+ tareaVersion.append(s);
+
+ s = GlueGenVersion.getInstance().toString();
+ System.err.println(s);
+ tareaVersion.append(s);
+
+ s = NativeWindowVersion.getInstance().toString();
+ System.err.println(s);
+ tareaVersion.append(NativeWindowVersion.getInstance().toString());
+
+ s = JoglVersion.getInstance().toString();
+ System.err.println(s);
+ tareaVersion.append(s);
+
+ s = NewtVersion.getInstance().toString();
+ System.err.println(s);
+ tareaVersion.append(s);
+
+ tareaCaps = new TextArea(120, 20);
+ GLDrawableFactory factory = GLDrawableFactory.getFactory(glp);
+ List/*<GLCapabilitiesImmutable>*/ availCaps = factory.getAvailableCapabilities(null);
+ for(int i=0; i<availCaps.size(); i++) {
+ s = ((GLCapabilitiesImmutable) availCaps.get(i)).toString();
+ System.err.println(s);
+ tareaCaps.append(s);
+ tareaCaps.append(Platform.getNewline());
+ }
+
+ Container grid = new Container();
+ grid.setLayout(new GridLayout(2, 1));
+ grid.add(tareaVersion);
+ grid.add(tareaCaps);
+ add(grid, BorderLayout.CENTER);
+
+ canvas = new GLCanvas(glcaps);
+ canvas.addGLEventListener(new GLInfo());
+ canvas.setSize(10, 10);
+ add(canvas, BorderLayout.SOUTH);
+ validate();
+ }
+
+ private synchronized void my_release() {
+ if(null!=canvas) {
+ remove(canvas);
+ canvas.destroy();
+ canvas = null;
+ remove(tareaVersion);
+ tareaVersion=null;
+ }
+ }
+
+ public void init() {
+ System.err.println("VersionApplet: init() - begin");
+ my_init();
+ System.err.println("VersionApplet: init() - end");
+ }
+
+ public void start() {
+ System.err.println("VersionApplet: start() - begin");
+ System.err.println("VersionApplet: start() - end");
+ }
+
+ public void stop() {
+ System.err.println("VersionApplet: stop() - begin");
+ System.err.println("VersionApplet: stop() - end");
+ }
+
+ public void destroy() {
+ System.err.println("VersionApplet: destroy() - start");
+ my_release();
+ System.err.println("VersionApplet: destroy() - end");
+ }
+
+ class GLInfo implements GLEventListener {
+ public void init(GLAutoDrawable drawable) {
+ GL gl = drawable.getGL();
+ String s = JoglVersion.getInstance().getGLInfo(gl, null).toString();
+ System.err.println(s);
+ tareaVersion.append(s);
+ }
+
+ public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
+ }
+
+ public void display(GLAutoDrawable drawable) {
+ }
+
+ public void dispose(GLAutoDrawable drawable) {
+ }
+ }
+
+}
diff --git a/src/newt/classes/jogamp/newt/event/NEWTEventTask.java b/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
new file mode 100644
index 000000000..1b4bce4b0
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/event/NEWTEventTask.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.impl.event;
+
+import com.jogamp.newt.event.NEWTEvent;
+
+/**
+ * Helper class to provide a NEWTEvent queue implementation with a NEWTEvent wrapper
+ * which notifies after sending the event for the <code>invokeAndWait()</code> semantics.
+ */
+public class NEWTEventTask {
+ NEWTEvent event;
+ Object notifyObject;
+
+ public NEWTEventTask(NEWTEvent event, Object notifyObject) {
+ this.event = event ;
+ this.notifyObject = notifyObject ;
+ }
+
+ public NEWTEvent get() { return event; }
+
+ public void notifyIssuer() {
+ if(null != notifyObject) {
+ synchronized (notifyObject) {
+ notifyObject.notifyAll();
+ }
+ }
+ }
+}
+
diff --git a/src/newt/classes/jogamp/newt/intel/gdl/Display.java b/src/newt/classes/jogamp/newt/intel/gdl/Display.java
new file mode 100644
index 000000000..c08f239d9
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/intel/gdl/Display.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.intel.gdl;
+
+import com.jogamp.newt.impl.*;
+import javax.media.nativewindow.*;
+
+public class Display extends com.jogamp.newt.impl.DisplayImpl {
+ static int initCounter = 0;
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!Screen.initIDs()) {
+ throw new NativeWindowException("Failed to initialize GDL Screen jmethodIDs");
+ }
+ if (!Window.initIDs()) {
+ throw new NativeWindowException("Failed to initialize GDL Window jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public Display() {
+ }
+
+ protected void createNativeImpl() {
+ synchronized(Display.class) {
+ if(0==initCounter) {
+ displayHandle = CreateDisplay();
+ if(0==displayHandle) {
+ throw new NativeWindowException("Couldn't initialize GDL Display");
+ }
+ }
+ initCounter++;
+ }
+ aDevice = new DefaultGraphicsDevice(NativeWindowFactory.TYPE_DEFAULT, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT, displayHandle);
+ }
+
+ protected void closeNativeImpl() {
+ if(0==displayHandle) {
+ throw new NativeWindowException("displayHandle null; initCnt "+initCounter);
+ }
+ synchronized(Display.class) {
+ if(initCounter>0) {
+ initCounter--;
+ if(0==initCounter) {
+ DestroyDisplay(displayHandle);
+ }
+ }
+ }
+ }
+
+ protected void dispatchMessagesNative() {
+ if(0!=displayHandle) {
+ DispatchMessages(displayHandle, focusedWindow);
+ }
+ }
+
+ protected void setFocus(Window focus) {
+ focusedWindow = focus;
+ }
+
+ private long displayHandle = 0;
+ private Window focusedWindow = null;
+ private native long CreateDisplay();
+ private native void DestroyDisplay(long displayHandle);
+ private native void DispatchMessages(long displayHandle, Window focusedWindow);
+}
+
diff --git a/src/newt/classes/jogamp/newt/intel/gdl/Screen.java b/src/newt/classes/jogamp/newt/intel/gdl/Screen.java
new file mode 100644
index 000000000..4abee350f
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/intel/gdl/Screen.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.intel.gdl;
+
+import com.jogamp.newt.impl.*;
+import javax.media.nativewindow.*;
+
+public class Screen extends com.jogamp.newt.impl.ScreenImpl {
+
+ static {
+ Display.initSingleton();
+ }
+
+ public Screen() {
+ }
+
+ protected void createNativeImpl() {
+ AbstractGraphicsDevice adevice = getDisplay().getGraphicsDevice();
+ GetScreenInfo(adevice.getHandle(), screen_idx);
+ aScreen = new DefaultGraphicsScreen(adevice, screen_idx);
+ }
+
+ protected void closeNativeImpl() { }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native void GetScreenInfo(long displayHandle, int screen_idx);
+
+ // called by GetScreenInfo() ..
+ private void screenCreated(int width, int height) {
+ setScreenSize(width, height);
+ }
+}
+
diff --git a/src/newt/classes/jogamp/newt/intel/gdl/Window.java b/src/newt/classes/jogamp/newt/intel/gdl/Window.java
new file mode 100644
index 000000000..c9a322942
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/intel/gdl/Window.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.intel.gdl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Point;
+
+public class Window extends com.jogamp.newt.impl.WindowImpl {
+ static {
+ Display.initSingleton();
+ }
+
+ public Window() {
+ }
+
+ static long nextWindowHandle = 1;
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new NativeWindowException("GDL Window does not support window parenting");
+ }
+ AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
+
+ config = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, aScreen);
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ synchronized(Window.class) {
+ setWindowHandle(nextWindowHandle++); // just a marker
+
+ surfaceHandle = CreateSurface(aDevice.getHandle(), getScreen().getWidth(), getScreen().getHeight(), x, y, width, height);
+ if (surfaceHandle == 0) {
+ throw new NativeWindowException("Error creating window");
+ }
+ }
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=surfaceHandle) {
+ synchronized(Window.class) {
+ CloseSurface(getDisplayHandle(), surfaceHandle);
+ }
+ surfaceHandle = 0;
+ ((Display)getScreen().getDisplay()).setFocus(null);
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ if(visible) {
+ ((Display)getScreen().getDisplay()).setFocus(this);
+ }
+ this.visibleChanged(visible);
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
+ Screen screen = (Screen) getScreen();
+
+ int _x=(x>=0)?x:this.x;
+ int _y=(x>=0)?y:this.y;
+ int _w=(width>0)?width:this.width;
+ int _h=(height>0)?height:this.height;
+
+ if(_w>screen.getWidth()) {
+ _w=screen.getWidth();
+ }
+ if(_h>screen.getHeight()) {
+ _h=screen.getHeight();
+ }
+ if((_x+_w)>screen.getWidth()) {
+ _x=screen.getWidth()-_w;
+ }
+ if((_y+_h)>screen.getHeight()) {
+ _y=screen.getHeight()-_h;
+ }
+
+ if(0!=surfaceHandle) {
+ SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), _x, _y, _w, _h);
+ }
+
+ return true;
+ }
+
+ protected void requestFocusImpl(boolean reparented) {
+ ((Display)getScreen().getDisplay()).setFocus(this);
+ }
+
+ public final long getSurfaceHandle() {
+ return surfaceHandle;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native long CreateSurface(long displayHandle, int scrn_width, int scrn_height, int x, int y, int width, int height);
+ private native void CloseSurface(long displayHandle, long surfaceHandle);
+ private native void SetBounds0(long surfaceHandle, int scrn_width, int scrn_height, int x, int y, int width, int height);
+
+ private void updateBounds(int x, int y, int width, int height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ private long surfaceHandle;
+}
diff --git a/src/newt/classes/jogamp/newt/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/macosx/MacDisplay.java
new file mode 100644
index 000000000..cf9d4f0a3
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/macosx/MacDisplay.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.macosx;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.macosx.*;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.*;
+import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.newt.util.MainThread;
+
+public class MacDisplay extends DisplayImpl {
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if(!initNSApplication0()) {
+ throw new NativeWindowException("Failed to initialize native Application hook");
+ }
+ if(!MacWindow.initIDs0()) {
+ throw new NativeWindowException("Failed to initialize jmethodIDs");
+ }
+ if(DEBUG) {
+ System.err.println("MacDisplay.init App and IDs OK "+Thread.currentThread().getName());
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+ public MacDisplay() {
+ }
+
+ protected void dispatchMessagesNative() {
+ dispatchMessages0();
+ }
+
+ protected void createNativeImpl() {
+ aDevice = new MacOSXGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+
+ protected void closeNativeImpl() { }
+
+ protected void createEDTUtil() {
+ if(NewtFactory.useEDT()) {
+ final Display f_dpy = this;
+ MainThread.addPumpMessage(this,
+ new Runnable() {
+ public void run() {
+ if(null!=f_dpy.getGraphicsDevice()) {
+ f_dpy.dispatchMessages();
+ } } } );
+ edtUtil = MainThread.getSingleton();
+ edtUtil.start();
+ }
+ }
+
+ protected void releaseEDTUtil() {
+ if(null!=edtUtil) {
+ MainThread.removePumpMessage(this);
+ edtUtil.waitUntilStopped();
+ edtUtil=null;
+ }
+ }
+
+ private static native boolean initNSApplication0();
+ protected native void dispatchMessages0();
+}
+
diff --git a/src/newt/classes/jogamp/newt/macosx/MacScreen.java b/src/newt/classes/jogamp/newt/macosx/MacScreen.java
new file mode 100644
index 000000000..f0c388366
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/macosx/MacScreen.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.macosx;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import javax.media.nativewindow.*;
+
+public class MacScreen extends ScreenImpl {
+ static {
+ MacDisplay.initSingleton();
+ }
+
+ public MacScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
+ }
+
+ protected void closeNativeImpl() { }
+
+ private static native int getWidthImpl0(int scrn_idx);
+ private static native int getHeightImpl0(int scrn_idx);
+}
diff --git a/src/newt/classes/jogamp/newt/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/macosx/MacWindow.java
new file mode 100644
index 000000000..e789a0dc9
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/macosx/MacWindow.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.macosx;
+
+import javax.media.nativewindow.*;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.impl.*;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
+
+public class MacWindow extends WindowImpl {
+
+ // Window styles
+ private static final int NSBorderlessWindowMask = 0;
+ private static final int NSTitledWindowMask = 1 << 0;
+ private static final int NSClosableWindowMask = 1 << 1;
+ private static final int NSMiniaturizableWindowMask = 1 << 2;
+ private static final int NSResizableWindowMask = 1 << 3;
+
+ // Window backing store types
+ private static final int NSBackingStoreRetained = 0;
+ private static final int NSBackingStoreNonretained = 1;
+ private static final int NSBackingStoreBuffered = 2;
+
+ // Key constants handled differently on Mac OS X than other platforms
+ private static final int NSUpArrowFunctionKey = 0xF700;
+ private static final int NSDownArrowFunctionKey = 0xF701;
+ private static final int NSLeftArrowFunctionKey = 0xF702;
+ private static final int NSRightArrowFunctionKey = 0xF703;
+ private static final int NSF1FunctionKey = 0xF704;
+ private static final int NSF2FunctionKey = 0xF705;
+ private static final int NSF3FunctionKey = 0xF706;
+ private static final int NSF4FunctionKey = 0xF707;
+ private static final int NSF5FunctionKey = 0xF708;
+ private static final int NSF6FunctionKey = 0xF709;
+ private static final int NSF7FunctionKey = 0xF70A;
+ private static final int NSF8FunctionKey = 0xF70B;
+ private static final int NSF9FunctionKey = 0xF70C;
+ private static final int NSF10FunctionKey = 0xF70D;
+ private static final int NSF11FunctionKey = 0xF70E;
+ private static final int NSF12FunctionKey = 0xF70F;
+ private static final int NSF13FunctionKey = 0xF710;
+ private static final int NSF14FunctionKey = 0xF711;
+ private static final int NSF15FunctionKey = 0xF712;
+ private static final int NSF16FunctionKey = 0xF713;
+ private static final int NSF17FunctionKey = 0xF714;
+ private static final int NSF18FunctionKey = 0xF715;
+ private static final int NSF19FunctionKey = 0xF716;
+ private static final int NSF20FunctionKey = 0xF717;
+ private static final int NSF21FunctionKey = 0xF718;
+ private static final int NSF22FunctionKey = 0xF719;
+ private static final int NSF23FunctionKey = 0xF71A;
+ private static final int NSF24FunctionKey = 0xF71B;
+ private static final int NSF25FunctionKey = 0xF71C;
+ private static final int NSF26FunctionKey = 0xF71D;
+ private static final int NSF27FunctionKey = 0xF71E;
+ private static final int NSF28FunctionKey = 0xF71F;
+ private static final int NSF29FunctionKey = 0xF720;
+ private static final int NSF30FunctionKey = 0xF721;
+ private static final int NSF31FunctionKey = 0xF722;
+ private static final int NSF32FunctionKey = 0xF723;
+ private static final int NSF33FunctionKey = 0xF724;
+ private static final int NSF34FunctionKey = 0xF725;
+ private static final int NSF35FunctionKey = 0xF726;
+ private static final int NSInsertFunctionKey = 0xF727;
+ private static final int NSDeleteFunctionKey = 0xF728;
+ private static final int NSHomeFunctionKey = 0xF729;
+ private static final int NSBeginFunctionKey = 0xF72A;
+ private static final int NSEndFunctionKey = 0xF72B;
+ private static final int NSPageUpFunctionKey = 0xF72C;
+ private static final int NSPageDownFunctionKey = 0xF72D;
+ private static final int NSPrintScreenFunctionKey = 0xF72E;
+ private static final int NSScrollLockFunctionKey = 0xF72F;
+ private static final int NSPauseFunctionKey = 0xF730;
+ private static final int NSSysReqFunctionKey = 0xF731;
+ private static final int NSBreakFunctionKey = 0xF732;
+ private static final int NSResetFunctionKey = 0xF733;
+ private static final int NSStopFunctionKey = 0xF734;
+ private static final int NSMenuFunctionKey = 0xF735;
+ private static final int NSUserFunctionKey = 0xF736;
+ private static final int NSSystemFunctionKey = 0xF737;
+ private static final int NSPrintFunctionKey = 0xF738;
+ private static final int NSClearLineFunctionKey = 0xF739;
+ private static final int NSClearDisplayFunctionKey = 0xF73A;
+ private static final int NSInsertLineFunctionKey = 0xF73B;
+ private static final int NSDeleteLineFunctionKey = 0xF73C;
+ private static final int NSInsertCharFunctionKey = 0xF73D;
+ private static final int NSDeleteCharFunctionKey = 0xF73E;
+ private static final int NSPrevFunctionKey = 0xF73F;
+ private static final int NSNextFunctionKey = 0xF740;
+ private static final int NSSelectFunctionKey = 0xF741;
+ private static final int NSExecuteFunctionKey = 0xF742;
+ private static final int NSUndoFunctionKey = 0xF743;
+ private static final int NSRedoFunctionKey = 0xF744;
+ private static final int NSFindFunctionKey = 0xF745;
+ private static final int NSHelpFunctionKey = 0xF746;
+ private static final int NSModeSwitchFunctionKey = 0xF747;
+
+ private volatile long surfaceHandle;
+
+ // non fullscreen dimensions ..
+ private final Insets insets = new Insets(0,0,0,0);
+
+ static {
+ MacDisplay.initSingleton();
+ }
+
+ public MacWindow() {
+ }
+
+ protected void createNativeImpl() {
+ config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ }
+
+ protected void closeNativeImpl() {
+ nsViewLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
+ if (getWindowHandle() != 0) {
+ close0(getWindowHandle());
+ }
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNative failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ } finally {
+ setWindowHandle(0);
+ nsViewLock.unlock();
+ }
+ }
+
+ public final long getSurfaceHandle() {
+ return surfaceHandle;
+ }
+
+ public Insets getInsets() {
+ // in order to properly calculate insets we need the window to be
+ // created
+ nsViewLock.lock();
+ try {
+ createWindow(false, getX(), getY(), getWidth(), getHeight(), isFullscreen());
+ return (Insets) insets.clone();
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ private RecursiveLock nsViewLock = new RecursiveLock();
+
+ protected int lockSurfaceImpl() {
+ nsViewLock.lock();
+ return LOCK_SUCCESS;
+ }
+
+ protected void unlockSurfaceImpl() {
+ nsViewLock.unlock();
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ nsViewLock.lock();
+ try {
+ if (visible) {
+ createWindow(false, x, y, width, height, isFullscreen());
+ if (getWindowHandle() != 0) {
+ makeKeyAndOrderFront0(getWindowHandle());
+ }
+ } else {
+ if (getWindowHandle() != 0) {
+ orderOut0(getWindowHandle());
+ }
+ }
+ visibleChanged(visible);
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ protected void setTitleImpl(final String title) {
+ // FIXME: move nsViewLock up to window lock
+ nsViewLock.lock();
+ try {
+ setTitle0(getWindowHandle(), title);
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ protected void requestFocusImpl(boolean reparented) {
+ // FIXME: move nsViewLock up to window lock
+ nsViewLock.lock();
+ try {
+ makeKey0(getWindowHandle());
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
+ nsViewLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("MacWindow reconfig: parentChange "+parentChange+", fullScreenChange "+fullScreenChange+", decorationChange "+decorationChange+" "+x+"/"+y+" "+width+"x"+height);
+ }
+ int _x=(x>=0)?x:this.x;
+ int _y=(x>=0)?y:this.y;
+ int _w=(width>0)?width:this.width;
+ int _h=(height>0)?height:this.height;
+
+ if(decorationChange!=0 || parentChange || fullScreenChange!=0) {
+ createWindow(true, _x, _y, _w, _h, fullScreenChange>0);
+ if (getWindowHandle() != 0) {
+ makeKeyAndOrderFront0(getWindowHandle());
+ }
+ } else {
+ if(x>=0 || y>=0) {
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y);
+ }
+ if(width>0 || height>0) {
+ setContentSize0(getWindowHandle(), _w, _h);
+ }
+ }
+ } finally {
+ nsViewLock.unlock();
+ }
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return null;
+ }
+
+ private void insetsChanged(int left, int top, int right, int bottom) {
+ if (DEBUG_IMPLEMENTATION) {
+ System.err.println(Thread.currentThread().getName()+
+ " Insets changed to " + left + ", " + top + ", " + right + ", " + bottom);
+ }
+ if (left != -1 && top != -1 && right != -1 && bottom != -1) {
+ insets.left = left;
+ insets.top = top;
+ insets.right = right;
+ insets.bottom = bottom;
+ }
+ }
+
+ private char convertKeyChar(char keyChar) {
+ if (keyChar == '\r') {
+ // Turn these into \n
+ return '\n';
+ }
+
+ if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
+ switch (keyChar) {
+ case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
+ case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
+ case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
+ case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
+ case NSF1FunctionKey: return KeyEvent.VK_F1;
+ case NSF2FunctionKey: return KeyEvent.VK_F2;
+ case NSF3FunctionKey: return KeyEvent.VK_F3;
+ case NSF4FunctionKey: return KeyEvent.VK_F4;
+ case NSF5FunctionKey: return KeyEvent.VK_F5;
+ case NSF6FunctionKey: return KeyEvent.VK_F6;
+ case NSF7FunctionKey: return KeyEvent.VK_F7;
+ case NSF8FunctionKey: return KeyEvent.VK_F8;
+ case NSF9FunctionKey: return KeyEvent.VK_F9;
+ case NSF10FunctionKey: return KeyEvent.VK_F10;
+ case NSF11FunctionKey: return KeyEvent.VK_F11;
+ case NSF12FunctionKey: return KeyEvent.VK_F12;
+ case NSF13FunctionKey: return KeyEvent.VK_F13;
+ case NSF14FunctionKey: return KeyEvent.VK_F14;
+ case NSF15FunctionKey: return KeyEvent.VK_F15;
+ case NSF16FunctionKey: return KeyEvent.VK_F16;
+ case NSF17FunctionKey: return KeyEvent.VK_F17;
+ case NSF18FunctionKey: return KeyEvent.VK_F18;
+ case NSF19FunctionKey: return KeyEvent.VK_F19;
+ case NSF20FunctionKey: return KeyEvent.VK_F20;
+ case NSF21FunctionKey: return KeyEvent.VK_F21;
+ case NSF22FunctionKey: return KeyEvent.VK_F22;
+ case NSF23FunctionKey: return KeyEvent.VK_F23;
+ case NSF24FunctionKey: return KeyEvent.VK_F24;
+ case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
+ case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
+ case NSHomeFunctionKey: return KeyEvent.VK_HOME;
+ case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
+ case NSEndFunctionKey: return KeyEvent.VK_END;
+ case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
+ case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
+ case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
+ case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
+ case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
+ // Not handled:
+ // NSSysReqFunctionKey
+ // NSBreakFunctionKey
+ // NSResetFunctionKey
+ case NSStopFunctionKey: return KeyEvent.VK_STOP;
+ // Not handled:
+ // NSMenuFunctionKey
+ // NSUserFunctionKey
+ // NSSystemFunctionKey
+ // NSPrintFunctionKey
+ // NSClearLineFunctionKey
+ // NSClearDisplayFunctionKey
+ // NSInsertLineFunctionKey
+ // NSDeleteLineFunctionKey
+ // NSInsertCharFunctionKey
+ // NSDeleteCharFunctionKey
+ // NSPrevFunctionKey
+ // NSNextFunctionKey
+ // NSSelectFunctionKey
+ // NSExecuteFunctionKey
+ // NSUndoFunctionKey
+ // NSRedoFunctionKey
+ // NSFindFunctionKey
+ // NSHelpFunctionKey
+ // NSModeSwitchFunctionKey
+ default: break;
+ }
+ }
+
+ // NSEvent's charactersIgnoringModifiers doesn't ignore the shift key
+ if (keyChar >= 'a' && keyChar <= 'z') {
+ return Character.toUpperCase(keyChar);
+ }
+
+ return keyChar;
+ }
+
+ public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ int key = convertKeyChar(keyChar);
+ if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName());
+ // Note that we send the key char for the key code on this
+ // platform -- we do not get any useful key codes out of the system
+ super.enqueueKeyEvent(wait, eventType, modifiers, key, keyChar);
+ }
+
+ private void createWindow(final boolean recreate, final int x, final int y, final int width, final int height, final boolean fullscreen) {
+
+ if(0!=getWindowHandle() && !recreate) {
+ return;
+ }
+
+ try {
+ //runOnEDTIfAvail(true, new Runnable() {
+ // public void run() {
+ if(0!=getWindowHandle()) {
+ // save the view .. close the window
+ surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0);
+ if(recreate && 0==surfaceHandle) {
+ throw new NativeWindowException("Internal Error - recreate, window but no view");
+ }
+ close0(getWindowHandle());
+ setWindowHandle(0);
+ } else {
+ surfaceHandle = 0;
+ }
+ setWindowHandle(createWindow0(getParentWindowHandle(),
+ x, y, width, height, fullscreen,
+ (isUndecorated() ?
+ NSBorderlessWindowMask :
+ NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
+ NSBackingStoreBuffered,
+ getScreen().getIndex(), surfaceHandle));
+ if (getWindowHandle() == 0) {
+ throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this);
+ }
+ surfaceHandle = contentView0(getWindowHandle());
+ setTitle0(getWindowHandle(), getTitle());
+ // don't make the window visible on window creation
+ // makeKeyAndOrderFront0(windowHandle);
+ // } } );
+ } catch (Exception ie) {
+ ie.printStackTrace();
+ }
+
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED);
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED);
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ }
+
+ protected static native boolean initIDs0();
+ private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h,
+ boolean fullscreen, int windowStyle,
+ int backingStoreType,
+ int screen_idx, long view);
+ private native void makeKeyAndOrderFront0(long window);
+ private native void makeKey0(long window);
+ private native void orderOut0(long window);
+ private native void close0(long window);
+ private native void setTitle0(long window, String title);
+ private native long contentView0(long window);
+ private native long changeContentView0(long parentWindowHandle, long window, long view);
+ private native void setContentSize0(long window, int w, int h);
+ private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y);
+}
diff --git a/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Display.java b/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Display.java
new file mode 100644
index 000000000..5a875846e
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Display.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.broadcom.egl;
+
+import com.jogamp.newt.impl.*;
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+
+public class Display extends com.jogamp.newt.impl.DisplayImpl {
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!Window.initIDs()) {
+ throw new NativeWindowException("Failed to initialize BCEGL Window jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public Display() {
+ }
+
+ protected void createNativeImpl() {
+ long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight);
+ if (handle == EGL.EGL_NO_DISPLAY) {
+ throw new NativeWindowException("BC EGL CreateDisplay failed");
+ }
+ aDevice = new EGLGraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+
+ protected void closeNativeImpl() {
+ if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
+ DestroyDisplay(aDevice.getHandle());
+ }
+ }
+
+ protected void dispatchMessagesNative() {
+ // n/a .. DispatchMessages();
+ }
+
+ private native long CreateDisplay(int width, int height);
+ private native void DestroyDisplay(long dpy);
+ private native void DispatchMessages();
+}
+
diff --git a/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Screen.java b/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Screen.java
new file mode 100644
index 000000000..144fe5e83
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Screen.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.broadcom.egl;
+
+import javax.media.nativewindow.*;
+
+public class Screen extends com.jogamp.newt.impl.ScreenImpl {
+
+ static {
+ Display.initSingleton();
+ }
+
+
+ public Screen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(fixedWidth, fixedHeight);
+ }
+
+ protected void closeNativeImpl() { }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ static final int fixedWidth = 1920;
+ static final int fixedHeight = 1080;
+}
+
diff --git a/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Window.java b/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Window.java
new file mode 100644
index 000000000..cfc5bd5a9
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/opengl/broadcom/egl/Window.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.broadcom.egl;
+
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Point;
+import javax.media.opengl.GLCapabilitiesImmutable;
+
+public class Window extends com.jogamp.newt.impl.WindowImpl {
+ static {
+ Display.initSingleton();
+ }
+
+ public Window() {
+ }
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new RuntimeException("Window parenting not supported (yet)");
+ }
+ // query a good configuration .. even thought we drop this one
+ // and reuse the EGLUtil choosen one later.
+ config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ setSizeImpl(getScreen().getWidth(), getScreen().getHeight());
+
+ setWindowHandle(realizeWindow(true, width, height));
+ if (0 == getWindowHandle()) {
+ throw new NativeWindowException("Error native Window Handle is null");
+ }
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=windowHandleClose) {
+ CloseWindow(getDisplayHandle(), windowHandleClose);
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ visibleChanged(visible);
+ }
+
+ protected void requestFocusImpl(boolean reparented) { }
+
+ protected void setSizeImpl(int width, int height) {
+ if(0!=getWindowHandle()) {
+ // n/a in BroadcomEGL
+ System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window");
+ } else {
+ this.width = width;
+ this.height = height;
+ }
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ if(0!=getWindowHandle()) {
+ if(0!=fullScreenChange) {
+ if( fullScreenChange > 0 ) {
+ // n/a in BroadcomEGL
+ System.err.println("setFullscreen n/a in BroadcomEGL");
+ return false;
+ }
+ }
+ }
+ if(width>0 || height>0) {
+ if(0!=getWindowHandle()) {
+ // n/a in BroadcomEGL
+ System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window");
+ } else {
+ this.width=(width>0)?width:this.width;
+ this.height=(height>0)?height:this.height;
+ }
+ }
+ if(x>=0 || y>=0) {
+ System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL");
+ }
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+
+
+ public boolean surfaceSwap() {
+ SwapWindow(getDisplayHandle(), getWindowHandle());
+ return true;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native long CreateWindow(long eglDisplayHandle, boolean chromaKey, int width, int height);
+ private native void CloseWindow(long eglDisplayHandle, long eglWindowHandle);
+ private native void SwapWindow(long eglDisplayHandle, long eglWindowHandle);
+
+
+ private long realizeWindow(boolean chromaKey, int width, int height) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("BCEGL Window.realizeWindow() with: chroma "+chromaKey+", "+width+"x"+height+", "+config);
+ }
+ long handle = CreateWindow(getDisplayHandle(), chromaKey, width, height);
+ if (0 == handle) {
+ throw new NativeWindowException("Error native Window Handle is null");
+ }
+ windowHandleClose = handle;
+ return handle;
+ }
+
+ private void windowCreated(int cfgID, int width, int height) {
+ this.width = width;
+ this.height = height;
+ GLCapabilitiesImmutable capsReq = (GLCapabilitiesImmutable) config.getRequestedCapabilities();
+ config = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID);
+ if (config == null) {
+ throw new NativeWindowException("Error creating EGLGraphicsConfiguration from id: "+cfgID+", "+this);
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("BCEGL Window.windowCreated(): "+toHexString(cfgID)+", "+width+"x"+height+", "+config);
+ }
+ }
+
+ private long windowHandleClose;
+}
diff --git a/src/newt/classes/jogamp/newt/opengl/kd/KDDisplay.java b/src/newt/classes/jogamp/newt/opengl/kd/KDDisplay.java
new file mode 100644
index 000000000..3e677f0d7
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/opengl/kd/KDDisplay.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.kd;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.*;
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+
+public class KDDisplay extends DisplayImpl {
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!KDWindow.initIDs()) {
+ throw new NativeWindowException("Failed to initialize KDWindow jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public KDDisplay() {
+ }
+
+ protected void createNativeImpl() {
+ // FIXME: map name to EGL_*_DISPLAY
+ long handle = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ if (handle == EGL.EGL_NO_DISPLAY) {
+ throw new NativeWindowException("eglGetDisplay failed");
+ }
+ if (!EGL.eglInitialize(handle, null, null)) {
+ throw new NativeWindowException("eglInitialize failed");
+ }
+ aDevice = new EGLGraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_CONNECTION, AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+
+ protected void closeNativeImpl() {
+ if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
+ EGL.eglTerminate(aDevice.getHandle());
+ }
+ }
+
+ protected void dispatchMessagesNative() {
+ DispatchMessages();
+ }
+
+ private native void DispatchMessages();
+}
+
diff --git a/src/newt/classes/jogamp/newt/opengl/kd/KDScreen.java b/src/newt/classes/jogamp/newt/opengl/kd/KDScreen.java
new file mode 100644
index 000000000..1a73d0e5d
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/opengl/kd/KDScreen.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.kd;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import javax.media.nativewindow.*;
+
+public class KDScreen extends ScreenImpl {
+ static {
+ KDDisplay.initSingleton();
+ }
+
+ public KDScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ }
+
+ protected void closeNativeImpl() { }
+
+ // elevate access to this package ..
+ protected void setScreenSize(int w, int h) {
+ super.setScreenSize(w, h);
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/opengl/kd/KDWindow.java b/src/newt/classes/jogamp/newt/opengl/kd/KDWindow.java
new file mode 100644
index 000000000..b49b6f7b7
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/opengl/kd/KDWindow.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.kd;
+
+import com.jogamp.newt.impl.*;
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Point;
+import javax.media.opengl.GLCapabilitiesImmutable;
+
+public class KDWindow extends WindowImpl {
+ private static final String WINDOW_CLASS_NAME = "NewtWindow";
+
+ static {
+ KDDisplay.initSingleton();
+ }
+
+ public KDWindow() {
+ }
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new RuntimeException("Window parenting not supported (yet)");
+ }
+ config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ int[] eglAttribs = EGLGraphicsConfiguration.GLCapabilities2AttribList(eglCaps);
+
+ eglWindowHandle = CreateWindow(getDisplayHandle(), eglAttribs);
+ if (eglWindowHandle == 0) {
+ throw new NativeWindowException("Error creating egl window: "+config);
+ }
+ setVisible0(eglWindowHandle, false);
+ setWindowHandle(RealizeWindow(eglWindowHandle));
+ if (0 == getWindowHandle()) {
+ throw new NativeWindowException("Error native Window Handle is null");
+ }
+ windowHandleClose = eglWindowHandle;
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=windowHandleClose) {
+ CloseWindow(windowHandleClose, windowUserData);
+ windowUserData=0;
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ setVisible0(eglWindowHandle, visible);
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ visibleChanged(visible);
+ }
+
+ protected void requestFocusImpl(boolean reparented) { }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ if(0!=eglWindowHandle) {
+ if(0!=fullScreenChange) {
+ boolean fs = fullScreenChange > 0;
+ setFullScreen0(eglWindowHandle, fs);
+ if(fs) {
+ return true;
+ }
+ }
+ // int _x=(x>=0)?x:this.x;
+ // int _y=(x>=0)?y:this.y;
+ int _w=(width>0)?width:this.width;
+ int _h=(height>0)?height:this.height;
+ if(width>0 || height>0) {
+ setSize0(eglWindowHandle, _w, _h);
+ }
+ if(x>=0 || y>=0) {
+ System.err.println("setPosition n/a in KD");
+ }
+ }
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native long CreateWindow(long displayHandle, int[] attributes);
+ private native long RealizeWindow(long eglWindowHandle);
+ private native int CloseWindow(long eglWindowHandle, long userData);
+ private native void setVisible0(long eglWindowHandle, boolean visible);
+ private native void setSize0(long eglWindowHandle, int width, int height);
+ private native void setFullScreen0(long eglWindowHandle, boolean fullscreen);
+
+ private void windowCreated(long userData) {
+ windowUserData=userData;
+ }
+
+ protected void sizeChanged(int newWidth, int newHeight, boolean force) {
+ if(fullscreen) {
+ ((KDScreen)getScreen()).setScreenSize(width, height);
+ }
+ super.sizeChanged(newWidth, newHeight, force);
+ }
+
+ private long eglWindowHandle;
+ private long windowHandleClose;
+ private long windowUserData;
+}
diff --git a/src/newt/classes/jogamp/newt/windows/WindowsDisplay.java b/src/newt/classes/jogamp/newt/windows/WindowsDisplay.java
new file mode 100644
index 000000000..af32d1693
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/windows/WindowsDisplay.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.windows;
+
+import com.jogamp.nativewindow.impl.windows.RegisteredClass;
+import com.jogamp.nativewindow.impl.windows.RegisteredClassFactory;
+import com.jogamp.newt.impl.DisplayImpl;
+import com.jogamp.newt.impl.NEWTJNILibLoader;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.windows.WindowsGraphicsDevice;
+
+public class WindowsDisplay extends DisplayImpl {
+
+ private static final String newtClassBaseName = "_newt_clazz" ;
+ private static RegisteredClassFactory sharedClassFactory;
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!WindowsWindow.initIDs0()) {
+ throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs");
+ }
+ sharedClassFactory = new RegisteredClassFactory(newtClassBaseName, WindowsWindow.getNewtWndProc0());
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+ private RegisteredClass sharedClass;
+
+ public WindowsDisplay() {
+ }
+
+ protected void createNativeImpl() {
+ sharedClass = sharedClassFactory.getSharedClass();
+ aDevice = new WindowsGraphicsDevice(AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+
+ protected void closeNativeImpl() {
+ sharedClassFactory.releaseSharedClass();
+ }
+
+ protected void dispatchMessagesNative() {
+ DispatchMessages0();
+ }
+
+ protected long getHInstance() {
+ return sharedClass.getHandle();
+ }
+
+ protected String getWindowClassName() {
+ return sharedClass.getName();
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ private static native void DispatchMessages0();
+}
+
diff --git a/src/newt/classes/jogamp/newt/windows/WindowsScreen.java b/src/newt/classes/jogamp/newt/windows/WindowsScreen.java
new file mode 100644
index 000000000..e15a40e7b
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/windows/WindowsScreen.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+package com.jogamp.newt.impl.windows;
+
+import com.jogamp.common.util.ArrayHashSet;
+import java.util.ArrayList;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.impl.ScreenModeStatus;
+import com.jogamp.newt.util.ScreenModeUtil;
+
+import javax.media.nativewindow.*;
+
+public class WindowsScreen extends ScreenImpl {
+
+ static {
+ WindowsDisplay.initSingleton();
+ }
+
+ public WindowsScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
+ }
+
+ protected void closeNativeImpl() {
+ }
+
+ private int[] getScreenModeIdx(int idx) {
+ int[] modeProps = getScreenMode0(screen_idx, idx);
+ if (null == modeProps || 0 == modeProps.length) {
+ return null;
+ }
+ if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) {
+ throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length);
+ }
+ return modeProps;
+ }
+
+ private int nativeModeIdx;
+
+ protected int[] getScreenModeFirstImpl() {
+ nativeModeIdx = 0;
+ return getScreenModeNextImpl();
+ }
+
+ protected int[] getScreenModeNextImpl() {
+ int[] modeProps = getScreenModeIdx(nativeModeIdx);
+ if (null != modeProps && 0 < modeProps.length) {
+ nativeModeIdx++;
+ return modeProps;
+ }
+ return null;
+ }
+
+ protected ScreenMode getCurrentScreenModeImpl() {
+ int[] modeProps = getScreenModeIdx(-1);
+ if (null != modeProps && 0 < modeProps.length) {
+ return ScreenModeUtil.streamIn(modeProps, 0);
+ }
+ return null;
+ }
+
+ protected boolean setCurrentScreenModeImpl(ScreenMode sm) {
+ return setScreenMode0(screen_idx,
+ sm.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
+ sm.getMonitorMode().getSurfaceSize().getResolution().getHeight(),
+ sm.getMonitorMode().getSurfaceSize().getBitsPerPixel(),
+ sm.getMonitorMode().getRefreshRate(),
+ sm.getRotation());
+ }
+
+ // Native calls
+ private native int getWidthImpl0(int scrn_idx);
+
+ private native int getHeightImpl0(int scrn_idx);
+
+ private native int[] getScreenMode0(int screen_index, int mode_index);
+ private native boolean setScreenMode0(int screen_index, int width, int height, int bits, int freq, int rot);
+}
diff --git a/src/newt/classes/jogamp/newt/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/windows/WindowsWindow.java
new file mode 100644
index 000000000..5ab0a5b79
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/windows/WindowsWindow.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.windows;
+
+import com.jogamp.nativewindow.impl.windows.GDI;
+import com.jogamp.newt.impl.WindowImpl;
+import javax.media.nativewindow.GraphicsConfigurationFactory;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
+
+public class WindowsWindow extends WindowImpl {
+
+ private long hmon;
+ private long hdc;
+ private long windowHandleClose;
+ private final Insets insets = new Insets(0, 0, 0, 0);
+
+ static {
+ WindowsDisplay.initSingleton();
+ }
+
+ public WindowsWindow() {
+ }
+
+ protected int lockSurfaceImpl() {
+ if( 0 != getWindowHandle() && 0 == hdc ) {
+ hdc = GDI.GetDC(getWindowHandle());
+ hmon = MonitorFromWindow0(getWindowHandle());
+ }
+ return ( 0 != hdc ) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
+ }
+
+ protected void unlockSurfaceImpl() {
+ if ( 0 != hdc && 0 != getWindowHandle() && getWindowLockRecursionCount() == 0) {
+ GDI.ReleaseDC(getWindowHandle(), hdc);
+ hdc=0;
+ }
+ }
+
+ public final long getSurfaceHandle() {
+ return hdc;
+ }
+
+ public boolean hasDeviceChanged() {
+ if(0!=getWindowHandle()) {
+ long _hmon = MonitorFromWindow0(getWindowHandle());
+ if (hmon != _hmon) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ Exception e = new Exception("Info: Window Device Changed "+Thread.currentThread().getName()+
+ ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon));
+ e.printStackTrace();
+ }
+ hmon = _hmon;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected void createNativeImpl() {
+ WindowsScreen screen = (WindowsScreen) getScreen();
+ WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
+ config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ setWindowHandle(CreateWindow0(display.getHInstance(), display.getWindowClassName(), display.getWindowClassName(),
+ getParentWindowHandle(), 0, undecorated, x, y, width, height));
+ if (getWindowHandle() == 0) {
+ throw new NativeWindowException("Error creating window");
+ }
+ windowHandleClose = getWindowHandle();
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+
+ " (Parent HWND "+toHexString(getParentWindowHandle())+
+ ") : HWND "+toHexString(getWindowHandle())+", "+Thread.currentThread());
+ e.printStackTrace();
+ }
+ }
+
+ protected void closeNativeImpl() {
+ if (hdc != 0) {
+ if(windowHandleClose != 0) {
+ try {
+ GDI.ReleaseDC(windowHandleClose, hdc);
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ }
+ }
+ hdc = 0;
+ }
+ if(windowHandleClose != 0) {
+ try {
+ GDI.DestroyWindow(windowHandleClose);
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ } finally {
+ windowHandleClose = 0;
+ }
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ setVisible0(getWindowHandle(), visible, (getParentWindowHandle()==0)?true:false, x, y, width, height);
+ visibleChanged(visible);
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ reconfigureWindow0( (fullScreenChange>0)?0:getParentWindowHandle(),
+ getWindowHandle(), x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange);
+ return true;
+ }
+
+ protected void requestFocusImpl(boolean force) {
+ requestFocus0(getWindowHandle(), force);
+ }
+
+ protected void setTitleImpl(final String title) {
+ setTitle0(getWindowHandle(), title);
+ }
+
+ public Insets getInsets() {
+ return (Insets)insets.clone();
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ protected static native boolean initIDs0();
+ protected static native long getNewtWndProc0();
+
+ private native long CreateWindow0(long hInstance, String wndClassName, String wndName,
+ long parentWindowHandle, long visualID, boolean isUndecorated,
+ int x, int y, int width, int height);
+ private native long MonitorFromWindow0(long windowHandle);
+ private native void setVisible0(long windowHandle, boolean visible, boolean top, int x, int y, int width, int height);
+ private native void reconfigureWindow0(long parentWindowHandle, long windowHandle,
+ int x, int y, int width, int height, boolean isVisible,
+ boolean parentChange, int fullScreenChange, int decorationChange);
+ private static native void setTitle0(long windowHandle, String title);
+ private native void requestFocus0(long windowHandle, boolean force);
+
+ private void insetsChanged(int left, int top, int right, int bottom) {
+ if (left != -1 && top != -1 && right != -1 && bottom != -1) {
+ if (left != insets.left || top != insets.top || right != insets.right || bottom != insets.bottom) {
+ insets.left = left;
+ insets.top = top;
+ insets.right = right;
+ insets.bottom = bottom;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.insetsChanged: "+insets);
+ }
+ }
+ }
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/x11/X11Display.java b/src/newt/classes/jogamp/newt/x11/X11Display.java
new file mode 100644
index 000000000..af05c0356
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/x11/X11Display.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.x11;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import com.jogamp.newt.impl.*;
+import com.jogamp.nativewindow.impl.x11.X11Util;
+
+public class X11Display extends DisplayImpl {
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if ( !initIDs0() ) {
+ throw new NativeWindowException("Failed to initialize X11Display jmethodIDs");
+ }
+
+ if (!X11Window.initIDs0()) {
+ throw new NativeWindowException("Failed to initialize X11Window jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public X11Display() {
+ }
+
+ public String validateDisplayName(String name, long handle) {
+ return X11Util.validateDisplayName(name, handle);
+ }
+
+ protected void createNativeImpl() {
+ long handle = X11Util.createDisplay(name);
+ if( 0 == handle ) {
+ throw new RuntimeException("Error creating display: "+name);
+ }
+ try {
+ CompleteDisplay0(handle);
+ } catch(RuntimeException e) {
+ X11Util.closeDisplay(handle);
+ throw e;
+ }
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock());
+ // aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.createDefaultToolkitLockNoAWT(NativeWindowFactory.TYPE_X11, handle));
+ // aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT);
+ }
+
+ protected void closeNativeImpl() {
+ X11Util.closeDisplay(getHandle());
+ }
+
+ protected void dispatchMessagesNative() {
+ long dpy = getHandle();
+ if(0!=dpy) {
+ DispatchMessages0(dpy, javaObjectAtom, windowDeleteAtom);
+ }
+ }
+
+ protected long getJavaObjectAtom() { return javaObjectAtom; }
+ protected long getWindowDeleteAtom() { return windowDeleteAtom; }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ private static native boolean initIDs0();
+
+ private native void CompleteDisplay0(long handle);
+
+ private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom);
+
+ private void displayCompleted(long javaObjectAtom, long windowDeleteAtom) {
+ this.javaObjectAtom=javaObjectAtom;
+ this.windowDeleteAtom=windowDeleteAtom;
+ }
+
+ private long windowDeleteAtom;
+ private long javaObjectAtom;
+}
+
diff --git a/src/newt/classes/jogamp/newt/x11/X11Screen.java b/src/newt/classes/jogamp/newt/x11/X11Screen.java
new file mode 100644
index 000000000..5e89a9972
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/x11/X11Screen.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+package com.jogamp.newt.impl.x11;
+
+import com.jogamp.nativewindow.impl.x11.X11Util;
+import com.jogamp.newt.impl.ScreenImpl;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.util.ScreenModeUtil;
+import java.util.List;
+
+import javax.media.nativewindow.x11.*;
+
+public class X11Screen extends ScreenImpl {
+
+ static {
+ X11Display.initSingleton();
+ }
+
+ public X11Screen() {
+ }
+
+ protected void createNativeImpl() {
+ long handle = GetScreen0(display.getHandle(), screen_idx);
+ if (handle == 0) {
+ throw new RuntimeException("Error creating screen: " + screen_idx);
+ }
+ aScreen = new X11GraphicsScreen((X11GraphicsDevice) getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidth0(display.getHandle(), screen_idx),
+ getHeight0(display.getHandle(), screen_idx));
+ }
+
+ protected void closeNativeImpl() {
+ }
+
+ private int[] nrotations;
+ private int nrotation_index;
+ private int nres_number;
+ private int nres_index;
+ private int[] nrates;
+ private int nrate_index;
+ private int nmode_number;
+
+ protected int[] getScreenModeFirstImpl() {
+ // initialize iterators and static data
+ nrotations = getAvailableScreenModeRotations0(display.getHandle(), screen_idx);
+ if(null==nrotations || 0==nrotations.length) {
+ return null;
+ }
+ nrotation_index = 0;
+
+ nres_number = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ if(0==nres_number) {
+ return null;
+ }
+ nres_index = 0;
+
+ nrates = getScreenModeRates0(display.getHandle(), screen_idx, nres_index);
+ if(null==nrates || 0==nrates.length) {
+ return null;
+ }
+ nrate_index = 0;
+
+ nmode_number = 0;
+
+ return getScreenModeNextImpl();
+ }
+
+ protected int[] getScreenModeNextImpl() {
+ // assemble: w x h x bpp x f x r
+
+ /**
+ System.err.println("******** mode: "+nmode_number);
+ System.err.println("rot "+nrotation_index);
+ System.err.println("rate "+nrate_index);
+ System.err.println("res "+nres_index); */
+
+ int[] res = getScreenModeResolution0(display.getHandle(), screen_idx, nres_index);
+ if(null==res || 0==res.length) {
+ return null;
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number);
+ }
+ int bpp = 32; // FIXME
+ int rate = nrates[nrate_index];
+ if(0>=rate) {
+ throw new InternalError("invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length);
+ }
+ int rotation = nrotations[nrotation_index];
+
+ int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = bpp; // bpp
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rotation;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element
+
+ nmode_number++;
+
+ // iteration: r -> f -> bpp -> [w x h]
+ nrotation_index++;
+ if(nrotation_index == nrotations.length) {
+ nrotation_index=0;
+ nrate_index++;
+ if(null == nrates || nrate_index == nrates.length){
+ nres_index++;
+ if(nres_index == nres_number) {
+ // done
+ nrates=null;
+ nrotations=null;
+ return null;
+ }
+
+ nrates = getScreenModeRates0(display.getHandle(), screen_idx, nres_index);
+ if(null==nrates || 0==nrates.length) {
+ return null;
+ }
+ nrate_index = 0;
+ }
+ }
+
+ return props;
+ }
+
+ protected ScreenMode getCurrentScreenModeImpl() {
+ int resNumber = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ if(0==resNumber) {
+ return null;
+ }
+ int resIdx = getCurrentScreenResolutionIndex0(display.getHandle(), screen_idx);
+ if(0>resIdx) {
+ return null;
+ }
+ if(resIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber);
+ }
+ int[] res = getScreenModeResolution0(display.getHandle(), screen_idx, resIdx);
+ if(null==res || 0==res.length) {
+ return null;
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber);
+ }
+ int rate = getCurrentScreenRate0(display.getHandle(), screen_idx);
+ if(0>rate) {
+ return null;
+ }
+ int rot = getCurrentScreenRotation0(display.getHandle(), screen_idx);
+ if(0>rot) {
+ return null;
+ }
+
+ int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int i = 0;
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = 32; // FIXME: bpp
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rot;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count
+ return ScreenModeUtil.streamIn(props, 0);
+ }
+
+ protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) {
+ List screenModes = this.getScreenModesOrig();
+ int screenModeIdx = screenModes.indexOf(screenMode);
+ if(0>screenModeIdx) {
+ throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
+ }
+ int resNumber = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
+ if(0>resIdx || resIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode);
+ }
+
+ long dpy = X11Util.createDisplay(display.getName());
+ if( 0 == dpy ) {
+ throw new RuntimeException("Error creating display: "+display.getName());
+ }
+
+ boolean done = false;
+ long t0 = System.currentTimeMillis();
+ try {
+ int f = screenMode.getMonitorMode().getRefreshRate();
+ int r = screenMode.getRotation();
+ if( setCurrentScreenModeStart0(dpy, screen_idx, resIdx, f, r) ) {
+ while(!done && System.currentTimeMillis()-t0 < SCREEN_MODE_CHANGE_TIMEOUT) {
+ done = setCurrentScreenModePollEnd0(dpy, screen_idx, resIdx, f, r);
+ if(!done) {
+ Thread.yield();
+ }
+ }
+ }
+ } finally {
+ X11Util.closeDisplay(dpy);
+ }
+
+ if(!done) {
+ System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
+ (System.currentTimeMillis()-t0)+"ms");
+ }
+ return done;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ private static native long GetScreen0(long dpy, int scrn_idx);
+
+ private static native int getWidth0(long display, int scrn_idx);
+
+ private static native int getHeight0(long display, int scrn_idx);
+
+ /** @return int[] { rot1, .. } */
+ private static native int[] getAvailableScreenModeRotations0(long display, int screen_index);
+
+ private static native int getNumScreenModeResolutions0(long display, int screen_index);
+
+ /** @return int[] { width, height, widthmm, heightmm } */
+ private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index);
+
+ private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index);
+
+ private static native int getCurrentScreenResolutionIndex0(long display, int screen_index);
+ private static native int getCurrentScreenRate0(long display, int screen_index);
+ private static native int getCurrentScreenRotation0(long display, int screen_index);
+
+ /** needs own Display connection for XRANDR event handling */
+ private static native boolean setCurrentScreenModeStart0(long display, int screen_index, int mode_index, int freq, int rot);
+ private static native boolean setCurrentScreenModePollEnd0(long display, int screen_index, int mode_index, int freq, int rot);
+}
diff --git a/src/newt/classes/jogamp/newt/x11/X11Window.java b/src/newt/classes/jogamp/newt/x11/X11Window.java
new file mode 100644
index 000000000..b8f1a0c95
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/x11/X11Window.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.x11;
+
+import com.jogamp.nativewindow.impl.x11.X11Util;
+import com.jogamp.newt.impl.WindowImpl;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.util.Point;
+
+public class X11Window extends WindowImpl {
+ private static final String WINDOW_CLASS_NAME = "NewtWindow";
+
+ static {
+ X11Display.initSingleton();
+ }
+
+ public X11Window() {
+ }
+
+ protected void createNativeImpl() {
+ X11Screen screen = (X11Screen) getScreen();
+ X11Display display = (X11Display) screen.getDisplay();
+ config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config;
+ long visualID = x11config.getVisualID();
+ long w = CreateWindow0(getParentWindowHandle(),
+ display.getHandle(), screen.getIndex(), visualID,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
+ x, y, width, height, isUndecorated());
+ if (w == 0) {
+ throw new NativeWindowException("Error creating window: "+w);
+ }
+ setWindowHandle(w);
+ windowHandleClose = w;
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=windowHandleClose && null!=getScreen() ) {
+ X11Display display = (X11Display) getScreen().getDisplay();
+ try {
+ CloseWindow0(display.getHandle(), windowHandleClose,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom());
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ } finally {
+ windowHandleClose = 0;
+ }
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ setVisible0(getDisplayHandle(), getWindowHandle(), visible, x, y, width, height);
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ reparentHandle=0;
+ reparentCount=0;
+ long reqNewParentHandle = ( fullScreenChange > 0 ) ? 0 : getParentWindowHandle() ;
+
+ reconfigureWindow0( getDisplayHandle(), getScreenIndex(), reqNewParentHandle, getWindowHandle(),
+ x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange);
+ return true;
+ }
+
+ protected void requestFocusImpl(boolean force) {
+ requestFocus0(getDisplayHandle(), getWindowHandle(), force);
+ }
+
+ protected void setTitleImpl(String title) {
+ setTitle0(getDisplayHandle(), getWindowHandle(), title);
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return X11Util.GetRelativeLocation( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs0();
+ private native long CreateWindow0(long parentWindowHandle, long display, int screen_index,
+ long visualID, long javaObjectAtom, long windowDeleteAtom,
+ int x, int y, int width, int height, boolean undecorated);
+ private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom);
+ private native void setVisible0(long display, long windowHandle, boolean visible, int x, int y, int width, int height);
+ private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle,
+ int x, int y, int width, int height, boolean isVisible,
+ boolean parentChange, int fullScreenChange, int decorationChange);
+ private native void setTitle0(long display, long windowHandle, String title);
+ private native void requestFocus0(long display, long windowHandle, boolean force);
+ private native Object getRelativeLocation0(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y);
+
+ private void windowReparented(long gotParentHandle) {
+ reparentHandle = gotParentHandle;
+ reparentCount++;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("******** new parent ("+reparentCount+"): " + toHexString(reparentHandle) );
+ }
+ }
+
+ private long windowHandleClose;
+ private volatile long reparentHandle;
+ private volatile int reparentCount;
+}