summaryrefslogtreecommitdiffstats
path: root/src/newt/classes/com
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/classes/com')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java223
-rw-r--r--src/newt/classes/com/jogamp/newt/NewtFactory.java288
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java227
-rw-r--r--src/newt/classes/com/jogamp/newt/ScreenMode.java189
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java413
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java328
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java74
-rw-r--r--src/newt/classes/com/jogamp/newt/event/InputEvent.java89
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyAdapter.java41
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java736
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyListener.java43
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseAdapter.java50
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseEvent.java110
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseListener.java48
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java164
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEventConsumer.java40
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java62
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEventListener.java40
-rw-r--r--src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java39
-rw-r--r--src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java56
-rw-r--r--src/newt/classes/com/jogamp/newt/event/TraceMouseAdapter.java76
-rw-r--r--src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java67
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowAdapter.java45
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowEvent.java69
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowListener.java55
-rw-r--r--src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java49
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java180
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java82
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTMouseAdapter.java120
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java146
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java130
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java204
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/Debug.java140
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java325
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java395
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/NEWTJNILibLoader.java62
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java127
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java503
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java207
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/WindowImpl.java2128
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java284
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java63
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java65
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java289
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java56
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java104
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java68
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java146
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java101
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java57
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java433
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java81
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java62
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java163
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java84
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java58
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java149
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java105
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java114
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java208
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java115
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java270
-rw-r--r--src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java148
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java843
-rw-r--r--src/newt/classes/com/jogamp/newt/util/EDTUtil.java115
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MainThread.java419
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MonitorMode.java109
-rw-r--r--src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java340
68 files changed, 13419 insertions, 0 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
new file mode 100644
index 000000000..bec014c0b
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -0,0 +1,223 @@
+/**
+ * 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.util.EDTUtil;
+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");
+
+ /** return precomputed hashCode from FQN {@link #getFQName()} */
+ public abstract int hashCode();
+
+ /** return true if obj is of type Display and both FQN {@link #getFQName()} equals */
+ public boolean equals(Object obj) {
+ if (this == obj) { return true; }
+ if (obj instanceof Display) {
+ Display d = (Display)obj;
+ return d.getFQName().equals(getFQName());
+ }
+ return false;
+ }
+
+ /**
+ * @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();
+
+ /**
+ * @return the value set by {@link #setDestroyWhenUnused(boolean)}
+ * or the default <code>false</code>.
+ *
+ * @see #addReference()
+ * @see #removeReference()
+ */
+ public abstract boolean getDestroyWhenUnused();
+
+ /**
+ * Handles the lifecycle of the native Display instance.<br>
+ * If set to <code>true</code>, the last {@link #removeReference()} call
+ * will destroy this instance, otherwise it will stay alive.<br>
+ * Default is <code>false</code>.
+ *
+ * @see #addReference()
+ * @see #removeReference()
+ */
+ public abstract void setDestroyWhenUnused(boolean v);
+
+ /**
+ * The 1st call will initiate native creation,
+ * since we follow the lazy creation pattern.
+ *
+ * @return number of references after adding one
+ * @see #removeReference()
+ */
+ public abstract int addReference();
+
+ /**
+ * The last call may destroy this instance,
+ * if {@link #getDestroyWhenUnused()} returns <code>true</code>.
+ *
+ * @return number of references after removing one
+ * @see #addReference()
+ * @see #getDestroyWhenUnused()
+ * @see #setDestroyWhenUnused(boolean)
+ */
+ public abstract int removeReference();
+
+ public abstract AbstractGraphicsDevice getGraphicsDevice();
+
+ /**
+ * @return the fully qualified Display name,
+ * which is a key of {@link #getType()} + {@link #getName()} + {@link #getId()}
+ */
+ public abstract String getFQName();
+
+ public abstract long getHandle();
+
+ /**
+ * @return this display internal serial id
+ */
+ public abstract int getId();
+
+ /**
+ * @return this display instance name as defined at creation time
+ */
+ public abstract String getName();
+
+ /**
+ * @return the native display type, ie {@link javax.media.nativewindow.NativeWindowFactory#getNativeWindowType(boolean)}
+ */
+ public abstract String getType();
+
+ public abstract EDTUtil getEDTUtil();
+
+ public abstract boolean isEDTRunning();
+
+ public abstract void dispatchMessages();
+
+ // Global Displays
+ 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++) {
+ DisplayImpl d = (DisplayImpl) i.next();
+ System.err.println(" ["+j+"] : "+d);
+ }
+ }
+ }
+
+ /**
+ *
+ * @param type
+ * @param name
+ * @param fromIndex start index, then increasing until found or end of list *
+ * @return
+ */
+ public static Display getFirstDisplayOf(String type, String name, int fromIndex) {
+ return getDisplayOfImpl(type, name, fromIndex, 1);
+ }
+
+ /**
+ *
+ * @param type
+ * @param name
+ * @param fromIndex start index, then decreasing until found or end of list. -1 is interpreted as size - 1.
+ * @return
+ */
+ public static Display getLastDisplayOf(String type, String name, int fromIndex) {
+ return getDisplayOfImpl(type, name, fromIndex, -1);
+ }
+
+ private static Display getDisplayOfImpl(String type, String name, int fromIndex, int incr) {
+ synchronized(displayList) {
+ int i = fromIndex >= 0 ? fromIndex : displayList.size() - 1 ;
+ while( ( incr > 0 ) ? i < displayList.size() : i >= 0 ) {
+ Display display = (Display) displayList.get(i);
+ if( display.getType().equals(type) &&
+ display.getName().equals(name) ) {
+ return display;
+ }
+ i+=incr;
+ }
+ }
+ return null;
+ }
+
+ /** Returns the global display collection */
+ public static Collection getAllDisplays() {
+ ArrayList list;
+ synchronized(displayList) {
+ list = (ArrayList) displayList.clone();
+ }
+ return list;
+ }
+
+ public static int getActiveDisplayNumber() {
+ synchronized(displayList) {
+ return displaysActive;
+ }
+ }
+
+ public static String getThreadName() {
+ return Thread.currentThread().getName();
+ }
+
+ public static String toHexString(int hex) {
+ return "0x" + Integer.toHexString(hex);
+ }
+
+ public static String toHexString(long hex) {
+ return "0x" + Long.toHexString(hex);
+ }
+
+ public static int hashCodeNullSafe(Object o) {
+ return ( null != o ) ? o.hashCode() : 0;
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
new file mode 100644
index 000000000..e1b15da69
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -0,0 +1,288 @@
+/*
+ * 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;
+
+import javax.media.nativewindow.*;
+import com.jogamp.common.jvm.JVMUtil;
+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 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();
+ NativeWindowFactory.initSingleton(false); // last resort ..
+ WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
+ }
+
+ public static Class getCustomClass(String packageName, String classBaseName) {
+ Class clazz = null;
+ if(packageName!=null || classBaseName!=null) {
+ String clazzName = packageName + "." + classBaseName ;
+ try {
+ clazz = Class.forName(clazzName);
+ } catch (Throwable t) {}
+ }
+ return clazz;
+ }
+
+ private static boolean useEDT = true;
+
+ /**
+ * Toggles the usage of an EventDispatchThread while creating a Display.<br>
+ * The default is enabled.<br>
+ * The EventDispatchThread is thread local to the Display instance.<br>
+ */
+ public static synchronized void setUseEDT(boolean onoff) {
+ useEDT = onoff;
+ }
+
+ /** @see #setUseEDT(boolean) */
+ public static boolean useEDT() { return useEDT; }
+
+ /**
+ * Create a Display entity, incl native creation
+ */
+ public static Display createDisplay(String name) {
+ return createDisplay(name, true);
+ }
+
+ public static Display createDisplay(String name, boolean reuse) {
+ return DisplayImpl.create(NativeWindowFactory.getNativeWindowType(true), name, 0, reuse);
+ }
+
+ /**
+ * Create a Display entity using the given implementation type, incl native creation
+ */
+ public static Display createDisplay(String type, String name) {
+ return createDisplay(type, name, true);
+ }
+
+ public static Display createDisplay(String type, String name, boolean reuse) {
+ return DisplayImpl.create(type, name, 0, reuse);
+ }
+
+ /**
+ * Create a Screen entity, incl native creation
+ */
+ public static Screen createScreen(Display display, int index) {
+ return ScreenImpl.create(display, index);
+ }
+
+ /**
+ * Create a top level Window entity, incl native creation.<br>
+ * The Display/Screen is created and owned, ie destructed atomatically.<br>
+ * A new Display is only created if no preexisting one could be found via {@link Display#getLastDisplayOf(java.lang.String, java.lang.String, int)}.
+ */
+ 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) {
+ return createWindowImpl(screen, caps);
+ }
+
+ /**
+ * Create a child Window entity attached to the given parent, incl native creation.<br>
+ * The Screen and Display information is regenerated utilizing the parents information.<br>
+ * <p>
+ * In case <code>parentWindowObject</code> is a {@link com.jogamp.newt.Window} instance,<br>
+ * the new window is added to it's list of children.<br>
+ * This assures proper handling of visibility, creation and destruction.<br>
+ * {@link com.jogamp.newt.event.WindowEvent#EVENT_WINDOW_RESIZED} is not propagated to the child window for layout<br>,
+ * you have to add an appropriate {@link com.jogamp.newt.event.WindowListener} for this use case.<br>
+ * 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 appropriate.<br></p>
+ * <p>
+ *
+ * @param parentWindowObject either a NativeWindow instance
+ */
+ public static Window createWindow(NativeWindow nParentWindow, Capabilities caps) {
+ final String type = NativeWindowFactory.getNativeWindowType(true);
+
+ Screen screen = null;
+ Window parentWindow = null;
+
+ if ( nParentWindow instanceof Window ) {
+ // use parent NEWT Windows Display/Screen
+ parentWindow = (Window) nParentWindow ;
+ screen = parentWindow.getScreen();
+ } else {
+ // create a Display/Screen compatible to the NativeWindow
+ AbstractGraphicsConfiguration nParentConfig = nParentWindow.getGraphicsConfiguration();
+ if(null!=nParentConfig) {
+ AbstractGraphicsScreen nParentScreen = nParentConfig.getScreen();
+ AbstractGraphicsDevice nParentDevice = nParentScreen.getDevice();
+ Display display = NewtFactory.createDisplay(type, nParentDevice.getHandle(), true);
+ screen = NewtFactory.createScreen(display, nParentScreen.getIndex());
+ } else {
+ Display display = NewtFactory.createDisplay(type, null, true); // local display
+ screen = NewtFactory.createScreen(display, 0); // screen 0
+ }
+ screen.setDestroyWhenUnused(true);
+ }
+ final Window win = createWindowImpl(nParentWindow, screen, caps);
+
+ win.setSize(nParentWindow.getWidth(), nParentWindow.getHeight());
+ if ( null != parentWindow ) {
+ parentWindow.addChild(win);
+ win.setVisible(parentWindow.isVisible());
+ }
+ return win;
+ }
+
+ protected static Window createWindowImpl(NativeWindow parentNativeWindow, Screen screen, Capabilities caps) {
+ return WindowImpl.create(parentNativeWindow, 0, screen, caps);
+ }
+
+ protected static Window createWindowImpl(long parentWindowHandle, Screen screen, Capabilities caps) {
+ return WindowImpl.create(null, parentWindowHandle, screen, caps);
+ }
+
+ protected static Window createWindowImpl(Screen screen, Capabilities caps) {
+ return WindowImpl.create(null, 0, screen, caps);
+ }
+
+ protected static Window createWindowImpl(String type, Capabilities caps) {
+ Display display = NewtFactory.createDisplay(type, null, true); // local display
+ Screen screen = NewtFactory.createScreen(display, 0); // screen 0
+ screen.setDestroyWhenUnused(true);
+ return WindowImpl.create(null, 0, screen, caps);
+ }
+
+ /**
+ * Create a child Window entity attached to the given parent, incl native creation<br>
+ *
+ * @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) {
+ return createWindowImpl(parentWindowHandle, screen, caps);
+ }
+
+ /**
+ * 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) {
+ return WindowImpl.create(cstrArguments, screen, caps);
+ }
+
+ /**
+ * Instantiate a Display entity using the native handle.
+ */
+ public static Display createDisplay(String type, long handle, boolean reuse) {
+ return DisplayImpl.create(type, null, handle, false);
+ }
+
+ private static final boolean instanceOf(Object obj, String clazzName) {
+ Class clazz = obj.getClass();
+ do {
+ if(clazz.getName().equals(clazzName)) {
+ return true;
+ }
+ clazz = clazz.getSuperclass();
+ } while (clazz!=null);
+ return false;
+ }
+
+ public static boolean isScreenCompatible(NativeWindow parent, Screen childScreen) {
+ // Get parent's NativeWindow details
+ AbstractGraphicsConfiguration parentConfig = (AbstractGraphicsConfiguration) parent.getGraphicsConfiguration();
+ AbstractGraphicsScreen parentScreen = (AbstractGraphicsScreen) parentConfig.getScreen();
+ AbstractGraphicsDevice parentDevice = (AbstractGraphicsDevice) parentScreen.getDevice();
+
+ DisplayImpl childDisplay = (DisplayImpl) childScreen.getDisplay();
+ String parentDisplayName = childDisplay.validateDisplayName(null, parentDevice.getHandle());
+ String childDisplayName = childDisplay.getName();
+ if( ! parentDisplayName.equals( childDisplayName ) ) {
+ return false;
+ }
+
+ if( parentScreen.getIndex() != childScreen.getIndex() ) {
+ return false;
+ }
+ return true;
+ }
+
+ public static Screen createCompatibleScreen(NativeWindow parent) {
+ return createCompatibleScreen(parent, null);
+ }
+
+ public static Screen createCompatibleScreen(NativeWindow parent, Screen childScreen) {
+ // Get parent's NativeWindow details
+ AbstractGraphicsConfiguration parentConfig = (AbstractGraphicsConfiguration) parent.getGraphicsConfiguration();
+ AbstractGraphicsScreen parentScreen = (AbstractGraphicsScreen) parentConfig.getScreen();
+ AbstractGraphicsDevice parentDevice = (AbstractGraphicsDevice) parentScreen.getDevice();
+
+ if(null != childScreen) {
+ // check if child Display/Screen is compatible already
+ DisplayImpl childDisplay = (DisplayImpl) childScreen.getDisplay();
+ String parentDisplayName = childDisplay.validateDisplayName(null, parentDevice.getHandle());
+ String childDisplayName = childDisplay.getName();
+ boolean displayEqual = parentDisplayName.equals( childDisplayName );
+ boolean screenEqual = parentScreen.getIndex() == childScreen.getIndex();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("NewtFactory.createCompatibleScreen: Display: "+
+ parentDisplayName+" =? "+childDisplayName+" : "+displayEqual+"; Screen: "+
+ parentScreen.getIndex()+" =? "+childScreen.getIndex()+" : "+screenEqual);
+ }
+ if( displayEqual && screenEqual ) {
+ // match: display/screen
+ return childScreen;
+ }
+ }
+
+ // Prep NEWT's Display and Screen according to the parent
+ final String type = NativeWindowFactory.getNativeWindowType(true);
+ Display display = NewtFactory.createDisplay(type, parentDevice.getHandle(), true);
+ return NewtFactory.createScreen(display, parentScreen.getIndex());
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
new file mode 100644
index 000000000..d7d6baea7
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -0,0 +1,227 @@
+/**
+ * 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.ScreenModeListener;
+import com.jogamp.newt.impl.Debug;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+
+public abstract class Screen {
+
+ /**
+ * A 10s timeout for screen mode change. It is observed, that some platforms
+ * need a notable amount of time for this task, especially in case of rotation change.
+ */
+ public static final int SCREEN_MODE_CHANGE_TIMEOUT = 10000;
+
+ public static final boolean DEBUG = Debug.debug("Screen");
+
+ /** return precomputed hashCode from FQN {@link #getFQName()} */
+ public abstract int hashCode();
+
+ /** return true if obj is of type Display and both FQN {@link #getFQName()} equals */
+ public boolean equals(Object obj) {
+ if (this == obj) { return true; }
+ if (obj instanceof Screen) {
+ Screen s = (Screen)obj;
+ return s.getFQName().equals(getFQName());
+ }
+ return false;
+ }
+
+ public abstract boolean isNativeValid();
+
+ /**
+ *
+ * @return number of references by Window
+ */
+ public abstract int getReferenceCount();
+
+ public abstract void destroy();
+
+ /**
+ * @return {@link Display#getDestroyWhenUnused()}
+ *
+ * @see #addReference()
+ * @see #removeReference()
+ * @see Display#setDestroyWhenUnused(boolean)
+ */
+ public abstract boolean getDestroyWhenUnused();
+
+ /**
+ * calls {@link Display#setDestroyWhenUnused(boolean)}.
+ *
+ * @see #addReference()
+ * @see #removeReference()
+ * @see Display#setDestroyWhenUnused(boolean)
+ */
+ public abstract void setDestroyWhenUnused(boolean v);
+
+ /**
+ * See {@link Display#addReference()}
+ *
+ * @see #removeReference()
+ * @see #setDestroyWhenUnused(boolean)
+ * @see #getDestroyWhenUnused()
+ */
+ public abstract int addReference();
+
+ /**
+ * See {@link Display#removeReference()}
+ *
+ * @see #addReference()
+ * @see #setDestroyWhenUnused(boolean)
+ * @see #getDestroyWhenUnused()
+ */
+ public abstract int removeReference();
+
+ public abstract AbstractGraphicsScreen getGraphicsScreen();
+
+ /**
+ * @return this Screen index of all Screens of {@link #getDisplay()}.
+ */
+ public abstract int getIndex();
+
+ /**
+ * @return the current screen width
+ */
+ public abstract int getWidth();
+
+ /**
+ * @return the current screen height
+ */
+ public abstract int getHeight();
+
+ /**
+ * @return the associated Display
+ */
+ public abstract Display getDisplay();
+
+ /**
+ * @return the screen fully qualified Screen name,
+ * which is a key of {@link com.jogamp.newt.Display#getFQName()} + {@link #getIndex()}.
+ */
+ public abstract String getFQName();
+
+ /**
+ * @param sml ScreenModeListener to be added for ScreenMode change events
+ */
+ public abstract void addScreenModeListener(ScreenModeListener sml);
+
+ /**
+ * @param sml ScreenModeListener to be removed from ScreenMode change events
+ */
+ public abstract void removeScreenModeListener(ScreenModeListener sml);
+
+ /**
+ * Return a list of available {@link com.jogamp.newt.ScreenMode}s.
+ * @return a shallow copy of the internal immutable {@link com.jogamp.newt.ScreenMode}s,
+ * or null if not implemented for this native type {@link com.jogamp.newt.Display#getType()}.
+ */
+ public abstract List/*<ScreenMode>*/ getScreenModes();
+
+ /**
+ * Return the original {@link com.jogamp.newt.ScreenMode}, as used at NEWT initialization.
+ * @return null if functionality not implemented,
+ * otherwise the original ScreenMode which is element of the list {@link #getScreenModes()}.
+ *
+ */
+ public abstract ScreenMode getOriginalScreenMode();
+
+ /**
+ * Return the current {@link com.jogamp.newt.ScreenMode}.
+ * @return null if functionality not implemented,
+ * otherwise the current ScreenMode which is element of the list {@link #getScreenModes()}.
+ */
+ public abstract ScreenMode getCurrentScreenMode();
+
+ /**
+ * Set the current {@link com.jogamp.newt.ScreenMode}.
+ * @param screenMode to be made current, must be element of the list {@link #getScreenModes()}.
+ * @return true if successful, otherwise false
+ */
+ public abstract boolean setCurrentScreenMode(ScreenMode screenMode);
+
+ // Global Screens
+ protected static ArrayList screenList = new ArrayList();
+ protected static int screensActive = 0;
+
+ /**
+ *
+ * @param type
+ * @param name
+ * @param fromIndex start index, then increasing until found or end of list *
+ * @return
+ */
+ public static Screen getFirstScreenOf(Display display, int idx, int fromIndex) {
+ return getScreenOfImpl(display, idx, fromIndex, 1);
+ }
+
+ /**
+ *
+ * @param type
+ * @param name
+ * @param fromIndex start index, then decreasing until found or end of list. -1 is interpreted as size - 1.
+ * @return
+ */
+ public static Screen getLastScreenOf(Display display, int idx, int fromIndex) {
+ return getScreenOfImpl(display, idx, fromIndex, -1);
+ }
+
+ private static Screen getScreenOfImpl(Display display, int idx, int fromIndex, int incr) {
+ synchronized(screenList) {
+ int i = fromIndex >= 0 ? fromIndex : screenList.size() - 1 ;
+ while( ( incr > 0 ) ? i < screenList.size() : i >= 0 ) {
+ Screen screen = (Screen) screenList.get(i);
+ if( screen.getDisplay().equals(display) &&
+ screen.getIndex() == idx ) {
+ return screen;
+ }
+ i+=incr;
+ }
+ }
+ return null;
+ }
+ /** Returns the global display collection */
+ public static Collection getAllScreens() {
+ ArrayList list;
+ synchronized(screenList) {
+ list = (ArrayList) screenList.clone();
+ }
+ return list;
+ }
+
+ public static int getActiveScreenNumber() {
+ synchronized(screenList) {
+ return screensActive;
+ }
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/ScreenMode.java b/src/newt/classes/com/jogamp/newt/ScreenMode.java
new file mode 100644
index 000000000..81ce70249
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/ScreenMode.java
@@ -0,0 +1,189 @@
+/**
+ * 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.util.MonitorMode;
+
+/** Immutable ScreenMode Class, consisting of it's read only components:<br>
+ * <ul>
+ * <li>{@link com.jogamp.newt.util.MonitorMode}, non rotated values</li>
+ * <li><code>rotation</code>, measured counter clockwise (CCW)</li>
+ * </ul>
+ *
+ * <i>Aquire and filter ScreenModes</i><br>
+ * <ul>
+ * <li>A List of read only ScreenMode's is being returned by {@link com.jogamp.newt.Screen#getScreenModes()}.</li>
+ * <li>You may utilize {@link com.jogamp.newt.util.ScreenModeUtil} to filter and select a desired ScreenMode.</li>
+ * <li>The current ScreenMode can be obtained via {@link com.jogamp.newt.Screen#getCurrentScreenMode()}.</li>
+ * <li>The initial original ScreenMode (at startup) can be obtained via {@link com.jogamp.newt.Screen#getOriginalScreenMode()}.</li>
+ * </ul>
+ * <br>
+ *
+ * <i>Changing ScreenModes</i><br>
+ * <ul>
+ * <li> Use {@link com.jogamp.newt.Screen#setCurrentScreenMode(com.jogamp.newt.ScreenMode)}</li>
+ * to change the current ScreenMode of all Screen's referenced via the full qualified name (FQN)
+ * {@link com.jogamp.newt.Screen#getFQName()}.</li>
+ * <li> When the last FQN referenced Screen closes, the original ScreenMode ({@link com.jogamp.newt.Screen#getOriginalScreenMode()})
+ * is restored.</li>
+ * </ul>
+ * <br>
+ * Example for changing the ScreenMode:
+ * <pre>
+ // determine target refresh rate
+ ScreenMode orig = screen.getOriginalScreenMode();
+ int freq = orig.getMonitorMode().getRefreshRate();
+
+ // target resolution
+ Dimension res = new Dimension(800, 600);
+
+ // target rotation
+ int rot = 0;
+
+ // filter available ScreenModes
+ List screenModes = screen.getScreenModes();
+ screenModes = ScreenModeUtil.filterByRate(screenModes, freq); // get the nearest ones
+ screenModes = ScreenModeUtil.filterByRotation(screenModes, rot);
+ screenModes = ScreenModeUtil.filterByResolution(screenModes, res); // get the nearest ones
+ screenModes = ScreenModeUtil.getHighestAvailableBpp(screenModes);
+
+ // pick 1st one ..
+ screen.setCurrentScreenMode((ScreenMode) screenModes.get(0));
+ * </pre>
+ *
+ * X11 / AMD just works<br>
+ * <br>
+ * X11 / NVidia difficulties
+ * <pre>
+ NVidia RANDR RefreshRate Bug
+ If NVidia's 'DynamicTwinView' is enabled, all refresh rates are
+ unique, ie consequent numbers starting with the default refresh, ie 50, 51, ..
+ The only way to workaround it is to disable 'DynamicTwinView'.
+ Read: http://us.download.nvidia.com/XFree86/Linux-x86/260.19.12/README/configtwinview.html
+
+ Check to see if 'DynamicTwinView' is enable:
+ nvidia-settings -q :0/DynamicTwinview
+
+ To disable it (workaround), add the following option to your xorg.conf device section:
+ Option "DynamicTwinView" "False"
+
+ NVidia RANDR Rotation:
+ To enable it, add the following option to your xorg.conf device section:
+ Option "RandRRotation" "on"
+ * </pre>
+ *
+ */
+public class ScreenMode implements Cloneable {
+ /** zero rotation, compared to normal settings */
+ public static final int ROTATE_0 = 0;
+
+ /** 90 degrees CCW rotation */
+ public static final int ROTATE_90 = 90;
+
+ /** 180 degrees CCW rotation */
+ public static final int ROTATE_180 = 180;
+
+ /** 270 degrees CCW rotation */
+ public static final int ROTATE_270 = 270;
+
+ MonitorMode monitorMode;
+ int rotation;
+
+ public static boolean isRotationValid(int rotation) {
+ return rotation == ScreenMode.ROTATE_0 || rotation == ScreenMode.ROTATE_90 ||
+ rotation == ScreenMode.ROTATE_180 || rotation == ScreenMode.ROTATE_270 ;
+ }
+
+ /**
+ * @param monitorMode the monitor mode
+ * @param rotation the screen rotation, measured counter clockwise (CCW)
+ */
+ public ScreenMode(MonitorMode monitorMode, int rotation) {
+ if ( !isRotationValid(rotation) ) {
+ throw new RuntimeException("invalid rotation: "+rotation);
+ }
+ this.monitorMode = monitorMode;
+ this.rotation = rotation;
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
+ /** Returns the unrotated <code>MonitorMode</code> */
+ public final MonitorMode getMonitorMode() {
+ return monitorMode;
+ }
+
+ /** Returns the CCW rotation of this mode */
+ public final int getRotation() {
+ return rotation;
+ }
+
+ public final String toString() {
+ return "[ " + getMonitorMode() + ", " + rotation + " degr ]";
+ }
+
+ /**
+ * Tests equality of two <code>ScreenMode</code> objects
+ * by evaluating equality of it's components:<br>
+ * <ul>
+ * <li><code>monitorMode</code></li>
+ * <li><code>rotation</code></li>
+ * </ul>
+ * <br>
+ */
+ public final boolean equals(Object obj) {
+ if (this == obj) { return true; }
+ if (obj instanceof ScreenMode) {
+ ScreenMode sm = (ScreenMode)obj;
+ return sm.getMonitorMode().equals(getMonitorMode()) &&
+ sm.getRotation() == this.getRotation() ;
+ }
+ return false;
+ }
+
+ /**
+ * Returns a combined hash code of it's elements:<br>
+ * <ul>
+ * <li><code>monitorMode</code></li>
+ * <li><code>rotation</code></li>
+ * </ul>
+ */
+ public final int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + getMonitorMode().hashCode();
+ hash = ((hash << 5) - hash) + getRotation();
+ return hash;
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
new file mode 100644
index 000000000..ba7d51e67
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -0,0 +1,413 @@
+/**
+ * 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.WindowListener;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.impl.Debug;
+import javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
+
+/**
+ * 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, ScreenModeListener {
+ 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");
+
+ /** A 1s timeout while waiting for a native action response, ie {@link #setVisible(boolean)}. */
+ public static final long TIMEOUT_NATIVEWINDOW = 1000;
+
+ //
+ // Lifecycle
+ //
+
+ /**
+ * @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)
+ */
+ boolean isValid();
+
+ /**
+ * @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)
+ */
+ boolean isNativeValid();
+
+ /**
+ * @return The associated Screen
+ */
+ Screen getScreen();
+
+ /**
+ * @return The requested capabilities
+ */
+ Capabilities getRequestedCapabilities();
+
+ Capabilities getChosenCapabilities();
+
+ /**
+ *
+ * <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()
+ */
+ void destroy();
+
+ /**
+ *
+ * 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>
+ * <code>setVisible</code> makes the window and children visible if <code>visible</code> is true,
+ * otherwise the window and children becomes invisible.<br></p>
+ * <p>
+ * The <code>setVisible(true)</code> is responsible to actual create the native window.<br></p>
+ * <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();
+ * }
+ * } else if ( this.visible != visible ) {
+ * this.visible = visible;
+ * setNativeSizeImpl();
+ * }
+ * </pre></p>
+ * <p>
+ * In case this window is a child window and a parent {@link javax.media.nativewindow.NativeWindow} is being used,<br>
+ * the parent's {@link javax.media.nativewindow.NativeWindow} handle is retrieved via {@link javax.media.nativewindow.NativeWindow#getWindowHandle()}.<br>
+ * 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>
+ */
+ 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
+ * Total size of the window will be
+ * {@code width+insets.left+insets.right, height+insets.top+insets.bottom}<br>
+ * <p>
+ * Zero size semantics are respected, see {@link #setVisible(boolean)}:<br>
+ * <pre>
+ * if ( 0 != windowHandle && 0>=width*height && visible ) {
+ * setVisible(false);
+ * } else if ( 0 == windowHandle && 0<width*height && visible ) {
+ * setVisible(true);
+ * } else {
+ * // as expected ..
+ * }
+ * </pre></p>
+ * <p>
+ * This call is ignored if in fullscreen mode.<br></p>
+ *
+ * @param width of the client area of the window
+ * @param height of the client area of the window
+ */
+ 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;
+ }
+
+ /**
+ * 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
+ * decorations (so the client area will be placed at
+ * {@code x+insets.left,y+insets.top}.<br>
+ *
+ * This call is ignored if in fullscreen mode.<br>
+ *
+ * @param x coord of the top left corner
+ * @param y coord of the top left corner
+ */
+ void setPosition(int x, int y);
+
+ int getX();
+
+ int getY();
+
+ /**
+ * 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();
+
+ void setUndecorated(boolean value);
+
+ boolean isUndecorated();
+
+ void setTitle(String title);
+
+ 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();
+ }
+
+ /**
+ * 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);
+
+ void requestFocus();
+
+ boolean hasFocus();
+
+ void windowRepaint(int x, int y, int width, int height);
+
+ void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event);
+
+ void runOnEDTIfAvail(boolean wait, final Runnable task);
+
+
+ //
+ // SurfaceUpdateListener
+ //
+
+ /**
+ * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of
+ * the list.
+ */
+ void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
+ /**
+ *
+ * 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 l The listener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
+
+ void removeAllSurfaceUpdatedListener();
+
+ void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
+
+ SurfaceUpdatedListener getSurfaceUpdatedListener(int index);
+
+ SurfaceUpdatedListener[] getSurfaceUpdatedListeners();
+
+
+ //
+ // WindowListener
+ //
+
+ public void sendWindowEvent(int eventType);
+
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.WindowListener} to the end of
+ * the list.
+ */
+ void addWindowListener(WindowListener l);
+
+ /**
+ *
+ * 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 l The listener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException;
+
+ void removeWindowListener(WindowListener l);
+
+ WindowListener getWindowListener(int index);
+
+ WindowListener[] getWindowListeners();
+
+ //
+ // KeyListener
+ //
+
+
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.KeyListener} to the end of
+ * the list.
+ */
+ void addKeyListener(KeyListener l);
+
+ /**
+ *
+ * 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 l The listener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ void addKeyListener(int index, KeyListener l);
+
+ void removeKeyListener(KeyListener l);
+
+ KeyListener getKeyListener(int index);
+
+ KeyListener[] getKeyListeners();
+
+
+ //
+ // MouseListener
+ //
+
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.MouseListener} to the end of
+ * the list.
+ */
+ void addMouseListener(MouseListener l);
+
+ /**
+ *
+ * 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 l The listener object to be inserted
+ * @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
+ */
+ void addMouseListener(int index, MouseListener l);
+
+ void removeMouseListener(MouseListener l);
+
+ MouseListener getMouseListener(int index);
+
+ MouseListener[] getMouseListeners();
+
+}
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
new file mode 100644
index 000000000..3ba721855
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -0,0 +1,328 @@
+/**
+ * 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.awt;
+
+import com.jogamp.newt.Display;
+import java.lang.reflect.*;
+import java.security.*;
+
+import java.awt.Canvas;
+import java.awt.EventQueue;
+import java.awt.Graphics;
+import java.awt.KeyboardFocusManager;
+
+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.Window;
+import com.jogamp.newt.impl.Debug;
+
+public class NewtCanvasAWT extends java.awt.Canvas {
+ public static final boolean DEBUG = Debug.debug("Window");
+
+ NativeWindow nativeWindow = null;
+ Window newtChild = null;
+ AWTAdapter awtAdapter = null;
+
+ /**
+ * Instantiates a NewtCanvas without a NEWT child.<br>
+ */
+ public NewtCanvasAWT() {
+ super();
+ }
+
+ /**
+ * Instantiates a NewtCanvas with a NEWT child.
+ */
+ public NewtCanvasAWT(Window child) {
+ super();
+ setNEWTChild(child);
+ }
+
+ class FocusAction implements Window.FocusRunnable {
+ public boolean run() {
+ if ( EventQueue.isDispatchThread() ) {
+ focusActionImpl.run();
+ } else {
+ try {
+ EventQueue.invokeAndWait(focusActionImpl);
+ } catch (Exception e) {
+ throw new NativeWindowException(e);
+ }
+ }
+ return focusActionImpl.result;
+ }
+
+ class FocusActionImpl implements Runnable {
+ public final boolean result = false; // NEWT shall always proceed requesting the native focus
+ public void run() {
+ if(DEBUG) {
+ System.err.println("FocusActionImpl.run() "+Display.getThreadName());
+ }
+ NewtCanvasAWT.this.requestFocusAWTParent();
+ KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ kfm.clearGlobalFocusOwner();
+ }
+ }
+ FocusActionImpl focusActionImpl = new FocusActionImpl();
+ }
+ FocusAction focusAction = new FocusAction();
+
+ /** sets a new NEWT child, provoking reparenting on the NEWT level. */
+ public NewtCanvasAWT setNEWTChild(Window child) {
+ if(newtChild!=child) {
+ newtChild = child;
+ if(null!=nativeWindow) {
+ java.awt.Container cont = getContainer(this);
+ // reparent right away, addNotify has been called already
+ reparentWindow( (null!=newtChild) ? true : false, cont );
+ }
+ }
+ return this;
+ }
+
+ /** @return the current NEWT child */
+ public Window getNEWTChild() {
+ return newtChild;
+ }
+
+ /** @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 nativeWindow; }
+
+ void setWindowAdapter(boolean attach) {
+ if(null!=awtAdapter) {
+ awtAdapter.removeFrom(this);
+ awtAdapter=null;
+ }
+ if(attach && null!=newtChild) {
+ awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this);
+ }
+ }
+
+ static java.awt.Container getContainer(java.awt.Component comp) {
+ while( null != comp ) {
+ if( comp instanceof java.awt.Container ) {
+ return (java.awt.Container) comp;
+ }
+ comp = comp.getParent();
+ }
+ return null;
+ }
+
+ public void addNotify() {
+ super.addNotify();
+ disableBackgroundErase();
+ java.awt.Container cont = getContainer(this);
+ if(DEBUG) {
+ // if ( isShowing() == false ) -> Container was not visible yet.
+ // if ( isShowing() == true ) -> Container is already visible.
+ System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+
+ ", displayable "+isDisplayable()+" -> "+cont);
+ }
+ reparentWindow(true, cont);
+ }
+
+ public void removeNotify() {
+ java.awt.Container cont = getContainer(this);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.removeNotify: "+newtChild+", from "+cont);
+ }
+ reparentWindow(false, cont);
+ super.removeNotify();
+ }
+
+ void reparentWindow(boolean add, java.awt.Container cont) {
+ if(null==newtChild) {
+ return; // nop
+ }
+
+ newtChild.setFocusAction(null); // no AWT focus traversal ..
+ if(add) {
+ nativeWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
+ if(null!=nativeWindow) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild);
+ }
+ final int w = cont.getWidth();
+ final int h = cont.getHeight();
+ setSize(w, h);
+ newtChild.setSize(w, h);
+ newtChild.reparentWindow(nativeWindow);
+ newtChild.setVisible(true);
+ setWindowAdapter(true);
+ newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
+ newtChild.windowRepaint(0, 0, w, h);
+ newtChild.setFocusAction(focusAction); // enable AWT focus traversal
+ }
+ } else {
+ setWindowAdapter(false);
+ nativeWindow = null;
+ newtChild.setVisible(false);
+ newtChild.reparentWindow(null);
+ }
+ }
+
+ /**
+ * @see #destroy(boolean)
+ */
+ public final void destroy() {
+ destroy(false);
+ }
+
+ /**
+ * Destroys this resource:
+ * <ul>
+ * <li> Make the NEWT Child invisible </li>
+ * <li> Disconnects the NEWT Child from this Canvas NativeWindow, reparent to NULL </li>
+ * <li> Issues <code>destroy(unrecoverable)</code> on the NEWT Child</li>
+ * <li> Remove reference to the NEWT Child, if unrecoverable</li>
+ * <li> Remove this Canvas from it's parent.</li>
+ * </ul>
+ * @see Window#destroy()
+ * @see Window#destroy(boolean)
+ */
+ public final void destroy(boolean unrecoverable) {
+ if(null!=newtChild) {
+ java.awt.Container cont = getContainer(this);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.destroy("+unrecoverable+"): "+newtChild+", from "+cont);
+ }
+ nativeWindow = null;
+ newtChild.setVisible(false);
+ newtChild.reparentWindow(null);
+ newtChild.destroy(unrecoverable);
+ if(unrecoverable) {
+ newtChild = null;
+ }
+ if(null!=cont) {
+ cont.remove(this);
+ }
+ }
+ }
+
+ public void paint(Graphics g) {
+ if(null!=newtChild) {
+ newtChild.windowRepaint(0, 0, getWidth(), getHeight());
+ }
+ }
+ public void update(Graphics g) {
+ if(null!=newtChild) {
+ newtChild.windowRepaint(0, 0, getWidth(), getHeight());
+ }
+ }
+
+ final void requestFocusAWTParent() {
+ super.requestFocus();
+ }
+
+ final void requestFocusNEWTChild() {
+ if(null!=newtChild) {
+ newtChild.setFocusAction(null);
+ newtChild.requestFocus();
+ newtChild.setFocusAction(focusAction);
+ }
+ }
+
+ public void requestFocus() {
+ requestFocusAWTParent();
+ requestFocusNEWTChild();
+ }
+
+ public boolean requestFocus(boolean temporary) {
+ boolean res = super.requestFocus(temporary);
+ if(res) {
+ requestFocusNEWTChild();
+ }
+ return res;
+ }
+
+ public boolean requestFocusInWindow() {
+ boolean res = super.requestFocusInWindow();
+ if(res) {
+ requestFocusNEWTChild();
+ }
+ return res;
+ }
+
+ public boolean requestFocusInWindow(boolean temporary) {
+ boolean res = super.requestFocusInWindow(temporary);
+ if(res) {
+ requestFocusNEWTChild();
+ }
+ return res;
+ }
+
+ // Disables the AWT's erasing of this Canvas's background on Windows
+ // in Java SE 6. This internal API is not available in previous
+ // releases, but the system property
+ // -Dsun.awt.noerasebackground=true can be specified to get similar
+ // results globally in previous releases.
+ private static boolean disableBackgroundEraseInitialized;
+ private static Method disableBackgroundEraseMethod;
+ private void disableBackgroundErase() {
+ if (!disableBackgroundEraseInitialized) {
+ try {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class clazz = getToolkit().getClass();
+ while (clazz != null && disableBackgroundEraseMethod == null) {
+ try {
+ disableBackgroundEraseMethod =
+ clazz.getDeclaredMethod("disableBackgroundErase",
+ new Class[] { Canvas.class });
+ disableBackgroundEraseMethod.setAccessible(true);
+ } catch (Exception e) {
+ clazz = clazz.getSuperclass();
+ }
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ }
+ disableBackgroundEraseInitialized = true;
+ }
+ if (disableBackgroundEraseMethod != null) {
+ try {
+ disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this });
+ } catch (Exception e) {
+ // FIXME: workaround for 6504460 (incorrect backport of 6333613 in 5.0u10)
+ // throw new GLException(e);
+ }
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java
new file mode 100644
index 000000000..7b9130188
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtFactoryAWT.java
@@ -0,0 +1,74 @@
+/**
+ * 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.awt;
+
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.impl.Debug;
+
+public class NewtFactoryAWT extends NewtFactory {
+ public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
+
+ /**
+ * Wraps an AWT component into a {@link javax.media.nativewindow.NativeWindow} utilizing the {@link javax.media.nativewindow.NativeWindowFactory},<br>
+ * using a configuration agnostic dummy {@link javax.media.nativewindow.DefaultGraphicsConfiguration}.<br>
+ * <p>
+ * The actual wrapping implementation is {@link com.jogamp.nativewindow.impl.jawt.JAWTWindow}.<br></p>
+ * <p>
+ * Purpose of this wrapping is to access the AWT window handle,<br>
+ * not to actually render into it.<br>
+ * Hence the dummy configuration only.</p>
+ *
+ * @param awtCompObject must be of type java.awt.Component
+ */
+ public static NativeWindow getNativeWindow(Object awtCompObject, Capabilities capsRequested) {
+ if(null==awtCompObject) {
+ throw new NativeWindowException("Null AWT Component");
+ }
+ if( ! (awtCompObject instanceof java.awt.Component) ) {
+ throw new NativeWindowException("AWT Component not a java.awt.Component");
+ }
+ return getNativeWindow( (java.awt.Component) awtCompObject, capsRequested );
+ }
+
+ public static NativeWindow getNativeWindow(java.awt.Component awtComp, Capabilities capsRequested) {
+ DefaultGraphicsConfiguration config =
+ AWTGraphicsConfiguration.create(awtComp, (Capabilities) capsRequested.clone(), capsRequested);
+ NativeWindow awtNative = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+awtNative);
+ }
+ return awtNative;
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
new file mode 100644
index 000000000..148787845
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
@@ -0,0 +1,89 @@
+/*
+ * 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.event;
+
+public abstract class InputEvent extends NEWTEvent
+{
+ public static final int SHIFT_MASK = 1 << 0;
+ public static final int CTRL_MASK = 1 << 1;
+ public static final int META_MASK = 1 << 2;
+ public static final int ALT_MASK = 1 << 3;
+ public static final int ALT_GRAPH_MASK = 1 << 5;
+ public static final int BUTTON1_MASK = 1 << 6;
+ public static final int BUTTON2_MASK = 1 << 7;
+ public static final int BUTTON3_MASK = 1 << 8;
+
+ protected InputEvent(int eventType, Object source, long when, int modifiers) {
+ super(eventType, source, when);
+ this.modifiers=modifiers;
+ }
+
+ public int getModifiers() {
+ return modifiers;
+ }
+ public boolean isAltDown() {
+ return (modifiers&ALT_MASK)!=0;
+ }
+ public boolean isAltGraphDown() {
+ return (modifiers&ALT_GRAPH_MASK)!=0;
+ }
+ public boolean isControlDown() {
+ return (modifiers&CTRL_MASK)!=0;
+ }
+ public boolean isMetaDown() {
+ return (modifiers&META_MASK)!=0;
+ }
+ public boolean isShiftDown() {
+ return (modifiers&SHIFT_MASK)!=0;
+ }
+
+ public boolean isButton1Down() {
+ return (modifiers&BUTTON1_MASK)!=0;
+ }
+
+ public boolean isButton2Down() {
+ return (modifiers&BUTTON2_MASK)!=0;
+ }
+
+ public boolean isButton3Down() {
+ return (modifiers&BUTTON3_MASK)!=0;
+ }
+
+ public String toString() {
+ return "InputEvent[modifiers:"+modifiers+", "+super.toString()+"]";
+ }
+
+ private int modifiers;
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyAdapter.java b/src/newt/classes/com/jogamp/newt/event/KeyAdapter.java
new file mode 100644
index 000000000..93c8409b1
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/KeyAdapter.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright 2010 JogAmp Community. 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:
+ *
+ * 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.event;
+
+public abstract class KeyAdapter implements KeyListener
+{
+ public void keyPressed(KeyEvent e) {
+ }
+ public void keyReleased(KeyEvent e) {
+ }
+ public void keyTyped(KeyEvent e) {
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
new file mode 100644
index 000000000..852f77fcb
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -0,0 +1,736 @@
+/*
+ * 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.event;
+
+public class KeyEvent extends InputEvent
+{
+ public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
+ super(eventType, source, when, modifiers);
+ this.keyCode=keyCode;
+ this.keyChar=keyChar;
+ }
+
+ public char getKeyChar() {
+ return keyChar;
+ }
+ public int getKeyCode() {
+ return keyCode;
+ }
+
+ public String toString() {
+ return "KeyEvent["+getEventTypeString(getEventType())+
+ ", code "+keyCode+"("+toHexString(keyCode)+"), char <"+keyChar+"> ("+toHexString((int)keyChar)+"), isActionKey "+isActionKey()+", "+super.toString()+"]";
+ }
+
+ public static String getEventTypeString(int type) {
+ switch(type) {
+ case EVENT_KEY_PRESSED: return "EVENT_KEY_PRESSED";
+ case EVENT_KEY_RELEASED: return "EVENT_KEY_RELEASED";
+ case EVENT_KEY_TYPED: return "EVENT_KEY_TYPED";
+ default: return "unknown (" + type + ")";
+ }
+ }
+
+ public boolean isActionKey() {
+ switch (keyCode) {
+ case VK_HOME:
+ case VK_END:
+ case VK_PAGE_UP:
+ case VK_PAGE_DOWN:
+ case VK_UP:
+ case VK_DOWN:
+ case VK_LEFT:
+ case VK_RIGHT:
+
+ case VK_F1:
+ case VK_F2:
+ case VK_F3:
+ case VK_F4:
+ case VK_F5:
+ case VK_F6:
+ case VK_F7:
+ case VK_F8:
+ case VK_F9:
+ case VK_F10:
+ case VK_F11:
+ case VK_F12:
+ case VK_F13:
+ case VK_F14:
+ case VK_F15:
+ case VK_F16:
+ case VK_F17:
+ case VK_F18:
+ case VK_F19:
+ case VK_F20:
+ case VK_F21:
+ case VK_F22:
+ case VK_F23:
+ case VK_F24:
+ case VK_PRINTSCREEN:
+ case VK_CAPS_LOCK:
+ case VK_PAUSE:
+ case VK_INSERT:
+
+ case VK_HELP:
+ case VK_WINDOWS:
+ return true;
+ }
+ return false;
+ }
+
+ private int keyCode;
+ private char keyChar;
+
+ public static final int EVENT_KEY_PRESSED = 300;
+ public static final int EVENT_KEY_RELEASED= 301;
+ public static final int EVENT_KEY_TYPED = 302;
+
+ /* Virtual key codes. */
+
+ public static final int VK_ENTER = '\n';
+ public static final int VK_BACK_SPACE = '\b';
+ public static final int VK_TAB = '\t';
+ public static final int VK_CANCEL = 0x03;
+ public static final int VK_CLEAR = 0x0C;
+ public static final int VK_SHIFT = 0x10;
+ public static final int VK_CONTROL = 0x11;
+ public static final int VK_ALT = 0x12;
+ public static final int VK_PAUSE = 0x13;
+ public static final int VK_CAPS_LOCK = 0x14;
+ public static final int VK_ESCAPE = 0x1B;
+ public static final int VK_SPACE = 0x20;
+ public static final int VK_PAGE_UP = 0x21;
+ public static final int VK_PAGE_DOWN = 0x22;
+ public static final int VK_END = 0x23;
+ public static final int VK_HOME = 0x24;
+
+ /**
+ * Constant for the non-numpad <b>left</b> arrow key.
+ * @see #VK_KP_LEFT
+ */
+ public static final int VK_LEFT = 0x25;
+
+ /**
+ * Constant for the non-numpad <b>up</b> arrow key.
+ * @see #VK_KP_UP
+ */
+ public static final int VK_UP = 0x26;
+
+ /**
+ * Constant for the non-numpad <b>right</b> arrow key.
+ * @see #VK_KP_RIGHT
+ */
+ public static final int VK_RIGHT = 0x27;
+
+ /**
+ * Constant for the non-numpad <b>down</b> arrow key.
+ * @see #VK_KP_DOWN
+ */
+ public static final int VK_DOWN = 0x28;
+
+ /**
+ * Constant for the comma key, ","
+ */
+ public static final int VK_COMMA = 0x2C;
+
+ /**
+ * Constant for the minus key, "-"
+ * @since 1.2
+ */
+ public static final int VK_MINUS = 0x2D;
+
+ /**
+ * Constant for the period key, "."
+ */
+ public static final int VK_PERIOD = 0x2E;
+
+ /**
+ * Constant for the forward slash key, "/"
+ */
+ public static final int VK_SLASH = 0x2F;
+
+ /** VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
+ public static final int VK_0 = 0x30;
+ public static final int VK_1 = 0x31;
+ public static final int VK_2 = 0x32;
+ public static final int VK_3 = 0x33;
+ public static final int VK_4 = 0x34;
+ public static final int VK_5 = 0x35;
+ public static final int VK_6 = 0x36;
+ public static final int VK_7 = 0x37;
+ public static final int VK_8 = 0x38;
+ public static final int VK_9 = 0x39;
+
+ /**
+ * Constant for the semicolon key, ";"
+ */
+ public static final int VK_SEMICOLON = 0x3B;
+
+ /**
+ * Constant for the equals key, "="
+ */
+ public static final int VK_EQUALS = 0x3D;
+
+ /** VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
+ public static final int VK_A = 0x41;
+ public static final int VK_B = 0x42;
+ public static final int VK_C = 0x43;
+ public static final int VK_D = 0x44;
+ public static final int VK_E = 0x45;
+ public static final int VK_F = 0x46;
+ public static final int VK_G = 0x47;
+ public static final int VK_H = 0x48;
+ public static final int VK_I = 0x49;
+ public static final int VK_J = 0x4A;
+ public static final int VK_K = 0x4B;
+ public static final int VK_L = 0x4C;
+ public static final int VK_M = 0x4D;
+ public static final int VK_N = 0x4E;
+ public static final int VK_O = 0x4F;
+ public static final int VK_P = 0x50;
+ public static final int VK_Q = 0x51;
+ public static final int VK_R = 0x52;
+ public static final int VK_S = 0x53;
+ public static final int VK_T = 0x54;
+ public static final int VK_U = 0x55;
+ public static final int VK_V = 0x56;
+ public static final int VK_W = 0x57;
+ public static final int VK_X = 0x58;
+ public static final int VK_Y = 0x59;
+ public static final int VK_Z = 0x5A;
+
+ /**
+ * Constant for the open bracket key, "["
+ */
+ public static final int VK_OPEN_BRACKET = 0x5B;
+
+ /**
+ * Constant for the back slash key, "\"
+ */
+ public static final int VK_BACK_SLASH = 0x5C;
+
+ /**
+ * Constant for the close bracket key, "]"
+ */
+ public static final int VK_CLOSE_BRACKET = 0x5D;
+
+ public static final int VK_NUMPAD0 = 0x60;
+ public static final int VK_NUMPAD1 = 0x61;
+ public static final int VK_NUMPAD2 = 0x62;
+ public static final int VK_NUMPAD3 = 0x63;
+ public static final int VK_NUMPAD4 = 0x64;
+ public static final int VK_NUMPAD5 = 0x65;
+ public static final int VK_NUMPAD6 = 0x66;
+ public static final int VK_NUMPAD7 = 0x67;
+ public static final int VK_NUMPAD8 = 0x68;
+ public static final int VK_NUMPAD9 = 0x69;
+ public static final int VK_MULTIPLY = 0x6A;
+ public static final int VK_ADD = 0x6B;
+
+ /**
+ * This constant is obsolete, and is included only for backwards
+ * compatibility.
+ * @see #VK_SEPARATOR
+ */
+ public static final int VK_SEPARATER = 0x6C;
+
+ /**
+ * Constant for the Numpad Separator key.
+ * @since 1.4
+ */
+ public static final int VK_SEPARATOR = VK_SEPARATER;
+
+ public static final int VK_SUBTRACT = 0x6D;
+ public static final int VK_DECIMAL = 0x6E;
+ public static final int VK_DIVIDE = 0x6F;
+ public static final int VK_DELETE = 0x7F; /* ASCII DEL */
+ public static final int VK_NUM_LOCK = 0x90;
+ public static final int VK_SCROLL_LOCK = 0x91;
+
+ /** Constant for the F1 function key. */
+ public static final int VK_F1 = 0x70;
+
+ /** Constant for the F2 function key. */
+ public static final int VK_F2 = 0x71;
+
+ /** Constant for the F3 function key. */
+ public static final int VK_F3 = 0x72;
+
+ /** Constant for the F4 function key. */
+ public static final int VK_F4 = 0x73;
+
+ /** Constant for the F5 function key. */
+ public static final int VK_F5 = 0x74;
+
+ /** Constant for the F6 function key. */
+ public static final int VK_F6 = 0x75;
+
+ /** Constant for the F7 function key. */
+ public static final int VK_F7 = 0x76;
+
+ /** Constant for the F8 function key. */
+ public static final int VK_F8 = 0x77;
+
+ /** Constant for the F9 function key. */
+ public static final int VK_F9 = 0x78;
+
+ /** Constant for the F10 function key. */
+ public static final int VK_F10 = 0x79;
+
+ /** Constant for the F11 function key. */
+ public static final int VK_F11 = 0x7A;
+
+ /** Constant for the F12 function key. */
+ public static final int VK_F12 = 0x7B;
+
+ /**
+ * Constant for the F13 function key.
+ * @since 1.2
+ */
+ /* F13 - F24 are used on IBM 3270 keyboard; use random range for constants. */
+ public static final int VK_F13 = 0xF000;
+
+ /**
+ * Constant for the F14 function key.
+ * @since 1.2
+ */
+ public static final int VK_F14 = 0xF001;
+
+ /**
+ * Constant for the F15 function key.
+ * @since 1.2
+ */
+ public static final int VK_F15 = 0xF002;
+
+ /**
+ * Constant for the F16 function key.
+ * @since 1.2
+ */
+ public static final int VK_F16 = 0xF003;
+
+ /**
+ * Constant for the F17 function key.
+ * @since 1.2
+ */
+ public static final int VK_F17 = 0xF004;
+
+ /**
+ * Constant for the F18 function key.
+ * @since 1.2
+ */
+ public static final int VK_F18 = 0xF005;
+
+ /**
+ * Constant for the F19 function key.
+ * @since 1.2
+ */
+ public static final int VK_F19 = 0xF006;
+
+ /**
+ * Constant for the F20 function key.
+ * @since 1.2
+ */
+ public static final int VK_F20 = 0xF007;
+
+ /**
+ * Constant for the F21 function key.
+ * @since 1.2
+ */
+ public static final int VK_F21 = 0xF008;
+
+ /**
+ * Constant for the F22 function key.
+ * @since 1.2
+ */
+ public static final int VK_F22 = 0xF009;
+
+ /**
+ * Constant for the F23 function key.
+ * @since 1.2
+ */
+ public static final int VK_F23 = 0xF00A;
+
+ /**
+ * Constant for the F24 function key.
+ * @since 1.2
+ */
+ public static final int VK_F24 = 0xF00B;
+
+ public static final int VK_PRINTSCREEN = 0x9A;
+ public static final int VK_INSERT = 0x9B;
+ public static final int VK_HELP = 0x9C;
+ public static final int VK_META = 0x9D;
+
+ public static final int VK_BACK_QUOTE = 0xC0;
+ public static final int VK_QUOTE = 0xDE;
+
+ /**
+ * Constant for the numeric keypad <b>up</b> arrow key.
+ * @see #VK_UP
+ * @since 1.2
+ */
+ public static final int VK_KP_UP = 0xE0;
+
+ /**
+ * Constant for the numeric keypad <b>down</b> arrow key.
+ * @see #VK_DOWN
+ * @since 1.2
+ */
+ public static final int VK_KP_DOWN = 0xE1;
+
+ /**
+ * Constant for the numeric keypad <b>left</b> arrow key.
+ * @see #VK_LEFT
+ * @since 1.2
+ */
+ public static final int VK_KP_LEFT = 0xE2;
+
+ /**
+ * Constant for the numeric keypad <b>right</b> arrow key.
+ * @see #VK_RIGHT
+ * @since 1.2
+ */
+ public static final int VK_KP_RIGHT = 0xE3;
+
+ /* For European keyboards */
+ /** @since 1.2 */
+ public static final int VK_DEAD_GRAVE = 0x80;
+ /** @since 1.2 */
+ public static final int VK_DEAD_ACUTE = 0x81;
+ /** @since 1.2 */
+ public static final int VK_DEAD_CIRCUMFLEX = 0x82;
+ /** @since 1.2 */
+ public static final int VK_DEAD_TILDE = 0x83;
+ /** @since 1.2 */
+ public static final int VK_DEAD_MACRON = 0x84;
+ /** @since 1.2 */
+ public static final int VK_DEAD_BREVE = 0x85;
+ /** @since 1.2 */
+ public static final int VK_DEAD_ABOVEDOT = 0x86;
+ /** @since 1.2 */
+ public static final int VK_DEAD_DIAERESIS = 0x87;
+ /** @since 1.2 */
+ public static final int VK_DEAD_ABOVERING = 0x88;
+ /** @since 1.2 */
+ public static final int VK_DEAD_DOUBLEACUTE = 0x89;
+ /** @since 1.2 */
+ public static final int VK_DEAD_CARON = 0x8a;
+ /** @since 1.2 */
+ public static final int VK_DEAD_CEDILLA = 0x8b;
+ /** @since 1.2 */
+ public static final int VK_DEAD_OGONEK = 0x8c;
+ /** @since 1.2 */
+ public static final int VK_DEAD_IOTA = 0x8d;
+ /** @since 1.2 */
+ public static final int VK_DEAD_VOICED_SOUND = 0x8e;
+ /** @since 1.2 */
+ public static final int VK_DEAD_SEMIVOICED_SOUND = 0x8f;
+
+ /** @since 1.2 */
+ public static final int VK_AMPERSAND = 0x96;
+ /** @since 1.2 */
+ public static final int VK_ASTERISK = 0x97;
+ /** @since 1.2 */
+ public static final int VK_QUOTEDBL = 0x98;
+ /** @since 1.2 */
+ public static final int VK_LESS = 0x99;
+
+ /** @since 1.2 */
+ public static final int VK_GREATER = 0xa0;
+ /** @since 1.2 */
+ public static final int VK_BRACELEFT = 0xa1;
+ /** @since 1.2 */
+ public static final int VK_BRACERIGHT = 0xa2;
+
+ /**
+ * Constant for the "@" key.
+ * @since 1.2
+ */
+ public static final int VK_AT = 0x0200;
+
+ /**
+ * Constant for the ":" key.
+ * @since 1.2
+ */
+ public static final int VK_COLON = 0x0201;
+
+ /**
+ * Constant for the "^" key.
+ * @since 1.2
+ */
+ public static final int VK_CIRCUMFLEX = 0x0202;
+
+ /**
+ * Constant for the "$" key.
+ * @since 1.2
+ */
+ public static final int VK_DOLLAR = 0x0203;
+
+ /**
+ * Constant for the Euro currency sign key.
+ * @since 1.2
+ */
+ public static final int VK_EURO_SIGN = 0x0204;
+
+ /**
+ * Constant for the "!" key.
+ * @since 1.2
+ */
+ public static final int VK_EXCLAMATION_MARK = 0x0205;
+
+ /**
+ * Constant for the inverted exclamation mark key.
+ * @since 1.2
+ */
+ public static final int VK_INVERTED_EXCLAMATION_MARK = 0x0206;
+
+ /**
+ * Constant for the "(" key.
+ * @since 1.2
+ */
+ public static final int VK_LEFT_PARENTHESIS = 0x0207;
+
+ /**
+ * Constant for the "#" key.
+ * @since 1.2
+ */
+ public static final int VK_NUMBER_SIGN = 0x0208;
+
+ /**
+ * Constant for the "+" key.
+ * @since 1.2
+ */
+ public static final int VK_PLUS = 0x0209;
+
+ /**
+ * Constant for the ")" key.
+ * @since 1.2
+ */
+ public static final int VK_RIGHT_PARENTHESIS = 0x020A;
+
+ /**
+ * Constant for the "_" key.
+ * @since 1.2
+ */
+ public static final int VK_UNDERSCORE = 0x020B;
+
+ /**
+ * Constant for the Microsoft Windows "Windows" key.
+ * It is used for both the left and right version of the key.
+ * @see #getKeyLocation()
+ * @since 1.5
+ */
+ public static final int VK_WINDOWS = 0x020C;
+
+ /**
+ * Constant for the Microsoft Windows Context Menu key.
+ * @since 1.5
+ */
+ public static final int VK_CONTEXT_MENU = 0x020D;
+
+ /* for input method support on Asian Keyboards */
+
+ /* not clear what this means - listed in Microsoft Windows API */
+ public static final int VK_FINAL = 0x0018;
+
+ /** Constant for the Convert function key. */
+ /* Japanese PC 106 keyboard, Japanese Solaris keyboard: henkan */
+ public static final int VK_CONVERT = 0x001C;
+
+ /** Constant for the Don't Convert function key. */
+ /* Japanese PC 106 keyboard: muhenkan */
+ public static final int VK_NONCONVERT = 0x001D;
+
+ /** Constant for the Accept or Commit function key. */
+ /* Japanese Solaris keyboard: kakutei */
+ public static final int VK_ACCEPT = 0x001E;
+
+ /* not clear what this means - listed in Microsoft Windows API */
+ public static final int VK_MODECHANGE = 0x001F;
+
+ /* replaced by VK_KANA_LOCK for Microsoft Windows and Solaris;
+ might still be used on other platforms */
+ public static final int VK_KANA = 0x0015;
+
+ /* replaced by VK_INPUT_METHOD_ON_OFF for Microsoft Windows and Solaris;
+ might still be used for other platforms */
+ public static final int VK_KANJI = 0x0019;
+
+ /**
+ * Constant for the Alphanumeric function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard: eisuu */
+ public static final int VK_ALPHANUMERIC = 0x00F0;
+
+ /**
+ * Constant for the Katakana function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard: katakana */
+ public static final int VK_KATAKANA = 0x00F1;
+
+ /**
+ * Constant for the Hiragana function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard: hiragana */
+ public static final int VK_HIRAGANA = 0x00F2;
+
+ /**
+ * Constant for the Full-Width Characters function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard: zenkaku */
+ public static final int VK_FULL_WIDTH = 0x00F3;
+
+ /**
+ * Constant for the Half-Width Characters function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard: hankaku */
+ public static final int VK_HALF_WIDTH = 0x00F4;
+
+ /**
+ * Constant for the Roman Characters function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard: roumaji */
+ public static final int VK_ROMAN_CHARACTERS = 0x00F5;
+
+ /**
+ * Constant for the All Candidates function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard - VK_CONVERT + ALT: zenkouho */
+ public static final int VK_ALL_CANDIDATES = 0x0100;
+
+ /**
+ * Constant for the Previous Candidate function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard - VK_CONVERT + SHIFT: maekouho */
+ public static final int VK_PREVIOUS_CANDIDATE = 0x0101;
+
+ /**
+ * Constant for the Code Input function key.
+ * @since 1.2
+ */
+ /* Japanese PC 106 keyboard - VK_ALPHANUMERIC + ALT: kanji bangou */
+ public static final int VK_CODE_INPUT = 0x0102;
+
+ /**
+ * Constant for the Japanese-Katakana function key.
+ * This key switches to a Japanese input method and selects its Katakana input mode.
+ * @since 1.2
+ */
+ /* Japanese Macintosh keyboard - VK_JAPANESE_HIRAGANA + SHIFT */
+ public static final int VK_JAPANESE_KATAKANA = 0x0103;
+
+ /**
+ * Constant for the Japanese-Hiragana function key.
+ * This key switches to a Japanese input method and selects its Hiragana input mode.
+ * @since 1.2
+ */
+ /* Japanese Macintosh keyboard */
+ public static final int VK_JAPANESE_HIRAGANA = 0x0104;
+
+ /**
+ * Constant for the Japanese-Roman function key.
+ * This key switches to a Japanese input method and selects its Roman-Direct input mode.
+ * @since 1.2
+ */
+ /* Japanese Macintosh keyboard */
+ public static final int VK_JAPANESE_ROMAN = 0x0105;
+
+ /**
+ * Constant for the locking Kana function key.
+ * This key locks the keyboard into a Kana layout.
+ * @since 1.3
+ */
+ /* Japanese PC 106 keyboard with special Windows driver - eisuu + Control; Japanese Solaris keyboard: kana */
+ public static final int VK_KANA_LOCK = 0x0106;
+
+ /**
+ * Constant for the input method on/off key.
+ * @since 1.3
+ */
+ /* Japanese PC 106 keyboard: kanji. Japanese Solaris keyboard: nihongo */
+ public static final int VK_INPUT_METHOD_ON_OFF = 0x0107;
+
+ /* for Sun keyboards */
+ /** @since 1.2 */
+ public static final int VK_CUT = 0xFFD1;
+ /** @since 1.2 */
+ public static final int VK_COPY = 0xFFCD;
+ /** @since 1.2 */
+ public static final int VK_PASTE = 0xFFCF;
+ /** @since 1.2 */
+ public static final int VK_UNDO = 0xFFCB;
+ /** @since 1.2 */
+ public static final int VK_AGAIN = 0xFFC9;
+ /** @since 1.2 */
+ public static final int VK_FIND = 0xFFD0;
+ /** @since 1.2 */
+ public static final int VK_PROPS = 0xFFCA;
+ /** @since 1.2 */
+ public static final int VK_STOP = 0xFFC8;
+
+ /**
+ * Constant for the Compose function key.
+ * @since 1.2
+ */
+ public static final int VK_COMPOSE = 0xFF20;
+
+ /**
+ * Constant for the AltGraph function key.
+ * @since 1.2
+ */
+ public static final int VK_ALT_GRAPH = 0xFF7E;
+
+ /**
+ * Constant for the Begin key.
+ * @since 1.5
+ */
+ public static final int VK_BEGIN = 0xFF58;
+
+ /**
+ * This value is used to indicate that the keyCode is unknown.
+ * KEY_TYPED events do not have a keyCode value; this value
+ * is used instead.
+ */
+ public static final int VK_UNDEFINED = 0x0;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyListener.java b/src/newt/classes/com/jogamp/newt/event/KeyListener.java
new file mode 100644
index 000000000..dae343d80
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/KeyListener.java
@@ -0,0 +1,43 @@
+/*
+ * 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.event;
+
+public interface KeyListener extends NEWTEventListener
+{
+ public void keyPressed(KeyEvent e);
+ public void keyReleased(KeyEvent e);
+ public void keyTyped(KeyEvent e) ;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseAdapter.java b/src/newt/classes/com/jogamp/newt/event/MouseAdapter.java
new file mode 100644
index 000000000..3607ae634
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/MouseAdapter.java
@@ -0,0 +1,50 @@
+/**
+ * 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.event;
+
+public abstract class MouseAdapter implements MouseListener
+{
+ public void mouseClicked(MouseEvent e) {
+ }
+ public void mouseEntered(MouseEvent e) {
+ }
+ public void mouseExited(MouseEvent e) {
+ }
+ public void mousePressed(MouseEvent e) {
+ }
+ public void mouseReleased(MouseEvent e) {
+ }
+ public void mouseMoved(MouseEvent e) {
+ }
+ public void mouseDragged(MouseEvent e) {
+ }
+ public void mouseWheelMoved(MouseEvent e) {
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
new file mode 100644
index 000000000..fbe32d41d
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
@@ -0,0 +1,110 @@
+/*
+ * 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.event;
+
+public class MouseEvent extends InputEvent
+{
+ public static final int BUTTON1 = 1;
+ public static final int BUTTON2 = 2;
+ public static final int BUTTON3 = 3;
+ public static final int BUTTON4 = 4;
+ public static final int BUTTON5 = 5;
+ public static final int BUTTON6 = 6;
+ public static final int BUTTON_NUMBER = 6;
+
+ public static final int getClickTimeout() {
+ return 300;
+ }
+
+ public MouseEvent(int eventType, Object source, long when,
+ int modifiers, int x, int y, int clickCount, int button,
+ int rotation)
+ {
+ super(eventType, source, when, modifiers);
+ this.x=x;
+ this.y=y;
+ this.clickCount=clickCount;
+ this.button=button;
+ this.wheelRotation = rotation;
+ }
+
+ public int getButton() {
+ return button;
+ }
+ public int getClickCount() {
+ return clickCount;
+ }
+ public int getX() {
+ return x;
+ }
+ public int getY() {
+ return y;
+ }
+ public int getWheelRotation() {
+ return wheelRotation;
+ }
+
+ public String toString() {
+ return "MouseEvent["+getEventTypeString(getEventType())+
+ ", "+x+"/"+y+", button "+button+", count "+clickCount+
+ ", wheel rotation "+wheelRotation+
+ ", "+super.toString()+"]";
+ }
+
+ public static String getEventTypeString(int type) {
+ switch(type) {
+ case EVENT_MOUSE_CLICKED: return "EVENT_MOUSE_CLICKED";
+ case EVENT_MOUSE_ENTERED: return "EVENT_MOUSE_ENTERED";
+ case EVENT_MOUSE_EXITED: return "EVENT_MOUSE_EXITED";
+ case EVENT_MOUSE_PRESSED: return "EVENT_MOUSE_PRESSED";
+ case EVENT_MOUSE_RELEASED: return "EVENT_MOUSE_RELEASED";
+ case EVENT_MOUSE_MOVED: return "EVENT_MOUSE_MOVED";
+ case EVENT_MOUSE_DRAGGED: return "EVENT_MOUSE_DRAGGED";
+ case EVENT_MOUSE_WHEEL_MOVED: return "EVENT_MOUSE_WHEEL_MOVED";
+ default: return "unknown (" + type + ")";
+ }
+ }
+
+ private int x, y, clickCount, button, wheelRotation;
+
+ public static final int EVENT_MOUSE_CLICKED = 200;
+ public static final int EVENT_MOUSE_ENTERED = 201;
+ public static final int EVENT_MOUSE_EXITED = 202;
+ public static final int EVENT_MOUSE_PRESSED = 203;
+ public static final int EVENT_MOUSE_RELEASED = 204;
+ public static final int EVENT_MOUSE_MOVED = 205;
+ public static final int EVENT_MOUSE_DRAGGED = 206;
+ public static final int EVENT_MOUSE_WHEEL_MOVED = 207;
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseListener.java b/src/newt/classes/com/jogamp/newt/event/MouseListener.java
new file mode 100644
index 000000000..5ec086b94
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/MouseListener.java
@@ -0,0 +1,48 @@
+/*
+ * 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.event;
+
+public interface MouseListener extends NEWTEventListener
+{
+ public void mouseClicked(MouseEvent e);
+ public void mouseEntered(MouseEvent e);
+ public void mouseExited(MouseEvent e);
+ public void mousePressed(MouseEvent e);
+ public void mouseReleased(MouseEvent e);
+ public void mouseMoved(MouseEvent e);
+ public void mouseDragged(MouseEvent e);
+ public void mouseWheelMoved(MouseEvent e);
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
new file mode 100644
index 000000000..10673be3d
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -0,0 +1,164 @@
+/*
+ * 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.event;
+
+/**
+ * NEWT events are provided for notification purposes ONLY;<br>
+ * The NEWT will automatically handle the event semantics internally, regardless of whether a program is receiving these events or not.<br>
+ * The actual event semantic is processed before the event is send.<br>
+ *
+ * Event type registry:<br>
+ * <ul>
+ * <li> WindowEvent <code>100..10x</code></li>
+ * <li> MouseEvent <code>200..20x</code></li>
+ * <li> KeyEvent <code>300..30x</code></li>
+ * </ul><br>
+ */
+public class NEWTEvent extends java.util.EventObject {
+ private boolean isSystemEvent;
+ private int eventType;
+ private long when;
+ private Object attachment;
+
+ static final boolean DEBUG = false;
+
+ // 0: NEWTEvent.java
+ // 1: InputEvent.java
+ // 2: KeyEvent.java
+ // 3: com.jogamp.newt.Window
+ // 3: com.jogamp.newt.event.awt.AWTNewtEventFactory
+ // 2: MouseEvent.java
+ // 3: com.jogamp.newt.Window
+ // 3: com.jogamp.newt.event.awt.AWTNewtEventFactory
+ // 1: WindowEvent.java
+ // 2: com.jogamp.newt.Window
+ // 2: com.jogamp.newt.event.awt.AWTNewtEventFactory
+ //
+ // FIXME: verify the isSystemEvent evaluation
+ //
+ static final String WindowClazzName = "com.jogamp.newt.Window" ;
+ static final String AWTNewtEventFactoryClazzName = "com.jogamp.newt.event.awt.AWTNewtEventFactory" ;
+
+ /**
+ static final boolean evaluateIsSystemEvent(NEWTEvent event, Throwable t) {
+ StackTraceElement[] stack = t.getStackTrace();
+ if(stack.length==0 || null==stack[0]) {
+ return false;
+ }
+ if(DEBUG) {
+ for (int i = 0; i < stack.length && i<5; i++) {
+ System.err.println(i+": " + stack[i].getClassName()+ "." + stack[i].getMethodName());
+ }
+ }
+
+ String clazzName = null;
+
+ if( event instanceof com.jogamp.newt.event.WindowEvent ) {
+ if ( stack.length > 2 ) {
+ clazzName = stack[2].getClassName();
+ }
+ } else if( (event instanceof com.jogamp.newt.event.MouseEvent) ||
+ (event instanceof com.jogamp.newt.event.KeyEvent) ) {
+ if ( stack.length > 3 ) {
+ clazzName = stack[3].getClassName();
+ }
+ }
+
+ boolean res = null!=clazzName && (
+ clazzName.equals(WindowClazzName) ||
+ clazzName.equals(AWTNewtEventFactoryClazzName) ) ;
+ if(DEBUG) {
+ System.err.println("system: "+res);
+ }
+ return res;
+ } */
+
+ protected NEWTEvent(int eventType, Object source, long when) {
+ super(source);
+ // this.isSystemEvent = evaluateIsSystemEvent(this, new Throwable());
+ this.isSystemEvent = false; // FIXME: Need a more efficient way to determine system events
+ this.eventType = eventType;
+ this.when = when;
+ this.attachment=null;
+ }
+
+ /** Indicates whether this event was produced by the system or
+ generated by user code. */
+ public final boolean isSystemEvent() {
+ return isSystemEvent;
+ }
+
+ /** Returns the event type of this event. */
+ public final int getEventType() {
+ return eventType;
+ }
+
+ /** Returns the timestamp, in milliseconds, of this event. */
+ public final long getWhen() {
+ return when;
+ }
+
+ /**
+ * Attach the passed object to this event.<br>
+ * If an object was previously attached, it will be replaced.<br>
+ * Attachments to NEWT events allow users to pass on information
+ * from one custom listener to another, ie custom listener to listener
+ * communication.
+ * @param attachment User application specific object
+ */
+ public final void setAttachment(Object attachment) {
+ this.attachment=attachment;
+ }
+
+ /**
+ * @return The user application specific attachment, or null
+ */
+ public final Object getAttachment() {
+ return attachment;
+ }
+
+ public String toString() {
+ return "NEWTEvent[sys:"+isSystemEvent()+", source:"+getSource().getClass().getName()+", when:"+getWhen()+" d "+(System.currentTimeMillis()-getWhen())+"ms]";
+ }
+
+ public static String toHexString(int hex) {
+ return "0x" + Integer.toHexString(hex);
+ }
+
+ public static String toHexString(long hex) {
+ return "0x" + Long.toHexString(hex);
+ }
+
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEventConsumer.java b/src/newt/classes/com/jogamp/newt/event/NEWTEventConsumer.java
new file mode 100644
index 000000000..6aa19e5f8
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEventConsumer.java
@@ -0,0 +1,40 @@
+/**
+ * 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.event;
+
+public interface NEWTEventConsumer {
+
+ /**
+ * Consume the event
+ *
+ * @return true if the event has been consumed,
+ * otherwise it returns false for later propagation.
+ */
+ public boolean consumeEvent(NEWTEvent event);
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java b/src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java
new file mode 100644
index 000000000..fe224bba6
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEventFiFo.java
@@ -0,0 +1,62 @@
+/**
+ * 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.event;
+
+import java.util.LinkedList;
+
+public class NEWTEventFiFo
+{
+ private LinkedList/*<NEWTEvent>*/ events = new LinkedList/*<NEWTEvent>*/();
+
+ /** Add NEWTEvent to tail */
+ public synchronized void put(NEWTEvent event) {
+ events.addLast(event);
+ notifyAll();
+ }
+
+ /** Remove NEWTEvent from head */
+ public synchronized NEWTEvent get() {
+ if (0 == events.size()) {
+ return null;
+ }
+
+ return (NEWTEvent) events.removeFirst();
+ }
+
+ /** Get NEWTEvents in queue */
+ public synchronized int size() {
+ return events.size();
+ }
+
+ /** Clear all NEWTEvents from queue */
+ public synchronized void clear() {
+ events.clear();
+ }
+
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/NEWTEventListener.java b/src/newt/classes/com/jogamp/newt/event/NEWTEventListener.java
new file mode 100644
index 000000000..677136573
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEventListener.java
@@ -0,0 +1,40 @@
+/*
+ * 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.event;
+
+public interface NEWTEventListener extends java.util.EventListener
+{
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java b/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java
new file mode 100644
index 000000000..7bca23cfe
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/ScreenModeListener.java
@@ -0,0 +1,39 @@
+/**
+ * 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.event;
+
+import com.jogamp.newt.ScreenMode;
+
+public interface ScreenModeListener {
+ /** called before the screen mode will be changed */
+ void screenModeChangeNotify(ScreenMode sm);
+
+ /** called after the screen mode has been changed */
+ void screenModeChanged(ScreenMode sm, boolean success);
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java b/src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java
new file mode 100644
index 000000000..98ba5a24d
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/TraceKeyAdapter.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.event;
+
+public class TraceKeyAdapter implements KeyListener {
+
+ KeyListener downstream;
+
+ public TraceKeyAdapter() {
+ this.downstream = null;
+ }
+
+ public TraceKeyAdapter(KeyListener downstream) {
+ this.downstream = downstream;
+ }
+
+ public void keyPressed(KeyEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.keyPressed(e); }
+ }
+ public void keyReleased(KeyEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.keyReleased(e); }
+ }
+ public void keyTyped(KeyEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.keyTyped(e); }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/TraceMouseAdapter.java b/src/newt/classes/com/jogamp/newt/event/TraceMouseAdapter.java
new file mode 100644
index 000000000..14ee633a0
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/TraceMouseAdapter.java
@@ -0,0 +1,76 @@
+/**
+ * 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.event;
+
+public class TraceMouseAdapter implements MouseListener {
+
+ MouseListener downstream;
+
+ public TraceMouseAdapter() {
+ this.downstream = null;
+ }
+
+ public TraceMouseAdapter(MouseListener downstream) {
+ this.downstream = downstream;
+ }
+
+ public void mouseClicked(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mouseClicked(e); }
+ }
+ public void mouseEntered(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mouseEntered(e); }
+ }
+ public void mouseExited(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mouseExited(e); }
+ }
+ public void mousePressed(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mousePressed(e); }
+ }
+ public void mouseReleased(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mouseReleased(e); }
+ }
+ public void mouseMoved(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mouseMoved(e); }
+ }
+ public void mouseDragged(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mouseDragged(e); }
+ }
+ public void mouseWheelMoved(MouseEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.mouseWheelMoved(e); }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java
new file mode 100644
index 000000000..88b165a8d
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/TraceWindowAdapter.java
@@ -0,0 +1,67 @@
+/**
+ * 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.event;
+
+public class TraceWindowAdapter implements WindowListener {
+
+ WindowListener downstream;
+
+ public TraceWindowAdapter() {
+ this.downstream = null;
+ }
+
+ public TraceWindowAdapter(WindowListener downstream) {
+ this.downstream = downstream;
+ }
+
+ public void windowResized(WindowEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.windowResized(e); }
+ }
+ public void windowMoved(WindowEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.windowMoved(e); }
+ }
+ public void windowDestroyNotify(WindowEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.windowDestroyNotify(e); }
+ }
+ public void windowGainedFocus(WindowEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.windowGainedFocus(e); }
+ }
+ public void windowLostFocus(WindowEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.windowLostFocus(e); }
+ }
+ public void windowRepaint(WindowUpdateEvent e) {
+ System.err.println(e);
+ if(null!=downstream) { downstream.windowRepaint(e); }
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java
new file mode 100644
index 000000000..a1ad43a13
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/WindowAdapter.java
@@ -0,0 +1,45 @@
+/**
+ * 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.event;
+
+public abstract class WindowAdapter implements WindowListener
+{
+ public void windowResized(WindowEvent e) {
+ }
+ public void windowMoved(WindowEvent e) {
+ }
+ public void windowDestroyNotify(WindowEvent e) {
+ }
+ public void windowGainedFocus(WindowEvent e) {
+ }
+ public void windowLostFocus(WindowEvent e) {
+ }
+ public void windowRepaint(WindowUpdateEvent e) {
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
new file mode 100644
index 000000000..2742e0d95
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/WindowEvent.java
@@ -0,0 +1,69 @@
+/*
+ * 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.event;
+
+/**
+ * NEWT Window events are provided for notification purposes ONLY.<br>
+ * NEWT will automatically handle component moves and resizes internally, regardless of whether a program is receiving these events or not. <br>
+ * The actual event semantic, here move and resize, is processed before the event is send.<br>
+ */
+public class WindowEvent extends NEWTEvent {
+ public static final int EVENT_WINDOW_RESIZED = 100;
+ public static final int EVENT_WINDOW_MOVED = 101;
+ public static final int EVENT_WINDOW_DESTROY_NOTIFY = 102;
+ public static final int EVENT_WINDOW_GAINED_FOCUS = 103;
+ public static final int EVENT_WINDOW_LOST_FOCUS = 104;
+ public static final int EVENT_WINDOW_REPAINT = 105;
+
+ public WindowEvent(int eventType, Object source, long when) {
+ super(eventType, source, when);
+ }
+
+ public static String getEventTypeString(int type) {
+ switch(type) {
+ case EVENT_WINDOW_RESIZED: return "WINDOW_RESIZED";
+ case EVENT_WINDOW_MOVED: return "WINDOW_MOVED";
+ case EVENT_WINDOW_DESTROY_NOTIFY: return "EVENT_WINDOW_DESTROY_NOTIFY";
+ case EVENT_WINDOW_GAINED_FOCUS: return "EVENT_WINDOW_GAINED_FOCUS";
+ case EVENT_WINDOW_LOST_FOCUS: return "EVENT_WINDOW_LOST_FOCUS";
+ case EVENT_WINDOW_REPAINT: return "EVENT_WINDOW_REPAINT";
+ default: return "unknown (" + type + ")";
+ }
+ }
+ public String toString() {
+ return "WindowEvent["+getEventTypeString(getEventType()) +
+ ", " + super.toString() + "]";
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/WindowListener.java b/src/newt/classes/com/jogamp/newt/event/WindowListener.java
new file mode 100644
index 000000000..0d201a2a4
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/WindowListener.java
@@ -0,0 +1,55 @@
+/*
+ * 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.event;
+
+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/event/WindowUpdateEvent.java b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
new file mode 100644
index 000000000..7cd6ee370
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/WindowUpdateEvent.java
@@ -0,0 +1,49 @@
+/**
+ * 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.event;
+
+import javax.media.nativewindow.util.Rectangle;
+
+public class WindowUpdateEvent extends WindowEvent {
+ Rectangle bounds;
+
+ public WindowUpdateEvent(int eventType, Object source, long when, Rectangle bounds)
+ {
+ super(eventType, source, when);
+ this.bounds = bounds;
+ }
+
+ public Rectangle getBounds() {
+ return bounds;
+ }
+
+ public String toString() {
+ return "WindowUpdateEvent["+super.toString()+", "+bounds+"]";
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java
new file mode 100644
index 000000000..c136946ac
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTAdapter.java
@@ -0,0 +1,180 @@
+/**
+ * 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.event.awt;
+
+import com.jogamp.newt.impl.Debug;
+
+/**
+ * Convenient adapter forwarding AWT events to NEWT via the event listener model.<br>
+ * <p>
+ * You may attach an instance of this adapter to an AWT Component. When an event happens,
+ * it is converted to a NEWT event and the given NEWT listener is being called.<br></p>
+ * <p>
+ * This adapter fullfills three use cases. First as a plain utility to write code AWT agnostic,
+ * ie write an {@link javax.media.opengl.GLEvenListener} and some appropriate NEWT {@link com.jogamp.newt.event.NEWTEventListener}.<br></p>
+ * <p>
+ * Attach the {@link javax.media.opengl.GLEvenListener} to a NEWT {@link javax.media.opengl.GLAutoDrawable}, e.g. {@link com.jogamp.newt.opengl.GLWindow},<br>
+ * or to an AWT {@link javax.media.opengl.GLAutoDrawable}, e.g. {@link javax.media.opengl.awt.GLCanvas}.<br>
+ * <br>
+ * Attach the NEWT {@link com.jogamp.newt.event.NEWTEventListener} to a NEWT component, e.g. {@link com.jogamp.newt.Window},<br>
+ * or to an AWT component, e.g. {@link java.awt.Component}.<br></p>
+ * <p>
+ * Common:<br>
+ * <pre>
+ // your demo/render code
+ javax.media.opengl.GLEvenListener demo1 = new javax.media.opengl.GLEvenListener() { ... } ;
+
+ // your AWT agnostic NEWT mouse listener code
+ com.jogamp.newt.event.MouseListener mouseListener = new com.jogamp.newt.event.MouseAdapter() { ... } ;
+ * </pre> </p>
+ * <p>
+ * Default NEWT use case, without using the AWTAdapter:<br>
+ * <pre>
+ // the NEWT GLAutoDrawable and Window
+ GLWindow glWindow = GLWindow.create();
+
+ // attach the renderer demo1
+ glWindow.addGLEventListener(demo1);
+
+ // attach the NEWT mouse event listener to glWindow
+ glWindow.addMouseListener(mouseListener);
+ * </pre> </p>
+ * <p>
+ * AWT use case, AWTAdapter used as an AWT event translator and forwarder to your NEWT listener:<br>
+ * <pre>
+ // the AWT GLAutoDrawable and Canvas
+ GLCanvas glCanvas = new GLCanvas();
+
+ // attach the renderer demo1
+ glCanvas.addGLEventListener(demo1);
+
+ // attach the AWTMouseAdapter to glCanvas, which translates and forwards events to the NEWT mouseListener
+ new AWTMouseAdapter(mouseListener).addTo(glCanvas);
+ * </pre> </p>
+ * <p>
+ * Previous code in detail:<br>
+ * <pre>
+ AWTMouseAdapter mouseAdapter = new AWTMouseAdapter(mouseListener);
+ glCanvas.addMouseListener(mouseAdapter);
+ glCanvas.addMouseMotionListener(mouseAdapter);
+ * </pre> </p>
+ *
+ * <p>
+ * Second use case is just a litte variation of the previous use case, where we pass a NEWT Window <br>
+ * to be used as the source of the event.<br></p>
+ * <p>
+ * <pre>
+ com.jogamp.newt.event.MouseListener mouseListener = new com.jogamp.newt.event.MouseAdapter() { ... } ;<br>
+ Component comp = ... ; // the AWT component<br>
+ GLWindow glWindow = GLWindow.create(); // the NEWT component<br>
+ <br>
+ new AWTMouseAdapter(mouseListener, glWindow).addTo(comp);<br>
+ * </pre> </p>
+ *
+ * Last but not least, the AWTAdapter maybe used as a general AWT event forwarder to NEWT.<br>
+ *
+ * <p>
+ * <pre>
+ com.jogamp.newt.event.MouseListener mouseListener = new com.jogamp.newt.event.MouseAdapter() { ... } ;<br>
+ Component comp = ... ; // the AWT component<br>
+ GLWindow glWindow = GLWindow.create(); // the NEWT component<br>
+ glWindow.addMouseListener(mouseListener); // add the custom EventListener to the NEWT component<br>
+ <br>
+ new AWTMouseAdapter(glWindow).addTo(comp); // forward all AWT events to glWindow, as NEWT events<br>
+ * </pre> </p>
+ *
+ * @see #attachTo
+ */
+public abstract class AWTAdapter implements java.util.EventListener
+{
+ public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
+
+ com.jogamp.newt.event.NEWTEventListener newtListener;
+ com.jogamp.newt.Window newtWindow;
+
+ /**
+ * Simply wrap aroung a NEWT EventListener, exposed as an AWT EventListener.<br>
+ * The NEWT EventListener will be called when an event happens.<br>
+ */
+ public AWTAdapter(com.jogamp.newt.event.NEWTEventListener newtListener) {
+ if(null==newtListener) {
+ throw new RuntimeException("Argument newtListener is null");
+ }
+ this.newtListener = newtListener;
+ this.newtWindow = null;
+ }
+
+ /**
+ * Wrap aroung a NEWT EventListener, exposed as an AWT EventListener,<br>
+ * where the given NEWT Window impersonates as the event's source.
+ * The NEWT EventListener will be called when an event happens.<br>
+ */
+ public AWTAdapter(com.jogamp.newt.event.NEWTEventListener newtListener, com.jogamp.newt.Window newtProxy) {
+ if(null==newtListener) {
+ throw new RuntimeException("Argument newtListener is null");
+ }
+ if(null==newtProxy) {
+ throw new RuntimeException("Argument newtProxy is null");
+ }
+ this.newtListener = newtListener;
+ this.newtWindow = newtProxy;
+ }
+
+ /**
+ * Create a pipeline adapter, AWT EventListener.<br>
+ * Once attached to an AWT component, it sends the converted AWT events to the NEWT downstream window.<br>
+ * This is only supported with EDT enabled!
+ */
+ public AWTAdapter(com.jogamp.newt.Window downstream) {
+ if(null==downstream) {
+ throw new RuntimeException("Argument downstream is null");
+ }
+ this.newtListener = null;
+ this.newtWindow = downstream;
+ if( null == newtWindow.getScreen().getDisplay().getEDTUtil() ) {
+ throw new RuntimeException("EDT not enabled");
+ }
+ }
+
+ /**
+ * Due to the fact that some NEWT {@link com.jogamp.newt.event.NEWTEventListener}
+ * are mapped to more than one {@link java.util.EventListener},
+ * this method is for your convenience to use this Adapter as a listener for all types.<br>
+ * E.g. {@link com.jogamp.newt.event.MouseListener} is mapped to {@link java.awt.event.MouseListener} and {@link java.awt.event.MouseMotionListener}.
+ */
+ public abstract AWTAdapter addTo(java.awt.Component awtComponent);
+
+ /** @see #addTo(java.awt.Component) */
+ public abstract AWTAdapter removeFrom(java.awt.Component awtComponent);
+
+ void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
+ newtWindow.enqueueEvent(wait, event);
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java
new file mode 100644
index 000000000..8fe6ff63a
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTKeyAdapter.java
@@ -0,0 +1,82 @@
+/**
+ * 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.event.awt;
+
+public class AWTKeyAdapter extends AWTAdapter implements java.awt.event.KeyListener
+{
+ public AWTKeyAdapter(com.jogamp.newt.event.KeyListener newtListener) {
+ super(newtListener);
+ }
+
+ public AWTKeyAdapter(com.jogamp.newt.event.KeyListener newtListener, com.jogamp.newt.Window newtProxy) {
+ super(newtListener, newtProxy);
+ }
+
+ public AWTKeyAdapter(com.jogamp.newt.Window downstream) {
+ super(downstream);
+ }
+
+ public AWTAdapter addTo(java.awt.Component awtComponent) {
+ awtComponent.addKeyListener(this);
+ return this;
+ }
+
+ public AWTAdapter removeFrom(java.awt.Component awtComponent) {
+ awtComponent.removeKeyListener(this);
+ return this;
+ }
+
+ public void keyPressed(java.awt.event.KeyEvent e) {
+ com.jogamp.newt.event.KeyEvent event = AWTNewtEventFactory.createKeyEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.KeyListener)newtListener).keyPressed(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void keyReleased(java.awt.event.KeyEvent e) {
+ com.jogamp.newt.event.KeyEvent event = AWTNewtEventFactory.createKeyEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.KeyListener)newtListener).keyReleased(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void keyTyped(java.awt.event.KeyEvent e) {
+ com.jogamp.newt.event.KeyEvent event = AWTNewtEventFactory.createKeyEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.KeyListener)newtListener).keyTyped(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTMouseAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTMouseAdapter.java
new file mode 100644
index 000000000..bd421073a
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTMouseAdapter.java
@@ -0,0 +1,120 @@
+/**
+ * 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.event.awt;
+
+public class AWTMouseAdapter extends AWTAdapter implements java.awt.event.MouseListener, java.awt.event.MouseMotionListener
+{
+ public AWTMouseAdapter(com.jogamp.newt.event.MouseListener newtListener) {
+ super(newtListener);
+ }
+
+ public AWTMouseAdapter(com.jogamp.newt.event.MouseListener newtListener, com.jogamp.newt.Window newtProxy) {
+ super(newtListener, newtProxy);
+ }
+
+ public AWTMouseAdapter(com.jogamp.newt.Window downstream) {
+ super(downstream);
+ }
+
+ public AWTAdapter addTo(java.awt.Component awtComponent) {
+ awtComponent.addMouseListener(this);
+ awtComponent.addMouseMotionListener(this);
+ return this;
+ }
+
+ public AWTAdapter removeFrom(java.awt.Component awtComponent) {
+ awtComponent.removeMouseListener(this);
+ awtComponent.removeMouseMotionListener(this);
+ return this;
+ }
+
+ public void mouseClicked(java.awt.event.MouseEvent e) {
+ com.jogamp.newt.event.MouseEvent event = AWTNewtEventFactory.createMouseEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.MouseListener)newtListener).mouseClicked(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void mouseEntered(java.awt.event.MouseEvent e) {
+ com.jogamp.newt.event.MouseEvent event = AWTNewtEventFactory.createMouseEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.MouseListener)newtListener).mouseEntered(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void mouseExited(java.awt.event.MouseEvent e) {
+ com.jogamp.newt.event.MouseEvent event = AWTNewtEventFactory.createMouseEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.MouseListener)newtListener).mouseExited(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void mousePressed(java.awt.event.MouseEvent e) {
+ com.jogamp.newt.event.MouseEvent event = AWTNewtEventFactory.createMouseEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.MouseListener)newtListener).mousePressed(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void mouseReleased(java.awt.event.MouseEvent e) {
+ com.jogamp.newt.event.MouseEvent event = AWTNewtEventFactory.createMouseEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.MouseListener)newtListener).mouseReleased(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void mouseDragged(java.awt.event.MouseEvent e) {
+ com.jogamp.newt.event.MouseEvent event = AWTNewtEventFactory.createMouseEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.MouseListener)newtListener).mouseDragged(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void mouseMoved(java.awt.event.MouseEvent e) {
+ com.jogamp.newt.event.MouseEvent event = AWTNewtEventFactory.createMouseEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.MouseListener)newtListener).mouseMoved(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java
new file mode 100644
index 000000000..8e33285bf
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTNewtEventFactory.java
@@ -0,0 +1,146 @@
+/**
+ * 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.event.awt;
+
+import com.jogamp.common.util.IntIntHashMap;
+
+class AWTNewtEventFactory {
+
+ protected static final IntIntHashMap eventTypeAWT2NEWT;
+
+ static {
+ IntIntHashMap map = new IntIntHashMap();
+ map.setKeyNotFoundValue(-1);
+ // n/a map.put(java.awt.event.WindowEvent.WINDOW_OPENED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_OPENED);
+ map.put(java.awt.event.WindowEvent.WINDOW_CLOSING, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
+ // n/a map.put(java.awt.event.WindowEvent.WINDOW_CLOSED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_CLOSED);
+ // n/a map.put(java.awt.event.WindowEvent.WINDOW_ICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_ICONIFIED);
+ // n/a map.put(java.awt.event.WindowEvent.WINDOW_DEICONIFIED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_DEICONIFIED);
+ map.put(java.awt.event.WindowEvent.WINDOW_ACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ map.put(java.awt.event.WindowEvent.WINDOW_GAINED_FOCUS, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ map.put(java.awt.event.FocusEvent.FOCUS_GAINED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ map.put(java.awt.event.WindowEvent.WINDOW_DEACTIVATED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS);
+ map.put(java.awt.event.WindowEvent.WINDOW_LOST_FOCUS, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS);
+ map.put(java.awt.event.FocusEvent.FOCUS_LOST, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_LOST_FOCUS);
+ // n/a map.put(java.awt.event.WindowEvent.WINDOW_STATE_CHANGED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_STATE_CHANGED);
+
+ map.put(java.awt.event.ComponentEvent.COMPONENT_MOVED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_MOVED);
+ map.put(java.awt.event.ComponentEvent.COMPONENT_RESIZED, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_RESIZED);
+ // n/a map.put(java.awt.event.ComponentEvent.COMPONENT_SHOWN, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_SHOWN);
+ // n/a map.put(java.awt.event.ComponentEvent.COMPONENT_HIDDEN, com.jogamp.newt.event.WindowEvent.EVENT_WINDOW_HIDDEN);
+
+ map.put(java.awt.event.MouseEvent.MOUSE_CLICKED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_CLICKED);
+ map.put(java.awt.event.MouseEvent.MOUSE_PRESSED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_PRESSED);
+ map.put(java.awt.event.MouseEvent.MOUSE_RELEASED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_RELEASED);
+ map.put(java.awt.event.MouseEvent.MOUSE_MOVED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_MOVED);
+ map.put(java.awt.event.MouseEvent.MOUSE_ENTERED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_ENTERED);
+ map.put(java.awt.event.MouseEvent.MOUSE_EXITED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_EXITED);
+ map.put(java.awt.event.MouseEvent.MOUSE_DRAGGED, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_DRAGGED);
+ map.put(java.awt.event.MouseEvent.MOUSE_WHEEL, com.jogamp.newt.event.MouseEvent.EVENT_MOUSE_WHEEL_MOVED);
+
+ map.put(java.awt.event.KeyEvent.KEY_PRESSED, com.jogamp.newt.event.KeyEvent.EVENT_KEY_PRESSED);
+ map.put(java.awt.event.KeyEvent.KEY_RELEASED, com.jogamp.newt.event.KeyEvent.EVENT_KEY_RELEASED);
+ map.put(java.awt.event.KeyEvent.KEY_TYPED, com.jogamp.newt.event.KeyEvent.EVENT_KEY_TYPED);
+
+ eventTypeAWT2NEWT = map;
+ }
+
+ public static final int awtModifiers2Newt(int awtMods, boolean mouseHint) {
+ int newtMods = 0;
+ if ((awtMods & java.awt.event.InputEvent.SHIFT_MASK) != 0) newtMods |= com.jogamp.newt.event.InputEvent.SHIFT_MASK;
+ if ((awtMods & java.awt.event.InputEvent.CTRL_MASK) != 0) newtMods |= com.jogamp.newt.event.InputEvent.CTRL_MASK;
+ if ((awtMods & java.awt.event.InputEvent.META_MASK) != 0) newtMods |= com.jogamp.newt.event.InputEvent.META_MASK;
+ if ((awtMods & java.awt.event.InputEvent.ALT_MASK) != 0) newtMods |= com.jogamp.newt.event.InputEvent.ALT_MASK;
+ if ((awtMods & java.awt.event.InputEvent.ALT_GRAPH_MASK) != 0) newtMods |= com.jogamp.newt.event.InputEvent.ALT_GRAPH_MASK;
+ return newtMods;
+ }
+
+ public static final int awtButton2Newt(int awtButton) {
+ switch (awtButton) {
+ case java.awt.event.MouseEvent.BUTTON1: return com.jogamp.newt.event.MouseEvent.BUTTON1;
+ case java.awt.event.MouseEvent.BUTTON2: return com.jogamp.newt.event.MouseEvent.BUTTON2;
+ case java.awt.event.MouseEvent.BUTTON3: return com.jogamp.newt.event.MouseEvent.BUTTON3;
+ }
+ return 0;
+ }
+
+ static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.WindowEvent event, com.jogamp.newt.Window newtSource) {
+ int type = eventTypeAWT2NEWT.get(event.getID());
+ if(-1 < type) {
+ return new com.jogamp.newt.event.WindowEvent(type, ((null==newtSource)?(Object)event.getComponent():(Object)newtSource), System.currentTimeMillis());
+ }
+ return null; // no mapping ..
+ }
+
+ static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.ComponentEvent event, com.jogamp.newt.Window newtSource) {
+ int type = eventTypeAWT2NEWT.get(event.getID());
+ if(-1 < type) {
+ return new com.jogamp.newt.event.WindowEvent(type, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, System.currentTimeMillis());
+ }
+ return null; // no mapping ..
+ }
+
+ static final com.jogamp.newt.event.WindowEvent createWindowEvent(java.awt.event.FocusEvent event, com.jogamp.newt.Window newtSource) {
+ int type = eventTypeAWT2NEWT.get(event.getID());
+ if(-1 < type) {
+ return new com.jogamp.newt.event.WindowEvent(type, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, System.currentTimeMillis());
+ }
+ return null; // no mapping ..
+ }
+
+ static final com.jogamp.newt.event.MouseEvent createMouseEvent(java.awt.event.MouseEvent event, com.jogamp.newt.Window newtSource) {
+ int type = eventTypeAWT2NEWT.get(event.getID());
+ if(-1 < type) {
+ int rotation = 0;
+ if (event instanceof java.awt.event.MouseWheelEvent) {
+ rotation = ((java.awt.event.MouseWheelEvent)event).getWheelRotation();
+ }
+
+ return new com.jogamp.newt.event.MouseEvent(
+ type, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, event.getWhen(),
+ awtModifiers2Newt(event.getModifiers(), true),
+ event.getX(), event.getY(), event.getClickCount(),
+ awtButton2Newt(event.getButton()), rotation);
+ }
+ return null; // no mapping ..
+ }
+
+ static final com.jogamp.newt.event.KeyEvent createKeyEvent(java.awt.event.KeyEvent event, com.jogamp.newt.Window newtSource) {
+ int type = eventTypeAWT2NEWT.get(event.getID());
+ if(-1 < type) {
+ return new com.jogamp.newt.event.KeyEvent(
+ type, (null==newtSource)?(Object)event.getComponent():(Object)newtSource, event.getWhen(),
+ awtModifiers2Newt(event.getModifiers(), false),
+ event.getKeyCode(), event.getKeyChar());
+ }
+ return null; // no mapping ..
+ }
+
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java
new file mode 100644
index 000000000..68f2b3e0f
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java
@@ -0,0 +1,130 @@
+/**
+ * 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.event.awt;
+
+/**
+ * Specialized parent/client adapter,
+ * where the NEWT child window really gets resized,
+ * and the parent move window event gets discarded. */
+public class AWTParentWindowAdapter
+ extends AWTWindowAdapter
+ implements java.awt.event.HierarchyListener
+{
+ public AWTParentWindowAdapter(com.jogamp.newt.Window downstream) {
+ super(downstream);
+ }
+
+ public AWTAdapter addTo(java.awt.Component awtComponent) {
+ awtComponent.addHierarchyListener(this);
+ return super.addTo(awtComponent);
+ }
+
+ public AWTAdapter removeFrom(java.awt.Component awtComponent) {
+ awtComponent.removeHierarchyListener(this);
+ return super.removeFrom(awtComponent);
+ }
+
+ public void focusGained(java.awt.event.FocusEvent e) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: focusGained: "+ e);
+ }
+ }
+
+ public void focusLost(java.awt.event.FocusEvent e) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: focusLost: "+ e);
+ }
+ }
+
+ public void componentResized(java.awt.event.ComponentEvent e) {
+ // Need to resize the NEWT child window
+ // the resized event will be send via the native window feedback.
+ final java.awt.Component comp = e.getComponent();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentResized: "+comp);
+ }
+ if(newtWindow.isValid()) {
+ newtWindow.runOnEDTIfAvail(false, new Runnable() {
+ public void run() {
+ int cw = comp.getWidth();
+ int ch = comp.getHeight();
+ if( 0 < cw * ch ) {
+ if( newtWindow.getWidth() != cw || newtWindow.getHeight() != ch ) {
+ newtWindow.setSize(cw, ch);
+ if(comp.isVisible() != newtWindow.isVisible()) {
+ newtWindow.setVisible(comp.isVisible());
+ }
+ }
+ } else if(newtWindow.isVisible()) {
+ newtWindow.setVisible(false);
+ }
+ }});
+ }
+ }
+
+ public void componentMoved(java.awt.event.ComponentEvent e) {
+ // no propagation to NEWT child window
+ }
+
+ public void windowActivated(java.awt.event.WindowEvent e) {
+ // no propagation to NEWT child window
+ }
+
+ public void windowDeactivated(java.awt.event.WindowEvent e) {
+ // no propagation to NEWT child window
+ }
+
+ public void hierarchyChanged(java.awt.event.HierarchyEvent e) {
+ if( null == newtListener ) {
+ long bits = e.getChangeFlags();
+ final java.awt.Component changed = e.getChanged();
+ if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) {
+ final boolean showing = changed.isShowing();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed);
+ }
+ if(newtWindow.isValid()) {
+ newtWindow.runOnEDTIfAvail(false, new Runnable() {
+ public void run() {
+ if(newtWindow.isVisible() != showing) {
+ newtWindow.setVisible(showing);
+ }
+ }});
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) {
+ final boolean displayability = changed.isDisplayable();
+ System.err.println("AWT: hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed);
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
new file mode 100644
index 000000000..85fe5407b
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
@@ -0,0 +1,204 @@
+/**
+ * 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.event.awt;
+
+public class AWTWindowAdapter
+ extends AWTAdapter
+ implements java.awt.event.ComponentListener, java.awt.event.WindowListener, java.awt.event.FocusListener
+{
+ WindowClosingListener windowClosingListener;
+
+ public AWTWindowAdapter(com.jogamp.newt.event.WindowListener newtListener) {
+ super(newtListener);
+ }
+
+ public AWTWindowAdapter(com.jogamp.newt.event.WindowListener newtListener, com.jogamp.newt.Window newtProxy) {
+ super(newtListener, newtProxy);
+ }
+
+ public AWTWindowAdapter(com.jogamp.newt.Window downstream) {
+ super(downstream);
+ }
+
+ public AWTAdapter addTo(java.awt.Component awtComponent) {
+ java.awt.Window win = getWindow(awtComponent);
+ awtComponent.addComponentListener(this);
+ awtComponent.addFocusListener(this);
+ if( null == windowClosingListener ) {
+ windowClosingListener = new WindowClosingListener();
+ }
+ if( null != win ) {
+ win.addWindowListener(windowClosingListener);
+ }
+ if(awtComponent instanceof java.awt.Window) {
+ ((java.awt.Window)awtComponent).addWindowListener(this);
+ }
+ return this;
+ }
+
+ public AWTAdapter removeFrom(java.awt.Component awtComponent) {
+ awtComponent.removeFocusListener(this);
+ awtComponent.removeComponentListener(this);
+ java.awt.Window win = getWindow(awtComponent);
+ if( null != win && null != windowClosingListener ) {
+ win.removeWindowListener(windowClosingListener);
+ }
+ if(awtComponent instanceof java.awt.Window) {
+ ((java.awt.Window)awtComponent).removeWindowListener(this);
+ }
+ return this;
+ }
+
+ static java.awt.Window getWindow(java.awt.Component comp) {
+ while( null != comp && !(comp instanceof java.awt.Window) ) {
+ comp = comp.getParent();
+ }
+ if(comp instanceof java.awt.Window) {
+ return (java.awt.Window) comp;
+ }
+ return null;
+ }
+
+ public void focusGained(java.awt.event.FocusEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowGainedFocus(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void focusLost(java.awt.event.FocusEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowLostFocus(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void componentResized(java.awt.event.ComponentEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowResized(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void componentMoved(java.awt.event.ComponentEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowMoved(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void componentShown(java.awt.event.ComponentEvent e) {
+ final java.awt.Component comp = e.getComponent();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentShown: "+comp);
+ }
+ /**
+ if(null==newtListener) {
+ if(newtWindow.isValid()) {
+ newtWindow.runOnEDTIfAvail(false, new Runnable() {
+ public void run() {
+ newtWindow.setVisible(true);
+ }
+ });
+ }
+ }*/
+ }
+
+ public void componentHidden(java.awt.event.ComponentEvent e) {
+ final java.awt.Component comp = e.getComponent();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentHidden: "+comp);
+ }
+ /**
+ if(null==newtListener) {
+ if(newtWindow.isValid()) {
+ newtWindow.runOnEDTIfAvail(false, new Runnable() {
+ public void run() {
+ newtWindow.setVisible(false);
+ }
+ });
+ }
+ }*/
+ }
+
+ public void windowActivated(java.awt.event.WindowEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowGainedFocus(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void windowClosed(java.awt.event.WindowEvent e) { }
+
+ public void windowClosing(java.awt.event.WindowEvent e) { }
+
+ public void windowDeactivated(java.awt.event.WindowEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowLostFocus(event);
+ } else {
+ enqueueEvent(false, event);
+ }
+ }
+
+ public void windowDeiconified(java.awt.event.WindowEvent e) { }
+
+ public void windowIconified(java.awt.event.WindowEvent e) { }
+
+ public void windowOpened(java.awt.event.WindowEvent e) { }
+
+ class WindowClosingListener implements java.awt.event.WindowListener {
+ public void windowClosing(java.awt.event.WindowEvent e) {
+ com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(null!=newtListener) {
+ ((com.jogamp.newt.event.WindowListener)newtListener).windowDestroyNotify(event);
+ } else {
+ enqueueEvent(true, event);
+ }
+ }
+
+ public void windowActivated(java.awt.event.WindowEvent e) { }
+ public void windowClosed(java.awt.event.WindowEvent e) { }
+ public void windowDeactivated(java.awt.event.WindowEvent e) { }
+ public void windowDeiconified(java.awt.event.WindowEvent e) { }
+ public void windowIconified(java.awt.event.WindowEvent e) { }
+ public void windowOpened(java.awt.event.WindowEvent e) { }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/Debug.java b/src/newt/classes/com/jogamp/newt/impl/Debug.java
new file mode 100644
index 000000000..62c261d2e
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/Debug.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.newt.impl;
+
+import java.security.*;
+
+/** Helper routines for logging and debugging. */
+
+public class Debug {
+ // Some common properties
+ private static boolean verbose;
+ private static boolean debugAll;
+ private static AccessControlContext localACC;
+
+ static {
+ localACC=AccessController.getContext();
+ verbose = isPropertyDefined("newt.verbose", true);
+ debugAll = isPropertyDefined("newt.debug", true);
+ if (verbose) {
+ Package p = Package.getPackage("com.jogamp.newt");
+ System.err.println("NEWT specification version " + p.getSpecificationVersion());
+ System.err.println("NEWT implementation version " + p.getImplementationVersion());
+ System.err.println("NEWT implementation vendor " + p.getImplementationVendor());
+ }
+ }
+
+ static int getIntProperty(final String property, final boolean jnlpAlias) {
+ return getIntProperty(property, jnlpAlias, localACC);
+ }
+
+ public static int getIntProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ int i=0;
+ try {
+ Integer iv = Integer.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ i = iv.intValue();
+ } catch (NumberFormatException nfe) {}
+ return i;
+ }
+
+ static boolean getBooleanProperty(final String property, final boolean jnlpAlias) {
+ return getBooleanProperty(property, jnlpAlias, localACC);
+ }
+
+ public static boolean getBooleanProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ Boolean b = Boolean.valueOf(Debug.getProperty(property, jnlpAlias, acc));
+ return b.booleanValue();
+ }
+
+ static boolean isPropertyDefined(final String property, final boolean jnlpAlias) {
+ return isPropertyDefined(property, jnlpAlias, localACC);
+ }
+
+ public static boolean isPropertyDefined(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ return (Debug.getProperty(property, jnlpAlias, acc) != null) ? true : false;
+ }
+
+ static String getProperty(final String property, final boolean jnlpAlias) {
+ return getProperty(property, jnlpAlias, localACC);
+ }
+
+ public static String getProperty(final String property, final boolean jnlpAlias, final AccessControlContext acc) {
+ String s=null;
+ if(null!=acc && acc.equals(localACC)) {
+ s = (String) AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String val=null;
+ try {
+ val = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==val && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ val = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ return val;
+ }
+ });
+ } else {
+ try {
+ s = System.getProperty(property);
+ } catch (Exception e) {}
+ if(null==s && jnlpAlias && !property.startsWith(jnlp_prefix)) {
+ try {
+ s = System.getProperty(jnlp_prefix + property);
+ } catch (Exception e) {}
+ }
+ }
+ return s;
+ }
+ public static final String jnlp_prefix = "jnlp." ;
+
+ public static boolean verbose() {
+ return verbose;
+ }
+
+ public static boolean debugAll() {
+ return debugAll;
+ }
+
+ public static boolean debug(String subcomponent) {
+ return debugAll() || isPropertyDefined("newt.debug." + subcomponent, true);
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java b/src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java
new file mode 100644
index 000000000..d7a22b92c
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/DefaultEDTUtil.java
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.common.util.RunnableTask;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.util.EDTUtil;
+import java.util.*;
+
+public class DefaultEDTUtil implements EDTUtil {
+ public static final boolean DEBUG = Debug.debug("EDT");
+
+ private ThreadGroup threadGroup;
+ private EventDispatchThread edt = null;
+ private Object edtLock = new Object(); // locking the EDT start/stop state
+ private String name;
+ int start_iter=0;
+ private Runnable dispatchMessages;
+
+ public DefaultEDTUtil(ThreadGroup tg, String name, Runnable dispatchMessages) {
+ this.threadGroup = tg;
+ this.name=new String(Thread.currentThread().getName()+"-"+name+"-EDT-");
+ this.dispatchMessages=dispatchMessages;
+ this.edt = new EventDispatchThread(threadGroup, name);
+ }
+
+ public final void reset() {
+ synchronized(edtLock) {
+ waitUntilStopped();
+ if(DEBUG) {
+ if(edt.tasks.size()>0) {
+ String msg = Thread.currentThread()+": EDT reset, remaining tasks: "+edt.tasks.size()+" - "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ }
+ System.err.println(Thread.currentThread()+": EDT reset - edt: "+edt);
+ }
+ this.edt = new EventDispatchThread(threadGroup, name);
+ }
+ }
+
+ public final void start() {
+ synchronized(edtLock) {
+ if(!edt.isRunning() && !edt.shouldStop) {
+ if(edt.isAlive()) {
+ throw new RuntimeException("EDT Thread.isAlive(): true, isRunning: "+edt.isRunning()+", edt: "+edt+", tasks: "+edt.tasks.size());
+ }
+ start_iter++;
+ edt.setName(name+start_iter);
+ edt.shouldStop = false;
+ if(DEBUG) {
+ String msg = Thread.currentThread()+": EDT START - edt: "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ }
+ edt.start();
+ }
+ }
+ }
+
+ public final boolean isCurrentThreadEDT() {
+ return edt == Thread.currentThread();
+ }
+
+ public final boolean isRunning() {
+ return edt.isRunning() ;
+ }
+
+ public final void invokeStop(Runnable task) {
+ invokeImpl(true, task, true);
+ }
+
+ public final void invoke(boolean wait, Runnable task) {
+ invokeImpl(wait, task, false);
+ }
+
+ private final void invokeImpl(boolean wait, Runnable task, boolean stop) {
+ if(task == null) {
+ throw new RuntimeException("Null Runnable");
+ }
+ Throwable throwable = null;
+ RunnableTask rTask = null;
+ Object rTaskLock = new Object();
+ synchronized(rTaskLock) { // lock the optional task execution
+ synchronized(edtLock) { // lock the EDT status
+ if( edt.shouldStop ) {
+ // drop task ..
+ if(DEBUG) {
+ Throwable t = new Throwable("Warning: EDT about (1) to stop, won't enqueue new task: "+edt);
+ t.printStackTrace();
+ }
+ return;
+ }
+ // Exception ee = new Exception("XXX stop: "+stop+", tasks: "+edt.tasks.size()+", task: "+task);
+ // ee.printStackTrace();
+ if(stop) {
+ edt.shouldStop = true;
+ if(DEBUG) {
+ String msg = Thread.currentThread()+": EDT signal STOP (on edt: "+isCurrentThreadEDT()+") - edt: "+edt;
+ System.err.println(msg);
+ // Throwable t = new Throwable(msg);
+ // t.printStackTrace();
+ }
+ }
+ if( isCurrentThreadEDT() ) {
+ task.run();
+ wait = false; // running in same thread (EDT) -> no wait
+ if(stop && edt.tasks.size()>0) {
+ String msg = "Warning: EDT about (2) to stop, having remaining tasks: "+edt.tasks.size()+" - "+edt;
+ if(DEBUG) {
+ Throwable t = new Throwable(msg);
+ t.printStackTrace();
+ } else {
+ System.err.println(msg);
+ }
+ }
+ } else {
+ synchronized(edt.tasks) {
+ start(); // start if not started yet and !shouldStop
+ wait = wait && edt.isRunning();
+ rTask = new RunnableTask(task,
+ wait ? rTaskLock : null,
+ true /* always catch and report Exceptions, don't disturb EDT */);
+ if(stop) {
+ rTask.setAttachment(new Boolean(true)); // mark final task
+ }
+ // append task ..
+ edt.tasks.add(rTask);
+ edt.tasks.notifyAll();
+ }
+ }
+ }
+ if( wait ) {
+ try {
+ rTaskLock.wait(); // free lock, allow execution of rTask
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+ }
+ if(DEBUG && stop) {
+ System.err.println(Thread.currentThread()+": EDT signal STOP X edt: "+edt);
+ }
+ }
+
+ public void waitUntilIdle() {
+ if(edt.isRunning() && edt != Thread.currentThread()) {
+ synchronized(edt.tasks) {
+ while(edt.isRunning() && edt.tasks.size()>0) {
+ try {
+ edt.tasks.notifyAll();
+ edt.tasks.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ public void waitUntilStopped() {
+ if(edt.isRunning() && edt != Thread.currentThread() ) {
+ synchronized(edtLock) {
+ if(edt.isRunning() && edt != Thread.currentThread() ) {
+ while(edt.isRunning()) {
+ try {
+ edtLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ class EventDispatchThread extends Thread {
+ volatile boolean shouldStop = false;
+ volatile boolean isRunning = false;
+ ArrayList tasks = new ArrayList(); // one shot tasks
+
+ public EventDispatchThread(ThreadGroup tg, String name) {
+ super(tg, name);
+ }
+
+ public final boolean isRunning() {
+ return isRunning;
+ }
+
+ public void start() throws IllegalThreadStateException {
+ isRunning = true;
+ super.start();
+ }
+
+ /**
+ * Utilizing locking only on tasks and its execution,
+ * not for event dispatching.
+ */
+ public void run() {
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() START "+ getName());
+ }
+ RuntimeException error = null;
+ try {
+ do {
+ // event dispatch
+ if(!shouldStop) {
+ dispatchMessages.run();
+ }
+ // wait and work on tasks
+ RunnableTask task = null;
+ synchronized(tasks) {
+ // wait for tasks
+ if(!shouldStop && tasks.size()==0) {
+ try {
+ tasks.wait(defaultEDTPollGranularity);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ // execute one task, if available
+ if(tasks.size()>0) {
+ task = (RunnableTask) tasks.remove(0);
+ tasks.notifyAll();
+ }
+ }
+ if(null!=task) {
+ // Exceptions are always catched, see RunnableTask creation above
+ task.run();
+ }
+ } while(!shouldStop) ;
+ } catch (Throwable t) {
+ // handle errors ..
+ shouldStop = true;
+ if(t instanceof RuntimeException) {
+ error = (RuntimeException) t;
+ } else {
+ error = new RuntimeException("Within EDT", t);
+ }
+ } finally {
+ if(DEBUG) {
+ RunnableTask rt = ( tasks.size() > 0 ) ? (RunnableTask) tasks.get(0) : null ;
+ System.err.println(getName()+": EDT run() END "+ getName()+", tasks: "+tasks.size()+", "+rt+", "+error);
+ }
+ synchronized(edtLock) {
+ if(null==error) {
+ synchronized(tasks) {
+ // drain remaining tasks (stop not on EDT),
+ // while having tasks and no previous-task, or previous-task is non final
+ RunnableTask task = null;
+ while ( ( null == task || task.getAttachment() == null ) && tasks.size() > 0 ) {
+ task = ( RunnableTask ) tasks.remove(0);
+ task.run();
+ tasks.notifyAll();
+ }
+ if(DEBUG) {
+ if(null!=task && task.getAttachment()==null) {
+ Throwable t = new Throwable("Warning: EDT exit: Last task Not Final: "+tasks.size()+", "+task+" - "+edt);
+ t.printStackTrace();
+ } else if(tasks.size()>0) {
+ Throwable t = new Throwable("Warning: EDT exit: Remaining tasks Post Final: "+tasks.size());
+ t.printStackTrace();
+ }
+ }
+ }
+ }
+ isRunning = !shouldStop;
+ if(!isRunning) {
+ edtLock.notifyAll();
+ }
+ }
+ if(DEBUG) {
+ System.err.println(getName()+": EDT run() EXIT "+ getName()+", "+error);
+ }
+ if(null!=error) {
+ throw error;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java
new file mode 100644
index 000000000..d22e9c7c4
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/DisplayImpl.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.event.NEWTEvent;
+import com.jogamp.newt.event.NEWTEventConsumer;
+import com.jogamp.newt.impl.event.NEWTEventTask;
+import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.newt.util.MainThread;
+import java.util.ArrayList;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowFactory;
+
+public abstract class DisplayImpl extends Display {
+ public static final boolean DEBUG_TEST_EDT_MAINTHREAD = Debug.isPropertyDefined("newt.test.EDTMainThread", true); // JAU EDT Test ..
+
+ private static int serialno = 1;
+
+ private static Class getDisplayClass(String type)
+ throws ClassNotFoundException
+ {
+ Class displayClass = NewtFactory.getCustomClass(type, "Display");
+ if(null==displayClass) {
+ if (NativeWindowFactory.TYPE_EGL.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDDisplay");
+ } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.windows.WindowsDisplay");
+ } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.macosx.MacDisplay");
+ } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.x11.X11Display");
+ } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
+ displayClass = Class.forName("com.jogamp.newt.impl.awt.AWTDisplay");
+ } else {
+ throw new RuntimeException("Unknown display type \"" + type + "\"");
+ }
+ }
+ return displayClass;
+ }
+
+ /** Make sure to reuse a Display with the same name */
+ public static Display create(String type, String name, final long handle, boolean reuse) {
+ try {
+ Class displayClass = getDisplayClass(type);
+ DisplayImpl display = (DisplayImpl) displayClass.newInstance();
+ name = display.validateDisplayName(name, handle);
+ synchronized(displayList) {
+ if(reuse) {
+ Display display0 = Display.getLastDisplayOf(type, name, -1);
+ if(null != display0) {
+ if(DEBUG) {
+ System.err.println("Display.create() REUSE: "+display0+" "+getThreadName());
+ }
+ return display0;
+ }
+ }
+ display.name = name;
+ display.type=type;
+ display.destroyWhenUnused=false;
+ display.refCount=0;
+ display.id = serialno++;
+ display.fqname = getFQName(display.type, display.name, display.id);
+ display.hashCode = display.fqname.hashCode();
+ displayList.add(display);
+ }
+ display.createEDTUtil();
+ if(DEBUG) {
+ System.err.println("Display.create() NEW: "+display+" "+getThreadName());
+ }
+ return display;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ 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(DEBUG) {
+ dumpDisplayList("Display.destroy("+getFQName()+") BEGIN");
+ }
+ synchronized(displayList) {
+ displayList.remove(this);
+ displaysActive--;
+ }
+ if(DEBUG) {
+ System.err.println("Display.destroy(): "+this+" "+getThreadName());
+ }
+ final AbstractGraphicsDevice f_aDevice = aDevice;
+ final DisplayImpl f_dpy = this;
+ stopEDT( new Runnable() {
+ public void run() {
+ if ( null != f_aDevice ) {
+ f_dpy.closeNativeImpl();
+ }
+ }
+ } );
+ if(null!=edtUtil) {
+ if ( DEBUG_TEST_EDT_MAINTHREAD ) {
+ MainThread.removePumpMessage(this); // JAU EDT Test ..
+ }
+ edtUtil.waitUntilStopped();
+ edtUtil.reset();
+ }
+ aDevice = null;
+ refCount=0;
+ if(DEBUG) {
+ dumpDisplayList("Display.destroy("+getFQName()+") END");
+ }
+ }
+
+ public synchronized final int addReference() {
+ if(DEBUG) {
+ System.err.println("Display.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ }
+ if ( 0 == refCount ) {
+ createNative();
+ }
+ if(null == aDevice) {
+ throw new RuntimeException("Display.addReference() (refCount "+refCount+") null AbstractGraphicsDevice");
+ }
+ return ++refCount;
+ }
+
+
+ public synchronized final int removeReference() {
+ if(DEBUG) {
+ System.err.println("Display.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ }
+ refCount--; // could become < 0, in case of forced destruction without actual creation/addReference
+ if(0>=refCount && getDestroyWhenUnused()) {
+ 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 ;
+ }
+
+ protected static final String getFQName(String type, String name, int id) {
+ if(null==type) type=nilString;
+ if(null==name) name=nilString;
+ StringBuffer sb = new StringBuffer();
+ sb.append(type);
+ sb.append("_");
+ sb.append(name);
+ sb.append("-");
+ sb.append(id);
+ return sb.toString();
+ }
+
+ public final long getHandle() {
+ if(null!=aDevice) {
+ return aDevice.getHandle();
+ }
+ return 0;
+ }
+
+ public final AbstractGraphicsDevice getGraphicsDevice() {
+ return aDevice;
+ }
+
+ public final boolean isNativeValid() {
+ return null != aDevice;
+ }
+
+ public boolean isEDTRunning() {
+ if(null!=edtUtil) {
+ return edtUtil.isRunning();
+ }
+ return false;
+ }
+
+ public String toString() {
+ return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", edtRunning "+isEDTRunning()+", "+aDevice+"]";
+ }
+
+ protected abstract void dispatchMessagesNative();
+
+ private Object eventsLock = new Object();
+ private ArrayList/*<NEWTEvent>*/ events = new ArrayList();
+
+ class DispatchMessagesRunnable implements Runnable {
+ public void run() {
+ DisplayImpl.this.dispatchMessages();
+ }
+ }
+ DispatchMessagesRunnable dispatchMessagesRunnable = new DispatchMessagesRunnable();
+
+ public void dispatchMessages() {
+ // System.err.println("Display.dispatchMessages() 0 "+this+" "+getThreadName());
+ if(0==refCount) return; // no screens
+ if(null==getGraphicsDevice()) return; // no native device
+
+ ArrayList/*<NEWTEvent>*/ _events = null;
+
+ if(events.size()>0) {
+ // swap events list to free ASAP
+ synchronized(eventsLock) {
+ if(events.size()>0) {
+ _events = events;
+ events = new ArrayList();
+ }
+ eventsLock.notifyAll();
+ }
+ if( null != _events ) {
+ for (int i=0; i < _events.size(); i++) {
+ NEWTEventTask eventTask = (NEWTEventTask) _events.get(i);
+ NEWTEvent event = eventTask.get();
+ Object source = event.getSource();
+ if(source instanceof NEWTEventConsumer) {
+ NEWTEventConsumer consumer = (NEWTEventConsumer) source ;
+ if(!consumer.consumeEvent(event)) {
+ enqueueEvent(false, event);
+ }
+ } else {
+ throw new RuntimeException("Event source not NEWT: "+source.getClass().getName()+", "+source);
+ }
+ eventTask.notifyIssuer();
+ }
+ }
+ }
+
+ // System.err.println("Display.dispatchMessages() NATIVE "+this+" "+getThreadName());
+ dispatchMessagesNative();
+ }
+
+ public void enqueueEvent(boolean wait, NEWTEvent e) {
+ if(!isEDTRunning()) {
+ // oops .. we are already dead
+ if(DEBUG) {
+ Throwable t = new Throwable("Warning: EDT already stopped: wait:="+wait+", "+e);
+ t.printStackTrace();
+ }
+ return;
+ }
+ Object lock = new Object();
+ NEWTEventTask eTask = new NEWTEventTask(e, wait?lock:null);
+ synchronized(lock) {
+ synchronized(eventsLock) {
+ events.add(eTask);
+ eventsLock.notifyAll();
+ }
+ if( wait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throw new RuntimeException(ie);
+ }
+ }
+ }
+ }
+
+ protected EDTUtil edtUtil = null;
+ protected int id;
+ protected String name;
+ protected String type;
+ protected String fqname;
+ protected int hashCode;
+ protected int refCount; // number of Display references by Screen
+ protected boolean destroyWhenUnused;
+ protected AbstractGraphicsDevice aDevice;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/NEWTJNILibLoader.java b/src/newt/classes/com/jogamp/newt/impl/NEWTJNILibLoader.java
new file mode 100644
index 000000000..a4d234fd5
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/NEWTJNILibLoader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+package com.jogamp.newt.impl;
+
+// FIXME: refactor Java SE dependencies
+//import java.awt.Toolkit;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.HashSet;
+import com.jogamp.common.jvm.JNILibLoaderBase;
+
+public class NEWTJNILibLoader extends JNILibLoaderBase {
+
+ public static void loadNEWT() {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ loadLibrary("newt", null, true);
+ return null;
+ }
+ });
+ }
+
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java b/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java
new file mode 100644
index 000000000..f3c7b8415
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/OffscreenWindow.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Point;
+
+public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
+
+ long surfaceHandle = 0;
+
+ public OffscreenWindow() {
+ }
+
+ static long nextWindowHandle = 0x100; // start here - a marker
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new NativeWindowException("OffscreenWindow does not support window parenting");
+ }
+ if(caps.isOnscreen()) {
+ throw new NativeWindowException("Capabilities is onscreen");
+ }
+ 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) {
+ setWindowHandle(nextWindowHandle++);
+ }
+ }
+
+ protected void closeNativeImpl() {
+ // nop
+ }
+
+ public void invalidate(boolean unrecoverable) {
+ super.invalidate(unrecoverable);
+ surfaceHandle = 0;
+ }
+
+ public synchronized void destroy(boolean unrecoverable) {
+ super.destroy(unrecoverable);
+ surfaceHandle = 0;
+ }
+
+ public void setSurfaceHandle(long handle) {
+ surfaceHandle = handle ;
+ }
+
+ public long getSurfaceHandle() {
+ return surfaceHandle;
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ sizeChanged(width, height, false);
+ visibleChanged(visible);
+ }
+
+ protected void requestFocusImpl(boolean reparented) {
+ }
+
+ public void setSize(int width, int height) {
+ if(!visible) {
+ sizeChanged(width, height, false);
+ }
+ }
+ public void setPosition(int x, int y) {
+ // nop
+ }
+ public boolean setFullscreen(boolean fullscreen) {
+ // nop
+ return false;
+ }
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
+ shouldNotCallThis();
+ return false;
+ }
+
+ public Point getLocationOnScreen(Point storage) {
+ if(null!=storage) {
+ storage.setX(0);
+ storage.setY(0);
+ return storage;
+ }
+ return new Point(0,0);
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java
new file mode 100644
index 000000000..ebb496988
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/ScreenImpl.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.util.ScreenModeUtil;
+
+import javax.media.nativewindow.*;
+
+import java.security.*;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class ScreenImpl extends Screen implements ScreenModeListener {
+ protected static final boolean DisableScreenModeImpl = Debug.debug("Screen.DisableScreenModeImpl");
+ protected DisplayImpl display;
+ protected int screen_idx;
+ protected String fqname;
+ protected int hashCode;
+ protected AbstractGraphicsScreen aScreen;
+ protected int refCount; // number of Screen references by Window
+ protected int width=-1, height=-1; // detected values: set using setScreenSize
+ protected static int usrWidth=-1, usrHeight=-1; // property values: newt.ws.swidth and newt.ws.sheight
+ private static AccessControlContext localACC = AccessController.getContext();
+ private List/*<ScreenModeListener>*/ referencedScreenModeListener = new ArrayList();
+ long t0; // creationTime
+
+ private static Class getScreenClass(String type)
+ throws ClassNotFoundException
+ {
+ Class screenClass = NewtFactory.getCustomClass(type, "Screen");
+ if(null==screenClass) {
+ if (NativeWindowFactory.TYPE_EGL.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDScreen");
+ } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.windows.WindowsScreen");
+ } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.macosx.MacScreen");
+ } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.x11.X11Screen");
+ } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
+ screenClass = Class.forName("com.jogamp.newt.impl.awt.AWTScreen");
+ } else {
+ throw new RuntimeException("Unknown window type \"" + type + "\"");
+ }
+ }
+ return screenClass;
+ }
+
+ public static Screen create(Display display, final int idx) {
+ try {
+ if(usrWidth<0 || usrHeight<0) {
+ synchronized (Screen.class) {
+ if(usrWidth<0 || usrHeight<0) {
+ usrWidth = Debug.getIntProperty("newt.ws.swidth", true, localACC);
+ usrHeight = Debug.getIntProperty("newt.ws.sheight", true, localACC);
+ if(usrWidth>0 || usrHeight>0) {
+ System.err.println("User screen size "+usrWidth+"x"+usrHeight);
+ }
+ }
+ }
+ }
+ synchronized(screenList) {
+ {
+ Screen screen0 = ScreenImpl.getLastScreenOf(display, idx, -1);
+ if(null != screen0) {
+ if(DEBUG) {
+ System.err.println("Screen.create() REUSE: "+screen0+" "+Display.getThreadName());
+ }
+ return screen0;
+ }
+ }
+ Class screenClass = getScreenClass(display.getType());
+ ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
+ screen.display = (DisplayImpl) display;
+ screen.screen_idx = idx;
+ screen.fqname = display.getFQName()+idx;
+ screen.hashCode = screen.fqname.hashCode();
+ screenList.add(screen);
+ if(DEBUG) {
+ System.err.println("Screen.create() NEW: "+screen+" "+Display.getThreadName());
+ }
+ return screen;
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public int hashCode() {
+ return hashCode;
+ }
+
+ protected synchronized final void createNative() {
+ if(null == aScreen) {
+ if(DEBUG) {
+ System.err.println("Screen.createNative() START ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ t0 = System.currentTimeMillis();
+ display.addReference();
+ createNativeImpl();
+ if(null == aScreen) {
+ throw new RuntimeException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
+ }
+ if(DEBUG) {
+ System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")");
+ }
+ synchronized(screenList) {
+ screensActive++;
+ }
+ }
+ initScreenModeStatus();
+ }
+
+ public synchronized final void destroy() {
+ releaseScreenModeStatus();
+
+ synchronized(screenList) {
+ screenList.remove(this);
+ screensActive--;
+ }
+
+ if ( null != aScreen ) {
+ closeNativeImpl();
+ aScreen = null;
+ }
+ refCount = 0;
+ display.removeReference();
+ }
+
+ public 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;
+ }
+
+ public synchronized final int removeReference() {
+ if(DEBUG) {
+ System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ }
+ refCount--; // could become < 0, in case of forced destruction without actual creation/addReference
+ 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();
+
+ public final String getFQName() {
+ return fqname;
+ }
+
+ protected void setScreenSize(int w, int h) {
+ System.err.println("Detected screen size "+w+"x"+h);
+ width=w; height=h;
+ }
+
+ public final Display getDisplay() {
+ return display;
+ }
+
+ public final int getIndex() {
+ return screen_idx;
+ }
+
+ public final AbstractGraphicsScreen getGraphicsScreen() {
+ return aScreen;
+ }
+
+ public final boolean isNativeValid() {
+ return null != aScreen;
+ }
+
+ public final int getWidth() {
+ return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
+ }
+
+ public final int getHeight() {
+ return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
+ }
+
+ public String toString() {
+ return "NEWT-Screen["+getFQName()+", idx "+screen_idx+", refCount "+refCount+", "+getWidth()+"x"+getHeight()+", "+aScreen+", "+display+"]";
+ }
+
+ public final List/*<ScreenMode>*/ getScreenModes() {
+ ArrayHashSet screenModes = getScreenModesOrig();
+ if(null != screenModes && 0 < screenModes.size()) {
+ return screenModes.toArrayList();
+ }
+ return null;
+ }
+
+ public ScreenMode getOriginalScreenMode() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ return ( null != sms ) ? sms.getOriginalScreenMode() : null ;
+ }
+
+ public ScreenMode getCurrentScreenMode() {
+ ScreenMode smU = null;
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null != sms) {
+ ScreenMode sm0 = ( DisableScreenModeImpl ) ? null : getCurrentScreenModeImpl();
+ if(null == sm0) {
+ return null;
+ }
+ sms.lock();
+ try {
+ smU = (ScreenMode) sms.getScreenModes().get(sm0); // unify via value hash
+ if(null == smU) {
+ throw new RuntimeException(sm0+" could not be hashed from ScreenMode list");
+ }
+
+ // if mode has changed somehow, update it ..
+ if( sms.getCurrentScreenMode().hashCode() != smU.hashCode() ) {
+ sms.fireScreenModeChanged(smU, true);
+ }
+ } finally {
+ sms.unlock();
+ }
+ }
+ return smU;
+ }
+
+ public boolean setCurrentScreenMode(ScreenMode screenMode) {
+ ScreenMode smU = (ScreenMode) getScreenModesOrig().get(screenMode); // unify via value hash
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ sms.lock();
+ try {
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.0 "+screenMode);
+ }
+
+ sms.fireScreenModeChangeNotify(smU);
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.1 "+screenMode);
+ }
+
+ boolean success = setCurrentScreenModeImpl(smU);
+ if(success) {
+ setScreenSize(screenMode.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
+ screenMode.getMonitorMode().getSurfaceSize().getResolution().getHeight());
+ }
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.0 "+screenMode+", success: "+success);
+ }
+
+ sms.fireScreenModeChanged(smU, success);
+
+ if(DEBUG) {
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.X "+screenMode+", success: "+success);
+ }
+
+ return success;
+ } finally {
+ sms.unlock();
+ }
+ }
+ return false;
+ }
+
+ public void screenModeChangeNotify(ScreenMode sm) {
+ for(int i=0; i<referencedScreenModeListener.size(); i++) {
+ ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChangeNotify(sm);
+ }
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ for(int i=0; i<referencedScreenModeListener.size(); i++) {
+ ((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChanged(sm, success);
+ }
+ }
+
+ public synchronized final void addScreenModeListener(ScreenModeListener sml) {
+ referencedScreenModeListener.add(sml);
+ }
+
+ public synchronized final void removeScreenModeListener(ScreenModeListener sml) {
+ referencedScreenModeListener.remove(sml);
+ }
+
+ /** ScreenModeStatus bridge to native implementation */
+ protected final ArrayHashSet getScreenModesOrig() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ return sms.getScreenModes();
+ }
+ return null;
+ }
+
+ /** ScreenModeStatus bridge to native implementation */
+ protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
+ ScreenModeStatus sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null!=sms) {
+ return sms.getScreenModesIdx2NativeIdx();
+ }
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
+ * <br>
+ * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
+ * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
+ * <br>
+ * <b>Note</b>: Additional 1st element is native mode id.
+ */
+ protected int[] getScreenModeFirstImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ * Is called only to collect the ScreenModes, usually at startup setting up modes.<br>
+ * <br>
+ * <b>WARNING</b>: must be synchronized with {@link com.jogamp.newt.util.ScreenModeUtil#NUM_SCREEN_MODE_PROPERTIES},
+ * ie {@link com.jogamp.newt.util.ScreenModeUtil#streamIn(com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, com.jogamp.common.util.ArrayHashSet, int[], int)}<br>
+ * <br>
+ * <b>Note</b>: Additional 1st element is native mode id.
+ */
+ protected int[] getScreenModeNextImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ */
+ protected ScreenMode getCurrentScreenModeImpl() {
+ return null;
+ }
+
+ /**
+ * To be implemented by the native specification.<br>
+ * Is called within a thread safe environment.<br>
+ */
+ protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) {
+ return false;
+ }
+
+ private void initScreenModeStatus() {
+ ScreenModeStatus sms;
+ ScreenModeStatus.lockScreenModeStatus();
+ try {
+ sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null==sms) {
+ IntIntHashMap screenModesIdx2NativeIdx = new IntIntHashMap();
+
+ ArrayHashSet screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx);
+ sms = new ScreenModeStatus(screenModes, screenModesIdx2NativeIdx);
+ if(null!=screenModes && screenModes.size()>0) {
+ ScreenMode originalScreenMode = ( DisableScreenModeImpl ) ? null : getCurrentScreenModeImpl();
+ if(null != originalScreenMode) {
+ ScreenMode originalScreenMode0 = (ScreenMode) screenModes.get(originalScreenMode); // unify via value hash
+ if(null == originalScreenMode0) {
+ throw new RuntimeException(originalScreenMode+" could not be hashed from ScreenMode list");
+ }
+ sms.setOriginalScreenMode(originalScreenMode0);
+ }
+ }
+ ScreenModeStatus.mapScreenModeStatus(this.getFQName(), sms);
+ }
+ sms.addListener(this);
+ } finally {
+ ScreenModeStatus.unlockScreenModeStatus();
+ }
+ }
+
+ /** ignores bpp < 15 */
+ private ArrayHashSet collectNativeScreenModes(IntIntHashMap screenModesIdx2NativeId) {
+ ArrayHashSet resolutionPool = new ArrayHashSet();
+ ArrayHashSet surfaceSizePool = new ArrayHashSet();
+ ArrayHashSet screenSizeMMPool = new ArrayHashSet();
+ ArrayHashSet monitorModePool = new ArrayHashSet();
+ ArrayHashSet screenModePool = null;
+
+ screenModePool = new ArrayHashSet();
+
+ int[] smProps = null;
+ int num = 0;
+ final int idxBpp = 1 // native mode
+ + 1 // count
+ + ScreenModeUtil.NUM_RESOLUTION_PROPERTIES
+ + ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES
+ - 1 ; // index 0 based
+ do {
+ if(DisableScreenModeImpl) {
+ smProps = null;
+ } else if(0 == num) {
+ smProps = getScreenModeFirstImpl();
+ } else {
+ smProps = getScreenModeNextImpl();
+ }
+ if(null != smProps && 0 < smProps.length && smProps[idxBpp] >= 15) {
+ int nativeId = smProps[0];
+ int screenModeIdx = ScreenModeUtil.streamIn(resolutionPool, surfaceSizePool, screenSizeMMPool,
+ monitorModePool, screenModePool, smProps, 1);
+ if(screenModeIdx >= 0) {
+ screenModesIdx2NativeId.put(screenModeIdx, nativeId);
+ }
+ }
+ num++;
+ } while ( null != smProps && 0 < smProps.length );
+
+ if(DEBUG) {
+ System.err.println("ScreenImpl.collectNativeScreenModes: ScreenMode number : "+screenModePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: MonitorMode number : "+monitorModePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: ScreenSizeMM number: "+screenSizeMMPool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: SurfaceSize number : "+surfaceSizePool.size());
+ System.err.println("ScreenImpl.collectNativeScreenModes: Resolution number : "+resolutionPool.size());
+ }
+
+ return screenModePool;
+ }
+
+ private void releaseScreenModeStatus() {
+ ScreenModeStatus sms;
+ ScreenModeStatus.lockScreenModeStatus();
+ try {
+ sms = ScreenModeStatus.getScreenModeStatus(this.getFQName());
+ if(null != sms) {
+ sms.lock();
+ try {
+ if(0 == sms.removeListener(this)) {
+ if(!sms.isOriginalMode()) {
+ setCurrentScreenMode(sms.getOriginalScreenMode());
+ }
+ ScreenModeStatus.unmapScreenModeStatus(this.getFQName());
+ }
+ } finally {
+ sms.unlock();
+ }
+ }
+ } finally {
+ ScreenModeStatus.unlockScreenModeStatus();
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java b/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java
new file mode 100644
index 000000000..3ca9b638b
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/ScreenModeStatus.java
@@ -0,0 +1,207 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.common.util.IntIntHashMap;
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.ScreenModeListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class ScreenModeStatus {
+ private static boolean DEBUG = Screen.DEBUG;
+
+ private RecursiveLock lock = new RecursiveLock();
+ private ArrayHashSet/*<ScreenMode>*/ screenModes;
+ private IntIntHashMap screenModesIdx2NativeIdx;
+ private ScreenMode currentScreenMode;
+ private ScreenMode originalScreenMode;
+ private ArrayList/*<ScreenModeChangeListener>*/ listener = new ArrayList();
+
+ private static HashMap screenFQN2ScreenModeStatus = new HashMap();
+ private static RecursiveLock screen2ScreenModeStatusLock = new RecursiveLock();
+
+ protected static void mapScreenModeStatus(String screenFQN, ScreenModeStatus sms) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ ScreenModeStatus _sms = (ScreenModeStatus) screenFQN2ScreenModeStatus.get(screenFQN);
+ if( null != _sms ) {
+ throw new RuntimeException("ScreenModeStatus "+_sms+" already mapped to "+screenFQN);
+ }
+ screenFQN2ScreenModeStatus.put(screenFQN, sms);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.map "+screenFQN+" -> "+sms);
+ }
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ /**
+ * @param screen the prev user
+ * @return true if mapping is empty, ie no more usage of the mapped ScreenModeStatus
+ */
+ protected static void unmapScreenModeStatus(String screenFQN) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ ScreenModeStatus sms = (ScreenModeStatus) screenFQN2ScreenModeStatus.remove(screenFQN);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.unmap "+screenFQN+" -> "+sms);
+ }
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ protected static ScreenModeStatus getScreenModeStatus(String screenFQN) {
+ screen2ScreenModeStatusLock.lock();
+ try {
+ return (ScreenModeStatus) screenFQN2ScreenModeStatus.get(screenFQN);
+ } finally {
+ screen2ScreenModeStatusLock.unlock();
+ }
+ }
+
+ protected static void lockScreenModeStatus() {
+ screen2ScreenModeStatusLock.lock();
+ }
+
+ protected static void unlockScreenModeStatus() {
+ screen2ScreenModeStatusLock.unlock();
+ }
+
+ public ScreenModeStatus(ArrayHashSet/*<ScreenMode>*/ screenModes,
+ IntIntHashMap screenModesIdx2NativeIdx) {
+ this.screenModes = screenModes;
+ this.screenModesIdx2NativeIdx = screenModesIdx2NativeIdx;
+ }
+
+ protected final void setOriginalScreenMode(ScreenMode originalScreenMode) {
+ this.originalScreenMode = originalScreenMode;
+ this.currentScreenMode = originalScreenMode;
+ }
+
+ public final ScreenMode getOriginalScreenMode() {
+ return originalScreenMode;
+ }
+
+ public final ScreenMode getCurrentScreenMode() {
+ lock();
+ try {
+ return currentScreenMode;
+ } finally {
+ unlock();
+ }
+ }
+
+ public final boolean isOriginalMode() {
+ lock();
+ try {
+ if(null != currentScreenMode && null != originalScreenMode) {
+ return currentScreenMode.hashCode() == originalScreenMode.hashCode();
+ }
+ return true;
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final ArrayHashSet/*<ScreenMode>*/ getScreenModes() {
+ return screenModes;
+ }
+
+ protected final IntIntHashMap getScreenModesIdx2NativeIdx() {
+ return screenModesIdx2NativeIdx;
+ }
+
+ protected final int addListener(ScreenModeListener l) {
+ lock();
+ try {
+ listener.add(l);
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.addListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final int removeListener(ScreenModeListener l) {
+ lock();
+ try {
+ if(!listener.remove(l)) {
+ throw new RuntimeException("ScreenModeListener "+l+" not contained");
+ }
+ if(DEBUG) {
+ System.err.println("ScreenModeStatus.removeListener (size: "+listener.size()+"): "+l);
+ }
+ return listener.size();
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final void fireScreenModeChangeNotify(ScreenMode desiredScreenMode) {
+ lock();
+ try {
+ for(int i=0; i<listener.size(); i++) {
+ ((ScreenModeListener)listener.get(i)).screenModeChangeNotify(desiredScreenMode);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected void fireScreenModeChanged(ScreenMode currentScreenMode, boolean success) {
+ lock();
+ try {
+ if(success) {
+ this.currentScreenMode = currentScreenMode;
+ }
+ for(int i=0; i<listener.size(); i++) {
+ ((ScreenModeListener)listener.get(i)).screenModeChanged(currentScreenMode, success);
+ }
+ } finally {
+ unlock();
+ }
+ }
+
+ protected final void lock() throws RuntimeException {
+ lock.lock();
+ }
+
+ protected final void unlock() throws RuntimeException {
+ lock.unlock();
+ }
+
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
new file mode 100644
index 000000000..d7504cfdf
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/WindowImpl.java
@@ -0,0 +1,2128 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl;
+
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.newt.NewtFactory;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Screen;
+import com.jogamp.newt.Window;
+import com.jogamp.common.util.locks.RecursiveLock;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseEvent;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.NEWTEvent;
+import com.jogamp.newt.event.NEWTEventConsumer;
+import com.jogamp.newt.event.ScreenModeListener;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
+import com.jogamp.newt.event.WindowUpdateEvent;
+
+import java.util.ArrayList;
+import java.lang.reflect.Method;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.NativeSurface;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.SurfaceUpdatedListener;
+import javax.media.nativewindow.util.DimensionReadOnly;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.Rectangle;
+
+public abstract class WindowImpl implements Window, NEWTEventConsumer, ScreenModeListener
+{
+ 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(NativeWindow parentWindow, long parentWindowHandle, Screen screen, Capabilities caps) {
+ try {
+ Class windowClass;
+ if(caps.isOnscreen()) {
+ windowClass = getWindowClass(screen.getDisplay().getType());
+ } 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(Object[] cstrArguments, Screen screen, Capabilities caps) {
+ try {
+ Class windowClass = getWindowClass(screen.getDisplay().getType());
+ Class[] cstrArgumentTypes = getCustomConstructorArgumentTypes(windowClass);
+ if(null==cstrArgumentTypes) {
+ throw new NativeWindowException("WindowClass "+windowClass+" doesn't support custom arguments in constructor");
+ }
+ int argsChecked = verifyConstructorArgumentTypes(cstrArgumentTypes, cstrArguments);
+ if ( argsChecked < cstrArguments.length ) {
+ throw new NativeWindowException("WindowClass "+windowClass+" constructor mismatch at argument #"+argsChecked+"; Constructor: "+getTypeStrList(cstrArgumentTypes)+", arguments: "+getArgsStrList(cstrArguments));
+ }
+ WindowImpl window = (WindowImpl) ReflectionUtil.createInstance( windowClass, cstrArgumentTypes, cstrArguments ) ;
+ window.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.<br>
+ * Surface not locked yet.<br>
+ * Called not necessarily from EDT.
+ */
+ void destroyActionPreLock(boolean unrecoverable);
+
+ /**
+ * Invoked before Window destroy action,
+ * allows releasing of resources depending on the native Window.<br>
+ * Surface locked.<br>
+ * Called from EDT.
+ */
+ void destroyActionInLock(boolean unrecoverable);
+
+ /**
+ * Invoked for expensive modifications, ie while reparenting and ScreenMode change.<br>
+ * No lock is hold when invoked.<br>
+ *
+ * @see #resumeRenderingAction()
+ */
+ void pauseRenderingAction();
+
+ /**
+ * Invoked for expensive modifications, ie while reparenting and ScreenMode change.
+ * No lock is hold when invoked.<br>
+ *
+ * @see #pauseRenderingAction()
+ */
+ void resumeRenderingAction();
+ }
+
+ private LifecycleHook lifecycleHook = null;
+ private RecursiveLock windowLock = new RecursiveLock();
+ 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, hasFocus;
+ protected int width, height, x, y;
+ protected int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen dimensions ..
+
+ protected String title = "Newt Window";
+ protected boolean undecorated = false;
+ private boolean handleDestroyNotify = true;
+
+ private final void destroyScreen() {
+ if(null!=screen) {
+ if(screenReferenced) {
+ screen.removeReference();
+ screenReferenced = false;
+ }
+ screen = null;
+ }
+ }
+ private final void setScreen(ScreenImpl newScreen) {
+ if(screenReferenced) {
+ screenReferenced = false;
+ screen.removeReference();
+ }
+ screen = newScreen;
+ }
+
+ private boolean createNative() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")");
+ }
+ if( null != parentWindow &&
+ NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindow.lockSurface() ) {
+ throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
+ }
+ try {
+ if(validateParentWindowHandle()) {
+ if(!screenReferenced) {
+ screenReferenced = true;
+ screen.addReference();
+ }
+ createNativeImpl();
+ setVisibleImpl(true, x, y, width, height);
+ screen.addScreenModeListener(this);
+ }
+ } 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 wasLocked = false;
+ if( NativeSurface.LOCK_SURFACE_NOT_READY < nativeWindow.lockSurface() ) {
+ wasLocked = true;
+ try {
+ handle = nativeWindow.getWindowHandle();
+ if(0==handle) {
+ throw new NativeWindowException("Parent native window handle is NULL, after succesful locking: "+nativeWindow);
+ }
+ } catch (NativeWindowException nwe) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.getNativeWindowHandle: not successful yet: "+nwe);
+ }
+ } finally {
+ nativeWindow.unlockSurface();
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.getNativeWindowHandle: locked "+wasLocked+", "+nativeWindow);
+ }
+ }
+ return handle;
+ }
+
+
+ //----------------------------------------------------------------------
+ // NativeSurface: Native implementation
+ //
+
+ protected int lockSurfaceImpl() { return LOCK_SUCCESS; }
+
+ protected void unlockSurfaceImpl() { }
+
+ //----------------------------------------------------------------------
+ // Window: Native implementation
+ //
+
+ /**
+ * The native implementation must set the native windowHandle.<br>
+ *
+ * The implementation should invoke the referenced java state callbacks
+ * to notify this Java object of state changes.
+ *
+ * @see #windowDestroyNotify()
+ * @see #focusChanged(boolean)
+ * @see #visibleChanged(boolean)
+ * @see #sizeChanged(int,int)
+ * @see #positionChanged(int,int)
+ * @see #windowDestroyNotify()
+ */
+ protected abstract void createNativeImpl();
+
+ protected abstract void closeNativeImpl();
+
+ /**
+ * The native implementation must invoke {@link #focusChanged(boolean)}
+ * to change the focus state, if <code>force == false</code>.
+ * This may happen asynchronous within {@link #TIMEOUT_NATIVEWINDOW}.
+ *
+ * @param force if true, bypass {@link #focusChanged(boolean)} and force focus request
+ */
+ protected abstract void requestFocusImpl(boolean force);
+
+ /**
+ * The native implementation must invoke {@link #visibleChanged(boolean)}
+ * to change the visibility state. This may happen asynchronous within
+ * {@link #TIMEOUT_NATIVEWINDOW}.
+ */
+ protected abstract void setVisibleImpl(boolean visible, int x, int y, int width, int height);
+
+ /**
+ * The native implementation should invoke the referenced java state callbacks
+ * to notify this Java object of state changes.
+ *
+ * @param x -1 if no position change requested, otherwise greater than zero
+ * @param y -1 if no position change requested, otherwise greater than zero
+ * @param width -1 if no size change requested, otherwise greater than zero
+ * @param height -1 if no size change requested, otherwise greater than zero
+ * @param parentChange true if reparenting requested, otherwise false
+ * @param fullScreenChange 0 if unchanged, -1 fullscreen off, 1 fullscreen on
+ * @param decorationChange 0 if unchanged, -1 undecorated, 1 decorated
+ *
+ * @see #sizeChanged(int,int)
+ * @see #positionChanged(int,int)
+ */
+ protected abstract boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange);
+
+ protected void setTitleImpl(String title) {}
+
+ /**
+ * Return screen coordinates of the given coordinates
+ * or null, in which case a NativeWindow traversal shall being used
+ * as demonstrated in {@link #getLocationOnScreen(javax.media.nativewindow.util.Point)}.
+ *
+ * @return if not null, the screen location of the given coordinates
+ */
+ protected abstract Point getLocationOnScreenImpl(int x, int y);
+
+ //----------------------------------------------------------------------
+ // NativeSurface
+ //
+
+ public final int lockSurface() {
+ int res = LOCK_SURFACE_NOT_READY;
+
+ windowLock.lock();
+
+ AbstractGraphicsDevice adevice = screen.getDisplay().getGraphicsDevice();
+ adevice.lock();
+ try {
+ res = lockSurfaceImpl();
+ } finally {
+ if(!isNativeValid()) {
+ adevice.unlock();
+ windowLock.unlock();
+ res = LOCK_SURFACE_NOT_READY;
+ }
+ }
+
+ return res;
+ }
+
+ public final void unlockSurface() {
+ // may throw RuntimeException if not locked
+ windowLock.validateLocked();
+
+ try {
+ unlockSurfaceImpl();
+ } finally {
+ screen.getDisplay().getGraphicsDevice().unlock();
+ }
+ windowLock.unlock();
+ }
+
+ public final boolean isSurfaceLockedByOtherThread() {
+ return windowLock.isLockedByOtherThread();
+ }
+
+ public final boolean isSurfaceLocked() {
+ return windowLock.isLocked();
+ }
+
+ public final Thread getSurfaceLockOwner() {
+ return windowLock.getOwner();
+ }
+
+ public long getSurfaceHandle() {
+ return windowHandle; // default: return window handle
+ }
+
+ public boolean surfaceSwap() {
+ return false;
+ }
+
+ public AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config;
+ }
+
+ public final long getDisplayHandle() {
+ return getScreen().getDisplay().getHandle();
+ }
+
+ public final int getScreenIndex() {
+ return getScreen().getIndex();
+ }
+
+ //----------------------------------------------------------------------
+ // NativeWindow
+ //
+
+ public final void destroy() {
+ destroy(false);
+ }
+
+ public final NativeWindow getParent() {
+ return parentWindow;
+ }
+
+ public final long getWindowHandle() {
+ return windowHandle;
+ }
+
+ public Point getLocationOnScreen(Point storage) {
+ if(isNativeValid()) {
+ Point d;
+ windowLock.lock();
+ try {
+ d = getLocationOnScreenImpl(0, 0);
+ } finally {
+ windowLock.unlock();
+ }
+ if(null!=d) {
+ if(null!=storage) {
+ storage.translate(d.getX(),d.getY());
+ return storage;
+ }
+ return d;
+ }
+ // fall through intended ..
+ }
+
+ if(null!=storage) {
+ storage.translate(getX(),getY());
+ } else {
+ storage = new Point(getX(),getY());
+ }
+ if(null!=parentWindow) {
+ // traverse through parent list ..
+ parentWindow.getLocationOnScreen(storage);
+ }
+ return storage;
+ }
+
+ //----------------------------------------------------------------------
+ // Window
+ //
+
+ public final boolean isNativeValid() {
+ return null != getScreen() && 0 != getWindowHandle() ;
+ }
+
+ public final boolean isValid() {
+ return null != getScreen() ;
+ }
+
+ public final Screen getScreen() {
+ return screen;
+ }
+
+ class VisibleAction implements Runnable {
+ boolean visible;
+ boolean nativeWindowCreated;
+ boolean madeVisible;
+
+ public VisibleAction (boolean visible) {
+ this.visible = visible;
+ this.nativeWindowCreated = false;
+ this.madeVisible = false;
+ }
+
+ public final boolean getNativeWindowCreated() { return nativeWindowCreated; }
+ public final boolean getBecameVisible() { return madeVisible; }
+ public final boolean getChanged() { return nativeWindowCreated || madeVisible; }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+" -> "+visible+", parentWindowHandle "+toHexString(WindowImpl.this.parentWindowHandle)+", parentWindow "+(null!=WindowImpl.this.parentWindow)/*+", "+this*/);
+ System.err.println(msg);
+ }
+ if(!visible && childWindows.size()>0) {
+ synchronized(childWindowsLock) {
+ for(int i = 0; i < childWindows.size(); i++ ) {
+ NativeWindow nw = (NativeWindow) childWindows.get(i);
+ if(nw instanceof WindowImpl) {
+ ((WindowImpl)nw).setVisible(false);
+ }
+ }
+ }
+ }
+ if(0==windowHandle && visible) {
+ if( 0<width*height ) {
+ nativeWindowCreated = createNative();
+ WindowImpl.this.waitForVisible(visible, true);
+ madeVisible = visible;
+ }
+ } else if(WindowImpl.this.visible != visible) {
+ if(0 != windowHandle) {
+ setVisibleImpl(visible, x, y, width, height);
+ WindowImpl.this.waitForVisible(visible, true);
+ madeVisible = visible;
+ }
+ }
+
+ if(null!=lifecycleHook) {
+ lifecycleHook.setVisibleAction(visible, nativeWindowCreated);
+ }
+
+ if(0!=windowHandle && visible && childWindows.size()>0) {
+ synchronized(childWindowsLock) {
+ for(int i = 0; i < childWindows.size(); i++ ) {
+ NativeWindow nw = (NativeWindow) childWindows.get(i);
+ if(nw instanceof WindowImpl) {
+ ((WindowImpl)nw).setVisible(true);
+ }
+ }
+ }
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+WindowImpl.this.visible+", nativeWindowCreated: "+nativeWindowCreated+", madeVisible: "+madeVisible);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void setVisible(boolean visible) {
+ if(isValid()) {
+ if( 0==windowHandle && visible && 0>=width*height ) {
+ // fast-path: not realized yet, make visible, but zero size
+ return;
+ }
+ VisibleAction visibleAction = new VisibleAction(visible);
+ runOnEDTIfAvail(true, visibleAction);
+ if( visibleAction.getChanged() ) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+ }
+
+ class SetSizeActionImpl implements Runnable {
+ int visibleAction = 0; // 1 invisible, 2 visible (create)
+ int width, height;
+
+ public int getVisibleAction() {
+ return visibleAction;
+ }
+ public SetSizeActionImpl(int w, int h) {
+ width = w;
+ height = h;
+ }
+ public void run() {
+ windowLock.lock();
+ try {
+ if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
+ if(DEBUG_IMPLEMENTATION) {
+ String msg = new String("Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
+ System.err.println(msg);
+ }
+ if ( 0 != windowHandle && 0>=width*height && visible ) {
+ visibleAction=1; // invisible
+ WindowImpl.this.width = 0;
+ WindowImpl.this.height = 0;
+ } else if ( 0 == windowHandle && 0<width*height && visible ) {
+ visibleAction = 2; // visible (create)
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ } else if ( 0 != windowHandle ) {
+ // this width/height will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ } else {
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: END "+WindowImpl.this.width+"x"+WindowImpl.this.height+", visibleAction "+visibleAction);
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void setSize(int width, int height) {
+ if(isValid()) {
+ SetSizeActionImpl setSizeAction = new SetSizeActionImpl(width, height);
+ runOnEDTIfAvail(true, setSizeAction);
+ switch(setSizeAction.getVisibleAction()) {
+ case 1: setVisible(false); break;
+ case 2: setVisible(true); break;
+ }
+ }
+ }
+
+ class DestroyAction implements Runnable {
+ 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.destroyActionInLock(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 ) {
+ screen.removeScreenModeListener(WindowImpl.this);
+ closeNativeImpl();
+ }
+ invalidate(unrecoverable);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") END "+getThreadName()/*+", "+WindowImpl.this*/);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ 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();
+ }
+ if(null!=lifecycleHook) {
+ lifecycleHook.destroyActionPreLock(unrecoverable);
+ }
+ DestroyAction destroyAction = new DestroyAction(unrecoverable);
+ runOnEDTIfAvail(true, destroyAction);
+ }
+ }
+
+ /**
+ * <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;
+ hasFocus = false;
+
+ if(unrecoverable) {
+ destroyScreen();
+ 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;
+
+ // mirror pos/size so native change notification can get overwritten
+ int x = WindowImpl.this.x;
+ int y = WindowImpl.this.y;
+ int width = WindowImpl.this.width;
+ int height = WindowImpl.this.height;
+
+ windowLock.lock();
+ try {
+ wasVisible = isVisible();
+
+ Window newParentWindowNEWT = null;
+ if(newParentWindow instanceof Window) {
+ newParentWindowNEWT = (Window) newParentWindow;
+ }
+
+ long newParentWindowHandle = 0 ;
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE+" "+x+"/"+y+" "+width+"x"+height);
+ }
+
+ if(null!=newParentWindow) {
+ // reset position to 0/0 within parent space
+ x = 0;
+ y = 0;
+
+ // refit if size is bigger than parent
+ if( width > newParentWindow.getWidth() ) {
+ width = newParentWindow.getWidth();
+ }
+ if( height > newParentWindow.getHeight() ) {
+ height = newParentWindow.getHeight();
+ }
+
+ // Case: Child Window
+ newParentWindowHandle = getNativeWindowHandle(newParentWindow);
+ if(0 == newParentWindowHandle) {
+ // Case: Parent's native window not realized yet
+ if(null==newParentWindowNEWT) {
+ throw new NativeWindowException("Reparenting with non NEWT Window type only available after it's realized: "+newParentWindow);
+ }
+ // Destroy this window (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 != getParent()) {
+ // Case: Parent's native window realized and changed
+ if( !isNativeValid() ) {
+ // May create a new compatible Screen/Display and
+ // mark it for creation.
+ if(null!=newParentWindowNEWT) {
+ setScreen( (ScreenImpl) newParentWindowNEWT.getScreen() );
+ } else {
+ Screen newScreen = NewtFactory.createCompatibleScreen(newParentWindow, getScreen());
+ if( getScreen() != newScreen ) {
+ // auto destroy on-the-fly created Screen/Display
+ newScreen.setDestroyWhenUnused(true);
+ setScreen( (ScreenImpl) newScreen );
+ displayChanged = true;
+ }
+ }
+ if( 0<width*height ) {
+ reparentAction = ACTION_NATIVE_CREATION;
+ } else {
+ reparentAction = ACTION_NATIVE_CREATION_PENDING;
+ }
+ } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ||
+ !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
+ // Destroy this window (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 {
+ if( null != parentWindow ) {
+ // child -> top
+ // put client to current parent+child position
+ Point p = getLocationOnScreen(null);
+ x = p.getX();
+ y = p.getY();
+ }
+
+ // Case: Top Window
+ if( 0 == getParentWindowHandle() ) {
+ // Already Top Window
+ reparentAction = ACTION_UNCHANGED;
+ } else if( !isNativeValid() || DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) {
+ // Destroy this window (handle screen + native),
+ // keep Screen/Display and mark it for creation.
+ destroy(false);
+ if( 0<width*height ) {
+ reparentAction = ACTION_NATIVE_CREATION;
+ } else {
+ reparentAction = ACTION_NATIVE_CREATION_PENDING;
+ }
+ } else {
+ // Mark it for native reparenting
+ reparentAction = ACTION_NATIVE_REPARENTING;
+ }
+ }
+ parentWindowHandle = newParentWindowHandle;
+
+ if ( ACTION_UNCHANGED > reparentAction ) {
+ throw new NativeWindowException("Internal Error: reparentAction not set");
+ }
+
+ if( ACTION_UNCHANGED == reparentAction ) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: NO CHANGE ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", visible "+wasVisible);
+ }
+ return;
+ }
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: ACTION ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" new parentWindowHandle "+toHexString(newParentWindowHandle)+", reparentAction "+reparentAction+", visible "+wasVisible);
+ }
+
+ // rearrange window tree
+ if(null!=parentWindow && parentWindow instanceof Window) {
+ ((Window)parentWindow).removeChild(WindowImpl.this);
+ }
+ parentWindow = newParentWindow;
+ if(parentWindow instanceof Window) {
+ ((Window)parentWindow).addChild(WindowImpl.this);
+ }
+
+ if( ACTION_NATIVE_CREATION_PENDING == reparentAction ) {
+ return;
+ }
+
+ if( ACTION_NATIVE_REPARENTING == reparentAction ) {
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
+ if(wasVisible) {
+ setVisibleImpl(false, x, y, width, height);
+ WindowImpl.this.waitForVisible(false, true);
+ }
+
+ // Lock parentWindow only during reparenting (attempt)
+ NativeWindow parentWindowLocked = null;
+ if( null != parentWindow ) {
+ parentWindowLocked = parentWindow;
+ if( NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindowLocked.lockSurface() ) {
+ throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
+ }
+ }
+ boolean ok = false;
+ try {
+ // write back mirrored values, to be able to detect satisfaction
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ ok = reconfigureWindowImpl(x, y, width, height, true, 0, isUndecorated()?-1:1);
+ } finally {
+ if(null!=parentWindowLocked) {
+ parentWindowLocked.unlockSurface();
+ }
+ }
+
+ // set visible again, and revalidate 'ok',
+ // since it has been experience that in some cases the reparented window gets hidden
+ if(ok) {
+ display.dispatchMessagesNative(); // status up2date
+ if(wasVisible) {
+ setVisibleImpl(true, x, y, width, height);
+ ok = WindowImpl.this.waitForVisible(true, false);
+ display.dispatchMessagesNative(); // status up2date
+ if( ok &&
+ ( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != width ||
+ WindowImpl.this.height != height ) )
+ {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent (reconfig)");
+ }
+ // reset pos/size .. due to some native impl flakyness
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ }
+ }
+
+ if(ok) {
+ if(wasVisible) {
+ requestFocusImpl(true);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ } else {
+ // native reparent failed -> try creation
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparent: native reparenting failed ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentWindowHandle)+" - Trying recreation");
+ }
+ destroy(false);
+ reparentAction = ACTION_NATIVE_CREATION ;
+ }
+ }
+
+ // write back mirrored values, ensuring persitence
+ // and not relying on native messaging
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+ Display.hashCodeNullSafe(parentWindow)+" "+x+"/"+y+" "+width+"x"+height);
+ }
+ } finally {
+ windowLock.unlock();
+ }
+
+ if( ACTION_NATIVE_CREATION == reparentAction && wasVisible ) {
+ // This may run on 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.hashCodeNullSafe(parentWindow));
+ }
+ setVisible(true); // native creation
+ } 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) {
+ // pause animation
+ lifecycleHook.pauseRenderingAction();
+ }
+ try {
+ ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
+ runOnEDTIfAvail(true, reparentAction);
+ reparentActionStrategy = reparentAction.getStrategy();
+ } finally {
+ if(null!=lifecycleHook) {
+ // resume animation
+ lifecycleHook.resumeRenderingAction();
+ }
+ }
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ 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);
+ }
+ }
+
+ class DecorationActionImpl implements Runnable {
+ boolean undecorated;
+
+ public DecorationActionImpl(boolean undecorated) {
+ this.undecorated = undecorated;
+ }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(!fullscreen && isNativeValid() && WindowImpl.this.undecorated != undecorated) {
+ WindowImpl.this.undecorated = undecorated;
+ // mirror pos/size so native change notification can get overwritten
+ int x = WindowImpl.this.x;
+ int y = WindowImpl.this.y;
+ int width = WindowImpl.this.width;
+ int height = WindowImpl.this.height;
+
+ if( 0 != windowHandle ) {
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
+ boolean wasVisible = isVisible();
+ setVisibleImpl(false, x, y, width, height);
+ WindowImpl.this.waitForVisible(false, true);
+ display.dispatchMessagesNative(); // status up2date
+ reconfigureWindowImpl(x, y, width, height, false, 0, undecorated?-1:1);
+ display.dispatchMessagesNative(); // status up2date
+ if(wasVisible) {
+ setVisibleImpl(true, x, y, width, height);
+ WindowImpl.this.waitForVisible(true, true);
+ display.dispatchMessagesNative(); // status up2date
+ if( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != width ||
+ WindowImpl.this.height != height )
+ {
+ // reset pos/size .. due to some native impl flakyness
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ requestFocusImpl(true);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void setUndecorated(boolean value) {
+ if(isValid()) {
+ DecorationActionImpl decorationAction = new DecorationActionImpl(value);
+ runOnEDTIfAvail(true, decorationAction);
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+
+ public boolean isUndecorated() {
+ return 0 != parentWindowHandle || undecorated || fullscreen ;
+ }
+
+ public void requestFocus() {
+ enqueueRequestFocus(true);
+ }
+
+ public boolean hasFocus() {
+ return hasFocus;
+ }
+
+ public Insets getInsets() {
+ return new Insets(0,0,0,0);
+ }
+
+ public final int getWidth() {
+ return width;
+ }
+
+ public final int getHeight() {
+ return height;
+ }
+
+ public final int getX() {
+ return x;
+ }
+
+ public final int getY() {
+ return y;
+ }
+
+ public final boolean isVisible() {
+ return visible;
+ }
+
+ public final boolean isFullscreen() {
+ return fullscreen;
+ }
+
+
+ //----------------------------------------------------------------------
+ // Window
+ //
+
+ /**
+ * If the implementation is capable of detecting a device change
+ * return true and clear the status/reason of the change.
+ */
+ public boolean hasDeviceChanged() {
+ return false;
+ }
+
+ public LifecycleHook getLifecycleHook() {
+ return lifecycleHook;
+ }
+
+ public LifecycleHook setLifecycleHook(LifecycleHook hook) {
+ LifecycleHook old = lifecycleHook;
+ lifecycleHook = hook;
+ return old;
+ }
+
+ /** If this Window actually wraps one from another toolkit such as
+ the AWT, this will return a non-null value. */
+ public Object getWrappedWindow() {
+ return null;
+ }
+
+ /**
+ * If set to true, the default value, this NEWT Window implementation will
+ * handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br>
+ * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify()}.
+ */
+ public void setHandleDestroyNotify(boolean b) {
+ handleDestroyNotify = b;
+ }
+
+ //----------------------------------------------------------------------
+ // WindowImpl
+ //
+
+ protected final long getParentWindowHandle() {
+ return parentWindowHandle;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ sb.append(getClass().getName()+"[Config "+config+
+ "\n, "+screen+
+ "\n, ParentWindow "+parentWindow+
+ "\n, ParentWindowHandle "+toHexString(parentWindowHandle)+
+ "\n, WindowHandle "+toHexString(getWindowHandle())+
+ "\n, SurfaceHandle "+toHexString(getSurfaceHandle())+ " (lockedExt "+isSurfaceLockedByOtherThread()+")"+
+ "\n, Pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
+ "\n, Visible "+isVisible()+
+ "\n, Undecorated "+undecorated+
+ "\n, Fullscreen "+fullscreen+
+ "\n, WrappedWindow "+getWrappedWindow()+
+ "\n, ChildWindows "+childWindows.size());
+
+ sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" [");
+ for (int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ sb.append(surfaceUpdatedListeners.get(i)+", ");
+ }
+ sb.append("], WindowListeners num "+windowListeners.size()+" [");
+ for (int i = 0; i < windowListeners.size(); i++ ) {
+ sb.append(windowListeners.get(i)+", ");
+ }
+ sb.append("], MouseListeners num "+mouseListeners.size()+" [");
+ for (int i = 0; i < mouseListeners.size(); i++ ) {
+ sb.append(mouseListeners.get(i)+", ");
+ }
+ sb.append("], KeyListeners num "+keyListeners.size()+" [");
+ for (int i = 0; i < keyListeners.size(); i++ ) {
+ sb.append(keyListeners.get(i)+", ");
+ }
+ sb.append("] ]");
+ return sb.toString();
+ }
+
+ protected final void setWindowHandle(long handle) {
+ windowHandle = handle;
+ }
+
+ public void runOnEDTIfAvail(boolean wait, final Runnable task) {
+ Screen screen = getScreen();
+ if(null==screen) {
+ throw new RuntimeException("Null screen of inner class: "+this);
+ }
+ DisplayImpl d = (DisplayImpl) screen.getDisplay();
+ d.runOnEDTIfAvail(wait, task);
+ }
+
+ class RequestFocusAction implements Runnable {
+ public void run() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.RequestFocusAction: ("+getThreadName()+"): "+hasFocus+" -> true - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ WindowImpl.this.requestFocusImpl(false);
+ }
+ }
+ RequestFocusAction requestFocusAction = new RequestFocusAction();
+
+ protected void enqueueRequestFocus(boolean wait) {
+ runOnEDTIfAvail(wait, requestFocusAction);
+ }
+
+ /**
+ * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
+ * This allows notifying a covered window toolkit like AWT that the focus is requested,
+ * hence focus traversal can be made transparent.
+ */
+ public void setFocusAction(FocusRunnable focusAction) {
+ this.focusAction = focusAction;
+ }
+ protected boolean focusAction() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.focusAction() START - "+getThreadName()+", focusAction: "+focusAction+" - windowHandle "+toHexString(getWindowHandle()));
+ }
+ boolean res;
+ if(null!=focusAction) {
+ res = focusAction.run();
+ } else {
+ res = false;
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.focusAction() END - "+getThreadName()+", focusAction: "+focusAction+" - windowHandle "+toHexString(getWindowHandle())+", res: "+res);
+ }
+ return res;
+ }
+ protected FocusRunnable focusAction = null;
+
+ class SetPositionActionImpl implements Runnable {
+ int x, y;
+
+ public SetPositionActionImpl(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+ public void run() {
+ windowLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setPosition: "+WindowImpl.this.x+"/"+WindowImpl.this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
+ }
+ if ( WindowImpl.this.x != x || WindowImpl.this.y != y ) {
+ if(!fullscreen) {
+ if(0!=windowHandle) {
+ // this.x/this.y will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, -1, -1, false, 0, 0);
+ } else {
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public void setPosition(int x, int y) {
+ if(isValid()) {
+ SetPositionActionImpl setPositionAction = new SetPositionActionImpl(x, y);
+ runOnEDTIfAvail(true, setPositionAction);
+ }
+ }
+
+ class FullScreenActionImpl implements Runnable {
+ boolean fullscreen;
+
+ public FullScreenActionImpl (boolean fullscreen) {
+ this.fullscreen = fullscreen;
+ }
+
+ public void run() {
+ windowLock.lock();
+ try {
+ if(isNativeValid() && WindowImpl.this.fullscreen != fullscreen) {
+ int x,y,w,h;
+ WindowImpl.this.fullscreen = fullscreen;
+ if(fullscreen) {
+ x = 0; y = 0;
+ w = screen.getWidth();
+ h = screen.getHeight();
+ nfs_width = width;
+ nfs_height = height;
+ nfs_x = x;
+ nfs_y = y;
+ } else {
+ x = nfs_x;
+ y = nfs_y;
+ w = nfs_width;
+ h = nfs_height;
+ }
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()+", "+screen);
+ }
+
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ display.dispatchMessagesNative(); // status up2date
+ boolean wasVisible = isVisible();
+ setVisibleImpl(false, x, y, width, height);
+ WindowImpl.this.waitForVisible(false, true);
+ display.dispatchMessagesNative(); // status up2date
+
+ // write back mirrored values, to be able to detect satisfaction
+ WindowImpl.this.x = x;
+ WindowImpl.this.y = y;
+ WindowImpl.this.width = w;
+ WindowImpl.this.height = h;
+ reconfigureWindowImpl(x, y, w, h, getParentWindowHandle()!=0, fullscreen?1:-1, isUndecorated()?-1:1);
+ display.dispatchMessagesNative(); // status up2date
+
+ if(wasVisible) {
+ setVisibleImpl(true, x, y, width, height);
+ boolean ok = WindowImpl.this.waitForVisible(true, true, Screen.SCREEN_MODE_CHANGE_TIMEOUT);
+ display.dispatchMessagesNative(); // status up2date
+ if( ok &&
+ ( WindowImpl.this.x != x ||
+ WindowImpl.this.y != y ||
+ WindowImpl.this.width != w ||
+ WindowImpl.this.height != h ) )
+ {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs (reconfig): "+x+"/"+y+" "+w+"x"+h+", "+screen);
+ }
+ // reset pos/size .. due to some native impl flakyness
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ display.dispatchMessagesNative(); // status up2date
+ }
+ requestFocusImpl(true);
+ display.dispatchMessagesNative(); // status up2date
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window fs done");
+ }
+ }
+ }
+ } finally {
+ windowLock.unlock();
+ }
+ }
+ }
+
+ public boolean setFullscreen(boolean fullscreen) {
+ if(isValid()) {
+ FullScreenActionImpl fullScreenAction = new FullScreenActionImpl(fullscreen);
+ runOnEDTIfAvail(true, fullScreenAction);
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ return this.fullscreen;
+ }
+
+ public void screenModeChangeNotify(ScreenMode sm) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window.screenModeChangeNotify: "+sm);
+ }
+
+ if(null!=lifecycleHook) {
+ // pause animation
+ lifecycleHook.pauseRenderingAction();
+ }
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("Window.screenModeChanged: "+sm+", success: "+success);
+ }
+
+ if(success) {
+ DimensionReadOnly screenSize = sm.getMonitorMode().getSurfaceSize().getResolution();
+ if ( getHeight() > screenSize.getHeight() ||
+ getWidth() > screenSize.getWidth() ) {
+ setSize(screenSize.getWidth(), screenSize.getHeight());
+ }
+ }
+
+ if(null!=lifecycleHook) {
+ // resume animation
+ lifecycleHook.resumeRenderingAction();
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // 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, NativeSurface ns, long when) {
+ synchronized(surfaceUpdatedListenersLock) {
+ for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
+ SurfaceUpdatedListener l = (SurfaceUpdatedListener) surfaceUpdatedListeners.get(i);
+ l.surfaceUpdated(updater, ns, when);
+ }
+ }
+ }
+
+ //
+ // MouseListener/Event Support
+ //
+ 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 void sendMouseEvent(int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ doMouseEvent(false, false, eventType, modifiers, x, y, button, rotation);
+ }
+ public void enqueueMouseEvent(boolean wait, int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ doMouseEvent(true, wait, eventType, modifiers, x, y, button, rotation);
+ }
+ private void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ if(x<0||y<0||x>=width||y>=height) {
+ return; // .. invalid ..
+ }
+ if(DEBUG_MOUSE_EVENT) {
+ System.err.println("doMouseEvent: enqueue"+enqueue+", wait "+wait+", "+MouseEvent.getEventTypeString(eventType)+
+ ", mod "+modifiers+", pos "+x+"/"+y+", button "+button);
+ }
+ if(button<0||button>MouseEvent.BUTTON_NUMBER) {
+ throw new NativeWindowException("Invalid mouse button number" + button);
+ }
+ long when = System.currentTimeMillis();
+ MouseEvent eClicked = null;
+ MouseEvent e = null;
+
+ if(MouseEvent.EVENT_MOUSE_PRESSED==eventType) {
+ if(when-lastMousePressed<MouseEvent.getClickTimeout()) {
+ lastMouseClickCount++;
+ } else {
+ lastMouseClickCount=1;
+ }
+ lastMousePressed=when;
+ mouseButtonPressed=button;
+ e = new MouseEvent(eventType, this, when,
+ modifiers, x, y, lastMouseClickCount, button, 0);
+ } else if(MouseEvent.EVENT_MOUSE_RELEASED==eventType) {
+ e = new MouseEvent(eventType, this, when,
+ modifiers, x, y, lastMouseClickCount, button, 0);
+ if(when-lastMousePressed<MouseEvent.getClickTimeout()) {
+ eClicked = new MouseEvent(MouseEvent.EVENT_MOUSE_CLICKED, this, when,
+ modifiers, x, y, lastMouseClickCount, button, 0);
+ } else {
+ lastMouseClickCount=0;
+ lastMousePressed=0;
+ }
+ mouseButtonPressed=0;
+ } else if(MouseEvent.EVENT_MOUSE_MOVED==eventType) {
+ if (mouseButtonPressed>0) {
+ e = new MouseEvent(MouseEvent.EVENT_MOUSE_DRAGGED, this, when,
+ modifiers, x, y, 1, mouseButtonPressed, 0);
+ } else {
+ e = new MouseEvent(eventType, this, when,
+ modifiers, x, y, 0, button, 0);
+ }
+ } else if(MouseEvent.EVENT_MOUSE_WHEEL_MOVED==eventType) {
+ e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, rotation);
+ } else {
+ e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, 0);
+ }
+ doEvent(enqueue, wait, e);
+ if(null!=eClicked) {
+ if(DEBUG_MOUSE_EVENT) {
+ System.err.println("doMouseEvent: synthesized MOUSE_CLICKED event");
+ }
+ doEvent(enqueue, wait, eClicked);
+ }
+ }
+
+
+ public void addMouseListener(MouseListener l) {
+ addMouseListener(-1, l);
+ }
+
+ public void addMouseListener(int index, MouseListener l) {
+ if(l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size();
+ }
+ clonedListeners.add(index, l);
+ mouseListeners = clonedListeners;
+ }
+
+ public void removeMouseListener(MouseListener l) {
+ if (l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
+ clonedListeners.remove(l);
+ mouseListeners = clonedListeners;
+ }
+
+ public MouseListener getMouseListener(int index) {
+ ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size()-1;
+ }
+ return (MouseListener) clonedListeners.get(index);
+ }
+
+ public MouseListener[] getMouseListeners() {
+ return (MouseListener[]) mouseListeners.toArray();
+ }
+
+ protected void consumeMouseEvent(MouseEvent e) {
+ if(DEBUG_MOUSE_EVENT) {
+ System.err.println("consumeMouseEvent: event: "+e);
+ }
+
+ for(int i = 0; i < mouseListeners.size(); i++ ) {
+ MouseListener l = (MouseListener) mouseListeners.get(i);
+ switch(e.getEventType()) {
+ case MouseEvent.EVENT_MOUSE_CLICKED:
+ l.mouseClicked(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_ENTERED:
+ l.mouseEntered(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_EXITED:
+ l.mouseExited(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_PRESSED:
+ l.mousePressed(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_RELEASED:
+ l.mouseReleased(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_MOVED:
+ l.mouseMoved(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_DRAGGED:
+ l.mouseDragged(e);
+ break;
+ case MouseEvent.EVENT_MOUSE_WHEEL_MOVED:
+ l.mouseWheelMoved(e);
+ break;
+ default:
+ throw new NativeWindowException("Unexpected mouse event type " + e.getEventType());
+ }
+ }
+ }
+
+ //
+ // KeyListener/Event Support
+ //
+
+ public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
+ }
+
+ public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ enqueueEvent(wait, new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
+ }
+
+ public void addKeyListener(KeyListener l) {
+ addKeyListener(-1, l);
+ }
+
+ public void addKeyListener(int index, KeyListener l) {
+ if(l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) keyListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size();
+ }
+ clonedListeners.add(index, l);
+ keyListeners = clonedListeners;
+ }
+
+ public void removeKeyListener(KeyListener l) {
+ if (l == null) {
+ return;
+ }
+ ArrayList clonedListeners = (ArrayList) keyListeners.clone();
+ clonedListeners.remove(l);
+ keyListeners = clonedListeners;
+ }
+
+ public KeyListener getKeyListener(int index) {
+ ArrayList clonedListeners = (ArrayList) keyListeners.clone();
+ if(0>index) {
+ index = clonedListeners.size()-1;
+ }
+ return (KeyListener) clonedListeners.get(index);
+ }
+
+ public KeyListener[] getKeyListeners() {
+ return (KeyListener[]) keyListeners.toArray();
+ }
+
+ private ArrayList keyListeners = new ArrayList();
+
+ protected void consumeKeyEvent(KeyEvent e) {
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e);
+ }
+ for(int i = 0; i < keyListeners.size(); i++ ) {
+ KeyListener l = (KeyListener) keyListeners.get(i);
+ switch(e.getEventType()) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ l.keyPressed(e);
+ break;
+ case KeyEvent.EVENT_KEY_RELEASED:
+ l.keyReleased(e);
+ break;
+ case KeyEvent.EVENT_KEY_TYPED:
+ l.keyTyped(e);
+ break;
+ default:
+ throw new NativeWindowException("Unexpected key event type " + e.getEventType());
+ }
+ }
+ }
+
+ //
+ // WindowListener/Event Support
+ //
+ public void sendWindowEvent(int eventType) {
+ consumeWindowEvent( new WindowEvent(eventType, this, System.currentTimeMillis()) );
+ }
+
+ public void enqueueWindowEvent(boolean wait, int eventType) {
+ enqueueEvent( wait, new WindowEvent(eventType, this, System.currentTimeMillis()) );
+ }
+
+ 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+", visible "+isVisible()+" "+getX()+"/"+getY()+" "+getWidth()+"x"+getHeight());
+ }
+ for(int i = 0; i < windowListeners.size(); i++ ) {
+ WindowListener l = (WindowListener) windowListeners.get(i);
+ switch(e.getEventType()) {
+ case WindowEvent.EVENT_WINDOW_RESIZED:
+ l.windowResized(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_MOVED:
+ l.windowMoved(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY:
+ l.windowDestroyNotify(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_GAINED_FOCUS:
+ l.windowGainedFocus(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_LOST_FOCUS:
+ l.windowLostFocus(e);
+ break;
+ case WindowEvent.EVENT_WINDOW_REPAINT:
+ l.windowRepaint((WindowUpdateEvent)e);
+ break;
+ default:
+ throw
+ new NativeWindowException("Unexpected window event type "
+ + e.getEventType());
+ }
+ }
+ }
+
+ /**
+ * @param focusGained
+ */
+ protected void focusChanged(boolean focusGained) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.focusChanged: ("+getThreadName()+"): "+this.hasFocus+" -> "+focusGained+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ hasFocus = focusGained;
+ if (focusGained) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ } else {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS);
+ }
+ }
+
+ protected void visibleChanged(boolean visible) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ this.visible = visible ;
+ }
+
+ private boolean waitForVisible(boolean visible, boolean failFast) {
+ return waitForVisible(visible, failFast, TIMEOUT_NATIVEWINDOW);
+ }
+
+ private boolean waitForVisible(boolean visible, boolean failFast, long timeOut) {
+ DisplayImpl display = (DisplayImpl) screen.getDisplay();
+ for(long sleep = timeOut; 0<sleep && this.visible != visible; sleep-=10 ) {
+ display.dispatchMessagesNative(); // status up2date
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException ie) {}
+ sleep -=10;
+ }
+ if(this.visible != visible) {
+ if(failFast) {
+ throw new NativeWindowException("Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible);
+ } else if (DEBUG_IMPLEMENTATION) {
+ System.err.println("******* Visibility not reached as requested within "+timeOut+"ms : requested "+visible+", is "+this.visible);
+ }
+ }
+ return this.visible == visible;
+ }
+
+ protected void sizeChanged(int newWidth, int newHeight, boolean force) {
+ if(force || width != newWidth || height != newHeight) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.sizeChanged: ("+getThreadName()+"): force "+force+", "+width+"x"+height+" -> "+newWidth+"x"+newHeight+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ width = newWidth;
+ height = newHeight;
+ if(isNativeValid()) {
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
+ }
+ }
+ }
+
+ protected void positionChanged(int newX, int newY) {
+ if( 0==parentWindowHandle && ( x != newX || y != newY ) ) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.positionChanged: ("+getThreadName()+"): "+x+"/"+y+" -> "+newX+"/"+newY+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
+ }
+ x = newX;
+ y = newY;
+ sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
+ }
+ }
+
+ protected void windowDestroyNotify() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.windowDestroyNotify START "+getThreadName());
+ }
+
+ 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);
+ // Exception ee = new Exception("Window.windowRepaint: "+" - "+x+"/"+y+" "+width+"x"+height);
+ // ee.printStackTrace();
+ }
+
+ if(isNativeValid()) {
+ if(0>width) {
+ width=this.width;
+ }
+ if(0>height) {
+ height=this.height;
+ }
+
+ NEWTEvent e = new WindowUpdateEvent(WindowEvent.EVENT_WINDOW_REPAINT, this, System.currentTimeMillis(),
+ new Rectangle(x, y, width, height));
+ doEvent(false, false, e);
+ }
+ }
+
+ protected int getWindowLockRecursionCount() {
+ return windowLock.getRecursionCount();
+ }
+
+ //
+ // Reflection helper ..
+ //
+
+ private static Class[] getCustomConstructorArgumentTypes(Class windowClass) {
+ Class[] argTypes = null;
+ try {
+ Method m = windowClass.getDeclaredMethod("getCustomConstructorArgumentTypes", new Class[] {});
+ argTypes = (Class[]) m.invoke(null, null);
+ } catch (Throwable t) {}
+ return argTypes;
+ }
+
+ private static int verifyConstructorArgumentTypes(Class[] types, Object[] args) {
+ if(types.length != args.length) {
+ return -1;
+ }
+ for(int i=0; i<args.length; i++) {
+ if(!types[i].isInstance(args[i])) {
+ return i;
+ }
+ }
+ return args.length;
+ }
+
+ private static String getArgsStrList(Object[] args) {
+ StringBuffer sb = new StringBuffer();
+ for(int i=0; i<args.length; i++) {
+ sb.append(args[i].getClass());
+ if(i<args.length) {
+ sb.append(", ");
+ }
+ }
+ return sb.toString();
+ }
+
+ private static String getTypeStrList(Class[] types) {
+ StringBuffer sb = new StringBuffer();
+ for(int i=0; i<types.length; i++) {
+ sb.append(types[i]);
+ if(i<types.length) {
+ sb.append(", ");
+ }
+ }
+ return sb.toString();
+ }
+
+ protected final void shouldNotCallThis() {
+ throw new NativeWindowException("Should not call this");
+ }
+
+ public static String getThreadName() {
+ return Display.getThreadName();
+ }
+
+ public static String toHexString(int hex) {
+ return Display.toHexString(hex);
+ }
+
+ public static String toHexString(long hex) {
+ return Display.toHexString(hex);
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java
new file mode 100644
index 000000000..9b0ec6907
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTCanvas.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import com.jogamp.newt.Window;
+
+import java.awt.Canvas;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsConfiguration;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class AWTCanvas extends Canvas {
+ private GraphicsDevice device;
+ private GraphicsConfiguration chosen;
+ private AWTGraphicsConfiguration awtConfig;
+
+ private Capabilities capabilities;
+
+ private boolean displayConfigChanged=false;
+
+ public AWTCanvas(Capabilities capabilities) {
+ super();
+
+ if(null==capabilities) {
+ throw new NativeWindowException("Capabilities null");
+ }
+ this.capabilities=capabilities;
+ }
+
+ public AWTGraphicsConfiguration getAWTGraphicsConfiguration() {
+ return awtConfig;
+ }
+
+ public boolean hasDeviceChanged() {
+ boolean res = displayConfigChanged;
+ displayConfigChanged=false;
+ return res;
+ }
+
+ public void addNotify() {
+ super.addNotify();
+
+ disableBackgroundErase();
+
+ GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ if(null!=gc) {
+ device = gc.getDevice();
+ }
+
+ /*
+ * Save the chosen capabilities for use in getGraphicsConfiguration().
+ */
+ awtConfig = chooseGraphicsConfiguration(capabilities, device);
+ if(Window.DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Info: Created Config: "+awtConfig);
+ e.printStackTrace();
+ }
+ if(null!=awtConfig) {
+ // update ..
+ chosen = awtConfig.getGraphicsConfiguration();
+ }
+ if(null==awtConfig) {
+ throw new NativeWindowException("Error: AWTGraphicsConfiguration is null");
+ }
+ }
+
+ public void removeNotify() {
+ try {
+ dispose();
+ } finally {
+ super.removeNotify();
+ }
+ }
+
+ private void dispose() {
+ if(null != awtConfig) {
+ AbstractGraphicsDevice adevice = awtConfig.getNativeGraphicsConfiguration().getScreen().getDevice();
+ String adeviceMsg=null;
+ if(Window.DEBUG_IMPLEMENTATION) {
+ adeviceMsg = adevice.toString();
+ }
+ boolean closed = adevice.close();
+ if(Window.DEBUG_IMPLEMENTATION) {
+ System.err.println("AWTCanvas.dispose(): closed GraphicsDevice: "+adeviceMsg+", result: "+closed);
+ }
+ }
+ }
+
+ /**
+ * Overridden to choose a GraphicsConfiguration on a parent container's
+ * GraphicsDevice because both devices
+ */
+ public GraphicsConfiguration getGraphicsConfiguration() {
+ /*
+ * Workaround for problems with Xinerama and java.awt.Component.checkGD
+ * when adding to a container on a different graphics device than the
+ * one that this Canvas is associated with.
+ *
+ * GC will be null unless:
+ * - A native peer has assigned it. This means we have a native
+ * peer, and are already comitted to a graphics configuration.
+ * - This canvas has been added to a component hierarchy and has
+ * an ancestor with a non-null GC, but the native peer has not
+ * yet been created. This means we can still choose the GC on
+ * all platforms since the peer hasn't been created.
+ */
+ final GraphicsConfiguration gc = super.getGraphicsConfiguration();
+ /*
+ * chosen is only non-null on platforms where the GLDrawableFactory
+ * returns a non-null GraphicsConfiguration (in the GLCanvas
+ * constructor).
+ *
+ * if gc is from this Canvas' native peer then it should equal chosen,
+ * otherwise it is from an ancestor component that this Canvas is being
+ * added to, and we go into this block.
+ */
+ if (gc != null && chosen != null && !chosen.equals(gc)) {
+ /*
+ * Check for compatibility with gc. If they differ by only the
+ * device then return a new GCconfig with the super-class' GDevice
+ * (and presumably the same visual ID in Xinerama).
+ *
+ */
+ if (!chosen.getDevice().getIDstring().equals(gc.getDevice().getIDstring())) {
+ /*
+ * Here we select a GraphicsConfiguration on the alternate
+ * device that is presumably identical to the chosen
+ * configuration, but on the other device.
+ *
+ * Should really check to ensure that we select a configuration
+ * with the same X visual ID for Xinerama screens, otherwise the
+ * GLDrawable may have the wrong visual ID (I don't think this
+ * ever gets updated). May need to add a method to
+ * X11GLDrawableFactory to do this in a platform specific
+ * manner.
+ *
+ * However, on platforms where we can actually get into this
+ * block, both devices should have the same visual list, and the
+ * same configuration should be selected here.
+ */
+ AWTGraphicsConfiguration config = chooseGraphicsConfiguration((Capabilities)awtConfig.getRequestedCapabilities(), gc.getDevice());
+ final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null;
+ if(Window.DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
+ e.printStackTrace();
+ System.err.println("!!! Created Config (n): HAVE GC "+chosen);
+ System.err.println("!!! Created Config (n): THIS GC "+gc);
+ System.err.println("!!! Created Config (n): Choosen GC "+compatible);
+ System.err.println("!!! Created Config (n): HAVE CF "+awtConfig);
+ System.err.println("!!! Created Config (n): Choosen CF "+config);
+ System.err.println("!!! Created Config (n): EQUALS CAPS "+config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities()));
+ }
+
+ if (compatible != null) {
+ /*
+ * Save the new GC for equals test above, and to return to
+ * any outside callers of this method.
+ */
+ chosen = compatible;
+ if( !config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities())) {
+ displayConfigChanged=true;
+ }
+ awtConfig = config;
+ }
+ }
+
+ /*
+ * If a compatible GC was not found in the block above, this will
+ * return the GC that was selected in the constructor (and might
+ * cause an exception in Component.checkGD when adding to a
+ * container, but in this case that would be the desired behavior).
+ *
+ */
+ return chosen;
+ } else if (gc == null) {
+ /*
+ * The GC is null, which means we have no native peer, and are not
+ * part of a (realized) component hierarchy. So we return the
+ * desired visual that was selected in the constructor (possibly
+ * null).
+ */
+ return chosen;
+ }
+
+ /*
+ * Otherwise we have not explicitly selected a GC in the constructor, so
+ * just return what Canvas would have.
+ */
+ return gc;
+ }
+
+ private static AWTGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities,
+ GraphicsDevice device) {
+ AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device);
+ AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
+ GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capabilities,
+ null,
+ aScreen);
+ if (config == null) {
+ throw new NativeWindowException("Error: Couldn't fetch AWTGraphicsConfiguration");
+ }
+
+ return config;
+ }
+
+ // Disables the AWT's erasing of this Canvas's background on Windows
+ // in Java SE 6. This internal API is not available in previous
+ // releases, but the system property
+ // -Dsun.awt.noerasebackground=true can be specified to get similar
+ // results globally in previous releases.
+ private static boolean disableBackgroundEraseInitialized;
+ private static Method disableBackgroundEraseMethod;
+ private void disableBackgroundErase() {
+ if (!disableBackgroundEraseInitialized) {
+ try {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ Class clazz = getToolkit().getClass();
+ while (clazz != null && disableBackgroundEraseMethod == null) {
+ try {
+ disableBackgroundEraseMethod =
+ clazz.getDeclaredMethod("disableBackgroundErase",
+ new Class[] { Canvas.class });
+ disableBackgroundEraseMethod.setAccessible(true);
+ } catch (Exception e) {
+ clazz = clazz.getSuperclass();
+ }
+ }
+ } catch (Exception e) {
+ }
+ return null;
+ }
+ });
+ } catch (Exception e) {
+ }
+ disableBackgroundEraseInitialized = true;
+ }
+ if (disableBackgroundEraseMethod != null) {
+ try {
+ disableBackgroundEraseMethod.invoke(getToolkit(), new Object[] { this });
+ } catch (Exception e) {
+ // FIXME: workaround for 6504460 (incorrect backport of 6333613 in 5.0u10)
+ // throw new GLException(e);
+ }
+ }
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java
new file mode 100644
index 000000000..0199d6c72
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTDisplay.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import java.awt.event.*;
+import com.jogamp.newt.Display;
+import com.jogamp.newt.Window;
+import com.jogamp.newt.impl.DisplayImpl;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+import java.util.*;
+
+public class AWTDisplay extends DisplayImpl {
+ public AWTDisplay() {
+ }
+
+ protected void createNativeImpl() {
+ aDevice = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(null); // default
+ }
+
+ protected void setAWTGraphicsDevice(AWTGraphicsDevice d) {
+ aDevice = d;
+ }
+
+ protected void closeNativeImpl() { }
+
+ protected boolean shallRunOnEDT() {
+ return false;
+ }
+ protected void dispatchMessagesNative() { /* nop */ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
new file mode 100644
index 000000000..5e097fdc3
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTScreen.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import java.awt.DisplayMode;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+
+public class AWTScreen extends ScreenImpl {
+ public AWTScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new AWTGraphicsScreen((AWTGraphicsDevice)display.getGraphicsDevice());
+
+ DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode();
+ int w = mode.getWidth();
+ int h = mode.getHeight();
+ setScreenSize(w, h);
+ }
+
+ protected void setAWTGraphicsScreen(AWTGraphicsScreen s) {
+ aScreen = s;
+ }
+
+ // done by AWTWindow ..
+ protected void setScreenSize(int w, int h) {
+ super.setScreenSize(w, h);
+ }
+
+ protected void closeNativeImpl() { }
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
new file mode 100644
index 000000000..edd851451
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.awt;
+
+import com.jogamp.newt.event.awt.*;
+import com.jogamp.newt.util.EDTUtil;
+
+import java.awt.BorderLayout;
+import java.awt.Container;
+import java.awt.DisplayMode;
+import java.awt.EventQueue;
+import java.awt.Frame;
+import com.jogamp.newt.impl.WindowImpl;
+import java.awt.Insets;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.*;
+import javax.media.nativewindow.util.Point;
+
+/** An implementation of the Newt Window class built using the
+ AWT. This is provided for convenience of porting to platforms
+ supporting Java SE. */
+
+public class AWTWindow extends WindowImpl {
+
+ public AWTWindow() {
+ this(null);
+ }
+
+ public static Class[] getCustomConstructorArgumentTypes() {
+ return new Class[] { Container.class } ;
+ }
+
+ public AWTWindow(Container container) {
+ super();
+ title = "AWT NewtWindow";
+ this.container = container;
+ if(container instanceof Frame) {
+ frame = (Frame) container;
+ }
+ }
+
+ private boolean owningFrame;
+ private Container container = null;
+ private Frame frame = null; // same instance as container, just for impl. convenience
+ private AWTCanvas canvas;
+
+ protected void requestFocusImpl(boolean reparented) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ container.requestFocus();
+ }
+ });
+ }
+
+ protected void setTitleImpl(final String title) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ if (frame != null) {
+ frame.setTitle(title);
+ }
+ }
+ });
+ }
+
+ protected void createNativeImpl() {
+
+ if(0!=getParentWindowHandle()) {
+ throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
+ }
+
+ final AWTWindow awtWindow = this;
+
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ if(null==container) {
+ frame = new Frame();
+ container = frame;
+ owningFrame=true;
+ } else {
+ owningFrame=false;
+ width = container.getWidth();
+ height = container.getHeight();
+ x = container.getX();
+ y = container.getY();
+ }
+ if(null!=frame) {
+ frame.setTitle(getTitle());
+ }
+ container.setLayout(new BorderLayout());
+ canvas = new AWTCanvas(caps);
+
+ addWindowListener(new LocalWindowListener());
+
+ new AWTMouseAdapter(awtWindow).addTo(canvas); // fwd all AWT Mouse events to here
+ new AWTKeyAdapter(awtWindow).addTo(canvas); // fwd all AWT Key events to here
+
+ // canvas.addComponentListener(listener);
+ container.add(canvas, BorderLayout.CENTER);
+ container.setSize(width, height);
+ container.setLocation(x, y);
+ new AWTWindowAdapter(awtWindow).addTo(container); // fwd all AWT Window events to here
+
+ if(null!=frame) {
+ frame.setUndecorated(undecorated||fullscreen);
+ }
+ }
+ });
+ setWindowHandle(1); // just a marker ..
+ }
+
+ protected void closeNativeImpl() {
+ setWindowHandle(0); // just a marker ..
+ if(null!=container) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ container.setVisible(false);
+ container.remove(canvas);
+ container.setEnabled(false);
+ canvas.setEnabled(false);
+ }
+ });
+ }
+ if(owningFrame && null!=frame) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ frame.dispose();
+ owningFrame=false;
+ frame = null;
+ }
+ });
+ }
+ }
+
+ public boolean hasDeviceChanged() {
+ boolean res = canvas.hasDeviceChanged();
+ if(res) {
+ config = canvas.getAWTGraphicsConfiguration();
+ if (config == null) {
+ throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this);
+ }
+ updateDeviceData();
+ }
+ return res;
+ }
+
+ protected void setVisibleImpl(final boolean visible, int x, int y, int width, int height) {
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ container.setVisible(visible);
+ }
+ });
+
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ config = canvas.getAWTGraphicsConfiguration();
+
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ updateDeviceData();
+ visibleChanged(visible);
+ }
+
+ private void updateDeviceData() {
+ // propagate new info ..
+ ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)config.getScreen());
+ ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)config.getScreen().getDevice());
+
+ DisplayMode mode = ((AWTGraphicsDevice)config.getScreen().getDevice()).getGraphicsDevice().getDisplayMode();
+ int w = mode.getWidth();
+ int h = mode.getHeight();
+ ((AWTScreen)getScreen()).setScreenSize(w, h);
+ }
+
+ public javax.media.nativewindow.util.Insets getInsets() {
+ final int insets[] = new int[] { 0, 0, 0, 0 };
+ runOnEDT(true, new Runnable() {
+ public void run() {
+ Insets contInsets = container.getInsets();
+ insets[0] = contInsets.top;
+ insets[1] = contInsets.left;
+ insets[2] = contInsets.bottom;
+ insets[3] = contInsets.right;
+ }
+ });
+ return new javax.media.nativewindow.util.Insets(insets[0],insets[1],insets[2],insets[3]);
+ }
+
+ protected boolean reconfigureWindowImpl(final int x, final int y, final int width, final int height, final boolean parentChange, final int fullScreenChange, final int decorationChange) {
+ /** An AWT event on setSize() would bring us in a deadlock situation, hence invokeLater() */
+ runOnEDT(false, new Runnable() {
+ public void run() {
+ if(decorationChange!=0 && null!=frame) {
+ if(!container.isDisplayable()) {
+ frame.setUndecorated(isUndecorated());
+ } else {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("AWTWindow can't undecorate already created frame");
+ }
+ }
+ }
+ int _x=(x>=0)?x:AWTWindow.this.x;
+ int _y=(x>=0)?y:AWTWindow.this.y;
+ int _w=(width>0)?width:AWTWindow.this.width;
+ int _h=(height>0)?height:AWTWindow.this.height;
+
+ container.setLocation(_x, _y);
+ Insets insets = container.getInsets();
+ container.setSize(_w + insets.left + insets.right,
+ _h + insets.top + insets.bottom);
+ }
+ });
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ java.awt.Point ap = canvas.getLocationOnScreen();
+ ap.translate(x, y);
+ return new Point((int)(ap.getX()+0.5),(int)(ap.getY()+0.5));
+ }
+
+ public Object getWrappedWindow() {
+ return canvas;
+ }
+
+ private void runOnEDT(boolean wait, Runnable r) {
+ EDTUtil edtUtil = getScreen().getDisplay().getEDTUtil();
+ if ( ( null != edtUtil && edtUtil.isCurrentThreadEDT() ) || EventQueue.isDispatchThread() ) {
+ r.run();
+ } else {
+ try {
+ if(wait) {
+ EventQueue.invokeAndWait(r);
+ } else {
+ EventQueue.invokeLater(r);
+ }
+ } catch (Exception e) {
+ throw new NativeWindowException(e);
+ }
+ }
+ }
+
+ class LocalWindowListener extends com.jogamp.newt.event.WindowAdapter {
+ public void windowMoved(com.jogamp.newt.event.WindowEvent e) {
+ if(null!=container) {
+ x = container.getX();
+ y = container.getY();
+ }
+ }
+ public void windowResized(com.jogamp.newt.event.WindowEvent e) {
+ if(null!=canvas) {
+ width = canvas.getWidth();
+ height = canvas.getHeight();
+ }
+ }
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java b/src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java
new file mode 100644
index 000000000..1b4bce4b0
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/event/NEWTEventTask.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
+ */
+
+package com.jogamp.newt.impl.event;
+
+import com.jogamp.newt.event.NEWTEvent;
+
+/**
+ * Helper class to provide a NEWTEvent queue implementation with a NEWTEvent wrapper
+ * which notifies after sending the event for the <code>invokeAndWait()</code> semantics.
+ */
+public class NEWTEventTask {
+ NEWTEvent event;
+ Object notifyObject;
+
+ public NEWTEventTask(NEWTEvent event, Object notifyObject) {
+ this.event = event ;
+ this.notifyObject = notifyObject ;
+ }
+
+ public NEWTEvent get() { return event; }
+
+ public void notifyIssuer() {
+ if(null != notifyObject) {
+ synchronized (notifyObject) {
+ notifyObject.notifyAll();
+ }
+ }
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java
new file mode 100644
index 000000000..0bd4c3b5d
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Display.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.intel.gdl;
+
+import com.jogamp.newt.impl.*;
+import javax.media.nativewindow.*;
+
+public class Display extends com.jogamp.newt.impl.DisplayImpl {
+ static int initCounter = 0;
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!Screen.initIDs()) {
+ throw new NativeWindowException("Failed to initialize GDL Screen jmethodIDs");
+ }
+ if (!Window.initIDs()) {
+ throw new NativeWindowException("Failed to initialize GDL Window jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public Display() {
+ }
+
+ protected void createNativeImpl() {
+ synchronized(Display.class) {
+ if(0==initCounter) {
+ displayHandle = CreateDisplay();
+ if(0==displayHandle) {
+ throw new NativeWindowException("Couldn't initialize GDL Display");
+ }
+ }
+ initCounter++;
+ }
+ aDevice = new DefaultGraphicsDevice(NativeWindowFactory.TYPE_DEFAULT, displayHandle);
+ }
+
+ protected void closeNativeImpl() {
+ if(0==displayHandle) {
+ throw new NativeWindowException("displayHandle null; initCnt "+initCounter);
+ }
+ synchronized(Display.class) {
+ if(initCounter>0) {
+ initCounter--;
+ if(0==initCounter) {
+ DestroyDisplay(displayHandle);
+ }
+ }
+ }
+ }
+
+ protected void dispatchMessagesNative() {
+ if(0!=displayHandle) {
+ DispatchMessages(displayHandle, focusedWindow);
+ }
+ }
+
+ protected void setFocus(Window focus) {
+ focusedWindow = focus;
+ }
+
+ private long displayHandle = 0;
+ private Window focusedWindow = null;
+ private native long CreateDisplay();
+ private native void DestroyDisplay(long displayHandle);
+ private native void DispatchMessages(long displayHandle, Window focusedWindow);
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
new file mode 100644
index 000000000..4abee350f
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Screen.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.intel.gdl;
+
+import com.jogamp.newt.impl.*;
+import javax.media.nativewindow.*;
+
+public class Screen extends com.jogamp.newt.impl.ScreenImpl {
+
+ static {
+ Display.initSingleton();
+ }
+
+ public Screen() {
+ }
+
+ protected void createNativeImpl() {
+ AbstractGraphicsDevice adevice = getDisplay().getGraphicsDevice();
+ GetScreenInfo(adevice.getHandle(), screen_idx);
+ aScreen = new DefaultGraphicsScreen(adevice, screen_idx);
+ }
+
+ protected void closeNativeImpl() { }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native void GetScreenInfo(long displayHandle, int screen_idx);
+
+ // called by GetScreenInfo() ..
+ private void screenCreated(int width, int height) {
+ setScreenSize(width, height);
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
new file mode 100644
index 000000000..749be8506
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.intel.gdl;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Point;
+
+public class Window extends com.jogamp.newt.impl.WindowImpl {
+ static {
+ Display.initSingleton();
+ }
+
+ public Window() {
+ }
+
+ static long nextWindowHandle = 1;
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new NativeWindowException("GDL Window does not support window parenting");
+ }
+ AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
+
+ config = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(caps, null, aScreen);
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ synchronized(Window.class) {
+ setWindowHandle(nextWindowHandle++); // just a marker
+
+ surfaceHandle = CreateSurface(aDevice.getHandle(), getScreen().getWidth(), getScreen().getHeight(), x, y, width, height);
+ if (surfaceHandle == 0) {
+ throw new NativeWindowException("Error creating window");
+ }
+ }
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=surfaceHandle) {
+ synchronized(Window.class) {
+ CloseSurface(getDisplayHandle(), surfaceHandle);
+ }
+ surfaceHandle = 0;
+ ((Display)getScreen().getDisplay()).setFocus(null);
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ if(visible) {
+ ((Display)getScreen().getDisplay()).setFocus(this);
+ }
+ this.visibleChanged(visible);
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
+ Screen screen = (Screen) getScreen();
+
+ int _x=(x>=0)?x:this.x;
+ int _y=(x>=0)?y:this.y;
+ int _w=(width>0)?width:this.width;
+ int _h=(height>0)?height:this.height;
+
+ if(_w>screen.getWidth()) {
+ _w=screen.getWidth();
+ }
+ if(_h>screen.getHeight()) {
+ _h=screen.getHeight();
+ }
+ if((_x+_w)>screen.getWidth()) {
+ _x=screen.getWidth()-_w;
+ }
+ if((_y+_h)>screen.getHeight()) {
+ _y=screen.getHeight()-_h;
+ }
+
+ if(0!=surfaceHandle) {
+ SetBounds0(surfaceHandle, getScreen().getWidth(), getScreen().getHeight(), _x, _y, _w, _h);
+ }
+
+ return true;
+ }
+
+ protected void requestFocusImpl(boolean reparented) {
+ ((Display)getScreen().getDisplay()).setFocus(this);
+ }
+
+ public final long getSurfaceHandle() {
+ return surfaceHandle;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native long CreateSurface(long displayHandle, int scrn_width, int scrn_height, int x, int y, int width, int height);
+ private native void CloseSurface(long displayHandle, long surfaceHandle);
+ private native void SetBounds0(long surfaceHandle, int scrn_width, int scrn_height, int x, int y, int width, int height);
+
+ private void updateBounds(int x, int y, int width, int height) {
+ this.x = x;
+ this.y = y;
+ this.width = width;
+ this.height = height;
+ }
+
+ private long surfaceHandle;
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java
new file mode 100644
index 000000000..dc45f7479
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.macosx;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.macosx.*;
+import com.jogamp.common.util.ReflectionUtil;
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.*;
+import com.jogamp.newt.util.EDTUtil;
+import com.jogamp.newt.util.MainThread;
+
+public class MacDisplay extends DisplayImpl {
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if(!initNSApplication0()) {
+ throw new NativeWindowException("Failed to initialize native Application hook");
+ }
+ if(!MacWindow.initIDs0()) {
+ throw new NativeWindowException("Failed to initialize jmethodIDs");
+ }
+ if(DEBUG) {
+ System.err.println("MacDisplay.init App and IDs OK "+Thread.currentThread().getName());
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+ public MacDisplay() {
+ }
+
+ protected void dispatchMessagesNative() {
+ dispatchMessages0();
+ }
+
+ protected void createNativeImpl() {
+ aDevice = new MacOSXGraphicsDevice();
+ }
+
+ protected void closeNativeImpl() { }
+
+ protected void createEDTUtil() {
+ if(NewtFactory.useEDT()) {
+ final Display f_dpy = this;
+ MainThread.addPumpMessage(this,
+ new Runnable() {
+ public void run() {
+ if(null!=f_dpy.getGraphicsDevice()) {
+ f_dpy.dispatchMessages();
+ } } } );
+ edtUtil = MainThread.getSingleton();
+ edtUtil.start();
+ }
+ }
+
+ protected void releaseEDTUtil() {
+ if(null!=edtUtil) {
+ MainThread.removePumpMessage(this);
+ edtUtil.waitUntilStopped();
+ edtUtil=null;
+ }
+ }
+
+ private static native boolean initNSApplication0();
+ protected native void dispatchMessages0();
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
new file mode 100644
index 000000000..f0c388366
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacScreen.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.macosx;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import javax.media.nativewindow.*;
+
+public class MacScreen extends ScreenImpl {
+ static {
+ MacDisplay.initSingleton();
+ }
+
+ public MacScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
+ }
+
+ protected void closeNativeImpl() { }
+
+ private static native int getWidthImpl0(int scrn_idx);
+ private static native int getHeightImpl0(int scrn_idx);
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
new file mode 100644
index 000000000..59b41c2aa
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.macosx;
+
+import javax.media.nativewindow.*;
+import com.jogamp.common.util.locks.RecursiveLock;
+
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.impl.*;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
+
+public class MacWindow extends WindowImpl {
+
+ // Window styles
+ private static final int NSBorderlessWindowMask = 0;
+ private static final int NSTitledWindowMask = 1 << 0;
+ private static final int NSClosableWindowMask = 1 << 1;
+ private static final int NSMiniaturizableWindowMask = 1 << 2;
+ private static final int NSResizableWindowMask = 1 << 3;
+
+ // Window backing store types
+ private static final int NSBackingStoreRetained = 0;
+ private static final int NSBackingStoreNonretained = 1;
+ private static final int NSBackingStoreBuffered = 2;
+
+ // Key constants handled differently on Mac OS X than other platforms
+ private static final int NSUpArrowFunctionKey = 0xF700;
+ private static final int NSDownArrowFunctionKey = 0xF701;
+ private static final int NSLeftArrowFunctionKey = 0xF702;
+ private static final int NSRightArrowFunctionKey = 0xF703;
+ private static final int NSF1FunctionKey = 0xF704;
+ private static final int NSF2FunctionKey = 0xF705;
+ private static final int NSF3FunctionKey = 0xF706;
+ private static final int NSF4FunctionKey = 0xF707;
+ private static final int NSF5FunctionKey = 0xF708;
+ private static final int NSF6FunctionKey = 0xF709;
+ private static final int NSF7FunctionKey = 0xF70A;
+ private static final int NSF8FunctionKey = 0xF70B;
+ private static final int NSF9FunctionKey = 0xF70C;
+ private static final int NSF10FunctionKey = 0xF70D;
+ private static final int NSF11FunctionKey = 0xF70E;
+ private static final int NSF12FunctionKey = 0xF70F;
+ private static final int NSF13FunctionKey = 0xF710;
+ private static final int NSF14FunctionKey = 0xF711;
+ private static final int NSF15FunctionKey = 0xF712;
+ private static final int NSF16FunctionKey = 0xF713;
+ private static final int NSF17FunctionKey = 0xF714;
+ private static final int NSF18FunctionKey = 0xF715;
+ private static final int NSF19FunctionKey = 0xF716;
+ private static final int NSF20FunctionKey = 0xF717;
+ private static final int NSF21FunctionKey = 0xF718;
+ private static final int NSF22FunctionKey = 0xF719;
+ private static final int NSF23FunctionKey = 0xF71A;
+ private static final int NSF24FunctionKey = 0xF71B;
+ private static final int NSF25FunctionKey = 0xF71C;
+ private static final int NSF26FunctionKey = 0xF71D;
+ private static final int NSF27FunctionKey = 0xF71E;
+ private static final int NSF28FunctionKey = 0xF71F;
+ private static final int NSF29FunctionKey = 0xF720;
+ private static final int NSF30FunctionKey = 0xF721;
+ private static final int NSF31FunctionKey = 0xF722;
+ private static final int NSF32FunctionKey = 0xF723;
+ private static final int NSF33FunctionKey = 0xF724;
+ private static final int NSF34FunctionKey = 0xF725;
+ private static final int NSF35FunctionKey = 0xF726;
+ private static final int NSInsertFunctionKey = 0xF727;
+ private static final int NSDeleteFunctionKey = 0xF728;
+ private static final int NSHomeFunctionKey = 0xF729;
+ private static final int NSBeginFunctionKey = 0xF72A;
+ private static final int NSEndFunctionKey = 0xF72B;
+ private static final int NSPageUpFunctionKey = 0xF72C;
+ private static final int NSPageDownFunctionKey = 0xF72D;
+ private static final int NSPrintScreenFunctionKey = 0xF72E;
+ private static final int NSScrollLockFunctionKey = 0xF72F;
+ private static final int NSPauseFunctionKey = 0xF730;
+ private static final int NSSysReqFunctionKey = 0xF731;
+ private static final int NSBreakFunctionKey = 0xF732;
+ private static final int NSResetFunctionKey = 0xF733;
+ private static final int NSStopFunctionKey = 0xF734;
+ private static final int NSMenuFunctionKey = 0xF735;
+ private static final int NSUserFunctionKey = 0xF736;
+ private static final int NSSystemFunctionKey = 0xF737;
+ private static final int NSPrintFunctionKey = 0xF738;
+ private static final int NSClearLineFunctionKey = 0xF739;
+ private static final int NSClearDisplayFunctionKey = 0xF73A;
+ private static final int NSInsertLineFunctionKey = 0xF73B;
+ private static final int NSDeleteLineFunctionKey = 0xF73C;
+ private static final int NSInsertCharFunctionKey = 0xF73D;
+ private static final int NSDeleteCharFunctionKey = 0xF73E;
+ private static final int NSPrevFunctionKey = 0xF73F;
+ private static final int NSNextFunctionKey = 0xF740;
+ private static final int NSSelectFunctionKey = 0xF741;
+ private static final int NSExecuteFunctionKey = 0xF742;
+ private static final int NSUndoFunctionKey = 0xF743;
+ private static final int NSRedoFunctionKey = 0xF744;
+ private static final int NSFindFunctionKey = 0xF745;
+ private static final int NSHelpFunctionKey = 0xF746;
+ private static final int NSModeSwitchFunctionKey = 0xF747;
+
+ private volatile long surfaceHandle;
+
+ // non fullscreen dimensions ..
+ private final Insets insets = new Insets(0,0,0,0);
+
+ static {
+ MacDisplay.initSingleton();
+ }
+
+ public MacWindow() {
+ }
+
+ protected void createNativeImpl() {
+ config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ }
+
+ protected void closeNativeImpl() {
+ nsViewLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
+ if (getWindowHandle() != 0) {
+ close0(getWindowHandle());
+ }
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNative failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ } finally {
+ setWindowHandle(0);
+ nsViewLock.unlock();
+ }
+ windowDestroyed(); // No OSX hook for DidClose, so do it here
+ }
+
+ public final long getSurfaceHandle() {
+ return surfaceHandle;
+ }
+
+ public Insets getInsets() {
+ // in order to properly calculate insets we need the window to be
+ // created
+ nsViewLock.lock();
+ try {
+ createWindow(false, getX(), getY(), getWidth(), getHeight(), isFullscreen());
+ return (Insets) insets.clone();
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ private RecursiveLock nsViewLock = new RecursiveLock();
+
+ protected int lockSurfaceImpl() {
+ nsViewLock.lock();
+ return LOCK_SUCCESS;
+ }
+
+ protected void unlockSurfaceImpl() {
+ nsViewLock.unlock();
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ nsViewLock.lock();
+ try {
+ if (visible) {
+ createWindow(false, x, y, width, height, isFullscreen());
+ if (getWindowHandle() != 0) {
+ makeKeyAndOrderFront0(getWindowHandle());
+ }
+ } else {
+ if (getWindowHandle() != 0) {
+ orderOut0(getWindowHandle());
+ }
+ }
+ visibleChanged(visible);
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ protected void setTitleImpl(final String title) {
+ // FIXME: move nsViewLock up to window lock
+ nsViewLock.lock();
+ try {
+ setTitle0(getWindowHandle(), title);
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ protected void requestFocusImpl(boolean reparented) {
+ // FIXME: move nsViewLock up to window lock
+ nsViewLock.lock();
+ try {
+ makeKey0(getWindowHandle());
+ } finally {
+ nsViewLock.unlock();
+ }
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height, boolean parentChange, int fullScreenChange, int decorationChange) {
+ nsViewLock.lock();
+ try {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ System.err.println("MacWindow reconfig: parentChange "+parentChange+", fullScreenChange "+fullScreenChange+", decorationChange "+decorationChange+" "+x+"/"+y+" "+width+"x"+height);
+ }
+ int _x=(x>=0)?x:this.x;
+ int _y=(x>=0)?y:this.y;
+ int _w=(width>0)?width:this.width;
+ int _h=(height>0)?height:this.height;
+
+ if(decorationChange!=0 || parentChange || fullScreenChange!=0) {
+ createWindow(true, _x, _y, _w, _h, fullScreenChange>0);
+ if (getWindowHandle() != 0) {
+ makeKeyAndOrderFront0(getWindowHandle());
+ }
+ } else {
+ if(x>=0 || y>=0) {
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), _x, _y);
+ }
+ if(width>0 || height>0) {
+ setContentSize0(getWindowHandle(), _w, _h);
+ }
+ }
+ } finally {
+ nsViewLock.unlock();
+ }
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return null;
+ }
+
+ private void insetsChanged(int left, int top, int right, int bottom) {
+ if (DEBUG_IMPLEMENTATION) {
+ System.err.println(Thread.currentThread().getName()+
+ " Insets changed to " + left + ", " + top + ", " + right + ", " + bottom);
+ }
+ if (left != -1 && top != -1 && right != -1 && bottom != -1) {
+ insets.left = left;
+ insets.top = top;
+ insets.right = right;
+ insets.bottom = bottom;
+ }
+ }
+
+ private char convertKeyChar(char keyChar) {
+ if (keyChar == '\r') {
+ // Turn these into \n
+ return '\n';
+ }
+
+ if (keyChar >= NSUpArrowFunctionKey && keyChar <= NSModeSwitchFunctionKey) {
+ switch (keyChar) {
+ case NSUpArrowFunctionKey: return KeyEvent.VK_UP;
+ case NSDownArrowFunctionKey: return KeyEvent.VK_DOWN;
+ case NSLeftArrowFunctionKey: return KeyEvent.VK_LEFT;
+ case NSRightArrowFunctionKey: return KeyEvent.VK_RIGHT;
+ case NSF1FunctionKey: return KeyEvent.VK_F1;
+ case NSF2FunctionKey: return KeyEvent.VK_F2;
+ case NSF3FunctionKey: return KeyEvent.VK_F3;
+ case NSF4FunctionKey: return KeyEvent.VK_F4;
+ case NSF5FunctionKey: return KeyEvent.VK_F5;
+ case NSF6FunctionKey: return KeyEvent.VK_F6;
+ case NSF7FunctionKey: return KeyEvent.VK_F7;
+ case NSF8FunctionKey: return KeyEvent.VK_F8;
+ case NSF9FunctionKey: return KeyEvent.VK_F9;
+ case NSF10FunctionKey: return KeyEvent.VK_F10;
+ case NSF11FunctionKey: return KeyEvent.VK_F11;
+ case NSF12FunctionKey: return KeyEvent.VK_F12;
+ case NSF13FunctionKey: return KeyEvent.VK_F13;
+ case NSF14FunctionKey: return KeyEvent.VK_F14;
+ case NSF15FunctionKey: return KeyEvent.VK_F15;
+ case NSF16FunctionKey: return KeyEvent.VK_F16;
+ case NSF17FunctionKey: return KeyEvent.VK_F17;
+ case NSF18FunctionKey: return KeyEvent.VK_F18;
+ case NSF19FunctionKey: return KeyEvent.VK_F19;
+ case NSF20FunctionKey: return KeyEvent.VK_F20;
+ case NSF21FunctionKey: return KeyEvent.VK_F21;
+ case NSF22FunctionKey: return KeyEvent.VK_F22;
+ case NSF23FunctionKey: return KeyEvent.VK_F23;
+ case NSF24FunctionKey: return KeyEvent.VK_F24;
+ case NSInsertFunctionKey: return KeyEvent.VK_INSERT;
+ case NSDeleteFunctionKey: return KeyEvent.VK_DELETE;
+ case NSHomeFunctionKey: return KeyEvent.VK_HOME;
+ case NSBeginFunctionKey: return KeyEvent.VK_BEGIN;
+ case NSEndFunctionKey: return KeyEvent.VK_END;
+ case NSPageUpFunctionKey: return KeyEvent.VK_PAGE_UP;
+ case NSPageDownFunctionKey: return KeyEvent.VK_PAGE_DOWN;
+ case NSPrintScreenFunctionKey: return KeyEvent.VK_PRINTSCREEN;
+ case NSScrollLockFunctionKey: return KeyEvent.VK_SCROLL_LOCK;
+ case NSPauseFunctionKey: return KeyEvent.VK_PAUSE;
+ // Not handled:
+ // NSSysReqFunctionKey
+ // NSBreakFunctionKey
+ // NSResetFunctionKey
+ case NSStopFunctionKey: return KeyEvent.VK_STOP;
+ // Not handled:
+ // NSMenuFunctionKey
+ // NSUserFunctionKey
+ // NSSystemFunctionKey
+ // NSPrintFunctionKey
+ // NSClearLineFunctionKey
+ // NSClearDisplayFunctionKey
+ // NSInsertLineFunctionKey
+ // NSDeleteLineFunctionKey
+ // NSInsertCharFunctionKey
+ // NSDeleteCharFunctionKey
+ // NSPrevFunctionKey
+ // NSNextFunctionKey
+ // NSSelectFunctionKey
+ // NSExecuteFunctionKey
+ // NSUndoFunctionKey
+ // NSRedoFunctionKey
+ // NSFindFunctionKey
+ // NSHelpFunctionKey
+ // NSModeSwitchFunctionKey
+ default: break;
+ }
+ }
+
+ // NSEvent's charactersIgnoringModifiers doesn't ignore the shift key
+ if (keyChar >= 'a' && keyChar <= 'z') {
+ return Character.toUpperCase(keyChar);
+ }
+
+ return keyChar;
+ }
+
+ public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ int key = convertKeyChar(keyChar);
+ if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName());
+ // Note that we send the key char for the key code on this
+ // platform -- we do not get any useful key codes out of the system
+ super.enqueueKeyEvent(wait, eventType, modifiers, key, keyChar);
+ }
+
+ private void createWindow(final boolean recreate, final int x, final int y, final int width, final int height, final boolean fullscreen) {
+
+ if(0!=getWindowHandle() && !recreate) {
+ return;
+ }
+
+ try {
+ //runOnEDTIfAvail(true, new Runnable() {
+ // public void run() {
+ if(0!=getWindowHandle()) {
+ // save the view .. close the window
+ surfaceHandle = changeContentView0(getParentWindowHandle(), getWindowHandle(), 0);
+ if(recreate && 0==surfaceHandle) {
+ throw new NativeWindowException("Internal Error - recreate, window but no view");
+ }
+ close0(getWindowHandle());
+ setWindowHandle(0);
+ } else {
+ surfaceHandle = 0;
+ }
+ setWindowHandle(createWindow0(getParentWindowHandle(),
+ x, y, width, height, fullscreen,
+ (isUndecorated() ?
+ NSBorderlessWindowMask :
+ NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
+ NSBackingStoreBuffered,
+ getScreen().getIndex(), surfaceHandle));
+ if (getWindowHandle() == 0) {
+ throw new NativeWindowException("Could create native window "+Thread.currentThread().getName()+" "+this);
+ }
+ surfaceHandle = contentView0(getWindowHandle());
+ setTitle0(getWindowHandle(), getTitle());
+ // don't make the window visible on window creation
+ // makeKeyAndOrderFront0(windowHandle);
+ // } } );
+ } catch (Exception ie) {
+ ie.printStackTrace();
+ }
+
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_MOVED);
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_RESIZED);
+ enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
+ }
+
+ protected static native boolean initIDs0();
+ private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h,
+ boolean fullscreen, int windowStyle,
+ int backingStoreType,
+ int screen_idx, long view);
+ private native void makeKeyAndOrderFront0(long window);
+ private native void makeKey0(long window);
+ private native void orderOut0(long window);
+ private native void close0(long window);
+ private native void setTitle0(long window, String title);
+ private native long contentView0(long window);
+ private native long changeContentView0(long parentWindowHandle, long window, long view);
+ private native void setContentSize0(long window, int w, int h);
+ private native void setFrameTopLeftPoint0(long parentWindowHandle, long window, int x, int y);
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java
new file mode 100644
index 000000000..18d058a9c
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Display.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.broadcom.egl;
+
+import com.jogamp.newt.impl.*;
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+
+public class Display extends com.jogamp.newt.impl.DisplayImpl {
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!Window.initIDs()) {
+ throw new NativeWindowException("Failed to initialize BCEGL Window jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public Display() {
+ }
+
+ protected void createNativeImpl() {
+ long handle = CreateDisplay(Screen.fixedWidth, Screen.fixedHeight);
+ if (handle == EGL.EGL_NO_DISPLAY) {
+ throw new NativeWindowException("BC EGL CreateDisplay failed");
+ }
+ aDevice = new EGLGraphicsDevice(handle);
+ }
+
+ protected void closeNativeImpl() {
+ if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
+ DestroyDisplay(aDevice.getHandle());
+ }
+ }
+
+ protected void dispatchMessagesNative() {
+ // n/a .. DispatchMessages();
+ }
+
+ private native long CreateDisplay(int width, int height);
+ private native void DestroyDisplay(long dpy);
+ private native void DispatchMessages();
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
new file mode 100644
index 000000000..144fe5e83
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Screen.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.broadcom.egl;
+
+import javax.media.nativewindow.*;
+
+public class Screen extends com.jogamp.newt.impl.ScreenImpl {
+
+ static {
+ Display.initSingleton();
+ }
+
+
+ public Screen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(fixedWidth, fixedHeight);
+ }
+
+ protected void closeNativeImpl() { }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ static final int fixedWidth = 1920;
+ static final int fixedHeight = 1080;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
new file mode 100644
index 000000000..ad903731b
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.broadcom.egl;
+
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.GLCapabilities;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Point;
+
+public class Window extends com.jogamp.newt.impl.WindowImpl {
+ static {
+ Display.initSingleton();
+ }
+
+ public Window() {
+ }
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new RuntimeException("Window parenting not supported (yet)");
+ }
+ // query a good configuration .. even thought we drop this one
+ // and reuse the EGLUtil choosen one later.
+ config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ setSizeImpl(getScreen().getWidth(), getScreen().getHeight());
+
+ setWindowHandle(realizeWindow(true, width, height));
+ if (0 == getWindowHandle()) {
+ throw new NativeWindowException("Error native Window Handle is null");
+ }
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=windowHandleClose) {
+ CloseWindow(getDisplayHandle(), windowHandleClose);
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ visibleChanged(visible);
+ }
+
+ protected void requestFocusImpl(boolean reparented) { }
+
+ protected void setSizeImpl(int width, int height) {
+ if(0!=getWindowHandle()) {
+ // n/a in BroadcomEGL
+ System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window");
+ } else {
+ this.width = width;
+ this.height = height;
+ }
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ if(0!=getWindowHandle()) {
+ if(0!=fullScreenChange) {
+ if( fullScreenChange > 0 ) {
+ // n/a in BroadcomEGL
+ System.err.println("setFullscreen n/a in BroadcomEGL");
+ return false;
+ }
+ }
+ }
+ if(width>0 || height>0) {
+ if(0!=getWindowHandle()) {
+ // n/a in BroadcomEGL
+ System.err.println("BCEGL Window.setSizeImpl n/a in BroadcomEGL with realized window");
+ } else {
+ this.width=(width>0)?width:this.width;
+ this.height=(height>0)?height:this.height;
+ }
+ }
+ if(x>=0 || y>=0) {
+ System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL");
+ }
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+
+
+ public boolean surfaceSwap() {
+ SwapWindow(getDisplayHandle(), getWindowHandle());
+ return true;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native long CreateWindow(long eglDisplayHandle, boolean chromaKey, int width, int height);
+ private native void CloseWindow(long eglDisplayHandle, long eglWindowHandle);
+ private native void SwapWindow(long eglDisplayHandle, long eglWindowHandle);
+
+
+ private long realizeWindow(boolean chromaKey, int width, int height) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("BCEGL Window.realizeWindow() with: chroma "+chromaKey+", "+width+"x"+height+", "+config);
+ }
+ long handle = CreateWindow(getDisplayHandle(), chromaKey, width, height);
+ if (0 == handle) {
+ throw new NativeWindowException("Error native Window Handle is null");
+ }
+ windowHandleClose = handle;
+ return handle;
+ }
+
+ private void windowCreated(int cfgID, int width, int height) {
+ this.width = width;
+ this.height = height;
+ GLCapabilities capsReq = (GLCapabilities) config.getRequestedCapabilities();
+ config = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID);
+ if (config == null) {
+ throw new NativeWindowException("Error creating EGLGraphicsConfiguration from id: "+cfgID+", "+this);
+ }
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("BCEGL Window.windowCreated(): "+toHexString(cfgID)+", "+width+"x"+height+", "+config);
+ }
+ }
+
+ private long windowHandleClose;
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java
new file mode 100644
index 000000000..eab1816da
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDDisplay.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.kd;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.*;
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.egl.*;
+
+public class KDDisplay extends DisplayImpl {
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!KDWindow.initIDs()) {
+ throw new NativeWindowException("Failed to initialize KDWindow jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public KDDisplay() {
+ }
+
+ protected void createNativeImpl() {
+ // FIXME: map name to EGL_*_DISPLAY
+ long handle = EGL.eglGetDisplay(EGL.EGL_DEFAULT_DISPLAY);
+ if (handle == EGL.EGL_NO_DISPLAY) {
+ throw new NativeWindowException("eglGetDisplay failed");
+ }
+ if (!EGL.eglInitialize(handle, null, null)) {
+ throw new NativeWindowException("eglInitialize failed");
+ }
+ aDevice = new EGLGraphicsDevice(handle);
+ }
+
+ protected void closeNativeImpl() {
+ if (aDevice.getHandle() != EGL.EGL_NO_DISPLAY) {
+ EGL.eglTerminate(aDevice.getHandle());
+ }
+ }
+
+ protected void dispatchMessagesNative() {
+ DispatchMessages();
+ }
+
+ private native void DispatchMessages();
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
new file mode 100644
index 000000000..1a73d0e5d
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDScreen.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.kd;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import javax.media.nativewindow.*;
+
+public class KDScreen extends ScreenImpl {
+ static {
+ KDDisplay.initSingleton();
+ }
+
+ public KDScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ }
+
+ protected void closeNativeImpl() { }
+
+ // elevate access to this package ..
+ protected void setScreenSize(int w, int h) {
+ super.setScreenSize(w, h);
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
new file mode 100644
index 000000000..f0bc8587b
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.opengl.kd;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.impl.*;
+import com.jogamp.opengl.impl.egl.*;
+import javax.media.nativewindow.*;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLProfile;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.util.Point;
+
+public class KDWindow extends WindowImpl {
+ private static final String WINDOW_CLASS_NAME = "NewtWindow";
+
+ static {
+ KDDisplay.initSingleton();
+ }
+
+ public KDWindow() {
+ }
+
+ protected void createNativeImpl() {
+ if(0!=getParentWindowHandle()) {
+ throw new RuntimeException("Window parenting not supported (yet)");
+ }
+ config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+
+ GLCapabilities eglCaps = (GLCapabilities)config.getChosenCapabilities();
+ int[] eglAttribs = EGLGraphicsConfiguration.GLCapabilities2AttribList(eglCaps);
+
+ eglWindowHandle = CreateWindow(getDisplayHandle(), eglAttribs);
+ if (eglWindowHandle == 0) {
+ throw new NativeWindowException("Error creating egl window: "+config);
+ }
+ setVisible0(eglWindowHandle, false);
+ setWindowHandle(RealizeWindow(eglWindowHandle));
+ if (0 == getWindowHandle()) {
+ throw new NativeWindowException("Error native Window Handle is null");
+ }
+ windowHandleClose = eglWindowHandle;
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=windowHandleClose) {
+ CloseWindow(windowHandleClose, windowUserData);
+ windowUserData=0;
+ }
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ setVisible0(eglWindowHandle, visible);
+ reconfigureWindowImpl(x, y, width, height, false, 0, 0);
+ visibleChanged(visible);
+ }
+
+ protected void requestFocusImpl(boolean reparented) { }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ if(0!=eglWindowHandle) {
+ if(0!=fullScreenChange) {
+ boolean fs = fullScreenChange > 0;
+ setFullScreen0(eglWindowHandle, fs);
+ if(fs) {
+ return true;
+ }
+ }
+ // int _x=(x>=0)?x:this.x;
+ // int _y=(x>=0)?y:this.y;
+ int _w=(width>0)?width:this.width;
+ int _h=(height>0)?height:this.height;
+ if(width>0 || height>0) {
+ setSize0(eglWindowHandle, _w, _h);
+ }
+ if(x>=0 || y>=0) {
+ System.err.println("setPosition n/a in KD");
+ }
+ }
+ return true;
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return new Point(x,y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs();
+ private native long CreateWindow(long displayHandle, int[] attributes);
+ private native long RealizeWindow(long eglWindowHandle);
+ private native int CloseWindow(long eglWindowHandle, long userData);
+ private native void setVisible0(long eglWindowHandle, boolean visible);
+ private native void setSize0(long eglWindowHandle, int width, int height);
+ private native void setFullScreen0(long eglWindowHandle, boolean fullscreen);
+
+ private void windowCreated(long userData) {
+ windowUserData=userData;
+ }
+
+ protected void sizeChanged(int newWidth, int newHeight, boolean force) {
+ if(fullscreen) {
+ ((KDScreen)getScreen()).setScreenSize(width, height);
+ }
+ super.sizeChanged(newWidth, newHeight, force);
+ }
+
+ private long eglWindowHandle;
+ private long windowHandleClose;
+ private long windowUserData;
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java
new file mode 100644
index 000000000..fe86257ff
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsDisplay.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.windows;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.windows.*;
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.*;
+
+public class WindowsDisplay extends DisplayImpl {
+
+ protected static final String WINDOW_CLASS_NAME = "NewtWindowClass";
+ private static int windowClassAtom;
+ private static long hInstance;
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if (!WindowsWindow.initIDs0()) {
+ throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public WindowsDisplay() {
+ }
+
+ protected void createNativeImpl() {
+ aDevice = new WindowsGraphicsDevice();
+ }
+
+ protected void closeNativeImpl() {
+ // Can't do .. only at application shutdown
+ // UnregisterWindowClass0(getWindowClassAtom(), getHInstance());
+ }
+
+ protected void dispatchMessagesNative() {
+ DispatchMessages0();
+ }
+
+ protected static synchronized int getWindowClassAtom() {
+ if(0 == windowClassAtom) {
+ windowClassAtom = RegisterWindowClass0(WINDOW_CLASS_NAME, getHInstance());
+ if (0 == windowClassAtom) {
+ throw new NativeWindowException("Error while registering window class");
+ }
+ }
+ return windowClassAtom;
+ }
+
+ protected static synchronized long getHInstance() {
+ if(0 == hInstance) {
+ hInstance = LoadLibraryW0("newt");
+ if (0 == hInstance) {
+ throw new NativeWindowException("Error finding HINSTANCE for \"newt\"");
+ }
+ }
+ return hInstance;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ private static native long LoadLibraryW0(String libraryName);
+ private static native int RegisterWindowClass0(String windowClassName, long hInstance);
+ private static native void UnregisterWindowClass0(int wndClassAtom, long hInstance);
+
+ private static native void DispatchMessages0();
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
new file mode 100644
index 000000000..e15a40e7b
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsScreen.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+package com.jogamp.newt.impl.windows;
+
+import com.jogamp.common.util.ArrayHashSet;
+import java.util.ArrayList;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.ScreenImpl;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.impl.ScreenModeStatus;
+import com.jogamp.newt.util.ScreenModeUtil;
+
+import javax.media.nativewindow.*;
+
+public class WindowsScreen extends ScreenImpl {
+
+ static {
+ WindowsDisplay.initSingleton();
+ }
+
+ public WindowsScreen() {
+ }
+
+ protected void createNativeImpl() {
+ aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
+ }
+
+ protected void closeNativeImpl() {
+ }
+
+ private int[] getScreenModeIdx(int idx) {
+ int[] modeProps = getScreenMode0(screen_idx, idx);
+ if (null == modeProps || 0 == modeProps.length) {
+ return null;
+ }
+ if(modeProps.length < ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL) {
+ throw new RuntimeException("properties array too short, should be >= "+ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+modeProps.length);
+ }
+ return modeProps;
+ }
+
+ private int nativeModeIdx;
+
+ protected int[] getScreenModeFirstImpl() {
+ nativeModeIdx = 0;
+ return getScreenModeNextImpl();
+ }
+
+ protected int[] getScreenModeNextImpl() {
+ int[] modeProps = getScreenModeIdx(nativeModeIdx);
+ if (null != modeProps && 0 < modeProps.length) {
+ nativeModeIdx++;
+ return modeProps;
+ }
+ return null;
+ }
+
+ protected ScreenMode getCurrentScreenModeImpl() {
+ int[] modeProps = getScreenModeIdx(-1);
+ if (null != modeProps && 0 < modeProps.length) {
+ return ScreenModeUtil.streamIn(modeProps, 0);
+ }
+ return null;
+ }
+
+ protected boolean setCurrentScreenModeImpl(ScreenMode sm) {
+ return setScreenMode0(screen_idx,
+ sm.getMonitorMode().getSurfaceSize().getResolution().getWidth(),
+ sm.getMonitorMode().getSurfaceSize().getResolution().getHeight(),
+ sm.getMonitorMode().getSurfaceSize().getBitsPerPixel(),
+ sm.getMonitorMode().getRefreshRate(),
+ sm.getRotation());
+ }
+
+ // Native calls
+ private native int getWidthImpl0(int scrn_idx);
+
+ private native int getHeightImpl0(int scrn_idx);
+
+ private native int[] getScreenMode0(int screen_index, int mode_index);
+ private native boolean setScreenMode0(int screen_index, int width, int height, int bits, int freq, int rot);
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
new file mode 100644
index 000000000..daa09b034
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.windows;
+
+import javax.media.nativewindow.*;
+import com.jogamp.newt.impl.WindowImpl;
+import javax.media.nativewindow.util.Insets;
+import javax.media.nativewindow.util.Point;
+
+public class WindowsWindow extends WindowImpl {
+
+ private long hmon;
+ private long hdc;
+ private long windowHandleClose;
+ private final Insets insets = new Insets(0, 0, 0, 0);
+
+ static {
+ WindowsDisplay.initSingleton();
+ }
+
+ public WindowsWindow() {
+ }
+
+ protected int lockSurfaceImpl() {
+ if( 0 != getWindowHandle() && 0 == hdc ) {
+ hdc = GetDC0(getWindowHandle());
+ hmon = MonitorFromWindow0(getWindowHandle());
+ }
+ return LOCK_SUCCESS;
+ }
+
+ protected void unlockSurfaceImpl() {
+ if ( 0 != hdc && 0 != getWindowHandle() && getWindowLockRecursionCount() == 0) {
+ ReleaseDC0(getWindowHandle(), hdc);
+ hdc=0;
+ }
+ }
+
+ public final long getSurfaceHandle() {
+ return hdc;
+ }
+
+ public boolean hasDeviceChanged() {
+ if(0!=getWindowHandle()) {
+ long _hmon = MonitorFromWindow0(getWindowHandle());
+ if (hmon != _hmon) {
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ Exception e = new Exception("Info: Window Device Changed "+Thread.currentThread().getName()+
+ ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon));
+ e.printStackTrace();
+ }
+ hmon = _hmon;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ protected void createNativeImpl() {
+ WindowsScreen screen = (WindowsScreen) getScreen();
+ WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
+ config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, screen.getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ setWindowHandle(CreateWindow0(getParentWindowHandle(),
+ display.getWindowClassAtom(), display.WINDOW_CLASS_NAME, display.getHInstance(),
+ 0, undecorated, x, y, width, height));
+ if (getWindowHandle() == 0) {
+ throw new NativeWindowException("Error creating window");
+ }
+ windowHandleClose = getWindowHandle();
+ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
+ Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+
+ " (Parent HWND "+toHexString(getParentWindowHandle())+
+ ") : HWND "+toHexString(getWindowHandle())+", "+Thread.currentThread());
+ e.printStackTrace();
+ }
+ }
+
+ protected void closeNativeImpl() {
+ if (hdc != 0) {
+ if(windowHandleClose != 0) {
+ try {
+ ReleaseDC0(windowHandleClose, hdc);
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ }
+ }
+ hdc = 0;
+ }
+ if(windowHandleClose != 0) {
+ try {
+ DestroyWindow0(windowHandleClose);
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ } finally {
+ windowHandleClose = 0;
+ }
+ }
+ }
+
+ protected void windowDestroyed() {
+ windowHandleClose = 0;
+ super.windowDestroyed();
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ setVisible0(getWindowHandle(), visible, (getParentWindowHandle()==0)?true:false, x, y, width, height);
+ visibleChanged(visible);
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ reconfigureWindow0( (fullScreenChange>0)?0:getParentWindowHandle(),
+ getWindowHandle(), x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange);
+ return true;
+ }
+
+ protected void requestFocusImpl(boolean force) {
+ requestFocus0(getWindowHandle(), force);
+ }
+
+ protected void setTitleImpl(final String title) {
+ setTitle0(getWindowHandle(), title);
+ }
+
+ public Insets getInsets() {
+ return (Insets)insets.clone();
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return (Point) getRelativeLocation0( getWindowHandle(), 0 /*root win*/, x, y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ protected static native boolean initIDs0();
+ private native long CreateWindow0(long parentWindowHandle,
+ int wndClassAtom, String wndName,
+ long hInstance, long visualID,
+ boolean isUndecorated,
+ int x, int y, int width, int height);
+ private native void DestroyWindow0(long windowHandle);
+ private native long GetDC0(long windowHandle);
+ private native void ReleaseDC0(long windowHandle, long hdc);
+ private native long MonitorFromWindow0(long windowHandle);
+ private native void setVisible0(long windowHandle, boolean visible, boolean top, int x, int y, int width, int height);
+ private native void reconfigureWindow0(long parentWindowHandle, long windowHandle,
+ int x, int y, int width, int height, boolean isVisible,
+ boolean parentChange, int fullScreenChange, int decorationChange);
+ private static native void setTitle0(long windowHandle, String title);
+ private native void requestFocus0(long windowHandle, boolean force);
+ private native Object getRelativeLocation0(long src_win, long dest_win, int src_x, int src_y);
+
+ private void insetsChanged(int left, int top, int right, int bottom) {
+ if (left != -1 && top != -1 && right != -1 && bottom != -1) {
+ if (left != insets.left || top != insets.top || right != insets.right || bottom != insets.bottom) {
+ insets.left = left;
+ insets.top = top;
+ insets.right = right;
+ insets.bottom = bottom;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window.insetsChanged: "+insets);
+ }
+ }
+ }
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java
new file mode 100644
index 000000000..a24d0953e
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.x11;
+
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import com.jogamp.newt.impl.*;
+import com.jogamp.nativewindow.impl.x11.X11Util;
+
+public class X11Display extends DisplayImpl {
+
+ static {
+ NEWTJNILibLoader.loadNEWT();
+
+ if ( !initIDs0() ) {
+ throw new NativeWindowException("Failed to initialize X11Display jmethodIDs");
+ }
+
+ if (!X11Window.initIDs0()) {
+ throw new NativeWindowException("Failed to initialize X11Window jmethodIDs");
+ }
+ }
+
+ public static void initSingleton() {
+ // just exist to ensure static init has been run
+ }
+
+
+ public X11Display() {
+ }
+
+ public String validateDisplayName(String name, long handle) {
+ return X11Util.validateDisplayName(name, handle);
+ }
+
+ protected void createNativeImpl() {
+ long handle = X11Util.createDisplay(name);
+ if( 0 == handle ) {
+ throw new RuntimeException("Error creating display: "+name);
+ }
+ try {
+ CompleteDisplay0(handle);
+ } catch(RuntimeException e) {
+ X11Util.closeDisplay(handle);
+ throw e;
+ }
+ aDevice = new X11GraphicsDevice(handle, NativeWindowFactory.getNullToolkitLock());
+ // aDevice = new X11GraphicsDevice(handle, NativeWindowFactory.createDefaultToolkitLockNoAWT(NativeWindowFactory.TYPE_X11, handle));
+ // aDevice = new X11GraphicsDevice(handle);
+
+ }
+
+ protected void closeNativeImpl() {
+ X11Util.closeDisplay(getHandle());
+ }
+
+ protected void dispatchMessagesNative() {
+ if(0==getHandle()) {
+ throw new RuntimeException("display handle null");
+ }
+ DispatchMessages0(getHandle(), javaObjectAtom, windowDeleteAtom);
+ }
+
+ protected long getJavaObjectAtom() { return javaObjectAtom; }
+ protected long getWindowDeleteAtom() { return windowDeleteAtom; }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ private static native boolean initIDs0();
+
+ private native void CompleteDisplay0(long handle);
+
+ private native void DispatchMessages0(long display, long javaObjectAtom, long windowDeleteAtom);
+
+ private void displayCompleted(long javaObjectAtom, long windowDeleteAtom) {
+ this.javaObjectAtom=javaObjectAtom;
+ this.windowDeleteAtom=windowDeleteAtom;
+ }
+
+ private long windowDeleteAtom;
+ private long javaObjectAtom;
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
new file mode 100644
index 000000000..5e89a9972
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Screen.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+package com.jogamp.newt.impl.x11;
+
+import com.jogamp.nativewindow.impl.x11.X11Util;
+import com.jogamp.newt.impl.ScreenImpl;
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.util.ScreenModeUtil;
+import java.util.List;
+
+import javax.media.nativewindow.x11.*;
+
+public class X11Screen extends ScreenImpl {
+
+ static {
+ X11Display.initSingleton();
+ }
+
+ public X11Screen() {
+ }
+
+ protected void createNativeImpl() {
+ long handle = GetScreen0(display.getHandle(), screen_idx);
+ if (handle == 0) {
+ throw new RuntimeException("Error creating screen: " + screen_idx);
+ }
+ aScreen = new X11GraphicsScreen((X11GraphicsDevice) getDisplay().getGraphicsDevice(), screen_idx);
+ setScreenSize(getWidth0(display.getHandle(), screen_idx),
+ getHeight0(display.getHandle(), screen_idx));
+ }
+
+ protected void closeNativeImpl() {
+ }
+
+ private int[] nrotations;
+ private int nrotation_index;
+ private int nres_number;
+ private int nres_index;
+ private int[] nrates;
+ private int nrate_index;
+ private int nmode_number;
+
+ protected int[] getScreenModeFirstImpl() {
+ // initialize iterators and static data
+ nrotations = getAvailableScreenModeRotations0(display.getHandle(), screen_idx);
+ if(null==nrotations || 0==nrotations.length) {
+ return null;
+ }
+ nrotation_index = 0;
+
+ nres_number = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ if(0==nres_number) {
+ return null;
+ }
+ nres_index = 0;
+
+ nrates = getScreenModeRates0(display.getHandle(), screen_idx, nres_index);
+ if(null==nrates || 0==nrates.length) {
+ return null;
+ }
+ nrate_index = 0;
+
+ nmode_number = 0;
+
+ return getScreenModeNextImpl();
+ }
+
+ protected int[] getScreenModeNextImpl() {
+ // assemble: w x h x bpp x f x r
+
+ /**
+ System.err.println("******** mode: "+nmode_number);
+ System.err.println("rot "+nrotation_index);
+ System.err.println("rate "+nrate_index);
+ System.err.println("res "+nres_index); */
+
+ int[] res = getScreenModeResolution0(display.getHandle(), screen_idx, nres_index);
+ if(null==res || 0==res.length) {
+ return null;
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+nres_index+"/"+nres_number);
+ }
+ int bpp = 32; // FIXME
+ int rate = nrates[nrate_index];
+ if(0>=rate) {
+ throw new InternalError("invalid rate: "+rate+" at index "+nrate_index+"/"+nrates.length);
+ }
+ int rotation = nrotations[nrotation_index];
+
+ int[] props = new int[ 1 + ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL ];
+ int i = 0;
+ props[i++] = nres_index; // use resolution index, not unique for native -> ScreenMode
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = bpp; // bpp
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rotation;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i - 1; // count without extra element
+
+ nmode_number++;
+
+ // iteration: r -> f -> bpp -> [w x h]
+ nrotation_index++;
+ if(nrotation_index == nrotations.length) {
+ nrotation_index=0;
+ nrate_index++;
+ if(null == nrates || nrate_index == nrates.length){
+ nres_index++;
+ if(nres_index == nres_number) {
+ // done
+ nrates=null;
+ nrotations=null;
+ return null;
+ }
+
+ nrates = getScreenModeRates0(display.getHandle(), screen_idx, nres_index);
+ if(null==nrates || 0==nrates.length) {
+ return null;
+ }
+ nrate_index = 0;
+ }
+ }
+
+ return props;
+ }
+
+ protected ScreenMode getCurrentScreenModeImpl() {
+ int resNumber = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ if(0==resNumber) {
+ return null;
+ }
+ int resIdx = getCurrentScreenResolutionIndex0(display.getHandle(), screen_idx);
+ if(0>resIdx) {
+ return null;
+ }
+ if(resIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! "+resIdx+" < "+resNumber);
+ }
+ int[] res = getScreenModeResolution0(display.getHandle(), screen_idx, resIdx);
+ if(null==res || 0==res.length) {
+ return null;
+ }
+ if(0>=res[0] || 0>=res[1]) {
+ throw new InternalError("invalid resolution: "+res[0]+"x"+res[1]+" for res idx "+resIdx+"/"+resNumber);
+ }
+ int rate = getCurrentScreenRate0(display.getHandle(), screen_idx);
+ if(0>rate) {
+ return null;
+ }
+ int rot = getCurrentScreenRotation0(display.getHandle(), screen_idx);
+ if(0>rot) {
+ return null;
+ }
+
+ int[] props = new int[ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int i = 0;
+ props[i++] = 0; // set later for verification of iterator
+ props[i++] = res[0]; // width
+ props[i++] = res[1]; // height
+ props[i++] = 32; // FIXME: bpp
+ props[i++] = res[2]; // widthmm
+ props[i++] = res[3]; // heightmm
+ props[i++] = rate; // rate
+ props[i++] = rot;
+ props[i - ScreenModeUtil.NUM_SCREEN_MODE_PROPERTIES_ALL] = i; // count
+ return ScreenModeUtil.streamIn(props, 0);
+ }
+
+ protected boolean setCurrentScreenModeImpl(ScreenMode screenMode) {
+ List screenModes = this.getScreenModesOrig();
+ int screenModeIdx = screenModes.indexOf(screenMode);
+ if(0>screenModeIdx) {
+ throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
+ }
+ int resNumber = getNumScreenModeResolutions0(display.getHandle(), screen_idx);
+ int resIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
+ if(0>resIdx || resIdx>=resNumber) {
+ throw new RuntimeException("Invalid resolution index: ! 0 < "+resIdx+" < "+resNumber+", screenMode["+screenModeIdx+"] "+screenMode);
+ }
+
+ long dpy = X11Util.createDisplay(display.getName());
+ if( 0 == dpy ) {
+ throw new RuntimeException("Error creating display: "+display.getName());
+ }
+
+ boolean done = false;
+ long t0 = System.currentTimeMillis();
+ try {
+ int f = screenMode.getMonitorMode().getRefreshRate();
+ int r = screenMode.getRotation();
+ if( setCurrentScreenModeStart0(dpy, screen_idx, resIdx, f, r) ) {
+ while(!done && System.currentTimeMillis()-t0 < SCREEN_MODE_CHANGE_TIMEOUT) {
+ done = setCurrentScreenModePollEnd0(dpy, screen_idx, resIdx, f, r);
+ if(!done) {
+ Thread.yield();
+ }
+ }
+ }
+ } finally {
+ X11Util.closeDisplay(dpy);
+ }
+
+ if(!done) {
+ System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
+ (System.currentTimeMillis()-t0)+"ms");
+ }
+ return done;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ private static native long GetScreen0(long dpy, int scrn_idx);
+
+ private static native int getWidth0(long display, int scrn_idx);
+
+ private static native int getHeight0(long display, int scrn_idx);
+
+ /** @return int[] { rot1, .. } */
+ private static native int[] getAvailableScreenModeRotations0(long display, int screen_index);
+
+ private static native int getNumScreenModeResolutions0(long display, int screen_index);
+
+ /** @return int[] { width, height, widthmm, heightmm } */
+ private static native int[] getScreenModeResolution0(long display, int screen_index, int mode_index);
+
+ private static native int[] getScreenModeRates0(long display, int screen_index, int mode_index);
+
+ private static native int getCurrentScreenResolutionIndex0(long display, int screen_index);
+ private static native int getCurrentScreenRate0(long display, int screen_index);
+ private static native int getCurrentScreenRotation0(long display, int screen_index);
+
+ /** needs own Display connection for XRANDR event handling */
+ private static native boolean setCurrentScreenModeStart0(long display, int screen_index, int mode_index, int freq, int rot);
+ private static native boolean setCurrentScreenModePollEnd0(long display, int screen_index, int mode_index, int freq, int rot);
+}
diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
new file mode 100644
index 000000000..06c7dfa99
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+package com.jogamp.newt.impl.x11;
+
+import com.jogamp.newt.impl.WindowImpl;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.x11.*;
+import javax.media.nativewindow.util.Point;
+
+public class X11Window extends WindowImpl {
+ private static final String WINDOW_CLASS_NAME = "NewtWindow";
+
+ static {
+ X11Display.initSingleton();
+ }
+
+ public X11Window() {
+ }
+
+ protected void createNativeImpl() {
+ X11Screen screen = (X11Screen) getScreen();
+ X11Display display = (X11Display) screen.getDisplay();
+ config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, screen.getGraphicsScreen());
+ if (config == null) {
+ throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
+ }
+ X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config;
+ long visualID = x11config.getVisualID();
+ long w = CreateWindow0(getParentWindowHandle(),
+ display.getHandle(), screen.getIndex(), visualID,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
+ x, y, width, height, isUndecorated());
+ if (w == 0) {
+ throw new NativeWindowException("Error creating window: "+w);
+ }
+ setWindowHandle(w);
+ windowHandleClose = w;
+ }
+
+ protected void closeNativeImpl() {
+ if(0!=windowHandleClose && null!=getScreen() ) {
+ X11Display display = (X11Display) getScreen().getDisplay();
+ try {
+ CloseWindow0(display.getHandle(), windowHandleClose,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom());
+ } catch (Throwable t) {
+ if(DEBUG_IMPLEMENTATION) {
+ Exception e = new Exception("Warning: closeNativeImpl failed - "+Thread.currentThread().getName(), t);
+ e.printStackTrace();
+ }
+ } finally {
+ windowHandleClose = 0;
+ }
+ }
+ }
+
+ protected void windowDestroyed() {
+ windowHandleClose = 0;
+ super.windowDestroyed();
+ }
+
+ protected void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ setVisible0(getDisplayHandle(), getWindowHandle(), visible, x, y, width, height);
+ }
+
+ protected boolean reconfigureWindowImpl(int x, int y, int width, int height,
+ boolean parentChange, int fullScreenChange, int decorationChange) {
+ reparentHandle=0;
+ reparentCount=0;
+ long reqNewParentHandle = ( fullScreenChange > 0 ) ? 0 : getParentWindowHandle() ;
+
+ reconfigureWindow0( getDisplayHandle(), getScreenIndex(), reqNewParentHandle, getWindowHandle(),
+ x, y, width, height, isVisible(), parentChange, fullScreenChange, decorationChange);
+ return true;
+ }
+
+ protected void requestFocusImpl(boolean force) {
+ requestFocus0(getDisplayHandle(), getWindowHandle(), force);
+ }
+
+ protected void setTitleImpl(String title) {
+ setTitle0(getDisplayHandle(), getWindowHandle(), title);
+ }
+
+ protected Point getLocationOnScreenImpl(int x, int y) {
+ return (Point) getRelativeLocation0( getDisplayHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+
+ protected static native boolean initIDs0();
+ private native long CreateWindow0(long parentWindowHandle, long display, int screen_index,
+ long visualID, long javaObjectAtom, long windowDeleteAtom,
+ int x, int y, int width, int height, boolean undecorated);
+ private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom);
+ private native void setVisible0(long display, long windowHandle, boolean visible, int x, int y, int width, int height);
+ private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle,
+ int x, int y, int width, int height, boolean isVisible,
+ boolean parentChange, int fullScreenChange, int decorationChange);
+ private native void setTitle0(long display, long windowHandle, String title);
+ private native void requestFocus0(long display, long windowHandle, boolean force);
+ private native Object getRelativeLocation0(long display, int screen_index, long src_win, long dest_win, int src_x, int src_y);
+
+ private void windowReparented(long gotParentHandle) {
+ reparentHandle = gotParentHandle;
+ reparentCount++;
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("******** new parent ("+reparentCount+"): " + toHexString(reparentHandle) );
+ }
+ }
+
+ private long windowHandleClose;
+ private volatile long reparentHandle;
+ private volatile int reparentCount;
+}
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
new file mode 100644
index 000000000..36302c55a
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -0,0 +1,843 @@
+/*
+ * 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.opengl;
+
+import com.jogamp.newt.*;
+import com.jogamp.newt.event.*;
+import com.jogamp.newt.impl.WindowImpl;
+import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Point;
+import javax.media.opengl.*;
+import com.jogamp.opengl.impl.GLDrawableHelper;
+import javax.media.nativewindow.util.Insets;
+
+/**
+ * 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, 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 implements GLAutoDrawable, Window {
+ private WindowImpl window;
+
+ /**
+ * Constructor. Do not call this directly -- use {@link #create()} instead.
+ */
+ protected GLWindow(Window window) {
+ resetCounter();
+ this.window = (WindowImpl) window;
+ ((WindowImpl)this.window).setHandleDestroyNotify(false);
+ window.addWindowListener(new WindowAdapter() {
+ public void windowRepaint(WindowUpdateEvent e) {
+ if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
+ display();
+ }
+ }
+
+ public void windowResized(WindowEvent e) {
+ sendReshape = true;
+ if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
+ display();
+ }
+ }
+
+ public void windowDestroyNotify(WindowEvent e) {
+ if( !GLWindow.this.window.isSurfaceLockedByOtherThread() && !GLWindow.this.helper.isExternalAnimatorAnimating() ) {
+ destroy();
+ } else {
+ sendDestroy = true;
+ }
+ }
+ });
+ this.window.setLifecycleHook(new GLLifecycleHook());
+ }
+
+ /**
+ * 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 new GLWindow(NewtFactory.createWindow(caps));
+ }
+
+ /**
+ * 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));
+ }
+
+ /**
+ * 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);
+ }
+
+ /**
+ * 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));
+ }
+
+ //----------------------------------------------------------------------
+ // Window Access
+ //
+
+ public final Capabilities getChosenCapabilities() {
+ if (drawable == null) {
+ return window.getChosenCapabilities();
+ }
+
+ return drawable.getChosenGLCapabilities();
+ }
+
+ public final Capabilities getRequestedCapabilities() {
+ return window.getRequestedCapabilities();
+ }
+
+ public final Window getWindow() {
+ return window;
+ }
+
+ public final NativeWindow getParent() {
+ return window.getParent();
+ }
+
+ public final Screen getScreen() {
+ return window.getScreen();
+ }
+
+ public final void setTitle(String title) {
+ window.setTitle(title);
+ }
+
+ public final String getTitle() {
+ return window.getTitle();
+ }
+
+ public final void setUndecorated(boolean value) {
+ window.setUndecorated(value);
+ }
+
+ public final boolean isUndecorated() {
+ return window.isUndecorated();
+ }
+
+ public final void setFocusAction(FocusRunnable focusAction) {
+ window.setFocusAction(focusAction);
+ }
+
+ public final void requestFocus() {
+ window.requestFocus();
+ }
+
+ public boolean hasFocus() {
+ return window.hasFocus();
+ }
+
+ public final Insets getInsets() {
+ return window.getInsets();
+ }
+
+ public final void setPosition(int x, int y) {
+ window.setPosition(x, y);
+ }
+
+ public final boolean setFullscreen(boolean fullscreen) {
+ return window.setFullscreen(fullscreen);
+ }
+
+ public final boolean isFullscreen() {
+ return window.isFullscreen();
+ }
+
+ public final boolean isVisible() {
+ return window.isVisible();
+ }
+
+ public final String toString() {
+ return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
+ ", \n\tContext: " + context + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
+ }
+
+ public final int reparentWindow(NativeWindow newParent) {
+ return window.reparentWindow(newParent);
+ }
+
+ public final int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
+ return window.reparentWindow(newParent, forceDestroyCreate);
+ }
+
+ public final void removeChild(NativeWindow win) {
+ window.removeChild(win);
+ }
+
+ public final void addChild(NativeWindow win) {
+ window.addChild(win);
+ }
+
+ public void screenModeChangeNotify(ScreenMode sm) {
+ window.screenModeChangeNotify(sm);
+ }
+
+ public void screenModeChanged(ScreenMode sm, boolean success) {
+ window.screenModeChanged(sm, success);
+ }
+
+ //----------------------------------------------------------------------
+ // Window.LifecycleHook Implementation
+ //
+
+ public final void destroy(boolean unrecoverable) {
+ window.destroy(unrecoverable);
+ }
+
+ public final void setVisible(boolean visible) {
+ window.setVisible(visible);
+ }
+
+ public final void setSize(int width, int height) {
+ window.setSize(width, height);
+ }
+
+ public final boolean isValid() {
+ return window.isValid();
+ }
+
+ public final boolean isNativeValid() {
+ return window.isNativeValid();
+ }
+
+ public Point getLocationOnScreen(Point storage) {
+ return window.getLocationOnScreen(storage);
+ }
+
+ // 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 destroyActionPreLock(boolean unrecoverable) {
+ GLAnimatorControl animator = GLWindow.this.getAnimator();
+ if(null!=animator) {
+ if(unrecoverable) {
+ if(animator.isStarted()) {
+ animator.stop();
+ }
+ } else if(animator.isAnimating()) {
+ animator.pause();
+ }
+ }
+ }
+
+ /** Window.LifecycleHook */
+ public synchronized void destroyActionInLock(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);
+ resetCounter();
+ } else if(!visible) {
+ resetCounter();
+ }
+ 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 pauseRenderingAction() {
+ GLAnimatorControl ctrl = GLWindow.this.getAnimator();
+ if ( null!=ctrl && ctrl.isAnimating() && ctrl.getThread() != Thread.currentThread() ) {
+ animatorPaused = true;
+ ctrl.pause();
+ }
+ }
+
+ public synchronized void resumeRenderingAction() {
+ resetCounter();
+ GLAnimatorControl ctrl = GLWindow.this.getAnimator();
+ if ( null!=ctrl && animatorPaused ) {
+ animatorPaused = false;
+ ctrl.resume();
+ }
+ }
+ }
+
+ //----------------------------------------------------------------------
+ // OpenGL-related methods and state
+ //
+
+ private GLDrawableFactory factory;
+ private GLDrawable drawable;
+ private GLContext context;
+ private GLDrawableHelper helper = new GLDrawableHelper();
+ // To make reshape events be sent immediately before a display event
+ private boolean sendReshape=false;
+ private boolean sendDestroy=false;
+ private boolean perfLog = false;
+ private long startTime, curTime, lastCheck;
+ private int totalFrames, lastFrames;
+
+ public GLDrawableFactory getFactory() {
+ return factory;
+ }
+
+ public void setContext(GLContext newCtx) {
+ context = newCtx;
+ }
+
+ public GLContext getContext() {
+ return context;
+ }
+
+ public GL getGL() {
+ if (context == null) {
+ return null;
+ }
+ return context.getGL();
+ }
+
+ public GL setGL(GL gl) {
+ if (context != null) {
+ context.setGL(gl);
+ return gl;
+ }
+ return null;
+ }
+
+ public void addGLEventListener(GLEventListener listener) {
+ if(null!=helper) {
+ helper.addGLEventListener(listener);
+ }
+ }
+
+ public void addGLEventListener(int index, GLEventListener listener) {
+ if(null!=helper) {
+ helper.addGLEventListener(index, listener);
+ }
+ }
+
+ public void removeGLEventListener(GLEventListener listener) {
+ if(null!=helper) {
+ helper.removeGLEventListener(listener);
+ }
+ }
+
+ public void setAnimator(GLAnimatorControl animatorControl) {
+ if(null!=helper) {
+ helper.setAnimator(animatorControl);
+ }
+ }
+
+ public GLAnimatorControl getAnimator() {
+ if(null!=helper) {
+ return helper.getAnimator();
+ }
+ return null;
+ }
+
+ public boolean getPerfLogEnabled() { return perfLog; }
+
+ public void enablePerfLog(boolean v) {
+ perfLog = v;
+ }
+
+ public void invoke(boolean wait, GLRunnable glRunnable) {
+ if(null!=helper) {
+ helper.invoke(this, wait, glRunnable);
+ }
+ }
+
+ public void display() {
+ display(false);
+ }
+
+ public void display(boolean forceReshape) {
+ if( null == window ) { return; }
+
+ if(sendDestroy || ( null!=window && window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) ) {
+ sendDestroy=false;
+ destroy();
+ return;
+ }
+
+ if( null == context && isVisible() && 0<getWidth()*getHeight() ) {
+ // retry native window and drawable/context creation
+ setVisible(true);
+ }
+
+ if( isVisible() && isNativeValid() && null != context ) {
+ if(forceReshape) {
+ sendReshape = true;
+ }
+ if( NativeSurface.LOCK_SURFACE_NOT_READY < lockSurface() ) {
+ try {
+ helper.invokeGL(drawable, context, displayAction, initAction);
+ } finally {
+ unlockSurface();
+ }
+ }
+ }
+ }
+
+ /** This implementation uses a static value */
+ public void setAutoSwapBufferMode(boolean onOrOff) {
+ if(null!=helper) {
+ helper.setAutoSwapBufferMode(onOrOff);
+ }
+ }
+
+ /** This implementation uses a static value */
+ public boolean getAutoSwapBufferMode() {
+ if(null!=helper) {
+ return helper.getAutoSwapBufferMode();
+ }
+ return false;
+ }
+
+ public void swapBuffers() {
+ if(drawable!=null && context != null) {
+ // Lock: Locked Surface/Window by MakeCurrent/Release
+ if (context != GLContext.getCurrent()) {
+ // Assume we should try to make the context current before swapping the buffers
+ helper.invokeGL(drawable, context, swapBuffersAction, initAction);
+ } else {
+ drawable.swapBuffers();
+ }
+ }
+ }
+
+ class InitAction implements Runnable {
+ public void run() {
+ // Lock: Locked Surface/Window by MakeCurrent/Release
+ helper.init(GLWindow.this);
+ resetCounter();
+ }
+ }
+ private InitAction initAction = new InitAction();
+
+ class DisplayAction implements Runnable {
+ public void run() {
+ // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release
+ if (sendReshape) {
+ helper.reshape(GLWindow.this, 0, 0, getWidth(), getHeight());
+ sendReshape = false;
+ }
+
+ helper.display(GLWindow.this);
+
+ curTime = System.currentTimeMillis();
+ totalFrames++;
+
+ if(perfLog) {
+ long dt0, dt1;
+ lastFrames++;
+ dt0 = curTime-lastCheck;
+ if ( dt0 > 5000 ) {
+ dt1 = curTime-startTime;
+ 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;
+ }
+ }
+ }
+ }
+ private DisplayAction displayAction = new DisplayAction();
+
+ /**
+ * @return Time of the first display call in milliseconds.
+ * This value is reset if becoming visible again or reparenting.
+ */
+ public final long getStartTime() {
+ return startTime;
+ }
+
+ /**
+ * @return Time of the last display call in milliseconds.
+ * This value is reset if becoming visible again or reparenting.
+ */
+ public final long getCurrentTime() {
+ return curTime;
+ }
+
+ /**
+ * @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.
+ */
+ public final int getTotalFrames() {
+ return totalFrames;
+ }
+
+ /** Reset all counter (startTime, currentTime, frame number) */
+ public synchronized void resetCounter() {
+ startTime = System.currentTimeMillis(); // overwrite startTime to real init one
+ curTime = startTime;
+ lastCheck = startTime;
+ totalFrames = 0; lastFrames = 0;
+ }
+
+ class SwapBuffersAction implements Runnable {
+ public void run() {
+ drawable.swapBuffers();
+ }
+ }
+ private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
+
+ //----------------------------------------------------------------------
+ // GLDrawable methods
+ //
+
+ public final NativeSurface getNativeSurface() {
+ return null!=drawable ? drawable.getNativeSurface() : null;
+ }
+
+ public final long getHandle() {
+ return null!=drawable ? drawable.getHandle() : 0;
+ }
+
+ public final void destroy() {
+ window.destroy();
+ }
+
+ public final int getX() {
+ return window.getX();
+ }
+
+ public final int getY() {
+ return window.getY();
+ }
+
+ public final int getWidth() {
+ return window.getWidth();
+ }
+
+ public final int getHeight() {
+ return window.getHeight();
+ }
+
+ //----------------------------------------------------------------------
+ // GLDrawable methods that are not really needed
+ //
+
+ public final GLContext createContext(GLContext shareWith) {
+ return drawable.createContext(shareWith);
+ }
+
+ public final void setRealized(boolean realized) {
+ }
+
+ public final boolean isRealized() {
+ return ( null != drawable ) ? drawable.isRealized() : false;
+ }
+
+ public final GLCapabilities getChosenGLCapabilities() {
+ if (drawable == null) {
+ throw new GLException("No drawable yet");
+ }
+
+ return drawable.getChosenGLCapabilities();
+ }
+
+ 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 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, NativeSurface ns, long when) {
+ window.surfaceUpdated(updater, ns, when);
+ }
+}
diff --git a/src/newt/classes/com/jogamp/newt/util/EDTUtil.java b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
new file mode 100644
index 000000000..d1a11a788
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/EDTUtil.java
@@ -0,0 +1,115 @@
+/**
+ * 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.util;
+
+/**
+ * EDT stands for Event Dispatch Thread.
+ * <p>
+ * EDTUtil comprises the functionality of:
+ * <ul>
+ * <li> Periodically issuing an event dispatch command on the EDT.</li>
+ * <li> Ability to enqueue tasks, executed on the EDT.</li>
+ * <li> Controlling the EDT, ie start and stop in a sane manner.</li>
+ * </ul>
+ * The EDT pattern is a common tool to comply with todays windowing toolkits,
+ * where the common denominator in regards to multithreading is to:
+ * <ul>
+ * <li> Create a Window on one thread </li>
+ * <li> Modify the Window within the same thread </li>
+ * <li> Handle incoming events from within the same thread </li>
+ * </ul>
+ * Note: This is not true on MacOSX, where all these actions have to be
+ * performed by a unique, so called main thread.<br>
+ */
+public interface EDTUtil {
+
+ public static final long defaultEDTPollGranularity = 10; // 10ms, 1/100s
+
+ /**
+ * Create a new EDT. One should invoke <code>reset()</code><br>
+ * after <code>invokeStop(..)</code> in case another <code>start()</code> or <code>invoke(..)</code>
+ * is expected.
+ *
+ * @see #start()
+ * @see #invoke(boolean, java.lang.Runnable)
+ * @see #invokeStop(java.lang.Runnable)
+ */
+ public void reset();
+
+ /**
+ * Start the EDT
+ */
+ public void start();
+
+ /**
+ * @return True if the current thread is the EDT thread
+ */
+ public boolean isCurrentThreadEDT();
+
+ /**
+ * @return True if EDT is running
+ */
+ public boolean isRunning();
+
+ /**
+ * Append the final task to the EDT task queue,
+ * signals EDT to stop and wait until stopped.<br>
+ * Due to the nature of this method:
+ * <ul>
+ * <li>All previous queued tasks will be finished.</li>
+ * <li>No new tasks are allowed, an Exception is thrown.</li>
+ * <li>Can be issued from within EDT, ie from within an enqueued task.</li>
+ * <li>{@link #reset()} may follow immediately, ie creating a new EDT</li>
+ * </ul>
+ */
+ public void invokeStop(Runnable finalTask);
+
+ /**
+ * Append task to the EDT task queue.<br>
+ * Wait until execution is finished if <code>wait == true</code>.<br>
+ * Shall start the thread if not running.<br>
+ * Can be issued from within EDT, ie from within an enqueued task.<br>
+ *
+ * @throws RuntimeException in case EDT is stopped and not {@link #reset()}
+ */
+ public void invoke(boolean wait, Runnable task);
+
+ /**
+ * Wait until the EDT task queue is empty.<br>
+ * The last task may still be in execution when this method returns.
+ */
+ public void waitUntilIdle();
+
+ /**
+ * Wait until EDT task is stopped.<br>
+ * No <code>stop</code> action is performed, {@link #invokeStop(java.lang.Runnable)} should be used before.
+ */
+ public void waitUntilStopped();
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
new file mode 100644
index 000000000..5b26cfbda
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ */
+
+package com.jogamp.newt.util;
+
+import java.util.*;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.security.*;
+
+import javax.media.nativewindow.*;
+
+import com.jogamp.common.util.*;
+import com.jogamp.newt.*;
+import com.jogamp.newt.impl.*;
+
+/**
+ * NEWT Utility class MainThread<P>
+ *
+ * This class provides a startup singleton <i>main thread</i>,
+ * from which a new thread with the users main class is launched.<br>
+ *
+ * Such behavior is necessary for native windowing toolkits,
+ * where the windowing management must happen on the so called
+ * <i>main thread</i> e.g. for Mac OS X !<br>
+ *
+ * Utilizing this class as a launchpad, now you are able to
+ * use a NEWT multithreaded application with window handling within the different threads,
+ * even on these restricted platforms.<br>
+ *
+ * To support your NEWT Window platform,
+ * you have to pass your <i>main thread</i> actions to {@link #invoke invoke(..)},
+ * have a look at the {@link com.jogamp.newt.macosx.MacWindow MacWindow} implementation.<br>
+ * <i>TODO</i>: Some hardcoded dependencies exist in this implementation,
+ * where you have to patch this code or factor it out. <P>
+ *
+ * If your platform is not Mac OS X, but you want to test your code without modifying
+ * this class, you have to set the system property <code>newt.MainThread.force</code> to <code>true</code>.<P>
+ *
+ * The code is compatible with all other platform, which support multithreaded windowing handling.
+ * Since those platforms won't trigger the <i>main thread</i> serialization, the main method
+ * will be simply executed, in case you haven't set <code>newt.MainThread.force</code> to <code>true</code>.<P>
+ *
+ * Test case on Mac OS X (or any other platform):
+ <PRE>
+ java -XstartOnFirstThread com.jogamp.newt.util.MainThread demos.es1.RedSquare -GL2 -GL2 -GL2 -GL2
+ </PRE>
+ * Which starts 4 threads, each with a window and OpenGL rendering.<br>
+ */
+public class MainThread implements EDTUtil {
+ private static AccessControlContext localACC = AccessController.getContext();
+ public static final boolean MAIN_THREAD_CRITERIA = ( !NativeWindowFactory.isAWTAvailable() &&
+ NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))
+ ) || Debug.getBooleanProperty("newt.MainThread.force", true, localACC);
+
+ protected static final boolean DEBUG = Debug.debug("MainThread");
+
+ private static MainThread singletonMainThread = new MainThread(); // one singleton MainThread
+
+ private static boolean isExit=false;
+ private static volatile boolean isRunning=false;
+ private static Object taskWorkerLock=new Object();
+ private static boolean shouldStop;
+ private static ArrayList tasks;
+ private static Thread mainThread;
+
+ private static Timer pumpMessagesTimer=null;
+ private static TimerTask pumpMessagesTimerTask=null;
+ private static Map/*<Display, Runnable>*/ pumpMessageDisplayMap = new HashMap();
+
+ private static boolean useMainThread = false;
+ private static Class cAWTEventQueue=null;
+ private static Method mAWTInvokeAndWait=null;
+ private static Method mAWTInvokeLater=null;
+ private static Method mAWTIsDispatchThread=null;
+
+ static class MainAction extends Thread {
+ private String mainClassName;
+ private String[] mainClassArgs;
+
+ private Class mainClass;
+ private Method mainClassMain;
+
+ public MainAction(String mainClassName, String[] mainClassArgs) {
+ this.mainClassName=mainClassName;
+ this.mainClassArgs=mainClassArgs;
+ }
+
+ public void run() {
+ if ( useMainThread ) {
+ // we have to start first to provide the service ..
+ singletonMainThread.waitUntilRunning();
+ }
+
+ // start user app ..
+ try {
+ Class mainClass = ReflectionUtil.getClass(mainClassName, true, getClass().getClassLoader());
+ if(null==mainClass) {
+ throw new RuntimeException(new ClassNotFoundException("MainThread couldn't find main class "+mainClassName));
+ }
+ try {
+ mainClassMain = mainClass.getDeclaredMethod("main", new Class[] { String[].class });
+ mainClassMain.setAccessible(true);
+ } catch (Throwable t) {
+ throw new RuntimeException(t);
+ }
+ if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" invoke "+mainClassName);
+ mainClassMain.invoke(null, new Object[] { mainClassArgs } );
+ } catch (InvocationTargetException ite) {
+ ite.getTargetException().printStackTrace();
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" user app fin");
+
+ if ( useMainThread ) {
+ singletonMainThread.invokeStop(new Runnable() {
+ public void run() {
+ // nop
+ }});
+ if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainThread fin - stop");
+ System.exit(0);
+ }
+ }
+ }
+ private static MainAction mainAction;
+
+ /** Your new java application main entry, which pipelines your application */
+ public static void main(String[] args) {
+ useMainThread = MAIN_THREAD_CRITERIA;
+
+ if(DEBUG) System.err.println("MainThread.main(): "+Thread.currentThread().getName()+" useMainThread "+ useMainThread );
+
+ if(args.length==0) {
+ return;
+ }
+
+ String mainClassName=args[0];
+ String[] mainClassArgs=new String[args.length-1];
+ if(args.length>1) {
+ System.arraycopy(args, 1, mainClassArgs, 0, args.length-1);
+ }
+
+ NEWTJNILibLoader.loadNEWT();
+
+ mainAction = new MainAction(mainClassName, mainClassArgs);
+
+ if(NativeWindowFactory.TYPE_MACOSX.equals(NativeWindowFactory.getNativeWindowType(false))) {
+ ReflectionUtil.callStaticMethod("com.jogamp.newt.impl.macosx.MacDisplay", "initSingleton",
+ null, null, MainThread.class.getClassLoader());
+ }
+
+ if ( useMainThread ) {
+ shouldStop = false;
+ tasks = new ArrayList();
+ mainThread = Thread.currentThread();
+
+ // dispatch user's main thread ..
+ mainAction.start();
+
+ // do our main thread task scheduling
+ singletonMainThread.run();
+ } else {
+ // run user's main in this thread
+ mainAction.run();
+ }
+ }
+
+ public static final MainThread getSingleton() {
+ return singletonMainThread;
+ }
+
+ public static Runnable removePumpMessage(Display dpy) {
+ synchronized(pumpMessageDisplayMap) {
+ return (Runnable) pumpMessageDisplayMap.remove(dpy);
+ }
+ }
+
+ public static void addPumpMessage(Display dpy, Runnable pumpMessage) {
+ if ( useMainThread ) {
+ return; // error ?
+ }
+ if(null == pumpMessagesTimer) {
+ synchronized (MainThread.class) {
+ if(null == pumpMessagesTimer) {
+ pumpMessagesTimer = new Timer();
+ pumpMessagesTimerTask = new TimerTask() {
+ public void run() {
+ synchronized(pumpMessageDisplayMap) {
+ for(Iterator i = pumpMessageDisplayMap.values().iterator(); i.hasNext(); ) {
+ ((Runnable) i.next()).run();
+ }
+ }
+ }
+ };
+ pumpMessagesTimer.scheduleAtFixedRate(pumpMessagesTimerTask, 0, defaultEDTPollGranularity);
+ }
+ }
+ }
+ synchronized(pumpMessageDisplayMap) {
+ pumpMessageDisplayMap.put(dpy, pumpMessage);
+ }
+ }
+
+ private void initAWTReflection() {
+ if(null == cAWTEventQueue) {
+ ClassLoader cl = MainThread.class.getClassLoader();
+ cAWTEventQueue = ReflectionUtil.getClass("java.awt.EventQueue", true, cl);
+ mAWTInvokeAndWait = ReflectionUtil.getMethod(cAWTEventQueue, "invokeAndWait", new Class[] { java.lang.Runnable.class }, cl);
+ mAWTInvokeLater = ReflectionUtil.getMethod(cAWTEventQueue, "invokeLater", new Class[] { java.lang.Runnable.class }, cl);
+ mAWTIsDispatchThread = ReflectionUtil.getMethod(cAWTEventQueue, "isDispatchThread", new Class[] { }, cl);
+ }
+ }
+
+ public void reset() {
+ // nop
+ }
+
+ public void start() {
+ // nop
+ }
+
+ public boolean isCurrentThreadEDT() {
+ if(NativeWindowFactory.isAWTAvailable()) {
+ initAWTReflection();
+ return ((Boolean) ReflectionUtil.callMethod(null, mAWTIsDispatchThread, null) ).booleanValue();
+ }
+ return isRunning() && mainThread == Thread.currentThread() ;
+ }
+
+ public boolean isRunning() {
+ if( useMainThread ) {
+ synchronized(taskWorkerLock) {
+ return isRunning;
+ }
+ }
+ return true; // AWT is always running
+ }
+
+ private void invokeLater(Runnable task) {
+ synchronized(taskWorkerLock) {
+ if(isRunning() && mainThread != Thread.currentThread()) {
+ tasks.add(task);
+ taskWorkerLock.notifyAll();
+ } else {
+ // if !running or isEDTThread, do it right away
+ task.run();
+ }
+ }
+ }
+
+ public void invokeStop(Runnable r) {
+ invokeImpl(true, r, true);
+ }
+
+ public void invoke(boolean wait, Runnable r) {
+ invokeImpl(wait, r, false);
+ }
+
+ private void invokeImpl(boolean wait, Runnable r, boolean stop) {
+ if(r == null) {
+ return;
+ }
+
+ if(NativeWindowFactory.isAWTAvailable()) {
+ initAWTReflection();
+
+ // handover to AWT MainThread ..
+ try {
+ if ( ((Boolean) ReflectionUtil.callMethod(null, mAWTIsDispatchThread, null) ).booleanValue() ) {
+ r.run();
+ return;
+ }
+ if(wait) {
+ ReflectionUtil.callMethod(null, mAWTInvokeAndWait, new Object[] { r });
+ } else {
+ ReflectionUtil.callMethod(null, mAWTInvokeLater, new Object[] { r });
+ }
+ } catch (Exception e) {
+ throw new NativeWindowException(e);
+ }
+ return;
+ }
+
+ // if this main thread is not being used or
+ // if this is already the main thread .. just execute.
+ // FIXME: start if not started .. sync logic with DefaultEDTUtil!!!
+ if( !isRunning() || mainThread == Thread.currentThread() ) {
+ r.run();
+ return;
+ }
+
+ boolean doWait = wait && isRunning() && mainThread != Thread.currentThread();
+ Object lock = new Object();
+ RunnableTask rTask = new RunnableTask(r, doWait?lock:null, true);
+ Throwable throwable = null;
+ synchronized(lock) {
+ invokeLater(rTask);
+ // FIXME ..
+ synchronized(taskWorkerLock) {
+ if(isRunning) {
+ shouldStop = true;
+ if(DEBUG) System.err.println("MainThread.stop(): "+Thread.currentThread().getName()+" start");
+ }
+ taskWorkerLock.notifyAll();
+ }
+ if( doWait ) {
+ try {
+ lock.wait();
+ } catch (InterruptedException ie) {
+ throwable = ie;
+ }
+ }
+ }
+ if(null==throwable) {
+ throwable = rTask.getThrowable();
+ }
+ if(null!=throwable) {
+ throw new RuntimeException(throwable);
+ }
+ }
+
+ public void waitUntilIdle() {
+ }
+
+ public void waitUntilStopped() {
+ }
+
+ private void waitUntilRunning() {
+ synchronized(taskWorkerLock) {
+ if(isExit) return;
+
+ while(!isRunning) {
+ try {
+ taskWorkerLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ public void run() {
+ if(DEBUG) System.err.println("MainThread.run(): "+Thread.currentThread().getName());
+ synchronized(taskWorkerLock) {
+ isRunning = true;
+ taskWorkerLock.notifyAll();
+ }
+ while(!shouldStop) {
+ try {
+ // wait for something todo ..
+ synchronized(taskWorkerLock) {
+ while(!shouldStop && tasks.size()==0) {
+ try {
+ taskWorkerLock.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // take over the tasks ..
+ if(!shouldStop && tasks.size()>0) {
+ Runnable task = (Runnable) tasks.remove(0);
+ task.run(); // FIXME: could be run outside of lock
+ }
+ taskWorkerLock.notifyAll();
+ }
+ } catch (Throwable t) {
+ // handle errors ..
+ t.printStackTrace();
+ } finally {
+ // epilog - unlock locked stuff
+ }
+ }
+ if(DEBUG) System.err.println("MainThread.run(): "+Thread.currentThread().getName()+" fin");
+ synchronized(taskWorkerLock) {
+ isRunning = false;
+ isExit = true;
+ taskWorkerLock.notifyAll();
+ }
+ }
+}
+
+
diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
new file mode 100644
index 000000000..fb2d0ceb5
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
@@ -0,0 +1,109 @@
+/**
+ * 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.util;
+
+import javax.media.nativewindow.util.*;
+
+/** Immutable MonitorMode Class, consisting of it's read only components:<br>
+ * <ul>
+ * <li>{@link javax.media.nativewindow.util.SurfaceSize} surface memory size</li>
+ * <li>{@link javax.media.nativewindow.util.DimensionReadOnly} size in [mm]</li>
+ * <li><code>refresh rate</code></li>
+ * </ul>
+ */
+public class MonitorMode implements Cloneable {
+ SurfaceSize surfaceSize;
+ DimensionReadOnly screenSizeMM; // in [mm]
+ int refreshRate;
+
+ public MonitorMode(SurfaceSize surfaceSize, DimensionReadOnly screenSizeMM, int refreshRate) {
+ if(null==surfaceSize || refreshRate<=0) {
+ throw new IllegalArgumentException("surfaceSize must be set and refreshRate greater 0");
+ }
+ this.surfaceSize=surfaceSize;
+ this.screenSizeMM=screenSizeMM;
+ this.refreshRate=refreshRate;
+ }
+
+ public Object clone() {
+ try {
+ return super.clone();
+ } catch (CloneNotSupportedException ex) {
+ throw new InternalError();
+ }
+ }
+
+ public final SurfaceSize getSurfaceSize() {
+ return surfaceSize;
+ }
+
+ public final DimensionReadOnly getScreenSizeMM() {
+ return screenSizeMM;
+ }
+
+ public final int getRefreshRate() {
+ return refreshRate;
+ }
+
+ public final String toString() {
+ return new String("[ "+surfaceSize+" x "+refreshRate+" Hz, "+screenSizeMM+" mm ]");
+ }
+
+ /**
+ * Checks whether two size objects are equal. Two instances
+ * of <code>MonitorMode</code> are equal if the three components
+ * <code>surfaceSize</code> and <code>refreshRate</code>
+ * are equal. <code>screenSizeMM</code> is kept out intentional to reduce the requirements for finding the current mode.
+ * @return <code>true</code> if the two dimensions are equal;
+ * otherwise <code>false</code>.
+ */
+ public final boolean equals(Object obj) {
+ if (this == obj) { return true; }
+ if (obj instanceof MonitorMode) {
+ MonitorMode p = (MonitorMode)obj;
+ return getSurfaceSize().equals(p.getSurfaceSize()) &&
+ /* getScreenSizeMM().equals(p.getScreenSizeMM()) && */
+ getRefreshRate() == p.getRefreshRate() ;
+ }
+ return false;
+ }
+
+ /**
+ * returns a hash code over <code>surfaceSize</code> and <code>refreshRate</code>.
+ * <code>screenSizeMM</code> is kept out intentional to reduce the requirements for finding the current mode.
+ */
+ public final int hashCode() {
+ // 31 * x == (x << 5) - x
+ int hash = 31 + getSurfaceSize().hashCode();
+ /* hash = ((hash << 5) - hash) + getScreenSizeMM().hashCode(); */
+ hash = ((hash << 5) - hash) + getRefreshRate();
+ return hash;
+ }
+}
+
diff --git a/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
new file mode 100644
index 000000000..3e0e3dac5
--- /dev/null
+++ b/src/newt/classes/com/jogamp/newt/util/ScreenModeUtil.java
@@ -0,0 +1,340 @@
+/**
+ * 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.util;
+
+import com.jogamp.common.util.ArrayHashSet;
+import com.jogamp.newt.ScreenMode;
+import java.util.ArrayList;
+import java.util.List;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.DimensionReadOnly;
+import javax.media.nativewindow.util.SurfaceSize;
+
+/**
+ * Convenient {@link com.jogamp.newt.ScreenMode} utility methods,
+ * filters etc.
+ */
+public class ScreenModeUtil {
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 2: width and height
+ */
+ public static final int NUM_RESOLUTION_PROPERTIES = 2;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 1: bpp
+ */
+ public static final int NUM_SURFACE_SIZE_PROPERTIES = 1;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 3: ScreenSizeMM[width, height], refresh-rate
+ */
+ public static final int NUM_MONITOR_MODE_PROPERTIES = 3;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * 1: rotation, native_mode_id
+ */
+ public static final int NUM_SCREEN_MODE_PROPERTIES = 1;
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation
+ * count + all the above
+ */
+ public static final int NUM_SCREEN_MODE_PROPERTIES_ALL = 8;
+
+ public static int getIndex(List/*<ScreenMode>*/ screenModes, ScreenMode search) {
+ return screenModes.indexOf(search);
+ }
+
+ public static int getIndexByHashCode(List/*<ScreenMode>*/ screenModes, ScreenMode search) {
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ if ( search.hashCode() == ((ScreenMode)screenModes.get(i)).hashCode() ) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * @param screenModes
+ * @param resolution
+ * @return modes with nearest resolution, or matching ones
+ */
+ public static List/*<ScreenMode>*/ filterByResolution(List/*<ScreenMode>*/ screenModes, DimensionReadOnly resolution) {
+ if(null==screenModes || screenModes.size()==0) {
+ return null;
+ }
+ List out = new ArrayList();
+ int resolution_sq = resolution.getHeight()*resolution.getWidth();
+ int sm_dsq=resolution_sq, sm_dsq_idx=0;
+
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ DimensionReadOnly res = sm.getMonitorMode().getSurfaceSize().getResolution();
+ int dsq = Math.abs(resolution_sq - res.getHeight()*res.getWidth());
+ if(dsq<sm_dsq) {
+ sm_dsq = dsq;
+ sm_dsq_idx = i;
+ }
+ if(res.equals(resolution)) {
+ out.add(sm);
+ }
+ }
+ if(out.size()>0) {
+ return out;
+ }
+ // nearest ..
+ resolution = ((ScreenMode)screenModes.get(sm_dsq_idx)).getMonitorMode().getSurfaceSize().getResolution();
+ return filterByResolution(screenModes, resolution);
+ }
+
+ public static List/*<ScreenMode>*/ filterBySurfaceSize(List/*<ScreenMode>*/ screenModes, SurfaceSize surfaceSize) {
+ if(null==screenModes || screenModes.size()==0) {
+ return null;
+ }
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ if(sm.getMonitorMode().getSurfaceSize().equals(surfaceSize)) {
+ out.add(sm);
+ }
+ }
+ return out.size()>0 ? out : null;
+ }
+
+ public static List/*<ScreenMode>*/ filterByRotation(List/*<ScreenMode>*/ screenModes, int rotation) {
+ if(null==screenModes || screenModes.size()==0) {
+ return null;
+ }
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ if(sm.getRotation() == rotation) {
+ out.add(sm);
+ }
+ }
+ return out.size()>0 ? out : null;
+ }
+
+ public static List/*<ScreenMode>*/ filterByBpp(List/*<ScreenMode>*/ screenModes, int bitsPerPixel) {
+ if(null==screenModes || screenModes.size()==0) {
+ return null;
+ }
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ if(sm.getMonitorMode().getSurfaceSize().getBitsPerPixel() == bitsPerPixel) {
+ out.add(sm);
+ }
+ }
+ return out.size()>0 ? out : null;
+ }
+
+ /**
+ *
+ * @param screenModes
+ * @param refreshRate
+ * @return modes with nearest refreshRate, or matching ones
+ */
+ public static List/*<ScreenMode>*/ filterByRate(List/*<ScreenMode>*/ screenModes, int refreshRate) {
+ if(null==screenModes || screenModes.size()==0) {
+ return null;
+ }
+ int sm_dr = refreshRate;
+ int sm_dr_idx = -1;
+ List out = new ArrayList();
+ for (int i=0; null!=screenModes && i<screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ int dr = Math.abs(refreshRate - sm.getMonitorMode().getRefreshRate());
+ if(dr<sm_dr) {
+ sm_dr = dr;
+ sm_dr_idx = i;
+ }
+ if(0 == dr) {
+ out.add(sm);
+ }
+ }
+ if(out.size()>0) {
+ return out;
+ }
+ refreshRate = ((ScreenMode)screenModes.get(sm_dr_idx)).getMonitorMode().getRefreshRate();
+ return filterByRate(screenModes, refreshRate);
+ }
+
+ public static List/*<ScreenMode>*/ getHighestAvailableBpp(List/*<ScreenMode>*/ screenModes) {
+ if(null==screenModes || screenModes.size()==0) {
+ return null;
+ }
+ int highest = -1;
+ for (int i=0; null!=screenModes && i < screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ int bpp = sm.getMonitorMode().getSurfaceSize().getBitsPerPixel();
+ if (bpp > highest) {
+ highest = bpp;
+ }
+ }
+ return filterByBpp(screenModes, highest);
+ }
+
+ public static List/*<ScreenMode>*/ getHighestAvailableRate(List/*<ScreenMode>*/ screenModes) {
+ if(null==screenModes || screenModes.size()==0) {
+ return null;
+ }
+ int highest = -1;
+ for (int i=0; null!=screenModes && i < screenModes.size(); i++) {
+ ScreenMode sm = (ScreenMode)screenModes.get(i);
+ int rate = sm.getMonitorMode().getRefreshRate();
+ if (rate > highest) {
+ highest = rate;
+ }
+ }
+ return filterByRate(screenModes, highest);
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static DimensionReadOnly streamInResolution(int[] resolutionProperties, int offset) {
+ Dimension resolution = new Dimension(resolutionProperties[offset++], resolutionProperties[offset++]);
+ return resolution;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static SurfaceSize streamInSurfaceSize(DimensionReadOnly resolution, int[] sizeProperties, int offset) {
+ SurfaceSize surfaceSize = new SurfaceSize(resolution, sizeProperties[offset++]);
+ return surfaceSize;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static MonitorMode streamInMonitorMode(SurfaceSize surfaceSize, DimensionReadOnly screenSizeMM, int[] monitorProperties, int offset) {
+ int refreshRate = monitorProperties[offset++];
+ return new MonitorMode(surfaceSize, screenSizeMM, refreshRate);
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static ScreenMode streamInScreenMode(MonitorMode monitorMode, int[] modeProperties, int offset) {
+ int rotation = modeProperties[offset++];
+ return new ScreenMode(monitorMode, rotation);
+ }
+
+ /**
+ * WARNING: must be synchronized with ScreenMode.h, native implementation
+ *
+ * @param modeProperties the input data
+ * @param offset the offset to the input data
+ * @return index of the identical (old or new) ScreenMode element in <code>screenModePool</code>,
+ * matching the input <code>modeProperties</code>, or -1 if input could not be processed.
+ */
+ public static ScreenMode streamIn(int[] modeProperties, int offset) {
+ return streamInImpl(null, null, null, null, null, modeProperties, offset);
+ }
+
+ /**
+ * WARNING: must be synchronized with ScreenMode.h, native implementation
+ *
+ * @param resolutionPool hash array of unique DimensionReadOnly resolutions, no duplicates
+ * @param surfaceSizePool hash array of unique SurfaceSize, no duplicates
+ * @param monitorModePool hash array of unique MonitorMode, no duplicates
+ * @param screenModePool hash array of unique ScreenMode, no duplicates
+ * @param modeProperties the input data
+ * @param offset the offset to the input data
+ * @return index of the identical (old or new) ScreenMode element in <code>screenModePool</code>,
+ * matching the input <code>modeProperties</code>, or -1 if input could not be processed.
+ */
+ public static int streamIn(ArrayHashSet resolutionPool,
+ ArrayHashSet surfaceSizePool,
+ ArrayHashSet screenSizeMMPool,
+ ArrayHashSet monitorModePool,
+ ArrayHashSet screenModePool,
+ int[] modeProperties, int offset) {
+ ScreenMode screenMode = streamInImpl(resolutionPool, surfaceSizePool, screenSizeMMPool, monitorModePool, screenModePool,
+ modeProperties, offset);
+ return screenModePool.indexOf(screenMode);
+ }
+
+ private static ScreenMode streamInImpl(ArrayHashSet resolutionPool,
+ ArrayHashSet surfaceSizePool,
+ ArrayHashSet screenSizeMMPool,
+ ArrayHashSet monitorModePool,
+ ArrayHashSet screenModePool,
+ int[] modeProperties, int offset) {
+ int count = modeProperties[offset];
+ if(NUM_SCREEN_MODE_PROPERTIES_ALL != count) {
+ throw new RuntimeException("NUM_SCREEN_MODE_PROPERTIES should be "+NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+count+", len "+(modeProperties.length-offset));
+ }
+ if(NUM_SCREEN_MODE_PROPERTIES_ALL > modeProperties.length-offset) {
+ throw new RuntimeException("properties array too short, should be >= "+NUM_SCREEN_MODE_PROPERTIES_ALL+", is "+(modeProperties.length-offset));
+ }
+ offset++;
+ DimensionReadOnly resolution = ScreenModeUtil.streamInResolution(modeProperties, offset);
+ offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
+ if(null!=resolutionPool) {
+ resolution = (DimensionReadOnly) resolutionPool.getOrAdd(resolution);
+ }
+
+ SurfaceSize surfaceSize = ScreenModeUtil.streamInSurfaceSize(resolution, modeProperties, offset);
+ offset += ScreenModeUtil.NUM_SURFACE_SIZE_PROPERTIES;
+ if(null!=surfaceSizePool) {
+ surfaceSize = (SurfaceSize) surfaceSizePool.getOrAdd(surfaceSize);
+ }
+
+ DimensionReadOnly screenSizeMM = ScreenModeUtil.streamInResolution(modeProperties, offset);
+ offset += ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
+ if(null!=screenSizeMMPool) {
+ screenSizeMM = (DimensionReadOnly) screenSizeMMPool.getOrAdd(screenSizeMM);
+ }
+
+ MonitorMode monitorMode = ScreenModeUtil.streamInMonitorMode(surfaceSize, screenSizeMM, modeProperties, offset);
+ offset += ScreenModeUtil.NUM_MONITOR_MODE_PROPERTIES - ScreenModeUtil.NUM_RESOLUTION_PROPERTIES;
+ if(null!=monitorModePool) {
+ monitorMode = (MonitorMode) monitorModePool.getOrAdd(monitorMode);
+ }
+
+ ScreenMode screenMode = ScreenModeUtil.streamInScreenMode(monitorMode, modeProperties, offset);
+ if(null!=screenModePool) {
+ screenMode = (ScreenMode) screenModePool.getOrAdd(screenMode);
+ }
+ return screenMode;
+ }
+
+ /** WARNING: must be synchronized with ScreenMode.h, native implementation */
+ public static int[] streamOut (ScreenMode screenMode) {
+ int[] data = new int[NUM_SCREEN_MODE_PROPERTIES_ALL];
+ int idx=0;
+ data[idx++] = NUM_SCREEN_MODE_PROPERTIES_ALL;
+ data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getResolution().getWidth();
+ data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getResolution().getHeight();
+ data[idx++] = screenMode.getMonitorMode().getSurfaceSize().getBitsPerPixel();
+ data[idx++] = screenMode.getMonitorMode().getScreenSizeMM().getWidth();
+ data[idx++] = screenMode.getMonitorMode().getScreenSizeMM().getHeight();
+ data[idx++] = screenMode.getMonitorMode().getRefreshRate();
+ data[idx++] = screenMode.getRotation();
+ if(NUM_SCREEN_MODE_PROPERTIES_ALL != idx) {
+ throw new InternalError("wrong number of attributes: got "+idx+" != should "+NUM_SCREEN_MODE_PROPERTIES_ALL);
+ }
+ return data;
+ }
+
+}