aboutsummaryrefslogtreecommitdiffstats
path: root/src/newt/classes/com/jogamp/newt/Window.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt/classes/com/jogamp/newt/Window.java')
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java1854
1 files changed, 251 insertions, 1603 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index 67374cc00..ef3e5e69c 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -1,884 +1,118 @@
-/*
- * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistribution of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistribution in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * Neither the name of Sun Microsystems, Inc. or the names of
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
- * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
- * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
- * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
- * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
- * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
- * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
- * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+/**
+ * Copyright 2010 JogAmp Community. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of JogAmp Community.
*/
package com.jogamp.newt;
-import com.jogamp.newt.event.*;
-import com.jogamp.newt.util.*;
+import com.jogamp.newt.util.Insets;
+import com.jogamp.newt.event.WindowListener;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.NEWTEventConsumer;
import com.jogamp.newt.impl.Debug;
+import javax.media.nativewindow.Capabilities;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.SurfaceUpdatedListener;
-import com.jogamp.common.util.*;
-import javax.media.nativewindow.*;
-import com.jogamp.nativewindow.util.Rectangle;
-import com.jogamp.nativewindow.impl.RecursiveToolkitLock;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Iterator;
-import java.lang.reflect.Method;
-
-public abstract class Window implements NativeWindow, NEWTEventConsumer
-{
+/**
+ * Specifying the public Window functionality for the
+ * using a Window and for shadowing one like {@link com.jogamp.newt.opengl.GLWindow}.
+ */
+public interface Window extends NativeWindow {
public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent");
public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent");
public static final boolean DEBUG_WINDOW_EVENT = Debug.debug("Window.WindowEvent");
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
- public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.reparent.incompatible", true);
-
- // Workaround for initialization order problems on Mac OS X
- // between native Newt and (apparently) Fmod -- if Fmod is
- // initialized first then the connection to the window server
- // breaks, leading to errors from deep within the AppKit
- static void init(String type) {
- if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
- try {
- getWindowClass(type);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- private static Class getWindowClass(String type)
- throws ClassNotFoundException
- {
- Class windowClass = NewtFactory.getCustomClass(type, "Window");
- if(null==windowClass) {
- if (NativeWindowFactory.TYPE_EGL.equals(type)) {
- windowClass = Class.forName("com.jogamp.newt.impl.opengl.kd.KDWindow");
- } else if (NativeWindowFactory.TYPE_WINDOWS.equals(type)) {
- windowClass = Class.forName("com.jogamp.newt.impl.windows.WindowsWindow");
- } else if (NativeWindowFactory.TYPE_MACOSX.equals(type)) {
- windowClass = Class.forName("com.jogamp.newt.impl.macosx.MacWindow");
- } else if (NativeWindowFactory.TYPE_X11.equals(type)) {
- windowClass = Class.forName("com.jogamp.newt.impl.x11.X11Window");
- } else if (NativeWindowFactory.TYPE_AWT.equals(type)) {
- windowClass = Class.forName("com.jogamp.newt.impl.awt.AWTWindow");
- } else {
- throw new NativeWindowException("Unknown window type \"" + type + "\"");
- }
- }
- return windowClass;
- }
-
- protected static Window create(String type, NativeWindow parentNativeWindow, long parentWindowHandle, Screen screen, Capabilities caps, boolean undecorated) {
- try {
- Class windowClass;
- if(caps.isOnscreen()) {
- windowClass = getWindowClass(type);
- } else {
- windowClass = OffscreenWindow.class;
- }
- Window window = (Window) windowClass.newInstance();
- window.invalidate(true);
- window.parentNativeWindow = parentNativeWindow;
- window.parentWindowHandle = parentWindowHandle;
- window.screen = screen;
- window.caps = (Capabilities)caps.clone();
- window.setUndecorated(undecorated||0!=parentWindowHandle);
- return window;
- } catch (Throwable t) {
- t.printStackTrace();
- throw new NativeWindowException(t);
- }
- }
-
- protected static Window create(String type, Object[] cstrArguments, Screen screen, Capabilities caps, boolean undecorated) {
- try {
- Class windowClass = getWindowClass(type);
- Class[] cstrArgumentTypes = getCustomConstructorArgumentTypes(windowClass);
- if(null==cstrArgumentTypes) {
- throw new NativeWindowException("WindowClass "+windowClass+" doesn't support custom arguments in constructor");
- }
- int argsChecked = verifyConstructorArgumentTypes(cstrArgumentTypes, cstrArguments);
- if ( argsChecked < cstrArguments.length ) {
- throw new NativeWindowException("WindowClass "+windowClass+" constructor mismatch at argument #"+argsChecked+"; Constructor: "+getTypeStrList(cstrArgumentTypes)+", arguments: "+getArgsStrList(cstrArguments));
- }
- Window window = (Window) ReflectionUtil.createInstance( windowClass, cstrArgumentTypes, cstrArguments ) ;
- window.invalidate(true);
- window.screen = screen;
- window.caps = (Capabilities)caps.clone();
- window.setUndecorated(undecorated);
- return window;
- } catch (Throwable t) {
- throw new NativeWindowException(t);
- }
- }
-
- protected Screen screen;
- protected boolean screenReferenced = false;
-
- protected NativeWindow parentNativeWindow;
- protected long parentWindowHandle;
-
- protected Capabilities caps;
- protected AbstractGraphicsConfiguration config;
- protected long windowHandle;
- protected boolean fullscreen, visible;
- protected int width, height, x, y;
-
- // non fullscreen dimensions ..
- protected int nfs_width, nfs_height, nfs_x, nfs_y;
-
- protected String title = "Newt Window";
- protected boolean undecorated = false;
-
- private final boolean createNative() {
- if( null==screen || 0!=windowHandle || !visible ) {
- return 0 != windowHandle ;
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")");
- }
- if(validateParentWindowHandle()) {
- if(!screenReferenced) {
- screenReferenced = true;
- screen.addReference();
- }
- createNativeImpl();
- setVisibleImpl(true);
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.createNative() END ("+getThreadName()+", "+this+")");
- }
- return 0 != windowHandle ;
- }
-
- private boolean validateParentWindowHandle() {
- if(null!=parentNativeWindow) {
- parentWindowHandle = getNativeWindowHandle(parentNativeWindow);
- return 0 != parentWindowHandle ;
- }
- return true;
- }
-
- private static long getNativeWindowHandle(NativeWindow nativeWindow) {
- long handle = 0;
- if(null!=nativeWindow) {
- boolean locked=false;
- try {
- if( NativeWindow.LOCK_SURFACE_NOT_READY < nativeWindow.lockSurface() ) {
- locked=true;
- handle = nativeWindow.getWindowHandle();
- if(0==handle) {
- throw new NativeWindowException("Parent native window handle is NULL, after succesful locking: "+nativeWindow);
- }
- }
- } catch (NativeWindowException nwe) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.getNativeWindowHandle: not successful yet: "+nwe);
- }
- } finally {
- if(locked) {
- nativeWindow.unlockSurface();
- }
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.getNativeWindowHandle: locked "+locked+", "+nativeWindow);
- }
- }
- return handle;
- }
-
- public void runOnEDTIfAvail(boolean wait, final Runnable task) {
- Screen screen = getInnerWindow().getScreen();
- if(null==screen) {
- throw new RuntimeException("Null screen of inner class: "+this);
- }
- Display d = screen.getDisplay();
- d.runOnEDTIfAvail(wait, task);
- }
-
- /**
- * Create native windowHandle, ie creates a new native invisible window.
- */
- protected abstract void createNativeImpl();
-
- protected abstract void closeNativeImpl();
-
- public Capabilities getRequestedCapabilities() {
- return (Capabilities)caps.clone();
- }
-
- public NativeWindow getParentNativeWindow() {
- return parentNativeWindow;
- }
-
- public Screen getScreen() {
- return screen;
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
-
- sb.append(getClass().getName()+"[Config "+config+
- "\n, "+screen+
- "\n, ParentWindow "+parentNativeWindow+
- "\n, ParentWindowHandle "+toHexString(parentWindowHandle)+
- "\n, WindowHandle "+toHexString(getWindowHandle())+
- "\n, SurfaceHandle "+toHexString(getSurfaceHandle())+
- "\n, Pos "+getX()+"/"+getY()+", size "+getWidth()+"x"+getHeight()+
- "\n, Visible "+isVisible()+
- "\n, Undecorated "+undecorated+
- "\n, Fullscreen "+fullscreen+
- "\n, WrappedWindow "+getWrappedWindow()+
- "\n, ChildWindows "+childWindows.size());
-
- sb.append(", SurfaceUpdatedListeners num "+surfaceUpdatedListeners.size()+" [");
- for (Iterator iter = surfaceUpdatedListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("], WindowListeners num "+windowListeners.size()+" [");
- for (Iterator iter = windowListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("], MouseListeners num "+mouseListeners.size()+" [");
- for (Iterator iter = mouseListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("], KeyListeners num "+keyListeners.size()+" [");
- for (Iterator iter = keyListeners.iterator(); iter.hasNext(); ) {
- sb.append(iter.next()+", ");
- }
- sb.append("] ]");
- return sb.toString();
- }
-
- public String getTitle() {
- return title;
- }
-
- public void setTitle(String title) {
- if (title == null) {
- title = "";
- }
- this.title = title;
- if(0 != windowHandle) {
- setTitleImpl(title);
- }
- }
- protected void setTitleImpl(String title) {}
-
- public void setUndecorated(boolean value) {
- undecorated = value;
- }
-
- public boolean isUndecorated(boolean fullscreen) {
- return 0 != parentWindowHandle || undecorated || fullscreen ;
- }
-
- public boolean isUndecorated() {
- return 0 != parentWindowHandle || undecorated || fullscreen ;
- }
-
- public void requestFocus() {
- enqueueRequestFocus(false); // FIXME: or shall we wait ?
- }
- protected void requestFocusImpl() {}
-
- class RequestFocusAction implements Runnable {
- public void run() {
- Window.this.requestFocusImpl();
- }
- }
- RequestFocusAction requestFocusAction = new RequestFocusAction();
-
- public void enqueueRequestFocus(boolean wait) {
- runOnEDTIfAvail(wait, requestFocusAction);
- }
-
- /**
- * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
- * This allows notifying a covered window toolkit like AWT that the focus is requested,
- * hence focus traversal can be made transparent.
- */
- public void setFocusAction(FocusRunnable focusAction) {
- this.focusAction = focusAction;
- }
- protected boolean focusAction() {
- if(null!=focusAction) {
- return focusAction.run();
- }
- return false;
- }
- protected FocusRunnable focusAction = null;
-
- public static interface FocusRunnable {
- /**
- * @return false if NEWT shall proceed requesting the focus,
- * true if NEWT shall not request the focus.
- */
- public boolean run();
- }
//
- // NativeWindow impl
+ // Lifecycle
//
- /** Recursive and blocking lockSurface() implementation */
- public int lockSurface() {
- // We leave the ToolkitLock lock to the specializtion's discretion,
- // ie the implicit JAWTWindow in case of AWTWindow
-
- windowLock.lock();
-
- // if(windowLock.getRecursionCount() == 0) { // allow recursion to lock again, always
- if(!isNativeValid()) {
- windowLock.unlock();
- return LOCK_SURFACE_NOT_READY;
- }
- // }
- return LOCK_SUCCESS;
- }
-
- /** Recursive and unblocking unlockSurface() implementation */
- public void unlockSurface() throws NativeWindowException {
- windowLock.unlock();
- // We leave the ToolkitLock unlock to the specializtion's discretion,
- // ie the implicit JAWTWindow in case of AWTWindow
- }
-
- public boolean isSurfaceLocked() {
- return windowLock.isLocked();
- }
-
- public Thread getSurfaceLockOwner() {
- return windowLock.getOwner();
- }
-
- public Exception getLockedStack() {
- return windowLock.getLockedStack();
- }
-
- /**
- * <p>
- * destroys the window and children and releases
- * windowing related resources.<br></p>
- * <p>
- * all other resources and states are kept intact,
- * ie listeners, parent handles, size, position and Screen reference.<br></p>
+ /**
+ * @return True if native window is valid, can be created or recovered.
+ * Otherwise false, ie this window is unrecoverable due to a <code>destroy(true)</code> call.
*
* @see #destroy(boolean)
- * @see #invalidate()
- */
- public final void destroy() {
- destroy(false);
- }
-
- /**
- * Destroys the Window and it's children.
- * @param unrecoverable If true, all resources, ie listeners, parent handles,
- * size, position and reference to it's Screen will be destroyed as well.
- * Otherwise you can recreate the window, via <code>setVisible(true)</code>.
- * @see #destroy()
- * @see #invalidate(boolean)
* @see #setVisible(boolean)
*/
- public void destroy(boolean unrecoverable) {
- if(isValid()) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = new String("Window.destroy(unrecoverable: "+unrecoverable+") START "+getThreadName()+", "+this);
- //System.err.println(msg);
- Exception ee = new Exception(msg);
- ee.printStackTrace();
- }
- runOnEDTIfAvail(true, new DestroyAction(unrecoverable));
- }
- }
-
- class DestroyAction implements Runnable {
- boolean unrecoverable;
- public DestroyAction(boolean unrecoverable) {
- this.unrecoverable = unrecoverable;
- }
- public void run() {
- windowLock();
- try {
- // Childs first ..
- synchronized(childWindowsLock) {
- for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
- NativeWindow nw = (NativeWindow) i.next();
- System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") CHILD BEGIN");
- if(nw instanceof Window) {
- ((Window)nw).sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
- if(unrecoverable) {
- ((Window)nw).destroy(unrecoverable);
- }
- } else {
- nw.destroy();
- }
- System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") CHILD END");
- }
- }
-
- // Now us ..
- if(unrecoverable) {
- synchronized(childWindowsLock) {
- childWindows = new ArrayList();
- }
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners = new ArrayList();
- }
- windowListeners = new ArrayList();
- mouseListeners = new ArrayList();
- keyListeners = new ArrayList();
- }
- if( null != screen && 0 != windowHandle ) {
- closeNativeImpl();
- }
- invalidate(unrecoverable);
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.destroy(unrecoverable: "+unrecoverable+") END "+getThreadName()+", "+Window.this);
- }
- } finally {
- windowUnlock();
- }
- }
- }
-
- /**
- * <p>
- * render all native window information invalid,
- * as if the native window was destroyed.<br></p>
- * <p>
- * all other resources and states are kept intact,
- * ie listeners, parent handles and size, position etc.<br></p>
- *
- * @see #destroy()
- * @see #destroy(boolean)
- * @see #invalidate(boolean)
- */
- public void invalidate() {
- invalidate(false);
- }
+ boolean isValid();
/**
- * @param unrecoverable If true, all states, size, position, parent handles,
- * reference to it's Screen are reset.
- * Otherwise you can recreate the window, via <code>setVisible(true)</code>.
- * @see #invalidate()
- * @see #destroy()
- * @see #destroy(boolean)
- */
- protected void invalidate(boolean unrecoverable) {
- windowLock();
- try{
- if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- String msg = new String("!!! Window Invalidate(unrecoverable: "+unrecoverable+") "+getThreadName());
- System.err.println(msg);
- // Exception e = new Exception(msg);
- // e.printStackTrace();
- }
- windowHandle = 0;
- visible = false;
- fullscreen = false;
-
- if(unrecoverable) {
- System.err.println("Window.invalidate: 1 "+screen);
- if(null!=screen) {
- screenReferenced = false;
- screen.removeReference();
- }
- screen = null;
- System.err.println("Window.invalidate: 2 "+screen);
- parentWindowHandle = 0;
- parentNativeWindow = null;
- caps = null;
-
- // Default position and dimension will be re-set immediately by user
- width = 128;
- height = 128;
- x=0;
- y=0;
- }
- } finally {
- windowUnlock();
- }
- }
-
- /** @return true if the native window handle is valid and ready to operate, ie
- * if the native window has been created, otherwise false.
+ * @return true if the native window handle is valid and ready to operate, ie
+ * if the native window has been created, otherwise false.
*
* @see #setVisible(boolean)
* @see #destroy(boolean)
*/
- public boolean isNativeValid() {
- return null != screen && 0 != windowHandle ;
- }
-
- /** @return True if native window is valid, can be created or recovered.
- * Otherwise false, ie this window is unrecoverable due to a <code>destroy(true)</code> call.
- *
- * @see #destroy(boolean)
- * @see #setVisible(boolean)
- */
- public boolean isValid() {
- return null != screen ;
- }
-
- public boolean surfaceSwap() {
- return false;
- }
-
- public long getDisplayHandle() {
- return screen.getDisplay().getHandle();
- }
-
- public int getScreenIndex() {
- return screen.getIndex();
- }
-
- public long getWindowHandle() {
- return windowHandle;
- }
-
- public long getSurfaceHandle() {
- return windowHandle; // default: return window handle
- }
-
- public AbstractGraphicsConfiguration getGraphicsConfiguration() {
- return config;
- }
+ boolean isNativeValid();
/**
- * Returns the width of the client area of this window
- * @return width of the client area
+ * @return The associated Screen
*/
- public int getWidth() {
- return width;
- }
+ Screen getScreen();
/**
- * Returns the height of the client area of this window
- * @return height of the client area
+ * @return The NativeWindow representation of the parent Window,
+ * or null if this Window is top level
*/
- public int getHeight() {
- return height;
- }
+ NativeWindow getParentNativeWindow();
/**
- * Returns the insets for this native window (the difference between the
- * size of the toplevel window with the decorations and the client area).
- *
- * @return insets for this platform window
+ * @return The requested capabilities
*/
- // this probably belongs to NativeWindow interface
- public Insets getInsets() {
- return new Insets(0,0,0,0);
- }
+ Capabilities getRequestedCapabilities();
- /** Returns the most inner Window instance.<br>
- Currently only {@link com.jogamp.newt.opengl.GLWindow}
- has an aggregation to an inner Window instance.
- */
- public Window getInnerWindow() {
- return this;
- }
-
- /** If this Window actually wraps one from another toolkit such as
- the AWT, this will return a non-null value. */
- public Object getWrappedWindow() {
- return null;
- }
-
- //
- // Additional methods
- //
-
- public int getX() {
- return x;
- }
-
- public int getY() {
- return y;
- }
-
- public boolean isVisible() {
- return visible;
- }
-
- public boolean isFullscreen() {
- return fullscreen;
- }
-
- private boolean handleDestroyNotify = true;
-
- /** If the implementation is capable of detecting a device change
- return true and clear the status/reason of the change. */
- public boolean hasDeviceChanged() {
- return false;
- }
-
- class ReparentAction implements Runnable {
- /** No native reparenting action */
- static final int ACTION_NONE = 0;
-
- /** Change Window tree only */
- static final int ACTION_SOFT_REPARENTING = 1;
-
- /** Native reparenting incl. Window tree */
- static final int ACTION_NATIVE_REPARENTING = 2;
-
- /** Native window creation after tree change - instead of reparenting. */
- static final int ACTION_NATIVE_CREATION = 3;
-
- NativeWindow newParent;
- public ReparentAction(NativeWindow newParent) {
- this.newParent = newParent;
- }
- public void run() {
- windowLock();
- try{
- Window newParentWindow = null;
- if(newParent instanceof Window) {
- newParentWindow = (Window) newParent;
- }
-
- int reparentAction = -1; // ensure it's set
- long newParentHandle = 0 ;
-
- if(null!=newParent) {
- // Case: Child Window
- newParentHandle = getNativeWindowHandle(newParent);
- if(0 == newParentHandle) {
- // Case: Parent's native window not realized yet
- if(null==newParentWindow) {
- throw new NativeWindowException("Parent not NEWT Window and not realized yet: "+newParent);
- }
- // Destroy this window (handle screen + native) and use parent's Screen.
- // It may be created properly when the parent is made visible.
- destroy(false);
- screen = newParentWindow.getScreen();
- reparentAction = ACTION_SOFT_REPARENTING;
- } else if(newParent != parentNativeWindow) {
- // Case: Parent's native window realized and changed
- if( !isNativeValid() ) {
- // May create a new compatible Screen/Display and
- // mark it for creation.
- if(null!=newParentWindow) {
- screen = newParentWindow.getScreen();
- } else {
- Screen newScreen = NewtFactory.createCompatibleScreen(newParent, screen);
- if( screen != newScreen ) {
- // auto destroy on-the-fly created Screen/Display
- newScreen.setDestroyWhenUnused(true);
- screen = newScreen;
- }
- }
- reparentAction = ACTION_NATIVE_CREATION;
- } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || !NewtFactory.isScreenCompatible(newParent, screen) ) {
- // Destroy this window (handle screen + native) and
- // may create a new compatible Screen/Display and
- // mark it for creation.
- destroy(false);
- if(null!=newParentWindow) {
- screen = newParentWindow.getScreen();
- } else {
- screen = NewtFactory.createCompatibleScreen(newParent, screen);
- screen.setDestroyWhenUnused(true);
- }
- reparentAction = ACTION_NATIVE_CREATION;
- } else {
- // Mark it for native reparenting
- reparentAction = ACTION_NATIVE_REPARENTING;
- }
- } else {
- // Case: Parent's native window realized and not changed
- reparentAction = ACTION_NONE;
- }
- } else {
- // Case: Top Window
- if( 0 == parentWindowHandle ) {
- // Already Top Window
- reparentAction = ACTION_NONE;
- } else {
- // Mark it for native reparenting
- reparentAction = ACTION_NATIVE_REPARENTING;
- }
- }
-
- if ( ACTION_NONE > reparentAction ) {
- throw new NativeWindowException("Internal Error: reparentAction not set");
- }
-
- if( ACTION_NONE == reparentAction ) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparent: NO CHANGE ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow));
- }
- return;
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", reparentAction "+reparentAction+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow));
- }
-
- // rearrange window tree
- if(null!=parentNativeWindow && parentNativeWindow instanceof Window) {
- ((Window)parentNativeWindow).getInnerWindow().removeChild(Window.this);
- }
- parentNativeWindow = newParent;
- if(parentNativeWindow instanceof Window) {
- ((Window)parentNativeWindow).getInnerWindow().addChild(Window.this);
- }
-
- if( ACTION_SOFT_REPARENTING == reparentAction ) {
- return;
- }
-
- if( ACTION_NATIVE_REPARENTING == reparentAction ) {
- Display display = screen.getDisplay();
-
- parentWindowHandle = newParentHandle;
- if(0!=parentWindowHandle) {
- // reset position to 0/0 within parent space
- // FIXME .. cache position ?
- x = 0;
- y = 0;
- }
- getScreen().getDisplay().dispatchMessages(); // status up2date
- boolean wasVisible = isVisible();
- if(wasVisible) {
- Window.this.visible = false;
- setVisibleImpl(false);
- display.dispatchMessages(); // status up2date
- }
- boolean ok = reparentWindowImpl();
- display.dispatchMessages(); // status up2date
- if ( !ok ) {
- // native reparent failed -> try creation
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparent: native reparenting failed ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+" - Trying recreation");
- }
- destroy(false);
- Window.this.visible = wasVisible;
- reparentAction = ACTION_NATIVE_CREATION ;
- } else {
- if(wasVisible) {
- Window.this.visible = true;
- setVisibleImpl(true);
- requestFocusImpl();
- display.dispatchMessages(); // status up2date
- }
- }
- }
-
- // not-else: re-entrance via reparentAction value change possible
- if( ACTION_NATIVE_CREATION == reparentAction ) {
- if(isVisible()) {
- setVisible(true); // native creation
- screen.getDisplay().dispatchMessages(); // status up2date
- }
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow));
- }
- } finally {
- windowUnlock();
- }
- }
- }
+ Capabilities getChosenCapabilities();
/**
- * Change this window's parent window.<br>
- * <P>
- * In case the old parent is not null and a Window,
- * this window is removed from it's list of children.<br>
- * In case the new parent is not null and a Window,
- * this window is added to it's list of children.<br></P>
*
- * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window.
+ * <p>
+ * destroys the window and children and releases
+ * windowing related resources.<br></p>
+ * <p>
+ * all other resources and states are kept intact,
+ * ie listeners, parent handles, size, position and Screen reference.<br></p>
+ *
+ * @see #destroy(boolean)
+ * @see #invalidate()
*/
- public void reparentWindow(NativeWindow newParent) {
- if(isValid()) {
- runOnEDTIfAvail(true, new ReparentAction(newParent));
- if( isVisible() ) {
- sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
- windowRepaint(0, 0, getWidth(), getHeight());
- }
- }
- }
+ void destroy();
- class VisibleAction implements Runnable {
- boolean visible;
- public VisibleAction(boolean visible) {
- this.visible = visible;
- }
- public void run() {
- windowLock();
- try{
- if( isValid() ) {
- if(!visible && childWindows.size()>0) {
- synchronized(childWindowsLock) {
- for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
- NativeWindow nw = (NativeWindow) i.next();
- if(nw instanceof Window) {
- ((Window)nw).setVisible(false);
- }
- }
- }
- }
- if(0==windowHandle && visible) {
- Window.this.visible = visible;
- if( 0<width*height ) {
- createNative();
- }
- } else if(Window.this.visible != visible) {
- Window.this.visible = visible;
- if(0 != windowHandle) {
- setVisibleImpl(visible);
- }
- }
- if(0!=windowHandle && visible && childWindows.size()>0) {
- synchronized(childWindowsLock) {
- for(Iterator i = childWindows.iterator(); i.hasNext(); ) {
- NativeWindow nw = (NativeWindow) i.next();
- if(nw instanceof Window) {
- ((Window)nw).setVisible(true);
- }
- }
- }
- }
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible);
- }
- } finally {
- windowUnlock();
- }
- }
- }
+ /**
+ *
+ * Destroys the Window and it's children.
+ * @param unrecoverable If true, all resources, ie listeners, parent handles,
+ * size, position and reference to it's Screen will be destroyed as well.
+ * Otherwise you can recreate the window, via <code>setVisible(true)</code>.
+ * @see #destroy()
+ * @see #invalidate(boolean)
+ * @see #setVisible(boolean)
+ */
+ void destroy(boolean unrecoverable);
/**
* <p>
@@ -889,14 +123,14 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* <p>
* Zero size semantics are respected, see {@link #setSize(int,int)}:<br>
* <pre>
- * if ( 0 == windowHandle && visible ) {
- * this.visible = visible;
- * if( 0<width*height ) {
- * createNative();
- * }
+ * if ( 0 == windowHandle && visible ) {
+ * this.visible = visible;
+ * if( 0<width*height ) {
+ * createNative();
+ * }
* } else if ( this.visible != visible ) {
- * this.visible = visible;
- * setNativeSizeImpl();
+ * this.visible = visible;
+ * setNativeSizeImpl();
* }
* </pre></p>
* <p>
@@ -905,18 +139,21 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* If this action fails, ie if the parent {@link javax.media.nativewindow.NativeWindow} is not valid yet,<br>
* no native window is created yet and <code>setVisible(true)</code> shall be repeated when it is.<br></p>
*/
- public void setVisible(boolean visible) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow));
- //System.err.println(msg);
- Exception ee = new Exception(msg);
- ee.printStackTrace();
- }
- if(isValid()) {
- runOnEDTIfAvail(true, new VisibleAction(visible));
- }
- }
- protected abstract void setVisibleImpl(boolean visible);
+ void setVisible(boolean visible);
+
+ boolean isVisible();
+
+ //
+ // Child Window Management
+ //
+
+ void addChild(NativeWindow win);
+
+ void removeChild(NativeWindow win);
+
+ //
+ // Modes / States
+ //
/**
* Sets the size of the client area of the window, excluding decorations
@@ -926,11 +163,11 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* Zero size semantics are respected, see {@link #setVisible(boolean)}:<br>
* <pre>
* if ( 0 != windowHandle && 0>=width*height && visible ) {
- * setVisible(false);
+ * setVisible(false);
* } else if ( 0 == windowHandle && 0<width*height && visible ) {
- * setVisible(true);
+ * setVisible(true);
* } else {
- * // as expected ..
+ * // as expected ..
* }
* </pre></p>
* <p>
@@ -939,48 +176,57 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* @param width of the client area of the window
* @param height of the client area of the window
*/
- public void setSize(int width, int height) {
- int visibleAction = 0; // 1 invisible, 2 visible
- windowLock();
- try{
- if(DEBUG_IMPLEMENTATION) {
- String msg = new String("Window setSize: START "+this.width+"x"+this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible);
- System.err.println(msg);
- // Exception e = new Exception(msg);
- // e.printStackTrace();
- }
- if (width != this.width || this.height != height) {
- if(!fullscreen) {
- nfs_width=width;
- nfs_height=height;
- if ( 0 != windowHandle && 0>=width*height && visible ) {
- visibleAction=1; // invisible
- this.width = 0;
- this.height = 0;
- } else if ( 0 == windowHandle && 0<width*height && visible ) {
- visibleAction = 2; // visible
- this.width = width;
- this.height = height;
- } else if ( 0 != windowHandle ) {
- // this width/height will be set by windowChanged, called by the native implementation
- setSizeImpl(width, height);
- } else {
- this.width = width;
- this.height = height;
- }
- }
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setSize: END "+this.width+"x"+this.height+", visibleAction "+visibleAction);
- }
- } finally {
- windowUnlock();
- }
- if(visibleAction>0) {
- setVisible( ( 1 == visibleAction ) ? false : true );
- }
+ void setSize(int width, int height);
+
+ /**
+ * Returns the width of the client area of this window
+ * @return width of the client area
+ */
+ int getWidth();
+
+ /**
+ * Returns the height of the client area of this window
+ * @return height of the client area
+ */
+ int getHeight();
+
+ /** Defining ids for the reparenting strategy */
+ public interface ReparentAction {
+ /** No native reparenting valid */
+ static final int ACTION_INVALID = -1;
+
+ /** No native reparenting action required, no change*/
+ static final int ACTION_UNCHANGED = 0;
+
+ /** Native reparenting incl. Window tree */
+ static final int ACTION_NATIVE_REPARENTING = 1;
+
+ /** Native window creation after tree change - instead of reparenting. */
+ static final int ACTION_NATIVE_CREATION = 2;
+
+ /** Change Window tree only, native creation is pending */
+ static final int ACTION_NATIVE_CREATION_PENDING = 3;
}
- protected abstract void setSizeImpl(int width, int height);
+
+ /**
+ * Change this window's parent window.<br>
+ * <P>
+ * In case the old parent is not null and a Window,
+ * this window is removed from it's list of children.<br>
+ * In case the new parent is not null and a Window,
+ * this window is added to it's list of children.<br></P>
+ *
+ * @param newParent The new parent NativeWindow. If null, this Window becomes a top level window.
+ *
+ * @return The issued reparent action type (strategy) as defined in Window.ReparentAction
+ */
+ int reparentWindow(NativeWindow newParent);
+
+ int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate);
+
+ boolean setFullscreen(boolean fullscreen);
+
+ boolean isFullscreen();
/**
* Sets the location of the top left corner of the window, including
@@ -992,774 +238,176 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer
* @param x coord of the top left corner
* @param y coord of the top left corner
*/
- public void setPosition(int x, int y) {
- windowLock();
- try{
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window setPosition: "+this.x+"/"+this.y+" -> "+x+"/"+y+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle));
- }
- if ( this.x != x || this.y != y ) {
- if(!fullscreen) {
- nfs_x=x;
- nfs_y=y;
- if(0!=windowHandle) {
- // this x/y will be set by windowChanged, called by X11
- setPositionImpl(x, y);
- } else {
- this.x = x;
- this.y = y;
- }
- }
- }
- } finally {
- windowUnlock();
- }
- }
- protected abstract void setPositionImpl(int x, int y);
-
- public boolean setFullscreen(boolean fullscreen) {
- windowLock();
- try{
- if(0!=windowHandle && this.fullscreen!=fullscreen) {
- int x,y,w,h;
- if(fullscreen) {
- x = 0; y = 0;
- w = screen.getWidth();
- h = screen.getHeight();
- } else {
- if(0!=parentWindowHandle) {
- x=0;
- y=0;
- } else {
- x = nfs_x;
- y = nfs_y;
- }
- w = nfs_width;
- h = nfs_height;
- }
- if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
- System.err.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated());
- }
- this.fullscreen = fullscreen;
- setFullscreenImpl(fullscreen, x, y, w, h);
- }
- } finally {
- windowUnlock();
- }
- if( isVisible() ) {
- windowRepaint(0, 0, getWidth(), getHeight());
- }
- return this.fullscreen;
- }
- protected abstract void setFullscreenImpl(boolean fullscreen, int x, int y, int widht, int height);
+ void setPosition(int x, int y);
+
+ int getX();
- //
- // Child Window Management
- //
+ int getY();
- private ArrayList childWindows = new ArrayList();
- private Object childWindowsLock = new Object();
+ /**
+ * Returns the insets for this native window (the difference between the
+ * size of the toplevel window with the decorations and the client area).
+ *
+ * @return insets for this platform window
+ */
+ Insets getInsets();
- protected void removeChild(NativeWindow win) {
- synchronized(childWindowsLock) {
- childWindows.remove(win);
- }
- }
+ void setUndecorated(boolean value);
+
+ boolean isUndecorated();
+
+ void setTitle(String title);
- protected void addChild(NativeWindow win) {
- if (win == null) {
- return;
- }
- synchronized(childWindowsLock) {
- childWindows.add(win);
- }
+ String getTitle();
+
+ static interface FocusRunnable {
+ /**
+ * @return false if NEWT shall proceed requesting the focus,
+ * true if NEWT shall not request the focus.
+ */
+ public boolean run();
}
- //
- // Generic Event Support
- //
- private void doEvent(boolean enqueue, boolean wait, com.jogamp.newt.event.NEWTEvent event) {
- boolean done = false;
+ /**
+ * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
+ * This allows notifying a covered window toolkit like AWT that the focus is requested,
+ * hence focus traversal can be made transparent.
+ */
+ void setFocusAction(FocusRunnable focusAction);
- if(!enqueue) {
- done = consumeEvent(event);
- wait = done; // don't wait if event can't be consumed now
- }
+ void requestFocus();
- if(!done) {
- enqueueEvent(wait, event);
- }
- }
+ void windowRepaint(int x, int y, int width, int height);
- public void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) {
- if(getInnerWindow().isValid()) {
- getInnerWindow().getScreen().getDisplay().enqueueEvent(wait, event);
- }
- }
+ void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event);
+
+ void runOnEDTIfAvail(boolean wait, final Runnable task);
- public boolean consumeEvent(NEWTEvent e) {
- switch(e.getEventType()) {
- case WindowEvent.EVENT_WINDOW_REPAINT:
- if( windowIsLocked() ) {
- // make sure only one repaint event is queued
- if(!repaintQueued) {
- repaintQueued=true;
- return false;
- }
- return true;
- }
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowRepaint: "+e);
- // Exception ee = new Exception("Window.windowRepaint: "+e);
- // ee.printStackTrace();
- }
- repaintQueued=false; // no repaint event queued
- break;
- default:
- break;
- }
- if(e instanceof WindowEvent) {
- getInnerWindow().consumeWindowEvent((WindowEvent)e);
- } else if(e instanceof KeyEvent) {
- getInnerWindow().consumeKeyEvent((KeyEvent)e);
- } else if(e instanceof MouseEvent) {
- getInnerWindow().consumeMouseEvent((MouseEvent)e);
- } else {
- throw new NativeWindowException("Unexpected NEWTEvent type " + e);
- }
- return true;
- }
- protected boolean repaintQueued = false;
//
- // SurfaceUpdatedListener Support
+ // SurfaceUpdateListener
//
- private ArrayList surfaceUpdatedListeners = new ArrayList();
- private Object surfaceUpdatedListenersLock = new Object();
-
- /**
- * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of
+ /**
+ * Appends the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} to the end of
* the list.
*/
- public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- getInnerWindow().addSurfaceUpdatedListener(-1, l);
- }
+ void addSurfaceUpdatedListener(SurfaceUpdatedListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.SurfaceUpdatedListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- public void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l)
- throws IndexOutOfBoundsException
- {
- if(l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size();
- }
- surfaceUpdatedListeners.add(index, l);
- }
- }
+ void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException;
- public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- if (l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners.remove(l);
- }
- }
+ void removeAllSurfaceUpdatedListener();
- public void removeAllSurfaceUpdatedListener() {
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners = new ArrayList();
- }
- }
+ void removeSurfaceUpdatedListener(SurfaceUpdatedListener l);
- public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size()-1;
- }
- return (SurfaceUpdatedListener) surfaceUpdatedListeners.get(index);
- }
- }
+ SurfaceUpdatedListener getSurfaceUpdatedListener(int index);
- public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- synchronized(surfaceUpdatedListenersLock) {
- return (SurfaceUpdatedListener[]) surfaceUpdatedListeners.toArray();
- }
- }
+ SurfaceUpdatedListener[] getSurfaceUpdatedListeners();
- public void surfaceUpdated(Object updater, NativeWindow window, long when) {
- synchronized(surfaceUpdatedListenersLock) {
- for(Iterator i = surfaceUpdatedListeners.iterator(); i.hasNext(); ) {
- SurfaceUpdatedListener l = (SurfaceUpdatedListener) i.next();
- l.surfaceUpdated(updater, window, when);
- }
- }
- }
//
- // MouseListener/Event Support
+ // WindowListener
//
- private ArrayList mouseListeners = new ArrayList();
- private int mouseButtonPressed = 0; // current pressed mouse button number
- private long lastMousePressed = 0; // last time when a mouse button was pressed
- private int lastMouseClickCount = 0; // last mouse button click count
- public static final int ClickTimeout = 300;
-
- public void sendMouseEvent(int eventType, int modifiers,
- int x, int y, int button, int rotation) {
- doMouseEvent(false, false, eventType, modifiers, x, y, button, rotation);
- }
- public void enqueueMouseEvent(boolean wait, int eventType, int modifiers,
- int x, int y, int button, int rotation) {
- doMouseEvent(true, wait, eventType, modifiers, x, y, button, rotation);
- }
- private void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
- int x, int y, int button, int rotation) {
- if(x<0||y<0||x>=width||y>=height) {
- return; // .. invalid ..
- }
- if(DEBUG_MOUSE_EVENT) {
- System.err.println("doMouseEvent: enqueue"+enqueue+", wait "+wait+", "+MouseEvent.getEventTypeString(eventType)+
- ", mod "+modifiers+", pos "+x+"/"+y+", button "+button);
- }
- if(button<0||button>MouseEvent.BUTTON_NUMBER) {
- throw new NativeWindowException("Invalid mouse button number" + button);
- }
- long when = System.currentTimeMillis();
- MouseEvent eClicked = null;
- MouseEvent e = null;
-
- if(MouseEvent.EVENT_MOUSE_PRESSED==eventType) {
- if(when-lastMousePressed<ClickTimeout) {
- lastMouseClickCount++;
- } else {
- lastMouseClickCount=1;
- }
- lastMousePressed=when;
- mouseButtonPressed=button;
- e = new MouseEvent(eventType, this, when,
- modifiers, x, y, lastMouseClickCount, button, 0);
- } else if(MouseEvent.EVENT_MOUSE_RELEASED==eventType) {
- e = new MouseEvent(eventType, this, when,
- modifiers, x, y, lastMouseClickCount, button, 0);
- if(when-lastMousePressed<ClickTimeout) {
- eClicked = new MouseEvent(MouseEvent.EVENT_MOUSE_CLICKED, this, when,
- modifiers, x, y, lastMouseClickCount, button, 0);
- } else {
- lastMouseClickCount=0;
- lastMousePressed=0;
- }
- mouseButtonPressed=0;
- } else if(MouseEvent.EVENT_MOUSE_MOVED==eventType) {
- if (mouseButtonPressed>0) {
- e = new MouseEvent(MouseEvent.EVENT_MOUSE_DRAGGED, this, when,
- modifiers, x, y, 1, mouseButtonPressed, 0);
- } else {
- e = new MouseEvent(eventType, this, when,
- modifiers, x, y, 0, button, 0);
- }
- } else if(MouseEvent.EVENT_MOUSE_WHEEL_MOVED==eventType) {
- e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, rotation);
- } else {
- e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, 0);
- }
- doEvent(enqueue, wait, e);
- if(null!=eClicked) {
- if(DEBUG_MOUSE_EVENT) {
- System.err.println("doMouseEvent: synthesized MOUSE_CLICKED event");
- }
- doEvent(enqueue, wait, eClicked);
- }
- }
+ public void sendWindowEvent(int eventType);
- /**
- * Appends the given {@link com.jogamp.newt.event.MouseListener} to the end of
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.WindowListener} to the end of
* the list.
*/
- public void addMouseListener(MouseListener l) {
- getInnerWindow().addMouseListener(-1, l);
- }
+ void addWindowListener(WindowListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.MouseListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.WindowListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- public void addMouseListener(int index, MouseListener l) {
- if(l == null) {
- return;
- }
- ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
- if(0>index) {
- index = clonedListeners.size();
- }
- clonedListeners.add(index, l);
- mouseListeners = clonedListeners;
- }
-
- public void removeMouseListener(MouseListener l) {
- if (l == null) {
- return;
- }
- ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
- clonedListeners.remove(l);
- mouseListeners = clonedListeners;
- }
+ void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException;
- public MouseListener getMouseListener(int index) {
- ArrayList clonedListeners = (ArrayList) mouseListeners.clone();
- if(0>index) {
- index = clonedListeners.size()-1;
- }
- return (MouseListener) clonedListeners.get(index);
- }
+ void removeWindowListener(WindowListener l);
- public MouseListener[] getMouseListeners() {
- return (MouseListener[]) mouseListeners.toArray();
- }
+ WindowListener getWindowListener(int index);
- protected void consumeMouseEvent(MouseEvent e) {
- if(DEBUG_MOUSE_EVENT) {
- System.err.println("consumeMouseEvent: event: "+e);
- }
-
- for(Iterator i = mouseListeners.iterator(); i.hasNext(); ) {
- MouseListener l = (MouseListener) i.next();
- switch(e.getEventType()) {
- case MouseEvent.EVENT_MOUSE_CLICKED:
- l.mouseClicked(e);
- break;
- case MouseEvent.EVENT_MOUSE_ENTERED:
- l.mouseEntered(e);
- break;
- case MouseEvent.EVENT_MOUSE_EXITED:
- l.mouseExited(e);
- break;
- case MouseEvent.EVENT_MOUSE_PRESSED:
- l.mousePressed(e);
- break;
- case MouseEvent.EVENT_MOUSE_RELEASED:
- l.mouseReleased(e);
- break;
- case MouseEvent.EVENT_MOUSE_MOVED:
- l.mouseMoved(e);
- break;
- case MouseEvent.EVENT_MOUSE_DRAGGED:
- l.mouseDragged(e);
- break;
- case MouseEvent.EVENT_MOUSE_WHEEL_MOVED:
- l.mouseWheelMoved(e);
- break;
- default:
- throw new NativeWindowException("Unexpected mouse event type " + e.getEventType());
- }
- }
- }
+ WindowListener[] getWindowListeners();
//
- // KeyListener/Event Support
+ // KeyListener
//
- public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
- }
-
- public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- enqueueEvent(wait, new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
- }
- /**
- * Appends the given {@link com.jogamp.newt.event.KeyListener} to the end of
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.KeyListener} to the end of
* the list.
*/
- public void addKeyListener(KeyListener l) {
- getInnerWindow().addKeyListener(-1, l);
- }
+ void addKeyListener(KeyListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.KeyListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.KeyListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- public void addKeyListener(int index, KeyListener l) {
- if(l == null) {
- return;
- }
- ArrayList clonedListeners = (ArrayList) keyListeners.clone();
- if(0>index) {
- index = clonedListeners.size();
- }
- clonedListeners.add(index, l);
- keyListeners = clonedListeners;
- }
+ void addKeyListener(int index, KeyListener l);
- public void removeKeyListener(KeyListener l) {
- if (l == null) {
- return;
- }
- ArrayList clonedListeners = (ArrayList) keyListeners.clone();
- clonedListeners.remove(l);
- keyListeners = clonedListeners;
- }
+ void removeKeyListener(KeyListener l);
- public KeyListener getKeyListener(int index) {
- ArrayList clonedListeners = (ArrayList) keyListeners.clone();
- if(0>index) {
- index = clonedListeners.size()-1;
- }
- return (KeyListener) clonedListeners.get(index);
- }
+ KeyListener getKeyListener(int index);
- public KeyListener[] getKeyListeners() {
- return (KeyListener[]) keyListeners.toArray();
- }
+ KeyListener[] getKeyListeners();
- private ArrayList keyListeners = new ArrayList();
-
- protected void consumeKeyEvent(KeyEvent e) {
- if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e);
- }
- for(Iterator i = keyListeners.iterator(); i.hasNext(); ) {
- KeyListener l = (KeyListener) i.next();
- switch(e.getEventType()) {
- case KeyEvent.EVENT_KEY_PRESSED:
- l.keyPressed(e);
- break;
- case KeyEvent.EVENT_KEY_RELEASED:
- l.keyReleased(e);
- break;
- case KeyEvent.EVENT_KEY_TYPED:
- l.keyTyped(e);
- break;
- default:
- throw new NativeWindowException("Unexpected key event type " + e.getEventType());
- }
- }
- }
//
- // WindowListener/Event Support
+ // MouseListener
//
- public void sendWindowEvent(int eventType) {
- consumeWindowEvent( new WindowEvent(eventType, this, System.currentTimeMillis()) );
- }
-
- public void enqueueWindowEvent(boolean wait, int eventType) {
- enqueueEvent( wait, new WindowEvent(eventType, this, System.currentTimeMillis()) );
- }
- private ArrayList windowListeners = new ArrayList();
-
- /**
- * Appends the given {@link com.jogamp.newt.event.WindowListener} to the end of
+ /**
+ *
+ * Appends the given {@link com.jogamp.newt.event.MouseListener} to the end of
* the list.
*/
- public void addWindowListener(WindowListener l) {
- getInnerWindow().addWindowListener(-1, l);
- }
+ void addMouseListener(MouseListener l);
- /**
- * Inserts the given {@link com.jogamp.newt.event.WindowListener} at the
+ /**
+ *
+ * Inserts the given {@link com.jogamp.newt.event.MouseListener} at the
* specified position in the list.<br>
-
- * @param index Position where the listener will be inserted.
- * Should be within (0 <= index && index <= size()).
- * An index value of -1 is interpreted as the end of the list, size().
+ *
+ * @param index Position where the listener will be inserted.
+ * Should be within (0 <= index && index <= size()).
+ * An index value of -1 is interpreted as the end of the list, size().
* @param l The listener object to be inserted
* @throws IndexOutOfBoundsException If the index is not within (0 <= index && index <= size()), or -1
*/
- public void addWindowListener(int index, WindowListener l)
- throws IndexOutOfBoundsException
- {
- if(l == null) {
- return;
- }
- ArrayList clonedListeners = (ArrayList) windowListeners.clone();
- if(0>index) {
- index = clonedListeners.size();
- }
- clonedListeners.add(index, l);
- windowListeners = clonedListeners;
- }
+ void addMouseListener(int index, MouseListener l);
- public void removeWindowListener(WindowListener l) {
- if (l == null) {
- return;
- }
- ArrayList clonedListeners = (ArrayList) windowListeners.clone();
- clonedListeners.remove(l);
- windowListeners = clonedListeners;
- }
-
- public WindowListener getWindowListener(int index) {
- ArrayList clonedListeners = (ArrayList) windowListeners.clone();
- if(0>index) {
- index = clonedListeners.size()-1;
- }
- return (WindowListener) clonedListeners.get(index);
- }
+ void removeMouseListener(MouseListener l);
- public WindowListener[] getWindowListeners() {
- return (WindowListener[]) windowListeners.toArray();
- }
-
- protected void consumeWindowEvent(WindowEvent e) {
- if(DEBUG_WINDOW_EVENT) {
- System.err.println("consumeWindowEvent: "+e);
- }
- for(Iterator i = windowListeners.iterator(); i.hasNext(); ) {
- WindowListener l = (WindowListener) i.next();
- switch(e.getEventType()) {
- case WindowEvent.EVENT_WINDOW_RESIZED:
- l.windowResized(e);
- break;
- case WindowEvent.EVENT_WINDOW_MOVED:
- l.windowMoved(e);
- break;
- case WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY:
- l.windowDestroyNotify(e);
- break;
- case WindowEvent.EVENT_WINDOW_GAINED_FOCUS:
- l.windowGainedFocus(e);
- break;
- case WindowEvent.EVENT_WINDOW_LOST_FOCUS:
- l.windowLostFocus(e);
- break;
- case WindowEvent.EVENT_WINDOW_REPAINT:
- l.windowRepaint((WindowUpdateEvent)e);
- break;
- default:
- throw
- new NativeWindowException("Unexpected window event type "
- + e.getEventType());
- }
- }
- }
+ MouseListener getMouseListener(int index);
- /**
- * @param focusGained
- */
- protected void focusChanged(boolean focusGained) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.focusChanged: "+focusGained);
- }
- if (focusGained) {
- sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
- } else {
- sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS);
- }
- }
-
- protected void visibleChanged(boolean visible) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
- // Exception e = new Exception("Window.visibleChanged ("+getThreadName()+"): "+this.visible+" -> "+visible+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
- // e.printStackTrace();
- }
- this.visible = visible ;
- }
+ MouseListener[] getMouseListeners();
- protected void sizeChanged(int newWidth, int newHeight) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.sizeChanged: "+width+"x"+height+" -> "+newWidth+"x"+newHeight);
- }
- if(width != newWidth || height != newHeight) {
- width = newWidth;
- height = newHeight;
- if(!fullscreen) {
- nfs_width=width;
- nfs_height=height;
- }
- sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
- }
- }
-
- protected void positionChanged(int newX, int newY) {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.positionChanged: "+x+"/"+y+" -> "+newX+"/"+newY);
- }
- if( 0==parentWindowHandle && ( x != newX || y != newY ) ) {
- x = newX;
- y = newY;
- if(!fullscreen) {
- nfs_x=x;
- nfs_y=y;
- }
- sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
- }
- }
-
- /**
- * If set to true, the default value, this NEWT Window implementation will
- * handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br>
- * If set to false, it's up to the caller/owner to handle destruction within {@link #windowDestroyNotify()}.
- */
- public void setHandleDestroyNotify(boolean b) {
- handleDestroyNotify = b;
- }
-
- protected void windowDestroyNotify() {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyNotify START "+getThreadName());
- }
-
- enqueueWindowEvent(false, WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY);
-
- if(handleDestroyNotify && isValid()) {
- destroy();
- }
-
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyeNotify END "+getThreadName());
- }
- }
-
- protected void windowDestroyed() {
- if(DEBUG_IMPLEMENTATION) {
- System.err.println("Window.windowDestroyed "+getThreadName());
- }
- invalidate();
- }
-
- public boolean getPropagateRepaint() {
- return propagateRepaint;
- }
- public void setPropagateRepaint(boolean v) {
- propagateRepaint = v;
- }
- protected boolean propagateRepaint = true;
-
- public void windowRepaint(int x, int y, int width, int height) {
- if(!propagateRepaint) {
- return;
- }
- if(0>width) {
- width=this.width;
- }
- if(0>height) {
- height=this.height;
- }
-
- NEWTEvent e = new WindowUpdateEvent(WindowEvent.EVENT_WINDOW_REPAINT, this, System.currentTimeMillis(),
- new Rectangle(x, y, width, height));
- doEvent(false, false, e);
- }
-
- protected boolean reparentWindowImpl() {
- // default implementation, no native reparenting support
- return false;
- }
-
- //
- // Reflection helper ..
- //
-
- private static Class[] getCustomConstructorArgumentTypes(Class windowClass) {
- Class[] argTypes = null;
- try {
- Method m = windowClass.getDeclaredMethod("getCustomConstructorArgumentTypes", new Class[] {});
- argTypes = (Class[]) m.invoke(null, null);
- } catch (Throwable t) {}
- return argTypes;
- }
-
- private static int verifyConstructorArgumentTypes(Class[] types, Object[] args) {
- if(types.length != args.length) {
- return -1;
- }
- for(int i=0; i<args.length; i++) {
- if(!types[i].isInstance(args[i])) {
- return i;
- }
- }
- return args.length;
- }
-
- private static String getArgsStrList(Object[] args) {
- StringBuffer sb = new StringBuffer();
- for(int i=0; i<args.length; i++) {
- sb.append(args[i].getClass());
- if(i<args.length) {
- sb.append(", ");
- }
- }
- return sb.toString();
- }
-
- private static String getTypeStrList(Class[] types) {
- StringBuffer sb = new StringBuffer();
- for(int i=0; i<types.length; i++) {
- sb.append(types[i]);
- if(i<types.length) {
- sb.append(", ");
- }
- }
- return sb.toString();
- }
-
- protected RecursiveToolkitLock windowLock = new RecursiveToolkitLock();
-
- private static final boolean TRACE_LOCK = false;
-
- protected final void windowLock() {
- getInnerWindow().windowLock.lock();
- if(TRACE_LOCK) {
- Exception e = new Exception("WINDOW LOCK SET: R "+getInnerWindow().windowLock.getRecursionCount()+", "+getInnerWindow().windowLock);
- e.printStackTrace();
- }
- }
- protected final void windowUnlock() {
- getInnerWindow().windowLock.unlock();
- if(TRACE_LOCK) {
- Exception e = new Exception("WINDOW LOCK FREE: R "+getInnerWindow().windowLock.getRecursionCount()+", "+getInnerWindow().windowLock);
- e.printStackTrace();
- }
- }
- protected final boolean windowIsLocked() {
- return getInnerWindow().windowLock.isLocked();
- }
- protected RecursiveToolkitLock getWindowLock() {
- return getInnerWindow().windowLock;
- }
- protected final void shouldNotCallThis() {
- throw new NativeWindowException("Should not call this");
- }
-
- public static String getThreadName() {
- return Display.getThreadName();
- }
-
- public static String toHexString(int hex) {
- return Display.toHexString(hex);
- }
-
- public static String toHexString(long hex) {
- return Display.toHexString(hex);
- }
}
-