summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java441
-rw-r--r--src/newt/classes/com/jogamp/newt/NewtFactory.java81
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java214
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java1854
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java13
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java11
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowListener.java12
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java381
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java (renamed from src/newt/classes/com/jogamp/newt/OffscreenWindow.java)23
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java188
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/WindowImpl.java1771
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java19
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java26
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java94
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java23
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java16
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java71
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java3
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java42
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java836
-rw-r--r--src/newt/native/WindowsWindow.c43
-rw-r--r--src/newt/native/X11Window.c32
35 files changed, 3437 insertions, 2788 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 5e3e32964..b09f63962 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -1,85 +1,95 @@
-/*
- * 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.
- *
+/**
+ * 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;
-import javax.media.nativewindow.*;
-import com.jogamp.nativewindow.impl.RecursiveToolkitLock;
-import com.jogamp.newt.event.*;
-import com.jogamp.newt.impl.event.*;
-import com.jogamp.newt.impl.Debug;
import com.jogamp.newt.util.EDTUtil;
-import com.jogamp.newt.util.MainThread;
-import com.jogamp.newt.util.DefaultEDTUtil;
+import com.jogamp.newt.impl.Debug;
+import com.jogamp.newt.impl.DisplayImpl;
+
import java.util.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+
public abstract class Display {
public static final boolean DEBUG = Debug.debug("Display");
- public static final boolean DEBUG_TEST_EDT_MAINTHREAD = Debug.isPropertyDefined("newt.test.EDTMainThread", true); // JAU EDT Test ..
- 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;
- }
+ /**
+ * @return true if the native display handle is valid and ready to operate,
+ * otherwise false.
+ *
+ * @see #destroy()
+ */
+ public abstract boolean isNativeValid();
+
+ /**
+ * @return number of references by Screen
+ */
+ public abstract int getReferenceCount();
+
+ public abstract void destroy();
+
+ public abstract boolean getDestroyWhenUnused();
+
+ /**
+ *
+ * @param v
+ */
+ public abstract void setDestroyWhenUnused(boolean v);
+ public abstract AbstractGraphicsDevice getGraphicsDevice();
+
+ public abstract String getFQName();
+
+ public abstract long getHandle();
+
+ public abstract int getId();
+
+ public abstract String getName();
+
+ public abstract String getType();
+
+ public abstract EDTUtil getEDTUtil();
+
+ public abstract boolean isEDTRunning();
+
+ public abstract void dispatchMessages();
+
// Global Displays
- private static ArrayList displayList = new ArrayList();
- private static int displaysActive = 0;
- private static int serialno = 1;
+ protected static ArrayList displayList = new ArrayList();
+ protected static int displaysActive = 0;
public static void dumpDisplayList(String prefix) {
synchronized(displayList) {
Iterator i = displayList.iterator();
System.err.println(prefix+" DisplayList[] entries: "+displayList.size()+" - "+getThreadName());
for(int j=0; i.hasNext(); j++) {
- Display d = (Display) i.next();
+ DisplayImpl d = (DisplayImpl) i.next();
System.err.println(" ["+j+"] : "+d);
}
}
@@ -100,219 +110,6 @@ public abstract class Display {
}
}
- /** Make sure to reuse a Display with the same name */
- protected static Display create(String type, String name, final long handle) {
- try {
- Class displayClass = getDisplayClass(type);
- Display display = (Display) displayClass.newInstance();
- name = display.validateDisplayName(name, handle);
- display.name = name;
- display.type=type;
- display.destroyWhenUnused=false;
- synchronized(displayList) {
- display.id = serialno++;
- display.fqname = getFQName(display.id, display.type, display.name);
- displayList.add(display);
- }
- display.createEDTUtil();
- if(DEBUG) {
- System.err.println("Display.create() NEW: "+display+" "+getThreadName());
- }
- return display;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- protected synchronized final void createNative() {
- if(null==aDevice) {
- if(DEBUG) {
- System.err.println("Display.createNative() START ("+getThreadName()+", "+this+")");
- }
- final Display f_dpy = this;
- runOnEDTIfAvail(true, new Runnable() {
- public void run() {
- f_dpy.createNativeImpl();
- }});
- if(null==aDevice) {
- throw new RuntimeException("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;
- }
-
- public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- if( shallRunOnEDT() && null!=edtUtil ) {
- edtUtil.invoke(wait, task);
- } else {
- task.run();
- }
- }
-
- public synchronized final void destroy() {
- if ( null != aDevice ) {
- if(DEBUG) {
- dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
- }
- synchronized(displayList) {
- displayList.remove(this);
- displaysActive--;
- }
- if(DEBUG) {
- System.err.println("Display.destroy(): "+this+" "+getThreadName());
- }
- final Display f_dpy = this;
- final EDTUtil f_edtUtil = edtUtil;
- runOnEDTIfAvail(true, new Runnable() {
- public void run() {
- f_dpy.closeNativeImpl();
- if(null!=f_edtUtil) {
- f_edtUtil.stop();
- }
- }
- } );
- if(null!=edtUtil) {
- if ( DEBUG_TEST_EDT_MAINTHREAD ) {
- MainThread.removePumpMessage(this); // JAU EDT Test ..
- }
- edtUtil.waitUntilStopped();
- edtUtil.reset();
- }
- aDevice = null;
- if(DEBUG) {
- dumpDisplayList("Display.destroy("+getFQName()+") END");
- }
- }
- }
-
- protected synchronized final int addReference() {
- if(DEBUG) {
- System.err.println("Display.addReference() ("+Display.getThreadName()+"): "+refCount+" -> "+(refCount+1));
- }
- if ( 0 == refCount ) {
- createNative();
- }
- if(null == aDevice) {
- throw new RuntimeException("Display.addReference() (refCount "+refCount+") null AbstractGraphicsDevice");
- }
- return ++refCount;
- }
-
-
- protected synchronized final int removeReference() {
- if(DEBUG) {
- System.err.println("Display.removeReference() ("+Display.getThreadName()+"): "+refCount+" -> "+(refCount-1));
- }
- refCount--;
- if(0==refCount && destroyWhenUnused) {
- destroy();
- }
- return refCount;
- }
-
- /**
- * @return number of references by Screen
- */
- public synchronized final int getReferenceCount() {
- return refCount;
- }
-
- public final boolean getDestroyWhenUnused() { return destroyWhenUnused; }
- public final void setDestroyWhenUnused(boolean v) { destroyWhenUnused=v; }
-
- 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 ;
- }
-
- public static final String getFQName(int id, String type, String name) {
- 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();
- }
-
- 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 synchronized void pumpMessages() {
- dispatchMessages();
- }
-
- public String toString() {
- return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", "+aDevice+"]";
- }
-
public static String getThreadName() {
return Thread.currentThread().getName();
}
@@ -325,93 +122,7 @@ public abstract class Display {
return "0x" + Long.toHexString(hex);
}
-
- protected abstract void dispatchMessagesNative();
-
- private Object eventsLock = new Object();
- private LinkedList/*<NEWTEvent>*/ events = new LinkedList();
-
- class DispatchMessagesRunnable implements Runnable {
- public void run() {
- Display.this.dispatchMessages();
- }
- }
- DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
-
- public void dispatchMessages() {
- if(0==refCount) return; // no screens
- if(null==getGraphicsDevice()) return; // no native device
-
- LinkedList/*<NEWTEvent>*/ _events = null;
-
- if(!events.isEmpty()) {
- // swap events list to free ASAP
- synchronized(eventsLock) {
- if(!events.isEmpty()) {
- _events = events;
- events = new LinkedList();
- }
- eventsLock.notifyAll();
- }
- if( null != _events ) {
- for (Iterator iter = _events.iterator(); iter.hasNext(); ) {
- NEWTEventTask eventTask = (NEWTEventTask) iter.next();
- 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();
- }
- }
- }
-
- // lock();
- try {
- dispatchMessagesNative();
- } finally {
- // unlock();
- }
- }
-
- public void enqueueEvent(boolean wait, NEWTEvent e) {
- Object lock = new Object();
- NEWTEventTask eTask = new NEWTEventTask(e, wait?lock:null);
- synchronized(lock) {
- synchronized(eventsLock) {
- events.addLast(eTask);
- eventsLock.notifyAll();
- }
- if( wait ) {
- try {
- lock.wait();
- } catch (InterruptedException ie) {
- throw new RuntimeException(ie);
- }
- }
- }
- }
-
- public void lock() {
- aDevice.lock();
+ public static int hashCode(Object o) {
+ return ( null != o ) ? o.hashCode() : 0;
}
-
- public void unlock() {
- aDevice.unlock();
- }
-
- protected EDTUtil edtUtil = null;
- protected int id;
- protected String name;
- protected String type;
- protected String fqname;
- protected int refCount; // number of Display references by Screen
- protected boolean destroyWhenUnused;
- protected AbstractGraphicsDevice aDevice;
}
-
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index 7c610c1b8..5f969777a 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -1,5 +1,6 @@
/*
* 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
@@ -40,19 +41,22 @@ import java.util.Iterator;
import com.jogamp.common.jvm.JVMUtil;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.impl.DisplayImpl;
+import com.jogamp.newt.impl.ScreenImpl;
+import com.jogamp.newt.impl.WindowImpl;
import com.jogamp.newt.impl.Debug;
-public abstract class NewtFactory {
+public class NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
// Work-around for initialization order problems on Mac OS X
// between native Newt and (apparently) Fmod
static {
JVMUtil.initSingleton();
- Window.init(NativeWindowFactory.getNativeWindowType(true));
+ WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
}
- static Class getCustomClass(String packageName, String classBaseName) {
+ public static Class getCustomClass(String packageName, String classBaseName) {
Class clazz = null;
if(packageName!=null || classBaseName!=null) {
String clazzName = packageName + "." + classBaseName ;
@@ -81,42 +85,43 @@ public abstract class NewtFactory {
* Create a Display entity, incl native creation
*/
public static Display createDisplay(String name) {
- return Display.create(NativeWindowFactory.getNativeWindowType(true), name, 0);
+ return DisplayImpl.create(NativeWindowFactory.getNativeWindowType(true), name, 0);
}
/**
* Create a Display entity using the given implementation type, incl native creation
*/
public static Display createDisplay(String type, String name) {
- return Display.create(type, name, 0);
+ return DisplayImpl.create(type, name, 0);
}
/**
* Create a Screen entity, incl native creation
*/
public static Screen createScreen(Display display, int index) {
- return Screen.create(NativeWindowFactory.getNativeWindowType(true), display, index);
+ return ScreenImpl.create(NativeWindowFactory.getNativeWindowType(true), display, index);
}
/**
* Create a Screen entity using the given implementation type, incl native creation
*/
public static Screen createScreen(String type, Display display, int index) {
- return Screen.create(type, display, index);
+ return ScreenImpl.create(type, display, index);
}
/**
- * Create a top level Window entity, incl native creation
+ * Create a top level Window entity, incl native creation.
+ * The Display/Screen is created and owned, ie destructed atomatic.
*/
- public static Window createWindow(Screen screen, Capabilities caps) {
- return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), screen, caps, false);
+ public static Window createWindow(Capabilities caps) {
+ return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), caps);
}
/**
* Create a top level Window entity, incl native creation
*/
- public static Window createWindow(Screen screen, Capabilities caps, boolean undecorated) {
- return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), screen, caps, undecorated);
+ public static Window createWindow(Screen screen, Capabilities caps) {
+ return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), screen, caps);
}
/**
@@ -131,17 +136,13 @@ public abstract class NewtFactory {
* The parents visibility is passed to the new Window<br></p>
* <p>
* In case <code>parentWindowObject</code> is a different {@link javax.media.nativewindow.NativeWindow} implementation,<br>
- * you have to handle all events appropriatly.<br></p>
+ * you have to handle all events appropriate.<br></p>
* <p>
*
* @param parentWindowObject either a NativeWindow instance
- * @param undecorated only impacts if the window is in top-level state, while attached to a parent window it's rendered undecorated always
*/
- public static Window createWindow(NativeWindow nParentWindow, Capabilities caps, boolean undecorated) {
+ public static Window createWindow(NativeWindow nParentWindow, Capabilities caps) {
final String type = NativeWindowFactory.getNativeWindowType(true);
- if(null==nParentWindow) {
- return createWindowImpl(type, caps, undecorated);
- }
Screen screen = null;
Window parentWindow = null;
@@ -164,33 +165,33 @@ public abstract class NewtFactory {
}
screen.setDestroyWhenUnused(true);
}
- final Window win = createWindowImpl(type, nParentWindow, screen, caps, undecorated);
+ final Window win = createWindowImpl(type, nParentWindow, screen, caps);
win.setSize(nParentWindow.getWidth(), nParentWindow.getHeight());
if ( null != parentWindow ) {
- parentWindow.getInnerWindow().addChild(win);
+ parentWindow.addChild(win);
win.setVisible(parentWindow.isVisible());
}
return win;
}
- protected static Window createWindowImpl(String type, NativeWindow parentNativeWindow, Screen screen, Capabilities caps, boolean undecorated) {
- return Window.create(type, parentNativeWindow, 0, screen, caps, undecorated);
+ protected static Window createWindowImpl(String type, NativeWindow parentNativeWindow, Screen screen, Capabilities caps) {
+ return WindowImpl.create(type, parentNativeWindow, 0, screen, caps);
}
- protected static Window createWindowImpl(String type, long parentWindowHandle, Screen screen, Capabilities caps, boolean undecorated) {
- return Window.create(type, null, parentWindowHandle, screen, caps, undecorated);
+ protected static Window createWindowImpl(String type, long parentWindowHandle, Screen screen, Capabilities caps) {
+ return WindowImpl.create(type, null, parentWindowHandle, screen, caps);
}
- protected static Window createWindowImpl(String type, Screen screen, Capabilities caps, boolean undecorated) {
- return Window.create(type, null, 0, screen, caps, undecorated);
+ protected static Window createWindowImpl(String type, Screen screen, Capabilities caps) {
+ return WindowImpl.create(type, null, 0, screen, caps);
}
- protected static Window createWindowImpl(String type, Capabilities caps, boolean undecorated) {
+ protected static Window createWindowImpl(String type, Capabilities caps) {
Display display = NewtFactory.createDisplay(type, null); // local display
Screen screen = NewtFactory.createScreen(type, display, 0); // screen 0
screen.setDestroyWhenUnused(true);
- return Window.create(type, null, 0, screen, caps, undecorated);
+ return WindowImpl.create(type, null, 0, screen, caps);
}
/**
@@ -199,19 +200,19 @@ public abstract class NewtFactory {
* @param parentWindowObject the native parent window handle
* @param undecorated only impacts if the window is in top-level state, while attached to a parent window it's rendered undecorated always
*/
- public static Window createWindow(long parentWindowHandle, Screen screen, Capabilities caps, boolean undecorated) {
- return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), parentWindowHandle, screen, caps, undecorated);
+ public static Window createWindow(long parentWindowHandle, Screen screen, Capabilities caps) {
+ return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), parentWindowHandle, screen, caps);
}
/**
- * Ability to try a Window type with a construnctor argument, if supported ..<p>
+ * Ability to try a Window type with a constructor argument, if supported ..<p>
* Currently only valid is <code> AWTWindow(Frame frame) </code>,
* to support an external created AWT Frame, ie the browsers embedded frame.
*
* @param undecorated only impacts if the window is in top-level state, while attached to a parent window it's rendered undecorated always
*/
- public static Window createWindow(Object[] cstrArguments, Screen screen, Capabilities caps, boolean undecorated) {
- return Window.create(NativeWindowFactory.getNativeWindowType(true), cstrArguments, screen, caps, undecorated);
+ public static Window createWindow(Object[] cstrArguments, Screen screen, Capabilities caps) {
+ return WindowImpl.create(NativeWindowFactory.getNativeWindowType(true), cstrArguments, screen, caps);
}
/**
@@ -219,19 +220,19 @@ public abstract class NewtFactory {
*
* @param undecorated only impacts if the window is in top-level state, while attached to a parent window it's rendered undecorated always
*/
- public static Window createWindow(String type, Screen screen, Capabilities caps, boolean undecorated) {
- return createWindowImpl(type, null, screen, caps, undecorated);
+ public static Window createWindow(String type, Screen screen, Capabilities caps) {
+ return createWindowImpl(type, null, screen, caps);
}
- public static Window createWindow(String type, Object[] cstrArguments, Screen screen, Capabilities caps, boolean undecorated) {
- return Window.create(type, cstrArguments, screen, caps, undecorated);
+ public static Window createWindow(String type, Object[] cstrArguments, Screen screen, Capabilities caps) {
+ return WindowImpl.create(type, cstrArguments, screen, caps);
}
/**
* Instantiate a Display entity using the native handle.
*/
public static Display createDisplay(String type, long handle) {
- return Display.create(type, null, handle);
+ return DisplayImpl.create(type, null, handle);
}
private static final boolean instanceOf(Object obj, String clazzName) {
@@ -251,7 +252,7 @@ public abstract class NewtFactory {
AbstractGraphicsScreen parentScreen = (AbstractGraphicsScreen) parentConfig.getScreen();
AbstractGraphicsDevice parentDevice = (AbstractGraphicsDevice) parentScreen.getDevice();
- Display childDisplay = childScreen.getDisplay();
+ DisplayImpl childDisplay = (DisplayImpl) childScreen.getDisplay();
String parentDisplayName = childDisplay.validateDisplayName(null, parentDevice.getHandle());
String childDisplayName = childDisplay.getName();
if( ! parentDisplayName.equals( childDisplayName ) ) {
@@ -276,7 +277,7 @@ public abstract class NewtFactory {
if(null != childScreen) {
// check if child Display/Screen is compatible already
- Display childDisplay = childScreen.getDisplay();
+ DisplayImpl childDisplay = (DisplayImpl) childScreen.getDisplay();
String parentDisplayName = childDisplay.validateDisplayName(null, parentDevice.getHandle());
String childDisplayName = childDisplay.getName();
boolean displayEqual = parentDisplayName.equals( childDisplayName );
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index d25da86d8..f1b4254d8 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -1,202 +1,70 @@
-/*
- * 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.
- *
+/**
+ * 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;
-import com.jogamp.newt.impl.*;
-
-import javax.media.nativewindow.*;
-import java.security.*;
-
-public abstract class Screen {
+import com.jogamp.newt.impl.Debug;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+public interface Screen {
public static final boolean DEBUG = Debug.debug("Display");
- 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;
- }
-
- protected static Screen create(String type, Display display, final int idx) {
- try {
- 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);
- }
- }
- Class screenClass = getScreenClass(type);
- Screen screen = (Screen) screenClass.newInstance();
- screen.display = display;
- screen.idx = idx;
- return screen;
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- protected synchronized final void createNative() {
- if(null == aScreen) {
- if(DEBUG) {
- System.err.println("Screen.createNative() START ("+Display.getThreadName()+", "+this+")");
- }
- display.addReference();
- createNativeImpl();
- if(null == aScreen) {
- throw new RuntimeException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
- }
- if(DEBUG) {
- System.err.println("Screen.createNative() END ("+Display.getThreadName()+", "+this+")");
- }
- }
- }
-
- public synchronized final void destroy() {
- if ( null != aScreen ) {
- closeNativeImpl();
- display.removeReference();
- aScreen = null;
- }
- }
-
- protected synchronized final int addReference() {
- if(DEBUG) {
- System.err.println("Screen.addReference() ("+Display.getThreadName()+"): "+refCount+" -> "+(refCount+1));
- }
- if ( 0 == refCount ) {
- createNative();
- }
- if(null == aScreen) {
- throw new RuntimeException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen");
- }
- return ++refCount;
- }
+ boolean isNativeValid();
- protected synchronized final int removeReference() {
- if(DEBUG) {
- System.err.println("Screen.removeReference() ("+Display.getThreadName()+"): "+refCount+" -> "+(refCount-1));
- }
- refCount--;
- if(0==refCount && getDestroyWhenUnused()) {
- destroy();
- }
- return refCount;
- }
-
- /**
+ /**
+ *
* @return number of references by Window
*/
- public synchronized final int getReferenceCount() {
- return refCount;
- }
-
- public final boolean getDestroyWhenUnused() {
- return display.getDestroyWhenUnused();
- }
- public final void setDestroyWhenUnused(boolean v) {
- display.setDestroyWhenUnused(v);
- }
+ int getReferenceCount();
- protected abstract void createNativeImpl();
- protected abstract void closeNativeImpl();
+ void destroy();
- protected void setScreenSize(int w, int h) {
- System.err.println("Detected screen size "+w+"x"+h);
- width=w; height=h;
- }
+ boolean getDestroyWhenUnused();
- public final Display getDisplay() {
- return display;
- }
+ void setDestroyWhenUnused(boolean v);
- public final int getIndex() {
- return idx;
- }
+ AbstractGraphicsScreen getGraphicsScreen();
- public final AbstractGraphicsScreen getGraphicsScreen() {
- return aScreen;
- }
-
- public final boolean isNativeValid() {
- return null != aScreen;
- }
+ int getIndex();
/**
* The actual implementation shall return the detected display value,
* if not we return 800.
* This can be overwritten with the user property 'newt.ws.swidth',
*/
- public final int getWidth() {
- return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
- }
+ int getWidth();
/**
* The actual implementation shall return the detected display value,
* if not we return 480.
* This can be overwritten with the user property 'newt.ws.sheight',
*/
- public final int getHeight() {
- return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
- }
-
- public String toString() {
- return "NEWT-Screen[idx "+idx+", refCount "+refCount+", "+aScreen+", "+display+"]";
- }
+ int getHeight();
- protected Display display;
- protected int idx;
- 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();
+ Display getDisplay();
}
-
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 67374cc00..ef3e5e69c 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -1,884 +1,118 @@
-/*
- * 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.
- *
+/**
+ * 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;
-import com.jogamp.newt.event.*;
-import com.jogamp.newt.util.*;
+import com.jogamp.newt.util.Insets;
+import com.jogamp.newt.event.WindowListener;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.NEWTEventConsumer;
import com.jogamp.newt.impl.Debug;
+import javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.SurfaceUpdatedListener;
-import com.jogamp.common.util.*;
-import javax.media.nativewindow.*;
-import com.jogamp.nativewindow.util.Rectangle;
-import com.jogamp.nativewindow.impl.RecursiveToolkitLock;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Iterator;
-import java.lang.reflect.Method;
-
-public abstract class Window implements NativeWindow, NEWTEventConsumer
-{
+/**
+ * Specifying the public Window functionality for the
+ * using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}.
+ */
+public interface Window extends NativeWindow {
public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent");
public static final boolean DEBUG_WINDOW_EVENT = Debug.debug("Window.WindowEvent");
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
- public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.reparent.incompatible", true);
-
- // 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
- static void init(String type) {
- if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
- try {
- getWindowClass(type);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- 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;
- }
-
- protected static Window create(String type, NativeWindow parentNativeWindow, long parentWindowHandle, Screen screen, Capabilities caps, boolean undecorated) {
- try {
- Class windowClass;
- if(caps.isOnscreen()) {
- windowClass = getWindowClass(type);
- } else {
- windowClass = OffscreenWindow.class;
- }
- Window window = (Window) windowClass.newInstance();
- window.invalidate(true);
- window.parentNativeWindow = parentNativeWindow;
- window.parentWindowHandle = parentWindowHandle;
- window.screen = screen;
- window.caps = (Capabilities)caps.clone();
- window.setUndecorated(undecorated||0!=parentWindowHandle);
- return window;
- } catch (Throwable t) {
- t.printStackTrace();
- throw new NativeWindowException(t);
- }
- }
-
- protected static Window create(String type, Object[] cstrArguments, Screen screen, Capabilities caps, boolean undecorated) {
- try {
- Class windowClass = getWindowClass(type);
- 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));
- }
- Window window = (Window) ReflectionUtil.createInstance( windowClass, cstrArgumentTypes, cstrArguments ) ;
- window.invalidate(true);
- window.screen = screen;
- window.caps = (Capabilities)caps.clone();
- window.setUndecorated(undecorated);
- return window;
- } catch (Throwable t) {
- throw new NativeWindowException(t);
- }
- }
-
- protected Screen screen;
- protected boolean screenReferenced = false;
-
- protected NativeWindow parentNativeWindow;
- protected long parentWindowHandle;
-
- protected Capabilities caps;
- protected AbstractGraphicsConfiguration config;
- protected long windowHandle;
- protected boolean fullscreen, visible;
- protected int width, height, x, y;
-
- // non fullscreen dimensions ..
- protected int nfs_width, nfs_height, nfs_x, nfs_y;
-
- protected String title = "Newt Window";
- protected boolean undecorated = false;
-
- private final boolean createNative() {
- if( null==screen || 0!=windowHandle || !visible ) {
- return 0 != windowHandle ;
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")");
- }
- if(validateParentWindowHandle()) {
- if(!screenReferenced) {
- screenReferenced = true;
- screen.addReference();
- }
- createNativeImpl();
- setVisibleImpl(true);
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.createNative() END ("+getThreadName()+", "+this+")");
- }
- return 0 != windowHandle ;
- }
-
- private boolean validateParentWindowHandle() {
- if(null!=parentNativeWindow) {
- parentWindowHandle = getNativeWindowHandle(parentNativeWindow);
- return 0 != parentWindowHandle ;
- }
- return true;
- }
-
- private static long getNativeWindowHandle(NativeWindow nativeWindow) {
- long handle = 0;
- if(null!=nativeWindow) {
- boolean locked=false;
- try {
- if( NativeWindow.LOCK_SURFACE_NOT_READY < nativeWindow.lockSurface() ) {
- locked=true;
- 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 {
- if(locked) {
- nativeWindow.unlockSurface();
- }
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.getNativeWindowHandle: locked "+locked+", "+nativeWindow);
- }
- }
- return handle;
- }
-
- public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- Screen screen = getInnerWindow().getScreen();
- if(null==screen) {
- throw new RuntimeException("Null screen of inner class: "+this);
- }
- Display d = screen.getDisplay();
- d.runOnEDTIfAvail(wait, task);
- }
-
- /**
- * Create native windowHandle, ie creates a new native invisible window.
- */
- protected abstract void createNativeImpl();
-
- protected abstract void closeNativeImpl();
-
- public Capabilities getRequestedCapabilities() {
- return (Capabilities)caps.clone();
- }
-
- public NativeWindow getParentNativeWindow() {
- return parentNativeWindow;
- }
-
- public Screen getScreen() {
- return screen;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
-
- sb.append(getClass().getName()+"[Config "+config+
- "\n, "+screen+
- "\n, ParentWindow "+parentNativeWindow+
- "\n, ParentWindowHandle "+toHexString(parentWindowHandle)+
- "\n, WindowHandle "+toHexString(getWindowHandle())+
- "\n, SurfaceHandle "+toHexString(getSurfaceHandle())+
- "\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 (Iterator iter = surfaceUpdatedListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("], WindowListeners num "+windowListeners.size()+" [");
- for (Iterator iter = windowListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("], MouseListeners num "+mouseListeners.size()+" [");
- for (Iterator iter = mouseListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("], KeyListeners num "+keyListeners.size()+" [");
- for (Iterator iter = keyListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("] ]");
- return sb.toString();
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- if (title == null) {
- title = "";
- }
- this.title = title;
- if(0 != windowHandle) {
- setTitleImpl(title);
- }
- }
- protected void setTitleImpl(String title) {}
-
- public void setUndecorated(boolean value) {
- undecorated = value;
- }
-
- public boolean isUndecorated(boolean fullscreen) {
- return 0 != parentWindowHandle || undecorated || fullscreen ;
- }
-
- public boolean isUndecorated() {
- return 0 != parentWindowHandle || undecorated || fullscreen ;
- }
-
- public void requestFocus() {
- enqueueRequestFocus(false); // FIXME: or shall we wait ?
- }
- protected void requestFocusImpl() {}
-
- class RequestFocusAction implements Runnable {
- public void run() {
- Window.this.requestFocusImpl();
- }
- }
- RequestFocusAction requestFocusAction = new RequestFocusAction();
-
- public 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(null!=focusAction) {
- return focusAction.run();
- }
- return false;
- }
- protected FocusRunnable focusAction = null;
-
- public static interface FocusRunnable {
- /**
- * @return false if NEWT shall proceed requesting the focus,
- * true if NEWT shall not request the focus.
- */
- public boolean run();
- }
//
- // NativeWindow impl
+ // Lifecycle
//
- /** Recursive and blocking lockSurface() implementation */
- public int lockSurface() {
- // We leave the ToolkitLock lock to the specializtion's discretion,
- // ie the implicit JAWTWindow in case of AWTWindow
-
- windowLock.lock();
-
- // if(windowLock.getRecursionCount() == 0) { // allow recursion to lock again, always
- if(!isNativeValid()) {
- windowLock.unlock();
- return LOCK_SURFACE_NOT_READY;
- }
- // }
- return LOCK_SUCCESS;
- }
-
- /** Recursive and unblocking unlockSurface() implementation */
- public void unlockSurface() throws NativeWindowException {
- windowLock.unlock();
- // We leave the ToolkitLock unlock to the specializtion's discretion,
- // ie the implicit JAWTWindow in case of AWTWindow
- }
-
- public boolean isSurfaceLocked() {
- return windowLock.isLocked();
- }
-
- public Thread getSurfaceLockOwner() {
- return windowLock.getOwner();
- }
-
- public Exception getLockedStack() {
- return windowLock.getLockedStack();
- }
-
- /**
- * <p>
- * destroys the window and children and releases
- * windowing related resources.<br></p>
- * <p>
- * all other resources and states are kept intact,
- * ie listeners, parent handles, size, position and Screen reference.<br></p>
+ /**
+ * @return True if native window is valid, can be created or recovered.
+ * Otherwise false, ie this window is unrecoverable due to a <code>destroy(true)</code> call.
*
* @see #destroy(boolean)
- * @see #invalidate()
- */
- public final void destroy() {
- destroy(false);
- }
-
- /**
- * Destroys the Window and it's children.
- * @param unrecoverable If true, all resources, ie listeners, parent handles,
- * size, position and reference to it's Screen will be destroyed as well.
- * Otherwise you can recreate the window, via <code>setVisible(true)</code>.
- * @see #destroy()
- * @see #invalidate(boolean)
* @see #setVisible(boolean)
*/
- public void destroy(boolean unrecoverable) {
- if(isValid()) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = new String("Window.destroy(unrecoverable: "+unrecoverable+") START "+getThreadName()+", "+this);
- //System.err.println(msg);
- Exception ee = new Exception(msg);
- ee.printStackTrace();
- }
- runOnEDTIfAvail(true, new DestroyAction(unrecoverable));
- }
- }
-
- class DestroyAction implements Runnable {
- boolean unrecoverable;
- public DestroyAction(boolean unrecoverable) {
- this.unrecoverable = unrecoverable;
- }
- public void run() {
- windowLock();
- try {
- // Childs first ..
- synchronized(childWindowsLock) {
- for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
- NativeWindow nw = (NativeWindow) i.next();
- System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") CHILD BEGIN");
- if(nw instanceof Window) {
- ((Window)nw).sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
- if(unrecoverable) {
- ((Window)nw).destroy(unrecoverable);
- }
- } else {
- nw.destroy();
- }
- System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") CHILD END");
- }
- }
-
- // Now us ..
- if(unrecoverable) {
- synchronized(childWindowsLock) {
- childWindows = new ArrayList();
- }
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners = new ArrayList();
- }
- windowListeners = new ArrayList();
- mouseListeners = new ArrayList();
- keyListeners = new ArrayList();
- }
- if( null != screen && 0 != windowHandle ) {
- closeNativeImpl();
- }
- invalidate(unrecoverable);
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") END "+getThreadName()+", "+Window.this);
- }
- } finally {
- windowUnlock();
- }
- }
- }
-
- /**
- * <p>
- * render all native window information invalid,
- * as if the native window was destroyed.<br></p>
- * <p>
- * all other resources and states are kept intact,
- * ie listeners, parent handles and size, position etc.<br></p>
- *
- * @see #destroy()
- * @see #destroy(boolean)
- * @see #invalidate(boolean)
- */
- public void invalidate() {
- invalidate(false);
- }
+ boolean isValid();
/**
- * @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();
- try{
- if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- String msg = new String("!!! Window Invalidate(unrecoverable: "+unrecoverable+") "+getThreadName());
- System.err.println(msg);
- // Exception e = new Exception(msg);
- // e.printStackTrace();
- }
- windowHandle = 0;
- visible = false;
- fullscreen = false;
-
- if(unrecoverable) {
- System.err.println("Window.invalidate: 1 "+screen);
- if(null!=screen) {
- screenReferenced = false;
- screen.removeReference();
- }
- screen = null;
- System.err.println("Window.invalidate: 2 "+screen);
- parentWindowHandle = 0;
- parentNativeWindow = null;
- caps = null;
-
- // Default position and dimension will be re-set immediately by user
- width = 128;
- height = 128;
- x=0;
- y=0;
- }
- } finally {
- windowUnlock();
- }
- }
-
- /** @return true if the native window handle is valid and ready to operate, ie
- * if the native window has been created, otherwise false.
+ * @return true if the native window handle is valid and ready to operate, ie
+ * if the native window has been created, otherwise false.
*
* @see #setVisible(boolean)
* @see #destroy(boolean)
*/
- public boolean isNativeValid() {
- return null != screen && 0 != windowHandle ;
- }
-
- /** @return True if native window is valid, can be created or recovered.
- * Otherwise false, ie this window is unrecoverable due to a <code>destroy(true)</code> call.
- *
- * @see #destroy(boolean)
- * @see #setVisible(boolean)
- */
- public boolean isValid() {
- return null != screen ;
- }
-
- public boolean surfaceSwap() {
- return false;
- }
-
- public long getDisplayHandle() {
- return screen.getDisplay().getHandle();
- }
-
- public int getScreenIndex() {
- return screen.getIndex();
- }
-
- public long getWindowHandle() {
- return windowHandle;
- }
-
- public long getSurfaceHandle() {
- return windowHandle; // default: return window handle
- }
-
- public AbstractGraphicsConfiguration getGraphicsConfiguration() {
- return config;
- }
+ boolean isNativeValid();
/**
- * Returns the width of the client area of this window
- * @return width of the client area
+ * @return The associated Screen
*/
- public int getWidth() {
- return width;
- }
+ Screen getScreen();
/**
- * Returns the height of the client area of this window
- * @return height of the client area
+ * @return The NativeWindow representation of the parent Window,
+ * or null if this Window is top level
*/
- public int getHeight() {
- return height;
- }
+ NativeWindow getParentNativeWindow();
/**
- * Returns the insets for this native window (the difference between the
- * size of the toplevel window with the decorations and the client area).
- *
- * @return insets for this platform window
+ * @return The requested capabilities
*/
- // this probably belongs to NativeWindow interface
- public Insets getInsets() {
- return new Insets(0,0,0,0);
- }
+ Capabilities getRequestedCapabilities();
- /** Returns the most inner Window instance.<br>
- Currently only {@link com.jogamp.newt.opengl.GLWindow}
- has an aggregation to an inner Window instance.
- */
- public Window getInnerWindow() {
- return this;
- }
-
- /** 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;
- }
-
- //
- // Additional methods
- //
-
- public int getX() {
- return x;
- }
-
- public int getY() {
- return y;
- }
-
- public boolean isVisible() {
- return visible;
- }
-
- public boolean isFullscreen() {
- return fullscreen;
- }
-
- private boolean handleDestroyNotify = true;
-
- /** 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;
- }
-
- class ReparentAction implements Runnable {
- /** No native reparenting action */
- static final int ACTION_NONE = 0;
-
- /** Change Window tree only */
- static final int ACTION_SOFT_REPARENTING = 1;
-
- /** Native reparenting incl. Window tree */
- static final int ACTION_NATIVE_REPARENTING = 2;
-
- /** Native window creation after tree change - instead of reparenting. */
- static final int ACTION_NATIVE_CREATION = 3;
-
- NativeWindow newParent;
- public ReparentAction(NativeWindow newParent) {
- this.newParent = newParent;
- }
- public void run() {
- windowLock();
- try{
- Window newParentWindow = null;
- if(newParent instanceof Window) {
- newParentWindow = (Window) newParent;
- }
-
- int reparentAction = -1; // ensure it's set
- long newParentHandle = 0 ;
-
- if(null!=newParent) {
- // Case: Child Window
- newParentHandle = getNativeWindowHandle(newParent);
- if(0 == newParentHandle) {
- // Case: Parent's native window not realized yet
- if(null==newParentWindow) {
- throw new NativeWindowException("Parent not NEWT Window and not realized yet: "+newParent);
- }
- // Destroy this window (handle screen + native) and use parent's Screen.
- // It may be created properly when the parent is made visible.
- destroy(false);
- screen = newParentWindow.getScreen();
- reparentAction = ACTION_SOFT_REPARENTING;
- } else if(newParent != parentNativeWindow) {
- // Case: Parent's native window realized and changed
- if( !isNativeValid() ) {
- // May create a new compatible Screen/Display and
- // mark it for creation.
- if(null!=newParentWindow) {
- screen = newParentWindow.getScreen();
- } else {
- Screen newScreen = NewtFactory.createCompatibleScreen(newParent, screen);
- if( screen != newScreen ) {
- // auto destroy on-the-fly created Screen/Display
- newScreen.setDestroyWhenUnused(true);
- screen = newScreen;
- }
- }
- reparentAction = ACTION_NATIVE_CREATION;
- } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || !NewtFactory.isScreenCompatible(newParent, screen) ) {
- // Destroy this window (handle screen + native) and
- // may create a new compatible Screen/Display and
- // mark it for creation.
- destroy(false);
- if(null!=newParentWindow) {
- screen = newParentWindow.getScreen();
- } else {
- screen = NewtFactory.createCompatibleScreen(newParent, screen);
- screen.setDestroyWhenUnused(true);
- }
- 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_NONE;
- }
- } else {
- // Case: Top Window
- if( 0 == parentWindowHandle ) {
- // Already Top Window
- reparentAction = ACTION_NONE;
- } else {
- // Mark it for native reparenting
- reparentAction = ACTION_NATIVE_REPARENTING;
- }
- }
-
- if ( ACTION_NONE > reparentAction ) {
- throw new NativeWindowException("Internal Error: reparentAction not set");
- }
-
- if( ACTION_NONE == reparentAction ) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparent: NO CHANGE ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow));
- }
- return;
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", reparentAction "+reparentAction+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow));
- }
-
- // rearrange window tree
- if(null!=parentNativeWindow && parentNativeWindow instanceof Window) {
- ((Window)parentNativeWindow).getInnerWindow().removeChild(Window.this);
- }
- parentNativeWindow = newParent;
- if(parentNativeWindow instanceof Window) {
- ((Window)parentNativeWindow).getInnerWindow().addChild(Window.this);
- }
-
- if( ACTION_SOFT_REPARENTING == reparentAction ) {
- return;
- }
-
- if( ACTION_NATIVE_REPARENTING == reparentAction ) {
- Display display = screen.getDisplay();
-
- parentWindowHandle = newParentHandle;
- if(0!=parentWindowHandle) {
- // reset position to 0/0 within parent space
- // FIXME .. cache position ?
- x = 0;
- y = 0;
- }
- getScreen().getDisplay().dispatchMessages(); // status up2date
- boolean wasVisible = isVisible();
- if(wasVisible) {
- Window.this.visible = false;
- setVisibleImpl(false);
- display.dispatchMessages(); // status up2date
- }
- boolean ok = reparentWindowImpl();
- display.dispatchMessages(); // status up2date
- if ( !ok ) {
- // native reparent failed -> try creation
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparent: native reparenting failed ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+" - Trying recreation");
- }
- destroy(false);
- Window.this.visible = wasVisible;
- reparentAction = ACTION_NATIVE_CREATION ;
- } else {
- if(wasVisible) {
- Window.this.visible = true;
- setVisibleImpl(true);
- requestFocusImpl();
- display.dispatchMessages(); // status up2date
- }
- }
- }
-
- // not-else: re-entrance via reparentAction value change possible
- if( ACTION_NATIVE_CREATION == reparentAction ) {
- if(isVisible()) {
- setVisible(true); // native creation
- screen.getDisplay().dispatchMessages(); // status up2date
- }
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow));
- }
- } finally {
- windowUnlock();
- }
- }
- }
+ Capabilities getChosenCapabilities();
/**
- * Change this window's parent window.<br>
- * <P>
- * In case the old parent is not null and a Window,
- * this window is removed from it's list of children.<br>
- * In case the new parent is not null and a Window,
- * this window is added to it's list of children.<br></P>
*
- * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window.
+ * <p>
+ * destroys the window and children and releases
+ * windowing related resources.<br></p>
+ * <p>
+ * all other resources and states are kept intact,
+ * ie listeners, parent handles, size, position and Screen reference.<br></p>
+ *
+ * @see #destroy(boolean)
+ * @see #invalidate()
*/
- public void reparentWindow(NativeWindow newParent) {
- if(isValid()) {
- runOnEDTIfAvail(true, new ReparentAction(newParent));
- if( isVisible() ) {
- sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
- windowRepaint(0, 0, getWidth(), getHeight());
- }
- }
- }
+ void destroy();
- class VisibleAction implements Runnable {
- boolean visible;
- public VisibleAction(boolean visible) {
- this.visible = visible;
- }
- public void run() {
- windowLock();
- try{
- if( isValid() ) {
- if(!visible && childWindows.size()>0) {
- synchronized(childWindowsLock) {
- for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
- NativeWindow nw = (NativeWindow) i.next();
- if(nw instanceof Window) {
- ((Window)nw).setVisible(false);
- }
- }
- }
- }
- if(0==windowHandle && visible) {
- Window.this.visible = visible;
- if( 0<width*height ) {
- createNative();
- }
- } else if(Window.this.visible != visible) {
- Window.this.visible = visible;
- if(0 != windowHandle) {
- setVisibleImpl(visible);
- }
- }
- if(0!=windowHandle && visible && childWindows.size()>0) {
- synchronized(childWindowsLock) {
- for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
- NativeWindow nw = (NativeWindow) i.next();
- if(nw instanceof Window) {
- ((Window)nw).setVisible(true);
- }
- }
- }
- }
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible);
- }
- } finally {
- windowUnlock();
- }
- }
- }
+ /**
+ *
+ * Destroys the Window and it's children.
+ * @param unrecoverable If true, all resources, ie listeners, parent handles,
+ * size, position and reference to it's Screen will be destroyed as well.
+ * Otherwise you can recreate the window, via <code>setVisible(true)</code>.
+ * @see #destroy()
+ * @see #invalidate(boolean)
+ * @see #setVisible(boolean)
+ */
+ void destroy(boolean unrecoverable);
/**
* <p>
@@ -889,14 +123,14 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* <p>
* Zero size semantics are respected, see {@link #setSize(int,int)}:<br>
* <pre>
- * if ( 0 == windowHandle && visible ) {
- * this.visible = visible;
- * if( 0<width*height ) {
- * createNative();
- * }
+ * if ( 0 == windowHandle && visible ) {
+ * this.visible = visible;
+ * if( 0<width*height ) {
+ * createNative();
+ * }
* } else if ( this.visible != visible ) {
- * this.visible = visible;
- * setNativeSizeImpl();
+ * this.visible = visible;
+ * setNativeSizeImpl();
* }
* </pre></p>
* <p>
@@ -905,18 +139,21 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* If this action fails, ie if the parent {@link javax.media.nativewindow.NativeWindow} is not valid yet,<br>
* no native window is created yet and <code>setVisible(true)</code> shall be repeated when it is.<br></p>
*/
- public void setVisible(boolean visible) {
- 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)+", parentNativeWindow "+(null!=parentNativeWindow));
- //System.err.println(msg);
- Exception ee = new Exception(msg);
- ee.printStackTrace();
- }
- if(isValid()) {
- runOnEDTIfAvail(true, new VisibleAction(visible));
- }
- }
- protected abstract void setVisibleImpl(boolean visible);
+ void setVisible(boolean visible);
+
+ boolean isVisible();
+
+ //
+ // Child Window Management
+ //
+
+ void addChild(NativeWindow win);
+
+ void removeChild(NativeWindow win);
+
+ //
+ // Modes / States
+ //
/**
* Sets the size of the client area of the window, excluding decorations
@@ -926,11 +163,11 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* Zero size semantics are respected, see {@link #setVisible(boolean)}:<br>
* <pre>
* if ( 0 != windowHandle && 0>=width*height && visible ) {
- * setVisible(false);
+ * setVisible(false);
* } else if ( 0 == windowHandle && 0<width*height && visible ) {
- * setVisible(true);
+ * setVisible(true);
* } else {
- * // as expected ..
+ * // as expected ..
* }
* </pre></p>
* <p>
@@ -939,48 +176,57 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* @param width of the client area of the window
* @param height of the client area of the window
*/
- public void setSize(int width, int height) {
- int visibleAction = 0; // 1 invisible, 2 visible
- windowLock();
- try{
- if(DEBUG_IMPLEMENTATION) {
- String msg = new String("Window setSize: START "+this.width+"x"+this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
- System.err.println(msg);
- // Exception e = new Exception(msg);
- // e.printStackTrace();
- }
- if (width != this.width || this.height != height) {
- if(!fullscreen) {
- nfs_width=width;
- nfs_height=height;
- if ( 0 != windowHandle && 0>=width*height && visible ) {
- visibleAction=1; // invisible
- this.width = 0;
- this.height = 0;
- } else if ( 0 == windowHandle && 0<width*height && visible ) {
- visibleAction = 2; // visible
- this.width = width;
- this.height = height;
- } else if ( 0 != windowHandle ) {
- // this width/height will be set by windowChanged, called by the native implementation
- setSizeImpl(width, height);
- } else {
- this.width = width;
- this.height = height;
- }
- }
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setSize: END "+this.width+"x"+this.height+", visibleAction "+visibleAction);
- }
- } finally {
- windowUnlock();
- }
- if(visibleAction>0) {
- setVisible( ( 1 == visibleAction ) ? false : true );
- }
+ void setSize(int width, int height);
+
+ /**
+ * Returns the width of the client area of this window
+ * @return width of the client area
+ */
+ int getWidth();
+
+ /**
+ * Returns the height of the client area of this window
+ * @return height of the client area
+ */
+ int getHeight();
+
+ /** Defining ids for the reparenting strategy */
+ public interface ReparentAction {
+ /** No native reparenting valid */
+ static final int ACTION_INVALID = -1;
+
+ /** No native reparenting action required, no change*/
+ static final int ACTION_UNCHANGED = 0;
+
+ /** Native reparenting incl. Window tree */
+ static final int ACTION_NATIVE_REPARENTING = 1;
+
+ /** Native window creation after tree change - instead of reparenting. */
+ static final int ACTION_NATIVE_CREATION = 2;
+
+ /** Change Window tree only, native creation is pending */
+ static final int ACTION_NATIVE_CREATION_PENDING = 3;
}
- protected abstract void setSizeImpl(int width, int height);
+
+ /**
+ * Change this window's parent window.<br>
+ * <P>
+ * In case the old parent is not null and a Window,
+ * this window is removed from it's list of children.<br>
+ * In case the new parent is not null and a Window,
+ * this window is added to it's list of children.<br></P>
+ *
+ * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window.
+ *
+ * @return The issued reparent action type (strategy) as defined in Window.ReparentAction
+ */
+ int reparentWindow(NativeWindow newParent);
+
+ int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate);
+
+ boolean setFullscreen(boolean fullscreen);
+
+ boolean isFullscreen();
/**
* Sets the location of the top left corner of the window, including
@@ -992,774 +238,176 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* @param x coord of the top left corner
* @param y coord of the top left corner
*/
- public void setPosition(int x, int y) {
- windowLock();
- try{
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setPosition: "+this.x+"/"+this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
- }
- if ( this.x != x || this.y != y ) {
- if(!fullscreen) {
- nfs_x=x;
- nfs_y=y;
- if(0!=windowHandle) {
- // this x/y will be set by windowChanged, called by X11
- setPositionImpl(x, y);
- } else {
- this.x = x;
- this.y = y;
- }
- }
- }
- } finally {
- windowUnlock();
- }
- }
- protected abstract void setPositionImpl(int x, int y);
-
- public boolean setFullscreen(boolean fullscreen) {
- windowLock();
- try{
- if(0!=windowHandle && this.fullscreen!=fullscreen) {
- int x,y,w,h;
- if(fullscreen) {
- x = 0; y = 0;
- w = screen.getWidth();
- h = screen.getHeight();
- } else {
- if(0!=parentWindowHandle) {
- x=0;
- y=0;
- } else {
- x = nfs_x;
- y = nfs_y;
- }
- w = nfs_width;
- h = nfs_height;
- }
- if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated());
- }
- this.fullscreen = fullscreen;
- setFullscreenImpl(fullscreen, x, y, w, h);
- }
- } finally {
- windowUnlock();
- }
- if( isVisible() ) {
- windowRepaint(0, 0, getWidth(), getHeight());
- }
- return this.fullscreen;
- }
- protected abstract void setFullscreenImpl(boolean fullscreen, int x, int y, int widht, int height);
+ void setPosition(int x, int y);
+
+ int getX();
- //
- // Child Window Management
- //
+ int getY();
- private ArrayList childWindows = new ArrayList();
- private Object childWindowsLock = new Object();
+ /**
+ * Returns the insets for this native window (the difference between the
+ * size of the toplevel window with the decorations and the client area).
+ *
+ * @return insets for this platform window
+ */
+ Insets getInsets();
- protected void removeChild(NativeWindow win) {
- synchronized(childWindowsLock) {
- childWindows.remove(win);
- }
- }
+ void setUndecorated(boolean value);
+
+ boolean isUndecorated();
+
+ void setTitle(String title);
- protected void addChild(NativeWindow win) {
- if (win == null) {
- return;
- }
- synchronized(childWindowsLock) {
- childWindows.add(win);
- }
+ String getTitle();
+
+ static interface FocusRunnable {
+ /**
+ * @return false if NEWT shall proceed requesting the focus,
+ * true if NEWT shall not request the focus.
+ */
+ public boolean run();
}
- //
- // Generic Event Support
- //
- private void doEvent(boolean enqueue, boolean wait, com.jogamp.newt.event.NEWTEvent event) {
- boolean done = false;
+ /**
+ * 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.
+ */
+ void setFocusAction(FocusRunnable focusAction);
- if(!enqueue) {
- done = consumeEvent(event);
- wait = done; // don't wait if event can't be consumed now
- }
+ void requestFocus();
- if(!done) {
- enqueueEvent(wait, event);
- }
- }
+ void windowRepaint(int x, int y, int width, int height);
- public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
- if(getInnerWindow().isValid()) {
- getInnerWindow().getScreen().getDisplay().enqueueEvent(wait, event);
- }
- }
+ void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event);
+
+ void runOnEDTIfAvail(boolean wait, final Runnable task);
- public boolean consumeEvent(NEWTEvent e) {
- switch(e.getEventType()) {
- case WindowEvent.EVENT_WINDOW_REPAINT:
- if( windowIsLocked() ) {
- // make sure only one repaint event is queued
- if(!repaintQueued) {
- repaintQueued=true;
- return false;
- }
- return true;
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowRepaint: "+e);
- // Exception ee = new Exception("Window.windowRepaint: "+e);
- // ee.printStackTrace();
- }
- repaintQueued=false; // no repaint event queued
- break;
- default:
- break;
- }
- if(e instanceof WindowEvent) {
- getInnerWindow().consumeWindowEvent((WindowEvent)e);
- } else if(e instanceof KeyEvent) {
- getInnerWindow().consumeKeyEvent((KeyEvent)e);
- } else if(e instanceof MouseEvent) {
- getInnerWindow().consumeMouseEvent((MouseEvent)e);
- } else {
- throw new NativeWindowException("Unexpected NEWTEvent type " + e);
- }
- return true;
- }
- protected boolean repaintQueued = false;
//
- // SurfaceUpdatedListener Support
+ // SurfaceUpdateListener
//
- private ArrayList surfaceUpdatedListeners = new ArrayList();
- private Object surfaceUpdatedListenersLock = new Object();
-
- /**
- * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of
+ /**
+ * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of
* the list.
*/
- public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- getInnerWindow().addSurfaceUpdatedListener(-1, l);
- }
+ void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- 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);
- }
- }
+ void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
- public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- if (l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners.remove(l);
- }
- }
+ void removeAllSurfaceUpdatedListener();
- public void removeAllSurfaceUpdatedListener() {
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners = new ArrayList();
- }
- }
+ void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
- public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size()-1;
- }
- return (SurfaceUpdatedListener) surfaceUpdatedListeners.get(index);
- }
- }
+ SurfaceUpdatedListener getSurfaceUpdatedListener(int index);
- public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- synchronized(surfaceUpdatedListenersLock) {
- return (SurfaceUpdatedListener[]) surfaceUpdatedListeners.toArray();
- }
- }
+ SurfaceUpdatedListener[] getSurfaceUpdatedListeners();
- public void surfaceUpdated(Object updater, NativeWindow window, long when) {
- synchronized(surfaceUpdatedListenersLock) {
- for(Iterator i = surfaceUpdatedListeners.iterator(); i.hasNext(); ) {
- SurfaceUpdatedListener l = (SurfaceUpdatedListener) i.next();
- l.surfaceUpdated(updater, window, when);
- }
- }
- }
//
- // MouseListener/Event Support
+ // WindowListener
//
- private ArrayList mouseListeners = new ArrayList();
- private int mouseButtonPressed = 0; // current pressed mouse button number
- private long lastMousePressed = 0; // last time when a mouse button was pressed
- private int lastMouseClickCount = 0; // last mouse button click count
- public static final int ClickTimeout = 300;
-
- 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<ClickTimeout) {
- 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<ClickTimeout) {
- 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 sendWindowEvent(int eventType);
- /**
- * Appends the given {@link com.jogamp.newt.event.MouseListener} to the end of
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.WindowListener} to the end of
* the list.
*/
- public void addMouseListener(MouseListener l) {
- getInnerWindow().addMouseListener(-1, l);
- }
+ void addWindowListener(WindowListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.MouseListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.WindowListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- 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;
- }
+ void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException;
- public MouseListener getMouseListener(int index) {
- ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
- if(0>index) {
- index = clonedListeners.size()-1;
- }
- return (MouseListener) clonedListeners.get(index);
- }
+ void removeWindowListener(WindowListener l);
- public MouseListener[] getMouseListeners() {
- return (MouseListener[]) mouseListeners.toArray();
- }
+ WindowListener getWindowListener(int index);
- protected void consumeMouseEvent(MouseEvent e) {
- if(DEBUG_MOUSE_EVENT) {
- System.err.println("consumeMouseEvent: event: "+e);
- }
-
- for(Iterator i = mouseListeners.iterator(); i.hasNext(); ) {
- MouseListener l = (MouseListener) i.next();
- 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());
- }
- }
- }
+ WindowListener[] getWindowListeners();
//
- // KeyListener/Event Support
+ // KeyListener
//
- 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) );
- }
- /**
- * Appends the given {@link com.jogamp.newt.event.KeyListener} to the end of
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.KeyListener} to the end of
* the list.
*/
- public void addKeyListener(KeyListener l) {
- getInnerWindow().addKeyListener(-1, l);
- }
+ void addKeyListener(KeyListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.KeyListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.KeyListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- 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;
- }
+ void addKeyListener(int index, KeyListener l);
- public void removeKeyListener(KeyListener l) {
- if (l == null) {
- return;
- }
- ArrayList clonedListeners = (ArrayList) keyListeners.clone();
- clonedListeners.remove(l);
- keyListeners = clonedListeners;
- }
+ void removeKeyListener(KeyListener l);
- public KeyListener getKeyListener(int index) {
- ArrayList clonedListeners = (ArrayList) keyListeners.clone();
- if(0>index) {
- index = clonedListeners.size()-1;
- }
- return (KeyListener) clonedListeners.get(index);
- }
+ KeyListener getKeyListener(int index);
- public KeyListener[] getKeyListeners() {
- return (KeyListener[]) keyListeners.toArray();
- }
+ KeyListener[] getKeyListeners();
- private ArrayList keyListeners = new ArrayList();
-
- protected void consumeKeyEvent(KeyEvent e) {
- if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e);
- }
- for(Iterator i = keyListeners.iterator(); i.hasNext(); ) {
- KeyListener l = (KeyListener) i.next();
- 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
+ // MouseListener
//
- 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()) );
- }
- private ArrayList windowListeners = new ArrayList();
-
- /**
- * Appends the given {@link com.jogamp.newt.event.WindowListener} to the end of
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.MouseListener} to the end of
* the list.
*/
- public void addWindowListener(WindowListener l) {
- getInnerWindow().addWindowListener(-1, l);
- }
+ void addMouseListener(MouseListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.WindowListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.MouseListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- 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;
- }
+ void addMouseListener(int index, MouseListener l);
- public 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);
- }
+ void removeMouseListener(MouseListener l);
- public WindowListener[] getWindowListeners() {
- return (WindowListener[]) windowListeners.toArray();
- }
-
- protected void consumeWindowEvent(WindowEvent e) {
- if(DEBUG_WINDOW_EVENT) {
- System.err.println("consumeWindowEvent: "+e);
- }
- for(Iterator i = windowListeners.iterator(); i.hasNext(); ) {
- WindowListener l = (WindowListener) i.next();
- 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_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());
- }
- }
- }
+ MouseListener getMouseListener(int index);
- /**
- * @param focusGained
- */
- protected void focusChanged(boolean focusGained) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.focusChanged: "+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));
- // Exception e = new Exception("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
- // e.printStackTrace();
- }
- this.visible = visible ;
- }
+ MouseListener[] getMouseListeners();
- protected void sizeChanged(int newWidth, int newHeight) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.sizeChanged: "+width+"x"+height+" -> "+newWidth+"x"+newHeight);
- }
- if(width != newWidth || height != newHeight) {
- width = newWidth;
- height = newHeight;
- if(!fullscreen) {
- nfs_width=width;
- nfs_height=height;
- }
- sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
- }
- }
-
- protected void positionChanged(int newX, int newY) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.positionChanged: "+x+"/"+y+" -> "+newX+"/"+newY);
- }
- if( 0==parentWindowHandle && ( x != newX || y != newY ) ) {
- x = newX;
- y = newY;
- if(!fullscreen) {
- nfs_x=x;
- nfs_y=y;
- }
- sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
- }
- }
-
- /**
- * 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;
- }
-
- protected void windowDestroyNotify() {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyNotify START "+getThreadName());
- }
-
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
-
- if(handleDestroyNotify && isValid()) {
- destroy();
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyeNotify END "+getThreadName());
- }
- }
-
- protected void windowDestroyed() {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyed "+getThreadName());
- }
- invalidate();
- }
-
- public boolean getPropagateRepaint() {
- return propagateRepaint;
- }
- public void setPropagateRepaint(boolean v) {
- propagateRepaint = v;
- }
- protected boolean propagateRepaint = true;
-
- public void windowRepaint(int x, int y, int width, int height) {
- if(!propagateRepaint) {
- return;
- }
- 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 boolean reparentWindowImpl() {
- // default implementation, no native reparenting support
- return false;
- }
-
- //
- // 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 RecursiveToolkitLock windowLock = new RecursiveToolkitLock();
-
- private static final boolean TRACE_LOCK = false;
-
- protected final void windowLock() {
- getInnerWindow().windowLock.lock();
- if(TRACE_LOCK) {
- Exception e = new Exception("WINDOW LOCK SET: R "+getInnerWindow().windowLock.getRecursionCount()+", "+getInnerWindow().windowLock);
- e.printStackTrace();
- }
- }
- protected final void windowUnlock() {
- getInnerWindow().windowLock.unlock();
- if(TRACE_LOCK) {
- Exception e = new Exception("WINDOW LOCK FREE: R "+getInnerWindow().windowLock.getRecursionCount()+", "+getInnerWindow().windowLock);
- e.printStackTrace();
- }
- }
- protected final boolean windowIsLocked() {
- return getInnerWindow().windowLock.isLocked();
- }
- protected RecursiveToolkitLock getWindowLock() {
- return getInnerWindow().windowLock;
- }
- 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/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 51b218aec..fdb434889 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -29,14 +29,12 @@
package com.jogamp.newt.awt;
+import com.jogamp.newt.Display;
import java.lang.reflect.*;
import java.security.*;
-import java.awt.Button;
import java.awt.Canvas;
-import java.awt.Component;
import java.awt.EventQueue;
-import java.awt.Frame;
import java.awt.Graphics;
import javax.media.nativewindow.*;
@@ -44,12 +42,7 @@ import javax.media.nativewindow.*;
import com.jogamp.newt.event.awt.AWTAdapter;
import com.jogamp.newt.event.awt.AWTParentWindowAdapter;
import com.jogamp.newt.event.WindowEvent;
-import com.jogamp.newt.event.WindowAdapter;
-import com.jogamp.newt.event.MouseEvent;
-import com.jogamp.newt.event.MouseAdapter;
-import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
-import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.impl.Debug;
public class NewtCanvasAWT extends java.awt.Canvas {
@@ -92,7 +85,7 @@ public class NewtCanvasAWT extends java.awt.Canvas {
public final boolean result = false; // NEWT shall always proceed requesting the native focus
public void run() {
if(DEBUG) {
- System.err.println("FocusActionImpl.run() "+Window.getThreadName());
+ System.err.println("FocusActionImpl.run() "+Display.getThreadName());
}
NewtCanvasAWT.this.requestFocusAWTParent();
}
@@ -120,7 +113,7 @@ public class NewtCanvasAWT extends java.awt.Canvas {
return newtChild;
}
- /** @return this AWT Canvas NativeWindow represention, may be null in case {@link #removeNotify()} has been called,
+ /** @return this AWT Canvas NativeWindow representation, may be null in case {@link #removeNotify()} has been called,
* or {@link #addNotify()} hasn't been called yet.*/
public NativeWindow getNativeWindow() { return parent; }
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java
index b28d41f7c..7b9130188 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java
@@ -29,23 +29,12 @@
package com.jogamp.newt.awt;
-import java.awt.GraphicsConfiguration;
-import java.awt.GraphicsDevice;
-import java.awt.Component;
-import java.awt.Canvas;
-import javax.media.opengl.*;
import javax.media.nativewindow.*;
import javax.media.nativewindow.awt.*;
-import com.jogamp.newt.event.awt.AWTParentWindowAdapter;
-import com.jogamp.newt.Display;
-import com.jogamp.newt.Screen;
-import com.jogamp.newt.Window;
import com.jogamp.newt.NewtFactory;
-import com.jogamp.newt.util.EDTUtil;
import com.jogamp.newt.impl.Debug;
-import com.jogamp.common.util.ReflectionUtil;
public class NewtFactoryAWT extends NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowListener.java b/src/newt/classes/com/jogamp/newt/event/WindowListener.java
index 1a10131f7..174d4a414 100644
--- a/src/newt/classes/com/jogamp/newt/event/WindowListener.java
+++ b/src/newt/classes/com/jogamp/newt/event/WindowListener.java
@@ -1,5 +1,6 @@
/*
* 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
@@ -36,10 +37,21 @@ package com.jogamp.newt.event;
import com.jogamp.newt.*;
public interface WindowListener extends NEWTEventListener {
+ /** Window is resized, your application shall respect the new window dimension. A repaint is recommended. */
public void windowResized(WindowEvent e);
+
+ /** Window has been moved. */
public void windowMoved(WindowEvent e);
+
+ /** Window will be destroyed. Release of resources is recommended. */
public void windowDestroyNotify(WindowEvent e);
+
+ /** Window gained focus. */
public void windowGainedFocus(WindowEvent e);
+
+ /** Window lost focus. */
public void windowLostFocus(WindowEvent e);
+
+ /** Window area shall be repainted. */
public void windowRepaint(WindowUpdateEvent e);
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java
new file mode 100644
index 000000000..4f839ed42
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java
@@ -0,0 +1,381 @@
+/*
+ * 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.*;
+import javax.media.nativewindow.*;
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.impl.event.*;
+import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.newt.util.MainThread;
+import java.util.*;
+
+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 DisplayImpl create(String type, String name, final long handle) {
+ try {
+ Class displayClass = getDisplayClass(type);
+ DisplayImpl display = (DisplayImpl) displayClass.newInstance();
+ name = display.validateDisplayName(name, handle);
+ display.name = name;
+ display.type=type;
+ display.destroyWhenUnused=false;
+ synchronized(displayList) {
+ display.id = serialno++;
+ display.fqname = getFQName(display.id, display.type, display.name);
+ displayList.add(display);
+ }
+ display.createEDTUtil();
+ if(DEBUG) {
+ System.err.println("Display.create() NEW: "+display+" "+getThreadName());
+ }
+ return display;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected synchronized final void createNative() {
+ if(null==aDevice) {
+ if(DEBUG) {
+ System.err.println("Display.createNative() START ("+getThreadName()+", "+this+")");
+ }
+ final DisplayImpl f_dpy = this;
+ runOnEDTIfAvail(true, new Runnable() {
+ public void run() {
+ f_dpy.createNativeImpl();
+ }});
+ if(null==aDevice) {
+ throw new RuntimeException("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 synchronized final void destroy() {
+ if ( null != aDevice ) {
+ if(DEBUG) {
+ dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
+ }
+ synchronized(displayList) {
+ displayList.remove(this);
+ displaysActive--;
+ }
+ if(DEBUG) {
+ System.err.println("Display.destroy(): "+this+" "+getThreadName());
+ }
+ final DisplayImpl f_dpy = this;
+ final EDTUtil f_edtUtil = edtUtil;
+ stopEDT( new Runnable() {
+ public void run() {
+ f_dpy.closeNativeImpl();
+ }
+ } );
+ if(null!=edtUtil) {
+ if ( DEBUG_TEST_EDT_MAINTHREAD ) {
+ MainThread.removePumpMessage(this); // JAU EDT Test ..
+ }
+ edtUtil.waitUntilStopped();
+ edtUtil.reset();
+ }
+ aDevice = null;
+ if(DEBUG) {
+ dumpDisplayList("Display.destroy("+getFQName()+") END");
+ }
+ }
+ }
+
+ protected 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 RuntimeException("Display.addReference() (refCount "+refCount+") null AbstractGraphicsDevice");
+ }
+ return ++refCount;
+ }
+
+
+ protected synchronized final int removeReference() {
+ if(DEBUG) {
+ System.err.println("Display.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ }
+ refCount--;
+ if(0==refCount && destroyWhenUnused) {
+ destroy();
+ }
+ return refCount;
+ }
+
+ public synchronized final int getReferenceCount() {
+ return refCount;
+ }
+
+ public final boolean getDestroyWhenUnused() { return destroyWhenUnused; }
+ public final void setDestroyWhenUnused(boolean v) { destroyWhenUnused=v; }
+
+ 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 ;
+ }
+
+ public static final String getFQName(int id, String type, String name) {
+ 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();
+ }
+
+ 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 LinkedList/*<NEWTEvent>*/ events = new LinkedList();
+
+ 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
+
+ LinkedList/*<NEWTEvent>*/ _events = null;
+
+ if(!events.isEmpty()) {
+ // swap events list to free ASAP
+ synchronized(eventsLock) {
+ if(!events.isEmpty()) {
+ _events = events;
+ events = new LinkedList();
+ }
+ eventsLock.notifyAll();
+ }
+ if( null != _events ) {
+ for (Iterator iter = _events.iterator(); iter.hasNext(); ) {
+ NEWTEventTask eventTask = (NEWTEventTask) iter.next();
+ 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();
+ }
+ }
+ }
+
+ // lock();
+ try {
+ // System.err.println("Display.dispatchMessages() NATIVE "+this+" "+getThreadName());
+ dispatchMessagesNative();
+ } finally {
+ // unlock();
+ // System.err.println("Display.dispatchMessages() X "+this+" "+getThreadName());
+ }
+ }
+
+ public void enqueueEvent(boolean wait, NEWTEvent e) {
+ Object lock = new Object();
+ NEWTEventTask eTask = new NEWTEventTask(e, wait?lock:null);
+ synchronized(lock) {
+ synchronized(eventsLock) {
+ events.addLast(eTask);
+ eventsLock.notifyAll();
+ }
+ if( wait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throw new RuntimeException(ie);
+ }
+ }
+ }
+ }
+
+ public void lock() {
+ aDevice.lock();
+ }
+
+ public void unlock() {
+ aDevice.unlock();
+ }
+
+ protected EDTUtil edtUtil = null;
+ protected int id;
+ protected String name;
+ protected String type;
+ protected String fqname;
+ protected int refCount; // number of Display references by Screen
+ protected boolean destroyWhenUnused;
+ protected AbstractGraphicsDevice aDevice;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/OffscreenWindow.java b/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java
index d17f8df07..217d9d293 100644
--- a/src/newt/classes/com/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java
@@ -1,5 +1,6 @@
/*
* 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
@@ -31,11 +32,11 @@
*
*/
-package com.jogamp.newt;
+package com.jogamp.newt.impl;
import javax.media.nativewindow.*;
-public class OffscreenWindow extends Window implements SurfaceChangeable {
+public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
long surfaceHandle = 0;
@@ -45,20 +46,20 @@ public class OffscreenWindow extends Window implements SurfaceChangeable {
static long nextWindowHandle = 0x100; // start here - a marker
protected void createNativeImpl() {
- if(0!=parentWindowHandle) {
+ if(0!=getParentWindowHandle()) {
throw new NativeWindowException("OffscreenWindow does not support window parenting");
}
if(caps.isOnscreen()) {
throw new NativeWindowException("Capabilities is onscreen");
}
- AbstractGraphicsScreen aScreen = screen.getGraphicsScreen();
+ AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
config = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(caps, null, aScreen);
if (config == null) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
synchronized(OffscreenWindow.class) {
- windowHandle = nextWindowHandle++;
+ setWindowHandle(nextWindowHandle++);
}
}
@@ -66,12 +67,13 @@ public class OffscreenWindow extends Window implements SurfaceChangeable {
// nop
}
- public void invalidate() {
- super.invalidate();
+ public void invalidate(boolean unrecoverable) {
+ super.invalidate(unrecoverable);
surfaceHandle = 0;
}
- public synchronized void destroy(boolean deep) {
+ public synchronized void destroy(boolean unrecoverable) {
+ super.destroy(unrecoverable);
surfaceHandle = 0;
}
@@ -86,6 +88,9 @@ public class OffscreenWindow extends Window implements SurfaceChangeable {
protected void setVisibleImpl(boolean visible) {
}
+ protected void requestFocusImpl(boolean reparented) {
+ }
+
public void setSize(int width, int height) {
if(!visible) {
this.width = width;
@@ -107,7 +112,7 @@ public class OffscreenWindow extends Window implements SurfaceChangeable {
// nop
return false;
}
- protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) {
+ protected void reconfigureWindowImpl(int x, int y, int width, int height) {
shouldNotCallThis();
}
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java
new file mode 100644
index 000000000..0104b4a4c
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java
@@ -0,0 +1,188 @@
+/*
+ * 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.*;
+
+import javax.media.nativewindow.*;
+import java.security.*;
+
+public abstract class ScreenImpl implements Screen {
+
+ 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 ScreenImpl create(String type, Display display, final int idx) {
+ try {
+ 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);
+ }
+ }
+ Class screenClass = getScreenClass(type);
+ ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
+ screen.display = (DisplayImpl) display;
+ screen.idx = idx;
+ return screen;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected synchronized final void createNative() {
+ if(null == aScreen) {
+ if(DEBUG) {
+ System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ display.addReference();
+ createNativeImpl();
+ if(null == aScreen) {
+ throw new RuntimeException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
+ }
+ if(DEBUG) {
+ System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ }
+ }
+
+ public synchronized final void destroy() {
+ if ( null != aScreen ) {
+ closeNativeImpl();
+ display.removeReference();
+ aScreen = null;
+ }
+ }
+
+ protected synchronized final int addReference() {
+ if(DEBUG) {
+ System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ }
+ if ( 0 == refCount ) {
+ createNative();
+ }
+ if(null == aScreen) {
+ throw new RuntimeException("Screen.addReference() (refCount "+refCount+") null AbstractGraphicsScreen");
+ }
+ return ++refCount;
+ }
+
+ protected synchronized final int removeReference() {
+ if(DEBUG) {
+ System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ }
+ refCount--;
+ if(0==refCount && getDestroyWhenUnused()) {
+ destroy();
+ }
+ return refCount;
+ }
+
+ public synchronized final int getReferenceCount() {
+ return refCount;
+ }
+
+ public final boolean getDestroyWhenUnused() {
+ return display.getDestroyWhenUnused();
+ }
+ public final void setDestroyWhenUnused(boolean v) {
+ display.setDestroyWhenUnused(v);
+ }
+
+ protected abstract void createNativeImpl();
+ protected abstract void closeNativeImpl();
+
+ 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 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[idx "+idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]";
+ }
+
+ protected DisplayImpl display;
+ protected int idx;
+ 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();
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
new file mode 100644
index 000000000..9111419fc
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
@@ -0,0 +1,1771 @@
+/*
+ * 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.NewtFactory;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.util.*;
+
+import com.jogamp.common.util.*;
+import javax.media.nativewindow.*;
+import com.jogamp.nativewindow.util.Rectangle;
+import com.jogamp.nativewindow.impl.RecursiveToolkitLock;
+import com.jogamp.newt.impl.OffscreenWindow;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.lang.reflect.Method;
+
+public abstract class WindowImpl implements Window, NEWTEventConsumer
+{
+ public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
+
+ // 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(String type, NativeWindow parentWindow, long parentWindowHandle, Screen screen, Capabilities caps) {
+ try {
+ Class windowClass;
+ if(caps.isOnscreen()) {
+ windowClass = getWindowClass(type);
+ } else {
+ windowClass = OffscreenWindow.class;
+ }
+ WindowImpl window = (WindowImpl) windowClass.newInstance();
+ window.invalidate(true);
+ window.parentWindow = parentWindow;
+ window.parentWindowHandle = parentWindowHandle;
+ window.screen = (ScreenImpl) screen;
+ window.caps = (Capabilities)caps.clone();
+ window.setUndecorated(0!=parentWindowHandle);
+ return window;
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw new NativeWindowException(t);
+ }
+ }
+
+ public static WindowImpl create(String type, Object[] cstrArguments, Screen screen, Capabilities caps) {
+ try {
+ Class windowClass = getWindowClass(type);
+ 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.invalidate(true);
+ window.screen = (ScreenImpl) screen;
+ window.caps = (Capabilities)caps.clone();
+ return window;
+ } catch (Throwable t) {
+ throw new NativeWindowException(t);
+ }
+ }
+
+ public static interface LifecycleHook {
+ /**
+ * Invoked after Window setVisible,
+ * allows allocating resources depending on the native Window.
+ * Called from EDT.
+ */
+ void setVisibleAction(boolean visible, boolean nativeWindowCreated);
+
+ /**
+ * Invoked before Window destroy action,
+ * allows releasing of resources depending on the native Window.
+ * Called from EDT.
+ */
+ void destroyAction(boolean unrecoverable);
+
+ /** Only informal, when starting reparenting */
+ void reparentActionPre();
+
+ /** Only informal, when finishing reparenting */
+ void reparentActionPost(int reparentActionType);
+ }
+
+ private LifecycleHook lifecycleHook = null;
+ private RecursiveToolkitLock windowLock = new RecursiveToolkitLock();
+ private long windowHandle;
+ private ScreenImpl screen;
+ private boolean screenReferenced = false;
+ private NativeWindow parentWindow;
+ private long parentWindowHandle;
+
+ protected AbstractGraphicsConfiguration config;
+ protected Capabilities caps;
+ protected boolean fullscreen, visible;
+ protected int width, height, x, y;
+
+ // non fullscreen dimensions ..
+ protected int nfs_width, nfs_height, nfs_x, nfs_y;
+
+ protected String title = "Newt Window";
+ protected boolean undecorated = false;
+
+ private final void setScreen(ScreenImpl newScreen) {
+ if(screenReferenced) {
+ screenReferenced = false;
+ screen.removeReference();
+ }
+ screen = newScreen;
+ }
+
+ private boolean createNative() {
+ if( null==screen || 0!=windowHandle || !visible ) {
+ return 0 != windowHandle ;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")");
+ }
+ if( null != parentWindow &&
+ NativeWindow.LOCK_SURFACE_NOT_READY >= parentWindow.lockSurface() ) {
+ throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
+ }
+ try {
+ if(validateParentWindowHandle()) {
+ if(!screenReferenced) {
+ screenReferenced = true;
+ screen.addReference();
+ }
+ createNativeImpl();
+ setVisibleImpl(true);
+ }
+ } finally {
+ if(null!=parentWindow) {
+ parentWindow.unlockSurface();
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.createNative() END ("+getThreadName()+", "+this+")");
+ }
+ return 0 != windowHandle ;
+ }
+
+ 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 locked=false;
+ try {
+ if( NativeWindow.LOCK_SURFACE_NOT_READY < nativeWindow.lockSurface() ) {
+ locked=true;
+ 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 {
+ if(locked) {
+ nativeWindow.unlockSurface();
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.getNativeWindowHandle: locked "+locked+", "+nativeWindow);
+ }
+ }
+ return handle;
+ }
+
+
+ //----------------------------------------------------------------------
+ // NativeWindow: Native implementation
+ //
+
+ protected int lockSurfaceImpl() { return LOCK_SUCCESS; }
+
+ protected void unlockSurfaceImpl() { }
+
+ //----------------------------------------------------------------------
+ // Window: Native implementation
+ //
+
+ protected abstract void createNativeImpl();
+
+ protected abstract void closeNativeImpl();
+
+ protected abstract void requestFocusImpl(boolean reparented);
+
+ protected abstract void setVisibleImpl(boolean visible);
+
+ protected abstract void setSizeImpl(int width, int height);
+
+ protected abstract void setPositionImpl(int x, int y);
+
+ protected abstract void reconfigureWindowImpl(int x, int y, int width, int height);
+
+ protected void setTitleImpl(String title) {}
+
+ //----------------------------------------------------------------------
+ // NativeWindow
+ //
+
+ public final int lockSurface() {
+ // We leave the ToolkitLock lock to the specializtion's discretion,
+ // ie the implicit JAWTWindow in case of AWTWindow
+
+ // may throw RuntimeException if timed out while waiting for lock
+ windowLock.lock();
+
+ int res = lockSurfaceImpl();
+ if(!isNativeValid()) {
+ windowLock.unlock();
+ res = LOCK_SURFACE_NOT_READY;
+ }
+ return res;
+ }
+
+ public final void unlockSurface() {
+ // may throw RuntimeException if not locked
+ windowLock.validateLocked();
+
+ unlockSurfaceImpl();
+
+ windowLock.unlock();
+ // We leave the ToolkitLock unlock to the specializtion's discretion,
+ // ie the implicit JAWTWindow in case of AWTWindow
+ }
+
+ public final boolean isSurfaceLockedByOtherThread() {
+ return windowLock.isLockedByOtherThread();
+ }
+
+ public final boolean isSurfaceLocked() {
+ return windowLock.isLocked();
+ }
+
+ public final Thread getSurfaceLockOwner() {
+ return windowLock.getOwner();
+ }
+
+ public final Exception getSurfaceLockStack() {
+ return windowLock.getLockedStack();
+ }
+
+ public final long getDisplayHandle() {
+ return getScreen().getDisplay().getHandle();
+ }
+
+ public final int getScreenIndex() {
+ return getScreen().getIndex();
+ }
+
+ public AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config;
+ }
+
+ public final long getWindowHandle() {
+ return windowHandle;
+ }
+
+ public long getSurfaceHandle() {
+ return windowHandle; // default: return window handle
+ }
+
+ public boolean surfaceSwap() {
+ return false;
+ }
+
+ //----------------------------------------------------------------------
+ // Window
+ //
+
+ public final boolean isNativeValid() {
+ return null != getScreen() && 0 != getWindowHandle() ;
+ }
+
+ public final boolean isValid() {
+ return null != getScreen() ;
+ }
+
+ public final NativeWindow getParentNativeWindow() {
+ return parentWindow;
+ }
+
+ public final Screen getScreen() {
+ return screen;
+ }
+
+ public void setVisible(boolean visible) {
+ 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(this.parentWindowHandle)+", parentWindow "+(null!=this.parentWindow)/*+", "+this*/);
+ System.err.println(msg);
+ //Exception ee = new Exception(msg);
+ //ee.printStackTrace();
+ }
+ if(isValid()) {
+ VisibleAction va = new VisibleAction(visible);
+ runOnEDTIfAvail(true, va);
+ if( va.getChanged() ) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+
+ }
+ }
+
+ 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( isValid() ) {
+ if(!visible && childWindows.size()>0) {
+ synchronized(childWindowsLock) {
+ for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
+ NativeWindow nw = (NativeWindow) i.next();
+ if(nw instanceof WindowImpl) {
+ ((WindowImpl)nw).setVisible(false);
+ }
+ }
+ }
+ }
+ if(0==windowHandle && visible) {
+ WindowImpl.this.visible = visible;
+ if( 0<width*height ) {
+ nativeWindowCreated = createNative();
+ }
+ } else if(WindowImpl.this.visible != visible) {
+ WindowImpl.this.visible = visible;
+ if(0 != windowHandle) {
+ setVisibleImpl(visible);
+ madeVisible = visible;
+ }
+ }
+
+ if(null!=lifecycleHook) {
+ lifecycleHook.setVisibleAction(visible, nativeWindowCreated);
+ }
+
+ if(0!=windowHandle && visible && childWindows.size()>0) {
+ synchronized(childWindowsLock) {
+ for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
+ NativeWindow nw = (NativeWindow) i.next();
+ 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();
+ }
+ getScreen().getDisplay().dispatchMessages(); // status up2date
+ }
+ }
+
+ public void setSize(int width, int height) {
+ int visibleAction = 0; // 1 invisible, 2 visible
+ windowLock.lock();
+ try{
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window setSize: START "+this.width+"x"+this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
+ System.err.println(msg);
+ // Exception e = new Exception(msg);
+ // e.printStackTrace();
+ }
+ if (width != this.width || this.height != height) {
+ if(!fullscreen) {
+ nfs_width=width;
+ nfs_height=height;
+ if ( 0 != windowHandle && 0>=width*height && visible ) {
+ visibleAction=1; // invisible
+ this.width = 0;
+ this.height = 0;
+ } else if ( 0 == windowHandle && 0<width*height && visible ) {
+ visibleAction = 2; // visible
+ this.width = width;
+ this.height = height;
+ } else if ( 0 != windowHandle ) {
+ // this width/height will be set by windowChanged, called by the native implementation
+ setSizeImpl(width, height);
+ } else {
+ this.width = width;
+ this.height = height;
+ }
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: END "+this.width+"x"+this.height+", visibleAction "+visibleAction);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ if(visibleAction>0) {
+ setVisible( ( 1 == visibleAction ) ? false : true );
+ }
+ }
+
+ public final void destroy() {
+ destroy(false);
+ }
+
+ public void destroy(boolean unrecoverable) {
+ if(isValid()) {
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window.destroy(unrecoverable: "+unrecoverable+") START "+getThreadName()/*+", "+this*/);
+ System.err.println(msg);
+ //Exception ee = new Exception(msg);
+ //ee.printStackTrace();
+ }
+ runOnEDTIfAvail(true, new DestroyAction(unrecoverable));
+ }
+ }
+
+ class DestroyAction implements Runnable {
+ boolean unrecoverable;
+ public DestroyAction(boolean unrecoverable) {
+ this.unrecoverable = unrecoverable;
+ }
+ public void run() {
+ windowLock.lock();
+ try {
+ if( !isValid() ) {
+ return; // nop
+ }
+
+ // Childs first ..
+ synchronized(childWindowsLock) {
+ // 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);
+ if(unrecoverable) {
+ ((WindowImpl)nw).destroy(unrecoverable);
+ }
+ } else {
+ nw.destroy();
+ }
+ }
+ }
+
+ if(null!=lifecycleHook) {
+ lifecycleHook.destroyAction(unrecoverable);
+ }
+
+ // Now us ..
+ if(unrecoverable) {
+ if(null!=parentWindow && parentWindow instanceof Window) {
+ ((Window)parentWindow).removeChild(WindowImpl.this);
+ }
+ synchronized(childWindowsLock) {
+ childWindows = new ArrayList();
+ }
+ synchronized(surfaceUpdatedListenersLock) {
+ surfaceUpdatedListeners = new ArrayList();
+ }
+ windowListeners = new ArrayList();
+ mouseListeners = new ArrayList();
+ keyListeners = new ArrayList();
+ }
+ if( null != screen && 0 != windowHandle ) {
+ closeNativeImpl();
+ }
+ invalidate(unrecoverable);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") END "+getThreadName()/*+", "+WindowImpl.this*/);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ /**
+ * <p>
+ * render all native window information invalid,
+ * as if the native window was destroyed.<br></p>
+ * <p>
+ * all other resources and states are kept intact,
+ * ie listeners, parent handles and size, position etc.<br></p>
+ *
+ * @see #destroy()
+ * @see #destroy(boolean)
+ * @see #invalidate(boolean)
+ */
+ public final void invalidate() {
+ invalidate(false);
+ }
+
+ /**
+ * @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);
+ // Exception e = new Exception(msg);
+ // e.printStackTrace();
+ }
+ windowHandle = 0;
+ visible = false;
+ fullscreen = false;
+
+ if(unrecoverable) {
+ setScreen(null);
+ parentWindowHandle = 0;
+ parentWindow = null;
+ caps = 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 int getStrategy() {
+ return reparentAction;
+ }
+
+ public void run() {
+ boolean wasVisible;
+ boolean displayChanged = false;
+
+ 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.hashCode(parentWindow)+", new parentWindow: "+Display.hashCode(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE);
+ }
+
+ if(null!=newParentWindow) {
+ // 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 (handle screen + native) and use parent's Screen.
+ // It may be created properly when the parent is made visible.
+ destroy(false);
+ setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
+ displayChanged = true;
+ reparentAction = ACTION_NATIVE_CREATION_PENDING;
+ } else if(newParentWindow != getParentNativeWindow()) {
+ // 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
+ newScreen.setDestroyWhenUnused(true);
+ setScreen( (ScreenImpl) newScreen );
+ displayChanged = true;
+ }
+ }
+ reparentAction = ACTION_NATIVE_CREATION;
+ } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ||
+ !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
+ // Destroy this window (handle screen + native) and
+ // may create a new compatible Screen/Display and
+ // mark it for creation.
+ destroy(false);
+ if(null!=newParentWindowNEWT) {
+ setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
+ } else {
+ setScreen( (ScreenImpl) NewtFactory.createCompatibleScreen(newParentWindow, getScreen()) );
+ screen.setDestroyWhenUnused(true);
+ }
+ displayChanged = true;
+ 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 {
+ // Case: Top Window
+ if( 0 == getParentWindowHandle() ) {
+ // Already Top Window
+ reparentAction = ACTION_UNCHANGED;
+ } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) {
+ // Destroy this window (handle screen + native) and
+ // keep Screen/Display and
+ // mark it for creation.
+ destroy(false);
+ reparentAction = ACTION_NATIVE_CREATION;
+ } 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 ) {
+ NativeWindow parentWindowLocked = null;
+ if( null != parentWindow ) {
+ parentWindowLocked = parentWindow;
+ if(NativeWindow.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) {
+ throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
+ }
+ }
+ try {
+ if(0!=parentWindowHandle) {
+ // reset position to 0/0 within parent space
+ // FIXME .. cache position ?
+ x = 0;
+ y = 0;
+ }
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessages(); // status up2date
+ if(wasVisible) {
+ visible = false;
+ setVisibleImpl(false);
+ display.dispatchMessages(); // status up2date
+ }
+ boolean ok = reparentWindowImpl();
+ display.dispatchMessages(); // status up2date
+ if ( !ok ) {
+ // 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(false);
+ reparentAction = ACTION_NATIVE_CREATION ;
+ } if(wasVisible) {
+ visible = true;
+ setVisibleImpl(true);
+ requestFocusImpl(true);
+ display.dispatchMessages(); // status up2date
+ }
+ } finally {
+ if(null!=parentWindowLocked) {
+ parentWindowLocked.unlockSurface();
+ }
+ }
+ }
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCode(parentWindow));
+ }
+ } finally {
+ windowLock.unlock();
+ }
+
+ if( ACTION_NATIVE_CREATION == reparentAction && wasVisible ) {
+ // This may run on the the Display/Screen connection,
+ // hence a new EDT task
+ runOnEDTIfAvail(true, reparentActionRecreate);
+ }
+ }
+ }
+
+ 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.hashCode(parentWindow));
+ }
+ setVisible(true); // native creation
+ requestFocus();
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+ private ReparentActionRecreate reparentActionRecreate = new ReparentActionRecreate();
+
+ public final int reparentWindow(NativeWindow newParent) {
+ return reparentWindow(newParent, false);
+ }
+
+ public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
+ int reparentActionStrategy = ReparentAction.ACTION_INVALID;
+ if(isValid()) {
+ if(null!=lifecycleHook) {
+ lifecycleHook.reparentActionPre();
+ }
+ try {
+ ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
+ runOnEDTIfAvail(true, reparentAction);
+ reparentActionStrategy = reparentAction.getStrategy();
+ if( isVisible() ) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ } finally {
+ if(null!=lifecycleHook) {
+ lifecycleHook.reparentActionPost(reparentActionStrategy);
+ }
+ }
+ }
+ return reparentActionStrategy;
+ }
+
+ public final Capabilities getChosenCapabilities() {
+ return config.getNativeGraphicsConfiguration().getChosenCapabilities();
+ }
+
+ public final Capabilities getRequestedCapabilities() {
+ return (Capabilities)caps.clone();
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ if (title == null) {
+ title = "";
+ }
+ this.title = title;
+ if(0 != getWindowHandle()) {
+ setTitleImpl(title);
+ }
+ }
+
+ public void setUndecorated(boolean value) {
+ if(this.undecorated != value) {
+ undecorated = value;
+ if( 0 != windowHandle ) {
+ reconfigureWindowImpl(x, y, width, height);
+ requestFocus();
+ }
+ }
+ }
+
+ public boolean isUndecorated(boolean fullscreen) {
+ return 0 != getParentWindowHandle() || undecorated || fullscreen ;
+ }
+
+ public boolean isUndecorated() {
+ return 0 != parentWindowHandle || undecorated || fullscreen ;
+ }
+
+ public void requestFocus() {
+ enqueueRequestFocus(false); // FIXME: or shall we wait ?
+ }
+
+ 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 (Iterator iter = surfaceUpdatedListeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("], WindowListeners num "+windowListeners.size()+" [");
+ for (Iterator iter = windowListeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("], MouseListeners num "+mouseListeners.size()+" [");
+ for (Iterator iter = mouseListeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ sb.append("], KeyListeners num "+keyListeners.size()+" [");
+ for (Iterator iter = keyListeners.iterator(); iter.hasNext(); ) {
+ sb.append(iter.next()+", ");
+ }
+ 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() {
+ WindowImpl.this.requestFocusImpl(false);
+ }
+ }
+ RequestFocusAction requestFocusAction = new RequestFocusAction();
+
+ public 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) {
+ 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;
+ }
+ protected FocusRunnable focusAction = null;
+
+ private boolean handleDestroyNotify = true;
+
+ public void setPosition(int x, int y) {
+ windowLock.lock();
+ try{
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setPosition: "+this.x+"/"+this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
+ }
+ if ( this.x != x || this.y != y ) {
+ if(!fullscreen) {
+ nfs_x=x;
+ nfs_y=y;
+ if(0!=windowHandle) {
+ // this x/y will be set by windowChanged, called by X11
+ setPositionImpl(x, y);
+ } else {
+ this.x = x;
+ this.y = y;
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+
+ public boolean setFullscreen(boolean fullscreen) {
+ windowLock.lock();
+ try{
+ if(0!=windowHandle && this.fullscreen!=fullscreen) {
+ int x,y,w,h;
+ if(fullscreen) {
+ x = 0; y = 0;
+ w = screen.getWidth();
+ h = screen.getHeight();
+ } else {
+ if(0!=parentWindowHandle) {
+ x=0;
+ y=0;
+ } else {
+ x = nfs_x;
+ y = nfs_y;
+ }
+ w = nfs_width;
+ h = nfs_height;
+ }
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
+ }
+ this.fullscreen = fullscreen;
+ reconfigureWindowImpl(x, y, w, h);
+ requestFocus();
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ if( isVisible() ) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ return this.fullscreen;
+ }
+
+ //----------------------------------------------------------------------
+ // Child Window Management
+ //
+
+ private ArrayList childWindows = new ArrayList();
+ private Object childWindowsLock = new Object();
+
+ 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;
+ }
+ protected boolean repaintQueued = false;
+
+ //
+ // SurfaceUpdatedListener Support
+ //
+
+ private ArrayList surfaceUpdatedListeners = new ArrayList();
+ private Object surfaceUpdatedListenersLock = new Object();
+
+ 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, NativeWindow window, long when) {
+ synchronized(surfaceUpdatedListenersLock) {
+ for(Iterator i = surfaceUpdatedListeners.iterator(); i.hasNext(); ) {
+ SurfaceUpdatedListener l = (SurfaceUpdatedListener) i.next();
+ l.surfaceUpdated(updater, window, when);
+ }
+ }
+ }
+
+ //
+ // MouseListener/Event Support
+ //
+ private ArrayList mouseListeners = new ArrayList();
+ private int mouseButtonPressed = 0; // current pressed mouse button number
+ private long lastMousePressed = 0; // last time when a mouse button was pressed
+ private int lastMouseClickCount = 0; // last mouse button click count
+ public static final int ClickTimeout = 300;
+
+ 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<ClickTimeout) {
+ 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<ClickTimeout) {
+ 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(Iterator i = mouseListeners.iterator(); i.hasNext(); ) {
+ MouseListener l = (MouseListener) i.next();
+ 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();
+ }
+
+ private ArrayList keyListeners = new ArrayList();
+
+ protected void consumeKeyEvent(KeyEvent e) {
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e);
+ }
+ for(Iterator i = keyListeners.iterator(); i.hasNext(); ) {
+ KeyListener l = (KeyListener) i.next();
+ 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()) );
+ }
+
+ private ArrayList windowListeners = new ArrayList();
+
+ 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);
+ }
+ for(Iterator i = windowListeners.iterator(); i.hasNext(); ) {
+ WindowListener l = (WindowListener) i.next();
+ 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_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()+"): "+focusGained+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ 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));
+ // Exception e = new Exception("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ // e.printStackTrace();
+ }
+ this.visible = visible ;
+ }
+
+ protected void sizeChanged(int newWidth, int newHeight) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.sizeChanged: ("+getThreadName()+"): "+width+"x"+height+" -> "+newWidth+"x"+newHeight+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ if(width != newWidth || height != newHeight) {
+ width = newWidth;
+ height = newHeight;
+ if(!fullscreen) {
+ nfs_width=width;
+ nfs_height=height;
+ }
+ if(isNativeValid()) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
+ }
+ }
+ }
+
+ protected void positionChanged(int newX, int newY) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.positionChanged: ("+getThreadName()+"): "+x+"/"+y+" -> "+newX+"/"+newY+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ if( 0==parentWindowHandle && ( x != newX || y != newY ) ) {
+ x = newX;
+ y = newY;
+ if(!fullscreen) {
+ nfs_x=x;
+ nfs_y=y;
+ }
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
+ }
+ }
+
+ protected void windowDestroyNotify() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.windowDestroyNotify START "+getThreadName());
+ }
+
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
+
+ if(handleDestroyNotify && isValid()) {
+ destroy();
+ }
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.windowDestroyeNotify END "+getThreadName());
+ }
+ }
+
+ protected void windowDestroyed() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.windowDestroyed "+getThreadName());
+ }
+ invalidate();
+ }
+
+ 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);
+ }
+ 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));
+ if(isNativeValid()) {
+ doEvent(false, false, e);
+ }
+ }
+
+ protected boolean reparentWindowImpl() {
+ // default implementation, no native reparenting support
+ return false;
+ }
+
+ 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/com/jogamp/newt/impl/awt/AWTDisplay.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java
index 3290309bb..0199d6c72 100644
--- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java
@@ -36,11 +36,12 @@ 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 Display {
+public class AWTDisplay extends DisplayImpl {
public AWTDisplay() {
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
index eec83d721..eaf758b2d 100644
--- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
@@ -34,11 +34,12 @@
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 Screen {
+public class AWTScreen extends ScreenImpl {
public AWTScreen() {
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
index 9da1eb860..e4452d2c8 100644
--- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
@@ -50,6 +50,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import com.jogamp.newt.Window;
+import com.jogamp.newt.impl.WindowImpl;
import java.awt.Insets;
import javax.media.nativewindow.*;
import javax.media.nativewindow.awt.*;
@@ -58,7 +59,7 @@ import javax.media.nativewindow.awt.*;
AWT. This is provided for convenience of porting to platforms
supporting Java SE. */
-public class AWTWindow extends Window {
+public class AWTWindow extends WindowImpl {
public AWTWindow() {
this(null);
@@ -84,7 +85,7 @@ public class AWTWindow extends Window {
// non fullscreen dimensions ..
private int nfs_width, nfs_height, nfs_x, nfs_y;
- protected void requestFocusImpl() {
+ protected void requestFocusImpl(boolean reparented) {
runOnEDT(true, new Runnable() {
public void run() {
container.requestFocus();
@@ -104,7 +105,7 @@ public class AWTWindow extends Window {
protected void createNativeImpl() {
- if(0!=parentWindowHandle) {
+ if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
}
@@ -145,11 +146,11 @@ public class AWTWindow extends Window {
}
}
});
- this.windowHandle = 1; // just a marker ..
+ setWindowHandle(1); // just a marker ..
}
protected void closeNativeImpl() {
- this.windowHandle = 0; // just a marker ..
+ setWindowHandle(0); // just a marker ..
if(null!=container) {
runOnEDT(true, new Runnable() {
public void run() {
@@ -207,7 +208,7 @@ public class AWTWindow extends Window {
DisplayMode mode = ((AWTGraphicsDevice)config.getScreen().getDevice()).getGraphicsDevice().getDisplayMode();
int w = mode.getWidth();
int h = mode.getHeight();
- ((AWTScreen)screen).setScreenSize(w, h);
+ ((AWTScreen)getScreen()).setScreenSize(w, h);
}
protected void setSizeImpl(final int width, final int height) {
@@ -248,7 +249,7 @@ public class AWTWindow extends Window {
}
}
- protected void setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) {
+ protected void reconfigureWindowImpl(final int x, final int y, final int width, final int height) {
/** An AWT event on setSize() would bring us in a deadlock situation, hence invokeLater() */
runOnEDT(false, new Runnable() {
public void run() {
@@ -262,7 +263,7 @@ public class AWTWindow extends Window {
}
}
container.setLocation(x, y);
- container.setSize(w, h);
+ container.setSize(width, height);
}
});
}
@@ -272,7 +273,7 @@ public class AWTWindow extends Window {
}
private void runOnEDT(boolean wait, Runnable r) {
- EDTUtil edtUtil = screen.getDisplay().getEDTUtil();
+ EDTUtil edtUtil = getScreen().getDisplay().getEDTUtil();
if ( ( null != edtUtil && edtUtil.isCurrentThreadEDT() ) || EventQueue.isDispatchThread() ) {
r.run();
} else {
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java
index c8e69dac6..0bd4c3b5d 100644
--- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java
@@ -36,7 +36,7 @@ package com.jogamp.newt.impl.intel.gdl;
import com.jogamp.newt.impl.*;
import javax.media.nativewindow.*;
-public class Display extends com.jogamp.newt.Display {
+public class Display extends com.jogamp.newt.impl.DisplayImpl {
static int initCounter = 0;
static {
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
index 3aded5df3..c5253e142 100644
--- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
@@ -36,7 +36,7 @@ package com.jogamp.newt.impl.intel.gdl;
import com.jogamp.newt.impl.*;
import javax.media.nativewindow.*;
-public class Screen extends com.jogamp.newt.Screen {
+public class Screen extends com.jogamp.newt.impl.ScreenImpl {
static {
Display.initSingleton();
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
index 5f40a35ae..040fa15a9 100644
--- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
@@ -35,7 +35,7 @@ package com.jogamp.newt.impl.intel.gdl;
import javax.media.nativewindow.*;
-public class Window extends com.jogamp.newt.Window {
+public class Window extends com.jogamp.newt.impl.WindowImpl {
static {
Display.initSingleton();
}
@@ -46,11 +46,11 @@ public class Window extends com.jogamp.newt.Window {
static long nextWindowHandle = 1;
protected void createNativeImpl() {
- if(0!=parentWindowHandle) {
+ if(0!=getParentWindowHandle()) {
throw new NativeWindowException("GDL Window does not support window parenting");
}
- AbstractGraphicsScreen aScreen = screen.getGraphicsScreen();
- AbstractGraphicsDevice aDevice = screen.getDisplay().getGraphicsDevice();
+ AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
config = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(caps, null, aScreen);
if (config == null) {
@@ -58,9 +58,9 @@ public class Window extends com.jogamp.newt.Window {
}
synchronized(Window.class) {
- windowHandle = nextWindowHandle++;
+ setWindowHandle(nextWindowHandle++); // just a marker
- surfaceHandle = CreateSurface(aDevice.getHandle(), screen.getWidth(), screen.getHeight(), x, y, width, height);
+ surfaceHandle = CreateSurface(aDevice.getHandle(), getScreen().getWidth(), getScreen().getHeight(), x, y, width, height);
if (surfaceHandle == 0) {
throw new NativeWindowException("Error creating window");
}
@@ -73,13 +73,13 @@ public class Window extends com.jogamp.newt.Window {
CloseSurface(getDisplayHandle(), surfaceHandle);
}
surfaceHandle = 0;
- ((Display)screen.getDisplay()).setFocus(null);
+ ((Display)getScreen().getDisplay()).setFocus(null);
}
}
protected void setVisibleImpl(boolean visible) {
if(visible) {
- ((Display)screen.getDisplay()).setFocus(this);
+ ((Display)getScreen().getDisplay()).setFocus(this);
}
}
@@ -109,17 +109,17 @@ public class Window extends com.jogamp.newt.Window {
}
}
- protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) {
+ protected void reconfigureWindowImpl(int x, int y, int width, int height) {
if(0!=surfaceHandle) {
- SetBounds0(surfaceHandle, screen.getWidth(), screen.getHeight(), x, y, w, h);
+ SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), x, y, width, height);
}
}
- protected void requestFocusImpl() {
- ((Display)screen.getDisplay()).setFocus(this);
+ protected void requestFocusImpl(boolean reparented) {
+ ((Display)getScreen().getDisplay()).setFocus(this);
}
- public long getSurfaceHandle() {
+ public final long getSurfaceHandle() {
return surfaceHandle;
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java
index 9b8689114..42cdb9ca3 100644
--- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java
@@ -41,7 +41,7 @@ import com.jogamp.newt.impl.*;
import com.jogamp.newt.util.EDTUtil;
import com.jogamp.newt.util.MainThread;
-public class MacDisplay extends Display {
+public class MacDisplay extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
index 317a3161c..21018b2be 100644
--- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
@@ -34,9 +34,10 @@
package com.jogamp.newt.impl.macosx;
import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
import javax.media.nativewindow.*;
-public class MacScreen extends Screen {
+public class MacScreen extends ScreenImpl {
static {
MacDisplay.initSingleton();
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
index 7571c05be..6432f363e 100644
--- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
@@ -41,7 +41,7 @@ import com.jogamp.newt.event.*;
import com.jogamp.newt.impl.*;
import com.jogamp.newt.util.*;
-public class MacWindow extends Window {
+public class MacWindow extends WindowImpl {
// Window styles
private static final int NSBorderlessWindowMask = 0;
@@ -153,8 +153,8 @@ public class MacWindow extends Window {
nsViewLock.lock();
try {
if(DEBUG_IMPLEMENTATION) { System.out.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
- if (windowHandle != 0) {
- close0(windowHandle);
+ if (getWindowHandle() != 0) {
+ close0(getWindowHandle());
}
} catch (Throwable t) {
if(DEBUG_IMPLEMENTATION) {
@@ -162,28 +162,14 @@ public class MacWindow extends Window {
e.printStackTrace();
}
} finally {
- windowHandle = 0;
+ setWindowHandle(0);
nsViewLock.unlock();
}
windowDestroyed(); // No OSX hook for DidClose, so do it here
}
- public long getWindowHandle() {
- nsViewLock.lock();
- try {
- return windowHandle;
- } finally {
- nsViewLock.unlock();
- }
- }
-
- public long getSurfaceHandle() {
- nsViewLock.lock();
- try {
- return surfaceHandle;
- } finally {
- nsViewLock.unlock();
- }
+ public final long getSurfaceHandle() {
+ return surfaceHandle;
}
public Insets getInsets() {
@@ -200,18 +186,12 @@ public class MacWindow extends Window {
private RecursiveToolkitLock nsViewLock = new RecursiveToolkitLock();
- public synchronized int lockSurface() throws NativeWindowException {
+ protected int lockSurfaceImpl() {
nsViewLock.lock();
- try {
- return super.lockSurface();
- } catch (RuntimeException re) {
- nsViewLock.unlock();
- throw re;
- }
+ return LOCK_SUCCESS;
}
- public void unlockSurface() {
- super.unlockSurface();
+ protected void unlockSurfaceImpl() {
nsViewLock.unlock();
}
@@ -220,12 +200,12 @@ public class MacWindow extends Window {
try {
if (visible) {
createWindow(false, getX(), getY(), getWidth(), getHeight(), isFullscreen());
- if (windowHandle != 0) {
- makeKeyAndOrderFront0(windowHandle);
+ if (getWindowHandle() != 0) {
+ makeKeyAndOrderFront0(getWindowHandle());
}
} else {
- if (windowHandle != 0) {
- orderOut0(windowHandle);
+ if (getWindowHandle() != 0) {
+ orderOut0(getWindowHandle());
}
}
} finally {
@@ -237,21 +217,17 @@ public class MacWindow extends Window {
// FIXME: move nsViewLock up to window lock
nsViewLock.lock();
try {
- if (windowHandle != 0) {
- setTitle0(windowHandle, title);
- }
+ setTitle0(getWindowHandle(), title);
} finally {
nsViewLock.unlock();
}
}
- protected void requestFocusImpl() {
+ protected void requestFocusImpl(boolean reparented) {
// FIXME: move nsViewLock up to window lock
nsViewLock.lock();
try {
- if (windowHandle != 0) {
- makeKey0(windowHandle);
- }
+ makeKey0(getWindowHandle());
} finally {
nsViewLock.unlock();
}
@@ -261,9 +237,7 @@ public class MacWindow extends Window {
// this width/height will be set by sizeChanged, called by OSX
nsViewLock.lock();
try {
- if (windowHandle != 0) {
- setContentSize0(windowHandle, width, height);
- }
+ setContentSize0(getWindowHandle(), width, height);
} finally {
nsViewLock.unlock();
}
@@ -273,23 +247,21 @@ public class MacWindow extends Window {
// this x/y will be set by positionChanged, called by OSX
nsViewLock.lock();
try {
- if (windowHandle != 0) {
- setFrameTopLeftPoint0(parentWindowHandle, windowHandle, x, y);
- }
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), x, y);
} finally {
nsViewLock.unlock();
}
}
- protected void setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) {
+ protected void reconfigureWindowImpl(int x, int y, int width, int height) {
nsViewLock.lock();
try {
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- System.err.println("MacWindow fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h);
+ System.err.println("MacWindow reconfig: "+fullscreen+" "+x+"/"+y+" "+width+"x"+height);
}
- createWindow(true, x, y, w, h, fullscreen);
- if (windowHandle != 0) {
- makeKeyAndOrderFront0(windowHandle);
+ createWindow(true, x, y, width, height, fullscreen);
+ if (getWindowHandle() != 0) {
+ makeKeyAndOrderFront0(getWindowHandle());
}
} finally {
nsViewLock.unlock();
@@ -402,36 +374,36 @@ public class MacWindow extends Window {
private void createWindow(final boolean recreate, final int x, final int y, final int width, final int height, final boolean fullscreen) {
- if(0!=windowHandle && !recreate) {
+ if(0!=getWindowHandle() && !recreate) {
return;
}
try {
//runOnEDTIfAvail(true, new Runnable() {
// public void run() {
- if(0!=windowHandle) {
+ if(0!=getWindowHandle()) {
// save the view .. close the window
- surfaceHandle = changeContentView0(parentWindowHandle, windowHandle, 0);
+ surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0);
if(recreate && 0==surfaceHandle) {
throw new NativeWindowException("Internal Error - recreate, window but no view");
}
- close0(windowHandle);
- windowHandle=0;
+ close0(getWindowHandle());
+ setWindowHandle(0);
} else {
surfaceHandle = 0;
}
- windowHandle = createWindow0(parentWindowHandle,
+ setWindowHandle(createWindow0(getParentWindowHandle(),
x, y, width, height, fullscreen,
(isUndecorated(fullscreen) ?
NSBorderlessWindowMask :
NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
NSBackingStoreBuffered,
- getScreen().getIndex(), surfaceHandle);
- if (windowHandle == 0) {
+ getScreen().getIndex(), surfaceHandle));
+ if (getWindowHandle() == 0) {
throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this);
}
- surfaceHandle = contentView0(windowHandle);
- setTitle0(windowHandle, getTitle());
+ surfaceHandle = contentView0(getWindowHandle());
+ setTitle0(getWindowHandle(), getTitle());
// don't make the window visible on window creation
// makeKeyAndOrderFront0(windowHandle);
// } } );
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java
index 8b8ce1f41..18d058a9c 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java
@@ -38,7 +38,7 @@ import com.jogamp.opengl.impl.egl.*;
import javax.media.nativewindow.*;
import javax.media.nativewindow.egl.*;
-public class Display extends com.jogamp.newt.Display {
+public class Display extends com.jogamp.newt.impl.DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
index f38e7b4dc..50fdf92e5 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
@@ -35,7 +35,7 @@ package com.jogamp.newt.impl.opengl.broadcom.egl;
import javax.media.nativewindow.*;
-public class Screen extends com.jogamp.newt.Screen {
+public class Screen extends com.jogamp.newt.impl.ScreenImpl {
static {
Display.initSingleton();
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
index d6b802a85..947e28c27 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
@@ -38,7 +38,7 @@ import javax.media.nativewindow.*;
import javax.media.opengl.GLCapabilities;
import javax.media.nativewindow.NativeWindowException;
-public class Window extends com.jogamp.newt.Window {
+public class Window extends com.jogamp.newt.impl.WindowImpl {
static {
Display.initSingleton();
}
@@ -47,7 +47,7 @@ public class Window extends com.jogamp.newt.Window {
}
protected void createNativeImpl() {
- if(0!=parentWindowHandle) {
+ if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
// query a good configuration .. even thought we drop this one
@@ -58,8 +58,8 @@ public class Window extends com.jogamp.newt.Window {
}
setSizeImpl(getScreen().getWidth(), getScreen().getHeight());
- windowHandle = realizeWindow(true, width, height);
- if (0 == windowHandle) {
+ setWindowHandle(realizeWindow(true, width, height));
+ if (0 == getWindowHandle()) {
throw new NativeWindowException("Error native Window Handle is null");
}
}
@@ -72,8 +72,10 @@ public class Window extends com.jogamp.newt.Window {
protected void setVisibleImpl(boolean visible) { }
+ protected void requestFocusImpl(boolean reparented) { }
+
protected void setSizeImpl(int width, int height) {
- if(0!=windowHandle) {
+ if(0!=getWindowHandle()) {
// n/a in BroadcomEGL
System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window");
} else {
@@ -87,17 +89,14 @@ public class Window extends com.jogamp.newt.Window {
System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL");
}
- protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) {
+ protected void reconfigureWindowImpl(int x, int y, int width, int height) {
// n/a in BroadcomEGL
System.err.println("setFullscreen n/a in BroadcomEGL");
}
public boolean surfaceSwap() {
- if ( 0!=windowHandle ) {
- SwapWindow(getDisplayHandle(), windowHandle);
- return true;
- }
- return false;
+ SwapWindow(getDisplayHandle(), getWindowHandle());
+ return true;
}
//----------------------------------------------------------------------
@@ -126,7 +125,7 @@ public class Window extends com.jogamp.newt.Window {
this.width = width;
this.height = height;
GLCapabilities capsReq = (GLCapabilities) config.getRequestedCapabilities();
- config = EGLGraphicsConfiguration.create(capsReq, screen.getGraphicsScreen(), cfgID);
+ config = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID);
if (config == null) {
throw new NativeWindowException("Error creating EGLGraphicsConfiguration from id: "+cfgID+", "+this);
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java
index 1845342a0..eab1816da 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java
@@ -39,7 +39,7 @@ import com.jogamp.opengl.impl.egl.*;
import javax.media.nativewindow.*;
import javax.media.nativewindow.egl.*;
-public class KDDisplay extends Display {
+public class KDDisplay extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
index c7db047f6..a814f15b5 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
@@ -34,9 +34,10 @@
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 Screen {
+public class KDScreen extends ScreenImpl {
static {
KDDisplay.initSingleton();
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
index 43e4ac021..6930741b8 100644
--- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
@@ -42,7 +42,7 @@ import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.nativewindow.NativeWindowException;
-public class KDWindow extends Window {
+public class KDWindow extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
// non fullscreen dimensions ..
private int nfs_width, nfs_height, nfs_x, nfs_y;
@@ -55,7 +55,7 @@ public class KDWindow extends Window {
}
protected void createNativeImpl() {
- if(0!=parentWindowHandle) {
+ if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen());
@@ -71,8 +71,8 @@ public class KDWindow extends Window {
throw new NativeWindowException("Error creating egl window: "+config);
}
setVisible0(eglWindowHandle, false);
- windowHandle = RealizeWindow(eglWindowHandle);
- if (0 == windowHandle) {
+ setWindowHandle(RealizeWindow(eglWindowHandle));
+ if (0 == getWindowHandle()) {
throw new NativeWindowException("Error native Window Handle is null");
}
windowHandleClose = eglWindowHandle;
@@ -89,6 +89,8 @@ public class KDWindow extends Window {
setVisible0(eglWindowHandle, visible);
}
+ protected void requestFocusImpl(boolean reparented) { }
+
protected void setSizeImpl(int width, int height) {
if(0!=eglWindowHandle) {
setSize0(eglWindowHandle, width, height);
@@ -100,11 +102,11 @@ public class KDWindow extends Window {
System.err.println("setPosition n/a in KD");
}
- protected void setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) {
+ protected void reconfigureWindowImpl(int x, int y, int width, int height) {
if(0!=eglWindowHandle) {
setFullScreen0(eglWindowHandle, fullscreen);
if(!fullscreen) {
- setSize0(eglWindowHandle, w, h);
+ setSize0(eglWindowHandle, width, height);
}
}
}
@@ -127,7 +129,7 @@ public class KDWindow extends Window {
protected void sizeChanged(int newWidth, int newHeight) {
if(fullscreen) {
- ((KDScreen)screen).setScreenSize(width, height);
+ ((KDScreen)getScreen()).setScreenSize(width, height);
}
super.sizeChanged(newWidth, newHeight);
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java
index cfc35e1f8..fe86257ff 100644
--- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java
@@ -38,7 +38,7 @@ import javax.media.nativewindow.windows.*;
import com.jogamp.newt.*;
import com.jogamp.newt.impl.*;
-public class WindowsDisplay extends Display {
+public class WindowsDisplay extends DisplayImpl {
protected static final String WINDOW_CLASS_NAME = "NewtWindowClass";
private static int windowClassAtom;
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
index 2197667cd..5dd2689e5 100644
--- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
@@ -34,9 +34,10 @@
package com.jogamp.newt.impl.windows;
import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
import javax.media.nativewindow.*;
-public class WindowsScreen extends Screen {
+public class WindowsScreen extends ScreenImpl {
static {
WindowsDisplay.initSingleton();
}
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
index 15d9ac8b0..ee3c8e197 100644
--- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
@@ -35,16 +35,14 @@ package com.jogamp.newt.impl.windows;
import javax.media.nativewindow.*;
import com.jogamp.newt.*;
-import com.jogamp.newt.event.*;
import com.jogamp.newt.util.*;
+import com.jogamp.newt.impl.WindowImpl;
-public class WindowsWindow extends Window {
+public class WindowsWindow extends WindowImpl {
private long hmon;
private long hdc;
private long windowHandleClose;
- // non fullscreen dimensions ..
- private int nfs_width, nfs_height, nfs_x, nfs_y;
private final Insets insets = new Insets(0, 0, 0, 0);
static {
@@ -54,32 +52,28 @@ public class WindowsWindow extends Window {
public WindowsWindow() {
}
- public int lockSurface() throws NativeWindowException {
- int res = super.lockSurface();
- if( LOCK_SUCCESS == res && 0 != windowHandle && 0 == hdc ) {
- hdc = GetDC0(windowHandle);
- hmon = MonitorFromWindow0(windowHandle);
+ protected int lockSurfaceImpl() {
+ if( 0 != getWindowHandle() && 0 == hdc ) {
+ hdc = GetDC0(getWindowHandle());
+ hmon = MonitorFromWindow0(getWindowHandle());
}
- return res;
+ return LOCK_SUCCESS;
}
- public void unlockSurface() {
- getWindowLock().validateLocked();
-
- if ( 0 != hdc && 0 != windowHandle && getWindowLock().getRecursionCount() == 0) {
- ReleaseDC0(windowHandle, hdc);
+ protected void unlockSurfaceImpl() {
+ if ( 0 != hdc && 0 != getWindowHandle() && getWindowLockRecursionCount() == 0) {
+ ReleaseDC0(getWindowHandle(), hdc);
hdc=0;
}
- super.unlockSurface();
}
- public long getSurfaceHandle() {
+ public final long getSurfaceHandle() {
return hdc;
}
public boolean hasDeviceChanged() {
- if(0!=windowHandle) {
- long _hmon = MonitorFromWindow0(windowHandle);
+ if(0!=getWindowHandle()) {
+ long _hmon = MonitorFromWindow0(getWindowHandle());
if (hmon != _hmon) {
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
Exception e = new Exception("!!! Window Device Changed "+Thread.currentThread().getName()+
@@ -100,17 +94,17 @@ public class WindowsWindow extends Window {
if (config == null) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
- windowHandle = CreateWindow0(parentWindowHandle,
+ setWindowHandle(CreateWindow0(getParentWindowHandle(),
display.getWindowClassAtom(), display.WINDOW_CLASS_NAME, display.getHInstance(),
- 0, undecorated, x, y, width, height);
- if (windowHandle == 0) {
+ 0, undecorated, x, y, width, height));
+ if (getWindowHandle() == 0) {
throw new NativeWindowException("Error creating window");
}
- windowHandleClose = windowHandle;
+ windowHandleClose = getWindowHandle();
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
Exception e = new Exception("!!! Window new window handle "+Thread.currentThread().getName()+
- " (Parent HWND "+toHexString(parentWindowHandle)+
- ") : HWND "+toHexString(windowHandle)+", "+Thread.currentThread());
+ " (Parent HWND "+toHexString(getParentWindowHandle())+
+ ") : HWND "+toHexString(getWindowHandle())+", "+Thread.currentThread());
e.printStackTrace();
}
}
@@ -149,38 +143,34 @@ public class WindowsWindow extends Window {
}
protected void setVisibleImpl(boolean visible) {
- setVisible0(windowHandle, visible);
+ setVisible0(getWindowHandle(), visible);
}
protected void setSizeImpl(int width, int height) {
// this width/height will be set by sizeChanged, called by Windows
- setSize0(parentWindowHandle, windowHandle, x, y, width, height);
+ setSize0(getParentWindowHandle(), getWindowHandle(), x, y, width, height);
}
protected void setPositionImpl(int x, int y) {
// this x/y will be set by positionChanged, called by Windows
- setPosition0(parentWindowHandle, windowHandle, x , y /*, width, height*/);
+ setPosition0(getParentWindowHandle(), getWindowHandle(), x , y /*, width, height*/);
}
- protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) {
- setFullscreen0(fullscreen?0:parentWindowHandle, windowHandle, x, y, w, h, isUndecorated(fullscreen));
+ protected void reconfigureWindowImpl(int x, int y, int width, int height) {
+ reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated(fullscreen));
}
protected boolean reparentWindowImpl() {
- if(0!=windowHandle) {
- reparentWindow0(fullscreen?0:parentWindowHandle, windowHandle, x, y, width, height, isUndecorated());
- }
+ reparentWindow0(fullscreen?0:getParentWindowHandle(), getWindowHandle(), x, y, width, height, isUndecorated());
return true;
}
- protected void requestFocusImpl() {
- if (windowHandle != 0L) {
- requestFocus0(windowHandle);
- }
+ protected void requestFocusImpl(boolean reparented) {
+ requestFocus0(getWindowHandle(), reparented);
}
protected void setTitleImpl(final String title) {
- setTitle0(windowHandle, title);
+ setTitle0(getWindowHandle(), title);
}
public Insets getInsets() {
@@ -203,10 +193,11 @@ public class WindowsWindow extends Window {
private static native void setVisible0(long windowHandle, boolean visible);
private native void setSize0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height);
private static native void setPosition0(long parentWindowHandle, long windowHandle, int x, int y /*, int width, int height*/);
- private native void setFullscreen0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated);
+ private native void reconfigureWindow0(long parentWindowHandle, long windowHandle,
+ int x, int y, int width, int height, boolean isUndecorated);
private native void reparentWindow0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated);
private static native void setTitle0(long windowHandle, String title);
- private native void requestFocus0(long windowHandle);
+ private native void requestFocus0(long windowHandle, boolean reparented);
private void insetsChanged(int left, int top, int right, int bottom) {
if (left != -1 && top != -1 && right != -1 && bottom != -1) {
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java
index 22b5e8470..f96625d8e 100644
--- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java
@@ -39,7 +39,7 @@ import com.jogamp.newt.*;
import com.jogamp.newt.impl.*;
import com.jogamp.nativewindow.impl.x11.X11Util;
-public class X11Display extends Display {
+public class X11Display extends DisplayImpl {
static {
NEWTJNILibLoader.loadNEWT();
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
index aa53ea5d0..9d4c592c8 100644
--- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
@@ -34,9 +34,10 @@
package com.jogamp.newt.impl.x11;
import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
import javax.media.nativewindow.x11.*;
-public class X11Screen extends Screen {
+public class X11Screen extends ScreenImpl {
static {
X11Display.initSingleton();
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
index 894de9ae5..f9fce6fc1 100644
--- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
@@ -35,10 +35,11 @@ package com.jogamp.newt.impl.x11;
import com.jogamp.newt.*;
import com.jogamp.newt.event.*;
+import com.jogamp.newt.impl.WindowImpl;
import javax.media.nativewindow.*;
import javax.media.nativewindow.x11.*;
-public class X11Window extends Window {
+public class X11Window extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
static {
@@ -57,14 +58,14 @@ public class X11Window extends Window {
}
X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config;
long visualID = x11config.getVisualID();
- long w = CreateWindow0(parentWindowHandle,
+ long w = CreateWindow0(getParentWindowHandle(),
display.getHandle(), screen.getIndex(), visualID,
display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
x, y, width, height, isUndecorated());
- if (w == 0 || w!=windowHandle) {
+ if (w == 0 || w!=getWindowHandle()) {
throw new NativeWindowException("Error creating window: "+w);
}
- windowHandleClose = windowHandle;
+ windowHandleClose = getWindowHandle();
}
protected void closeNativeImpl() {
@@ -90,42 +91,39 @@ public class X11Window extends Window {
}
protected void setVisibleImpl(boolean visible) {
- setVisible0(getDisplayHandle(), windowHandle, visible);
+ setVisible0(getDisplayHandle(), getWindowHandle(), visible);
}
protected void setSizeImpl(int width, int height) {
// this width/height will be set by windowChanged, called by X11
- setSize0(getDisplayHandle(), windowHandle, width, height);
+ setSize0(getDisplayHandle(), getWindowHandle(), width, height);
}
protected void setPositionImpl(int x, int y) {
- setPosition0(parentWindowHandle, getDisplayHandle(), windowHandle, x, y);
+ setPosition0(getParentWindowHandle(), getDisplayHandle(), getWindowHandle(), x, y);
}
- protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) {
- setPosSizeDecor0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle,
- x, y, w, h, isUndecorated(fullscreen), isVisible());
+ protected void reconfigureWindowImpl(int x, int y, int width, int height) {
+ reconfigureWindow0(fullscreen?0:getParentWindowHandle(), getDisplayHandle(), getScreenIndex(), getWindowHandle(),
+ x, y, width, height, isUndecorated(fullscreen), isVisible());
}
protected boolean reparentWindowImpl() {
- if(0!=windowHandle) {
- reparentWindow0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle,
+ if(0!=getWindowHandle()) {
+ reparentWindow0(fullscreen?0:getParentWindowHandle(), getDisplayHandle(), getScreenIndex(), getWindowHandle(),
x, y, isUndecorated(), isVisible());
}
return true;
}
- protected void requestFocusImpl() {
- if (windowHandle != 0L) {
- requestFocus0(getDisplayHandle(), windowHandle);
- }
+ protected void requestFocusImpl(boolean reparented) {
+ requestFocus0(getDisplayHandle(), getWindowHandle(), reparented);
}
protected void setTitleImpl(String title) {
- setTitle0(getDisplayHandle(), windowHandle, title);
+ setTitle0(getDisplayHandle(), getWindowHandle(), title);
}
-
//----------------------------------------------------------------------
// Internals only
//
@@ -137,16 +135,16 @@ public class X11Window extends Window {
private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom);
private native void setVisible0(long display, long windowHandle, boolean visible);
private native void setSize0(long display, long windowHandle, int width, int height);
- private native void setPosSizeDecor0(long parentWindowHandle, long display, int screen_index, long windowHandle,
- int x, int y, int width, int height, boolean undecorated, boolean isVisible);
+ private native void reconfigureWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle,
+ int x, int y, int width, int height, boolean undecorated, boolean isVisible);
private native void setTitle0(long display, long windowHandle, String title);
- private native void requestFocus0(long display, long windowHandle);
+ private native void requestFocus0(long display, long windowHandle, boolean reparented);
private native void setPosition0(long parentWindowHandle, long display, long windowHandle, int x, int y);
private native void reparentWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle,
int x, int y, boolean undecorated, boolean isVisible);
private void windowCreated(long windowHandle) {
- this.windowHandle = windowHandle;
+ setWindowHandle(windowHandle);
}
private long windowHandleClose;
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 0eb0f1571..13d549e24 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -1,5 +1,6 @@
/*
* 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
@@ -35,404 +36,323 @@ package com.jogamp.newt.opengl;
import com.jogamp.newt.*;
import com.jogamp.newt.event.*;
-import com.jogamp.newt.util.*;
-import com.jogamp.nativewindow.impl.RecursiveToolkitLock;
+import com.jogamp.newt.util.Insets;
+import com.jogamp.newt.impl.WindowImpl;
import javax.media.nativewindow.*;
import javax.media.opengl.*;
import com.jogamp.opengl.impl.GLDrawableHelper;
-import java.util.*;
/**
- * An implementation of {@link Window} which is customized for OpenGL
- * use, and which implements the {@link javax.media.opengl.GLAutoDrawable} interface.
+ * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
+ * using an aggregation of a {@link com.jogamp.newt.Window} implementation.
* <P>
* This implementation does not make the OpenGL context current<br>
- * before calling the various input EventListener callbacks (MouseListener, KeyListener,
- * etc.).<br>
- * This design decision is made to favor a more performant and simplified
- * implementation, as well as the event dispatcher shall be allowed
- * not having a notion about OpenGL.
+ * before calling the various input EventListener callbacks, ie {@link com.jogamp.newt.event.MouseListener} etc.<br>
+ * This design decision is made in favor of a more performant and simplified
+ * implementation. Also the event dispatcher shall be implemented OpenGL agnostic.<br>
+ * To be able to use OpenGL commands from within such input {@link com.jogamp.newt.event.NEWTEventListener},<br>
+ * you can inject {@link javax.media.opengl.GLRunnable} objects
+ * via {@link #invoke(boolean, javax.media.opengl.GLRunnable)} to the OpenGL command stream.<br>
* <p>
*/
-public class GLWindow extends Window implements GLAutoDrawable {
- private Window window;
+public class GLWindow implements GLAutoDrawable, Window {
+ private WindowImpl window;
/**
* Constructor. Do not call this directly -- use {@link #create()} instead.
*/
protected GLWindow(Window window) {
- this.startTime = System.currentTimeMillis();
- this.window = window;
- this.window.setHandleDestroyNotify(false);
+ resetPerfCounter();
+ this.window = (WindowImpl) window;
+ ((WindowImpl)this.window).setHandleDestroyNotify(false);
window.addWindowListener(new WindowAdapter() {
public void windowRepaint(WindowUpdateEvent e) {
- if( !windowIsLocked() && null == getAnimator() ) {
+ if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
display();
}
}
public void windowResized(WindowEvent e) {
sendReshape = true;
- if( !windowIsLocked() && null == getAnimator() ) {
+ if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
display();
}
}
public void windowDestroyNotify(WindowEvent e) {
- if( !windowIsLocked() && null == getAnimator() ) {
+ if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
destroy();
} else {
sendDestroy = true;
}
}
});
+ this.window.setLifecycleHook(new GLLifecycleHook());
}
- /** Creates a new GLWindow attaching the given window - not owning the Window. */
- public static GLWindow create(Window window) {
- return create(null, window, null, false);
- }
-
- /** Creates a new GLWindow attaching a new native child Window of the given <code>parentNativeWindow</code>
- with the given GLCapabilities - owning the Window */
- public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilities caps) {
- return create(parentNativeWindow, null, caps, false);
- }
-
- /** Creates a new GLWindow attaching a new decorated Window on the local display, screen 0, with a
- dummy visual ID and given GLCapabilities - owning the window */
+ /**
+ * Creates a new GLWindow attaching a new Window referencing a new Screen
+ * with the given GLCapabilities.
+ * <P>
+ * The resulting GLWindow owns the Window, Screen and Device, ie it will be destructed.
+ */
public static GLWindow create(GLCapabilities caps) {
- return create(null, null, caps, false);
+ return new GLWindow(NewtFactory.createWindow(caps));
}
- /** Creates a new GLWindow attaching a new Window on the local display, screen 0, with a
- dummy visual ID and given GLCapabilities - owning the window */
- public static GLWindow create(GLCapabilities caps, boolean undecorated) {
- return create(null, null, caps, undecorated);
+ /**
+ * Creates a new GLWindow attaching a new Window referencing the given Screen
+ * with the given GLCapabilities.
+ * <P>
+ * The resulting GLWindow owns the Window, ie it will be destructed.
+ */
+ public static GLWindow create(Screen screen, GLCapabilities caps) {
+ return new GLWindow(NewtFactory.createWindow(screen, caps));
}
- /** Either or: window (prio), or caps and undecorated (2nd choice) */
- private static GLWindow create(NativeWindow parentNativeWindow, Window window,
- GLCapabilities caps,
- boolean undecorated) {
- if (window == null) {
- if (caps == null) {
- caps = new GLCapabilities(null); // default ..
- }
- window = NewtFactory.createWindow(parentNativeWindow, caps, undecorated);
- }
-
+ /**
+ * Creates a new GLWindow attaching the given window.
+ * <P>
+ * The resulting GLWindow does not own the given Window, ie it will not be destructed.
+ */
+ public static GLWindow create(Window window) {
return new GLWindow(window);
}
-
- public boolean isNativeValid() {
- return (null!=window)?window.isNativeValid():false;
- }
-
- public boolean isValid() {
- return (null!=window)?window.isValid():true;
- }
-
- public final Window getInnerWindow() {
- return window.getInnerWindow();
- }
- public final Object getWrappedWindow() {
- return window.getWrappedWindow();
- }
-
- protected void createNativeImpl() {
- shouldNotCallThis();
- }
-
- protected void closeNativeImpl() {
- shouldNotCallThis();
- }
-
- class DisposeAction implements Runnable {
- public void run() {
- // Lock: Covered by DestroyAction ..
- helper.dispose(GLWindow.this);
- }
+ /**
+ * Creates a new GLWindow attaching a new child Window
+ * of the given <code>parentNativeWindow</code> with the given GLCapabilities.
+ * <P>
+ * The Display/Screen will be compatible with the <code>parentNativeWindow</code>,
+ * or even identical in case it's a Newt Window.
+ * <P>
+ * The resulting GLWindow owns the Window, ie it will be destructed.
+ */
+ public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilities caps) {
+ return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps));
}
- private DisposeAction disposeAction = new DisposeAction();
-
- class DestroyAction implements Runnable {
- boolean unrecoverable;
- public DestroyAction(boolean unrecoverable) {
- this.unrecoverable = unrecoverable;
- }
- public void run() {
- // Lock: Have to cover whole workflow (dispose all, context, drawable and window)
- windowLock();
- try {
- if( !isValid() ) {
- return; // nop
- }
- if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) {
- Exception e1 = new Exception("GLWindow.destroy("+unrecoverable+") "+Thread.currentThread()+", start: "+GLWindow.this);
- e1.printStackTrace();
- }
-
- if( window.isNativeValid() && null != drawable && drawable.isRealized() ) {
- if( null != context && context.isCreated() ) {
- // Catch dispose GLExceptions by GLEventListener, just 'print' them
- // so we can continue with the destruction.
- try {
- helper.invokeGL(drawable, context, disposeAction, null);
- } catch (GLException gle) {
- gle.printStackTrace();
- }
-
- context.destroy();
- context = null;
- }
-
- drawable.setRealized(false);
- drawable = null;
- }
-
- if(null!=window) {
- window.destroy(unrecoverable);
- }
- if(unrecoverable) {
- helper=null;
- }
- if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) {
- System.out.println("GLWindow.destroy("+unrecoverable+") "+Thread.currentThread()+", fin: "+GLWindow.this);
- }
- } finally {
- windowUnlock();
- }
- }
- }
+ //----------------------------------------------------------------------
+ // Window Access
+ //
- public void destroy(boolean unrecoverable) {
- if( isValid() ) {
- runOnEDTIfAvail(true, new DestroyAction(unrecoverable));
+ public final Capabilities getChosenCapabilities() {
+ if (drawable == null) {
+ return window.getChosenCapabilities();
}
- }
-
- public boolean getPerfLogEnabled() { return perfLog; }
-
- public void enablePerfLog(boolean v) {
- perfLog = v;
- }
-
- protected void setVisibleImpl(boolean visible) {
- shouldNotCallThis();
- }
-
- public void reparentWindow(NativeWindow newParent) {
- window.reparentWindow(newParent);
- }
- class VisibleAction implements Runnable {
- boolean visible;
- public VisibleAction(boolean visible) {
- this.visible = visible;
- }
- public void run() {
- // Lock: Have to cover whole workflow (window, may do nativeCreation, drawable and context)
- windowLock();
- try{
- window.setVisible(visible);
- if (null == context && visible && 0 != window.getWindowHandle() && 0<getWidth()*getHeight()) {
- NativeWindow nw;
- if (getWrappedWindow() != null) {
- nw = NativeWindowFactory.getNativeWindow(getWrappedWindow(), window.getGraphicsConfiguration());
- } else {
- nw = window;
- }
- GLCapabilities glCaps = (GLCapabilities) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
- if(null==factory) {
- factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
- }
- if(null==drawable) {
- drawable = factory.createGLDrawable(nw);
- }
- drawable.setRealized(true);
- context = drawable.createContext(null);
- sendReshape = true; // ensure a reshape event is send ..
- }
- } finally {
- windowUnlock();
- }
- }
+ return drawable.getChosenGLCapabilities();
}
- public void setVisible(boolean visible) {
- if(isValid()) {
- runOnEDTIfAvail(true, new VisibleAction(visible));
- }
+ public final Capabilities getRequestedCapabilities() {
+ return window.getRequestedCapabilities();
}
- public Capabilities getRequestedCapabilities() {
- return window.getRequestedCapabilities();
+ public final Window getWindow() {
+ return window;
}
- public NativeWindow getParentNativeWindow() {
+ public final NativeWindow getParentNativeWindow() {
return window.getParentNativeWindow();
}
- public Screen getScreen() {
+ public final Screen getScreen() {
return window.getScreen();
}
- public void setTitle(String title) {
+ public final void setTitle(String title) {
window.setTitle(title);
}
- public String getTitle() {
+ public final String getTitle() {
return window.getTitle();
}
- public void setUndecorated(boolean value) {
+ public final void setUndecorated(boolean value) {
window.setUndecorated(value);
}
- public boolean isUndecorated() {
+ public final boolean isUndecorated() {
return window.isUndecorated();
}
- public void requestFocus() {
- window.requestFocus();
- }
- public void setFocusAction(FocusRunnable focusAction) {
+ public final void setFocusAction(FocusRunnable focusAction) {
window.setFocusAction(focusAction);
}
-
- public Insets getInsets() {
- return window.getInsets();
+
+ public final void requestFocus() {
+ window.requestFocus();
}
- public void setSize(int width, int height) {
- window.setSize(width, height);
- }
- protected void setSizeImpl(int width, int height) {
- shouldNotCallThis();
+ public final Insets getInsets() {
+ return window.getInsets();
}
- public void setPosition(int x, int y) {
+ public final void setPosition(int x, int y) {
window.setPosition(x, y);
}
- protected void setPositionImpl(int x, int y) {
- shouldNotCallThis();
- }
- public boolean setFullscreen(boolean fullscreen) {
+ public final boolean setFullscreen(boolean fullscreen) {
return window.setFullscreen(fullscreen);
}
- protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) {
- shouldNotCallThis();
+
+ public final boolean isFullscreen() {
+ return window.isFullscreen();
}
- public boolean isVisible() {
+ public final boolean isVisible() {
return window.isVisible();
}
- public int getX() {
- return window.getX();
+ public final String toString() {
+ return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+ ", \n\tContext: " + context + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
}
- public int getY() {
- return window.getY();
+ public final int reparentWindow(NativeWindow newParent) {
+ return window.reparentWindow(newParent);
}
- public int getWidth() {
- return window.getWidth();
+ public final int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
+ return window.reparentWindow(newParent, forceDestroyCreate);
}
- public int getHeight() {
- return window.getHeight();
+ public final void removeChild(NativeWindow win) {
+ window.removeChild(win);
}
- public boolean isFullscreen() {
- return window.isFullscreen();
+ public final void addChild(NativeWindow win) {
+ window.addChild(win);
}
- public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
- window.enqueueEvent(wait, event);
- }
- public boolean consumeEvent(NEWTEvent e) {
- return window.consumeEvent(e);
- }
+ //----------------------------------------------------------------------
+ // Window.LifecycleHook Implementation
+ //
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) {
- window.addSurfaceUpdatedListener(index, l);
- }
- public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- window.removeSurfaceUpdatedListener(l);
- }
- public void removeAllSurfaceUpdatedListener() {
- window.removeAllSurfaceUpdatedListener();
- }
- public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- return window.getSurfaceUpdatedListener(index);
- }
- public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- return window.getSurfaceUpdatedListeners();
- }
- public void surfaceUpdated(Object updater, NativeWindow window0, long when) {
- window.surfaceUpdated(updater, window, when);
+ public final void destroy(boolean unrecoverable) {
+ window.destroy(unrecoverable);
}
- public void addMouseListener(int index, MouseListener l) {
- window.addMouseListener(index, l);
- }
- public void removeMouseListener(MouseListener l) {
- window.removeMouseListener(l);
- }
- public MouseListener getMouseListener(int index) {
- return window.getMouseListener(index);
- }
- public MouseListener[] getMouseListeners() {
- return window.getMouseListeners();
+ public final void setVisible(boolean visible) {
+ window.setVisible(visible);
}
- public void addKeyListener(int index, KeyListener l) {
- window.addKeyListener(index, l);
- }
- public void removeKeyListener(KeyListener l) {
- window.removeKeyListener(l);
- }
- public KeyListener getKeyListener(int index) {
- return window.getKeyListener(index);
- }
- public KeyListener[] getKeyListeners() {
- return window.getKeyListeners();
+ public final void setSize(int width, int height) {
+ window.setSize(width, height);
}
- public void sendWindowEvent(int eventType) {
- window.sendWindowEvent(eventType);
- }
- public void enqueueWindowEvent(boolean wait, int eventType) {
- window.enqueueWindowEvent(wait, eventType);
- }
- public void addWindowListener(int index, WindowListener l) {
- window.addWindowListener(index, l);
- }
- public void removeWindowListener(WindowListener l) {
- window.removeWindowListener(l);
- }
- public WindowListener getWindowListener(int index) {
- return window.getWindowListener(index);
- }
- public WindowListener[] getWindowListeners() {
- return window.getWindowListeners();
- }
- public void setPropagateRepaint(boolean v) {
- window.setPropagateRepaint(v);
- }
- public void windowRepaint(int x, int y, int width, int height) {
- window.windowRepaint(x, y, width, height);
+ public final boolean isValid() {
+ return window.isValid();
}
- public String toString() {
- return "NEWT-GLWindow[ \n\tHelper: "+helper+", \n\tDrawable: "+drawable + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
+ public final boolean isNativeValid() {
+ return window.isNativeValid();
}
+ // Hide methods here ..
+ protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
+
+ class DisposeAction implements Runnable {
+ public void run() {
+ // Lock: Covered by DestroyAction ..
+ helper.dispose(GLWindow.this);
+ }
+ }
+ DisposeAction disposeAction = new DisposeAction();
+
+ /** Window.LifecycleHook */
+ public synchronized void destroyAction(boolean unrecoverable) {
+ if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
+ String msg = new String("GLWindow.destroy("+unrecoverable+") "+Thread.currentThread()+", start");
+ System.err.println(msg);
+ //Exception e1 = new Exception(msg);
+ //e1.printStackTrace();
+ }
+
+ if( window.isNativeValid() && null != drawable && drawable.isRealized() ) {
+ if( null != context && context.isCreated() ) {
+ // Catch dispose GLExceptions by GLEventListener, just 'print' them
+ // so we can continue with the destruction.
+ try {
+ helper.invokeGL(drawable, context, disposeAction, null);
+ } catch (GLException gle) {
+ gle.printStackTrace();
+ }
+ context.destroy();
+ }
+ drawable.setRealized(false);
+ }
+ context = null;
+ drawable = null;
+
+ if(unrecoverable) {
+ helper=null;
+ }
+
+ if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
+ System.err.println("GLWindow.destroy("+unrecoverable+") "+Thread.currentThread()+", fin");
+ }
+ }
+
+ /** Window.LifecycleHook */
+ public synchronized void setVisibleAction(boolean visible, boolean nativeWindowCreated) {
+ if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
+ String msg = new String("GLWindow.setVisibleAction("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", start");
+ System.err.println(msg);
+ // Exception e1 = new Exception(msg);
+ // e1.printStackTrace();
+ }
+
+ /* if (nativeWindowCreated && null != context) {
+ throw new GLException("InternalError: Native Windows has been just created, but context wasn't destroyed (is not null)");
+ } */
+ if (null == context && visible && 0 != window.getWindowHandle() && 0<getWidth()*getHeight()) {
+ NativeWindow nw;
+ if (window.getWrappedWindow() != null) {
+ nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
+ } else {
+ nw = window;
+ }
+ GLCapabilities glCaps = (GLCapabilities) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ if(null==factory) {
+ factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
+ }
+ if(null==drawable) {
+ drawable = factory.createGLDrawable(nw);
+ }
+ drawable.setRealized(true);
+ context = drawable.createContext(null);
+ resetPerfCounter();
+ } else if(!visible) {
+ resetPerfCounter();
+ }
+ if(Window.DEBUG_WINDOW_EVENT || Window.DEBUG_IMPLEMENTATION) {
+ String msg = new String("GLWindow.setVisibleAction("+visible+", "+nativeWindowCreated+") "+Thread.currentThread()+", fin");
+ System.err.println(msg);
+ //Exception e1 = new Exception(msg);
+ //e1.printStackTrace();
+ }
+ }
+
+ boolean animatorPaused = false;
+
+ public synchronized void reparentActionPre() {
+ GLAnimatorControl ctrl = GLWindow.this.getAnimator();
+ if ( null!=ctrl && ctrl.isAnimating() && ctrl.getThread() != Thread.currentThread() ) {
+ animatorPaused = true;
+ ctrl.pause();
+ }
+ }
+
+ public synchronized void reparentActionPost(int reparentActionType) {
+ resetPerfCounter();
+ GLAnimatorControl ctrl = GLWindow.this.getAnimator();
+ if ( null!=ctrl && animatorPaused ) {
+ animatorPaused = false;
+ ctrl.resume();
+ }
+ }
+ }
//----------------------------------------------------------------------
// OpenGL-related methods and state
//
@@ -445,6 +365,16 @@ public class GLWindow extends Window implements GLAutoDrawable {
private boolean sendReshape=false;
private boolean sendDestroy=false;
private boolean perfLog = false;
+ private long startTime, curTime, lastCheck;
+ private int totalFrames, lastFrames;
+
+ /** Reset all performance counter (startTime, currentTime, frame number) */
+ public void resetPerfCounter() {
+ startTime = System.currentTimeMillis(); // overwrite startTime to real init one
+ curTime = startTime;
+ lastCheck = startTime;
+ totalFrames = 0; lastFrames = 0;
+ }
public GLDrawableFactory getFactory() {
return factory;
@@ -485,15 +415,20 @@ public class GLWindow extends Window implements GLAutoDrawable {
helper.removeGLEventListener(listener);
}
- public void setAnimator(Thread animator) {
- helper.setAnimator(animator);
- window.setPropagateRepaint(null==animator);
+ public void setAnimator(GLAnimatorControl animatorControl) {
+ helper.setAnimator(animatorControl);
}
- public Thread getAnimator() {
+ public GLAnimatorControl getAnimator() {
return helper.getAnimator();
}
+ public boolean getPerfLogEnabled() { return perfLog; }
+
+ public void enablePerfLog(boolean v) {
+ perfLog = v;
+ }
+
public void invoke(boolean wait, GLRunnable glRunnable) {
helper.invoke(this, wait, glRunnable);
}
@@ -516,15 +451,15 @@ public class GLWindow extends Window implements GLAutoDrawable {
setVisible(true);
}
- if( window.isVisible() && window.isNativeValid() && null != context ) {
+ if( isVisible() && isNativeValid() && null != context ) {
if(forceReshape) {
sendReshape = true;
}
- windowLock();
+ lockSurface();
try{
helper.invokeGL(drawable, context, displayAction, initAction);
} finally {
- windowUnlock();
+ unlockSurface();
}
}
}
@@ -555,12 +490,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
public void run() {
// Lock: Locked Surface/Window by MakeCurrent/Release
helper.init(GLWindow.this);
- startTime = System.currentTimeMillis(); // overwrite startTime to real init one
- curTime = startTime;
- if(perfLog) {
- lastCheck = startTime;
- totalFrames = 0; lastFrames = 0;
- }
+ resetPerfCounter();
}
}
private InitAction initAction = new InitAction();
@@ -584,7 +514,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
dt0 = curTime-lastCheck;
if ( dt0 > 5000 ) {
dt1 = curTime-startTime;
- System.out.println(dt0/1000 +"s: "+ lastFrames + "f, " + (lastFrames*1000)/dt0 + " fps, "+dt0/lastFrames+" ms/f; "+
+ System.err.println(dt0/1000 +"s: "+ lastFrames + "f, " + (lastFrames*1000)/dt0 + " fps, "+dt0/lastFrames+" ms/f; "+
"total: "+ dt1/1000+"s, "+(totalFrames*1000)/dt1 + " fps, "+dt1/totalFrames+" ms/f");
lastCheck=curTime;
lastFrames=0;
@@ -594,15 +524,69 @@ public class GLWindow extends Window implements GLAutoDrawable {
}
private DisplayAction displayAction = new DisplayAction();
- public long getStartTime() { return startTime; }
- public long getCurrentTime() { curTime = System.currentTimeMillis(); return curTime; }
- public long getDuration() { return getCurrentTime()-startTime; }
- public int getTotalFrames() { return totalFrames; }
+ /**
+ * @return Time of the first display call in milliseconds.
+ * This value is reset if becoming visible again or reparenting.
+ * In case an animator is used,
+ * the corresponding {@link javax.media.opengl.GLAnimatorControl} value is returned.
+ *
+ * @see javax.media.opengl.GLAnimatorControl#getStartTime()
+ */
+ public final long getStartTime() {
+ GLAnimatorControl animator = getAnimator();
+ if ( null == animator || null == animator.getThread() ) {
+ // no animator, or not started -> use local time
+ return startTime;
+ } else {
+ return animator.getStartTime();
+ }
+ }
- private long startTime = 0;
- private long curTime = 0;
- private long lastCheck = 0;
- private int totalFrames = 0, lastFrames = 0;
+ /**
+ * @return Time of the last display call in milliseconds.
+ * This value is reset if becoming visible again or reparenting.
+ * In case an animator is used,
+ * the corresponding {@link javax.media.opengl.GLAnimatorControl} value is returned.
+ *
+ * @see javax.media.opengl.GLAnimatorControl#getCurrentTime()
+ */
+ public final long getCurrentTime() {
+ GLAnimatorControl animator = getAnimator();
+ if ( null == animator || null == animator.getThread() ) {
+ // no animator, or not started -> use local time
+ return curTime;
+ } else {
+ return animator.getCurrentTime();
+ }
+ }
+
+ /**
+ * @return Duration <code>getCurrentTime() - getStartTime()</code>.
+ *
+ * @see #getStartTime()
+ * @see #getCurrentTime()
+ */
+ public final long getDuration() {
+ return getCurrentTime()-getStartTime();
+ }
+
+ /**
+ * @return Number of frames displayed since the first display call, ie <code>getStartTime()</code>.
+ * This value is reset if becoming visible again or reparenting.
+ * In case an animator is used,
+ * the corresponding {@link javax.media.opengl.GLAnimatorControl} value is returned.
+ *
+ * @see javax.media.opengl.GLAnimatorControl#getTotalFrames()
+ */
+ public final int getTotalFrames() {
+ GLAnimatorControl animator = getAnimator();
+ if ( null == animator || null == animator.getThread() ) {
+ // no animator, or not started -> use local value
+ return totalFrames;
+ } else {
+ return animator.getTotalFrames();
+ }
+ }
class SwapBuffersAction implements Runnable {
public void run() {
@@ -612,77 +596,53 @@ public class GLWindow extends Window implements GLAutoDrawable {
private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
//----------------------------------------------------------------------
- // NativeWindow/Window methods
+ // GLDrawable methods
//
- public int lockSurface() throws NativeWindowException {
- if(null!=drawable) return drawable.getNativeWindow().lockSurface();
- return window.lockSurface();
- }
-
- public void unlockSurface() {
- if(null!=drawable) drawable.getNativeWindow().unlockSurface();
- else window.unlockSurface();
- }
-
- public boolean isSurfaceLocked() {
- if(null!=drawable) return drawable.getNativeWindow().isSurfaceLocked();
- return window.isSurfaceLocked();
- }
-
- public Exception getLockedStack() {
- if(null!=drawable) return drawable.getNativeWindow().getLockedStack();
- return window.getLockedStack();
+ public final NativeWindow getNativeWindow() {
+ return null!=drawable ? drawable.getNativeWindow() : null;
}
- public boolean surfaceSwap() {
- if(null!=drawable) return drawable.getNativeWindow().surfaceSwap();
- return super.surfaceSwap();
+ public final long getHandle() {
+ return null!=drawable ? drawable.getHandle() : 0;
}
- public long getWindowHandle() {
- if(null!=drawable) return drawable.getNativeWindow().getWindowHandle();
- return window.getWindowHandle();
+ public final void destroy() {
+ window.destroy();
}
- public long getSurfaceHandle() {
- if(null!=drawable) return drawable.getNativeWindow().getSurfaceHandle();
- return window.getSurfaceHandle();
+ public final int getX() {
+ return window.getX();
}
- public AbstractGraphicsConfiguration getGraphicsConfiguration() {
- if(null!=drawable) return drawable.getNativeWindow().getGraphicsConfiguration();
- return window.getGraphicsConfiguration();
+ public final int getY() {
+ return window.getY();
}
- //----------------------------------------------------------------------
- // GLDrawable methods
- //
-
- public NativeWindow getNativeWindow() {
- return null!=drawable ? drawable.getNativeWindow() : null;
+ public final int getWidth() {
+ return window.getWidth();
}
- public long getHandle() {
- return null!=drawable ? drawable.getHandle() : 0;
+ public final int getHeight() {
+ return window.getHeight();
}
//----------------------------------------------------------------------
// GLDrawable methods that are not really needed
//
- public GLContext createContext(GLContext shareWith) {
+ public final GLContext createContext(GLContext shareWith) {
return drawable.createContext(shareWith);
}
- public void setRealized(boolean realized) {
+ public final void setRealized(boolean realized) {
}
- public boolean isRealized() {
+ public final boolean isRealized() {
return ( null != drawable ) ? drawable.isRealized() : false;
}
- public GLCapabilities getChosenGLCapabilities() {
+ public final GLCapabilities getChosenGLCapabilities() {
if (drawable == null) {
throw new GLException("No drawable yet");
}
@@ -690,11 +650,177 @@ public class GLWindow extends Window implements GLAutoDrawable {
return drawable.getChosenGLCapabilities();
}
- public GLProfile getGLProfile() {
+ public final GLProfile getGLProfile() {
if (drawable == null) {
throw new GLException("No drawable yet");
}
return drawable.getGLProfile();
}
+
+ //----------------------------------------------------------------------
+ // Window completion
+ //
+ public final void windowRepaint(int x, int y, int width, int height) {
+ window.windowRepaint(x, y, width, height);
+ }
+
+ public final void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
+ window.enqueueEvent(wait, event);
+ }
+
+ public final void runOnEDTIfAvail(boolean wait, final Runnable task) {
+ window.runOnEDTIfAvail(wait, task);
+ }
+
+ public final SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
+ return window.getSurfaceUpdatedListener(index);
+ }
+
+ public final SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
+ return window.getSurfaceUpdatedListeners();
+ }
+
+ public final void removeAllSurfaceUpdatedListener() {
+ window.removeAllSurfaceUpdatedListener();
+ }
+
+ public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ window.removeSurfaceUpdatedListener(l);
+ }
+
+ public final void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
+ window.addSurfaceUpdatedListener(l);
+ }
+
+ public final void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ window.addSurfaceUpdatedListener(index, l);
+ }
+
+ public void sendWindowEvent(int eventType) {
+ window.sendWindowEvent(eventType);
+ }
+
+ public final WindowListener getWindowListener(int index) {
+ return window.getWindowListener(index);
+ }
+
+ public final WindowListener[] getWindowListeners() {
+ return window.getWindowListeners();
+ }
+
+ public final void removeWindowListener(WindowListener l) {
+ window.removeWindowListener(l);
+ }
+
+ public final void addWindowListener(WindowListener l) {
+ window.addWindowListener(l);
+ }
+
+ public final void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException {
+ window.addWindowListener(index, l);
+ }
+
+ public final void addKeyListener(KeyListener l) {
+ window.addKeyListener(l);
+ }
+
+ public final void addKeyListener(int index, KeyListener l) {
+ window.addKeyListener(index, l);
+ }
+
+ public final void removeKeyListener(KeyListener l) {
+ window.removeKeyListener(l);
+ }
+
+ public final KeyListener getKeyListener(int index) {
+ return window.getKeyListener(index);
+ }
+
+ public final KeyListener[] getKeyListeners() {
+ return window.getKeyListeners();
+ }
+
+ public final void addMouseListener(MouseListener l) {
+ window.addMouseListener(l);
+ }
+
+ public final void addMouseListener(int index, MouseListener l) {
+ window.addMouseListener(index, l);
+ }
+
+ public final void removeMouseListener(MouseListener l) {
+ window.removeMouseListener(l);
+ }
+
+ public final MouseListener getMouseListener(int index) {
+ return window.getMouseListener(index);
+ }
+
+ public final MouseListener[] getMouseListeners() {
+ return window.getMouseListeners();
+ }
+
+ //----------------------------------------------------------------------
+ // NativeWindow completion
+ //
+
+ public final int lockSurface() {
+ return window.lockSurface();
+ }
+
+ public final void unlockSurface() throws NativeWindowException {
+ window.unlockSurface();
+ }
+
+ public final boolean isSurfaceLockedByOtherThread() {
+ return window.isSurfaceLockedByOtherThread();
+ }
+
+ public final boolean isSurfaceLocked() {
+ return window.isSurfaceLocked();
+ }
+
+ public final Thread getSurfaceLockOwner() {
+ return window.getSurfaceLockOwner();
+
+ }
+
+ public final Exception getSurfaceLockStack() {
+ return window.getSurfaceLockStack();
+ }
+
+ public final boolean surfaceSwap() {
+ return window.surfaceSwap();
+ }
+
+ public final void invalidate() {
+ window.invalidate();
+ }
+
+ public final long getWindowHandle() {
+ return window.getWindowHandle();
+
+ }
+
+ public final long getSurfaceHandle() {
+ return window.getSurfaceHandle();
+
+ }
+
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return window.getGraphicsConfiguration();
+ }
+
+ public final long getDisplayHandle() {
+ return window.getDisplayHandle();
+ }
+
+ public final int getScreenIndex() {
+ return window.getScreenIndex();
+ }
+
+ public final void surfaceUpdated(Object updater, NativeWindow window, long when) {
+ window.surfaceUpdated(updater, window, when);
+ }
}
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 6b8f2b73f..4bf2545ab 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -600,10 +600,11 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt,
}
static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, BOOL reparented) {
- HWND pHwnd = GetParent(hwnd);
- HWND current = GetFocus();
- DBG_PRINT("*** WindowsWindow: requestFocus.0 parent %p, window %p, isCurrent %d\n",
- (void*) pHwnd, (void*)hwnd, current==hwnd);
+ HWND pHwnd, current;
+ pHwnd = GetParent(hwnd);
+ current = GetFocus();
+ DBG_PRINT("*** WindowsWindow: requestFocus.S parent %p, window %p, isCurrent %d, reparented %d\n",
+ (void*) pHwnd, (void*)hwnd, current==hwnd, (int) reparented);
if(reparented || current!=hwnd) {
if( JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
@@ -621,6 +622,7 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, BO
DBG_PRINT("*** WindowsWindow: requestFocus.X0\n");
}
}
+ DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
static RECT * UpdateInsets(JNIEnv *env, HWND hwnd, jobject window)
@@ -738,12 +740,12 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
env = wud->jenv;
window = wud->jinstance;
+ // DBG_PRINT("*** WindowsWindow: thread 0x%X - window %p -> %p, 0x%X %d/%d\n", (int)GetCurrentThreadId(), wnd, window, message, (int)LOWORD(lParam), (int)HIWORD(lParam));
+
if (NULL==window || NULL==env) {
return DefWindowProc(wnd, message, wParam, lParam);
}
- // DBG_PRINT("*** WindowsWindow: window %p -> %p, 0x%X %d/%d\n", wnd, window, message, (int)LOWORD(lParam), (int)HIWORD(lParam));
-
switch (message) {
//
@@ -961,6 +963,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsDisplay_Dispatch
// Periodically take a break
do {
gotOne = PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE);
+ // DBG_PRINT("*** WindowsWindow.DispatchMessages0: thread 0x%X - gotOne %d\n", (int)GetCurrentThreadId(), (int)gotOne);
if (gotOne) {
++i;
#ifdef DEBUG_KEYS
@@ -1149,7 +1152,8 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi
(HINSTANCE) (intptr_t) hInstance,
NULL);
- DBG_PRINT("*** WindowsWindow: CreateWindow parent %p, window %p, %d/%d %dx%d\n", parentWindow, window, x, y, width, height);
+ DBG_PRINT("*** WindowsWindow: CreateWindow thread 0xX, parent %p, window %p, %d/%d %dx%d\n",
+ (int)GetCurrentThreadId(), parentWindow, window, x, y, width, height);
if (NULL == window) {
int lastError = (int) GetLastError();
@@ -1186,7 +1190,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_DestroyWindow0
(JNIEnv *env, jobject obj, jlong window)
{
- DBG_PRINT("*** WindowsWindow: DestroyWindow window %p\n", window);
+ DBG_PRINT("*** WindowsWindow: DestroyWindow thread 0x%X, window %p\n", (int)GetCurrentThreadId(), window);
DestroyWindow((HWND) (intptr_t) window);
}
@@ -1362,10 +1366,10 @@ static void NewtWindows_reparentWindow(JNIEnv *env, jobject obj, HWND hwndP, HWN
/*
* Class: com_jogamp_newt_impl_windows_WindowsWindow
- * Method: setFullscreen
+ * Method: reconfigureWindow0
* Signature: (JIIIIZ)V
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullscreen0
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reconfigureWindow0
(JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated)
{
UINT flags;
@@ -1374,7 +1378,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc
HWND hWndInsertAfter;
BOOL isVisible = IsWindowVisible(hwnd);
- DBG_PRINT("*** WindowsWindow: setFullscreen.1 parent %p, window %p, %d/%d %dx%d undeco %d visible\n",
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0.1 parent %p, window %p, %d/%d %dx%d undeco %d visible\n",
parent, window, x, y, width, height, bIsUndecorated, isVisible);
NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated);
@@ -1388,11 +1392,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc
}
SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags);
- if(isVisible) {
- NewtWindows_requestFocus ( env, obj, hwnd, TRUE ); // request focus on this window, if not already ..
- }
-
- DBG_PRINT("*** WindowsWindow: setFullscreen.X\n");
+ DBG_PRINT("*** WindowsWindow: reconfigureWindow0.X\n");
(*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); // resize necessary ..
}
@@ -1409,11 +1409,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentW
BOOL isVisible = IsWindowVisible(hwnd);
NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated);
-
- if(isVisible) {
- NewtWindows_requestFocus ( env, obj, hwnd, TRUE ); // request focus on this window, if not already ..
- }
-
}
/*
@@ -1440,9 +1435,9 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setTitle0
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_requestFocus0
- (JNIEnv *env, jobject obj, jlong window)
+ (JNIEnv *env, jobject obj, jlong window, jboolean bReparented)
{
- DBG_PRINT("*** WindowsWindow: RequestFocus0\n");
- NewtWindows_requestFocus ( env, obj, (HWND) (intptr_t) window, FALSE ) ;
+ DBG_PRINT("*** WindowsWindow: RequestFocus0: reparented %d\n", (int)bReparented);
+ NewtWindows_requestFocus ( env, obj, (HWND) (intptr_t) window, bReparented ) ;
}
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index 61575c947..350a0a704 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -393,27 +393,22 @@ static Window NewtWindows_getParent (Display *dpy, Window w) {
return 0;
} */
-static void NewtWindows_requestFocus0 (JNIEnv *env, jobject window, Display *dpy, Window w, XWindowAttributes *xwa,
- Bool reparented){
+static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy, Window w,
+ Bool reparented) {
+ XWindowAttributes xwa;
Window focus_return;
int revert_to_return;
+
+ XGetWindowAttributes(dpy, w, &xwa);
XGetInputFocus(dpy, &focus_return, &revert_to_return);
if(reparented || focus_return!=w) {
// Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
if( JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- if(xwa->map_state == IsViewable) {
+ if(xwa.map_state == IsViewable) {
XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
}
}
}
-}
-
-static void NewtWindows_requestFocus1 (JNIEnv *env, jobject window, Display *dpy, Window w,
- Bool reparented) {
- XWindowAttributes xwa;
-
- XGetWindowAttributes(dpy, w, &xwa);
- NewtWindows_requestFocus0 (env, window, dpy, w, &xwa, reparented);
XSync(dpy, False);
}
@@ -904,7 +899,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0
XUnmapWindow(dpy, w);
// Drain all events related to this window ..
- JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, wmDeleteAtom);
+ Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages0(env, obj, display, javaObjectAtom, wmDeleteAtom);
XDestroyWindow(dpy, w);
XSync(dpy, False);
@@ -1028,9 +1023,6 @@ static void NewtWindows_reparentWindow
if(JNI_TRUE == isVisible) {
XMapRaised(dpy, w);
XSync(dpy, False);
-
- NewtWindows_requestFocus0 ( env, obj, dpy, w, xwa, True );
- XSync(dpy, False);
}
DBG_PRINT( "X11: reparentWindow X\n");
@@ -1038,10 +1030,10 @@ static void NewtWindows_reparentWindow
/*
* Class: com_jogamp_newt_impl_x11_X11Window
- * Method: setPosSizeDecor0
+ * Method: reconfigureWindow0
* Signature: (JJIJIIIIZ)V
*/
-JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0
+JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reconfigureWindow0
(JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window,
jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible)
{
@@ -1052,7 +1044,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0
XWindowChanges xwc;
XWindowAttributes xwa;
- DBG_PRINT( "X11: setPosSizeDecor0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d\n",
+ DBG_PRINT( "X11: reconfigureWindow0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d\n",
(void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible);
if(dpy==NULL) {
@@ -1110,9 +1102,9 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_requestFocus0
- (JNIEnv *env, jobject obj, jlong display, jlong window)
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jboolean bReparented)
{
- NewtWindows_requestFocus1 ( env, obj, (Display *) (intptr_t) display, (Window)window, False ) ;
+ NewtWindows_requestFocus ( env, obj, (Display *) (intptr_t) display, (Window)window, bReparented ) ;
}
/*