summaryrefslogtreecommitdiffstats
path: root/src/newt
diff options
context:
space:
mode:
Diffstat (limited to 'src/newt')
-rw-r--r--src/newt/classes/com/jogamp/newt/Display.java7
-rw-r--r--src/newt/classes/com/jogamp/newt/NewtFactory.java140
-rw-r--r--src/newt/classes/com/jogamp/newt/Screen.java14
-rw-r--r--src/newt/classes/com/jogamp/newt/Window.java76
-rw-r--r--src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java297
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java98
-rwxr-xr-xsrc/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java46
-rw-r--r--src/newt/classes/com/jogamp/newt/event/InputEvent.java5
-rw-r--r--src/newt/classes/com/jogamp/newt/event/KeyEvent.java4
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseEvent.java14
-rw-r--r--src/newt/classes/com/jogamp/newt/event/MouseListener.java2
-rw-r--r--src/newt/classes/com/jogamp/newt/event/NEWTEvent.java1
-rw-r--r--src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java6
-rw-r--r--src/newt/classes/com/jogamp/newt/opengl/GLWindow.java81
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MainThread.java32
-rw-r--r--src/newt/classes/com/jogamp/newt/util/MonitorMode.java5
-rw-r--r--src/newt/classes/jogamp/newt/NEWTJNILibLoader.java4
-rw-r--r--src/newt/classes/jogamp/newt/OffscreenWindow.java37
-rw-r--r--src/newt/classes/jogamp/newt/ScreenImpl.java138
-rw-r--r--src/newt/classes/jogamp/newt/WindowImpl.java370
-rw-r--r--src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java (renamed from src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java)36
-rw-r--r--src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java24
-rw-r--r--src/newt/classes/jogamp/newt/driver/DriverClearFocus.java12
-rw-r--r--src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java9
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java16
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java6
-rw-r--r--src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java10
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java8
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java31
-rw-r--r--src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java39
-rw-r--r--src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java18
-rw-r--r--src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java21
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java23
-rw-r--r--src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java14
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/KDScreen.java22
-rw-r--r--src/newt/classes/jogamp/newt/driver/kd/KDWindow.java11
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java4
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java262
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java72
-rw-r--r--src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java450
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java28
-rw-r--r--src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java57
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/X11Display.java34
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/X11Screen.java60
-rw-r--r--src/newt/classes/jogamp/newt/driver/x11/X11Window.java73
-rw-r--r--src/newt/native/KDWindow.c2
-rw-r--r--src/newt/native/KeyEvent.h27
-rw-r--r--src/newt/native/MacWindow.m295
-rw-r--r--src/newt/native/MouseEvent.h27
-rw-r--r--src/newt/native/NewtCommon.h27
-rw-r--r--src/newt/native/NewtMacWindow.h10
-rw-r--r--src/newt/native/NewtMacWindow.m111
-rw-r--r--src/newt/native/ScreenMode.h28
-rw-r--r--src/newt/native/Window.h27
-rw-r--r--src/newt/native/WindowEvent.h27
-rw-r--r--src/newt/native/WindowsWindow.c111
-rw-r--r--src/newt/native/X11Common.h80
-rw-r--r--src/newt/native/X11Display.c660
-rw-r--r--src/newt/native/X11Screen.c469
-rw-r--r--src/newt/native/X11Window.c1115
61 files changed, 3617 insertions, 2120 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java
index 6a0ebe14a..7b6849a30 100644
--- a/src/newt/classes/com/jogamp/newt/Display.java
+++ b/src/newt/classes/com/jogamp/newt/Display.java
@@ -30,7 +30,6 @@ package com.jogamp.newt;
import com.jogamp.newt.util.EDTUtil;
import jogamp.newt.Debug;
-import jogamp.newt.DisplayImpl;
import java.util.*;
@@ -130,7 +129,10 @@ public abstract class Display {
public abstract int getId();
/**
- * @return this display instance name as defined at creation time
+ * @return This display connection name as defined at creation time.
+ * The display connection name is a technical platform specific detail, see {@link AbstractGraphicsDevice#getConnection()}.
+ *
+ * @see AbstractGraphicsDevice#getConnection()
*/
public abstract String getName();
@@ -198,6 +200,7 @@ public abstract class Display {
}
/** Returns the global display collection */
+ @SuppressWarnings("unchecked")
public static Collection<Display> getAllDisplays() {
ArrayList<Display> list;
synchronized(displayList) {
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java
index d3be098c0..4e6fa1aa5 100644
--- a/src/newt/classes/com/jogamp/newt/NewtFactory.java
+++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java
@@ -34,14 +34,19 @@
package com.jogamp.newt;
-import javax.media.nativewindow.*;
-
-import com.jogamp.common.os.Platform;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowFactory;
+import jogamp.newt.Debug;
import jogamp.newt.DisplayImpl;
import jogamp.newt.ScreenImpl;
import jogamp.newt.WindowImpl;
-import jogamp.newt.Debug;
+
+import com.jogamp.common.os.Platform;
public class NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
@@ -49,7 +54,6 @@ public class NewtFactory {
// Work-around for initialization order problems on Mac OS X
// between native Newt and (apparently) Fmod
static {
- Platform.initSingleton();
NativeWindowFactory.initSingleton(false); // last resort ..
WindowImpl.init(NativeWindowFactory.getNativeWindowType(true));
}
@@ -80,53 +84,124 @@ public class NewtFactory {
public static boolean useEDT() { return useEDT; }
/**
- * Create a Display entity, incl native creation
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused.
+ * </p>
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @return the new or reused Display instance
*/
public static Display createDisplay(String name) {
return createDisplay(name, true);
}
+ /**
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused
+ * <b>if</b> <code>reuse</code> is <code>true</code>, otherwise a new instance is being created.
+ * </p>
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @param reuse attempt to reuse an existing Display with same <code>name</code> if set true, otherwise create a new instance.
+ * @return the new or reused Display instance
+ */
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
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused.
+ * </p>
+ * @param type explicit NativeWindow type eg. {@link NativeWindowFactory#TYPE_AWT}
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @return the new or reused Display instance
*/
public static Display createDisplay(String type, String name) {
return createDisplay(type, name, true);
}
+ /**
+ * Create a Display entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Display#addReference()}.
+ * </p>
+ * <p>
+ * An already existing display connection of the same <code>name</code> will be reused
+ * <b>if</b> <code>reuse</code> is <code>true</code>, otherwise a new instance is being created.
+ * </p>
+ * @param type explicit NativeWindow type eg. {@link NativeWindowFactory#TYPE_AWT}
+ * @param name the display connection name which is a technical platform specific detail,
+ * see {@link AbstractGraphicsDevice#getConnection()}. Use <code>null</code> for default.
+ * @param reuse attempt to reuse an existing Display with same <code>name</code> if set true, otherwise create a new instance.
+ * @return the new or reused Display instance
+ */
public static Display createDisplay(String type, String name, boolean reuse) {
return DisplayImpl.create(type, name, 0, reuse);
}
/**
- * Create a Screen entity, incl native creation
+ * Create a Screen entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Screen#addReference()}.
+ * </p>
+ * <p>
+ * The lifecycle of this Screen's Display is handled via {@link Display#addReference()}
+ * and {@link Display#removeReference()}.
+ * </p>
*/
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)}.
+ * Create a top level Window entity on the default Display and default Screen.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Window#setVisible(boolean)}.
+ * </p>
+ * <p>
+ * An already existing default Display will be reused.
+ * </p>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static Window createWindow(CapabilitiesImmutable caps) {
return createWindowImpl(NativeWindowFactory.getNativeWindowType(true), caps);
}
/**
- * Create a top level Window entity, incl native creation
+ * Create a top level Window entity.
+ * <p>
+ * Native creation is lazily done at usage, ie. {@link Window#setVisible(boolean)}.
+ * </p>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static Window createWindow(Screen screen, CapabilitiesImmutable 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>
+ * Create a child Window entity attached to the given parent.<br>
+ * The Screen and Display information is regenerated utilizing the parents information,
+ * while reusing an existing Display.<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>
@@ -138,38 +213,41 @@ public class NewtFactory {
* 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>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*
* @param parentWindowObject either a NativeWindow instance
*/
- public static Window createWindow(NativeWindow nParentWindow, CapabilitiesImmutable caps) {
+ public static Window createWindow(NativeWindow parentWindow, CapabilitiesImmutable caps) {
final String type = NativeWindowFactory.getNativeWindowType(true);
-
Screen screen = null;
- Window parentWindow = null;
+ Window newtParentWindow = null;
- if ( nParentWindow instanceof Window ) {
+ if ( parentWindow instanceof Window ) {
// use parent NEWT Windows Display/Screen
- parentWindow = (Window) nParentWindow ;
- screen = parentWindow.getScreen();
+ newtParentWindow = (Window) parentWindow ;
+ screen = newtParentWindow.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());
+ AbstractGraphicsConfiguration parentConfig = parentWindow.getGraphicsConfiguration();
+ if(null!=parentConfig) {
+ AbstractGraphicsScreen parentScreen = parentConfig.getScreen();
+ AbstractGraphicsDevice parentDevice = parentScreen.getDevice();
+ Display display = NewtFactory.createDisplay(type, parentDevice.getHandle(), true);
+ screen = NewtFactory.createScreen(display, parentScreen.getIndex());
} else {
Display display = NewtFactory.createDisplay(type, null, true); // local display
screen = NewtFactory.createScreen(display, 0); // screen 0
}
}
- final Window win = createWindowImpl(nParentWindow, screen, caps);
+ final Window win = createWindowImpl(parentWindow, screen, caps);
- win.setSize(nParentWindow.getWidth(), nParentWindow.getHeight());
- if ( null != parentWindow ) {
- parentWindow.addChild(win);
- win.setVisible(parentWindow.isVisible());
+ win.setSize(parentWindow.getWidth(), parentWindow.getHeight());
+ if ( null != newtParentWindow ) {
+ newtParentWindow.addChild(win);
+ win.setVisible(newtParentWindow.isVisible());
}
return win;
}
diff --git a/src/newt/classes/com/jogamp/newt/Screen.java b/src/newt/classes/com/jogamp/newt/Screen.java
index d25d3e7ac..26f19ad6b 100644
--- a/src/newt/classes/com/jogamp/newt/Screen.java
+++ b/src/newt/classes/com/jogamp/newt/Screen.java
@@ -120,12 +120,22 @@ public abstract class Screen {
public abstract int getIndex();
/**
- * @return the current screen width
+ * @return the x position of the virtual top-left origin.
+ */
+ public abstract int getX();
+
+ /**
+ * @return the y position of the virtual top-left origin.
+ */
+ public abstract int getY();
+
+ /**
+ * @return the <b>rotated</b> virtual width.
*/
public abstract int getWidth();
/**
- * @return the current screen height
+ * @return the <b>rotated</b> virtual height.
*/
public abstract int getHeight();
diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java
index a78f81668..32024a49a 100644
--- a/src/newt/classes/com/jogamp/newt/Window.java
+++ b/src/newt/classes/com/jogamp/newt/Window.java
@@ -30,12 +30,13 @@ package com.jogamp.newt;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.InputEvent;
import com.jogamp.newt.event.MouseListener;
import jogamp.newt.Debug;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeWindow;
-import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.WindowClosingProtocol;
/**
@@ -133,6 +134,11 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
boolean isVisible();
+ /**
+ * If the implementation uses delegation, return the delegated {@link Window} instance,
+ * otherwise return <code>this</code> instance. */
+ Window getDelegatedWindow();
+
//
// Child Window Management
//
@@ -310,16 +316,46 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
}
/**
- * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus.
+ * Sets a {@link FocusRunnable},
+ * which {@link FocusRunnable#run()} method is executed before the native focus is requested.
+ * <p>
* This allows notifying a covered window toolkit like AWT that the focus is requested,
* hence focus traversal can be made transparent.
+ * </p>
*/
void setFocusAction(FocusRunnable focusAction);
+
+ /**
+ * Sets a {@link KeyListener} allowing focus traversal with a covered window toolkit like AWT.
+ * <p>
+ * The {@link KeyListener} methods are invoked prior to all other {@link KeyListener}'s
+ * allowing to suppress the {@link KeyEvent} via the {@link InputEvent#consumedTag}.
+ * </p>
+ * @param l
+ */
+ void setKeyboardFocusHandler(KeyListener l);
+ /**
+ * Request focus for this native window
+ * <p>
+ * The request is handled on this Window EDT and blocked until finished.
+ * </p>
+ *
+ * @see #requestFocus(boolean)
+ */
void requestFocus();
- boolean hasFocus();
-
+ /**
+ * Request focus for this native window
+ * <p>
+ * The request is handled on this Window EDT.
+ * </p>
+ *
+ * @param wait true if waiting until the request is executed, otherwise false
+ * @see #requestFocus()
+ */
+ void requestFocus(boolean wait);
+
void windowRepaint(int x, int y, int width, int height);
void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event);
@@ -328,38 +364,6 @@ public interface Window extends NativeWindow, WindowClosingProtocol {
//
- // 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
//
diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
index 31d42d21b..a71c6106d 100644
--- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
+++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java
@@ -29,42 +29,56 @@
package com.jogamp.newt.awt;
-import com.jogamp.newt.Display;
-import java.lang.reflect.*;
-import java.security.*;
-
+import java.awt.AWTKeyStroke;
import java.awt.Canvas;
-import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.KeyboardFocusManager;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Set;
import javax.media.nativewindow.NativeWindow;
-import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.OffscreenLayerOption;
import javax.media.nativewindow.WindowClosingProtocol;
import javax.media.nativewindow.awt.AWTWindowClosingProtocol;
+import javax.swing.MenuSelectionManager;
+
import jogamp.nativewindow.awt.AWTMisc;
+import jogamp.nativewindow.jawt.JAWTWindow;
+import jogamp.newt.Debug;
+import jogamp.newt.awt.NewtFactoryAWT;
+import jogamp.newt.awt.event.AWTParentWindowAdapter;
+import jogamp.newt.driver.DriverClearFocus;
-import com.jogamp.newt.event.awt.AWTAdapter;
-import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.Display;
import com.jogamp.newt.Window;
+import com.jogamp.newt.event.InputEvent;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.WindowAdapter;
+import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
-import jogamp.newt.Debug;
-import jogamp.newt.awt.event.AWTParentWindowAdapter;
-import jogamp.newt.awt.event.NewtFactoryAWT;
-
-import javax.swing.MenuSelectionManager;
+import com.jogamp.newt.event.awt.AWTAdapter;
+import com.jogamp.newt.event.awt.AWTKeyAdapter;
+import com.jogamp.newt.event.awt.AWTMouseAdapter;
@SuppressWarnings("serial")
-public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol {
+public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol, OffscreenLayerOption {
public static final boolean DEBUG = Debug.debug("Window");
- NativeWindow nativeWindow = null;
- Window newtChild = null;
- int newtChildCloseOp;
- AWTAdapter awtAdapter = null;
-
+ private JAWTWindow jawtWindow = null;
+ private boolean shallUseOffscreenLayer = false;
+ private Window newtChild = null;
+ private boolean isOnscreen = true;
+ private int newtChildCloseOp;
+ private AWTAdapter awtAdapter = null;
+ private AWTAdapter awtMouseAdapter = null;
+ private AWTAdapter awtKeyAdapter = null;
+
private AWTWindowClosingProtocol awtWindowClosingProtocol =
new AWTWindowClosingProtocol(this, new Runnable() {
public void run() {
@@ -102,53 +116,136 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
setNEWTChild(child);
}
+ public void setShallUseOffscreenLayer(boolean v) {
+ shallUseOffscreenLayer = v;
+ }
+
+ public final boolean getShallUseOffscreenLayer() {
+ return shallUseOffscreenLayer;
+ }
+
+ public final boolean isOffscreenLayerSurfaceEnabled() {
+ return jawtWindow.isOffscreenLayerSurfaceEnabled();
+ }
+
+ /**
+ * Returns true if the AWT component is parented to an {@link java.applet.Applet},
+ * otherwise false. This information is valid only after {@link #addNotify()} is issued,
+ * ie. before adding the component to the AWT tree and make it visible.
+ */
+ public boolean isApplet() {
+ return jawtWindow.isApplet();
+ }
+
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);
- }
- /**
- // wait for AWT focus !
- for(long sleep = Window.TIMEOUT_NATIVEWINDOW; 0<sleep && !isFocusOwner(); sleep-=10 ) {
- try { Thread.sleep(10); } catch (InterruptedException e) { }
- } */
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusAction: "+Display.getThreadName()+", isOnscreen "+isOnscreen+", hasFocus "+hasFocus());
}
- 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();
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ if(!hasFocus()) {
+ // Acquire the AWT focus 1st for proper AWT traversal
+ NewtCanvasAWT.super.requestFocus();
+ }
+ if(isOnscreen) {
+ // Remove the AWT focus in favor of the native NEWT focus
KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
}
+ return false; // NEWT shall proceed requesting the native focus
}
- FocusActionImpl focusActionImpl = new FocusActionImpl();
}
- FocusAction focusAction = new FocusAction();
+ private FocusAction focusAction = new FocusAction();
WindowListener clearAWTMenusOnNewtFocus = new WindowAdapter() {
@Override
public void windowGainedFocus(WindowEvent arg0) {
- MenuSelectionManager.defaultManager().clearSelectedPath();
+ MenuSelectionManager.defaultManager().clearSelectedPath();
}
};
- /** sets a new NEWT child, provoking reparenting on the NEWT level. */
- /*package */ NewtCanvasAWT setNEWTChild(Window child) {
+ class FocusTraversalKeyListener implements KeyListener {
+ boolean suppress = false;
+
+ public void keyPressed(KeyEvent e) {
+ handleKey(e, false);
+ }
+ public void keyReleased(KeyEvent e) {
+ handleKey(e, true);
+ }
+ public void keyTyped(KeyEvent e) {
+ if(suppress) {
+ e.setAttachment(InputEvent.consumedTag);
+ suppress = false; // reset
+ }
+ }
+
+ void handleKey(KeyEvent evt, boolean onRelease) {
+ if(null == keyboardFocusManager) {
+ throw new InternalError("XXX");
+ }
+ final AWTKeyStroke ks = AWTKeyStroke.getAWTKeyStroke(evt.getKeyCode(), evt.getModifiers(), onRelease);
+ if(null != ks) {
+ final Set<AWTKeyStroke> fwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
+ final Set<AWTKeyStroke> bwdKeys = keyboardFocusManager.getDefaultFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS);
+ if(fwdKeys.contains(ks)) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey (fwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ }
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ NewtCanvasAWT.this.transferFocus();
+ suppress = true;
+ } else if(bwdKeys.contains(ks)) {
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey (bwd): "+ks+", current focusOwner "+keyboardFocusManager.getFocusOwner());
+ }
+ // Newt-EDT -> AWT-EDT may freeze Window's native peer requestFocus.
+ NewtCanvasAWT.this.transferFocusBackward();
+ suppress = true;
+ }
+ }
+ if(suppress) {
+ evt.setAttachment(InputEvent.consumedTag);
+ }
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.focusKey: XXX: "+ks);
+ }
+ }
+ }
+ private final FocusTraversalKeyListener newtFocusTraversalKeyListener = new FocusTraversalKeyListener();
+
+ class FocusPropertyChangeListener implements PropertyChangeListener {
+ public void propertyChange(PropertyChangeEvent evt) {
+ final Object oldF = evt.getOldValue();
+ final Object newF = evt.getNewValue();
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: "+evt.getPropertyName()+", src "+evt.getSource()+", "+oldF+" -> "+newF);
+ }
+ if(oldF == NewtCanvasAWT.this && newF == null) {
+ // focus traversal to NEWT - NOP
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: NEWT focus traversal");
+ }
+ } else if(null != newF && newF != NewtCanvasAWT.this) {
+ // focus traversal to another AWT component
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.FocusProperty: lost focus - clear focus");
+ }
+ if(newtChild.getDelegatedWindow() instanceof DriverClearFocus) {
+ ((DriverClearFocus)newtChild.getDelegatedWindow()).clearFocus();
+ }
+ }
+ }
+ }
+ private final FocusPropertyChangeListener focusPropertyChangeListener = new FocusPropertyChangeListener();
+ private volatile KeyboardFocusManager keyboardFocusManager = null;
+
+ /** sets a new NEWT child, provoking reparenting. */
+ private NewtCanvasAWT setNEWTChild(Window child) {
if(newtChild!=child) {
newtChild = child;
- if(null!=nativeWindow) {
- java.awt.Container cont = AWTMisc.getContainer(this);
+ if(isDisplayable()) {
// reparent right away, addNotify has been called already
+ final java.awt.Container cont = AWTMisc.getContainer(this);
reparentWindow( (null!=child) ? true : false, cont );
}
}
@@ -162,8 +259,8 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
/** @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; }
-
+ public NativeWindow getNativeWindow() { return jawtWindow; }
+
public int getDefaultCloseOperation() {
return awtWindowClosingProtocol.getDefaultCloseOperation();
}
@@ -177,13 +274,41 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
awtAdapter.removeFrom(this);
awtAdapter=null;
}
+ if(null!=awtMouseAdapter) {
+ awtMouseAdapter.removeFrom(this);
+ awtMouseAdapter = null;
+ }
+ if(null!=awtKeyAdapter) {
+ awtKeyAdapter.removeFrom(this);
+ awtKeyAdapter = null;
+ }
+ newtChild.setKeyboardFocusHandler(null);
+ if(null != keyboardFocusManager) {
+ keyboardFocusManager.removePropertyChangeListener("focusOwner", focusPropertyChangeListener);
+ keyboardFocusManager = null;
+ }
+
if( null != newtChild ) {
if(attach) {
+ if(null == jawtWindow.getGraphicsConfiguration()) {
+ throw new InternalError("XXX");
+ }
+ isOnscreen = jawtWindow.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this);
newtChild.addWindowListener(clearAWTMenusOnNewtFocus);
newtChild.setFocusAction(focusAction); // enable AWT focus traversal
newtChildCloseOp = newtChild.setDefaultCloseOperation(WindowClosingProtocol.DO_NOTHING_ON_CLOSE);
awtWindowClosingProtocol.addClosingListenerOneShot();
+ keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+ keyboardFocusManager.addPropertyChangeListener("focusOwner", focusPropertyChangeListener);
+ if(isOnscreen) {
+ // onscreen newt child needs to fwd AWT focus
+ newtChild.setKeyboardFocusHandler(newtFocusTraversalKeyListener);
+ } else {
+ // offscreen newt child requires AWT to fwd AWT key/mouse event
+ awtMouseAdapter = new AWTMouseAdapter(newtChild).addTo(this);
+ awtKeyAdapter = new AWTKeyAdapter(newtChild).addTo(this);
+ }
} else {
newtChild.removeWindowListener(clearAWTMenusOnNewtFocus);
newtChild.setFocusAction(null);
@@ -232,26 +357,47 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
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);
- configureNewtChild(true);
- newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
- newtChild.windowRepaint(0, 0, w, h);
+ jawtWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities());
+ jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer);
+ if(DEBUG) {
+ System.err.println("NewtCanvasAWT.reparentWindow: newtChild: "+newtChild);
+ }
+ final int w;
+ final int h;
+ if(isPreferredSizeSet()) {
+ java.awt.Dimension d = getPreferredSize();
+ w = d.width;
+ h = d.height;
+ } else {
+ final java.awt.Dimension min;
+ if(this.isMinimumSizeSet()) {
+ min = getMinimumSize();
+ } else {
+ min = new java.awt.Dimension(0, 0);
+ }
+ java.awt.Insets ins = cont.getInsets();
+ w = Math.max(min.width, cont.getWidth() - ins.left - ins.right);
+ h = Math.max(min.height, cont.getHeight() - ins.top - ins.bottom);
}
+ setSize(w, h);
+ newtChild.setSize(w, h);
+ newtChild.reparentWindow(jawtWindow);
+ newtChild.setVisible(true);
+ configureNewtChild(true);
+ newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener
+ newtChild.windowRepaint(0, 0, w, h);
+
+ // force this AWT Canvas to be focus-able,
+ // since this it is completely covered by the newtChild (z-order).
+ setFocusable(true);
} else {
- configureNewtChild(false);
- nativeWindow = null;
+ configureNewtChild(false);
newtChild.setVisible(false);
newtChild.reparentWindow(null);
+ if(null != jawtWindow) {
+ NewtFactoryAWT.destroyNativeWindow(jawtWindow);
+ jawtWindow=null;
+ }
}
}
@@ -273,7 +419,10 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont);
}
configureNewtChild(false);
- nativeWindow = null;
+ if(null!=jawtWindow) {
+ NewtFactoryAWT.destroyNativeWindow(jawtWindow);
+ jawtWindow=null;
+ }
newtChild.setVisible(false);
newtChild.reparentWindow(null);
newtChild.destroy();
@@ -282,7 +431,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
cont.remove(this);
}
}
- }
+ }
@Override
public void paint(Graphics g) {
@@ -299,14 +448,12 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto
}
}
- final void requestFocusAWTParent() {
- super.requestFocusInWindow();
- }
-
- final void requestFocusNEWTChild() {
+ private final void requestFocusNEWTChild() {
if(null!=newtChild) {
newtChild.setFocusAction(null);
- KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ if(isOnscreen) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
+ }
newtChild.requestFocus();
newtChild.setFocusAction(focusAction);
}
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
index 2e86cb512..a052f6f97 100755
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtApplet1Run.java
@@ -1,20 +1,48 @@
+/**
+ * Copyright 2011 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.applet;
-import java.applet.*;
+import java.applet.Applet;
+import java.awt.BorderLayout;
+import java.awt.Button;
import java.awt.Component;
import java.awt.Container;
-import java.awt.Label;
+import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
-import java.awt.event.KeyListener;
-import javax.media.opengl.*;
+import javax.media.opengl.FPSCounter;
+import javax.media.opengl.GLCapabilities;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLProfile;
import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
-import java.awt.BorderLayout;
-
-import jogamp.newt.Debug;
/**
* Simple GLEventListener deployment as an applet using JOGL. This demo must be
@@ -62,7 +90,7 @@ import jogamp.newt.Debug;
*/
@SuppressWarnings("serial")
public class JOGLNewtApplet1Run extends Applet {
- public static final boolean DEBUG = Debug.debug("Applet");
+ public static final boolean DEBUG = JOGLNewtAppletBase.DEBUG;
GLWindow glWindow;
NewtCanvasAWT newtCanvasAWT;
@@ -72,6 +100,9 @@ public class JOGLNewtApplet1Run extends Applet {
boolean glStandalone = false;
public void init() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.init() START");
+ }
if(!(this instanceof Container)) {
throw new RuntimeException("This Applet is not a AWT Container");
}
@@ -88,6 +119,7 @@ public class JOGLNewtApplet1Run extends Applet {
int glAlphaBits=0;
int glNumMultisampleBuffer=0;
boolean glNoDefaultKeyListener = false;
+ boolean appletDebugTestBorder = false;
try {
glEventListenerClazzName = getParameter("gl_event_listener_class");
glProfileName = getParameter("gl_profile");
@@ -104,6 +136,7 @@ public class JOGLNewtApplet1Run extends Applet {
glWidth = JOGLNewtAppletBase.str2Int(getParameter("gl_width"), glWidth);
glHeight = JOGLNewtAppletBase.str2Int(getParameter("gl_height"), glHeight);
glNoDefaultKeyListener = JOGLNewtAppletBase.str2Bool(getParameter("gl_nodefaultkeyListener"), glNoDefaultKeyListener);
+ appletDebugTestBorder = JOGLNewtAppletBase.str2Bool(getParameter("appletDebugTestBorder"), appletDebugTestBorder);
} catch (Exception e) {
e.printStackTrace();
}
@@ -137,7 +170,6 @@ public class JOGLNewtApplet1Run extends Applet {
glTrace);
try {
- GLProfile.initSingleton(false);
GLCapabilities caps = new GLCapabilities(GLProfile.get(glProfileName));
caps.setAlphaBits(glAlphaBits);
if(0<glNumMultisampleBuffer) {
@@ -149,18 +181,12 @@ public class JOGLNewtApplet1Run extends Applet {
glWindow.setUpdateFPSFrames(FPSCounter.DEFAULT_FRAMES_PER_INTERVAL, System.err);
glWindow.setUndecorated(glUndecorated);
glWindow.setAlwaysOnTop(glAlwaysOnTop);
- if(glStandalone) {
- newtCanvasAWT = null;
- } else {
- newtCanvasAWT = new NewtCanvasAWT(glWindow);
- container.setLayout(new BorderLayout());
- container.add(newtCanvasAWT, BorderLayout.CENTER);
- }
- if(DEBUG) {
- container.add(new Label("North"), BorderLayout.NORTH);
- container.add(new Label("South"), BorderLayout.SOUTH);
- container.add(new Label("East"), BorderLayout.EAST);
- container.add(new Label("West"), BorderLayout.WEST);
+ container.setLayout(new BorderLayout());
+ if(appletDebugTestBorder) {
+ container.add(new Button("North"), BorderLayout.NORTH);
+ container.add(new Button("South"), BorderLayout.SOUTH);
+ container.add(new Button("East"), BorderLayout.EAST);
+ container.add(new Button("West"), BorderLayout.WEST);
}
base.init(glWindow);
if(base.isValid()) {
@@ -176,12 +202,25 @@ public class JOGLNewtApplet1Run extends Applet {
addKeyListener((KeyListener)glEventListener);
}
}
+ if(glStandalone) {
+ newtCanvasAWT = null;
+ } else {
+ newtCanvasAWT = new NewtCanvasAWT(glWindow);
+ container.add(newtCanvasAWT, BorderLayout.CENTER);
+ container.validate();
+ }
} catch (Throwable t) {
throw new RuntimeException(t);
}
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.init() END");
+ }
}
public void start() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.start() START");
+ }
this.validate();
this.setVisible(true);
@@ -195,21 +234,35 @@ public class JOGLNewtApplet1Run extends Applet {
while (null != topC.getParent()) {
topC = topC.getParent();
}
+ System.err.println("JOGLNewtApplet1Run start:");
System.err.println("TopComponent: "+topC.getLocation()+" rel, "+topC.getLocationOnScreen()+" screen, visible "+topC.isVisible()+", "+topC);
System.err.println("Applet Pos: "+this.getLocation()+" rel, "+p0+" screen, visible "+this.isVisible()+", "+this);
if(null != newtCanvasAWT) {
System.err.println("NewtCanvasAWT Pos: "+newtCanvasAWT.getLocation()+" rel, "+newtCanvasAWT.getLocationOnScreen()+" screen, visible "+newtCanvasAWT.isVisible()+", "+newtCanvasAWT);
}
System.err.println("GLWindow Pos: "+glWindow.getX()+"/"+glWindow.getY()+" rel, "+glWindow.getLocationOnScreen(null)+" screen");
+ System.err.println("GLWindow: "+glWindow);
}
base.start();
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.start() END");
+ }
}
public void stop() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.stop() START");
+ }
base.stop();
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.stop() END");
+ }
}
public void destroy() {
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.destroy() START");
+ }
glWindow.setVisible(false); // hide 1st
if(!glStandalone) {
glWindow.reparentWindow(null); // get out of newtCanvasAWT
@@ -217,6 +270,9 @@ public class JOGLNewtApplet1Run extends Applet {
}
base.destroy(); // destroy glWindow unrecoverable
base=null;
+ if(DEBUG) {
+ System.err.println("JOGLNewtApplet1Run.destroy() END");
+ }
}
}
diff --git a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
index b1061dd14..67da50210 100755
--- a/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
+++ b/src/newt/classes/com/jogamp/newt/awt/applet/JOGLNewtAppletBase.java
@@ -1,18 +1,53 @@
+/**
+ * Copyright 2011 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.applet;
-import java.lang.reflect.*;
+import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.media.nativewindow.NativeWindow;
-import javax.media.opengl.*;
+import javax.media.opengl.FPSCounter;
+import javax.media.opengl.GL;
+import javax.media.opengl.GLAutoDrawable;
+import javax.media.opengl.GLEventListener;
+import javax.media.opengl.GLPipelineFactory;
import jogamp.newt.Debug;
-import com.jogamp.opengl.util.*;
-
-import com.jogamp.newt.event.*;
+import com.jogamp.newt.event.KeyEvent;
+import com.jogamp.newt.event.KeyListener;
+import com.jogamp.newt.event.MouseListener;
+import com.jogamp.newt.event.WindowEvent;
+import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.opengl.GLWindow;
+import com.jogamp.opengl.util.Animator;
+
/** Shows how to deploy an applet using JOGL. This demo must be
referenced from a web page via an &lt;applet&gt; tag. */
@@ -165,6 +200,7 @@ public class JOGLNewtAppletBase implements KeyListener, GLEventListener {
public void start() {
if(isValid) {
glWindow.setVisible(true);
+ glWindow.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED);
glAnimator.start();
awtParent = glWindow.getParent();
}
diff --git a/src/newt/classes/com/jogamp/newt/event/InputEvent.java b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
index 51ceccf31..d8a9235c1 100644
--- a/src/newt/classes/com/jogamp/newt/event/InputEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/InputEvent.java
@@ -48,6 +48,11 @@ public abstract class InputEvent extends NEWTEvent
public static final int CONFINED_MASK = 1 << 16;
public static final int INVISIBLE_MASK = 1 << 17;
+ /** Object when attached via {@link #setAttachment(Object)} marks the event consumed,
+ * ie. stops propagating the event any further to the event listener.
+ */
+ public static final Object consumedTag = new Object();
+
protected InputEvent(int eventType, Object source, long when, int modifiers) {
super(eventType, source, when);
this.modifiers=modifiers;
diff --git a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
index 9e4fe372b..44fcea49c 100644
--- a/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/KeyEvent.java
@@ -34,6 +34,7 @@
package com.jogamp.newt.event;
+@SuppressWarnings("serial")
public class KeyEvent extends InputEvent
{
public KeyEvent(int eventType, Object source, long when, int modifiers, int keyCode, char keyChar) {
@@ -42,9 +43,12 @@ public class KeyEvent extends InputEvent
this.keyChar=keyChar;
}
+ /** Only valid if delivered via {@link KeyListener#keyPressed(KeyEvent)} */
public char getKeyChar() {
return keyChar;
}
+
+ /** Always valid. */
public int getKeyCode() {
return keyCode;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
index ccc674f1d..9bc3be1e5 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseEvent.java
@@ -139,6 +139,20 @@ public class MouseEvent extends InputEvent
return pressure[index];
}
+ /**
+ * <i>Usually</i> a wheel rotation of <b>&gt; 0 is up</b>,
+ * and <b>&lt; 0 is down</b>.<br>
+ * <i>However</i>, on some OS this might be flipped due to the OS <i>default</i> behavior.
+ * The latter is true for OS X 10.7 (Lion) for example.
+ * <p>
+ * The events will be send usually in steps of one, ie. <i>-1</i> and <i>1</i>.
+ * Higher values may result due to fast scrolling.
+ * </p>
+ * <p>
+ * The button number refers to the wheel number.
+ * </p>
+ * @return
+ */
public int getWheelRotation() {
return wheelRotation;
}
diff --git a/src/newt/classes/com/jogamp/newt/event/MouseListener.java b/src/newt/classes/com/jogamp/newt/event/MouseListener.java
index 5ec086b94..7668b755c 100644
--- a/src/newt/classes/com/jogamp/newt/event/MouseListener.java
+++ b/src/newt/classes/com/jogamp/newt/event/MouseListener.java
@@ -43,6 +43,8 @@ public interface MouseListener extends NEWTEventListener
public void mouseReleased(MouseEvent e);
public void mouseMoved(MouseEvent e);
public void mouseDragged(MouseEvent e);
+
+ /** See {@link MouseEvent#getWheelRotation() } */
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
index 50aed2c8e..3f3817b91 100644
--- a/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
+++ b/src/newt/classes/com/jogamp/newt/event/NEWTEvent.java
@@ -46,6 +46,7 @@ package com.jogamp.newt.event;
* <li> KeyEvent <code>300..30x</code></li>
* </ul><br>
*/
+@SuppressWarnings("serial")
public class NEWTEvent extends java.util.EventObject {
private final boolean isSystemEvent;
private final int eventType;
diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
index ae7474c73..69b0d0482 100644
--- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
+++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java
@@ -107,6 +107,9 @@ public class AWTWindowAdapter
public void componentResized(java.awt.event.ComponentEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentResized: "+event);
+ }
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowResized(event);
} else {
@@ -116,6 +119,9 @@ public class AWTWindowAdapter
public void componentMoved(java.awt.event.ComponentEvent e) {
com.jogamp.newt.event.WindowEvent event = AWTNewtEventFactory.createWindowEvent(e, newtWindow);
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentMoved: "+event);
+ }
if(null!=newtListener) {
((com.jogamp.newt.event.WindowListener)newtListener).windowMoved(event);
} else {
diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
index 2cd8c2ced..92f57577d 100644
--- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java
@@ -41,6 +41,7 @@ import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.newt.*;
import com.jogamp.newt.event.*;
+
import jogamp.newt.WindowImpl;
import javax.media.nativewindow.*;
@@ -54,8 +55,8 @@ import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.util.Animator;
/**
- * An implementation of {@link javax.media.opengl.GLAutoDrawable} interface,
- * using an aggregation of a {@link com.jogamp.newt.Window} implementation.
+ * An implementation of {@link GLAutoDrawable} and {@link Window} interface,
+ * using a delegated {@link Window} instance, which may be an aggregation (lifecycle: created and destroyed).
* <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>
@@ -121,12 +122,13 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
}
/**
- * 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.
- * <P>
- * The default display connection will be used and reused if already in process.
+ * Creates a new GLWindow attaching a new Window referencing a
+ * new default Screen and default Display with the given GLCapabilities.
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
+ * The default Display will be reused if already instantiated.
*/
public static GLWindow create(GLCapabilitiesImmutable caps) {
return new GLWindow(NewtFactory.createWindow(caps));
@@ -135,8 +137,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
/**
* 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.
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static GLWindow create(Screen screen, GLCapabilitiesImmutable caps) {
return new GLWindow(NewtFactory.createWindow(screen, caps));
@@ -144,8 +148,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
/**
* Creates a new GLWindow attaching the given window.
- * <P>
- * The resulting GLWindow does not own the given Window, ie it will not be destructed.
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static GLWindow create(Window window) {
return new GLWindow(window);
@@ -154,11 +160,15 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
/**
* Creates a new GLWindow attaching a new child Window
* of the given <code>parentNativeWindow</code> with the given GLCapabilities.
- * <P>
+ * <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.
+ * An already instantiated compatible Display will be reused.
+ * </p>
+ * <p>
+ * The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()}
+ * and {@link Screen#removeReference()}.
+ * </p>
*/
public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilitiesImmutable caps) {
return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps));
@@ -195,8 +205,8 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
return window.getRequestedCapabilities();
}
- public final Window getWindow() {
- return window;
+ public final Window getDelegatedWindow() {
+ return window.getDelegatedWindow();
}
public final NativeWindow getParent() {
@@ -254,10 +264,18 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
window.setFocusAction(focusAction);
}
+ public void setKeyboardFocusHandler(KeyListener l) {
+ window.setKeyboardFocusHandler(l);
+ }
+
public final void requestFocus() {
window.requestFocus();
}
+ public final void requestFocus(boolean wait) {
+ window.requestFocus(wait);
+ }
+
public boolean hasFocus() {
return window.hasFocus();
}
@@ -288,7 +306,7 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
@Override
public final String toString() {
return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable +
- ", \n\tContext: " + context + /** ", \n\tWindow: "+window+", \n\tFactory: "+factory+ */ "]";
+ ", \n\tContext: " + context + ", \n\tWindow: "+window+ /** ", \n\tFactory: "+factory+ */ "]";
}
public final int reparentWindow(NativeWindow newParent) {
@@ -337,14 +355,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
// Hide methods here ..
protected class GLLifecycleHook implements WindowImpl.LifecycleHook {
- private class DisposeAction implements Runnable {
- public final void run() {
- // Lock: Covered by DestroyAction ..
- helper.dispose(GLWindow.this);
- }
- }
- DisposeAction disposeAction = new DisposeAction();
-
public synchronized void destroyActionPreLock() {
// nop
}
@@ -362,11 +372,10 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
// Catch dispose GLExceptions by GLEventListener, just 'print' them
// so we can continue with the destruction.
try {
- helper.invokeGL(drawable, context, disposeAction, null);
+ helper.disposeGL(GLWindow.this, drawable, context, null);
} catch (GLException gle) {
gle.printStackTrace();
}
- context.destroy();
}
drawable.setRealized(false);
}
@@ -399,11 +408,11 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
if (null == context && visible && 0 != window.getWindowHandle() && 0<getWidth()*getHeight()) {
NativeWindow nw;
if (window.getWrappedWindow() != null) {
- nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration());
+ nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getPrivateGraphicsConfiguration());
} else {
nw = window;
}
- GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities();
+ GLCapabilitiesImmutable glCaps = (GLCapabilitiesImmutable) nw.getGraphicsConfiguration().getChosenCapabilities();
if(null==factory) {
factory = GLDrawableFactory.getFactory(glCaps.getGLProfile());
}
@@ -753,18 +762,6 @@ public class GLWindow implements GLAutoDrawable, Window, NEWTEventConsumer, FPSC
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);
}
diff --git a/src/newt/classes/com/jogamp/newt/util/MainThread.java b/src/newt/classes/com/jogamp/newt/util/MainThread.java
index c7780b0d8..e71ef75ec 100644
--- a/src/newt/classes/com/jogamp/newt/util/MainThread.java
+++ b/src/newt/classes/com/jogamp/newt/util/MainThread.java
@@ -93,17 +93,21 @@ import jogamp.newt.NEWTJNILibLoader;
*/
public class MainThread {
private static final String MACOSXDisplayClassName = "jogamp.newt.driver.macosx.MacDisplay";
+ private static final Platform.OSType osType;
+ private static final boolean isMacOSX;
+
/** if true, use the main thread EDT, otherwise AWT's EDT */
public static final boolean HINT_USE_MAIN_THREAD;
static {
final AccessControlContext localACC = AccessController.getContext();
- Platform.initSingleton();
NativeWindowFactory.initSingleton(true);
NEWTJNILibLoader.loadNEWT();
HINT_USE_MAIN_THREAD = !NativeWindowFactory.isAWTAvailable() ||
- Debug.getBooleanProperty("newt.MainThread.force", true, localACC);
+ Debug.getBooleanProperty("newt.MainThread.force", true, localACC);
+ osType = Platform.getOSType();
+ isMacOSX = osType == Platform.OSType.MACOS;
}
public static boolean useMainThread = false;
@@ -132,7 +136,7 @@ public class MainThread {
try {
Class<?> mainClass = ReflectionUtil.getClass(mainClassName, true, getClass().getClassLoader());
if(null==mainClass) {
- throw new RuntimeException(new ClassNotFoundException("MainThread couldn't find main class "+mainClassName));
+ throw new RuntimeException(new ClassNotFoundException("MainAction couldn't find main class "+mainClassName));
}
try {
mainClassMain = mainClass.getDeclaredMethod("main", new Class[] { String[].class });
@@ -151,8 +155,23 @@ public class MainThread {
if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" user app fin");
if ( useMainThread ) {
- if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainThread fin - stop");
- System.exit(0);
+ if(isMacOSX) {
+ try {
+ if(DEBUG) {
+ System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.0");
+ }
+ ReflectionUtil.callStaticMethod(MACOSXDisplayClassName, "stopNSApplication",
+ null, null, MainThread.class.getClassLoader());
+ if(DEBUG) {
+ System.err.println("MainAction.main(): "+Thread.currentThread()+" MainAction fin - stopNSApp.X");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ } else {
+ if(DEBUG) System.err.println("MainAction.run(): "+Thread.currentThread().getName()+" MainAction fin - System.exit(0)");
+ System.exit(0);
+ }
}
}
}
@@ -164,9 +183,6 @@ public class MainThread {
useMainThread = HINT_USE_MAIN_THREAD;
- final Platform.OSType osType = Platform.getOSType();
- final boolean isMacOSX = osType == Platform.OSType.MACOS;
-
if(DEBUG) {
System.err.println("MainThread.main(): "+cur.getName()+
", useMainThread "+ useMainThread +
diff --git a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
index 5a8bf5bf2..8104f207a 100644
--- a/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
+++ b/src/newt/classes/com/jogamp/newt/util/MonitorMode.java
@@ -43,8 +43,9 @@ public class MonitorMode {
int refreshRate;
public MonitorMode(SurfaceSize surfaceSize, DimensionImmutable screenSizeMM, int refreshRate) {
- if(null==surfaceSize || refreshRate<=0) {
- throw new IllegalArgumentException("surfaceSize must be set and refreshRate greater 0");
+ // Don't validate screenSizeMM and refreshRate, since they may not be supported by the OS
+ if(null==surfaceSize) {
+ throw new IllegalArgumentException("surfaceSize must be set ("+surfaceSize+")");
}
this.surfaceSize=surfaceSize;
this.screenSizeMM=screenSizeMM;
diff --git a/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java b/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
index 1f5d5dd3d..78707e7cf 100644
--- a/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
+++ b/src/newt/classes/jogamp/newt/NEWTJNILibLoader.java
@@ -43,6 +43,7 @@ import java.security.AccessController;
import java.security.PrivilegedAction;
import com.jogamp.common.jvm.JNILibLoaderBase;
+import com.jogamp.common.os.Platform;
import com.jogamp.common.util.cache.TempJarCache;
public class NEWTJNILibLoader extends JNILibLoaderBase {
@@ -50,9 +51,10 @@ public class NEWTJNILibLoader extends JNILibLoaderBase {
public static void loadNEWT() {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
+ Platform.initSingleton();
final String libName = "newt";
if(TempJarCache.isInitialized() && null == TempJarCache.findLibrary(libName)) {
- addNativeJarLibs(NEWTJNILibLoader.class, "jogl.all", "jogl-all", new String[] { "nativewindow", "newt" } );
+ addNativeJarLibs(NEWTJNILibLoader.class, "jogl-all", new String[] { "nativewindow", "newt" } );
}
loadLibrary(libName, false);
return null;
diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java
index fa7bafe5b..050e24b6c 100644
--- a/src/newt/classes/jogamp/newt/OffscreenWindow.java
+++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java
@@ -48,18 +48,16 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
static long nextWindowHandle = 0x100; // start here - a marker
protected void createNativeImpl() {
- if(0!=getParentWindowHandle()) {
- throw new NativeWindowException("OffscreenWindow does not support window parenting");
- }
if(capsRequested.isOnscreen()) {
throw new NativeWindowException("Capabilities is onscreen");
}
- AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
- config = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(
- capsRequested, capsRequested, capabilitiesChooser, aScreen);
- if (config == null) {
+ final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aScreen.getDevice()).chooseGraphicsConfiguration(
+ capsRequested, capsRequested, capabilitiesChooser, aScreen);
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
synchronized(OffscreenWindow.class) {
setWindowHandle(nextWindowHandle++);
@@ -70,6 +68,10 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
// nop
}
+ public void surfaceSizeChanged(int width, int height) {
+ sizeChanged(false, width, height, false);
+ }
+
@Override
public synchronized void destroy() {
super.destroy();
@@ -89,29 +91,30 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable {
}
@Override
- public void setSize(int width, int height) {
- if(!isVisible()) {
- sizeChanged(false, width, height, false);
- }
- }
- @Override
public void setPosition(int x, int y) {
// nop
}
+
@Override
public boolean setFullscreen(boolean fullscreen) {
// nop
return false;
}
-
+
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
sizeChanged(false, width, height, false);
- visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
+ visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
} else {
- shouldNotCallThis();
+ /**
+ * silently ignore:
+ FLAG_CHANGE_PARENTING
+ FLAG_CHANGE_DECORATION
+ FLAG_CHANGE_FULLSCREEN
+ FLAG_CHANGE_ALWAYSONTOP
+ */
}
- return false;
+ return true;
}
@Override
diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java
index 9c51fe973..575de6112 100644
--- a/src/newt/classes/jogamp/newt/ScreenImpl.java
+++ b/src/newt/classes/jogamp/newt/ScreenImpl.java
@@ -34,6 +34,21 @@
package jogamp.newt;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.media.nativewindow.AbstractGraphicsScreen;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.DimensionImmutable;
+import javax.media.nativewindow.util.Point;
+import javax.media.nativewindow.util.SurfaceSize;
+
import com.jogamp.common.util.ArrayHashSet;
import com.jogamp.common.util.IntIntHashMap;
import com.jogamp.newt.Display;
@@ -44,14 +59,6 @@ import com.jogamp.newt.event.ScreenModeListener;
import com.jogamp.newt.util.MonitorMode;
import com.jogamp.newt.util.ScreenModeUtil;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.util.DimensionImmutable;
-import javax.media.nativewindow.util.SurfaceSize;
-
-import java.security.*;
-import java.util.ArrayList;
-import java.util.List;
-
public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected static final boolean DEBUG_TEST_SCREENMODE_DISABLED = Debug.isPropertyDefined("newt.test.Screen.disableScreenMode", true);
@@ -61,8 +68,10 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
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
+ protected Point vOrigin = new Point(0, 0); // virtual top-left origin
+ protected Dimension vSize = new Dimension(0, 0); // virtual rotated screen size
+ protected static Dimension usrSize = null; // property values: newt.ws.swidth and newt.ws.sheight
+ protected static volatile boolean usrSizeQueried = false;
private static AccessControlContext localACC = AccessController.getContext();
private ArrayList<ScreenModeListener> referencedScreenModeListener = new ArrayList<ScreenModeListener>();
long t0; // creationTime
@@ -100,32 +109,36 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return (Class<? extends Screen>)screenClass;
}
- public static Screen create(Display display, final int idx) {
+ public static Screen create(Display display, int idx) {
try {
- if(usrWidth<0 || usrHeight<0) {
+ if(!usrSizeQueried) {
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);
+ if(!usrSizeQueried) {
+ usrSizeQueried = true;
+ final int w = Debug.getIntProperty("newt.ws.swidth", true, localACC);
+ final int h = Debug.getIntProperty("newt.ws.sheight", true, localACC);
+ if(w>0 && h>0) {
+ usrSize = new Dimension(w, h);
+ System.err.println("User screen size "+usrSize);
}
}
}
}
synchronized(screenList) {
+ Class<? extends Screen> screenClass = getScreenClass(display.getType());
+ ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
+ screen.display = (DisplayImpl) display;
+ idx = screen.validateScreenIndex(idx);
{
Screen screen0 = ScreenImpl.getLastScreenOf(display, idx, -1);
if(null != screen0) {
if(DEBUG) {
System.err.println("Screen.create() REUSE: "+screen0+" "+Display.getThreadName());
}
+ screen = null;
return screen0;
}
}
- Class<? extends Screen> screenClass = getScreenClass(display.getType());
- ScreenImpl screen = (ScreenImpl) screenClass.newInstance();
- screen.display = (DisplayImpl) display;
screen.screen_idx = idx;
screen.fqname = (display.getFQName()+idx).intern();
screen.hashCode = screen.fqname.hashCode();
@@ -176,6 +189,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
throw new NativeWindowException("Screen.createNative() failed to instanciate an AbstractGraphicsScreen");
}
initScreenModeStatus();
+ updateVirtualScreenOriginAndSize();
if(DEBUG) {
System.err.println("Screen.createNative() END ("+DisplayImpl.getThreadName()+", "+this+")");
}
@@ -208,6 +222,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public synchronized final int addReference() throws NativeWindowException {
if(DEBUG) {
System.err.println("Screen.addReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount+1));
+ // Thread.dumpStack();
}
if ( 0 == refCount ) {
createNative();
@@ -220,10 +235,8 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public synchronized final int removeReference() {
if(DEBUG) {
- String msg = "Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1);
- // Throwable t = new Throwable(msg);
- // t.printStackTrace();
- System.err.println(msg);
+ System.err.println("Screen.removeReference() ("+DisplayImpl.getThreadName()+"): "+refCount+" -> "+(refCount-1));
+ // Thread.dumpStack();
}
refCount--; // could become < 0, in case of manual destruction without actual creation/addReference
if(0>=refCount) {
@@ -239,19 +252,37 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
protected abstract void createNativeImpl();
protected abstract void closeNativeImpl();
-
+
+ /**
+ * Returns the validated screen index, which is either the passed <code>idx</code>
+ * value or <code>0</code>.
+ * <p>
+ * On big-desktops this shall return always 0.
+ * </p>
+ */
+ protected abstract int validateScreenIndex(int idx);
+
+ /**
+ * Stores the virtual origin and virtual <b>rotated</b> screen size.
+ * <p>
+ * This method is called after the ScreenMode has been set,
+ * hence you may utilize it.
+ * </p>
+ * @param virtualOrigin the store for the virtual origin
+ * @param virtualSize the store for the virtual rotated size
+ */
+ protected abstract void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize);
+
public final String getFQName() {
return fqname;
}
/**
- * Set the <b>rotated</b> ScreenSize.
- * @see com.jogamp.newt.ScreenMode#getRotatedWidth()
- * @see com.jogamp.newt.ScreenMode#getRotatedHeight()
+ * Updates the <b>rotated</b> virtual ScreenSize using the native impl.
*/
- protected void setScreenSize(int w, int h) {
- System.err.println("Detected screen size "+w+"x"+h);
- width=w; height=h;
+ protected void updateVirtualScreenOriginAndSize() {
+ getVirtualScreenOriginAndSize(vOrigin, vSize);
+ System.err.println("Detected screen origin "+vOrigin+", size "+vSize);
}
public final Display getDisplay() {
@@ -270,21 +301,15 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
return null != aScreen;
}
+ public int getX() { return vOrigin.getX(); }
+ public int getY() { return vOrigin.getY(); }
- /**
- * @return the <b>rotated</b> width.
- * @see com.jogamp.newt.ScreenMode#getRotatedWidth()
- */
public final int getWidth() {
- return (usrWidth>0) ? usrWidth : (width>0) ? width : 480;
+ return (null != usrSize) ? usrSize.getWidth() : vSize.getWidth();
}
- /**
- * @return the <b>rotated</b> height
- * @see com.jogamp.newt.ScreenMode#getRotatedHeight()
- */
public final int getHeight() {
- return (usrHeight>0) ? usrHeight : (height>0) ? height : 480;
+ return (null != usrSize) ? usrSize.getHeight() : vSize.getHeight();
}
@Override
@@ -347,32 +372,29 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
try {
long t0=0, t1=0;
if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.0 "+screenMode);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.0 "+smU);
t0 = System.currentTimeMillis();
}
sms.fireScreenModeChangeNotify(smU);
if(DEBUG) {
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.1 "+screenMode);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): 0.1 "+smU);
t1 = System.currentTimeMillis();
}
success = setCurrentScreenModeImpl(smU);
- if(success) {
- setScreenSize(screenMode.getRotatedWidth(), screenMode.getRotatedHeight());
- }
if(DEBUG) {
t1 = System.currentTimeMillis() - t1;
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.0 "+screenMode+", success: "+success);
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.0 "+smU+", success: "+success);
}
sms.fireScreenModeChanged(smU, success);
if(DEBUG) {
t0 = System.currentTimeMillis() - t0;
- System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.X "+screenMode+", success: "+success+
+ System.err.println("Screen.setCurrentScreenMode ("+(System.currentTimeMillis()-t0)+"): X.X "+smU+", success: "+success+
" - dt0 "+t0+"ms, dt1 "+t1+"ms");
}
} finally {
@@ -389,7 +411,7 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
public void screenModeChanged(ScreenMode sm, boolean success) {
if(success) {
- setScreenSize(sm.getRotatedWidth(), sm.getRotatedHeight());
+ updateVirtualScreenOriginAndSize();
}
for(int i=0; i<referencedScreenModeListener.size(); i++) {
((ScreenModeListener)referencedScreenModeListener.get(i)).screenModeChanged(sm, success);
@@ -502,11 +524,12 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
}
ArrayHashSet<ScreenMode> screenModes = collectNativeScreenModes(screenModesIdx2NativeIdx);
- if(screenModes.size()==0) {
- if(DEBUG) {
- System.err.println("ScreenImpl.initScreenModeStatus: added current (last resort, collect failed): "+currentSM);
+ screenModes.getOrAdd(currentSM);
+ if(DEBUG) {
+ int i=0;
+ for(Iterator<ScreenMode> iter=screenModes.iterator(); iter.hasNext(); i++) {
+ System.err.println(i+": "+iter.next());
}
- screenModes.getOrAdd(currentSM);
}
sms = new ScreenModeStatus(screenModes, screenModesIdx2NativeIdx);
@@ -550,9 +573,18 @@ public abstract class ScreenImpl extends Screen implements ScreenModeListener {
int nativeId = smProps[0];
int screenModeIdx = ScreenModeUtil.streamIn(resolutionPool, surfaceSizePool, screenSizeMMPool,
monitorModePool, screenModePool, smProps, 1);
+ if(DEBUG) {
+ System.err.println("ScreenImpl.collectNativeScreenModes: #"+num+": idx: "+nativeId+" native -> "+screenModeIdx+" newt");
+ }
+
if(screenModeIdx >= 0) {
screenModesIdx2NativeId.put(screenModeIdx, nativeId);
}
+ } else if(DEBUG) {
+ System.err.println("ScreenImpl.collectNativeScreenModes: #"+num+": smProps: "+(null!=smProps)+
+ ", len: "+(null != smProps ? smProps.length : 0)+
+ ", bpp: "+(null != smProps && 0 < smProps.length ? smProps[idxBpp] : 0)+
+ " - DROPPING");
}
num++;
} while ( null != smProps && 0 < smProps.length );
diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java
index 7df326e8e..6564857e4 100644
--- a/src/newt/classes/jogamp/newt/WindowImpl.java
+++ b/src/newt/classes/jogamp/newt/WindowImpl.java
@@ -72,6 +72,8 @@ import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.Rectangle;
+import jogamp.nativewindow.SurfaceUpdatedHelper;
+
public abstract class WindowImpl implements Window, NEWTEventConsumer
{
public static final boolean DEBUG_TEST_REPARENT_INCOMPATIBLE = Debug.isPropertyDefined("newt.test.Window.reparent.incompatible", true);
@@ -85,12 +87,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private boolean screenReferenceAdded = false;
private NativeWindow parentWindow = null;
private long parentWindowHandle = 0;
- protected AbstractGraphicsConfiguration config = null;
+ private AbstractGraphicsConfiguration config = null; // control access due to delegation
protected CapabilitiesImmutable capsRequested = null;
protected CapabilitiesChooser capabilitiesChooser = null; // default null -> default
protected boolean fullscreen = false, hasFocus = false;
protected int width = 128, height = 128; // client-area size w/o insets, default: may be overwritten by user
- protected int x = -1, y = -1; // client-area pos w/o insets, default: undefined (allow WM to choose if not set by user)
+ protected int x = 64, y = 64; // client-area pos w/o insets
+ protected boolean autoPosition = true; // default: true (allow WM to choose if not set by user)
protected Insets insets = new Insets(); // insets of decoration (if top-level && decorated)
protected int nfs_width, nfs_height, nfs_x, nfs_y; // non fullscreen client-area size/pos w/o insets
@@ -108,10 +111,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private RequestFocusAction requestFocusAction = new RequestFocusAction();
private FocusRunnable focusAction = null;
+ private KeyListener keyboardFocusHandler = null;
- private Object surfaceUpdatedListenersLock = new Object();
- private ArrayList<SurfaceUpdatedListener> surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
-
+ private SurfaceUpdatedHelper surfaceUpdatedHelper = new SurfaceUpdatedHelper();
+
private Object childWindowsLock = new Object();
private ArrayList<NativeWindow> childWindows = new ArrayList<NativeWindow>();
@@ -213,6 +216,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
+ protected final void setGraphicsConfiguration(AbstractGraphicsConfiguration cfg) {
+ config = cfg;
+ }
+
public static interface LifecycleHook {
/**
* Reset of internal state counter, ie totalFrames, etc.
@@ -270,8 +277,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
NativeSurface.LOCK_SURFACE_NOT_READY >= parentWindow.lockSurface() ) {
throw new NativeWindowException("Parent surface lock: not ready: "+parentWindow);
}
- if( ( 0>x || 0>y ) && ( isUndecorated() || null != parentWindow ) ) {
- // default child/undecorated window position is 0/0, if not set by user
+ if( ( 0>x || 0>y ) && null != parentWindow ) {
+ // min. child window position is 0/0
x = 0; y = 0;
}
try {
@@ -545,7 +552,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if ( LOCK_SURFACE_NOT_READY == res ) {
try {
if( isNativeValid() ) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
adevice.lock();
try {
res = lockSurfaceImpl();
@@ -570,7 +577,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowLock.validateLocked();
if (surfaceLock.getHoldCount() == 1) {
- final AbstractGraphicsDevice adevice = config.getScreen().getDevice();
+ final AbstractGraphicsDevice adevice = getGraphicsConfiguration().getScreen().getDevice();
try {
unlockSurfaceImpl();
} finally {
@@ -613,8 +620,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return false;
}
- public AbstractGraphicsConfiguration getGraphicsConfiguration() {
- return config;
+ public final AbstractGraphicsConfiguration getGraphicsConfiguration() {
+ return config.getNativeGraphicsConfiguration();
}
public final long getDisplayHandle() {
@@ -682,6 +689,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
return screen;
}
+ protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
+ reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible));
+ }
final void setVisibleActionImpl(boolean visible) {
boolean nativeWindowCreated = false;
boolean madeVisible = false;
@@ -740,8 +750,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( nativeWindowCreated || madeVisible ) {
sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout and repaint to listener
}
- }
-
+ }
private class VisibleAction implements Runnable {
boolean visible;
@@ -752,8 +761,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public final void run() {
setVisibleActionImpl(visible);
}
- }
-
+ }
public void setVisible(boolean visible) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentWindow "+(null!=parentWindow));
@@ -762,59 +770,67 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
runOnEDTIfAvail(true, new VisibleAction(visible));
}
- protected final void setVisibleImpl(boolean visible, int x, int y, int width, int height) {
- reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, visible));
+ final void setSizeActionImpl(int width, int height) {
+ boolean recreate = false;
+ windowLock.lock();
+ try {
+ int visibleAction = 0; // 1 invisible, 2 visible (create)
+ if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
+ recreate = isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("Window setSize: START "+WindowImpl.this.width+"x"+WindowImpl.this.height+" -> "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible "+visible+", recreate "+recreate);
+ }
+ if(recreate) {
+ // will trigger visibleAction:=2 -> create if wasVisible
+ final boolean wasVisible = WindowImpl.this.visible;
+ screen.addReference(); // retain screen
+ destroyAction.run();
+ WindowImpl.this.visible = wasVisible;
+ }
+ if ( isNativeValid() && 0>=width*height && visible ) {
+ visibleAction=1; // invisible
+ WindowImpl.this.width = 0;
+ WindowImpl.this.height = 0;
+ } else if ( !isNativeValid() && 0<width*height && visible ) {
+ visibleAction = 2; // visible (create)
+ WindowImpl.this.width = width;
+ WindowImpl.this.height = height;
+ } else if ( isNativeValid() ) {
+ // this width/height will be set by windowChanged, called by the native implementation
+ reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible()));
+ } 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);
+ }
+ switch(visibleAction) {
+ case 1: setVisibleActionImpl(false); break;
+ case 2: setVisibleActionImpl(true); break;
+ }
+ }
+ } finally {
+ if(recreate) {
+ screen.removeReference(); // bring back ref-count
+ }
+ windowLock.unlock();
+ }
}
-
- private class SetSizeActionImpl implements Runnable {
+ private class SetSizeAction implements Runnable {
int width, height;
- private SetSizeActionImpl(int w, int h) {
+ private SetSizeAction(int w, int h) {
width = w;
height = h;
}
public final void run() {
- windowLock.lock();
- try {
- int visibleAction = 0; // 1 invisible, 2 visible (create)
- if ( !fullscreen && ( width != WindowImpl.this.width || WindowImpl.this.height != height ) ) {
- if(DEBUG_IMPLEMENTATION) {
- String msg = "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 ( isNativeValid() && 0>=width*height && visible ) {
- visibleAction=1; // invisible
- WindowImpl.this.width = 0;
- WindowImpl.this.height = 0;
- } else if ( !isNativeValid() && 0<width*height && visible ) {
- visibleAction = 2; // visible (create)
- WindowImpl.this.width = width;
- WindowImpl.this.height = height;
- } else if ( isNativeValid() ) {
- // this width/height will be set by windowChanged, called by the native implementation
- reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(0, isVisible()));
- } 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);
- }
- switch(visibleAction) {
- case 1: setVisibleActionImpl(false); break;
- case 2: setVisibleActionImpl(true); break;
- }
- }
- } finally {
- windowLock.unlock();
- }
+ setSizeActionImpl(width, height);
}
- }
-
+ }
public void setSize(int width, int height) {
- runOnEDTIfAvail(true, new SetSizeActionImpl(width, height));
- }
-
+ runOnEDTIfAvail(true, new SetSizeAction(width, height));
+ }
public void setTopLevelSize(int width, int height) {
setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight());
}
@@ -911,6 +927,22 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
runOnEDTIfAvail(true, destroyAction);
}
+ /**
+ * @param cWin child window, must not be null
+ * @param pWin parent window, may be null
+ * @return true if at least one of both window's configurations is offscreen
+ */
+ protected static boolean isOffscreenInstance(NativeWindow cWin, NativeWindow pWin) {
+ boolean ofs = false;
+ if( null != cWin.getGraphicsConfiguration() ) {
+ ofs = !cWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ }
+ if( !ofs && null != pWin && null != pWin.getGraphicsConfiguration() ) {
+ ofs |= !pWin.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
+ }
+ return ofs;
+ }
+
private class ReparentActionImpl implements Runnable, ReparentAction {
NativeWindow newParentWindow;
boolean forceDestroyCreate;
@@ -918,7 +950,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
private ReparentActionImpl(NativeWindow newParentWindow, boolean forceDestroyCreate) {
this.newParentWindow = newParentWindow;
- this.forceDestroyCreate = forceDestroyCreate;
+ this.forceDestroyCreate = forceDestroyCreate | DEBUG_TEST_REPARENT_INCOMPATIBLE;
this.reparentAction = -1; // ensure it's set
}
@@ -927,10 +959,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
private void setScreen(ScreenImpl newScreen) { // never null !
- WindowImpl.this.removeScreenReference();
+ removeScreenReference();
screen = newScreen;
}
-
+
public final void run() {
boolean animatorPaused = false;
if(null!=lifecycleHook) {
@@ -952,6 +984,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
windowLock.lock();
try {
+ if(isNativeValid()) {
+ // force recreation if offscreen, since it may become onscreen
+ forceDestroyCreate |= isOffscreenInstance(WindowImpl.this, newParentWindow);
+ }
+
wasVisible = isVisible();
Window newParentWindowNEWT = null;
@@ -962,7 +999,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
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);
+ System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", "+x+"/"+y+" "+width+"x"+height);
}
if(null!=lifecycleHook) {
@@ -1013,8 +1050,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
} else {
reparentAction = ACTION_NATIVE_CREATION_PENDING;
}
- } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ||
- !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
+ } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) {
// Destroy this window, may create a new compatible Screen/Display,
// and mark it for creation.
destroy();
@@ -1045,7 +1081,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
if( 0 == parentWindowHandle ) {
// Already Top Window
reparentAction = ACTION_UNCHANGED;
- } else if( !isNativeValid() || DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) {
+ } else if( !isNativeValid() || forceDestroyCreate ) {
// Destroy this window and mark it for [pending] creation.
destroy();
if( 0<width*height ) {
@@ -1138,7 +1174,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
ok = WindowImpl.this.waitForSize(width, height, false, TIMEOUT_NATIVEWINDOW);
}
if(ok) {
- requestFocusImpl(true);
+ requestFocusInt(true);
display.dispatchMessagesNative(); // status up2date
}
}
@@ -1208,7 +1244,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) {
- ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
+ final ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate);
runOnEDTIfAvail(true, reparentAction);
return reparentAction.getStrategy();
}
@@ -1220,7 +1256,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public final CapabilitiesImmutable getChosenCapabilities() {
- return config.getNativeGraphicsConfiguration().getChosenCapabilities();
+ return getGraphicsConfiguration().getChosenCapabilities();
}
public final CapabilitiesImmutable getRequestedCapabilities() {
@@ -1385,14 +1421,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- public void requestFocus() {
- enqueueRequestFocus(true);
- }
-
- public final boolean hasFocus() {
- return hasFocus;
- }
-
public final InsetsImmutable getInsets() {
if(isUndecorated()) {
return Insets.getZero();
@@ -1452,7 +1480,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
public Object getWrappedWindow() {
return null;
}
-
+
+ public final Window getDelegatedWindow() {
+ return this;
+ }
+
/**
* If set to true, the default value, this NEWT Window implementation will
* handle the destruction (ie {@link #destroy()} call) within {@link #windowDestroyNotify()} implementation.<br>
@@ -1466,6 +1498,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// WindowImpl
//
+ /**
+ * Returns the non delegated {@link AbstractGraphicsConfiguration},
+ * see {@link #getGraphicsConfiguration()}. */
+ public final AbstractGraphicsConfiguration getPrivateGraphicsConfiguration() {
+ return config;
+ }
+
protected final long getParentWindowHandle() {
return isFullscreen() ? 0 : parentWindowHandle;
}
@@ -1487,9 +1526,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
"\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(", SurfaceUpdatedListeners num "+surfaceUpdatedHelper.size()+" [");
+ for (int i = 0; i < surfaceUpdatedHelper.size(); i++ ) {
+ sb.append(surfaceUpdatedHelper.get(i)+", ");
}
sb.append("], WindowListeners num "+windowListeners.size()+" [");
for (int i = 0; i < windowListeners.size(); i++ ) {
@@ -1503,7 +1542,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
for (int i = 0; i < keyListeners.size(); i++ ) {
sb.append(keyListeners.get(i)+", ");
}
- sb.append("] ]");
+ sb.append("], surfaceLock "+surfaceLock);
+ sb.append(", windowLock "+windowLock+"]");
return sb.toString();
}
@@ -1529,21 +1569,32 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
}
- protected void enqueueRequestFocus(boolean wait) {
- runOnEDTIfAvail(wait, requestFocusAction);
+ public final boolean hasFocus() {
+ return hasFocus;
}
- /**
- * 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 requestFocus() {
+ requestFocus(true);
+ }
+
+ public void requestFocus(boolean wait) {
+ if(isNativeValid() && !focusAction()) {
+ runOnEDTIfAvail(wait, requestFocusAction);
+ }
+ }
+
+ /** Internal request focus on current thread */
+ private void requestFocusInt(boolean force) {
+ if(!focusAction()) {
+ requestFocusImpl(force);
+ }
+ }
+
public void setFocusAction(FocusRunnable focusAction) {
this.focusAction = focusAction;
}
-
- /** Called by native requestFocusImpl() */
- protected boolean focusAction() {
+
+ private boolean focusAction() {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.focusAction() START - "+getThreadName()+", focusAction: "+focusAction+" - windowHandle "+toHexString(getWindowHandle()));
}
@@ -1558,7 +1609,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
return res;
}
-
+
+ public void setKeyboardFocusHandler(KeyListener l) {
+ keyboardFocusHandler = l;
+ }
+
private class SetPositionActionImpl implements Runnable {
int x, y;
@@ -1590,6 +1645,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public void setPosition(int x, int y) {
+ autoPosition = false;
runOnEDTIfAvail(true, new SetPositionActionImpl(x, y));
}
@@ -1622,7 +1678,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
nfs_y = WindowImpl.this.y;
nfs_width = WindowImpl.this.width;
nfs_height = WindowImpl.this.height;
- x = 0; y = 0;
+ x = screen.getX();
+ y = screen.getY();
w = screen.getWidth();
h = screen.getHeight();
} else {
@@ -1680,7 +1737,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
display.dispatchMessagesNative(); // status up2date
WindowImpl.this.waitForSize(w, h, false, TIMEOUT_NATIVEWINDOW);
display.dispatchMessagesNative(); // status up2date
- requestFocusImpl(true);
+ requestFocusInt(true);
display.dispatchMessagesNative(); // status up2date
if(DEBUG_IMPLEMENTATION) {
@@ -1800,8 +1857,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
// queue event in case window is locked, ie in operation
if( isWindowLocked() ) {
if(DEBUG_IMPLEMENTATION) {
- // System.err.println("Window.consumeEvent: queued "+e);
- // Thread.dumpStack(); // JAU
+ System.err.println("Window.consumeEvent: queued "+e);
+ // Thread.dumpStack();
}
return false;
}
@@ -1824,62 +1881,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
//
// SurfaceUpdatedListener Support
//
-
public void addSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- addSurfaceUpdatedListener(-1, l);
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(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 addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException {
+ surfaceUpdatedHelper.addSurfaceUpdatedListener(index, l);
}
public void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) {
- if (l == null) {
- return;
- }
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners.remove(l);
- }
- }
-
- public void removeAllSurfaceUpdatedListener() {
- synchronized(surfaceUpdatedListenersLock) {
- surfaceUpdatedListeners = new ArrayList<SurfaceUpdatedListener>();
- }
- }
-
- public SurfaceUpdatedListener getSurfaceUpdatedListener(int index) {
- synchronized(surfaceUpdatedListenersLock) {
- if(0>index) {
- index = surfaceUpdatedListeners.size()-1;
- }
- return surfaceUpdatedListeners.get(index);
- }
- }
-
- public SurfaceUpdatedListener[] getSurfaceUpdatedListeners() {
- synchronized(surfaceUpdatedListenersLock) {
- return (SurfaceUpdatedListener[]) surfaceUpdatedListeners.toArray();
- }
+ surfaceUpdatedHelper.removeSurfaceUpdatedListener(l);
}
public void surfaceUpdated(Object updater, NativeSurface ns, long when) {
- synchronized(surfaceUpdatedListenersLock) {
- for(int i = 0; i < surfaceUpdatedListeners.size(); i++ ) {
- SurfaceUpdatedListener l = surfaceUpdatedListeners.get(i);
- l.surfaceUpdated(updater, ns, when);
- }
- }
+ surfaceUpdatedHelper.surfaceUpdated(updater, ns, when);
}
//
@@ -1893,8 +1908,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
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) {
+
+ protected void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
if(eventType == MouseEvent.EVENT_MOUSE_ENTERED ||
eventType == MouseEvent.EVENT_MOUSE_EXITED) {
if(eventType == MouseEvent.EVENT_MOUSE_EXITED && x==-1 && y==-1) {
@@ -2026,15 +2042,15 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public MouseListener[] getMouseListeners() {
- return (MouseListener[]) mouseListeners.toArray();
+ return mouseListeners.toArray(new MouseListener[mouseListeners.size()]);
}
protected void consumeMouseEvent(MouseEvent e) {
if(DEBUG_MOUSE_EVENT) {
System.err.println("consumeMouseEvent: event: "+e);
}
-
- for(int i = 0; i < mouseListeners.size(); i++ ) {
+ boolean consumed = false;
+ for(int i = 0; !consumed && i < mouseListeners.size(); i++ ) {
MouseListener l = mouseListeners.get(i);
switch(e.getEventType()) {
case MouseEvent.EVENT_MOUSE_CLICKED:
@@ -2064,13 +2080,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
default:
throw new NativeWindowException("Unexpected mouse event type " + e.getEventType());
}
+ consumed = InputEvent.consumedTag == e.getAttachment();
}
}
//
// KeyListener/Event Support
//
-
public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
consumeKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), modifiers, keyCode, keyChar) );
}
@@ -2116,29 +2132,42 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public KeyListener[] getKeyListeners() {
- return (KeyListener[]) keyListeners.toArray();
+ return keyListeners.toArray(new KeyListener[keyListeners.size()]);
}
- protected void consumeKeyEvent(KeyEvent e) {
- if(DEBUG_KEY_EVENT) {
- System.err.println("consumeKeyEvent: "+e);
+ private final boolean propagateKeyEvent(KeyEvent e, KeyListener l) {
+ 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());
}
- for(int i = 0; i < keyListeners.size(); i++ ) {
- KeyListener l = 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());
+ return InputEvent.consumedTag == e.getAttachment();
+ }
+
+ protected void consumeKeyEvent(KeyEvent e) {
+ boolean consumed;
+ if(null != keyboardFocusHandler) {
+ consumed = propagateKeyEvent(e, keyboardFocusHandler);
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e+", keyboardFocusHandler consumed: "+consumed);
+ }
+ } else {
+ consumed = false;
+ if(DEBUG_KEY_EVENT) {
+ System.err.println("consumeKeyEvent: "+e);
}
}
+ for(int i = 0; !consumed && i < keyListeners.size(); i++ ) {
+ consumed = propagateKeyEvent(e, keyListeners.get(i));
+ }
}
//
@@ -2191,7 +2220,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
}
public WindowListener[] getWindowListeners() {
- return (WindowListener[]) windowListeners.toArray();
+ return windowListeners.toArray(new WindowListener[windowListeners.size()]);
}
protected void consumeWindowEvent(WindowEvent e) {
@@ -2324,6 +2353,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
/** Triggered by implementation's WM events to update the position. */
protected void positionChanged(boolean defer, int newX, int newY) {
+ autoPosition = false;
if ( x != newX || y != newY ) {
if(DEBUG_IMPLEMENTATION) {
System.err.println("Window.positionChanged: ("+getThreadName()+"): (defer: "+defer+") "+x+"/"+y+" -> "+newX+"/"+newY+" - windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle));
@@ -2389,8 +2419,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer
* Triggered by implementation's WM events to update the content
*/
protected void windowRepaint(boolean defer, int x, int y, int width, int height) {
- x = ( 0 > x ) ? this.x : x;
- y = ( 0 > y ) ? this.y : y;
width = ( 0 >= width ) ? this.width : width;
height = ( 0 >= height ) ? this.height : height;
if(DEBUG_IMPLEMENTATION) {
diff --git a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
index aa98d3a37..2ca3d2cfd 100644
--- a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java
+++ b/src/newt/classes/jogamp/newt/awt/NewtFactoryAWT.java
@@ -26,15 +26,19 @@
* or implied, of JogAmp Community.
*/
+package jogamp.newt.awt;
-package jogamp.newt.awt.event;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
+import javax.media.nativewindow.CapabilitiesImmutable;
+import javax.media.nativewindow.NativeWindow;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
-
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.awt.*;
+import jogamp.nativewindow.jawt.JAWTWindow;
+import jogamp.newt.Debug;
import com.jogamp.newt.NewtFactory;
-import jogamp.newt.Debug;
public class NewtFactoryAWT extends NewtFactory {
public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window");
@@ -51,7 +55,7 @@ public class NewtFactoryAWT extends NewtFactory {
*
* @param awtCompObject must be of type java.awt.Component
*/
- public static NativeWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) {
+ public static JAWTWindow getNativeWindow(Object awtCompObject, CapabilitiesImmutable capsRequested) {
if(null==awtCompObject) {
throw new NativeWindowException("Null AWT Component");
}
@@ -61,13 +65,23 @@ public class NewtFactoryAWT extends NewtFactory {
return getNativeWindow( (java.awt.Component) awtCompObject, capsRequested );
}
- public static NativeWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) {
- DefaultGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, capsRequested, capsRequested);
- NativeWindow awtNative = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ public static JAWTWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) {
+ AWTGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, null, capsRequested);
+ NativeWindow nw = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow
+ if(! ( nw instanceof JAWTWindow ) ) {
+ throw new NativeWindowException("Not an AWT NativeWindow: "+nw);
+ }
if(DEBUG_IMPLEMENTATION) {
- System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+awtNative);
+ System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+nw);
}
- return awtNative;
+ return (JAWTWindow)nw;
+ }
+
+ public static void destroyNativeWindow(JAWTWindow jawtWindow) {
+ final AbstractGraphicsConfiguration config = jawtWindow.getGraphicsConfiguration();
+ jawtWindow.destroy();
+ config.getScreen().getDevice().close();
}
+
}
diff --git a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
index 358864547..8e9c028d4 100644
--- a/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
+++ b/src/newt/classes/jogamp/newt/awt/event/AWTParentWindowAdapter.java
@@ -28,6 +28,10 @@
package jogamp.newt.awt.event;
+import java.awt.KeyboardFocusManager;
+
+import jogamp.newt.driver.DriverUpdatePosition;
+
import com.jogamp.newt.event.awt.AWTAdapter;
import com.jogamp.newt.event.awt.AWTWindowAdapter;
@@ -54,9 +58,16 @@ public class AWTParentWindowAdapter
}
public void focusGained(java.awt.event.FocusEvent e) {
+ // forward focus to NEWT child
+ final com.jogamp.newt.Window newtChild = getNewtWindow();
+ final boolean isOnscreen = newtChild.isNativeValid() && newtChild.getGraphicsConfiguration().getChosenCapabilities().isOnscreen();
if(DEBUG_IMPLEMENTATION) {
- System.err.println("AWT: focusGained: "+ e);
+ System.err.println("AWT: focusGained: onscreen "+ isOnscreen+", "+e);
+ }
+ if(isOnscreen) {
+ KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
}
+ newtChild.requestFocus(false);
}
public void focusLost(java.awt.event.FocusEvent e) {
@@ -90,7 +101,12 @@ public class AWTParentWindowAdapter
}
public void componentMoved(java.awt.event.ComponentEvent e) {
- // no propagation to NEWT child window
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("AWT: componentMoved: "+e);
+ }
+ if(getNewtWindow().getDelegatedWindow() instanceof DriverUpdatePosition) {
+ ((DriverUpdatePosition)getNewtWindow().getDelegatedWindow()).updatePosition();
+ }
}
public void windowActivated(java.awt.event.WindowEvent e) {
@@ -104,11 +120,11 @@ public class AWTParentWindowAdapter
public void hierarchyChanged(java.awt.event.HierarchyEvent e) {
if( null == getNewtEventListener() ) {
long bits = e.getChangeFlags();
- final java.awt.Component changed = e.getChanged();
+ 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);
+ System.err.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed+", source "+e.getComponent());
}
getNewtWindow().runOnEDTIfAvail(false, new Runnable() {
public void run() {
diff --git a/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java b/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java
new file mode 100644
index 000000000..0a824e83b
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/DriverClearFocus.java
@@ -0,0 +1,12 @@
+package jogamp.newt.driver;
+
+/**
+ * Interface tagging driver requirement of clearing the focus.
+ * <p>
+ * Some drivers require a programmatic {@link #clearFocus()} when traversing the focus.
+ * </p>
+ */
+public interface DriverClearFocus {
+ /** Programmatic clear the focus */
+ void clearFocus();
+}
diff --git a/src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java b/src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java
new file mode 100644
index 000000000..bb846c081
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/DriverUpdatePosition.java
@@ -0,0 +1,9 @@
+package jogamp.newt.driver;
+
+/**
+ * Interface tagging driver requirement of absolute positioning, ie. depend on parent position.
+ */
+public interface DriverUpdatePosition {
+ /** Programmatic update the position */
+ void updatePosition();
+}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java b/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
index ce6a9c594..e108ed0bb 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/android/AndroidScreen.java
@@ -29,6 +29,8 @@
package jogamp.newt.driver.android;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.util.ScreenModeUtil;
@@ -74,6 +76,18 @@ public class AndroidScreen extends jogamp.newt.ScreenImpl {
return ScreenModeUtil.streamIn(props, 0);
}
+ protected int validateScreenIndex(int idx) {
+ return 0; // FIXME: only one screen available ?
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ final ScreenMode sm = getCurrentScreenMode();
+ virtualSize.setWidth(sm.getRotatedWidth());
+ virtualSize.setHeight(sm.getRotatedHeight());
+ }
+
//----------------------------------------------------------------------
// Internals only
//
@@ -91,7 +105,7 @@ public class AndroidScreen extends jogamp.newt.ScreenImpl {
if (ScreenMode.ROTATE_90 == nrot || ScreenMode.ROTATE_270 == nrot) {
props[offset++] = outMetrics.heightPixels;
props[offset++] = outMetrics.widthPixels;
- } else {
+ } else {
props[offset++] = outMetrics.widthPixels;
props[offset++] = outMetrics.heightPixels;
}
diff --git a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
index 9cefa8163..6348cf19e 100644
--- a/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/android/AndroidWindow.java
@@ -239,7 +239,7 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
}
// propagate data ..
- config = eglConfig;
+ setGraphicsConfiguration(eglConfig);
setWindowHandle(surfaceHandle);
Log.d(MD.TAG, "createNativeImpl X");
}
@@ -343,7 +343,9 @@ public class AndroidWindow extends jogamp.newt.WindowImpl implements Callback2 {
surfaceHandle = 0;
surface=null;
}
- getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event
+ if(getScreen().isNativeValid()) {
+ getScreen().getCurrentScreenMode(); // if ScreenMode changed .. trigger ScreenMode event
+ }
if(0>x || 0>y) {
x = 0;
diff --git a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
index bb678935a..f7c05cd45 100644
--- a/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
+++ b/src/newt/classes/jogamp/newt/driver/android/NewtBaseActivity.java
@@ -27,10 +27,7 @@
*/
package jogamp.newt.driver.android;
-import javax.media.opengl.GLProfile;
-
import com.jogamp.newt.Window;
-import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import jogamp.newt.driver.android.AndroidWindow;
@@ -63,9 +60,7 @@ public class NewtBaseActivity extends Activity {
}
public void setContentView(android.view.Window androidWindow, Window newtWindow) {
- if(newtWindow instanceof GLWindow) {
- newtWindow = ((GLWindow)newtWindow).getWindow();
- }
+ newtWindow = newtWindow.getDelegatedWindow();
if(newtWindow instanceof AndroidWindow) {
this.newtWindow = (AndroidWindow)newtWindow;
this.newtWindow.setAndroidWindow(androidWindow);
@@ -103,9 +98,6 @@ public class NewtBaseActivity extends Activity {
jogamp.common.os.android.StaticContext.setContext(extActivity.getApplicationContext());
}
extActivity.getWindow();
-
- // init GLProfile
- GLProfile.initSingleton(true);
}
@Override
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
index 0729f02ab..b63e433f6 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java
@@ -99,7 +99,7 @@ public class AWTCanvas extends Canvas {
if(null==awtConfig) {
throw new NativeWindowException("Error: NULL AWTGraphicsConfiguration");
}
- chosen = awtConfig.getGraphicsConfiguration();
+ chosen = awtConfig.getAWTGraphicsConfiguration();
// before native peer is valid: X11
disableBackgroundErase();
@@ -192,7 +192,7 @@ public class AWTCanvas extends Canvas {
*/
AWTGraphicsConfiguration config = chooseGraphicsConfiguration(
awtConfig.getChosenCapabilities(), awtConfig.getRequestedCapabilities(), chooser, gc.getDevice());
- final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null;
+ final GraphicsConfiguration compatible = (null!=config)?config.getAWTGraphicsConfiguration():null;
if(Window.DEBUG_IMPLEMENTATION) {
Exception e = new Exception("Info: Call Stack: "+Thread.currentThread().getName());
e.printStackTrace();
@@ -246,7 +246,9 @@ public class AWTCanvas extends Canvas {
CapabilitiesImmutable capsRequested,
CapabilitiesChooser chooser,
GraphicsDevice device) {
- AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT);
+ final AbstractGraphicsScreen aScreen = null != device ?
+ AWTGraphicsScreen.createScreenDevice(device, AbstractGraphicsDevice.DEFAULT_UNIT):
+ AWTGraphicsScreen.createDefault();
AWTGraphicsConfiguration config = (AWTGraphicsConfiguration)
GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capsChosen,
capsRequested,
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java b/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
index 64c741464..f22ec6fad 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTDisplay.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,7 +34,6 @@
package jogamp.newt.driver.awt;
-import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.awt.AWTGraphicsDevice;
import com.jogamp.newt.NewtFactory;
import jogamp.newt.DisplayImpl;
@@ -43,7 +43,7 @@ public class AWTDisplay extends DisplayImpl {
}
protected void createNativeImpl() {
- aDevice = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(null, AbstractGraphicsDevice.DEFAULT_UNIT); // default
+ aDevice = AWTGraphicsDevice.createDefault();
}
protected void setAWTGraphicsDevice(AWTGraphicsDevice d) {
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java b/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
index 644c96391..9eed930b6 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTScreen.java
@@ -38,6 +38,8 @@ import java.awt.DisplayMode;
import jogamp.newt.ScreenImpl;
import javax.media.nativewindow.awt.AWTGraphicsDevice;
import javax.media.nativewindow.awt.AWTGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
public class AWTScreen extends ScreenImpl {
public AWTScreen() {
@@ -45,21 +47,34 @@ public class AWTScreen extends ScreenImpl {
protected void createNativeImpl() {
aScreen = new AWTGraphicsScreen((AWTGraphicsDevice)display.getGraphicsDevice());
-
- final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode();
- if(null != mode) {
- setScreenSize(mode.getWidth(), mode.getHeight());
- }
}
protected void setAWTGraphicsScreen(AWTGraphicsScreen s) {
aScreen = s;
}
- // done by AWTWindow ..
- protected void setScreenSize(int w, int h) {
- super.setScreenSize(w, h);
+ /**
+ * Used by AWTWindow ..
+ */
+ @Override
+ protected void updateVirtualScreenOriginAndSize() {
+ super.updateVirtualScreenOriginAndSize();
}
protected void closeNativeImpl() { }
+
+ protected int validateScreenIndex(int idx) {
+ return idx; // pass through ...
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ final DisplayMode mode = ((AWTGraphicsDevice)getDisplay().getGraphicsDevice()).getGraphicsDevice().getDisplayMode();
+ if(null != mode) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ virtualSize.setWidth(mode.getWidth());
+ virtualSize.setHeight(mode.getHeight());
+ }
+ }
+
}
diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java b/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
index 9aaa82fec..e9e3ec0ba 100644
--- a/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/awt/AWTWindow.java
@@ -36,10 +36,11 @@ package jogamp.newt.driver.awt;
import java.awt.BorderLayout;
import java.awt.Container;
-import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.Insets;
+
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.awt.AWTGraphicsDevice;
import javax.media.nativewindow.awt.AWTGraphicsScreen;
import javax.media.nativewindow.util.Point;
@@ -145,27 +146,21 @@ public class AWTWindow extends WindowImpl {
public boolean hasDeviceChanged() {
boolean res = canvas.hasDeviceChanged();
if(res) {
- config = canvas.getAWTGraphicsConfiguration();
- if (config == null) {
+ final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration();
+ if (null == cfg) {
throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this);
}
- updateDeviceData();
+ setGraphicsConfiguration(cfg);
+
+ // propagate new info ..
+ ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen());
+ ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice());
+
+ ((AWTScreen)getScreen()).updateVirtualScreenOriginAndSize();
}
return res;
}
- private void updateDeviceData() {
- // propagate new info ..
- ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)config.getScreen());
- ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)config.getScreen().getDevice());
-
- final DisplayMode mode = ((AWTGraphicsDevice)config.getScreen().getDevice()).getGraphicsDevice().getDisplayMode();
- if(null != mode) {
- ((AWTScreen)getScreen()).setScreenSize(mode.getWidth(), mode.getHeight());
- }
-
- }
-
protected void updateInsetsImpl(javax.media.nativewindow.util.Insets insets) {
Insets contInsets = container.getInsets();
insets.setLeftWidth(contInsets.left);
@@ -189,11 +184,6 @@ public class AWTWindow extends WindowImpl {
container.setVisible(0 != ( FLAG_IS_VISIBLE & flags));
}
- x=(x>=0)?x:AWTWindow.this.x;
- y=(x>=0)?y:AWTWindow.this.y;
- width=(width>0)?width:AWTWindow.this.width;
- height=(height>0)?height:AWTWindow.this.height;
-
container.setLocation(x, y);
Insets insets = container.getInsets();
container.setSize(width + insets.left + insets.right,
@@ -202,11 +192,12 @@ public class AWTWindow extends WindowImpl {
if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
if( 0 != ( FLAG_IS_VISIBLE & flags ) ) {
if( !hasDeviceChanged() ) {
- // oops ??
- config = canvas.getAWTGraphicsConfiguration();
- if(null == config) {
+ // oops ??
+ final AWTGraphicsConfiguration cfg = canvas.getAWTGraphicsConfiguration();
+ if(null == cfg) {
throw new NativeWindowException("Error: !hasDeviceChanged && null == GraphicsConfiguration: "+this);
}
+ setGraphicsConfiguration(cfg);
}
}
visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
index 0a8453701..11b8dfcf9 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Screen.java
@@ -34,6 +34,8 @@
package jogamp.newt.driver.broadcom.egl;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
public class Screen extends jogamp.newt.ScreenImpl {
@@ -47,16 +49,26 @@ public class Screen extends jogamp.newt.ScreenImpl {
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
- setScreenSize(fixedWidth, fixedHeight);
}
protected void closeNativeImpl() { }
+ protected int validateScreenIndex(int idx) {
+ return 0; // only one screen available
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ virtualSize.setWidth(fixedWidth); // FIXME
+ virtualSize.setHeight(fixedHeight); // FIXME
+ }
+
//----------------------------------------------------------------------
// Internals only
//
- static final int fixedWidth = 1920;
- static final int fixedHeight = 1080;
+ static final int fixedWidth = 1920; // FIXME
+ static final int fixedHeight = 1080; // FIXME
}
diff --git a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
index 7df293c0d..6f66eedd3 100644
--- a/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/broadcom/egl/Window.java
@@ -35,6 +35,7 @@ package jogamp.newt.driver.broadcom.egl;
import jogamp.opengl.egl.*;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.awt.AWTGraphicsConfiguration;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.GLCapabilitiesImmutable;
@@ -51,13 +52,14 @@ public class Window extends jogamp.newt.WindowImpl {
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(
+ // query a good configuration, however chose the final one by the native queried egl-cfg-id
+ // after creation at {@link #windowCreated(int, int, int)}.
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
setSizeImpl(getScreen().getWidth(), getScreen().getHeight());
setWindowHandle(realizeWindow(true, width, height));
@@ -139,7 +141,7 @@ public class Window extends jogamp.newt.WindowImpl {
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);
+ System.err.println("BCEGL Window.realizeWindow() with: chroma "+chromaKey+", "+width+"x"+height+", "+getGraphicsConfiguration());
}
long handle = CreateWindow(getDisplayHandle(), chromaKey, width, height);
if (0 == handle) {
@@ -152,13 +154,14 @@ public class Window extends jogamp.newt.WindowImpl {
private void windowCreated(int cfgID, int width, int height) {
this.width = width;
this.height = height;
- GLCapabilitiesImmutable capsReq = (GLCapabilitiesImmutable) config.getRequestedCapabilities();
- config = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID);
- if (config == null) {
+ GLCapabilitiesImmutable capsReq = (GLCapabilitiesImmutable) getGraphicsConfiguration().getRequestedCapabilities();
+ final AbstractGraphicsConfiguration cfg = EGLGraphicsConfiguration.create(capsReq, getScreen().getGraphicsScreen(), cfgID);
+ if (null == cfg) {
throw new NativeWindowException("Error creating EGLGraphicsConfiguration from id: "+cfgID+", "+this);
}
+ setGraphicsConfiguration(cfg);
if(DEBUG_IMPLEMENTATION) {
- System.err.println("BCEGL Window.windowCreated(): "+toHexString(cfgID)+", "+width+"x"+height+", "+config);
+ System.err.println("BCEGL Window.windowCreated(): "+toHexString(cfgID)+", "+width+"x"+height+", "+cfg);
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
index 26b7120a9..66ad1c691 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/Screen.java
@@ -33,8 +33,10 @@
package jogamp.newt.driver.intel.gdl;
-import jogamp.newt.*;
-import javax.media.nativewindow.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
public class Screen extends jogamp.newt.ScreenImpl {
@@ -53,6 +55,17 @@ public class Screen extends jogamp.newt.ScreenImpl {
protected void closeNativeImpl() { }
+ protected int validateScreenIndex(int idx) {
+ return 0; // only one screen available
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ virtualSize.setWidth(cachedWidth);
+ virtualSize.setHeight(cachedHeight);
+ }
+
//----------------------------------------------------------------------
// Internals only
//
@@ -62,7 +75,11 @@ public class Screen extends jogamp.newt.ScreenImpl {
// called by GetScreenInfo() ..
private void screenCreated(int width, int height) {
- setScreenSize(width, height);
+ cachedWidth = width;
+ cachedHeight = height;
}
+
+ private static int cachedWidth = 0;
+ private static int cachedHeight = 0;
}
diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
index ab3e95e7e..873d0a0c1 100644
--- a/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
+++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/Window.java
@@ -51,14 +51,15 @@ public class Window extends jogamp.newt.WindowImpl {
if(0!=getParentWindowHandle()) {
throw new NativeWindowException("GDL Window does not support window parenting");
}
- AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
- AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
+ final AbstractGraphicsScreen aScreen = getScreen().getGraphicsScreen();
+ final AbstractGraphicsDevice aDevice = getScreen().getDisplay().getGraphicsDevice();
- config = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(aDevice).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, aScreen);
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
synchronized(Window.class) {
setWindowHandle(nextWindowHandle++); // just a marker
@@ -83,11 +84,6 @@ public class Window extends jogamp.newt.WindowImpl {
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
Screen screen = (Screen) getScreen();
- x=(x>=0)?x:this.x;
- y=(x>=0)?y:this.y;
- width=(width>0)?width:this.width;
- height=(height>0)?height:this.height;
-
if(width>screen.getWidth()) {
width=screen.getWidth();
}
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java b/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
index a11b08b5c..6b6aecb20 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/KDScreen.java
@@ -35,6 +35,8 @@ package jogamp.newt.driver.kd;
import jogamp.newt.ScreenImpl;
import javax.media.nativewindow.*;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
public class KDScreen extends ScreenImpl {
static {
@@ -50,8 +52,22 @@ public class KDScreen extends ScreenImpl {
protected void closeNativeImpl() { }
- // elevate access to this package ..
- protected void setScreenSize(int w, int h) {
- super.setScreenSize(w, h);
+ protected int validateScreenIndex(int idx) {
+ return 0; // only one screen available
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ virtualSize.setWidth(cachedWidth);
+ virtualSize.setHeight(cachedHeight);
}
+
+ protected void sizeChanged(int w, int h) {
+ cachedWidth = w;
+ cachedHeight = h;
+ }
+
+ private static int cachedWidth = 0;
+ private static int cachedHeight = 0;
}
diff --git a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
index 10a75a017..92f8251bc 100644
--- a/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/kd/KDWindow.java
@@ -55,18 +55,19 @@ public class KDWindow extends WindowImpl {
if(0!=getParentWindowHandle()) {
throw new RuntimeException("Window parenting not supported (yet)");
}
- config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
- GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) config.getChosenCapabilities();
+ GLCapabilitiesImmutable eglCaps = (GLCapabilitiesImmutable) cfg.getChosenCapabilities();
int[] eglAttribs = EGLGraphicsConfiguration.GLCapabilities2AttribList(eglCaps);
eglWindowHandle = CreateWindow(getDisplayHandle(), eglAttribs);
if (eglWindowHandle == 0) {
- throw new NativeWindowException("Error creating egl window: "+config);
+ throw new NativeWindowException("Error creating egl window: "+cfg);
}
setVisible0(eglWindowHandle, false);
setWindowHandle(RealizeWindow(eglWindowHandle));
@@ -145,7 +146,7 @@ public class KDWindow extends WindowImpl {
@Override
protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
if(fullscreen) {
- ((KDScreen)getScreen()).setScreenSize(width, height);
+ ((KDScreen)getScreen()).sizeChanged(width, height);
}
super.sizeChanged(defer, newWidth, newHeight, force);
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
index 527fdac6d..2ac98f255 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacDisplay.java
@@ -72,8 +72,12 @@ public class MacDisplay extends DisplayImpl {
public static void runNSApplication() {
runNSApplication0();
}
+ public static void stopNSApplication() {
+ stopNSApplication0();
+ }
private static native boolean initNSApplication0();
private static native void runNSApplication0();
+ private static native void stopNSApplication0();
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
new file mode 100644
index 000000000..46625f7a9
--- /dev/null
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacKeyUtil.java
@@ -0,0 +1,262 @@
+package jogamp.newt.driver.macosx;
+
+import com.jogamp.newt.event.KeyEvent;
+
+public class MacKeyUtil {
+
+ // KeyCodes (independent)
+ private static final int kVK_Return = 0x24;
+ private static final int kVK_Tab = 0x30;
+ private static final int kVK_Space = 0x31;
+ private static final int kVK_Delete = 0x33;
+ private static final int kVK_Escape = 0x35;
+ private static final int kVK_Command = 0x37;
+ private static final int kVK_Shift = 0x38;
+ private static final int kVK_CapsLock = 0x39;
+ private static final int kVK_Option = 0x3A;
+ private static final int kVK_Control = 0x3B;
+ private static final int kVK_RightShift = 0x3C;
+ private static final int kVK_RightOption = 0x3D;
+ private static final int kVK_RightControl = 0x3E;
+ private static final int kVK_Function = 0x3F;
+ private static final int kVK_F17 = 0x40;
+ private static final int kVK_VolumeUp = 0x48;
+ private static final int kVK_VolumeDown = 0x49;
+ private static final int kVK_Mute = 0x4A;
+ private static final int kVK_F18 = 0x4F;
+ private static final int kVK_F19 = 0x50;
+ private static final int kVK_F20 = 0x5A;
+ private static final int kVK_F5 = 0x60;
+ private static final int kVK_F6 = 0x61;
+ private static final int kVK_F7 = 0x62;
+ private static final int kVK_F3 = 0x63;
+ private static final int kVK_F8 = 0x64;
+ private static final int kVK_F9 = 0x65;
+ private static final int kVK_F11 = 0x67;
+ private static final int kVK_F13 = 0x69;
+ private static final int kVK_F16 = 0x6A;
+ private static final int kVK_F14 = 0x6B;
+ private static final int kVK_F10 = 0x6D;
+ private static final int kVK_F12 = 0x6F;
+ private static final int kVK_F15 = 0x71;
+ private static final int kVK_Help = 0x72;
+ private static final int kVK_Home = 0x73;
+ private static final int kVK_PageUp = 0x74;
+ private static final int kVK_ForwardDelete = 0x75;
+ private static final int kVK_F4 = 0x76;
+ private static final int kVK_End = 0x77;
+ private static final int kVK_F2 = 0x78;
+ private static final int kVK_PageDown = 0x79;
+ private static final int kVK_F1 = 0x7A;
+ private static final int kVK_LeftArrow = 0x7B;
+ private static final int kVK_RightArrow = 0x7C;
+ private static final int kVK_DownArrow = 0x7D;
+ private static final int kVK_UpArrow = 0x7E;
+
+ // Key constants handled differently on Mac OS X than other platforms
+ private static final char NSUpArrowFunctionKey = 0xF700;
+ private static final char NSDownArrowFunctionKey = 0xF701;
+ private static final char NSLeftArrowFunctionKey = 0xF702;
+ private static final char NSRightArrowFunctionKey = 0xF703;
+ private static final char NSF1FunctionKey = 0xF704;
+ private static final char NSF2FunctionKey = 0xF705;
+ private static final char NSF3FunctionKey = 0xF706;
+ private static final char NSF4FunctionKey = 0xF707;
+ private static final char NSF5FunctionKey = 0xF708;
+ private static final char NSF6FunctionKey = 0xF709;
+ private static final char NSF7FunctionKey = 0xF70A;
+ private static final char NSF8FunctionKey = 0xF70B;
+ private static final char NSF9FunctionKey = 0xF70C;
+ private static final char NSF10FunctionKey = 0xF70D;
+ private static final char NSF11FunctionKey = 0xF70E;
+ private static final char NSF12FunctionKey = 0xF70F;
+ private static final char NSF13FunctionKey = 0xF710;
+ private static final char NSF14FunctionKey = 0xF711;
+ private static final char NSF15FunctionKey = 0xF712;
+ private static final char NSF16FunctionKey = 0xF713;
+ private static final char NSF17FunctionKey = 0xF714;
+ private static final char NSF18FunctionKey = 0xF715;
+ private static final char NSF19FunctionKey = 0xF716;
+ private static final char NSF20FunctionKey = 0xF717;
+ private static final char NSF21FunctionKey = 0xF718;
+ private static final char NSF22FunctionKey = 0xF719;
+ private static final char NSF23FunctionKey = 0xF71A;
+ private static final char NSF24FunctionKey = 0xF71B;
+ private static final char NSF25FunctionKey = 0xF71C;
+ private static final char NSF26FunctionKey = 0xF71D;
+ private static final char NSF27FunctionKey = 0xF71E;
+ private static final char NSF28FunctionKey = 0xF71F;
+ private static final char NSF29FunctionKey = 0xF720;
+ private static final char NSF30FunctionKey = 0xF721;
+ private static final char NSF31FunctionKey = 0xF722;
+ private static final char NSF32FunctionKey = 0xF723;
+ private static final char NSF33FunctionKey = 0xF724;
+ private static final char NSF34FunctionKey = 0xF725;
+ private static final char NSF35FunctionKey = 0xF726;
+ private static final char NSInsertFunctionKey = 0xF727;
+ private static final char NSDeleteFunctionKey = 0xF728;
+ private static final char NSHomeFunctionKey = 0xF729;
+ private static final char NSBeginFunctionKey = 0xF72A;
+ private static final char NSEndFunctionKey = 0xF72B;
+ private static final char NSPageUpFunctionKey = 0xF72C;
+ private static final char NSPageDownFunctionKey = 0xF72D;
+ private static final char NSPrintScreenFunctionKey = 0xF72E;
+ private static final char NSScrollLockFunctionKey = 0xF72F;
+ private static final char NSPauseFunctionKey = 0xF730;
+ private static final char NSSysReqFunctionKey = 0xF731;
+ private static final char NSBreakFunctionKey = 0xF732;
+ private static final char NSResetFunctionKey = 0xF733;
+ private static final char NSStopFunctionKey = 0xF734;
+ private static final char NSMenuFunctionKey = 0xF735;
+ private static final char NSUserFunctionKey = 0xF736;
+ private static final char NSSystemFunctionKey = 0xF737;
+ private static final char NSPrintFunctionKey = 0xF738;
+ private static final char NSClearLineFunctionKey = 0xF739;
+ private static final char NSClearDisplayFunctionKey = 0xF73A;
+ private static final char NSInsertLineFunctionKey = 0xF73B;
+ private static final char NSDeleteLineFunctionKey = 0xF73C;
+ private static final char NSInsertCharFunctionKey = 0xF73D;
+ private static final char NSDeleteCharFunctionKey = 0xF73E;
+ private static final char NSPrevFunctionKey = 0xF73F;
+ private static final char NSNextFunctionKey = 0xF740;
+ private static final char NSSelectFunctionKey = 0xF741;
+ private static final char NSExecuteFunctionKey = 0xF742;
+ private static final char NSUndoFunctionKey = 0xF743;
+ private static final char NSRedoFunctionKey = 0xF744;
+ private static final char NSFindFunctionKey = 0xF745;
+ private static final char NSHelpFunctionKey = 0xF746;
+ private static final char NSModeSwitchFunctionKey = 0xF747;
+
+ static int validateKeyCode(int keyCode, char keyChar) {
+ // OS X Virtual Keycodes
+ switch(keyCode) {
+ case kVK_Return: return KeyEvent.VK_ENTER;
+ case kVK_Tab: return KeyEvent.VK_TAB;
+ case kVK_Space: return KeyEvent.VK_SPACE;
+ case kVK_Delete: return KeyEvent.VK_BACK_SPACE;
+ case kVK_Escape: return KeyEvent.VK_ESCAPE;
+ case kVK_Command: return KeyEvent.VK_ALT;
+ case kVK_Shift: return KeyEvent.VK_SHIFT;
+ case kVK_CapsLock: return KeyEvent.VK_CAPS_LOCK;
+ case kVK_Option: return KeyEvent.VK_WINDOWS;
+ case kVK_Control: return KeyEvent.VK_CONTROL;
+ case kVK_RightShift: return KeyEvent.VK_SHIFT;
+ case kVK_RightOption: return KeyEvent.VK_WINDOWS;
+ case kVK_RightControl: return KeyEvent.VK_CONTROL;
+ // case kVK_Function: return KeyEvent.VK_F;
+ case kVK_F17: return KeyEvent.VK_F17;
+ // case kVK_VolumeUp:
+ // case kVK_VolumeDown:
+ // case kVK_Mute:
+ case kVK_F18: return KeyEvent.VK_F18;
+ case kVK_F19: return KeyEvent.VK_F19;
+ case kVK_F20: return KeyEvent.VK_F20;
+ case kVK_F5: return KeyEvent.VK_F5;
+ case kVK_F6: return KeyEvent.VK_F6;
+ case kVK_F7: return KeyEvent.VK_F7;
+ case kVK_F3: return KeyEvent.VK_F3;
+ case kVK_F8: return KeyEvent.VK_F8;
+ case kVK_F9: return KeyEvent.VK_F9;
+ case kVK_F11: return KeyEvent.VK_F11;
+ case kVK_F13: return KeyEvent.VK_F13;
+ case kVK_F16: return KeyEvent.VK_F16;
+ case kVK_F14: return KeyEvent.VK_F14;
+ case kVK_F10: return KeyEvent.VK_F10;
+ case kVK_F12: return KeyEvent.VK_F12;
+ case kVK_F15: return KeyEvent.VK_F15;
+ case kVK_Help: return KeyEvent.VK_HELP;
+ case kVK_Home: return KeyEvent.VK_HOME;
+ case kVK_PageUp: return KeyEvent.VK_PAGE_UP;
+ case kVK_ForwardDelete: return KeyEvent.VK_DELETE;
+ case kVK_F4: return KeyEvent.VK_F4;
+ case kVK_End: return KeyEvent.VK_END;
+ case kVK_F2: return KeyEvent.VK_F2;
+ case kVK_PageDown: return KeyEvent.VK_PAGE_DOWN;
+ case kVK_F1: return KeyEvent.VK_F1;
+ case kVK_LeftArrow: return KeyEvent.VK_LEFT;
+ case kVK_RightArrow: return KeyEvent.VK_RIGHT;
+ case kVK_DownArrow: return KeyEvent.VK_DOWN;
+ case kVK_UpArrow: return KeyEvent.VK_UP;
+ }
+
+ if (keyChar == '\r') {
+ // Turn these into \n
+ return KeyEvent.VK_ENTER;
+ }
+
+ 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;
+ }
+ }
+
+ if ('a' <= keyChar && keyChar <= 'z') {
+ return KeyEvent.VK_A + ( keyChar - 'a' ) ;
+ }
+
+ return (int) keyChar; // let's hope for the best (compatibility of keyChar/keyCode's)
+ }
+}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java b/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
index 67a3f8e92..3204982be 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacScreen.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2011 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
@@ -33,9 +34,16 @@
package jogamp.newt.driver.macosx;
-import com.jogamp.newt.*;
+import java.util.List;
+
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
+
import jogamp.newt.ScreenImpl;
-import javax.media.nativewindow.*;
+
+import com.jogamp.newt.ScreenMode;
+import com.jogamp.newt.util.ScreenModeUtil;
public class MacScreen extends ScreenImpl {
static {
@@ -47,11 +55,69 @@ public class MacScreen extends ScreenImpl {
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);
+
+ 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(final ScreenMode screenMode) {
+ final List<ScreenMode> screenModes = this.getScreenModesOrig();
+ final int screenModeIdx = screenModes.indexOf(screenMode);
+ if(0>screenModeIdx) {
+ throw new RuntimeException("ScreenMode not element of ScreenMode list: "+screenMode);
+ }
+ final int nativeModeIdx = getScreenModesIdx2NativeIdx().get(screenModeIdx);
+ return setScreenMode0(screen_idx, nativeModeIdx);
+ }
+
+ protected int validateScreenIndex(int idx) {
+ return idx;
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ virtualSize.setWidth(getWidthImpl0(screen_idx));
+ virtualSize.setHeight(getHeightImpl0(screen_idx));
+ }
+
+ private native int[] getScreenMode0(int screen_index, int mode_index);
+ private native boolean setScreenMode0(int screen_index, int mode_idx);
}
diff --git a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
index d09ac72ba..75a3cf6d5 100644
--- a/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/macosx/MacWindow.java
@@ -34,108 +34,24 @@
package jogamp.newt.driver.macosx;
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.SurfaceChangeable;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.util.PointImmutable;
import jogamp.newt.WindowImpl;
+import jogamp.newt.driver.DriverClearFocus;
+import jogamp.newt.driver.DriverUpdatePosition;
import com.jogamp.newt.event.KeyEvent;
-public class MacWindow extends WindowImpl {
+public class MacWindow extends WindowImpl implements SurfaceChangeable, DriverClearFocus, DriverUpdatePosition {
- // 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;
-
static {
MacDisplay.initSingleton();
}
@@ -143,18 +59,21 @@ public class MacWindow extends WindowImpl {
public MacWindow() {
}
+ @Override
protected void createNativeImpl() {
- config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, getScreen().getGraphicsScreen());
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
reconfigureWindowImpl(x, y, width, height, getReconfigureFlags(FLAG_CHANGE_VISIBILITY, true));
if (0 == getWindowHandle()) {
throw new NativeWindowException("Error creating window");
}
}
+ @Override
protected void closeNativeImpl() {
try {
if(DEBUG_IMPLEMENTATION) { System.err.println("MacWindow.CloseAction "+Thread.currentThread().getName()); }
@@ -168,81 +87,158 @@ public class MacWindow extends WindowImpl {
}
} finally {
setWindowHandle(0);
+ surfaceHandle = 0;
+ sscSurfaceHandle = 0;
+ isOffscreenInstance = false;
}
}
@Override
protected int lockSurfaceImpl() {
- return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
+ if(!isOffscreenInstance) {
+ return lockSurface0(getWindowHandle()) ? LOCK_SUCCESS : LOCK_SURFACE_NOT_READY;
+ }
+ return LOCK_SUCCESS;
}
@Override
protected void unlockSurfaceImpl() {
- unlockSurface0(getWindowHandle());
+ if(!isOffscreenInstance) {
+ unlockSurface0(getWindowHandle());
+ }
}
@Override
public final long getSurfaceHandle() {
- return surfaceHandle;
+ return 0 != sscSurfaceHandle ? sscSurfaceHandle : surfaceHandle;
+ }
+
+ public void setSurfaceHandle(long surfaceHandle) {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow.setSurfaceHandle(): 0x"+Long.toHexString(surfaceHandle));
+ }
+ sscSurfaceHandle = surfaceHandle;
+ if (isNativeValid()) {
+ if (0 != sscSurfaceHandle) {
+ orderOut0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() );
+ } /** this is done by recreation!
+ else if (isVisible()){
+ orderFront0( 0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle() );
+ } */
+ }
}
+ public void surfaceSizeChanged(int width, int height) {
+ sizeChanged(false, width, height, false);
+ }
+
@Override
protected void setTitleImpl(final String title) {
setTitle0(getWindowHandle(), title);
}
protected void requestFocusImpl(boolean force) {
- requestFocus0(getWindowHandle(), force);
+ if(!isOffscreenInstance) {
+ requestFocus0(getWindowHandle(), force);
+ } else {
+ focusChanged(false, true);
+ }
+ }
+
+ public final void clearFocus() {
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow: clearFocus() - requestFocusParent, isOffscreenInstance "+isOffscreenInstance);
+ }
+ if(!isOffscreenInstance) {
+ requestFocusParent0(getWindowHandle());
+ } else {
+ focusChanged(false, false);
+ }
+ }
+
+ public void updatePosition() {
+ final Point pS = getTopLevelLocationOnScreen(getX(), getY());
+ if(DEBUG_IMPLEMENTATION) {
+ System.err.println("MacWindow: updatePosition() - isOffscreenInstance "+isOffscreenInstance+", new abs pos: pS "+pS);
+ }
+ if( !isOffscreenInstance ) {
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
+ } // else no offscreen position
+ // no native event (fullscreen, some reparenting)
+ super.positionChanged(true, getX(), getY());
}
+
protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
- final PointImmutable pS = position2TopLevel(new Point(x, y));
+ final Point pS = getTopLevelLocationOnScreen(x, y);
+ isOffscreenInstance = 0 != sscSurfaceHandle || isOffscreenInstance(this, this.getParent());
if(DEBUG_IMPLEMENTATION) {
- System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+", "+
- getReconfigureFlagsAsString(null, flags));
+ System.err.println("MacWindow reconfig: "+x+"/"+y+" -> "+pS+" - "+width+"x"+height+
+ ", offscreenInstance "+isOffscreenInstance+
+ ", "+getReconfigureFlagsAsString(null, flags));
}
- if( getWindowHandle() == 0 ) {
- if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
- createWindow(false, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- // no native event ..
- visibleChanged(true, true);
- } /* else { ?? } */
- } else {
- if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
+ if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 == ( FLAG_IS_VISIBLE & flags) ) {
+ if ( !isOffscreenInstance ) {
orderOut0(getWindowHandle());
- // no native event ..
- visibleChanged(true, false);
- }
- if( 0 != ( FLAG_CHANGE_DECORATION & flags) ||
- 0 != ( FLAG_CHANGE_PARENTING & flags) ||
- 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
- createWindow(true, pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
- if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; }
- }
- if(x>=0 && y>=0) {
- setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
- // no native event (fullscreen, some reparenting)
- positionChanged(true, getLocationOnScreenImpl(0, 0)); // incl. validation
}
- if(width>0 && height>0) {
+ // no native event ..
+ visibleChanged(true, false);
+ }
+ if( 0 == getWindowHandle() && 0 != ( FLAG_IS_VISIBLE & flags) ||
+ 0 != ( FLAG_CHANGE_DECORATION & flags) ||
+ 0 != ( FLAG_CHANGE_PARENTING & flags) ||
+ 0 != ( FLAG_CHANGE_FULLSCREEN & flags) ) {
+ createWindow(isOffscreenInstance, 0 != getWindowHandle(), pS, width, height, 0 != ( FLAG_IS_FULLSCREEN & flags));
+ if(isVisible()) { flags |= FLAG_CHANGE_VISIBILITY; }
+ }
+ if(x>=0 && y>=0) {
+ if( !isOffscreenInstance ) {
+ setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), pS.getX(), pS.getY());
+ } // else no offscreen position
+ // no native event (fullscreen, some reparenting)
+ super.positionChanged(true, x, y);
+ }
+ if(width>0 && height>0) {
+ if( !isOffscreenInstance ) {
setContentSize0(getWindowHandle(), width, height);
- // no native event (fullscreen, some reparenting)
- sizeChanged(true, width, height, false); // incl. validation (incl. repositioning)
- }
- if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) {
+ } // else offscreen size is realized via recreation
+ // no native event (fullscreen, some reparenting)
+ sizeChanged(true, width, height, false); // incl. validation (incl. repositioning)
+ }
+ if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && 0 != ( FLAG_IS_VISIBLE & flags) ) {
+ if( !isOffscreenInstance ) {
orderFront0(getWindowHandle());
- // no native event ..
- visibleChanged(true, true);
- }
+ }
+ // no native event ..
+ visibleChanged(true, true);
+ }
+ if( !isOffscreenInstance ) {
setAlwaysOnTop0(getWindowHandle(), 0 != ( FLAG_IS_ALWAYSONTOP & flags));
}
return true;
}
protected Point getLocationOnScreenImpl(int x, int y) {
- return (Point) getLocationOnScreen0(getWindowHandle(), x, y);
+ Point p = new Point(x, y);
+ // min val is 0
+ p.setX(Math.max(p.getX(), 0));
+ p.setY(Math.max(p.getY(), 0));
+
+ final NativeWindow parent = getParent();
+ if( null != parent && 0 != parent.getWindowHandle() ) {
+ p.translate(parent.getLocationOnScreen(null));
+ }
+ return p;
+ }
+
+ private Point getTopLevelLocationOnScreen(int x, int y) {
+ final InsetsImmutable _insets = getInsets(); // zero if undecorated
+ // client position -> top-level window position
+ x -= _insets.getLeftWidth() ;
+ y -= _insets.getTopHeight() ;
+ return getLocationOnScreenImpl(x, y);
}
protected void updateInsetsImpl(Insets insets) {
@@ -252,138 +248,76 @@ public class MacWindow extends WindowImpl {
@Override
protected void sizeChanged(boolean defer, int newWidth, int newHeight, boolean force) {
if(width != newWidth || height != newHeight) {
- final Point p0S = position2TopLevel(new Point(x, y));
+ final Point p0S = getTopLevelLocationOnScreen(x, y);
setFrameTopLeftPoint0(getParentWindowHandle(), getWindowHandle(), p0S.getX(), p0S.getY());
}
super.sizeChanged(defer, newWidth, newHeight, force);
}
@Override
- protected void positionChanged(boolean defer, int newX, int newY) {
- positionChanged(defer, new Point(newX, newY));
+ protected void positionChanged(boolean defer, int newX, int newY) {
+ // passed coordinates are in screen position of the client area
+ if(getWindowHandle()!=0) {
+ // screen position -> window position
+ Point absPos = new Point(newX, newY);
+ final NativeWindow parent = getParent();
+ if(null != parent) {
+ absPos.translate( parent.getLocationOnScreen(null).scale(-1, -1) );
+ }
+ super.positionChanged(defer, absPos.getX(), absPos.getY());
+ }
}
@Override
protected boolean setPointerVisibleImpl(final boolean pointerVisible) {
- return setPointerVisible0(getWindowHandle(), pointerVisible);
+ if( !isOffscreenInstance ) {
+ return setPointerVisible0(getWindowHandle(), pointerVisible);
+ } // else may need offscreen solution ? FIXME
+ return false;
}
@Override
protected boolean confinePointerImpl(final boolean confine) {
- return confinePointer0(getWindowHandle(), confine);
+ if( !isOffscreenInstance ) {
+ return confinePointer0(getWindowHandle(), confine);
+ } // else may need offscreen solution ? FIXME
+ return false;
}
@Override
protected void warpPointerImpl(final int x, final int y) {
- warpPointer0(getWindowHandle(), x, y);
+ if( !isOffscreenInstance ) {
+ warpPointer0(getWindowHandle(), x, y);
+ } // else may need offscreen solution ? FIXME
}
@Override
public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
- final int key = convertKeyChar(keyChar);
- if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+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.sendKeyEvent(eventType, modifiers, key, keyChar);
+ final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
+ if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2));
+ // only deliver keyChar on key Typed events, harmonizing platform behavior
+ keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
+ super.sendKeyEvent(eventType, modifiers, keyCode2, keyChar);
}
@Override
public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
- final 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);
+ final int keyCode2 = MacKeyUtil.validateKeyCode(keyCode, keyChar);
+ if(DEBUG_IMPLEMENTATION) System.err.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()+" char: 0x"+Integer.toHexString(keyChar)+", code 0x"+Integer.toHexString(keyCode)+" -> 0x"+Integer.toHexString(keyCode2));
+ // only deliver keyChar on key Typed events, harmonizing platform behavior
+ keyChar = KeyEvent.EVENT_KEY_TYPED == eventType ? keyChar : (char)-1;
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode2, keyChar);
}
//----------------------------------------------------------------------
// Internals only
//
- 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;
- }
-
- private void createWindow(final boolean recreate,
+ private void createWindow(final boolean offscreenInstance, final boolean recreate,
final PointImmutable pS, final int width, final int height,
final boolean fullscreen) {
@@ -406,59 +340,27 @@ public class MacWindow extends WindowImpl {
}
setWindowHandle(createWindow0(getParentWindowHandle(),
pS.getX(), pS.getY(), width, height,
- config.getChosenCapabilities().isBackgroundOpaque(),
+ (getGraphicsConfiguration().getChosenCapabilities().isBackgroundOpaque() && !offscreenInstance),
fullscreen,
- (isUndecorated() ?
- NSBorderlessWindowMask :
- NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask),
+ ((isUndecorated() || offscreenInstance) ?
+ 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());
- // need to revalidate real position
- positionChanged(true, getLocationOnScreenImpl(0, 0)); // incl. validation
+ if( offscreenInstance ) {
+ orderOut0(0!=getParentWindowHandle() ? getParentWindowHandle() : getWindowHandle());
+ } else {
+ setTitle0(getWindowHandle(), getTitle());
+ }
} catch (Exception ie) {
ie.printStackTrace();
}
}
- private void positionChanged(boolean defer, Point absPos) {
- if(getWindowHandle()!=0) {
- position2ClientSpace(absPos);
- super.positionChanged(defer, absPos.getX(), absPos.getY());
- }
- }
-
- private Point position2ClientSpace(Point absPos) {
- final NativeWindow parent = getParent();
- if(null != parent) {
- return absPos.translate( parent.getLocationOnScreen(null).scale(-1, -1) );
- }
- return absPos;
- }
-
- private Point position2TopLevel(Point clientPos) {
- if(0<=clientPos.getX() && 0<=clientPos.getY()) {
- final InsetsImmutable _insets = getInsets(); // zero if undecorated
- // client position -> top-level window position
- clientPos.setX(clientPos.getX() - _insets.getLeftWidth()) ;
- clientPos.setY(clientPos.getY() - _insets.getTopHeight()) ;
- }
- // min val is 0
- clientPos.setX(Math.max(clientPos.getX(), 0));
- clientPos.setY(Math.max(clientPos.getY(), 0));
- // On MacOSX the absolute position is required to position
- // a window - even a child window!
- final NativeWindow parent = getParent();
- if( null != parent && 0 != parent.getWindowHandle() ) {
- clientPos.translate(parent.getLocationOnScreen(null));
- }
- return clientPos;
- }
-
protected static native boolean initIDs0();
private native long createWindow0(long parentWindowHandle, int x, int y, int w, int h,
boolean opaque, boolean fullscreen, int windowStyle,
@@ -467,6 +369,7 @@ public class MacWindow extends WindowImpl {
private native boolean lockSurface0(long window);
private native void unlockSurface0(long window);
private native void requestFocus0(long window, boolean force);
+ private native void requestFocusParent0(long window);
/** in case of a child window, it actually only issues orderBack(..) */
private native void orderOut0(long window);
private native void orderFront0(long window);
@@ -481,4 +384,21 @@ public class MacWindow extends WindowImpl {
private static native boolean setPointerVisible0(long windowHandle, boolean visible);
private static native boolean confinePointer0(long windowHandle, boolean confine);
private static native void warpPointer0(long windowHandle, int x, int y);
+
+ // 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;
+
+ private volatile long surfaceHandle = 0;
+ private long sscSurfaceHandle = 0;
+ private boolean isOffscreenInstance = false;
+
}
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
index f2e457a0f..f8bce9da3 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsScreen.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,17 +33,15 @@
*/
package jogamp.newt.driver.windows;
-import com.jogamp.common.util.ArrayHashSet;
-import java.util.ArrayList;
+import javax.media.nativewindow.DefaultGraphicsScreen;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
-import com.jogamp.newt.*;
import jogamp.newt.ScreenImpl;
+
import com.jogamp.newt.ScreenMode;
-import jogamp.newt.ScreenModeStatus;
import com.jogamp.newt.util.ScreenModeUtil;
-import javax.media.nativewindow.*;
-
public class WindowsScreen extends ScreenImpl {
static {
@@ -54,9 +53,8 @@ public class WindowsScreen extends ScreenImpl {
protected void createNativeImpl() {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), screen_idx);
- setScreenSize(getWidthImpl0(screen_idx), getHeightImpl0(screen_idx));
}
-
+
protected void closeNativeImpl() {
}
@@ -104,9 +102,21 @@ public class WindowsScreen extends ScreenImpl {
sm.getRotation());
}
+ protected int validateScreenIndex(int idx) {
+ return 0; // big-desktop, only one screen available
+ }
+
+ protected void getVirtualScreenOriginAndSize(Point virtualOrigin, Dimension virtualSize) {
+ virtualOrigin.setX(getOriginX0(screen_idx));
+ virtualOrigin.setY(getOriginY0(screen_idx));
+ virtualSize.setWidth(getWidthImpl0(screen_idx));
+ virtualSize.setHeight(getHeightImpl0(screen_idx));
+ }
+
// Native calls
+ private native int getOriginX0(int screen_idx);
+ private native int getOriginY0(int screen_idx);
private native int getWidthImpl0(int scrn_idx);
-
private native int getHeightImpl0(int scrn_idx);
private native int[] getScreenMode0(int screen_index, int mode_index);
diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
index cd5909d42..ff3bd5ef6 100644
--- a/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
+++ b/src/newt/classes/jogamp/newt/driver/windows/WindowsWindow.java
@@ -35,13 +35,17 @@
package jogamp.newt.driver.windows;
import jogamp.nativewindow.windows.GDI;
+import jogamp.nativewindow.windows.GDIUtil;
import jogamp.newt.WindowImpl;
+
+import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.GraphicsConfigurationFactory;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.newt.event.KeyEvent;
import com.jogamp.newt.event.MouseAdapter;
import com.jogamp.newt.event.MouseEvent;
@@ -100,17 +104,18 @@ public class WindowsWindow extends WindowImpl {
}
protected void createNativeImpl() {
- WindowsScreen screen = (WindowsScreen) getScreen();
- WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
- config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(
+ final WindowsScreen screen = (WindowsScreen) getScreen();
+ final WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
+ final AbstractGraphicsConfiguration cfg = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
+ setGraphicsConfiguration(cfg);
final int flags = getReconfigureFlags(0, true) &
( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
setWindowHandle(CreateWindow0(display.getHInstance(), display.getWindowClassName(), display.getWindowClassName(),
- getParentWindowHandle(), x, y, width, height, flags));
+ getParentWindowHandle(), x, y, width, height, autoPosition, flags));
if (getWindowHandle() == 0) {
throw new NativeWindowException("Error creating window");
}
@@ -169,12 +174,8 @@ public class WindowsWindow extends WindowImpl {
final InsetsImmutable i = getInsets();
// client position -> top-level window position
- if(0<=x && 0<=y) {
- x -= i.getLeftWidth() ;
- y -= i.getTopHeight() ;
- if( 0 > x ) { x = 0; }
- if( 0 > y ) { y = 0; }
- }
+ x -= i.getLeftWidth() ;
+ y -= i.getTopHeight() ;
if(0<width && 0<height) {
// client size -> top-level window size
@@ -237,13 +238,43 @@ public class WindowsWindow extends WindowImpl {
}
protected Point getLocationOnScreenImpl(int x, int y) {
- return GDI.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
+ return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y);
}
protected void updateInsetsImpl(Insets insets) {
// nop - using event driven insetsChange(..)
}
+ private final int validateKeyCode(int eventType, int keyCode) {
+ switch(eventType) {
+ case KeyEvent.EVENT_KEY_PRESSED:
+ lastPressedKeyCode = keyCode;
+ break;
+ case KeyEvent.EVENT_KEY_TYPED:
+ if(-1==keyCode) {
+ keyCode = lastPressedKeyCode;
+ }
+ lastPressedKeyCode = -1;
+ break;
+ }
+ return keyCode;
+ }
+ private int lastPressedKeyCode = 0;
+
+ @Override
+ public void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
+ keyCode = validateKeyCode(eventType, keyCode);
+ super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
+ }
+
+ @Override
+ public void enqueueKeyEvent(boolean wait, int eventType, int modifiers, int keyCode, char keyChar) {
+ // Note that we have to regenerate the keyCode for EVENT_KEY_TYPED on this platform
+ keyCode = validateKeyCode(eventType, keyCode);
+ super.enqueueKeyEvent(wait, eventType, modifiers, keyCode, keyChar);
+ }
+
//----------------------------------------------------------------------
// Internals only
//
@@ -252,7 +283,7 @@ public class WindowsWindow extends WindowImpl {
private native long CreateWindow0(long hInstance, String wndClassName, String wndName,
long parentWindowHandle,
- int x, int y, int width, int height, int flags);
+ int x, int y, int width, int height, boolean autoPosition, int flags);
private native long MonitorFromWindow0(long windowHandle);
private native void reconfigureWindow0(long parentWindowHandle, long windowHandle,
int x, int y, int width, int height, int flags);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java b/src/newt/classes/jogamp/newt/driver/x11/X11Display.java
index b9a32c7de..b3bc6e475 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Display.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Display.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,10 +34,14 @@
package jogamp.newt.driver.x11;
-import javax.media.nativewindow.*;
-import javax.media.nativewindow.x11.*;
-import jogamp.newt.*;
+import javax.media.nativewindow.AbstractGraphicsDevice;
+import javax.media.nativewindow.NativeWindowException;
+import javax.media.nativewindow.NativeWindowFactory;
+import javax.media.nativewindow.x11.X11GraphicsDevice;
+
import jogamp.nativewindow.x11.X11Util;
+import jogamp.newt.DisplayImpl;
+import jogamp.newt.NEWTJNILibLoader;
public class X11Display extends DisplayImpl {
@@ -64,6 +69,20 @@ public class X11Display extends DisplayImpl {
return X11Util.validateDisplayName(name, handle);
}
+ /**
+ * {@inheritDoc}
+ *
+ * We use a private non-shared X11 Display instance for EDT window operations and one for exposed animation, eg. OpenGL.
+ * <p>
+ * In case {@link X11Util#HAS_XLOCKDISPLAY_BUG} and {@link X11Util#XINITTHREADS_ALWAYS_ENABLED},
+ * we use null locking. Even though this seems not to be rational, it gives most stable results on all platforms.
+ * </p>
+ * <p>
+ * Otherwise we use basic locking via the constructor {@link X11GraphicsDevice#X11GraphicsDevice(long, int, boolean)},
+ * since it is possible to share this device via {@link com.jogamp.newt.NewtFactory#createDisplay(String, boolean)}.
+ * </p>
+ */
+ @SuppressWarnings("unused")
protected void createNativeImpl() {
long handle = X11Util.openDisplay(name);
if( 0 == handle ) {
@@ -85,12 +104,11 @@ public class X11Display extends DisplayImpl {
throw e;
}
- if(X11Util.XINITTHREADS_ALWAYS_ENABLED) {
- // Hack: Force non X11Display locking, even w/ AWT and w/o isFirstUIActionOnProcess()
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock());
+ // see API doc above!
+ if(X11Util.XINITTHREADS_ALWAYS_ENABLED && X11Util.HAS_XLOCKDISPLAY_BUG) {
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, NativeWindowFactory.getNullToolkitLock(), false);
} else {
- // Proper: Use AWT/X11Display locking w/ AWT and X11Display locking only w/o isFirstUIActionOnProcess()
- aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT);
+ aDevice = new X11GraphicsDevice(handle, AbstractGraphicsDevice.DEFAULT_UNIT, false);
}
}
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
index 5c9c326d7..ed5ebc04e 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Screen.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -32,6 +33,8 @@
*/
package jogamp.newt.driver.x11;
+import jogamp.nativewindow.x11.X11Lib;
+import jogamp.nativewindow.x11.X11Util;
import jogamp.newt.DisplayImpl;
import jogamp.newt.ScreenImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
@@ -40,6 +43,8 @@ import com.jogamp.newt.ScreenMode;
import com.jogamp.newt.util.ScreenModeUtil;
import java.util.List;
+import javax.media.nativewindow.util.Dimension;
+import javax.media.nativewindow.util.Point;
import javax.media.nativewindow.x11.*;
public class X11Screen extends ScreenImpl {
@@ -55,11 +60,7 @@ public class X11Screen extends ScreenImpl {
// validate screen index
Long handle = display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Long>() {
public Long run(long dpy) {
- long handle = GetScreen0(dpy, screen_idx);
- if(0 != handle) {
- setScreenSize(getWidth0(dpy, screen_idx), getHeight0(dpy, screen_idx));
- }
- return new Long(handle);
+ return new Long(GetScreen0(dpy, screen_idx));
} } );
if (handle.longValue() == 0) {
throw new RuntimeException("Error creating screen: " + screen_idx);
@@ -245,35 +246,64 @@ public class X11Screen extends ScreenImpl {
}
}).booleanValue();
- if(DEBUG && done) {
+ if(DEBUG || !done) {
System.err.println("X11Screen.setCurrentScreenModeImpl: TO ("+SCREEN_MODE_CHANGE_TIMEOUT+") reached: "+
- (System.currentTimeMillis()-t0)+"ms");
+ (System.currentTimeMillis()-t0)+"ms; Current: "+getCurrentScreenMode()+"; Desired: "+screenMode);
}
return done;
}
+ private class XineramaEnabledQuery implements DisplayImpl.DisplayRunnable<Boolean> {
+ public Boolean run(long dpy) {
+ return new Boolean(X11Lib.XineramaEnabled(dpy));
+ }
+ }
+ private XineramaEnabledQuery xineramaEnabledQuery = new XineramaEnabledQuery();
+
+ protected int validateScreenIndex(final int idx) {
+ if(getDisplay().isNativeValid()) {
+ return runWithLockedDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ } else {
+ return runWithTempDisplayHandle( xineramaEnabledQuery ).booleanValue() ? 0 : idx;
+ }
+ }
+
+ protected void getVirtualScreenOriginAndSize(final Point virtualOrigin, final Dimension virtualSize) {
+ display.runWithLockedDisplayHandle( new DisplayImpl.DisplayRunnable<Object>() {
+ public Object run(long dpy) {
+ virtualOrigin.setX(0);
+ virtualOrigin.setY(0);
+ virtualSize.setWidth(getWidth0(dpy, screen_idx));
+ virtualSize.setHeight(getHeight0(dpy, screen_idx));
+ return null;
+ } } );
+ }
+
//----------------------------------------------------------------------
// Internals only
//
private final <T> T runWithLockedDisplayHandle(DisplayRunnable<T> action) {
return display.runWithLockedDisplayHandle(action);
// return runWithTempDisplayHandle(action);
+ // return runWithoutLock(action);
}
- /** just here for testing some X11 RANDR bugs .. etc ..
- private final Object runWithTempDisplayHandle(DisplayRunnable action) {
- long dpy = X11Util.openDisplay(null);
- if(0 == dpy) {
+ private final <T> T runWithTempDisplayHandle(DisplayRunnable<T> action) {
+ final long displayHandle = X11Util.openDisplay(display.getName());
+ if(0 == displayHandle) {
throw new RuntimeException("null device");
}
- Object res;
+ T res;
try {
- res = action.run(dpy);
+ res = action.run(displayHandle);
} finally {
- X11Util.closeDisplay(dpy);
+ X11Util.closeDisplay(displayHandle);
}
return res;
- } */
+ }
+ private final <T> T runWithoutLock(DisplayRunnable<T> action) {
+ return action.run(display.getHandle());
+ }
private static native long GetScreen0(long dpy, int scrn_idx);
diff --git a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
index 2b6bac215..33b541c34 100644
--- a/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
+++ b/src/newt/classes/jogamp/newt/driver/x11/X11Window.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -33,7 +34,7 @@
package jogamp.newt.driver.x11;
-import jogamp.nativewindow.x11.X11Util;
+import jogamp.nativewindow.x11.X11Lib;
import jogamp.newt.DisplayImpl;
import jogamp.newt.DisplayImpl.DisplayRunnable;
import jogamp.newt.WindowImpl;
@@ -43,9 +44,15 @@ import javax.media.nativewindow.util.Insets;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
+import com.jogamp.newt.event.MouseEvent;
+
public class X11Window extends WindowImpl {
private static final String WINDOW_CLASS_NAME = "NewtWindow";
-
+ private static final int X11_WHEEL_ONE_UP_BUTTON = 4;
+ private static final int X11_WHEEL_ONE_DOWN_BUTTON = 5;
+ private static final int X11_WHEEL_TWO_UP_BUTTON = 6;
+ private static final int X11_WHEEL_TWO_DOWN_BUTTON = 7;
+
static {
X11Display.initSingleton();
}
@@ -57,22 +64,22 @@ public class X11Window extends WindowImpl {
final X11Screen screen = (X11Screen) getScreen();
final X11Display display = (X11Display) screen.getDisplay();
final GraphicsConfigurationFactory factory = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice());
- config = factory.chooseGraphicsConfiguration(
+ final X11GraphicsConfiguration cfg = (X11GraphicsConfiguration) factory.chooseGraphicsConfiguration(
capsRequested, capsRequested, capabilitiesChooser, screen.getGraphicsScreen());
if(DEBUG_IMPLEMENTATION) {
- System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+config);
+ System.err.println("X11Window.createNativeImpl() factory: "+factory+", chosen config: "+cfg);
}
- if (config == null) {
+ if (null == cfg) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
- X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config;
- final long visualID = x11config.getVisualID();
+ setGraphicsConfiguration(cfg);
+ final long visualID = cfg.getVisualID();
final int flags = getReconfigureFlags(0, true) &
( FLAG_IS_ALWAYSONTOP | FLAG_IS_UNDECORATED ) ;
setWindowHandle(CreateWindow0(getParentWindowHandle(),
display.getEDTHandle(), screen.getIndex(), visualID,
display.getJavaObjectAtom(), display.getWindowDeleteAtom(),
- x, y, width, height, flags));
+ x, y, width, height, autoPosition, flags));
windowHandleClose = getWindowHandle();
if (0 == windowHandleClose) {
throw new NativeWindowException("Error creating window");
@@ -101,14 +108,12 @@ public class X11Window extends WindowImpl {
System.err.println("X11Window reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
getReconfigureFlagsAsString(null, flags));
}
- if(0 == ( FLAG_IS_UNDECORATED & flags) && 0<=x && 0<=y) {
+ if(0 == ( FLAG_IS_UNDECORATED & flags)) {
final InsetsImmutable i = getInsets();
// client position -> top-level window position
x -= i.getLeftWidth() ;
y -= i.getTopHeight() ;
- if( 0 > x ) { x = 0; }
- if( 0 > y ) { y = 0; }
}
reconfigureWindow0( getDisplayEDTHandle(), getScreenIndex(), getParentWindowHandle(), getWindowHandle(),
x, y, width, height, flags);
@@ -167,13 +172,55 @@ public class X11Window extends WindowImpl {
protected Point getLocationOnScreenImpl(final int x, final int y) {
// X11Util.GetRelativeLocation: locks display already !
- return X11Util.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
+ return X11Lib.GetRelativeLocation( getScreen().getDisplay().getHandle(), getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y);
}
protected void updateInsetsImpl(Insets insets) {
// nop - using event driven insetsChange(..)
}
+ protected void doMouseEvent(boolean enqueue, boolean wait, int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ switch(eventType) {
+ case MouseEvent.EVENT_MOUSE_PRESSED:
+ switch(button) {
+ case X11_WHEEL_ONE_UP_BUTTON:
+ case X11_WHEEL_ONE_DOWN_BUTTON:
+ case X11_WHEEL_TWO_UP_BUTTON:
+ case X11_WHEEL_TWO_DOWN_BUTTON:
+ // ignore wheel pressed !
+ return;
+ }
+ break;
+ case MouseEvent.EVENT_MOUSE_RELEASED:
+ switch(button) {
+ case X11_WHEEL_ONE_UP_BUTTON:
+ eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
+ button = 1;
+ rotation = 1;
+ break;
+ case X11_WHEEL_ONE_DOWN_BUTTON:
+ eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
+ button = 1;
+ rotation = -1;
+ break;
+ case X11_WHEEL_TWO_UP_BUTTON:
+ eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
+ button = 2;
+ rotation = 1;
+ break;
+ case X11_WHEEL_TWO_DOWN_BUTTON:
+ eventType = MouseEvent.EVENT_MOUSE_WHEEL_MOVED;
+ button = 2;
+ rotation = -1;
+ break;
+ }
+ break;
+ }
+ super.doMouseEvent(enqueue, wait, eventType, modifiers, x, y, button, rotation);
+ }
+
+
//----------------------------------------------------------------------
// Internals only
//
@@ -190,7 +237,7 @@ public class X11Window extends WindowImpl {
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, int flags);
+ int x, int y, int width, int height, boolean autoPosition, int flags);
private native void CloseWindow0(long display, long windowHandle, long javaObjectAtom, long windowDeleteAtom);
private native void reconfigureWindow0(long display, int screen_index, long parentWindowHandle, long windowHandle,
int x, int y, int width, int height, int flags);
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index 5f1affed1..e6bc7952e 100644
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -256,7 +256,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_kd_KDWindow_RealizeWindow
jint res = kdRealizeWindow(w, &nativeWindow);
if(res) {
fprintf(stderr, "[RealizeWindow] failed: 0x%X, 0x%X\n", res, kdGetError());
- nativeWindow = NULL;
+ nativeWindow = 0;
}
DBG_PRINT( "[RealizeWindow] ok: %p\n", nativeWindow);
return (jlong) (intptr_t) nativeWindow;
diff --git a/src/newt/native/KeyEvent.h b/src/newt/native/KeyEvent.h
index 1ead0f5e8..0f7b1606b 100644
--- a/src/newt/native/KeyEvent.h
+++ b/src/newt/native/KeyEvent.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 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.
+ */
#ifndef _KEY_EVENT_H_
#define _KEY_EVENT_H_
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index a13ffaf31..ddd59f0a1 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -38,6 +38,7 @@
#import "MouseEvent.h"
#import "KeyEvent.h"
+#import "ScreenMode.h"
#import <ApplicationServices/ApplicationServices.h>
@@ -48,7 +49,6 @@ static const char * const ClazzAnyCstrName = "<init>";
static const char * const ClazzNamePointCstrSignature = "(II)V";
static jclass pointClz = NULL;
static jmethodID pointCstr = NULL;
-static jmethodID focusActionID = NULL;
static NSString* jstringToNSString(JNIEnv* env, jstring jstr)
{
@@ -192,13 +192,57 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_initNSAppli
JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_runNSApplication0
(JNIEnv *env, jclass clazz)
{
- // NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
DBG_PRINT( "\nrunNSApplication0.0\n");
[NSApp run];
DBG_PRINT( "\nrunNSApplication0.X\n");
- // [pool release];
+ [pool release];
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacDisplay
+ * Method: stopNSApplication0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacDisplay_stopNSApplication0
+ (JNIEnv *env, jclass clazz)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ DBG_PRINT( "\nstopNSApplication0.0 nsApp.running %d\n", (NSApp && [NSApp isRunning]));
+
+ if(NSApp && [NSApp isRunning]) {
+ [NSApp performSelectorOnMainThread:@selector(stop:) withObject:nil waitUntilDone:YES];
+ // [NSApp stop: nil];
+ NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
+ location: NSMakePoint(0,0)
+ modifierFlags: 0
+ timestamp: 0.0
+ windowNumber: 0
+ context: nil
+ subtype: 0
+ data1: 0
+ data2: 0];
+ DBG_PRINT( "\nstopNSApplication0.1\n");
+ [NSApp postEvent: event atStart: true];
+ }
+ /**
+ DBG_PRINT( "\nstopNSApplication0.2\n");
+ if(NSApp && [NSApp isRunning]) {
+ DBG_PRINT( "\nstopNSApplication0.3\n");
+ [NSApp terminate:nil];
+ } */
+
+ DBG_PRINT( "\nstopNSApplication0.X\n");
+ [pool release];
+}
+
+static NSScreen * NewtScreen_getNSScreenByIndex(int screen_idx) {
+ NSArray *screens = [NSScreen screens];
+ if(screen_idx<0) screen_idx=0;
+ if(screen_idx>=[screens count]) screen_idx=0;
+ return (NSScreen *) [screens objectAtIndex: screen_idx];
}
/*
@@ -211,10 +255,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getWidthImpl0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
NSRect rect = [screen frame];
[pool release];
@@ -232,10 +273,7 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSArray *screens = [NSScreen screens];
- if(screen_idx<0) screen_idx=0;
- if(screen_idx>=[screens count]) screen_idx=0;
- NSScreen *screen = (NSScreen *) [screens objectAtIndex: screen_idx];
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)screen_idx);
NSRect rect = [screen frame];
[pool release];
@@ -243,6 +281,175 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getHeightImpl0
return (jint) (rect.size.height);
}
+static CGDirectDisplayID NewtScreen_getCGDirectDisplayIDByNSScreen(NSScreen *screen) {
+ // Mind: typedef uint32_t CGDirectDisplayID; - however, we assume it's 64bit on 64bit ?!
+ NSDictionary * dict = [screen deviceDescription];
+ NSNumber * val = (NSNumber *) [dict objectForKey: @"NSScreenNumber"];
+ // [NSNumber integerValue] returns NSInteger which is 32 or 64 bit native size
+ return (CGDirectDisplayID) [val integerValue];
+}
+
+/**
+ * Only in >= 10.6:
+ * CGDisplayModeGetWidth(mode)
+ * CGDisplayModeGetRefreshRate(mode)
+ * CGDisplayModeGetHeight(mode)
+ */
+static long GetDictionaryLong(CFDictionaryRef theDict, const void* key)
+{
+ long value = 0;
+ CFNumberRef numRef;
+ numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
+ if (numRef != NULL)
+ CFNumberGetValue(numRef, kCFNumberLongType, &value);
+ return value;
+}
+#define CGDDGetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth)
+#define CGDDGetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight)
+#define CGDDGetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
+#define CGDDGetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel)
+
+// Duplicate each Mode by all possible rotations (4):
+// For each real-mode: [mode, 0], [mode, 90], [mode, 180], [mode, 270]
+#define ROTMODES_PER_REALMODE 4
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacScreen
+ * Method: getScreenMode0
+ * Signature: (II)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_macosx_MacScreen_getScreenMode0
+ (JNIEnv *env, jobject obj, jint scrn_idx, jint mode_idx)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ int prop_num = NUM_SCREEN_MODE_PROPERTIES_ALL;
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+
+ CFArrayRef availableModes = CGDisplayAvailableModes(display);
+ CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
+ CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
+ CFDictionaryRef mode = NULL;
+ int currentCCWRot = (int)CGDisplayRotation(display);
+ jint ccwRot = 0;
+
+#ifdef VERBOSE_ON
+ if(0 >= mode_idx) {
+ // only for current mode (-1) and first mode (scanning)
+ DBG_PRINT( "getScreenMode0: scrn %d (%p, %p), mode %d, avail: %d/%d, current rot %d ccw\n",
+ (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots, currentCCWRot);
+ }
+#endif
+
+ if(numberOfAvailableModesRots<=mode_idx) {
+ // n/a - end of modes
+ DBG_PRINT( "getScreenMode0: end of modes: mode %d, avail: %d/%d\n",
+ (int)mode_idx, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
+ [pool release];
+ return (*env)->NewIntArray(env, 0);
+ } else if(-1 < mode_idx) {
+ // only at initialization time, where index >= 0
+ prop_num++; // add 1st extra prop, mode_idx
+ mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE);
+ ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
+ } else {
+ // current mode
+ mode = CGDisplayCurrentMode(display);
+ ccwRot = currentCCWRot;
+ }
+ // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
+
+ CGSize screenDim = CGDisplayScreenSize(display);
+ int mWidth = CGDDGetModeWidth(mode);
+ int mHeight = CGDDGetModeHeight(mode);
+
+ // swap width and height, since OSX reflects rotated dimension, we don't
+ if ( 90 == currentCCWRot || 270 == currentCCWRot ) {
+ int tempWidth = mWidth;
+ mWidth = mHeight;
+ mHeight = tempWidth;
+ }
+
+ jint prop[ prop_num ];
+ int propIndex = 0;
+ int propIndexRes = 0;
+
+ if( -1 < mode_idx ) {
+ prop[propIndex++] = mode_idx;
+ }
+ prop[propIndex++] = 0; // set later for verification of iterator
+ propIndexRes = propIndex;
+ prop[propIndex++] = mWidth;
+ prop[propIndex++] = mHeight;
+ prop[propIndex++] = CGDDGetModeBitsPerPixel(mode);
+ prop[propIndex++] = (jint) screenDim.width;
+ prop[propIndex++] = (jint) screenDim.height;
+ prop[propIndex++] = CGDDGetModeRefreshRate(mode);
+ prop[propIndex++] = ccwRot;
+ prop[propIndex - NUM_SCREEN_MODE_PROPERTIES_ALL] = ( -1 < mode_idx ) ? propIndex-1 : propIndex ; // count == NUM_SCREEN_MODE_PROPERTIES_ALL
+
+ DBG_PRINT( "getScreenMode0: Mode %d/%d (%d): %dx%d, %d bpp, %dx%d mm, %d Hz, rot %d ccw\n",
+ (int)mode_idx, (int)numberOfAvailableModesRots, (int)numberOfAvailableModes,
+ (int)prop[propIndexRes+0], (int)prop[propIndexRes+1], (int)prop[propIndexRes+2],
+ (int)prop[propIndexRes+3], (int)prop[propIndexRes+4], (int)prop[propIndexRes+5], (int)prop[propIndexRes+6]);
+
+ jintArray properties = (*env)->NewIntArray(env, prop_num);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", prop_num);
+ }
+ (*env)->SetIntArrayRegion(env, properties, 0, prop_num, prop);
+
+ // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
+ [pool release];
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_macosx_MacScreen
+ * Method: setScreenMode0
+ * Signature: (II)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacScreen_setScreenMode0
+ (JNIEnv *env, jobject object, jint scrn_idx, jint mode_idx)
+{
+ jboolean res = JNI_TRUE;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+ NSScreen *screen = NewtScreen_getNSScreenByIndex((int)scrn_idx);
+ CGDirectDisplayID display = NewtScreen_getCGDirectDisplayIDByNSScreen(screen);
+
+ CFArrayRef availableModes = CGDisplayAvailableModes(display);
+ CFIndex numberOfAvailableModes = CFArrayGetCount(availableModes);
+ CFIndex numberOfAvailableModesRots = ROTMODES_PER_REALMODE * numberOfAvailableModes;
+
+ CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, mode_idx / ROTMODES_PER_REALMODE);
+ // mode = CGDisplayModeRetain(mode); // 10.6 on CGDisplayModeRef
+
+ int ccwRot = mode_idx % ROTMODES_PER_REALMODE * 90;
+ DBG_PRINT( "setScreenMode0: scrn %d (%p, %p), mode %d, rot %d ccw, avail: %d/%d\n",
+ (int)scrn_idx, screen, (void*)(intptr_t)display, (int)mode_idx, ccwRot, (int)numberOfAvailableModes, (int)numberOfAvailableModesRots);
+
+ if(ccwRot!=0) {
+ // FIXME: How to rotate the display/screen on OSX programmatically ?
+ DBG_PRINT( "setScreenMode0: Don't know how to rotate screen on OS X: rot %d ccw\n", ccwRot);
+ res = JNI_FALSE;
+ }
+ if(JNI_TRUE == res) {
+ CGError err = CGDisplaySwitchToMode(display, mode);
+ if(kCGErrorSuccess != err) {
+ DBG_PRINT( "setScreenMode0: SetMode failed: %d\n", (int)err);
+ res = JNI_FALSE;
+ }
+ }
+
+ // CGDisplayModeRelease(mode); // 10.6 on CGDisplayModeRef
+ [pool release];
+
+ return res;
+}
+
/*
* Class: jogamp_newt_driver_macosx_MacWindow
* Method: initIDs
@@ -272,11 +479,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_MacWindow_initIDs0
ClazzNamePoint, ClazzAnyCstrName, ClazzNamePointCstrSignature);
}
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
- if(NULL==focusActionID) {
- NewtCommon_FatalError(env, "FatalError Java_jogamp_newt_driver_macosx_MacWindow_initIDs0: can't fetch method focusAction()Z");
- }
-
// Need this when debugging, as it is necessary to attach gdb to
// the running java process -- "gdb java" doesn't work
// printf("Going to sleep for 10 seconds\n");
@@ -449,8 +651,9 @@ NS_DURING
if([mView isInFullScreenMode]) {
[mView exitFullScreenModeWithOptions: NULL];
}
- [mWin setContentView: nil];
- [mView release];
+ // Note: mWin's release will also release it's mView!
+ // [mWin setContentView: nil];
+ // [mView release];
}
NS_HANDLER
NS_ENDHANDLER
@@ -463,7 +666,11 @@ NS_ENDHANDLER
DBG_PRINT( "windowClose.1 - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
- [mWin close]; // performs release!
+ // '[mWin close]' causes a crash at exit.
+ // This probably happens b/c it sends events to the main loop
+ // but our resources are gone ?!
+ // However, issuing a simple release seems to work quite well.
+ [mWin release];
DBG_PRINT( "windowClose.X - %p,%d view %p,%d, parent %p\n",
mWin, getRetainCount(mWin), mView, getRetainCount(mView), pWin);
@@ -510,26 +717,44 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocus0
(JNIEnv *env, jobject window, jlong w, jboolean force)
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSWindow* win = (NSWindow*) ((intptr_t) w);
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
#ifdef VERBOSE_ON
- BOOL hasFocus = [win isKeyWindow];
+ BOOL hasFocus = [mWin isKeyWindow];
#endif
- DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", win, force, hasFocus);
-
- // Even if we already own the focus, we need the 'focusAction()' call
- // and the other probably redundant NS calls to force proper focus traversal
- // of the parent TK (AWT doesn't do it properly on OSX).
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "makeKeyWindow win %p\n", win);
- // [win performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
- // [win performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
- [win orderFrontRegardless];
- [win makeKeyWindow];
- [win makeFirstResponder: nil];
- }
+ DBG_PRINT( "requestFocus - window: %p, force %d, hasFocus %d (START)\n", mWin, force, hasFocus);
+
+ [mWin makeFirstResponder: nil];
+ // [mWin performSelectorOnMainThread:@selector(orderFrontRegardless) withObject:nil waitUntilDone:YES];
+ // [mWin performSelectorOnMainThread:@selector(makeKeyWindow) withObject:nil waitUntilDone:YES];
+ [mWin orderFrontRegardless];
+ [mWin makeKeyWindow];
+
+ DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", mWin, force);
+
+ [pool release];
+}
- DBG_PRINT( "requestFocus - window: %p, force %d (END)\n", win, force);
+/*
+ * Class: jogamp_newt_driver_macosx_MacWindow
+ * Method: requestFocusParent0
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_MacWindow_requestFocusParent0
+ (JNIEnv *env, jobject window, jlong w)
+{
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSWindow* mWin = (NSWindow*) ((intptr_t) w);
+ NSWindow* pWin = [mWin parentWindow];
+#ifdef VERBOSE_ON
+ BOOL hasFocus = [mWin isKeyWindow];
+#endif
+
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p, hasFocus %d (START)\n", mWin, pWin, hasFocus );
+ if(NULL != pWin) {
+ [pWin makeKeyWindow];
+ }
+ DBG_PRINT( "requestFocusParent0 - window: %p, parent: %p (END)\n", mWin, pWin);
[pool release];
}
diff --git a/src/newt/native/MouseEvent.h b/src/newt/native/MouseEvent.h
index e9c0476ef..59d63cecf 100644
--- a/src/newt/native/MouseEvent.h
+++ b/src/newt/native/MouseEvent.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 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.
+ */
#ifndef _MOUSE_EVENT_H_
#define _MOUSE_EVENT_H_
diff --git a/src/newt/native/NewtCommon.h b/src/newt/native/NewtCommon.h
index 91fceb310..33aba64ae 100644
--- a/src/newt/native/NewtCommon.h
+++ b/src/newt/native/NewtCommon.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 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.
+ */
#ifndef NEWT_COMMON_H
#define NEWT_COMMON_H 1
diff --git a/src/newt/native/NewtMacWindow.h b/src/newt/native/NewtMacWindow.h
index cb256e71f..3ba89de1e 100644
--- a/src/newt/native/NewtMacWindow.h
+++ b/src/newt/native/NewtMacWindow.h
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2011 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -40,7 +41,8 @@
// #define VERBOSE_ON 1
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+ #define DBG_PRINT(...) NSLog(@ __VA_ARGS__)
+ // #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
#else
#define DBG_PRINT(...)
#endif
@@ -53,8 +55,8 @@
JavaVM *jvmHandle;
int jvmVersion;
- BOOL destroyNotifySent;
- BOOL softLocked;
+ volatile BOOL destroyNotifySent;
+ volatile BOOL softLocked;
pthread_mutex_t softLockSync;
NSTrackingRectTag ptrTrackingTag;
@@ -88,7 +90,7 @@
- (BOOL) needsDisplay;
- (void) displayIfNeeded;
-- (void) viewWillDraw;
+- (void) display;
- (void) drawRect:(NSRect)dirtyRect;
- (void) viewDidHide;
- (void) viewDidUnhide;
diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m
index 1f74742ec..ce41673c4 100644
--- a/src/newt/native/NewtMacWindow.m
+++ b/src/newt/native/NewtMacWindow.m
@@ -44,15 +44,17 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
// mouse pad case
deltaY =
CGEventGetIntegerValueField(cgEvent, kCGScrollWheelEventPointDeltaAxis1);
+ // fprintf(stderr, "WHEEL/PAD: %lf\n", (double)deltaY);
} else {
// traditional mouse wheel case
deltaY = [event deltaY];
+ // fprintf(stderr, "WHEEL/TRAD: %lf\n", (double)deltaY);
if (deltaY == 0.0 && (javaMods & EVENT_SHIFT_MASK) != 0) {
// shift+vertical wheel scroll produces horizontal scroll
// we convert it to vertical
deltaY = [event deltaX];
}
- if (deltaY < 1.0 && deltaY > -1.0) {
+ if (-1.0 < deltaY && deltaY < 1.0) {
deltaY *= 10.0;
} else {
if (deltaY < 0.0) {
@@ -62,21 +64,15 @@ jint GetDeltaY(NSEvent *event, jint javaMods) {
}
}
}
-
- if (deltaY > 0) {
- return (NSInteger)deltaY;
- } else if (deltaY < 0) {
- return -(NSInteger)deltaY;
- }
-
- return 0;
+ // fprintf(stderr, "WHEEL/res: %d\n", (int)deltaY);
+ return (jint) deltaY;
}
static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static jmethodID insetsChangedID = NULL;
static jmethodID sizeChangedID = NULL;
@@ -104,7 +100,11 @@ static jmethodID windowRepaintID = NULL;
jvmVersion = 0;
destroyNotifySent = NO;
softLocked = NO;
- pthread_mutex_init(&softLockSync, NULL); // fast non-recursive
+
+ pthread_mutexattr_t softLockSyncAttr;
+ pthread_mutexattr_init(&softLockSyncAttr);
+ pthread_mutexattr_settype(&softLockSyncAttr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&softLockSync, &softLockSyncAttr); // recursive
ptrTrackingTag = 0;
@@ -122,7 +122,7 @@ static jmethodID windowRepaintID = NULL;
- (void) dealloc
{
if(softLocked) {
- fprintf(stderr, "*** Warning: softLock still hold @ dealloc!\n"); fflush(NULL);
+ NSLog(@"NewtView::dealloc: softLock still hold @ dealloc!\n");
}
pthread_mutex_destroy(&softLockSync);
[super dealloc];
@@ -193,72 +193,61 @@ static jmethodID windowRepaintID = NULL;
return destroyNotifySent;
}
-#define SOFT_LOCK_BLOCKING 1
-
- (BOOL) softLock
{
+ // DBG_PRINT("*************** softLock.0: %p\n", (void*)pthread_self());
+ // NSLog(@"NewtView::softLock: %@",[NSThread callStackSymbols]);
pthread_mutex_lock(&softLockSync);
softLocked = YES;
-#ifndef SOFT_LOCK_BLOCKING
- pthread_mutex_unlock(&softLockSync);
-#endif
+ // DBG_PRINT("*************** softLock.X: %p\n", (void*)pthread_self());
return softLocked;
}
- (void) softUnlock
{
-#ifndef SOFT_LOCK_BLOCKING
- pthread_mutex_lock(&softLockSync);
-#endif
+ // DBG_PRINT("*************** softUnlock: %p\n", (void*)pthread_self());
softLocked = NO;
pthread_mutex_unlock(&softLockSync);
}
- (BOOL) needsDisplay
{
-#ifndef SOFT_LOCK_BLOCKING
- return NO == softLocked && NO == destroyNotifySent && [super needsDisplay];
-#else
return NO == destroyNotifySent && [super needsDisplay];
-#endif
}
- (void) displayIfNeeded
{
-#ifndef SOFT_LOCK_BLOCKING
- if( NO == softLocked && NO == destroyNotifySent ) {
+ if( YES == [self needsDisplay] ) {
+ [self softLock];
[super displayIfNeeded];
+ [self softUnlock];
}
-#else
- [self softLock];
- if( NO == destroyNotifySent ) {
- [super displayIfNeeded];
- }
- [self softUnlock];
-#endif
}
-- (void) viewWillDraw
+- (void) display
{
- DBG_PRINT("*************** viewWillDraw: 0x%p\n", javaWindowObject);
- [super viewWillDraw];
+ if( NO == destroyNotifySent ) {
+ [self softLock];
+ [super display];
+ [self softUnlock];
+ }
}
- (void) drawRect:(NSRect)dirtyRect
{
- DBG_PRINT("*************** dirtyRect: 0x%p %lf/%lf %lfx%lf\n",
+ DBG_PRINT("*************** dirtyRect: %p %lf/%lf %lfx%lf\n",
javaWindowObject, dirtyRect.origin.x, dirtyRect.origin.y, dirtyRect.size.width, dirtyRect.size.height);
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
NSRect viewFrame = [self frame];
- (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_FALSE,
+ (*env)->CallVoidMethod(env, javaWindowObject, windowRepaintID, JNI_TRUE, // defer ..
dirtyRect.origin.x, viewFrame.size.height - dirtyRect.origin.y,
dirtyRect.size.width, dirtyRect.size.height);
@@ -272,7 +261,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -290,7 +279,7 @@ static jmethodID windowRepaintID = NULL;
int shallBeDetached = 0;
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
if(NULL==env) {
- NSLog(@"viewDidHide: null JNIEnv");
+ DBG_PRINT("viewDidHide: null JNIEnv\n");
return;
}
@@ -325,9 +314,9 @@ static jmethodID windowRepaintID = NULL;
focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (enqueueMouseEventID && sendMouseEventID && enqueueKeyEventID && sendKeyEventID && sizeChangedID && visibleChangedID && insetsChangedID &&
- positionChangedID && focusChangedID && windowDestroyNotifyID && enqueueRequestFocusID && windowRepaintID)
+ positionChangedID && focusChangedID && windowDestroyNotifyID && requestFocusID && windowRepaintID)
{
return YES;
}
@@ -512,14 +501,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendKeyEvent: null javaWindowObject");
+ DBG_PRINT("sendKeyEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendKeyEvent: null JNIEnv");
+ DBG_PRINT("sendKeyEvent: null JNIEnv\n");
return;
}
@@ -533,6 +522,8 @@ static jint mods2JavaMods(NSUInteger mods)
// Note: the key code in the NSEvent does not map to anything we can use
jchar keyChar = (jchar) [chars characterAtIndex: i];
+ DBG_PRINT("sendKeyEvent: %d/%d char 0x%X, code 0x%X\n", i, len, (int)keyChar, (int)keyCode);
+
#ifdef USE_SENDIO_DIRECT
(*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID,
evType, javaMods, keyCode, keyChar);
@@ -567,14 +558,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"sendMouseEvent: null javaWindowObject");
+ DBG_PRINT("sendMouseEvent: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"sendMouseEvent: null JNIEnv");
+ DBG_PRINT("sendMouseEvent: null JNIEnv\n");
return;
}
jint javaMods = mods2JavaMods([event modifierFlags]);
@@ -586,6 +577,7 @@ static jint mods2JavaMods(NSUInteger mods)
switch ([event type]) {
case NSScrollWheel: {
scrollDeltaY = GetDeltaY(event, javaMods);
+ javaButtonNum = 1;
break;
}
case NSLeftMouseDown:
@@ -603,9 +595,6 @@ static jint mods2JavaMods(NSUInteger mods)
case NSOtherMouseDragged:
javaButtonNum = 2;
break;
- default:
- javaButtonNum = 0;
- break;
}
if (evType == EVENT_MOUSE_WHEEL_MOVED && scrollDeltaY == 0) {
@@ -613,7 +602,7 @@ static jint mods2JavaMods(NSUInteger mods)
return;
}
if (evType == EVENT_MOUSE_PRESSED) {
- (*env)->CallVoidMethod(env, javaWindowObject, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, javaWindowObject, requestFocusID, JNI_FALSE);
}
NSPoint location = [self screenPos2NewtClientWinPos: [NSEvent mouseLocation]];
@@ -770,14 +759,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidResize: null javaWindowObject");
+ DBG_PRINT("windowDidResize: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidResize: null JNIEnv");
+ DBG_PRINT("windowDidResize: null JNIEnv\n");
return;
}
@@ -805,14 +794,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"windowDidMove: null javaWindowObject");
+ DBG_PRINT("windowDidMove: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowDidMove: null JNIEnv");
+ DBG_PRINT("windowDidMove: null JNIEnv\n");
return;
}
@@ -839,16 +828,16 @@ static jint mods2JavaMods(NSUInteger mods)
if( false == [view getDestroyNotifySent] ) {
jobject javaWindowObject = [view getJavaWindowObject];
- DBG_PRINT( "*************** windowWillClose.0: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ DBG_PRINT( "*************** windowWillClose.0: %p\n", (void *)(intptr_t)javaWindowObject);
if (javaWindowObject == NULL) {
- NSLog(@"windowWillClose: null javaWindowObject");
+ DBG_PRINT("windowWillClose: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"windowWillClose: null JNIEnv");
+ DBG_PRINT("windowWillClose: null JNIEnv\n");
return;
}
@@ -863,7 +852,7 @@ static jint mods2JavaMods(NSUInteger mods)
if (shallBeDetached) {
(*jvmHandle)->DetachCurrentThread(jvmHandle);
}
- DBG_PRINT( "*************** windowWillClose.X: 0x%p\n", (void *)(intptr_t)javaWindowObject);
+ DBG_PRINT( "*************** windowWillClose.X: %p\n", (void *)(intptr_t)javaWindowObject);
} else {
DBG_PRINT( "*************** windowWillClose (skip)\n");
}
@@ -916,14 +905,14 @@ static jint mods2JavaMods(NSUInteger mods)
NewtView* view = (NewtView *) nsview;
jobject javaWindowObject = [view getJavaWindowObject];
if (javaWindowObject == NULL) {
- NSLog(@"focusChanged: null javaWindowObject");
+ DBG_PRINT("focusChanged: null javaWindowObject\n");
return;
}
int shallBeDetached = 0;
JavaVM *jvmHandle = [view getJVMHandle];
JNIEnv* env = NewtCommon_GetJNIEnv(jvmHandle, [view getJVMVersion], &shallBeDetached);
if(NULL==env) {
- NSLog(@"focusChanged: null JNIEnv");
+ DBG_PRINT("focusChanged: null JNIEnv\n");
return;
}
diff --git a/src/newt/native/ScreenMode.h b/src/newt/native/ScreenMode.h
index 0a760d54a..bb782910e 100644
--- a/src/newt/native/ScreenMode.h
+++ b/src/newt/native/ScreenMode.h
@@ -1,4 +1,32 @@
/**
+ * Copyright 2011 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.
+ */
+
+/**
* WARNING: must be synced with com.jogamp.newt.util.ScreenModeUtil#streamIn*(int[])
*/
diff --git a/src/newt/native/Window.h b/src/newt/native/Window.h
index 865746b91..4755c4fc5 100644
--- a/src/newt/native/Window.h
+++ b/src/newt/native/Window.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 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.
+ */
#ifndef _WINDOW_H_
#define _WINDOW_H_
diff --git a/src/newt/native/WindowEvent.h b/src/newt/native/WindowEvent.h
index 05491b43c..3dc6ba97e 100644
--- a/src/newt/native/WindowEvent.h
+++ b/src/newt/native/WindowEvent.h
@@ -1,3 +1,30 @@
+/**
+ * Copyright 2011 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.
+ */
#ifndef _WINDOW_EVENT_H_
#define _WINDOW_EVENT_H_
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index d60c40496..97fe6f28d 100644
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -115,8 +115,7 @@ static jmethodID enqueueMouseEventID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID enqueueKeyEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID focusActionID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
+static jmethodID requestFocusID = NULL;
static RECT* UpdateInsets(JNIEnv *env, jobject window, HWND hwnd);
@@ -602,18 +601,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, jb
(void*) pHwnd, (void*)hwnd, current==hwnd);
if( JNI_TRUE==force || current!=hwnd) {
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
- SetForegroundWindow(hwnd); // Slightly Higher Priority
- SetFocus(hwnd);// Sets Keyboard Focus To Window
- if(NULL!=pHwnd) {
- SetActiveWindow(hwnd);
- }
- DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
- } else {
- DBG_PRINT("*** WindowsWindow: requestFocus.X0\n");
+ UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
+ SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags);
+ SetForegroundWindow(hwnd); // Slightly Higher Priority
+ SetFocus(hwnd);// Sets Keyboard Focus To Window
+ if(NULL!=pHwnd) {
+ SetActiveWindow(hwnd);
}
+ DBG_PRINT("*** WindowsWindow: requestFocus.X1\n");
}
DBG_PRINT("*** WindowsWindow: requestFocus.XX\n");
}
@@ -870,11 +865,11 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
case WM_LBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: LBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
break;
@@ -883,18 +878,18 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 1, (jint) 0);
useDefWindowProc = 1;
break;
case WM_MBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: MBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
break;
@@ -903,18 +898,18 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 2, (jint) 0);
useDefWindowProc = 1;
break;
case WM_RBUTTONDOWN:
DBG_PRINT("*** WindowsWindow: RBUTTONDOWN\n");
- (*env)->CallVoidMethod(env, window, enqueueRequestFocusID, JNI_FALSE);
+ (*env)->CallVoidMethod(env, window, requestFocusID, JNI_FALSE);
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_PRESSED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
break;
@@ -923,7 +918,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_RELEASED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 3, (jint) 0);
useDefWindowProc = 1;
break;
@@ -932,7 +927,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(*env)->CallVoidMethod(env, window, sendMouseEventID,
(jint) EVENT_MOUSE_MOVED,
GetModifiers(),
- (jint) LOWORD(lParam), (jint) HIWORD(lParam),
+ (jint) GET_X_LPARAM(lParam), (jint) GET_Y_LPARAM(lParam),
(jint) 0, (jint) 0);
useDefWindowProc = 1;
break;
@@ -958,7 +953,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
(jint) EVENT_MOUSE_WHEEL_MOVED,
GetModifiers(),
(jint) eventPt.x, (jint) eventPt.y,
- (jint) 0, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
+ (jint) 1, (jint) (GET_WHEEL_DELTA_WPARAM(wParam)/120.0f));
useDefWindowProc = 1;
break;
}
@@ -978,8 +973,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
break;
case WM_MOVE:
- DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, (int)LOWORD(lParam), (int)HIWORD(lParam));
- (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)LOWORD(lParam), (jint)HIWORD(lParam));
+ DBG_PRINT("*** WindowsWindow: WM_MOVE window %p, %d/%d\n", wnd, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ (*env)->CallVoidMethod(env, window, positionChangedID, JNI_FALSE, (jint)GET_X_LPARAM(lParam), (jint)GET_Y_LPARAM(lParam));
useDefWindowProc = 1;
break;
@@ -1046,13 +1041,47 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_windows_WindowsDisplay_DispatchMe
/*
* Class: jogamp_newt_driver_windows_WindowsScreen
+ * Method: getOriginX0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginX0
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ if( GetSystemMetrics( SM_CMONITORS) > 1) {
+ return (jint)GetSystemMetrics(SM_XVIRTUALSCREEN);
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowsScreen
+ * Method: getOriginY0
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getOriginY0
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ if( GetSystemMetrics( SM_CMONITORS ) > 1) {
+ return (jint)GetSystemMetrics(SM_YVIRTUALSCREEN);
+ } else {
+ return 0;
+ }
+}
+
+/*
+ * Class: jogamp_newt_driver_windows_WindowsScreen
* Method: getWidthImpl
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
- return (jint)GetSystemMetrics(SM_CXSCREEN);
+ if( GetSystemMetrics( SM_CMONITORS) > 1) {
+ return (jint)GetSystemMetrics(SM_CXVIRTUALSCREEN);
+ } else {
+ return (jint)GetSystemMetrics(SM_CXSCREEN);
+ }
}
/*
@@ -1063,7 +1092,11 @@ JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getWidthImp
JNIEXPORT jint JNICALL Java_jogamp_newt_driver_windows_WindowsScreen_getHeightImpl0
(JNIEnv *env, jobject obj, jint scrn_idx)
{
- return (jint)GetSystemMetrics(SM_CYSCREEN);
+ if( GetSystemMetrics( SM_CMONITORS ) > 1) {
+ return (jint)GetSystemMetrics(SM_CYVIRTUALSCREEN);
+ } else {
+ return (jint)GetSystemMetrics(SM_CYSCREEN);
+ }
}
static int NewtScreen_RotationNativeCCW2NewtCCW(JNIEnv *env, int native) {
@@ -1270,8 +1303,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
+ requestFocusID = (*env)->GetMethodID(env, clazz, "requestFocus", "(Z)V");
if (insetsChangedID == NULL ||
sizeChangedID == NULL ||
@@ -1284,8 +1316,7 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_initIDs
sendMouseEventID == NULL ||
enqueueKeyEventID == NULL ||
sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
+ requestFocusID == NULL) {
return JNI_FALSE;
}
BuildDynamicKeyMapTable();
@@ -1317,9 +1348,6 @@ static void NewtWindow_setVisiblePosSize(HWND hwnd, BOOL atop, BOOL visible,
} else {
flags = SWP_NOACTIVATE | SWP_NOZORDER;
}
- if(0>x || 0>y) {
- flags |= SWP_NOMOVE;
- }
if(0>=width || 0>=height ) {
flags |= SWP_NOSIZE;
}
@@ -1345,7 +1373,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
(JNIEnv *env, jobject obj,
jlong hInstance, jstring jWndClassName, jstring jWndName,
jlong parent,
- jint jx, jint jy, jint defaultWidth, jint defaultHeight, jint flags)
+ jint jx, jint jy, jint defaultWidth, jint defaultHeight, jboolean autoPosition, jint flags)
{
HWND parentWindow = (HWND) (intptr_t) parent;
const TCHAR* wndClassName = NULL;
@@ -1374,7 +1402,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
} else {
windowStyle |= WS_OVERLAPPEDWINDOW;
- if(0>_x || 0>_y) {
+ if(JNI_TRUE == autoPosition) {
// user didn't requested specific position, use WM default
_x = CW_USEDEFAULT;
_y = 0;
@@ -1387,9 +1415,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
(HINSTANCE) (intptr_t) hInstance,
NULL);
- DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d\n",
+ DBG_PRINT("*** WindowsWindow: CreateWindow thread 0x%X, parent %p, window %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
(int)GetCurrentThreadId(), parentWindow, window, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags));
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
if (NULL == window) {
int lastError = (int) GetLastError();
@@ -1409,7 +1437,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
{
RECT rc;
RECT * insets;
- BOOL userPos = 0<=x && 0<=y ;
ShowWindow(window, SW_SHOW);
@@ -1417,12 +1444,12 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_windows_WindowsWindow_CreateWind
insets = UpdateInsets(env, wud->jinstance, window);
(*env)->CallVoidMethod(env, wud->jinstance, visibleChangedID, JNI_FALSE, JNI_TRUE);
- if(!userPos) {
+ if(JNI_TRUE == autoPosition) {
GetWindowRect(window, &rc);
x = rc.left + insets->left; // client coords
y = rc.top + insets->top; // client coords
}
- DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (is user-pos %d)\n", x, y, width, height, userPos);
+ DBG_PRINT("*** WindowsWindow: CreateWindow client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
x -= insets->left; // top-level
y -= insets->top; // top-level
diff --git a/src/newt/native/X11Common.h b/src/newt/native/X11Common.h
new file mode 100644
index 000000000..cefef690f
--- /dev/null
+++ b/src/newt/native/X11Common.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright 2011 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.
+ */
+
+#ifndef _X11COMMON_H_
+#define _X11COMMON_H_
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+#include <gluegen_stdint.h>
+
+#include <unistd.h>
+#include <errno.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <X11/Xatom.h>
+
+#include <X11/extensions/Xrandr.h>
+
+#include "jogamp_newt_driver_x11_X11Screen.h"
+#include "jogamp_newt_driver_x11_X11Display.h"
+#include "jogamp_newt_driver_x11_X11Window.h"
+
+#include "Window.h"
+#include "MouseEvent.h"
+#include "InputEvent.h"
+#include "KeyEvent.h"
+#include "WindowEvent.h"
+#include "ScreenMode.h"
+
+#include "NewtCommon.h"
+
+// #define VERBOSE_ON 1
+
+#ifdef VERBOSE_ON
+ #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
+#else
+ #define DBG_PRINT(...)
+#endif
+
+extern jclass X11NewtWindowClazz;
+extern jmethodID insetsChangedID;
+extern jmethodID visibleChangedID;
+
+jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning);
+
+void NewtDisplay_displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env);
+Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return);
+Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom);
+
+#endif /* _X11COMMON_H_ */
+
diff --git a/src/newt/native/X11Display.c b/src/newt/native/X11Display.c
new file mode 100644
index 000000000..283636040
--- /dev/null
+++ b/src/newt/native/X11Display.c
@@ -0,0 +1,660 @@
+/**
+ * Copyright 2011 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.
+ */
+
+#include "X11Common.h"
+
+#define USE_SENDIO_DIRECT 1
+
+jclass X11NewtWindowClazz = NULL;
+jmethodID insetsChangedID = NULL;
+jmethodID visibleChangedID = NULL;
+
+static const char * const ClazzNameX11NewtWindow = "jogamp/newt/driver/x11/X11Window";
+
+static jmethodID displayCompletedID = NULL;
+
+static jmethodID sizeChangedID = NULL;
+static jmethodID positionChangedID = NULL;
+static jmethodID focusChangedID = NULL;
+static jmethodID reparentNotifyID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID windowRepaintID = NULL;
+static jmethodID enqueueMouseEventID = NULL;
+static jmethodID sendMouseEventID = NULL;
+static jmethodID enqueueKeyEventID = NULL;
+static jmethodID sendKeyEventID = NULL;
+static jmethodID requestFocusID = NULL;
+
+static JavaVM *jvmHandle = NULL;
+static int jvmVersion = 0;
+
+static void setupJVMVars(JNIEnv * env) {
+ if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
+ jvmHandle = NULL;
+ }
+ jvmVersion = (*env)->GetVersion(env);
+}
+
+static XErrorHandler origErrorHandler = NULL ;
+
+static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
+{
+ fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno));
+
+ if (e->error_code == BadAtom) {
+ fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", (void*)e->resourceid);
+ } else if (e->error_code == BadWindow) {
+ fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid);
+ } else {
+ int shallBeDetached = 0;
+ JNIEnv *jniEnv = NULL;
+ const char * errStr = strerror(errno);
+
+ fprintf(stderr, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
+
+ jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
+ if(NULL==jniEnv) {
+ fprintf(stderr, "NEWT X11 Error: null JNIEnv");
+ return;
+ }
+
+ NewtCommon_throwNewRuntimeException(jniEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
+ dpy, e->error_code, errStr);
+
+ if (shallBeDetached) {
+ (*jvmHandle)->DetachCurrentThread(jvmHandle);
+ }
+ }
+
+ return 0;
+}
+
+void NewtDisplay_displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) {
+ if(onoff) {
+ if(NULL==origErrorHandler) {
+ setupJVMVars(env);
+ origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler);
+ }
+ } else {
+ if(NULL!=origErrorHandler) {
+ XSetErrorHandler(origErrorHandler);
+ origErrorHandler = NULL;
+ }
+ }
+}
+
+/**
+ * Keycode
+ */
+
+#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
+
+static jint X11KeySym2NewtVKey(KeySym keySym) {
+ if(IS_WITHIN(keySym,XK_F1,XK_F12))
+ return (keySym-XK_F1)+J_VK_F1;
+ if(IS_WITHIN(keySym,XK_KP_0,XK_KP_9))
+ return (keySym-XK_KP_0)+J_VK_NUMPAD0;
+
+ switch(keySym) {
+ case XK_Return:
+ case XK_KP_Enter:
+ return J_VK_ENTER;
+ case XK_BackSpace:
+ return J_VK_BACK_SPACE;
+ case XK_Tab:
+ case XK_KP_Tab:
+ case XK_ISO_Left_Tab:
+ return J_VK_TAB;
+ case XK_Cancel:
+ return J_VK_CANCEL;
+ case XK_Clear:
+ return J_VK_CLEAR;
+ case XK_Shift_L:
+ case XK_Shift_R:
+ return J_VK_SHIFT;
+ case XK_Control_L:
+ case XK_Control_R:
+ return J_VK_CONTROL;
+ case XK_Alt_L:
+ case XK_Alt_R:
+ return J_VK_ALT;
+ case XK_Pause:
+ return J_VK_PAUSE;
+ case XK_Caps_Lock:
+ return J_VK_CAPS_LOCK;
+ case XK_Escape:
+ return J_VK_ESCAPE;
+ case XK_space:
+ case XK_KP_Space:
+ return J_VK_SPACE;
+ case XK_Page_Up:
+ case XK_KP_Page_Up:
+ return J_VK_PAGE_UP;
+ case XK_Page_Down:
+ case XK_KP_Page_Down:
+ return J_VK_PAGE_DOWN;
+ case XK_End:
+ case XK_KP_End:
+ return J_VK_END;
+ case XK_Home:
+ case XK_KP_Home:
+ return J_VK_HOME;
+ case XK_Left:
+ case XK_KP_Left:
+ return J_VK_LEFT;
+ case XK_Up:
+ case XK_KP_Up:
+ return J_VK_UP;
+ case XK_Right:
+ case XK_KP_Right:
+ return J_VK_RIGHT;
+ case XK_Down:
+ case XK_KP_Down:
+ return J_VK_DOWN;
+ case XK_KP_Multiply:
+ return J_VK_MULTIPLY;
+ case XK_KP_Add:
+ return J_VK_ADD;
+ case XK_KP_Separator:
+ return J_VK_SEPARATOR;
+ case XK_KP_Subtract:
+ return J_VK_SUBTRACT;
+ case XK_KP_Decimal:
+ return J_VK_DECIMAL;
+ case XK_KP_Divide:
+ return J_VK_DIVIDE;
+ case XK_Delete:
+ case XK_KP_Delete:
+ return J_VK_DELETE;
+ case XK_Num_Lock:
+ return J_VK_NUM_LOCK;
+ case XK_Scroll_Lock:
+ return J_VK_SCROLL_LOCK;
+ case XK_Print:
+ return J_VK_PRINTSCREEN;
+ case XK_Insert:
+ case XK_KP_Insert:
+ return J_VK_INSERT;
+ case XK_Help:
+ return J_VK_HELP;
+ }
+ return keySym;
+}
+
+static jint X11InputState2NewtModifiers(unsigned int xstate) {
+ jint modifiers = 0;
+ if ((ControlMask & xstate) != 0) {
+ modifiers |= EVENT_CTRL_MASK;
+ }
+ if ((ShiftMask & xstate) != 0) {
+ modifiers |= EVENT_SHIFT_MASK;
+ }
+ if ((Mod1Mask & xstate) != 0) {
+ modifiers |= EVENT_ALT_MASK;
+ }
+ if ((Button1Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON1_MASK;
+ }
+ if ((Button2Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON2_MASK;
+ }
+ if ((Button3Mask & xstate) != 0) {
+ modifiers |= EVENT_BUTTON3_MASK;
+ }
+
+ return modifiers;
+}
+
+
+/**
+ * Keycode
+ */
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: initIDs
+ * Signature: (Z)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
+ (JNIEnv *env, jclass clazz)
+{
+ jclass c;
+
+ NewtCommon_init(env);
+
+ if(NULL==X11NewtWindowClazz) {
+ c = (*env)->FindClass(env, ClazzNameX11NewtWindow);
+ if(NULL==c) {
+ NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameX11NewtWindow);
+ }
+ X11NewtWindowClazz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==X11NewtWindowClazz) {
+ NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameX11NewtWindow);
+ }
+ }
+
+ displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
+ insetsChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "insetsChanged", "(ZIIII)V");
+ sizeChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sizeChanged", "(ZIIZ)V");
+ positionChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "positionChanged", "(ZII)V");
+ focusChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "focusChanged", "(ZZ)V");
+ visibleChangedID = (*env)->GetMethodID(env, X11NewtWindowClazz, "visibleChanged", "(ZZ)V");
+ reparentNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "reparentNotify", "(J)V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowDestroyNotify", "()V");
+ windowRepaintID = (*env)->GetMethodID(env, X11NewtWindowClazz, "windowRepaint", "(ZIIII)V");
+ enqueueMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueMouseEvent", "(ZIIIIII)V");
+ sendMouseEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendMouseEvent", "(IIIIII)V");
+ enqueueKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "enqueueKeyEvent", "(ZIIIC)V");
+ sendKeyEventID = (*env)->GetMethodID(env, X11NewtWindowClazz, "sendKeyEvent", "(IIIC)V");
+ requestFocusID = (*env)->GetMethodID(env, X11NewtWindowClazz, "requestFocus", "(Z)V");
+
+ if (displayCompletedID == NULL ||
+ insetsChangedID == NULL ||
+ sizeChangedID == NULL ||
+ positionChangedID == NULL ||
+ focusChangedID == NULL ||
+ visibleChangedID == NULL ||
+ reparentNotifyID == NULL ||
+ windowDestroyNotifyID == NULL ||
+ windowRepaintID == NULL ||
+ enqueueMouseEventID == NULL ||
+ sendMouseEventID == NULL ||
+ enqueueKeyEventID == NULL ||
+ sendKeyEventID == NULL ||
+ requestFocusID == NULL) {
+ return JNI_FALSE;
+ }
+
+
+ return JNI_TRUE;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: CompleteDisplay
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
+ (JNIEnv *env, jobject obj, jlong display)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ jlong javaObjectAtom;
+ jlong windowDeleteAtom;
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
+ if(None==javaObjectAtom) {
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
+ return;
+ }
+
+ windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ if(None==windowDeleteAtom) {
+ NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
+ return;
+ }
+
+ // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
+
+ DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
+
+ (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: DisplayRelease0
+ * Signature: (JJJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Atom wm_javaobject_atom = (Atom)javaObjectAtom;
+ Atom wm_delete_atom = (Atom)windowDeleteAtom;
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ // nothing to do to free the atoms !
+ (void) wm_javaobject_atom;
+ (void) wm_delete_atom;
+
+ XSync(dpy, True); // discard all pending events
+ DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Display
+ * Method: DispatchMessages
+ * Signature: (JIJJ)V
+ */
+JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ Atom wm_delete_atom = (Atom)windowDeleteAtom;
+ int num_events = 100;
+
+ if ( NULL == dpy ) {
+ return;
+ }
+
+ // Periodically take a break
+ while( num_events > 0 ) {
+ jobject jwindow = NULL;
+ XEvent evt;
+ KeySym keySym = 0;
+ jint modifiers = 0;
+ char keyChar = 0;
+ char text[255];
+
+ // XEventsQueued(dpy, X):
+ // QueuedAlready : No I/O Flush or system call doesn't work on some cards (eg ATI) ?)
+ // QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available
+ // QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more ..
+ if ( 0 >= XPending(dpy) ) {
+ // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
+ return;
+ }
+
+ XNextEvent(dpy, &evt);
+ num_events--;
+
+ if( 0==evt.xany.window ) {
+ NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
+ return ;
+ }
+
+ if(dpy!=evt.xany.display) {
+ NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
+ return ;
+ }
+
+ // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
+
+ NewtDisplay_displayDispatchErrorHandlerEnable(1, env);
+
+ jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
+ #ifdef VERBOSE_ON
+ True
+ #else
+ False
+ #endif
+ );
+
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
+
+ if(NULL==jwindow) {
+ fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n",
+ (void*)dpy, evt.type, (void*)evt.xany.window);
+ continue;
+ }
+
+ switch(evt.type) {
+ case KeyRelease:
+ case KeyPress:
+ if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
+ KeySym lower_return = 0, upper_return = 0;
+ keyChar=text[0];
+ XConvertCase(keySym, &lower_return, &upper_return);
+ // always return upper case, set modifier masks (SHIFT, ..)
+ keySym = X11KeySym2NewtVKey(upper_return);
+ } else {
+ keyChar=0;
+ keySym = X11KeySym2NewtVKey(keySym);
+ }
+ modifiers = X11InputState2NewtModifiers(evt.xkey.state);
+ break;
+
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
+ break;
+
+ default:
+ break;
+ }
+
+ switch(evt.type) {
+ case ButtonPress:
+ (*env)->CallVoidMethod(env, jwindow, requestFocusID, JNI_FALSE);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
+ break;
+ case ButtonRelease:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED,
+ modifiers,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ #endif
+ break;
+ case MotionNotify:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED,
+ modifiers,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case EnterNotify:
+ DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_ENTERED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_ENTERED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case LeaveNotify:
+ DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_EXITED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_EXITED,
+ modifiers,
+ (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
+ #endif
+ break;
+ case KeyPress:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
+ modifiers, keySym, (jchar) -1);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
+ modifiers, keySym, (jchar) -1);
+ #endif
+
+ break;
+ case KeyRelease:
+ #ifdef USE_SENDIO_DIRECT
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
+ modifiers, keySym, (jchar) -1);
+
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED,
+ modifiers, keySym, (jchar) keyChar);
+ #else
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED,
+ modifiers, keySym, (jchar) -1);
+
+ (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
+ modifiers, keySym, (jchar) keyChar);
+ #endif
+
+ break;
+ case DestroyNotify:
+ DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
+ (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
+ if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
+ // ignore child destroy notification
+ }
+ break;
+ case CreateNotify:
+ DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n",
+ (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
+ break;
+ case ConfigureNotify:
+ DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n",
+ (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
+ evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height,
+ evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
+ if ( evt.xconfigure.window == evt.xconfigure.event ) {
+ // ignore child window change notification
+ {
+ // update insets
+ int left, right, top, bottom;
+ NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
+ }
+ (*env)->CallVoidMethod(env, jwindow, sizeChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
+ (*env)->CallVoidMethod(env, jwindow, positionChangedID, JNI_FALSE,
+ (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
+ }
+ break;
+ case ClientMessage:
+ if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
+ DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n",
+ (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
+ (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
+ // Called by Window.java: CloseWindow();
+ num_events = 0; // end loop in case of destroyed display
+ }
+ break;
+
+ case FocusIn:
+ DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
+ (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_TRUE);
+ break;
+
+ case FocusOut:
+ DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
+ (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_FALSE);
+ break;
+
+ case Expose:
+ DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
+
+ if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
+ (*env)->CallVoidMethod(env, jwindow, windowRepaintID, JNI_FALSE,
+ evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
+ }
+ break;
+
+ case MapNotify:
+ DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
+ (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect,
+ evt.xmap.event!=evt.xmap.window);
+ if( evt.xmap.event == evt.xmap.window ) {
+ // ignore child window notification
+ {
+ // update insets
+ int left, right, top, bottom;
+ NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
+ }
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
+ }
+ break;
+
+ case UnmapNotify:
+ DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n",
+ (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure,
+ evt.xunmap.event!=evt.xunmap.window);
+ if( evt.xunmap.event == evt.xunmap.window ) {
+ // ignore child window notification
+ (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_FALSE);
+ }
+ break;
+
+ case ReparentNotify:
+ {
+ jlong parentResult; // 0 if root, otherwise proper value
+ Window winRoot, winTopParent;
+ #ifdef VERBOSE_ON
+ Window oldParentRoot, oldParentTopParent;
+ Window parentRoot, parentTopParent;
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
+ oldParentRoot=0; oldParentTopParent = 0;
+ }
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
+ parentRoot=0; parentTopParent = 0;
+ }
+ #endif
+ if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
+ winRoot=0; winTopParent = 0;
+ }
+ if(evt.xreparent.parent == winRoot) {
+ parentResult = 0; // our java indicator for root window
+ } else {
+ parentResult = (jlong) (intptr_t) evt.xreparent.parent;
+ }
+ #ifdef VERBOSE_ON
+ DBG_PRINT( "X11: event . ReparentNotify: call %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
+ evt.xreparent.x, evt.xreparent.y,
+ (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
+ (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
+ (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
+ #endif
+ (*env)->CallVoidMethod(env, jwindow, reparentNotifyID, (jlong)evt.xreparent.parent);
+ }
+ break;
+
+ // unhandled events .. yet ..
+
+ default:
+ DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window);
+ }
+ }
+}
+
+
diff --git a/src/newt/native/X11Screen.c b/src/newt/native/X11Screen.c
new file mode 100644
index 000000000..1b7fea770
--- /dev/null
+++ b/src/newt/native/X11Screen.c
@@ -0,0 +1,469 @@
+/**
+ * Copyright 2011 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.
+ */
+
+#include "X11Common.h"
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: GetScreen
+ * Signature: (JI)J
+ */
+JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ Screen * scrn= NULL;
+
+ DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
+
+ if(dpy==NULL) {
+ NewtCommon_FatalError(env, "invalid display connection..");
+ }
+
+ scrn = ScreenOfDisplay(dpy, screen_index);
+ if(scrn==NULL) {
+ fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
+ }
+ DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
+ return (jlong) (intptr_t) scrn;
+}
+
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ return (jint) DisplayWidth( dpy, scrn_idx);
+}
+
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ return (jint) DisplayHeight( dpy, scrn_idx);
+}
+
+static int showedRandRVersion = 0;
+
+static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
+ if( 0 == XRRQueryVersion(dpy, major, minor) ) {
+ return False;
+ }
+ if(0 == showedRandRVersion) {
+ fprintf(stderr, "X11 RandR Version %d.%d\n", *major, *minor);
+ showedRandRVersion = 1;
+ }
+ return True;
+}
+
+static Bool NewtScreen_hasRANDR(Display *dpy) {
+ int major, minor;
+ return NewtScreen_getRANDRVersion(dpy, &major, &minor);
+}
+
+static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
+ int rot;
+ if(xrotation == RR_Rotate_0) {
+ rot = 0;
+ }
+ else if(xrotation == RR_Rotate_90) {
+ rot = 90;
+ }
+ else if(xrotation == RR_Rotate_180) {
+ rot = 180;
+ }
+ else if(xrotation == RR_Rotate_270) {
+ rot = 270;
+ } else {
+ NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
+ }
+ return rot;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getAvailableScreenModeRotations0
+ * Signature: (JI)I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+ int num_rotations = 0;
+ Rotation cur_rotation, rotations_supported;
+ int rotations[4];
+ int major, minor;
+
+ if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
+ fprintf(stderr, "RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
+
+ if(0 != (rotations_supported & RR_Rotate_0)) {
+ rotations[num_rotations++] = 0;
+ }
+ if(0 != (rotations_supported & RR_Rotate_90)) {
+ rotations[num_rotations++] = 90;
+ }
+ if(0 != (rotations_supported & RR_Rotate_180)) {
+ rotations[num_rotations++] = 180;
+ }
+ if(0 != (rotations_supported & RR_Rotate_270)) {
+ rotations[num_rotations++] = 270;
+ }
+
+ jintArray properties = NULL;
+
+ if(num_rotations>0) {
+ properties = (*env)->NewIntArray(env, num_rotations);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
+ }
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getNumScreenModeResolution0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
+ return 0;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
+
+ return num_sizes;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getScreenModeResolutions0
+ * Signature: (JII)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ // Fill the properties in temp jint array
+ int propIndex = 0;
+ jint prop[4];
+
+ prop[propIndex++] = xrrs[(int)resMode_idx].width;
+ prop[propIndex++] = xrrs[(int)resMode_idx].height;
+ prop[propIndex++] = xrrs[(int)resMode_idx].mwidth;
+ prop[propIndex++] = xrrs[(int)resMode_idx].mheight;
+
+ jintArray properties = (*env)->NewIntArray(env, 4);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getScreenModeRates0
+ * Signature: (JII)[I
+ */
+JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
+ return (*env)->NewIntArray(env, 0);
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ int num_rates;
+ short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
+
+ jint prop[num_rates];
+ int i;
+ for(i=0; i<num_rates; i++) {
+ prop[i] = (int) rates[i];
+ /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
+ }
+
+ jintArray properties = (*env)->NewIntArray(env, num_rates);
+ if (properties == NULL) {
+ NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
+ }
+
+ // move from the temp structure to the java structure
+ (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
+
+ return properties;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenRate0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
+ return -1;
+ }
+
+ // get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+ short original_rate = XRRConfigCurrentRate(conf);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
+
+ return (jint) original_rate;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenRotation0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
+ return -1;
+ }
+
+ //get current resolutions and frequencies
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+
+ Rotation rotation;
+ XRRConfigCurrentConfiguration(conf, &rotation);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ return NewtScreen_XRotation2Degree(env, rotation);
+}
+
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: getCurrentScreenResolutionIndex0
+ * Signature: (JI)I
+ */
+JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
+ (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)scrn_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
+ return -1;
+ }
+
+ // get current resolutions and frequency configuration
+ XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
+ short original_rate = XRRConfigCurrentRate(conf);
+
+ Rotation original_rotation;
+ SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+
+ DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
+ return (jint)original_size_id;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: setCurrentScreenModeStart0
+ * Signature: (JIIII)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ Window root = RootWindow(dpy, (int)screen_idx);
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0: RANDR not available\n");
+ return JNI_FALSE;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
+ int rot;
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ conf = XRRGetScreenInfo(dpy, root);
+
+ switch(rotation) {
+ case 0:
+ rot = RR_Rotate_0;
+ break;
+ case 90:
+ rot = RR_Rotate_90;
+ break;
+ case 180:
+ rot = RR_Rotate_180;
+ break;
+ case 270:
+ rot = RR_Rotate_270;
+ break;
+ default:
+ NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
+ }
+
+ DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
+ resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
+
+ XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
+
+ XSync(dpy, False);
+ XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
+ XSync(dpy, False);
+
+ //free
+ XRRFreeScreenConfigInfo(conf);
+ XSync(dpy, False);
+
+ return JNI_TRUE;
+}
+
+/*
+ * Class: jogamp_newt_driver_x11_X11Screen
+ * Method: setCurrentScreenModePollEnd0
+ * Signature: (J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
+ (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
+{
+ Display *dpy = (Display *) (intptr_t) display;
+ int randr_event_base, randr_error_base;
+ XEvent evt;
+ XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
+
+ if(False == NewtScreen_hasRANDR(dpy)) {
+ DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
+ return JNI_FALSE;
+ }
+
+ int num_sizes;
+ XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
+ XRRScreenConfiguration *conf;
+
+ if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
+ NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
+ }
+
+ XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
+
+ int done = 0;
+ int rot;
+ do {
+ if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
+ return;
+ }
+ XNextEvent(dpy, &evt);
+
+ switch (evt.type - randr_event_base) {
+ case RRScreenChangeNotify:
+ rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
+ DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
+ (void*)scn_event->window, (void*)scn_event->root,
+ (int)scn_event->size_index, rot,
+ scn_event->width, scn_event->height);
+ // done = scn_event->size_index == resMode_idx; // not reliable ..
+ done = rot == rotation &&
+ scn_event->width == xrrs[resMode_idx].width &&
+ scn_event->height == xrrs[resMode_idx].height;
+ break;
+ default:
+ DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
+ }
+ XRRUpdateConfiguration(&evt);
+ } while(!done);
+
+ XSync(dpy, False);
+
+}
+
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index f14138a0a..0a7e1cf77 100644
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -32,40 +32,9 @@
*
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include <gluegen_stdint.h>
-
-#include <unistd.h>
-#include <errno.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/keysym.h>
-#include <X11/Xatom.h>
-
-#include <X11/extensions/Xrandr.h>
-
-#include "jogamp_newt_driver_x11_X11Screen.h"
-#include "jogamp_newt_driver_x11_X11Display.h"
-#include "jogamp_newt_driver_x11_X11Window.h"
-
-#include "Window.h"
-#include "MouseEvent.h"
-#include "InputEvent.h"
-#include "KeyEvent.h"
-#include "WindowEvent.h"
-#include "ScreenMode.h"
-
-#include "NewtCommon.h"
-
-// #define VERBOSE_ON 1
+#include "X11Common.h"
#ifdef VERBOSE_ON
- #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr)
-
#define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b))
static void _dumpVisualInfo(const char * msg, XVisualInfo *pVisualQuery) {
@@ -90,259 +59,12 @@
#else
- #define DBG_PRINT(...)
-
#define DUMP_VISUAL_INFO(a,b)
#endif
-/**
- * Keycode
- */
-
-#define IS_WITHIN(k,a,b) ((a)<=(k)&&(k)<=(b))
-
-static jint X11KeySym2NewtVKey(KeySym keySym) {
- if(IS_WITHIN(keySym,XK_F1,XK_F12))
- return (keySym-XK_F1)+J_VK_F1;
-
- switch(keySym) {
- case XK_Alt_L:
- case XK_Alt_R:
- return J_VK_ALT;
-
- case XK_Left:
- return J_VK_LEFT;
- case XK_Right:
- return J_VK_RIGHT;
- case XK_Up:
- return J_VK_UP;
- case XK_Down:
- return J_VK_DOWN;
- case XK_Page_Up:
- return J_VK_PAGE_UP;
- case XK_Page_Down:
- return J_VK_PAGE_DOWN;
- case XK_Shift_L:
- case XK_Shift_R:
- return J_VK_SHIFT;
- case XK_Control_L:
- case XK_Control_R:
- return J_VK_CONTROL;
- case XK_Escape:
- return J_VK_ESCAPE;
- case XK_Delete:
- return J_VK_DELETE;
- }
- return keySym;
-}
-
-static jint X11InputState2NewtModifiers(unsigned int xstate) {
- jint modifiers = 0;
- if ((ControlMask & xstate) != 0) {
- modifiers |= EVENT_CTRL_MASK;
- }
- if ((ShiftMask & xstate) != 0) {
- modifiers |= EVENT_SHIFT_MASK;
- }
- if ((Mod1Mask & xstate) != 0) {
- modifiers |= EVENT_ALT_MASK;
- }
- if ((Button1Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON1_MASK;
- }
- if ((Button2Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON2_MASK;
- }
- if ((Button3Mask & xstate) != 0) {
- modifiers |= EVENT_BUTTON3_MASK;
- }
-
- return modifiers;
-}
-
#define X11_MOUSE_EVENT_MASK (ButtonPressMask | ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask)
-static const char * const ClazzNameNewtWindow = "com/jogamp/newt/Window";
-
-static jclass newtWindowClz=NULL;
-
-static jmethodID insetsChangedID = NULL;
-static jmethodID sizeChangedID = NULL;
-static jmethodID positionChangedID = NULL;
-static jmethodID focusChangedID = NULL;
-static jmethodID visibleChangedID = NULL;
-static jmethodID reparentNotifyID = NULL;
-static jmethodID windowDestroyNotifyID = NULL;
-static jmethodID windowRepaintID = NULL;
-static jmethodID enqueueMouseEventID = NULL;
-static jmethodID sendMouseEventID = NULL;
-static jmethodID enqueueKeyEventID = NULL;
-static jmethodID sendKeyEventID = NULL;
-static jmethodID focusActionID = NULL;
-static jmethodID enqueueRequestFocusID = NULL;
-
-static jmethodID displayCompletedID = NULL;
-
-
-/**
- * Display
- */
-
-static JavaVM *jvmHandle = NULL;
-static int jvmVersion = 0;
-
-static void setupJVMVars(JNIEnv * env) {
- if(0 != (*env)->GetJavaVM(env, &jvmHandle)) {
- jvmHandle = NULL;
- }
- jvmVersion = (*env)->GetVersion(env);
-}
-
-static XErrorHandler origErrorHandler = NULL ;
-
-static int displayDispatchErrorHandler(Display *dpy, XErrorEvent *e)
-{
- fprintf(stderr, "Warning: NEWT X11 Error: DisplayDispatch %p, Code 0x%X, errno %s\n", dpy, e->error_code, strerror(errno));
-
- if (e->error_code == BadAtom) {
- fprintf(stderr, " BadAtom (%p): Atom probably already removed\n", (void*)e->resourceid);
- } else if (e->error_code == BadWindow) {
- fprintf(stderr, " BadWindow (%p): Window probably already removed\n", (void*)e->resourceid);
- } else {
- int shallBeDetached = 0;
- JNIEnv *jniEnv = NULL;
- const char * errStr = strerror(errno);
-
- fprintf(stderr, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s\n", dpy, e->error_code, errStr);
-
- jniEnv = NewtCommon_GetJNIEnv(jvmHandle, jvmVersion, &shallBeDetached);
- if(NULL==jniEnv) {
- fprintf(stderr, "NEWT X11 Error: null JNIEnv");
- return;
- }
-
- NewtCommon_throwNewRuntimeException(jniEnv, "Info: NEWT X11 Error: Display %p, Code 0x%X, errno %s",
- dpy, e->error_code, errStr);
-
- if (shallBeDetached) {
- (*jvmHandle)->DetachCurrentThread(jvmHandle);
- }
- }
-
- return 0;
-}
-
-static void displayDispatchErrorHandlerEnable(int onoff, JNIEnv * env) {
- if(onoff) {
- if(NULL==origErrorHandler) {
- setupJVMVars(env);
- origErrorHandler = XSetErrorHandler(displayDispatchErrorHandler);
- }
- } else {
- if(NULL!=origErrorHandler) {
- XSetErrorHandler(origErrorHandler);
- origErrorHandler = NULL;
- }
- }
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: initIDs
- * Signature: (Z)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Display_initIDs0
- (JNIEnv *env, jclass clazz)
-{
- jclass c;
-
- NewtCommon_init(env);
-
- displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
- if (displayCompletedID == NULL) {
- return JNI_FALSE;
- }
-
- if(NULL==newtWindowClz) {
- c = (*env)->FindClass(env, ClazzNameNewtWindow);
- if(NULL==c) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't find %s", ClazzNameNewtWindow);
- }
- newtWindowClz = (jclass)(*env)->NewGlobalRef(env, c);
- (*env)->DeleteLocalRef(env, c);
- if(NULL==newtWindowClz) {
- NewtCommon_FatalError(env, "NEWT X11Window: can't use %s", ClazzNameNewtWindow);
- }
- }
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: CompleteDisplay
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_CompleteDisplay0
- (JNIEnv *env, jobject obj, jlong display)
-{
- Display * dpy = (Display *)(intptr_t)display;
- jlong javaObjectAtom;
- jlong windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- javaObjectAtom = (jlong) XInternAtom(dpy, "NEWT_JAVA_OBJECT", False);
- if(None==javaObjectAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom NEWT_JAVA_OBJECT, bail out!");
- return;
- }
-
- windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- if(None==windowDeleteAtom) {
- NewtCommon_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!");
- return;
- }
-
- // XSetCloseDownMode(dpy, RetainTemporary); // Just a try ..
-
- DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy);
-
- (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DisplayRelease0
- * Signature: (JJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DisplayRelease0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Atom wm_javaobject_atom = (Atom)javaObjectAtom;
- Atom wm_delete_atom = (Atom)windowDeleteAtom;
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- // nothing to do to free the atoms !
- (void) wm_javaobject_atom;
- (void) wm_delete_atom;
-
- XSync(dpy, True); // discard all pending events
- DBG_PRINT("X11: X11Display_DisplayRelease dpy %p\n", dpy);
-}
-
-
-/**
- * Window
- */
-
static int putPtrIn32Long(unsigned long * dst, uintptr_t src) {
int i=0;
dst[i++] = (unsigned long) ( ( src >> 0 ) & 0xFFFFFFFF ) ;
@@ -375,7 +97,7 @@ static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlon
(unsigned char *)&jogl_java_object_data, nitems_32);
}
-static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) {
+jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, Bool showWarning) {
Atom actual_type;
int actual_format;
int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ;
@@ -413,7 +135,7 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
XFree(jogl_java_object_data_pp);
#ifdef VERBOSE_ON
- if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, newtWindowClz)) {
+ if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, X11NewtWindowClazz)) {
NewtCommon_throwNewRuntimeException(env, "fetched Atom NEWT_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !", jwindow);
}
#endif
@@ -421,7 +143,7 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j
}
/** @return zero if fails, non zero if OK */
-static Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
+Status NewtWindows_getRootAndParent (Display *dpy, Window w, Window * root_return, Window * parent_return) {
Window *children_return=NULL;
unsigned int nchildren_return=0;
@@ -502,7 +224,7 @@ static Status NewtWindows_getFrameExtends(Display *dpy, Window window, int *left
return 1; // Ok
}
-static Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
+Status NewtWindows_updateInsets(JNIEnv *env, jobject jwindow, Display *dpy, Window window, int *left, int *right, int *top, int *bottom) {
if(0 != NewtWindows_getFrameExtends(dpy, window, left, right, top, bottom)) {
DBG_PRINT( "NewtWindows_updateInsets: insets by _NET_FRAME_EXTENTS [ l %d, r %d, t %d, b %d ]\n",
*left, *right, *top, *bottom);
@@ -535,16 +257,14 @@ static void NewtWindows_requestFocus (JNIEnv *env, jobject window, Display *dpy,
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d, hasFocus %d\n", dpy, (void*)w, force, focus_return==w);
if( JNI_TRUE==force || focus_return!=w) {
- if( JNI_TRUE==force || JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) {
- DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
- XRaiseWindow(dpy, w);
- NewtWindows_setCWAbove(dpy, w);
- // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
- XGetWindowAttributes(dpy, w, &xwa);
- if(xwa.map_state == IsViewable) {
- DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
- XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
- }
+ DBG_PRINT( "X11: XRaiseWindow dpy %p, win %p\n", dpy, (void*)w);
+ XRaiseWindow(dpy, w);
+ NewtWindows_setCWAbove(dpy, w);
+ // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable
+ XGetWindowAttributes(dpy, w, &xwa);
+ if(xwa.map_state == IsViewable) {
+ DBG_PRINT( "X11: XSetInputFocus dpy %p,win %pd\n", dpy, (void*)w);
+ XSetInputFocus(dpy, w, RevertToParent, CurrentTime);
}
}
DBG_PRINT( "X11: requestFocus dpy %p,win %p, force %d - FIN\n", dpy, (void*)w, force);
@@ -710,752 +430,6 @@ static Bool NewtWindows_setFullscreenEWMH (Display *dpy, Window root, Window w,
return res;
}
-#define USE_SENDIO_DIRECT 1
-
-/*
- * Class: jogamp_newt_driver_x11_X11Display
- * Method: DispatchMessages
- * Signature: (JIJJ)V
- */
-JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Display_DispatchMessages0
- (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong windowDeleteAtom)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Atom wm_delete_atom = (Atom)windowDeleteAtom;
- int num_events = 100;
-
- if ( NULL == dpy ) {
- return;
- }
-
- // Periodically take a break
- while( num_events > 0 ) {
- jobject jwindow = NULL;
- XEvent evt;
- KeySym keySym = 0;
- jint modifiers = 0;
- char keyChar = 0;
- char text[255];
-
- // XEventsQueued(dpy, X):
- // QueuedAlready : No I/O Flush or system call doesn't work on some cards (eg ATI) ?)
- // QueuedAfterFlush == XPending(): I/O Flush only if no already queued events are available
- // QueuedAfterReading : QueuedAlready + if queue==0, attempt to read more ..
- if ( 0 >= XPending(dpy) ) {
- // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy);
- return;
- }
-
- XNextEvent(dpy, &evt);
- num_events--;
-
- if( 0==evt.xany.window ) {
- NewtCommon_throwNewRuntimeException(env, "event window NULL, bail out!");
- return ;
- }
-
- if(dpy!=evt.xany.display) {
- NewtCommon_throwNewRuntimeException(env, "wrong display, bail out!");
- return ;
- }
-
- // DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, (int)evt.type);
-
- displayDispatchErrorHandlerEnable(1, env);
-
- jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom,
- #ifdef VERBOSE_ON
- True
- #else
- False
- #endif
- );
-
- displayDispatchErrorHandlerEnable(0, env);
-
- if(NULL==jwindow) {
- fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n",
- (void*)dpy, evt.type, (void*)evt.xany.window);
- continue;
- }
-
- switch(evt.type) {
- case KeyRelease:
- case KeyPress:
- if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
- KeySym lower_return = 0, upper_return = 0;
- keyChar=text[0];
- XConvertCase(keySym, &lower_return, &upper_return);
- // always return upper case, set modifier masks (SHIFT, ..)
- keySym = upper_return;
- modifiers = X11InputState2NewtModifiers(evt.xkey.state);
- } else {
- keyChar=0;
- }
- break;
-
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- modifiers = X11InputState2NewtModifiers(evt.xbutton.state);
- break;
-
- default:
- break;
- }
-
- switch(evt.type) {
- case ButtonPress:
- (*env)->CallVoidMethod(env, jwindow, enqueueRequestFocusID, JNI_FALSE);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_PRESSED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #endif
- break;
- case ButtonRelease:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_RELEASED,
- modifiers,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- #endif
- break;
- case MotionNotify:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
- modifiers,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_MOVED,
- modifiers,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
- #endif
- break;
- case EnterNotify:
- DBG_PRINT( "X11: event . EnterNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_ENTERED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #endif
- break;
- case LeaveNotify:
- DBG_PRINT( "X11: event . LeaveNotify call %p %d/%d\n", (void*)evt.xcrossing.window, evt.xcrossing.x, evt.xcrossing.y);
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, JNI_FALSE, (jint) EVENT_MOUSE_EXITED,
- modifiers,
- (jint) evt.xcrossing.x, (jint) evt.xcrossing.y, (jint) 0, 0 /*rotation*/);
- #endif
- break;
- case KeyPress:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_PRESSED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
- #endif
-
- break;
- case KeyRelease:
- #ifdef USE_SENDIO_DIRECT
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
-
- (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED,
- modifiers, (jint) -1, (jchar) keyChar);
- #else
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_RELEASED,
- modifiers, X11KeySym2NewtVKey(keySym), (jchar) keyChar);
-
- (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, JNI_FALSE, (jint) EVENT_KEY_TYPED,
- modifiers, (jint) -1, (jchar) keyChar);
- #endif
-
- break;
- case DestroyNotify:
- DBG_PRINT( "X11: event . DestroyNotify call %p, parent %p, child-event: %d\n",
- (void*)evt.xdestroywindow.window, (void*)evt.xdestroywindow.event, evt.xdestroywindow.window != evt.xdestroywindow.event);
- if ( evt.xdestroywindow.window == evt.xdestroywindow.event ) {
- // ignore child destroy notification
- }
- break;
- case CreateNotify:
- DBG_PRINT( "X11: event . CreateNotify call %p, parent %p, child-event: 1\n",
- (void*)evt.xcreatewindow.window, (void*) evt.xcreatewindow.parent);
- break;
- case ConfigureNotify:
- DBG_PRINT( "X11: event . ConfigureNotify call %p (parent %p, above %p) %d/%d %dx%d %d, child-event: %d\n",
- (void*)evt.xconfigure.window, (void*)evt.xconfigure.event, (void*)evt.xconfigure.above,
- evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height,
- evt.xconfigure.override_redirect, evt.xconfigure.window != evt.xconfigure.event);
- if ( evt.xconfigure.window == evt.xconfigure.event ) {
- // ignore child window change notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
- }
- (*env)->CallVoidMethod(env, jwindow, sizeChangedID, JNI_FALSE,
- (jint) evt.xconfigure.width, (jint) evt.xconfigure.height, JNI_FALSE);
- (*env)->CallVoidMethod(env, jwindow, positionChangedID, JNI_FALSE,
- (jint) evt.xconfigure.x, (jint) evt.xconfigure.y);
- }
- break;
- case ClientMessage:
- if (evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_atom) { // windowDeleteAtom
- DBG_PRINT( "X11: event . ClientMessage call %p type 0x%X !!!\n",
- (void*)evt.xclient.window, (unsigned int)evt.xclient.message_type);
- (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
- // Called by Window.java: CloseWindow();
- num_events = 0; // end loop in case of destroyed display
- }
- break;
-
- case FocusIn:
- DBG_PRINT( "X11: event . FocusIn call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_TRUE);
- break;
-
- case FocusOut:
- DBG_PRINT( "X11: event . FocusOut call %p\n", (void*)evt.xvisibility.window);
- (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE, JNI_FALSE);
- break;
-
- case Expose:
- DBG_PRINT( "X11: event . Expose call %p %d/%d %dx%d count %d\n", (void*)evt.xexpose.window,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height, evt.xexpose.count);
-
- if (evt.xexpose.count == 0 && evt.xexpose.width > 0 && evt.xexpose.height > 0) {
- (*env)->CallVoidMethod(env, jwindow, windowRepaintID, JNI_FALSE,
- evt.xexpose.x, evt.xexpose.y, evt.xexpose.width, evt.xexpose.height);
- }
- break;
-
- case MapNotify:
- DBG_PRINT( "X11: event . MapNotify call Event %p, Window %p, override_redirect %d, child-event: %d\n",
- (void*)evt.xmap.event, (void*)evt.xmap.window, (int)evt.xmap.override_redirect,
- evt.xmap.event!=evt.xmap.window);
- if( evt.xmap.event == evt.xmap.window ) {
- // ignore child window notification
- {
- // update insets
- int left, right, top, bottom;
- NewtWindows_updateInsets(env, jwindow, dpy, evt.xany.window, &left, &right, &top, &bottom);
- }
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
- }
- break;
-
- case UnmapNotify:
- DBG_PRINT( "X11: event . UnmapNotify call Event %p, Window %p, from_configure %d, child-event: %d\n",
- (void*)evt.xunmap.event, (void*)evt.xunmap.window, (int)evt.xunmap.from_configure,
- evt.xunmap.event!=evt.xunmap.window);
- if( evt.xunmap.event == evt.xunmap.window ) {
- // ignore child window notification
- (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_FALSE);
- }
- break;
-
- case ReparentNotify:
- {
- jlong parentResult; // 0 if root, otherwise proper value
- Window winRoot, winTopParent;
- #ifdef VERBOSE_ON
- Window oldParentRoot, oldParentTopParent;
- Window parentRoot, parentTopParent;
- if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.event, &oldParentRoot, &oldParentTopParent) ) {
- oldParentRoot=0; oldParentTopParent = 0;
- }
- if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.parent, &parentRoot, &parentTopParent) ) {
- parentRoot=0; parentTopParent = 0;
- }
- #endif
- if( 0 == NewtWindows_getRootAndParent(dpy, evt.xreparent.window, &winRoot, &winTopParent) ) {
- winRoot=0; winTopParent = 0;
- }
- if(evt.xreparent.parent == winRoot) {
- parentResult = 0; // our java indicator for root window
- } else {
- parentResult = (jlong) (intptr_t) evt.xreparent.parent;
- }
- #ifdef VERBOSE_ON
- DBG_PRINT( "X11: event . ReparentNotify: call %d/%d OldParent %p (root %p, top %p), NewParent %p (root %p, top %p), Window %p (root %p, top %p)\n",
- evt.xreparent.x, evt.xreparent.y,
- (void*)evt.xreparent.event, (void*)oldParentRoot, (void*)oldParentTopParent,
- (void*)evt.xreparent.parent, (void*)parentRoot, (void*)parentTopParent,
- (void*)evt.xreparent.window, (void*)winRoot, (void*)winTopParent);
- #endif
- (*env)->CallVoidMethod(env, jwindow, reparentNotifyID, (jlong)evt.xreparent.parent);
- }
- break;
-
- // unhandled events .. yet ..
-
- default:
- DBG_PRINT("X11: event . unhandled %d 0x%X call %p\n", (int)evt.type, (unsigned int)evt.type, (void*)evt.xunmap.window);
- }
- }
-}
-
-
-/**
- * Screen
- */
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: GetScreen
- * Signature: (JI)J
- */
-JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Screen_GetScreen0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_index)
-{
- Display * dpy = (Display *)(intptr_t)display;
- Screen * scrn= NULL;
-
- DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy);
-
- if(dpy==NULL) {
- NewtCommon_FatalError(env, "invalid display connection..");
- }
-
- scrn = ScreenOfDisplay(dpy, screen_index);
- if(scrn==NULL) {
- fprintf(stderr, "couldn't get screen idx %d\n", screen_index);
- }
- DBG_PRINT("X11: X11Screen_GetScreen0 idx %d -> scrn %p DONE\n", screen_index, scrn);
- return (jlong) (intptr_t) scrn;
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getWidth0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) XDisplayWidth( dpy, scrn_idx);
-}
-
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getHeight0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display * dpy = (Display *) (intptr_t) display;
- return (jint) XDisplayHeight( dpy, scrn_idx);
-}
-
-
-static Bool NewtScreen_getRANDRVersion(Display *dpy, int *major, int *minor) {
- if( 0 == XRRQueryVersion(dpy, major, minor) ) {
- return False;
- }
- return True;
-}
-
-static Bool NewtScreen_hasRANDR(Display *dpy) {
- int major, minor;
- return NewtScreen_getRANDRVersion(dpy, &major, &minor);
-}
-
-static int NewtScreen_XRotation2Degree(JNIEnv *env, int xrotation) {
- int rot;
- if(xrotation == RR_Rotate_0) {
- rot = 0;
- }
- else if(xrotation == RR_Rotate_90) {
- rot = 90;
- }
- else if(xrotation == RR_Rotate_180) {
- rot = 180;
- }
- else if(xrotation == RR_Rotate_270) {
- rot = 270;
- } else {
- NewtCommon_throwNewRuntimeException(env, "invalid native rotation: %d", xrotation);
- }
- return rot;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getAvailableScreenModeRotations0
- * Signature: (JI)I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getAvailableScreenModeRotations0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
- int num_rotations = 0;
- Rotation cur_rotation, rotations_supported;
- int rotations[4];
- int major, minor;
-
- if(False == NewtScreen_getRANDRVersion(dpy, &major, &minor)) {
- fprintf(stderr, "RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- rotations_supported = XRRRotations (dpy, (int)scrn_idx, &cur_rotation);
-
- if(0 != (rotations_supported & RR_Rotate_0)) {
- rotations[num_rotations++] = 0;
- }
- if(0 != (rotations_supported & RR_Rotate_90)) {
- rotations[num_rotations++] = 90;
- }
- if(0 != (rotations_supported & RR_Rotate_180)) {
- rotations[num_rotations++] = 180;
- }
- if(0 != (rotations_supported & RR_Rotate_270)) {
- rotations[num_rotations++] = 270;
- }
-
- jintArray properties = NULL;
-
- if(num_rotations>0) {
- properties = (*env)->NewIntArray(env, num_rotations);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rotations);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rotations, rotations);
- }
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getNumScreenModeResolution0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getNumScreenModeResolutions0: RANDR not available\n");
- return 0;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- DBG_PRINT("getNumScreenModeResolutions0: %d\n", num_sizes);
-
- return num_sizes;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeResolutions0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeResolution0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- // Fill the properties in temp jint array
- int propIndex = 0;
- jint prop[4];
-
- prop[propIndex++] = xrrs[(int)resMode_idx].width;
- prop[propIndex++] = xrrs[(int)resMode_idx].height;
- prop[propIndex++] = xrrs[(int)resMode_idx].mwidth;
- prop[propIndex++] = xrrs[(int)resMode_idx].mheight;
-
- jintArray properties = (*env)->NewIntArray(env, 4);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", 4);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, 4, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getScreenModeRates0
- * Signature: (JII)[I
- */
-JNIEXPORT jintArray JNICALL Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx, jint resMode_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getScreenModeRates0: RANDR not available\n");
- return (*env)->NewIntArray(env, 0);
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)scrn_idx, &num_sizes); //get possible screen resolutions
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- int num_rates;
- short *rates = XRRRates(dpy, (int)scrn_idx, (int)resMode_idx, &num_rates);
-
- jint prop[num_rates];
- int i;
- for(i=0; i<num_rates; i++) {
- prop[i] = (int) rates[i];
- /** fprintf(stderr, "rate[%d, %d, %d/%d]: %d\n", (int)scrn_idx, resMode_idx, i, num_rates, prop[i]); */
- }
-
- jintArray properties = (*env)->NewIntArray(env, num_rates);
- if (properties == NULL) {
- NewtCommon_throwNewRuntimeException(env, "Could not allocate int array of size %d", num_rates);
- }
-
- // move from the temp structure to the java structure
- (*env)->SetIntArrayRegion(env, properties, 0, num_rates, prop);
-
- return properties;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRate0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRate0: RANDR not available\n");
- return -1;
- }
-
- // get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- DBG_PRINT("getCurrentScreenRate0: %d\n", (int)original_rate);
-
- return (jint) original_rate;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenRotation0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenRotation0: RANDR not available\n");
- return -1;
- }
-
- //get current resolutions and frequencies
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
-
- Rotation rotation;
- XRRConfigCurrentConfiguration(conf, &rotation);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- return NewtScreen_XRotation2Degree(env, rotation);
-}
-
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: getCurrentScreenResolutionIndex0
- * Signature: (JI)I
- */
-JNIEXPORT jint JNICALL Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0
- (JNIEnv *env, jclass clazz, jlong display, jint scrn_idx)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)scrn_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_getCurrentScreenResolutionIndex0: RANDR not available\n");
- return -1;
- }
-
- // get current resolutions and frequency configuration
- XRRScreenConfiguration *conf = XRRGetScreenInfo(dpy, root);
- short original_rate = XRRConfigCurrentRate(conf);
-
- Rotation original_rotation;
- SizeID original_size_id = XRRConfigCurrentConfiguration(conf, &original_rotation);
-
- //free
- XRRFreeScreenConfigInfo(conf);
-
- DBG_PRINT("getCurrentScreenResolutionIndex0: %d\n", (int)original_size_id);
- return (jint)original_size_id;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModeStart0
- * Signature: (JIIII)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- Window root = RootWindow(dpy, (int)screen_idx);
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModeStart0: RANDR not available\n");
- return JNI_FALSE;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
- int rot;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- conf = XRRGetScreenInfo(dpy, root);
-
- switch(rotation) {
- case 0:
- rot = RR_Rotate_0;
- break;
- case 90:
- rot = RR_Rotate_90;
- break;
- case 180:
- rot = RR_Rotate_180;
- break;
- case 270:
- rot = RR_Rotate_270;
- break;
- default:
- NewtCommon_throwNewRuntimeException(env, "Invalid rotation: %d", rotation);
- }
-
- DBG_PRINT("X11Screen.setCurrentScreenMode0: CHANGED TO %d: %d x %d PIXELS, %d Hz, %d degree\n",
- resMode_idx, xrrs[resMode_idx].width, xrrs[resMode_idx].height, (int)freq, rotation);
-
- XRRSelectInput (dpy, root, RRScreenChangeNotifyMask);
-
- XSync(dpy, False);
- XRRSetScreenConfigAndRate(dpy, conf, root, (int)resMode_idx, rot, (short)freq, CurrentTime);
- XSync(dpy, False);
-
- //free
- XRRFreeScreenConfigInfo(conf);
- XSync(dpy, False);
-
- return JNI_TRUE;
-}
-
-/*
- * Class: jogamp_newt_driver_x11_X11Screen
- * Method: setCurrentScreenModePollEnd0
- * Signature: (J)Z
- */
-JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0
- (JNIEnv *env, jclass clazz, jlong display, jint screen_idx, jint resMode_idx, jint freq, jint rotation)
-{
- Display *dpy = (Display *) (intptr_t) display;
- int randr_event_base, randr_error_base;
- XEvent evt;
- XRRScreenChangeNotifyEvent * scn_event = (XRRScreenChangeNotifyEvent *) &evt;
-
- if(False == NewtScreen_hasRANDR(dpy)) {
- DBG_PRINT("Java_jogamp_newt_driver_x11_X11Screen_setCurrentScreenModePollEnd0: RANDR not available\n");
- return JNI_FALSE;
- }
-
- int num_sizes;
- XRRScreenSize *xrrs = XRRSizes(dpy, (int)screen_idx, &num_sizes); //get possible screen resolutions
- XRRScreenConfiguration *conf;
-
- if( 0 > resMode_idx || resMode_idx >= num_sizes ) {
- NewtCommon_throwNewRuntimeException(env, "Invalid resolution index: ! 0 < %d < %d", resMode_idx, num_sizes);
- }
-
- XRRQueryExtension(dpy, &randr_event_base, &randr_error_base);
-
- int done = 0;
- int rot;
- do {
- if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) {
- return;
- }
- XNextEvent(dpy, &evt);
-
- switch (evt.type - randr_event_base) {
- case RRScreenChangeNotify:
- rot = NewtScreen_XRotation2Degree(env, (int)scn_event->rotation);
- DBG_PRINT( "XRANDR: event . RRScreenChangeNotify call %p (root %p) resIdx %d rot %d %dx%d\n",
- (void*)scn_event->window, (void*)scn_event->root,
- (int)scn_event->size_index, rot,
- scn_event->width, scn_event->height);
- // done = scn_event->size_index == resMode_idx; // not reliable ..
- done = rot == rotation &&
- scn_event->width == xrrs[resMode_idx].width &&
- scn_event->height == xrrs[resMode_idx].height;
- break;
- default:
- DBG_PRINT("RANDR: event . unhandled %d 0x%X call %p\n", (int)evt.type, (int)evt.type, (void*)evt.xany.window);
- }
- XRRUpdateConfiguration(&evt);
- } while(!done);
-
- XSync(dpy, False);
-
-}
-
/**
* Window
*/
@@ -1468,37 +442,6 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Screen_setCurrentScree
JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_x11_X11Window_initIDs0
(JNIEnv *env, jclass clazz)
{
- insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V");
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(ZII)V");
- focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(ZZ)V");
- visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V");
- reparentNotifyID = (*env)->GetMethodID(env, clazz, "reparentNotify", "(J)V");
- windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
- windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(ZIIII)V");
- enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZIIIIII)V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
- enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZIIIC)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- enqueueRequestFocusID = (*env)->GetMethodID(env, clazz, "enqueueRequestFocus", "(Z)V");
- focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z");
-
- if (insetsChangedID == NULL ||
- sizeChangedID == NULL ||
- positionChangedID == NULL ||
- focusChangedID == NULL ||
- visibleChangedID == NULL ||
- reparentNotifyID == NULL ||
- windowDestroyNotifyID == NULL ||
- windowRepaintID == NULL ||
- enqueueMouseEventID == NULL ||
- sendMouseEventID == NULL ||
- enqueueKeyEventID == NULL ||
- sendKeyEventID == NULL ||
- focusActionID == NULL ||
- enqueueRequestFocusID == NULL) {
- return JNI_FALSE;
- }
return JNI_TRUE;
}
@@ -1513,14 +456,12 @@ static Bool WaitForUnmapNotify( Display *dpy, XEvent *event, XPointer arg ) {
static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint width, jint height) {
if(width>0 && height>0 || x>=0 && y>=0) { // resize/position if requested
XWindowChanges xwc;
- int flags = 0;
+ int flags = CWX | CWY;
memset(&xwc, 0, sizeof(XWindowChanges));
- if(0<=x && 0<=y) {
- flags |= CWX | CWY;
- xwc.x=x;
- xwc.y=y;
- }
+ xwc.x=x;
+ xwc.y=y;
+
if(0<width && 0<height) {
flags |= CWWidth | CWHeight;
xwc.width=width;
@@ -1534,13 +475,12 @@ static void NewtWindows_setPosSize(Display *dpy, Window w, jint x, jint y, jint
/*
* Class: jogamp_newt_driver_x11_X11Window
* Method: CreateWindow
- * Signature: (JJIJIIII)J
*/
JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
(JNIEnv *env, jobject obj, jlong parent, jlong display, jint screen_index,
jlong visualID,
jlong javaObjectAtom, jlong windowDeleteAtom,
- jint x, jint y, jint width, jint height, int flags)
+ jint x, jint y, jint width, jint height, jboolean autoPosition, int flags)
{
Display * dpy = (Display *)(intptr_t)display;
Atom wm_delete_atom = (Atom)windowDeleteAtom;
@@ -1576,9 +516,9 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
if(0==windowParent) {
windowParent = root;
}
- DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d, alwaysOnTop %d\n",
+ DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %d/%d %dx%d, undeco %d, alwaysOnTop %d, autoPosition %d\n",
(void*)dpy, (void*)windowParent, x, y, width, height,
- TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags));
+ TST_FLAG_IS_UNDECORATED(flags), TST_FLAG_IS_ALWAYSONTOP(flags), autoPosition);
// try given VisualID on screen
memset(&visualTemplate, 0, sizeof(XVisualInfo));
@@ -1628,7 +568,7 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
{
int _x = x, _y = y; // pos for CreateWindow, might be tweaked
- if(0>_x || 0>_y) {
+ if(JNI_TRUE == autoPosition) {
// user didn't requested specific position, use WM default
_x = 0;
_y = 0;
@@ -1662,7 +602,6 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
{
XEvent event;
int left, right, top, bottom;
- Bool userPos = 0<=x && 0<=y ;
XMapWindow(dpy, window);
XIfEvent( dpy, &event, WaitForMapNotify, (XPointer) window ); // wait to get proper insets values
@@ -1671,19 +610,17 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_x11_X11Window_CreateWindow0
NewtWindows_updateInsets(env, jwindow, dpy, window, &left, &right, &top, &bottom);
(*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE, JNI_TRUE);
- if(!userPos) {
+ if(JNI_TRUE == autoPosition) {
// get position from WM
int dest_x, dest_y;
Window child;
XTranslateCoordinates(dpy, window, windowParent, 0, 0, &dest_x, &dest_y, &child);
x = (int)dest_x; y = (int)dest_y;
}
- DBG_PRINT("X11: [CreateWindow]: client: %d/%d %dx%d (is user-pos %d)\n", x, y, width, height, userPos);
+ DBG_PRINT("X11: [CreateWindow]: client: %d/%d %dx%d (autoPosition %d)\n", x, y, width, height, autoPosition);
x -= left; // top-level
y -= top; // top-level
- if(0>x) { x = 0; }
- if(0>y) { y = 0; }
DBG_PRINT("X11: [CreateWindow]: top-level: %d/%d\n", x, y);
NewtWindows_setPosSize(dpy, window, x, y, width, height);
@@ -1774,7 +711,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
fsEWMHFlags |= _NET_WM_ABOVE; // toggle above only
}
- displayDispatchErrorHandlerEnable(1, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(1, env);
DBG_PRINT( "X11: reconfigureWindow0 dpy %p, scrn %d, parent %p/%p, win %p, %d/%d %dx%d, parentChange %d, hasParent %d, decorationChange %d, undecorated %d, fullscreenChange %d, fullscreen %d, alwaysOnTopChange %d, alwaysOnTop %d, visibleChange %d, visible %d, tempInvisible %d, fsEWMHFlags %d\n",
(void*)dpy, screen_index, (void*) jparent, (void*)parent, (void*)w,
@@ -1792,7 +729,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
( TST_FLAG_CHANGE_FULLSCREEN(flags) || TST_FLAG_CHANGE_ALWAYSONTOP(flags) ) ) {
Bool enable = TST_FLAG_CHANGE_FULLSCREEN(flags) ? TST_FLAG_IS_FULLSCREEN(flags) : TST_FLAG_IS_ALWAYSONTOP(flags) ;
if( NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, enable) ) {
- displayDispatchErrorHandlerEnable(0, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
return;
}
}
@@ -1856,7 +793,7 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_x11_X11Window_reconfigureWindow0
NewtWindows_setFullscreenEWMH(dpy, root, w, fsEWMHFlags, isVisible, True);
}
- displayDispatchErrorHandlerEnable(0, env);
+ NewtDisplay_displayDispatchErrorHandlerEnable(0, env);
DBG_PRINT( "X11: reconfigureWindow0 X\n");
}