aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2009-06-17 13:26:29 +0000
committerSven Gothel <[email protected]>2009-06-17 13:26:29 +0000
commita92906bcb4ce4746f291d40a736949ec8476de61 (patch)
tree49708922895aa07bdc72b0513bb5e90f63ecedb2
parent802288f8964affbda3460eea52df3d241ae3036a (diff)
- Add: GLProfile.get(name) return default if name=="GL" as well (or if null)
- Add: NEWT pumpMessages/dispatchMessages - Handled by the Display implementation for all windows - Windows .. OK - MacOSX .. OK - X11 .. OK - Added Atom Property handling to attach java window object to window - Removed the eventMask for dispatching messages, since dispatching is for all windows now. (Wasn't impl. for all platforms anyways) - All init static code will funnel in the Display.initSingletion(), to ensure a proper init order for all platforms. - Display creation is unique for (name,thread). Handling a TLS mapping of display-names to Displays. - GLWindow: autoSwapBufferMode and eventHandlerMode are static members - Tested with experimental tagged GLWindow.setRunPumpMessages()/runCurrentThreadPumpMessage(), 1 thread - 4 windows, etc .. java demos.es2.RedSquare -1thread -onepump -GL2 -GL2 -GL2 -GL2 No benefit .. However .. the implementation is more correct now, due to the display/current-thread message pumping. - Fix: Window.sendMouseEvent() bounds check - Fix: MacWindow has proper nsView locking now, local to the window instance. locked in lockSurface besides general window manipulation. - Fix: JAWT utilized JAWTUtil.init() to init libraries - NativeLibLoaderBase.loadNativeWindow("awt") call was missing. (Visible on MacOSX + AWT) - Fix: GLXUtil proper locking - Fix: X11Util proper locking git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@1976 232f8b59-042b-4e1e-8c03-345bb8c30851
-rwxr-xr-xmake/config/nativewindow/jawt-CustomJavaCode.java2
-rw-r--r--src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java64
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java4
-rw-r--r--src/nativewindow/classes/com/sun/nativewindow/impl/jawt/JAWTUtil.java21
-rw-r--r--src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java38
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/Display.java138
-rw-r--r--src/newt/classes/com/sun/javafx/newt/DisplayActionThread.java118
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/Window.java24
-rw-r--r--src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java118
-rw-r--r--src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java159
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/macosx/MacDisplay.java40
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/macosx/MacScreen.java10
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java126
-rw-r--r--src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java169
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/opengl/kd/KDDisplay.java21
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/opengl/kd/KDScreen.java4
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/opengl/kd/KDWindow.java30
-rw-r--r--src/newt/classes/com/sun/javafx/newt/util/MainThread.java4
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/windows/WindowsDisplay.java65
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/windows/WindowsScreen.java9
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java46
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/x11/X11Display.java44
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/x11/X11Screen.java4
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/x11/X11Window.java37
-rwxr-xr-xsrc/newt/native/KDWindow.c252
-rw-r--r--src/newt/native/MacWindow.m195
-rwxr-xr-xsrc/newt/native/WindowsWindow.c210
-rwxr-xr-xsrc/newt/native/X11Window.c530
28 files changed, 1548 insertions, 934 deletions
diff --git a/make/config/nativewindow/jawt-CustomJavaCode.java b/make/config/nativewindow/jawt-CustomJavaCode.java
index f1ef91075..b92e5a983 100755
--- a/make/config/nativewindow/jawt-CustomJavaCode.java
+++ b/make/config/nativewindow/jawt-CustomJavaCode.java
@@ -5,7 +5,7 @@ public static JAWT getJAWT() {
if (jawt == null) {
synchronized (JAWT.class) {
if (jawt == null) {
- JAWTNativeLibLoader.loadAWTImpl();
+ JAWTUtil.init();
// Workaround for 4845371.
// Make sure the first reference to the JNI GetDirectBufferAddress is done
// from a privileged context so the VM's internal class lookups will succeed.
diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java
index b8968ee99..8ab99ac0a 100644
--- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java
+++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java
@@ -51,40 +51,44 @@ public class GLXUtil {
// Display connection for use by visual selection algorithm and by all offscreen surfaces
private static boolean multisampleAvailable=false;
- private static boolean isInit=false;
+ private static volatile boolean isInit=false;
- private static void init() {
+ private static synchronized void init() {
if (!isInit) {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- try {
- long staticDisplay = X11Util.getStaticDefaultDisplay();
- if(staticDisplay!=0) {
- if (DEBUG) {
- long display = staticDisplay;
- int screen = X11Lib.DefaultScreen(display);
- System.err.println("!!! GLX server vendor : " +
- GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR));
- System.err.println("!!! GLX server version: " +
- GLX.glXQueryServerString(display, screen, GLX.GLX_VERSION));
- System.err.println("!!! GLX client vendor : " +
- GLX.glXGetClientString(display, GLX.GLX_VENDOR));
- System.err.println("!!! GLX client version: " +
- GLX.glXGetClientString(display, GLX.GLX_VERSION));
+ synchronized (GLXUtil.class) {
+ if (!isInit) {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ long staticDisplay = X11Util.getStaticDefaultDisplay();
+ if(staticDisplay!=0) {
+ if (DEBUG) {
+ long display = staticDisplay;
+ int screen = X11Lib.DefaultScreen(display);
+ System.err.println("!!! GLX server vendor : " +
+ GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR));
+ System.err.println("!!! GLX server version: " +
+ GLX.glXQueryServerString(display, screen, GLX.GLX_VERSION));
+ System.err.println("!!! GLX client vendor : " +
+ GLX.glXGetClientString(display, GLX.GLX_VENDOR));
+ System.err.println("!!! GLX client version: " +
+ GLX.glXGetClientString(display, GLX.GLX_VERSION));
+ }
+ String vendor = GLX.glXGetClientString(staticDisplay, GLX.GLX_VENDOR);
+ if (vendor != null && vendor.startsWith("ATI")) {
+ isVendorATI = true;
+ }
+ String exts = GLX.glXGetClientString(staticDisplay, GLX.GLX_EXTENSIONS);
+ if (exts != null) {
+ multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0);
+ }
+ isInit=true;
+ } else {
+ throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling");
+ }
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
}
- String vendor = GLX.glXGetClientString(staticDisplay, GLX.GLX_VENDOR);
- if (vendor != null && vendor.startsWith("ATI")) {
- isVendorATI = true;
- }
- String exts = GLX.glXGetClientString(staticDisplay, GLX.GLX_EXTENSIONS);
- if (exts != null) {
- multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0);
- }
- isInit=true;
- } else {
- throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling");
}
- } finally {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
}
}
}
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 57f4fb46a..385006b75 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -104,13 +104,15 @@ public class GLProfile implements Cloneable {
/** Returns a GLProfile object.
* Verfifies the given profile and chooses an apropriate implementation.
+ * A generic value of <code>null</code> or <code>GL</code> will result in
+ * the default profile.
*
* @throws GLException if no implementation for the given profile is found.
*/
public static final GLProfile get(String profile)
throws GLException
{
- if(null==profile) return getDefault();
+ if(null==profile || profile.equals("GL")) return getDefault();
GLProfile glProfile = (GLProfile) mappedProfiles.get(profile);
if(null==glProfile) {
throw new GLException("No implementation for profile "+profile+" available");
diff --git a/src/nativewindow/classes/com/sun/nativewindow/impl/jawt/JAWTUtil.java b/src/nativewindow/classes/com/sun/nativewindow/impl/jawt/JAWTUtil.java
index ae606a790..20e8cf966 100644
--- a/src/nativewindow/classes/com/sun/nativewindow/impl/jawt/JAWTUtil.java
+++ b/src/nativewindow/classes/com/sun/nativewindow/impl/jawt/JAWTUtil.java
@@ -43,21 +43,28 @@ import javax.media.nativewindow.*;
import java.awt.GraphicsEnvironment;
public class JAWTUtil {
- static {
- JAWTNativeLibLoader.loadAWTImpl();
- NativeLibLoaderBase.loadNativeWindow("awt");
- }
-
- // See whether we're running in headless mode
- private static boolean headlessMode;
static {
+ JAWTNativeLibLoader.loadAWTImpl();
+ NativeLibLoaderBase.loadNativeWindow("awt");
+
lockedStack = null;
headlessMode = GraphicsEnvironment.isHeadless();
}
+ // See whether we're running in headless mode
+ private static final boolean headlessMode;
+
private static Exception lockedStack;
+ // Just a hook to let this class being initialized,
+ // ie loading the native libraries ..
+ public static void init() { }
+
+ public static boolean isHeadlessMode() {
+ return headlessMode;
+ }
+
public static synchronized void lockToolkit() throws NativeWindowException {
if (null!=lockedStack) {
lockedStack.printStackTrace();
diff --git a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java
index 731bd3caf..38d0fb73d 100644
--- a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java
+++ b/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java
@@ -73,18 +73,23 @@ public class X11Util {
private static ThreadLocal currentDisplayAssociation = new ThreadLocal();
- private static long staticDefaultDisplay=0;
+ private static volatile long staticDefaultDisplay=0;
private static boolean staticDefaultDisplayXineramaEnable=false;
private static long fetchStaticDefaultDisplay() {
if(0==staticDefaultDisplay) {
synchronized (X11Util.class) {
if(0==staticDefaultDisplay) {
- staticDefaultDisplay = X11Lib.XOpenDisplay(null);
- if(0==staticDefaultDisplay) {
- throw new NativeWindowException("Unable to create a static default display connection");
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ staticDefaultDisplay = X11Lib.XOpenDisplay(null);
+ if(0==staticDefaultDisplay) {
+ throw new NativeWindowException("Unable to create a static default display connection");
+ }
+ staticDefaultDisplayXineramaEnable = X11Lib.XineramaEnabled(staticDefaultDisplay);
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
}
- staticDefaultDisplayXineramaEnable = X11Lib.XineramaEnabled(staticDefaultDisplay);
}
}
}
@@ -109,15 +114,20 @@ public class X11Util {
public static long getThreadLocalDefaultDisplay() {
Long dpyL = (Long) currentDisplayAssociation.get();
if(null==dpyL) {
- long dpy = X11Lib.XOpenDisplay(null);
- if(0==dpy) {
- throw new NativeWindowException("Unable to create a default display connection on Thread "+Thread.currentThread().getName());
- }
- dpyL = new Long(dpy);
- currentDisplayAssociation.set( dpyL );
- if(DEBUG) {
- Exception e = new Exception("Created new TLS display connection 0x"+Long.toHexString(dpy)+" for thread "+Thread.currentThread().getName());
- e.printStackTrace();
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
+ try {
+ long dpy = X11Lib.XOpenDisplay(null);
+ if(0==dpy) {
+ throw new NativeWindowException("Unable to create a default display connection on Thread "+Thread.currentThread().getName());
+ }
+ dpyL = new Long(dpy);
+ currentDisplayAssociation.set( dpyL );
+ if(DEBUG) {
+ Exception e = new Exception("Created new TLS display connection 0x"+Long.toHexString(dpy)+" for thread "+Thread.currentThread().getName());
+ e.printStackTrace();
+ }
+ } finally {
+ NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
}
}
return dpyL.longValue();
diff --git a/src/newt/classes/com/sun/javafx/newt/Display.java b/src/newt/classes/com/sun/javafx/newt/Display.java
index b5d3c8520..5032477c9 100755
--- a/src/newt/classes/com/sun/javafx/newt/Display.java
+++ b/src/newt/classes/com/sun/javafx/newt/Display.java
@@ -34,8 +34,11 @@
package com.sun.javafx.newt;
import javax.media.nativewindow.*;
+import com.sun.javafx.newt.impl.Debug;
+import java.util.*;
-public abstract class Display {
+public abstract class Display implements Runnable {
+ public static final boolean DEBUG = Debug.debug("Display");
private static Class getDisplayClass(String type)
throws ClassNotFoundException
@@ -57,14 +60,93 @@ public abstract class Display {
return displayClass;
}
+ private static ThreadLocal currentDisplayMap = new ThreadLocal();
+
+ /** Returns the thread local display map */
+ public static Map getCurrentDisplayMap() {
+ Map displayMap = (Map) currentDisplayMap.get();
+ if(null==displayMap) {
+ displayMap = new HashMap();
+ currentDisplayMap.set( displayMap );
+ }
+ return displayMap;
+ }
+
+ /** maps the given display to the thread local display map
+ * and notifies all threads synchronized to this display map. */
+ protected static Display setCurrentDisplay(Display display) {
+ Map displayMap = getCurrentDisplayMap();
+ Display oldDisplay = null;
+ synchronized(displayMap) {
+ String name = display.getName();
+ if(null==name) name="nil";
+ oldDisplay = (Display) displayMap.put(name, display);
+ displayMap.notifyAll();
+ }
+ return oldDisplay;
+ }
+
+ /** removes the mapping of the given name from the thread local display map
+ * and notifies all threads synchronized to this display map. */
+ protected static Display removeCurrentDisplay(String name) {
+ if(null==name) name="nil";
+ Map displayMap = getCurrentDisplayMap();
+ Display oldDisplay = null;
+ synchronized(displayMap) {
+ oldDisplay = (Display) displayMap.remove(name);
+ displayMap.notifyAll();
+ }
+ return oldDisplay;
+ }
+
+ /** Returns the thread local display mapped to the given name */
+ public static Display getCurrentDisplay(String name) {
+ if(null==name) name="nil";
+ Map displayMap = getCurrentDisplayMap();
+ Display display = (Display) displayMap.get(name);
+ return display;
+ }
+
+ private static void dumpDisplayMap(String prefix) {
+ Map displayMap = getCurrentDisplayMap();
+ Set entrySet = displayMap.entrySet();
+ Iterator i = entrySet.iterator();
+ System.err.println(prefix+" DisplayMap["+entrySet.size()+"] "+Thread.currentThread().getName());
+ for(int j=0; i.hasNext(); j++) {
+ Map.Entry entry = (Map.Entry) i.next();
+ System.err.println(" ["+j+"] "+entry.getKey()+" -> "+entry.getValue());
+ }
+ }
+
+ /** Returns the thread local display collection */
+ public static Collection getCurrentDisplays() {
+ return getCurrentDisplayMap().values();
+ }
+
+ /** Make sure to reuse a Display with the same name */
protected static Display create(String type, String name) {
try {
- Class displayClass = getDisplayClass(type);
- Display display = (Display) displayClass.newInstance();
- display.name=name;
- display.createNative();
- if(null==display.aDevice) {
- throw new RuntimeException("Display.createNative() failed to instanciate an AbstractGraphicsDevice");
+ Display display = getCurrentDisplay(name);
+ if(null==display) {
+ Class displayClass = getDisplayClass(type);
+ display = (Display) displayClass.newInstance();
+ display.name=name;
+ display.refCount=1;
+ display.createNative();
+ if(null==display.aDevice) {
+ throw new RuntimeException("Display.createNative() failed to instanciate an AbstractGraphicsDevice");
+ }
+ setCurrentDisplay(display);
+ if(DEBUG) {
+ System.err.println("Display.create("+name+") NEW: "+display+" "+Thread.currentThread().getName());
+ }
+ } else {
+ synchronized(display) {
+ display.refCount++;
+ if(DEBUG) {
+ System.err.println("Display.create("+name+") REUSE: refCount "+display.refCount+", "+display+" "+Thread.currentThread().getName());
+ }
+ }
}
return display;
} catch (Exception e) {
@@ -73,7 +155,18 @@ public abstract class Display {
}
public synchronized void destroy() {
- closeNative();
+ refCount--;
+ if(0==refCount) {
+ removeCurrentDisplay(name);
+ if(DEBUG) {
+ System.err.println("Display.destroy("+name+") REMOVE: "+this+" "+Thread.currentThread().getName());
+ }
+ closeNative();
+ } else {
+ if(DEBUG) {
+ System.err.println("Display.destroy("+name+") KEEP: refCount "+refCount+", "+this+" "+Thread.currentThread().getName());
+ }
+ }
}
protected static Display wrapHandle(String type, String name, AbstractGraphicsDevice aDevice) {
@@ -103,7 +196,36 @@ public abstract class Display {
return aDevice;
}
+ public synchronized void pumpMessages() {
+ dispatchMessages();
+ }
+
+ /** calls {@link #pumpMessages} */
+ public void run() {
+ pumpMessages();
+ }
+
+ public static interface Action {
+ public void run(Display display);
+ }
+
+ /** Calls {@link Display.Action#run(Display)} on all Display's
+ bound to the current thread. */
+ public static void runCurrentThreadDisplaysAction(Display.Action action) {
+ Iterator iter = getCurrentDisplays().iterator(); // Thread local .. no sync necessary
+ while(iter.hasNext()) {
+ action.run((Display) iter.next());
+ }
+ }
+
+ public String toString() {
+ return "NEWT-Display["+name+", refCount "+refCount+", "+aDevice+"]";
+ }
+
+ protected abstract void dispatchMessages();
+
protected String name;
+ protected int refCount;
protected AbstractGraphicsDevice aDevice;
}
diff --git a/src/newt/classes/com/sun/javafx/newt/DisplayActionThread.java b/src/newt/classes/com/sun/javafx/newt/DisplayActionThread.java
new file mode 100644
index 000000000..8f02148a2
--- /dev/null
+++ b/src/newt/classes/com/sun/javafx/newt/DisplayActionThread.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Sun Microsystems, Inc. or the names of
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind. ALL
+ * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
+ * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
+ * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
+ * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
+ * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
+ * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
+ * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+package com.sun.javafx.newt;
+
+import javax.media.nativewindow.*;
+import com.sun.javafx.newt.impl.Debug;
+import java.util.*;
+
+public class DisplayActionThread extends Thread {
+ private Object taskWorkerLock=new Object();
+ private boolean isRunning = false;
+ private boolean shouldStop = false;
+ private List/*DisplayAction*/ displayActions = new ArrayList();
+
+ public synchronized void addAction(Display.Action da) {
+ List newListeners = (List) ((ArrayList) displayActions).clone();
+ newListeners.add(da);
+ displayActions = newListeners;
+ }
+
+ public synchronized void removeAction(Display.Action da) {
+ List newListeners = (List) ((ArrayList) displayActions).clone();
+ newListeners.remove(da);
+ displayActions = newListeners;
+ }
+
+ public boolean isRunning() {
+ synchronized(taskWorkerLock) {
+ return isRunning;
+ }
+ }
+
+ public void exit() {
+ synchronized(taskWorkerLock) {
+ if(isRunning) {
+ shouldStop = true;
+ taskWorkerLock.notifyAll();
+ }
+ }
+ Map displayMap = Display.getCurrentDisplayMap();
+ synchronized(displayMap) {
+ displayMap.notifyAll();
+ }
+ }
+
+ public void start() {
+ synchronized(taskWorkerLock) {
+ if(!isRunning) {
+ shouldStop = false;
+ taskWorkerLock.notifyAll();
+ super.start();
+ }
+ }
+ }
+
+ public void run() {
+ synchronized(taskWorkerLock) {
+ isRunning = true;
+ taskWorkerLock.notifyAll();
+ }
+ while(!shouldStop) {
+ Map displayMap = Display.getCurrentDisplayMap();
+ // wait for something todo ..
+ synchronized(displayMap) {
+ while(!shouldStop && displayMap.size()==0) {
+ try {
+ displayMap.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ Iterator iter = Display.getCurrentDisplays().iterator();
+ while(iter.hasNext()) {
+ Display display = (Display) iter.next();
+ Iterator iterDA = displayActions.iterator();
+ while(iterDA.hasNext()) {
+ ((Display.Action)iterDA.next()).run(display);
+ }
+ }
+ }
+ synchronized(taskWorkerLock) {
+ isRunning = false;
+ taskWorkerLock.notifyAll();
+ }
+ }
+}
diff --git a/src/newt/classes/com/sun/javafx/newt/Window.java b/src/newt/classes/com/sun/javafx/newt/Window.java
index 68cb97834..36eafd32d 100755
--- a/src/newt/classes/com/sun/javafx/newt/Window.java
+++ b/src/newt/classes/com/sun/javafx/newt/Window.java
@@ -137,27 +137,6 @@ public abstract class Window implements NativeWindow
return screen;
}
- /**
- * eventMask is a bitfield of EventListener event flags
- */
- public void pumpMessages(int eventMask) {
- if(this.eventMask!=eventMask && eventMask>0) {
- this.eventMask=eventMask;
- eventMask*=-1;
- }
- dispatchMessages(eventMask);
- }
-
- public void pumpMessages() {
- int em = 0;
- if(windowListeners.size()>0) em |= EventListener.WINDOW;
- if(mouseListeners.size()>0) em |= EventListener.MOUSE;
- if(keyListeners.size()>0) em |= EventListener.KEY;
- pumpMessages(em);
- }
-
- protected abstract void dispatchMessages(int eventMask);
-
public String toString() {
StringBuffer sb = new StringBuffer();
@@ -438,6 +417,9 @@ public abstract class Window implements NativeWindow
protected void sendMouseEvent(int eventType, int modifiers,
int x, int y, int button, int rotation) {
+ if(x<0||y<0||x>=width||y>=height) {
+ return; // .. invalid ..
+ }
if(DEBUG_MOUSE_EVENT) {
System.out.println("sendMouseEvent: "+MouseEvent.getEventTypeString(eventType)+
", mod "+modifiers+", pos "+x+"/"+y+", button "+button);
diff --git a/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java b/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java
index 099125630..19f3ed1a8 100644
--- a/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java
+++ b/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java
@@ -33,10 +33,12 @@
package com.sun.javafx.newt.awt;
-import java.awt.*;
-import com.sun.javafx.newt.*;
+import java.awt.event.*;
+import com.sun.javafx.newt.Display;
+import com.sun.javafx.newt.Window;
import javax.media.nativewindow.*;
import javax.media.nativewindow.awt.*;
+import java.util.*;
public class AWTDisplay extends Display {
public AWTDisplay() {
@@ -51,4 +53,116 @@ public class AWTDisplay extends Display {
}
protected void closeNative() { }
+
+ public void dispatchMessages() {
+ AWTEventWrapper w;
+ do {
+ synchronized(this) {
+ if (!events.isEmpty()) {
+ w = (AWTEventWrapper) events.removeFirst();
+ } else {
+ w = null;
+ }
+ }
+ if (w != null) {
+ switch (w.getType()) {
+ case com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_RESIZED:
+ case com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_MOVED:
+ case com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY:
+ w.getWindow().sendWindowEvent(w.getType());
+ break;
+
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_CLICKED:
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_ENTERED:
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_EXITED:
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_PRESSED:
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_RELEASED:
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_MOVED:
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_DRAGGED:
+ case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_WHEEL_MOVED:
+ {
+ MouseEvent e = (MouseEvent) w.getEvent();
+ int rotation = 0;
+ if (e instanceof MouseWheelEvent) {
+ rotation = ((MouseWheelEvent)e).getWheelRotation();
+ }
+ w.getWindow().sendMouseEvent(w.getType(), convertModifiers(e),
+ e.getX(), e.getY(), convertButton(e),
+ rotation);
+ }
+ break;
+
+ case com.sun.javafx.newt.KeyEvent.EVENT_KEY_PRESSED:
+ case com.sun.javafx.newt.KeyEvent.EVENT_KEY_RELEASED:
+ case com.sun.javafx.newt.KeyEvent.EVENT_KEY_TYPED:
+ {
+ KeyEvent e = (KeyEvent) w.getEvent();
+ w.getWindow().sendKeyEvent(w.getType(), convertModifiers(e),
+ e.getKeyCode(), e.getKeyChar());
+ }
+ break;
+
+ default:
+ throw new NativeWindowException("Unknown event type " + w.getType());
+ }
+ if(Window.DEBUG_MOUSE_EVENT) {
+ System.out.println("dispatchMessages: "+w.getWindow()+" in event:"+w.getEvent());
+ }
+ }
+ } while (w != null);
+ }
+
+ protected void enqueueEvent(AWTWindow w, int type, InputEvent e) {
+ AWTEventWrapper wrapper = new AWTEventWrapper(w, type, e);
+ synchronized(this) {
+ events.add(wrapper);
+ }
+ }
+
+ private LinkedList/*<AWTEventWrapper>*/ events = new LinkedList();
+
+ static class AWTEventWrapper {
+ AWTWindow window;
+ int type;
+ InputEvent e;
+
+ AWTEventWrapper(AWTWindow w, int type, InputEvent e) {
+ this.window = w;
+ this.type = type;
+ this.e = e;
+ }
+
+ public AWTWindow getWindow() {
+ return window;
+ }
+
+ public int getType() {
+ return type;
+ }
+
+ public InputEvent getEvent() {
+ return e;
+ }
+ }
+
+ private static int convertModifiers(InputEvent e) {
+ int newtMods = 0;
+ int mods = e.getModifiers();
+ if ((mods & InputEvent.SHIFT_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.SHIFT_MASK;
+ if ((mods & InputEvent.CTRL_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.CTRL_MASK;
+ if ((mods & InputEvent.META_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.META_MASK;
+ if ((mods & InputEvent.ALT_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.ALT_MASK;
+ if ((mods & InputEvent.ALT_GRAPH_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.ALT_GRAPH_MASK;
+ return newtMods;
+ }
+
+ private static int convertButton(MouseEvent e) {
+ switch (e.getButton()) {
+ case MouseEvent.BUTTON1: return com.sun.javafx.newt.MouseEvent.BUTTON1;
+ case MouseEvent.BUTTON2: return com.sun.javafx.newt.MouseEvent.BUTTON2;
+ case MouseEvent.BUTTON3: return com.sun.javafx.newt.MouseEvent.BUTTON3;
+ }
+ return 0;
+ }
+
}
diff --git a/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java b/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java
index 3742a0e57..a425386a3 100644
--- a/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java
+++ b/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java
@@ -63,7 +63,6 @@ public class AWTWindow extends Window {
private Frame frame;
private AWTCanvas canvas;
- private LinkedList/*<AWTEventWrapper>*/ events = new LinkedList();
// non fullscreen dimensions ..
private int nfs_width, nfs_height, nfs_x, nfs_y;
@@ -80,13 +79,15 @@ public class AWTWindow extends Window {
protected void createNative(final Capabilities caps) {
+ final AWTWindow awtWindow = this;
+
runOnEDT(true, new Runnable() {
public void run() {
frame = new Frame(getTitle());
frame.setUndecorated(isUndecorated());
frame.setLayout(new BorderLayout());
canvas = new AWTCanvas(caps);
- Listener listener = new Listener();
+ Listener listener = new Listener(awtWindow);
canvas.addMouseListener(listener);
canvas.addMouseMotionListener(listener);
canvas.addKeyListener(listener);
@@ -94,8 +95,8 @@ public class AWTWindow extends Window {
frame.add(canvas, BorderLayout.CENTER);
frame.setSize(width, height);
frame.setLocation(x, y);
- frame.addComponentListener(new MoveListener());
- frame.addWindowListener(new WindowEventListener());
+ frame.addComponentListener(new MoveListener(awtWindow));
+ frame.addWindowListener(new WindowEventListener(awtWindow));
}
});
}
@@ -216,84 +217,17 @@ public class AWTWindow extends Window {
return canvas;
}
- public void dispatchMessages(int eventMask) {
- AWTEventWrapper w;
- do {
- synchronized(this) {
- if (!events.isEmpty()) {
- w = (AWTEventWrapper) events.removeFirst();
- } else {
- w = null;
- }
- }
- if (w != null) {
- switch (w.getType()) {
- case com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_RESIZED:
- case com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_MOVED:
- case com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY:
- if ((eventMask & com.sun.javafx.newt.EventListener.WINDOW) != 0) {
- sendWindowEvent(w.getType());
- }
- break;
-
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_CLICKED:
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_ENTERED:
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_EXITED:
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_PRESSED:
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_RELEASED:
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_MOVED:
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_DRAGGED:
- case com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_WHEEL_MOVED:
- if ((eventMask & com.sun.javafx.newt.EventListener.MOUSE) != 0) {
- MouseEvent e = (MouseEvent) w.getEvent();
- int rotation = 0;
- if (e instanceof MouseWheelEvent) {
- rotation = ((MouseWheelEvent)e).getWheelRotation();
- }
- sendMouseEvent(w.getType(), convertModifiers(e),
- e.getX(), e.getY(), convertButton(e),
- rotation);
- }
- break;
-
- case com.sun.javafx.newt.KeyEvent.EVENT_KEY_PRESSED:
- case com.sun.javafx.newt.KeyEvent.EVENT_KEY_RELEASED:
- case com.sun.javafx.newt.KeyEvent.EVENT_KEY_TYPED:
- if ((eventMask & com.sun.javafx.newt.EventListener.KEY) != 0) {
- KeyEvent e = (KeyEvent) w.getEvent();
- sendKeyEvent(w.getType(), convertModifiers(e),
- e.getKeyCode(), e.getKeyChar());
- }
- break;
-
- default:
- throw new NativeWindowException("Unknown event type " + w.getType());
- }
- if(Window.DEBUG_MOUSE_EVENT) {
- System.out.println("dispatchMessages: in event:"+w.getEvent());
- }
- }
- } while (w != null);
+ protected void sendWindowEvent(int eventType) {
+ super.sendWindowEvent(eventType);
}
- private static int convertModifiers(InputEvent e) {
- int newtMods = 0;
- int mods = e.getModifiers();
- if ((mods & InputEvent.SHIFT_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.SHIFT_MASK;
- if ((mods & InputEvent.CTRL_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.CTRL_MASK;
- if ((mods & InputEvent.META_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.META_MASK;
- if ((mods & InputEvent.ALT_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.ALT_MASK;
- if ((mods & InputEvent.ALT_GRAPH_MASK) != 0) newtMods |= com.sun.javafx.newt.InputEvent.ALT_GRAPH_MASK;
- return newtMods;
+ protected void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) {
+ super.sendKeyEvent(eventType, modifiers, keyCode, keyChar);
}
- private static int convertButton(MouseEvent e) {
- switch (e.getButton()) {
- case MouseEvent.BUTTON1: return com.sun.javafx.newt.MouseEvent.BUTTON1;
- case MouseEvent.BUTTON2: return com.sun.javafx.newt.MouseEvent.BUTTON2;
- case MouseEvent.BUTTON3: return com.sun.javafx.newt.MouseEvent.BUTTON3;
- }
- return 0;
+ protected void sendMouseEvent(int eventType, int modifiers,
+ int x, int y, int button, int rotation) {
+ super.sendMouseEvent(eventType, modifiers, x, y, button, rotation);
}
private static void runOnEDT(boolean wait, Runnable r) {
@@ -312,43 +246,26 @@ public class AWTWindow extends Window {
}
}
- private void enqueueEvent(int type, InputEvent e) {
- AWTEventWrapper wrapper = new AWTEventWrapper(type, e);
- synchronized(this) {
- events.add(wrapper);
- }
- }
-
private static final int WINDOW_EVENT = 1;
private static final int KEY_EVENT = 2;
private static final int MOUSE_EVENT = 3;
- static class AWTEventWrapper {
- int type;
- InputEvent e;
-
- AWTEventWrapper(int type, InputEvent e) {
- this.type = type;
- this.e = e;
- }
-
- public int getType() {
- return type;
- }
+ class MoveListener implements ComponentListener {
+ private AWTWindow window;
+ private AWTDisplay display;
- public InputEvent getEvent() {
- return e;
+ public MoveListener(AWTWindow w) {
+ window = w;
+ display = (AWTDisplay)window.getScreen().getDisplay();
}
- }
- class MoveListener implements ComponentListener {
public void componentResized(ComponentEvent e) {
}
public void componentMoved(ComponentEvent e) {
x = frame.getX();
y = frame.getY();
- enqueueEvent(com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_MOVED, null);
+ display.enqueueEvent(window, com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_MOVED, null);
}
public void componentShown(ComponentEvent e) {
@@ -360,10 +277,18 @@ public class AWTWindow extends Window {
}
class Listener implements ComponentListener, MouseListener, MouseMotionListener, KeyListener {
+ private AWTWindow window;
+ private AWTDisplay display;
+
+ public Listener(AWTWindow w) {
+ window = w;
+ display = (AWTDisplay)window.getScreen().getDisplay();
+ }
+
public void componentResized(ComponentEvent e) {
width = canvas.getWidth();
height = canvas.getHeight();
- enqueueEvent(com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_RESIZED, null);
+ display.enqueueEvent(window, com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_RESIZED, null);
}
public void componentMoved(ComponentEvent e) {
@@ -381,49 +306,57 @@ public class AWTWindow extends Window {
}
public void mouseEntered(MouseEvent e) {
- enqueueEvent(com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_ENTERED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_ENTERED, e);
}
public void mouseExited(MouseEvent e) {
- enqueueEvent(com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_EXITED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_EXITED, e);
}
public void mousePressed(MouseEvent e) {
- enqueueEvent(com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_PRESSED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_PRESSED, e);
}
public void mouseReleased(MouseEvent e) {
- enqueueEvent(com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_RELEASED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_RELEASED, e);
}
public void mouseMoved(MouseEvent e) {
- enqueueEvent(com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_MOVED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_MOVED, e);
}
public void mouseDragged(MouseEvent e) {
- enqueueEvent(com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_DRAGGED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.MouseEvent.EVENT_MOUSE_DRAGGED, e);
}
public void keyPressed(KeyEvent e) {
- enqueueEvent(com.sun.javafx.newt.KeyEvent.EVENT_KEY_PRESSED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.KeyEvent.EVENT_KEY_PRESSED, e);
}
public void keyReleased(KeyEvent e) {
- enqueueEvent(com.sun.javafx.newt.KeyEvent.EVENT_KEY_RELEASED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.KeyEvent.EVENT_KEY_RELEASED, e);
}
public void keyTyped(KeyEvent e) {
- enqueueEvent(com.sun.javafx.newt.KeyEvent.EVENT_KEY_TYPED, e);
+ display.enqueueEvent(window, com.sun.javafx.newt.KeyEvent.EVENT_KEY_TYPED, e);
}
}
class WindowEventListener implements WindowListener {
+ private AWTWindow window;
+ private AWTDisplay display;
+
+ public WindowEventListener(AWTWindow w) {
+ window = w;
+ display = (AWTDisplay)window.getScreen().getDisplay();
+ }
+
public void windowActivated(WindowEvent e) {
}
public void windowClosed(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
- enqueueEvent(com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY, null);
+ display.enqueueEvent(window, com.sun.javafx.newt.WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY, null);
}
public void windowDeactivated(WindowEvent e) {
}
diff --git a/src/newt/classes/com/sun/javafx/newt/macosx/MacDisplay.java b/src/newt/classes/com/sun/javafx/newt/macosx/MacDisplay.java
index 29b7151f4..63b7fe78c 100755
--- a/src/newt/classes/com/sun/javafx/newt/macosx/MacDisplay.java
+++ b/src/newt/classes/com/sun/javafx/newt/macosx/MacDisplay.java
@@ -33,17 +33,55 @@
package com.sun.javafx.newt.macosx;
-import com.sun.javafx.newt.*;
import javax.media.nativewindow.*;
import javax.media.nativewindow.macosx.*;
+import com.sun.javafx.newt.*;
+import com.sun.javafx.newt.impl.*;
+import com.sun.javafx.newt.util.MainThread;
public class MacDisplay extends Display {
+ static {
+ initSingleton();
+ }
+
+ private static volatile boolean isInit = false;
+
+ public static synchronized void initSingleton() {
+ if(isInit) return;
+ isInit=true;
+
+ NativeLibLoader.loadNEWT();
+
+ if(!initNSApplication()) {
+ throw new NativeWindowException("Failed to initialize native Application hook");
+ }
+ if(!MacWindow.initIDs()) {
+ throw new NativeWindowException("Failed to initialize jmethodIDs");
+ }
+ if(DEBUG) System.out.println("MacDisplay.init App and IDs OK "+Thread.currentThread().getName());
+ }
+
public MacDisplay() {
}
+ class DispatchAction implements Runnable {
+ public void run() {
+ dispatchMessages0();
+ }
+ }
+ private DispatchAction dispatchAction = new DispatchAction();
+
+ public void dispatchMessages() {
+ MainThread.invoke(false, dispatchAction);
+ }
+
protected void createNative() {
aDevice = new MacOSXGraphicsDevice();
}
protected void closeNative() { }
+
+ private static native boolean initNSApplication();
+ protected native void dispatchMessages0();
}
+
diff --git a/src/newt/classes/com/sun/javafx/newt/macosx/MacScreen.java b/src/newt/classes/com/sun/javafx/newt/macosx/MacScreen.java
index 06ef8aacd..8983b8803 100755
--- a/src/newt/classes/com/sun/javafx/newt/macosx/MacScreen.java
+++ b/src/newt/classes/com/sun/javafx/newt/macosx/MacScreen.java
@@ -37,14 +37,20 @@ import com.sun.javafx.newt.*;
import javax.media.nativewindow.*;
public class MacScreen extends Screen {
+ static {
+ MacDisplay.initSingleton();
+ }
+
public MacScreen() {
- MacWindow.initSingleton();
}
protected void createNative(int index) {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), index);
- setScreenSize(MacWindow.getScreenWidth(getIndex()), MacWindow.getScreenHeight(getIndex()));
+ setScreenSize(getWidthImpl(getIndex()), getHeightImpl(getIndex()));
}
protected void closeNative() { }
+
+ private static native int getWidthImpl(int scrn_idx);
+ private static native int getHeightImpl(int scrn_idx);
}
diff --git a/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java b/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java
index 2c1ca7c89..704b578c4 100755
--- a/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java
+++ b/src/newt/classes/com/sun/javafx/newt/macosx/MacWindow.java
@@ -41,8 +41,6 @@ import com.sun.javafx.newt.impl.*;
public class MacWindow extends Window {
- private static native boolean initIDs();
-
// Window styles
private static final int NSBorderlessWindowMask = 0;
private static final int NSTitledWindowMask = 1 << 0;
@@ -129,31 +127,14 @@ public class MacWindow extends Window {
private static final int NSHelpFunctionKey = 0xF746;
private static final int NSModeSwitchFunctionKey = 0xF747;
- // sync the MacOSX resources .. NSView, ie toggle fullscreen, window create
- private Object nsViewLock = new Object();
-
private volatile long surfaceHandle;
// non fullscreen dimensions ..
private int nfs_width, nfs_height, nfs_x, nfs_y;
static {
- initSingleton();
+ MacDisplay.initSingleton();
}
- private static volatile boolean isInit = false;
-
- public static synchronized void initSingleton() {
- if(isInit) return;
- isInit=true;
-
- NativeLibLoader.loadNEWT();
-
- if(!initIDs()) {
- throw new NativeWindowException("Failed to initialize jmethodIDs");
- }
- if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.initIDs OK "+Thread.currentThread().getName());
- }
-
public MacWindow() {
}
@@ -166,12 +147,15 @@ public class MacWindow extends Window {
class CloseAction implements Runnable {
public void run() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.CloseAction "+Thread.currentThread().getName());
if (windowHandle != 0) {
close0(windowHandle);
windowHandle = 0;
}
+ } finally {
+ nsViewLock.unlock();
}
}
}
@@ -182,20 +166,70 @@ public class MacWindow extends Window {
}
public long getWindowHandle() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
return windowHandle;
+ } finally {
+ nsViewLock.unlock();
}
}
public long getSurfaceHandle() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
return surfaceHandle;
+ } finally {
+ nsViewLock.unlock();
}
}
+ private ToolkitLock nsViewLock = new ToolkitLock() {
+ private Thread owner;
+ private int recursionCount;
+
+ public synchronized void lock() {
+ Thread cur = Thread.currentThread();
+ if (owner == cur) {
+ ++recursionCount;
+ return;
+ }
+ while (owner != null) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ owner = cur;
+ }
+
+ public synchronized void unlock() {
+ if (owner != Thread.currentThread()) {
+ throw new RuntimeException("Not owner");
+ }
+ if (recursionCount > 0) {
+ --recursionCount;
+ return;
+ }
+ owner = null;
+ notifyAll();
+ }
+ };
+
+ public synchronized int lockSurface() throws NativeWindowException {
+ nsViewLock.lock();
+ return super.lockSurface();
+ }
+
+ public void unlockSurface() {
+ super.unlockSurface();
+ nsViewLock.unlock();
+ }
+
class VisibleAction implements Runnable {
public void run() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.VisibleAction "+visible+" "+Thread.currentThread().getName());
if (visible) {
createWindow(false);
@@ -204,6 +238,8 @@ public class MacWindow extends Window {
orderOut(windowHandle);
}
}
+ } finally {
+ nsViewLock.unlock();
}
}
}
@@ -216,10 +252,13 @@ public class MacWindow extends Window {
class TitleAction implements Runnable {
public void run() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
if (windowHandle != 0) {
setTitle0(windowHandle, title);
}
+ } finally {
+ nsViewLock.unlock();
}
}
}
@@ -232,10 +271,13 @@ public class MacWindow extends Window {
class FocusAction implements Runnable {
public void run() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
if (windowHandle != 0) {
makeKey(windowHandle);
}
+ } finally {
+ nsViewLock.unlock();
}
}
}
@@ -248,10 +290,13 @@ public class MacWindow extends Window {
class SizeAction implements Runnable {
public void run() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
if (windowHandle != 0) {
setContentSize(windowHandle, width, height);
}
+ } finally {
+ nsViewLock.unlock();
}
}
}
@@ -269,10 +314,13 @@ public class MacWindow extends Window {
class PositionAction implements Runnable {
public void run() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
if (windowHandle != 0) {
setFrameTopLeftPoint(windowHandle, x, y);
}
+ } finally {
+ nsViewLock.unlock();
}
}
}
@@ -288,26 +336,16 @@ public class MacWindow extends Window {
MainThread.invoke(true, positionAction);
}
- class DispatchAction implements Runnable {
- public void run() {
- dispatchMessages0(windowHandle, eventMask);
- }
- }
- private DispatchAction dispatchAction = new DispatchAction();
- private int eventMask;
-
- public void dispatchMessages(int eventMask) {
- this.eventMask=eventMask;
- MainThread.invoke(false, dispatchAction);
- }
-
class FullscreenAction implements Runnable {
public void run() {
- synchronized(nsViewLock) {
+ nsViewLock.lock();
+ try {
if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) {
System.err.println("MacWindow fs: "+fullscreen+" "+x+"/"+y+" "+width+"x"+height);
}
createWindow(true);
+ } finally {
+ nsViewLock.unlock();
}
}
}
@@ -495,6 +533,7 @@ public class MacWindow extends Window {
sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS);
}
+ protected static native boolean initIDs();
private native long createWindow0(int x, int y, int w, int h,
boolean fullscreen, int windowStyle,
int backingStoreType,
@@ -504,11 +543,8 @@ public class MacWindow extends Window {
private native void orderOut(long window);
private native void close0(long window);
private native void setTitle0(long window, String title);
- protected native void dispatchMessages0(long window, int eventMask);
private native long contentView(long window);
private native long changeContentView(long window, long view);
private native void setContentSize(long window, int w, int h);
private native void setFrameTopLeftPoint(long window, int x, int y);
- protected static native int getScreenWidth(int scrn_idx);
- protected static native int getScreenHeight(int scrn_idx);
}
diff --git a/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java b/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java
index 5d50792db..8ecfe6216 100644
--- a/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java
+++ b/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java
@@ -37,6 +37,7 @@ import com.sun.javafx.newt.*;
import javax.media.nativewindow.*;
import javax.media.opengl.*;
import com.sun.opengl.impl.GLDrawableHelper;
+import java.util.*;
/**
* An implementation of {@link Window} which is customized for OpenGL
@@ -44,13 +45,20 @@ import com.sun.opengl.impl.GLDrawableHelper;
* javax.media.opengl.GLAutoDrawable} interface. For convenience, this
* window class guarantees that its OpenGL context is current inside
* the various EventListeners' callbacks (MouseListener, KeyListener,
- * etc.).
+ * etc.).<P>
+ *
+ * Best performance is currently achieved with default settings,
+ * {@link #setEventHandlerMode} to {@link #EVENT_HANDLER_GL_NONE}
+ * and one thread per GLWindow. To ensure compatibility with the
+ * underlying platform, window shall also be created within your
+ * working thread. See comment at {@link #setRunPumpMessages}.
*/
public class GLWindow extends Window implements GLAutoDrawable {
/**
* Event handling mode: EVENT_HANDLER_GL_NONE.
* No GL context is current, while calling the EventListener.
* This might be inconvenient, but don't impact the performance.
+ * Also
*
* @see com.sun.javafx.newt.GLWindow#setEventHandlerMode(int)
*/
@@ -68,7 +76,10 @@ public class GLWindow extends Window implements GLAutoDrawable {
*/
public static final int EVENT_HANDLER_GL_CURRENT = (1 << 0);
+ private static List/*GLWindow*/ glwindows = new ArrayList();
+
private Window window;
+ private boolean runPumpMessages = true;
/** Constructor. Do not call this directly -- use {@link
create()} instead. */
@@ -94,6 +105,10 @@ public class GLWindow extends Window implements GLAutoDrawable {
sendDestroy = true;
}
});
+
+ List newglw = (List) ((ArrayList) glwindows).clone();
+ newglw.add(this);
+ glwindows=newglw;
}
/** Creates a new GLWindow on the local display, screen 0, with a
@@ -132,10 +147,11 @@ public class GLWindow extends Window implements GLAutoDrawable {
caps = new GLCapabilities(null); // default ..
}
+ Display display;
boolean ownerOfDisplayAndScreen=false;
if (window == null) {
ownerOfDisplayAndScreen = true;
- Display display = NewtFactory.createDisplay(null); // local display
+ display = NewtFactory.createDisplay(null); // local display
Screen screen = NewtFactory.createScreen(display, 0); // screen 0
window = NewtFactory.createWindow(screen, caps, undecorated);
}
@@ -143,6 +159,24 @@ public class GLWindow extends Window implements GLAutoDrawable {
return new GLWindow(window, ownerOfDisplayAndScreen);
}
+ /**
+ * EXPERIMENTAL<br>
+ * Enable or disables running the {@link Display#pumpMessages} in the {@link #display()} call.<br>
+ * The default behavior is to run {@link Display#pumpMessages}.<P>
+ *
+ * The idea was that in a single threaded environment with one {@link Display} and many {@link Window}'s,
+ * a performance benefit was expected while disabling the implicit {@link Display#pumpMessages} and
+ * do it once via {@link GLWindow#runCurrentThreadPumpMessage()} <br>
+ * This could not have been verified. No measurable difference could have been recognized.<P>
+ *
+ * Best performance has been achieved with one GLWindow per thread.<br>
+ *
+ * @deprecated EXPERIMENTAL, semantic is about to be removed after further verification.
+ */
+ public void setRunPumpMessages(boolean onoff) {
+ runPumpMessages = onoff;
+ }
+
protected void createNative(Capabilities caps) {
shouldNotCallThis();
}
@@ -202,6 +236,10 @@ public class GLWindow extends Window implements GLAutoDrawable {
e1.printStackTrace();
}
+ List newglw = (List) ((ArrayList) glwindows).clone();
+ newglw.remove(this);
+ glwindows=newglw;
+
dispose(false);
Screen _screen = null;
@@ -251,57 +289,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
public int getEventHandlerMode() {
return eventHandlerMode;
}
-
- public void pumpMessages(int eventMask) {
- if( 0 == (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
- window.pumpMessages(eventMask);
- } else {
- pumpMessagesWithEventMaskAction.eventMask = eventMask;
- pumpMessagesImpl(pumpMessagesWithEventMaskAction);
- }
- }
-
- public void pumpMessages() {
- if( 0 == (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
- window.pumpMessages();
- } else {
- pumpMessagesImpl(pumpMessagesAction);
- }
- }
-
- class PumpMessagesWithEventMaskAction implements Runnable {
- private int eventMask;
-
- public void run() {
- window.pumpMessages(eventMask);
- }
- }
- private PumpMessagesWithEventMaskAction pumpMessagesWithEventMaskAction = new PumpMessagesWithEventMaskAction();
-
- class PumpMessagesAction implements Runnable {
- public void run() {
- window.pumpMessages();
- }
- }
- private PumpMessagesAction pumpMessagesAction = new PumpMessagesAction();
-
- private void pumpMessagesImpl(Runnable pumpMessagesAction) {
- // pumpMessagesAction.run();
-
- boolean autoSwapBuffer = helper.getAutoSwapBufferMode();
- helper.setAutoSwapBufferMode(false);
- try {
- helper.invokeGL(drawable, context, pumpMessagesAction, initAction);
- } finally {
- helper.setAutoSwapBufferMode(autoSwapBuffer);
- }
-
- }
-
- protected void dispatchMessages(int eventMask) {
- shouldNotCallThis();
- }
-
+
public void setVisible(boolean visible) {
window.setVisible(visible);
if (visible && context == null) {
@@ -423,7 +411,8 @@ public class GLWindow extends Window implements GLAutoDrawable {
// OpenGL-related methods and state
//
- private int eventHandlerMode = EVENT_HANDLER_GL_CURRENT;
+ private static int eventHandlerMode = EVENT_HANDLER_GL_CURRENT;
+ private static boolean autoSwapBufferMode = true;
private GLDrawableFactory factory;
private GLDrawable drawable;
private GLContext context;
@@ -466,9 +455,69 @@ public class GLWindow extends Window implements GLAutoDrawable {
helper.removeGLEventListener(listener);
}
+ class DisplayPumpMessage implements Display.Action {
+ public void run(Display display) {
+ if( 0 == (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
+ display.run();
+ } else {
+ helper.setAutoSwapBufferMode(false);
+ try {
+ helper.invokeGL(drawable, context, display, initAction);
+ } finally {
+ helper.setAutoSwapBufferMode(autoSwapBufferMode);
+ }
+ }
+ }
+ }
+ private DisplayPumpMessage displayPumpMessage = new DisplayPumpMessage();
+
+ static class DisplayPumpMessageStatic implements Display.Action {
+ public void run(Display display) {
+ display.run();
+ }
+ }
+ private static DisplayPumpMessageStatic displayPumpMessageStatic = new DisplayPumpMessageStatic();
+
+ /**
+ * @see #setRunPumpMessages
+ * @deprecated EXPERIMENTAL, semantic is about to be removed after further verification.
+ */
+ public static void runCurrentThreadPumpMessage() {
+ Exception safedE = null;
+
+ if( 0 != (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
+ // for all: setup / init / makeCurrent
+ for(Iterator i = glwindows.iterator(); i.hasNext(); ) {
+ GLWindow glw = (GLWindow) i.next();
+ glw.helper.setAutoSwapBufferMode(false);
+ glw.helper.invokeGL(glw.drawable, glw.context, null, glw.initAction);
+ }
+ }
+
+ try {
+ Display.runCurrentThreadDisplaysAction(displayPumpMessageStatic);
+ } catch (Exception e) {
+ safedE=e;
+ }
+
+ if( 0 != (eventHandlerMode & EVENT_HANDLER_GL_CURRENT) ) {
+ // for all: reset
+ for(Iterator i = glwindows.iterator(); i.hasNext(); ) {
+ GLWindow glw = (GLWindow) i.next();
+ glw.helper.setAutoSwapBufferMode(autoSwapBufferMode);
+ }
+ }
+
+ if(null!=safedE) {
+ throw new GLException(safedE);
+ }
+ }
+
public void display() {
if(getSurfaceHandle()!=0) {
- pumpMessages();
+ if(runPumpMessages) {
+ displayPumpMessage.run(window.getScreen().getDisplay());
+ }
if(window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED) {
dispose(true);
}
@@ -487,12 +536,14 @@ public class GLWindow extends Window implements GLAutoDrawable {
}
}
+ /** This implementation uses a static value */
public void setAutoSwapBufferMode(boolean onOrOff) {
- helper.setAutoSwapBufferMode(onOrOff);
+ autoSwapBufferMode = onOrOff;
}
+ /** This implementation uses a static value */
public boolean getAutoSwapBufferMode() {
- return helper.getAutoSwapBufferMode();
+ return autoSwapBufferMode;
}
public void swapBuffers() {
@@ -555,6 +606,7 @@ public class GLWindow extends Window implements GLAutoDrawable {
}
}
}
+ private DisplayAction displayAction = new DisplayAction();
public long getStartTime() { return startTime; }
public long getCurrentTime() { return curTime; }
@@ -567,14 +619,11 @@ public class GLWindow extends Window implements GLAutoDrawable {
private int totalFrames = 0, lastFrames = 0;
private boolean ownerOfDisplayAndScreen;
- private DisplayAction displayAction = new DisplayAction();
-
class SwapBuffersAction implements Runnable {
public void run() {
drawable.swapBuffers();
}
}
-
private SwapBuffersAction swapBuffersAction = new SwapBuffersAction();
//----------------------------------------------------------------------
diff --git a/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDDisplay.java b/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDDisplay.java
index a13a95586..64d640d11 100755
--- a/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDDisplay.java
+++ b/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDDisplay.java
@@ -40,10 +40,25 @@ import javax.media.nativewindow.*;
import javax.media.nativewindow.egl.*;
public class KDDisplay extends Display {
+
static {
+ initSingleton();
+ }
+
+ private static volatile boolean isInit = false;
+
+ public static synchronized void initSingleton() {
+ if(isInit) return;
+ isInit=true;
+
NativeLibLoader.loadNEWT();
+
+ if (!KDWindow.initIDs()) {
+ throw new NativeWindowException("Failed to initialize KDWindow jmethodIDs");
+ }
}
+
public KDDisplay() {
}
@@ -64,5 +79,11 @@ public class KDDisplay extends Display {
EGL.eglTerminate(aDevice.getHandle());
}
}
+
+ protected void dispatchMessages() {
+ DispatchMessages();
+ }
+
+ private native void DispatchMessages();
}
diff --git a/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDScreen.java b/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDScreen.java
index 752a55752..1767c1240 100755
--- a/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDScreen.java
+++ b/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDScreen.java
@@ -37,6 +37,10 @@ import com.sun.javafx.newt.*;
import javax.media.nativewindow.*;
public class KDScreen extends Screen {
+ static {
+ KDDisplay.initSingleton();
+ }
+
public KDScreen() {
}
diff --git a/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDWindow.java b/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDWindow.java
index 587bf185e..df0134c8e 100755
--- a/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDWindow.java
+++ b/src/newt/classes/com/sun/javafx/newt/opengl/kd/KDWindow.java
@@ -47,11 +47,7 @@ public class KDWindow extends Window {
private int nfs_width, nfs_height, nfs_x, nfs_y;
static {
- NativeLibLoader.loadNEWT();
-
- if (!initIDs()) {
- throw new NativeWindowException("Failed to initialize jmethodIDs");
- }
+ KDDisplay.initSingleton();
}
public KDWindow() {
@@ -67,8 +63,7 @@ public class KDWindow extends Window {
int[] eglAttribs = EGLGraphicsConfiguration.GLCapabilities2AttribList(eglCaps, EGL.EGL_WINDOW_BIT);
windowHandle = 0;
- windowID = ++_windowID;
- eglWindowHandle = CreateWindow(windowID, getDisplayHandle(), eglAttribs);
+ eglWindowHandle = CreateWindow(getDisplayHandle(), eglAttribs);
if (eglWindowHandle == 0) {
throw new NativeWindowException("Error creating egl window: "+config);
}
@@ -78,7 +73,8 @@ public class KDWindow extends Window {
protected void closeNative() {
if(0!=windowHandleClose) {
- CloseWindow(windowHandleClose);
+ CloseWindow(windowHandleClose, windowUserData);
+ windowUserData=0;
}
}
@@ -118,22 +114,21 @@ public class KDWindow extends Window {
return true;
}
- protected void dispatchMessages(int eventMask) {
- DispatchMessages(windowID, eglWindowHandle, eventMask);
- }
-
//----------------------------------------------------------------------
// Internals only
//
- private static native boolean initIDs();
- private native long CreateWindow(int owner, long displayHandle, int[] attributes);
+ protected static native boolean initIDs();
+ private native long CreateWindow(long displayHandle, int[] attributes);
private native long RealizeWindow(long eglWindowHandle);
- private native int CloseWindow(long eglWindowHandle);
+ private native int CloseWindow(long eglWindowHandle, long userData);
private native void setVisible0(long eglWindowHandle, boolean visible);
private native void setSize0(long eglWindowHandle, int width, int height);
private native void setFullScreen0(long eglWindowHandle, boolean fullscreen);
- private native void DispatchMessages(int owner, long eglWindowHandle, int eventMask);
+
+ private void windowCreated(long userData) {
+ windowUserData=userData;
+ }
private void sizeChanged(int newWidth, int newHeight) {
width = newWidth;
@@ -149,6 +144,5 @@ public class KDWindow extends Window {
private long eglWindowHandle;
private long windowHandleClose;
- private int windowID;
- private static int _windowID = 0;
+ private long windowUserData;
}
diff --git a/src/newt/classes/com/sun/javafx/newt/util/MainThread.java b/src/newt/classes/com/sun/javafx/newt/util/MainThread.java
index 01604476d..bb3718a83 100644
--- a/src/newt/classes/com/sun/javafx/newt/util/MainThread.java
+++ b/src/newt/classes/com/sun/javafx/newt/util/MainThread.java
@@ -44,7 +44,7 @@ import javax.media.nativewindow.*;
import com.sun.javafx.newt.*;
import com.sun.javafx.newt.impl.*;
-import com.sun.javafx.newt.macosx.MacWindow;
+import com.sun.javafx.newt.macosx.MacDisplay;
import com.sun.nativewindow.impl.NWReflection;
/**
@@ -167,7 +167,7 @@ public class MainThread {
mainAction = new MainAction(mainClassName, mainClassArgs);
if(NativeWindowFactory.getNativeWindowType(false)==NativeWindowFactory.TYPE_MACOSX) {
- MacWindow.initSingleton();
+ MacDisplay.initSingleton();
}
if ( USE_MAIN_THREAD ) {
diff --git a/src/newt/classes/com/sun/javafx/newt/windows/WindowsDisplay.java b/src/newt/classes/com/sun/javafx/newt/windows/WindowsDisplay.java
index 436101a35..975281c95 100755
--- a/src/newt/classes/com/sun/javafx/newt/windows/WindowsDisplay.java
+++ b/src/newt/classes/com/sun/javafx/newt/windows/WindowsDisplay.java
@@ -33,11 +33,35 @@
package com.sun.javafx.newt.windows;
-import com.sun.javafx.newt.*;
import javax.media.nativewindow.*;
import javax.media.nativewindow.windows.*;
+import com.sun.javafx.newt.*;
+import com.sun.javafx.newt.impl.*;
public class WindowsDisplay extends Display {
+
+ protected static final String WINDOW_CLASS_NAME = "NewtWindowClass";
+ private static int windowClassAtom;
+ private static long hInstance;
+
+ static {
+ initSingleton();
+ }
+
+ private static volatile boolean isInit = false;
+
+ public static synchronized void initSingleton() {
+ if(isInit) return;
+ isInit=true;
+
+ NativeLibLoader.loadNEWT();
+
+ if (!WindowsWindow.initIDs()) {
+ throw new NativeWindowException("Failed to initialize WindowsWindow jmethodIDs");
+ }
+ }
+
+
public WindowsDisplay() {
}
@@ -45,5 +69,42 @@ public class WindowsDisplay extends Display {
aDevice = new WindowsGraphicsDevice();
}
- protected void closeNative() { }
+ protected void closeNative() {
+ // Can't do .. only at application shutdown
+ // UnregisterWindowClass(getWindowClassAtom(), getHInstance());
+ }
+
+ protected void dispatchMessages() {
+ DispatchMessages();
+ }
+
+ protected static synchronized int getWindowClassAtom() {
+ if(0 == windowClassAtom) {
+ windowClassAtom = RegisterWindowClass(WINDOW_CLASS_NAME, getHInstance());
+ if (0 == windowClassAtom) {
+ throw new NativeWindowException("Error while registering window class");
+ }
+ }
+ return windowClassAtom;
+ }
+
+ protected static synchronized long getHInstance() {
+ if(0 == hInstance) {
+ hInstance = LoadLibraryW("newt");
+ if (0 == hInstance) {
+ throw new NativeWindowException("Error finding HINSTANCE for \"newt\"");
+ }
+ }
+ return hInstance;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only
+ //
+ private static native long LoadLibraryW(String libraryName);
+ private static native int RegisterWindowClass(String windowClassName, long hInstance);
+ private static native void UnregisterWindowClass(int wndClassAtom, long hInstance);
+
+ private static native void DispatchMessages();
}
+
diff --git a/src/newt/classes/com/sun/javafx/newt/windows/WindowsScreen.java b/src/newt/classes/com/sun/javafx/newt/windows/WindowsScreen.java
index 828cf4ca0..87ae1b49d 100755
--- a/src/newt/classes/com/sun/javafx/newt/windows/WindowsScreen.java
+++ b/src/newt/classes/com/sun/javafx/newt/windows/WindowsScreen.java
@@ -39,19 +39,20 @@ import javax.media.nativewindow.*;
public class WindowsScreen extends Screen {
static {
- NativeLibLoader.loadNEWT();
+ WindowsDisplay.initSingleton();
}
+
public WindowsScreen() {
}
protected void createNative(int index) {
aScreen = new DefaultGraphicsScreen(getDisplay().getGraphicsDevice(), index);
- setScreenSize(getScreenWidth(getIndex()), getScreenHeight(getIndex()));
+ setScreenSize(getWidthImpl(getIndex()), getHeightImpl(getIndex()));
}
protected void closeNative() { }
- private native int getScreenWidth(int scrn_idx);
- private native int getScreenHeight(int scrn_idx);
+ private native int getWidthImpl(int scrn_idx);
+ private native int getHeightImpl(int scrn_idx);
}
diff --git a/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java b/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java
index 273be6653..c42aaa6d9 100755
--- a/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java
+++ b/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java
@@ -47,11 +47,7 @@ public class WindowsWindow extends Window {
private int nfs_width, nfs_height, nfs_x, nfs_y;
static {
- NativeLibLoader.loadNEWT();
-
- if (!initIDs()) {
- throw new NativeWindowException("Failed to initialize jmethodIDs");
- }
+ WindowsDisplay.initSingleton();
}
public WindowsWindow() {
@@ -96,11 +92,13 @@ public class WindowsWindow extends Window {
}
protected void createNative(Capabilities caps) {
- config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen());
+ WindowsScreen screen = (WindowsScreen) getScreen();
+ WindowsDisplay display = (WindowsDisplay) screen.getDisplay();
+ config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, screen.getGraphicsScreen());
if (config == null) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
- windowHandle = CreateWindow(getWindowClassAtom(), WINDOW_CLASS_NAME, getHInstance(), 0, undecorated, x, y, width, height);
+ windowHandle = CreateWindow(display.getWindowClassAtom(), display.WINDOW_CLASS_NAME, display.getHInstance(), 0, undecorated, x, y, width, height);
if (windowHandle == 0) {
throw new NativeWindowException("Error creating window");
}
@@ -121,7 +119,6 @@ public class WindowsWindow extends Window {
}
protected void windowDestroyed() {
- // singleton ATOM CleanupWindowResources(getWindowClassAtom(), getHInstance());
windowHandleClose = 0;
super.windowDestroyed();
}
@@ -200,50 +197,19 @@ public class WindowsWindow extends Window {
}
}
- protected void dispatchMessages(int eventMask) {
- DispatchMessages(windowHandle, eventMask);
- }
-
//----------------------------------------------------------------------
// Internals only
//
- private static final String WINDOW_CLASS_NAME = "NewtWindowClass";
-
- private static int windowClassAtom = 0;
- private static synchronized int getWindowClassAtom() {
- if(0 == windowClassAtom) {
- windowClassAtom = RegisterWindowClass(WINDOW_CLASS_NAME, getHInstance());
- if (windowClassAtom == 0) {
- throw new NativeWindowException("Error while registering window class");
- }
- }
- return windowClassAtom;
- }
- private static long hInstance;
- private static synchronized long getHInstance() {
- if (hInstance == 0) {
- hInstance = LoadLibraryW("newt");
- if (hInstance == 0) {
- throw new NativeWindowException("Error finding HINSTANCE for \"newt\"");
- }
- }
- return hInstance;
- }
-
- private static native boolean initIDs();
- private static native long LoadLibraryW(String libraryName);
- private static native int RegisterWindowClass(String windowClassName, long hInstance);
+ protected static native boolean initIDs();
private native long CreateWindow(int wndClassAtom, String wndName,
long hInstance, long visualID,
boolean isUndecorated,
int x, int y, int width, int height);
- private native void CleanupWindowResources(int wndClassAtom, long hInstance);
private native void DestroyWindow(long windowHandle);
private native long GetDC(long windowHandle);
private native void ReleaseDC(long windowHandle, long hdc);
private native long MonitorFromWindow(long windowHandle);
private static native void setVisible0(long windowHandle, boolean visible);
- private static native void DispatchMessages(long windowHandle, int eventMask);
private native void setSize0(long windowHandle, int width, int height);
private native void setPosition(long windowHandle, int x, int y);
private native void setFullscreen0(long windowHandle, int x, int y, int width, int height, boolean isUndecorated, boolean on);
diff --git a/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java b/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java
index 2371b20e8..99c0f599c 100755
--- a/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java
+++ b/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java
@@ -40,25 +40,65 @@ import javax.media.nativewindow.x11.*;
public class X11Display extends Display {
static {
+ initSingleton();
+ }
+
+ private static volatile boolean isInit = false;
+
+ public static synchronized void initSingleton() {
+ if(isInit) return;
+ isInit=true;
+
NativeLibLoader.loadNEWT();
+
+ if (!initIDs()) {
+ throw new NativeWindowException("Failed to initialize X11Display jmethodIDs");
+ }
+
+ if (!X11Window.initIDs()) {
+ throw new NativeWindowException("Failed to initialize X11Window jmethodIDs");
+ }
}
+
public X11Display() {
}
protected void createNative() {
- long handle = CreateDisplay(name);
+ long handle= CreateDisplay(name);
if (handle == 0 ) {
throw new RuntimeException("Error creating display: "+name);
}
aDevice = new X11GraphicsDevice(handle);
}
- protected void closeNative() { }
+ protected void closeNative() {
+ DestroyDisplay(getHandle());
+ }
+
+ protected void dispatchMessages() {
+ DispatchMessages(getHandle(), javaObjectAtom, windowDeleteAtom);
+ }
+
+ protected long getJavaObjectAtom() { return javaObjectAtom; }
+ protected long getWindowDeleteAtom() { return windowDeleteAtom; }
//----------------------------------------------------------------------
// Internals only
//
+ private static native boolean initIDs();
private native long CreateDisplay(String name);
+ private native void DestroyDisplay(long handle);
+
+ private native void DispatchMessages(long display, long javaObjectAtom, long windowDeleteAtom);
+
+ private void displayCreated(long javaObjectAtom, long windowDeleteAtom) {
+ this.javaObjectAtom=javaObjectAtom;
+ this.windowDeleteAtom=windowDeleteAtom;
+ }
+
+ private long windowDeleteAtom;
+ private long javaObjectAtom;
}
+
diff --git a/src/newt/classes/com/sun/javafx/newt/x11/X11Screen.java b/src/newt/classes/com/sun/javafx/newt/x11/X11Screen.java
index 36d9d8baf..cee576e2c 100755
--- a/src/newt/classes/com/sun/javafx/newt/x11/X11Screen.java
+++ b/src/newt/classes/com/sun/javafx/newt/x11/X11Screen.java
@@ -39,10 +39,12 @@ import javax.media.nativewindow.*;
import javax.media.nativewindow.x11.*;
public class X11Screen extends Screen {
+
static {
- NativeLibLoader.loadNEWT();
+ X11Display.initSingleton();
}
+
public X11Screen() {
}
diff --git a/src/newt/classes/com/sun/javafx/newt/x11/X11Window.java b/src/newt/classes/com/sun/javafx/newt/x11/X11Window.java
index 3badcce16..bd6bb42c2 100755
--- a/src/newt/classes/com/sun/javafx/newt/x11/X11Window.java
+++ b/src/newt/classes/com/sun/javafx/newt/x11/X11Window.java
@@ -44,34 +44,34 @@ public class X11Window extends Window {
private int nfs_width, nfs_height, nfs_x, nfs_y;
static {
- NativeLibLoader.loadNEWT();
-
- if (!initIDs()) {
- throw new NativeWindowException("Failed to initialize jmethodIDs");
- }
+ X11Display.initSingleton();
}
public X11Window() {
}
protected void createNative(Capabilities caps) {
- config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen());
+ X11Screen screen = (X11Screen) getScreen();
+ X11Display display = (X11Display) screen.getDisplay();
+ config = GraphicsConfigurationFactory.getFactory(display.getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, screen.getGraphicsScreen());
if (config == null) {
throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this);
}
X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config;
long visualID = x11config.getVisualID();
- long w = CreateWindow(getDisplayHandle(), getScreenIndex(), visualID, x, y, width, height);
+ long w = CreateWindow(display.getHandle(), screen.getIndex(), visualID,
+ display.getJavaObjectAtom(), display.getWindowDeleteAtom(), x, y, width, height);
if (w == 0 || w!=windowHandle) {
throw new NativeWindowException("Error creating window: "+w);
}
windowHandleClose = windowHandle;
- displayHandleClose = getDisplayHandle();
+ displayHandleClose = display.getHandle();
}
protected void closeNative() {
if(0!=displayHandleClose && 0!=windowHandleClose) {
- CloseWindow(displayHandleClose, windowHandleClose);
+ X11Display display = (X11Display) getScreen().getDisplay();
+ CloseWindow(displayHandleClose, windowHandleClose, display.getJavaObjectAtom());
windowHandleClose = 0;
displayHandleClose = 0;
}
@@ -91,6 +91,10 @@ public class X11Window extends Window {
}
}
+ public void requestFocus() {
+ super.requestFocus();
+ }
+
public void setSize(int width, int height) {
if(!fullscreen) {
nfs_width=width;
@@ -129,20 +133,15 @@ public class X11Window extends Window {
return fullscreen;
}
- protected void dispatchMessages(int eventMask) {
- DispatchMessages(getDisplayHandle(), windowHandle, eventMask, windowDeleteAtom);
- }
-
//----------------------------------------------------------------------
// Internals only
//
- private static native boolean initIDs();
+ protected static native boolean initIDs();
private native long CreateWindow(long display, int screen_index,
- long visualID, int x, int y, int width, int height);
- private native void CloseWindow(long display, long windowHandle);
+ long visualID, long javaObjectAtom, long windowDeleteAtom, int x, int y, int width, int height);
+ private native void CloseWindow(long display, long windowHandle, long javaObjectAtom);
private native void setVisible0(long display, long windowHandle, boolean visible);
- private native void DispatchMessages(long display, long windowHandle, int eventMask, long windowDeleteAtom);
private native void setSize0(long display, int screen_index, long windowHandle,
int x, int y, int width, int height, int decorationToggle, boolean isVisible);
private native void setPosition0(long display, long windowHandle, int x, int y);
@@ -167,12 +166,10 @@ public class X11Window extends Window {
sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED);
}
- private void windowCreated(long windowHandle, long windowDeleteAtom) {
+ private void windowCreated(long windowHandle) {
this.windowHandle = windowHandle;
- this.windowDeleteAtom=windowDeleteAtom;
}
private long windowHandleClose;
private long displayHandleClose;
- private long windowDeleteAtom;
}
diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c
index d08d5411c..682edff24 100755
--- a/src/newt/native/KDWindow.c
+++ b/src/newt/native/KDWindow.c
@@ -81,16 +81,121 @@
#endif
#endif
-/**
- * Window
- */
-
+#define JOGL_KD_USERDATA_MAGIC 0xDEADBEEF
+typedef struct {
+ long magic;
+ KDWindow * kdWindow;
+ jobject javaWindow;
+} JOGLKDUserdata;
+
+static jmethodID windowCreatedID = NULL;
static jmethodID sizeChangedID = NULL;
static jmethodID windowDestroyNotifyID = NULL;
static jmethodID windowDestroyedID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
+/**
+ * Display
+ */
+
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDDisplay_DispatchMessages
+ (JNIEnv *env, jobject obj)
+{
+ const KDEvent * evt;
+ int numEvents = 0;
+
+ // Periodically take a break
+ while( numEvents<100 && NULL!=(evt=kdWaitEvent(0)) ) {
+ KDWindow *kdWindow;
+ jobject javaWindow;
+ JOGLKDUserdata * userData = (JOGLKDUserdata *)(intptr_t)evt->userptr;
+ if(NULL == userData || userData->magic!=JOGL_KD_USERDATA_MAGIC) {
+ DBG_PRINT( "event unrelated: evt type: 0x%X\n", evt->type);
+ continue;
+ }
+ kdWindow = userData->kdWindow;
+ javaWindow = userData->javaWindow;
+ DBG_PRINT( "[DispatchMessages]: userData %p, evt type: 0x%X\n", userData, evt->type);
+
+ numEvents++;
+
+ // FIXME: support resize and window re-positioning events
+
+ switch(evt->type) {
+ case KD_EVENT_WINDOW_FOCUS:
+ {
+ KDboolean hasFocus;
+ kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_FOCUS, &hasFocus);
+ DBG_PRINT( "event window focus : src: %p\n", userData);
+ }
+ break;
+ case KD_EVENT_WINDOW_CLOSE:
+ {
+ DBG_PRINT( "event window close : src: %p\n", userData);
+ (*env)->CallVoidMethod(env, javaWindow, windowDestroyNotifyID);
+ // Called by Window.java: DestroyWindow(wnd);
+ // (*env)->CallVoidMethod(env, javaWindow, windowDestroyedID);
+ }
+ break;
+ case KD_EVENT_WINDOWPROPERTY_CHANGE:
+ {
+ const KDEventWindowProperty* prop = &evt->data.windowproperty;
+ switch (prop->pname) {
+ case KD_WINDOWPROPERTY_SIZE:
+ {
+ KDint32 v[2];
+ if(!kdGetWindowPropertyiv(kdWindow, KD_WINDOWPROPERTY_SIZE, v)) {
+ DBG_PRINT( "event window size change : src: %p %dx%d\n", userData, v[0], v[1]);
+ (*env)->CallVoidMethod(env, javaWindow, sizeChangedID, (jint) v[0], (jint) v[1]);
+ } else {
+ DBG_PRINT( "event window size change error: src: %p %dx%d\n", userData, v[0], v[1]);
+ }
+ }
+ break;
+ case KD_WINDOWPROPERTY_FOCUS:
+ DBG_PRINT( "event window focus: src: %p\n", userData);
+ break;
+ case KD_WINDOWPROPERTY_VISIBILITY:
+ {
+ KDboolean visible;
+ kdGetWindowPropertybv(kdWindow, KD_WINDOWPROPERTY_VISIBILITY, &visible);
+ DBG_PRINT( "event window visibility: src: %p, v:%d\n", userData, visible);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case KD_EVENT_INPUT_POINTER:
+ {
+ const KDEventInputPointer* ptr = &(evt->data.inputpointer);
+ // button idx: evt->data.input.index
+ // pressed = ev->data.input.value.i
+ // time = ev->timestamp
+ if(KD_INPUT_POINTER_SELECT==ptr->index) {
+ DBG_PRINT( "event mouse click: src: %p, s:%d, (%d,%d)\n", userData, ptr->select, ptr->x, ptr->y);
+ (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID,
+ (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED,
+ (jint) 0,
+ (jint) ptr->x, (jint) ptr->y, 1, 0);
+ } else {
+ DBG_PRINT( "event mouse: src: %d, s:%p, i:0x%X (%d,%d)\n", userData, ptr->select, ptr->index, ptr->x, ptr->y);
+ (*env)->CallVoidMethod(env, javaWindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
+ 0,
+ (jint) ptr->x, (jint) ptr->y, 0, 0);
+ }
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * Window
+ */
+
JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs
(JNIEnv *env, jclass clazz)
{
@@ -100,12 +205,14 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs
_wfreopen(TEXT(STDERR_FILE),L"w",stderr);
#endif
#endif
+ windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- if (sizeChangedID == NULL ||
+ if (windowCreatedID == NULL ||
+ sizeChangedID == NULL ||
windowDestroyNotifyID == NULL ||
windowDestroyedID == NULL ||
sendMouseEventID == NULL ||
@@ -118,15 +225,13 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_kd_KDWindow_initIDs
}
JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CreateWindow
- (JNIEnv *env, jobject obj, jint owner, jlong display, jintArray jAttrs)
+ (JNIEnv *env, jobject obj, jlong display, jintArray jAttrs)
{
jint * attrs = NULL;
jsize attrsLen;
EGLDisplay dpy = (EGLDisplay)(intptr_t)display;
KDWindow *window = 0;
- DBG_PRINT( "[CreateWindow]: owner %d\n", owner);
-
if(dpy==NULL) {
fprintf(stderr, "[CreateWindow] invalid display connection..\n");
return 0;
@@ -143,15 +248,21 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CreateWindow
return 0;
}
- /* passing the KDWindow instance for the eventuserptr */
- window = kdCreateWindow(dpy, attrs, (void *)(intptr_t)owner);
+ JOGLKDUserdata * userData = kdMalloc(sizeof(JOGLKDUserdata));
+ userData->magic = JOGL_KD_USERDATA_MAGIC;
+ window = kdCreateWindow(dpy, attrs, (void *)userData);
(*env)->ReleaseIntArrayElements(env, jAttrs, attrs, 0);
if(NULL==window) {
+ kdFree(userData);
fprintf(stderr, "[CreateWindow] failed: 0x%X\n", kdGetError());
+ } else {
+ userData->javaWindow = (*env)->NewGlobalRef(env, obj);
+ userData->kdWindow = window;
+ (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) (intptr_t) userData);
+ DBG_PRINT( "[CreateWindow] ok: %p, userdata %p\n", window, userData);
}
- DBG_PRINT( "[CreateWindow] ok: %p, owner %d\n", window, (void *)(intptr_t)owner);
return (jlong) (intptr_t) window;
}
@@ -171,10 +282,13 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_kd_KDWindow_RealizeWindow
}
JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_kd_KDWindow_CloseWindow
- (JNIEnv *env, jobject obj, jlong window)
+ (JNIEnv *env, jobject obj, jlong window, jlong juserData)
{
KDWindow *w = (KDWindow*) (intptr_t) window;
+ JOGLKDUserdata * userData = (JOGLKDUserdata*) (intptr_t) juserData;
int res = kdDestroyWindow(w);
+ (*env)->DeleteGlobalRef(env, userData->javaWindow);
+ kdFree(userData);
DBG_PRINT( "[CloseWindow] res: %d\n", res);
return res;
@@ -194,120 +308,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setVisible0
DBG_PRINT( "[setVisible] v=%d\n", visible);
}
-JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_DispatchMessages
- (JNIEnv *env, jobject obj, jint owner, jlong window, jint eventMask)
-{
- KDWindow *w = (KDWindow*) (intptr_t) window;
- const KDEvent * evt;
-
- // Periodically take a break
- while( NULL!=(evt=kdWaitEvent(0)) ) {
- jint src_owner = (jint)(intptr_t)evt->userptr;
- if(src_owner != owner) {
- DBG_PRINT( "event unrelated: src: %d, caller: %d, evt type: 0x%X\n", src_owner, owner, evt->type);
- continue;
- }
- DBG_PRINT( "[DispatchMessages]: caller %d, evt type: 0x%X\n", owner, evt->type);
-
- switch(evt->type) {
- case KD_EVENT_INPUT_POINTER:
- if( ! ( eventMask & EVENT_MOUSE ) ) {
- DBG_PRINT( "event mouse ignored: src: %d\n", owner);
- continue;
- }
- break;
- /*
- case KeyPress:
- case KeyRelease:
- if( ! ( eventMask & EVENT_KEY ) ) {
- DBG_PRINT( "event key ignored: src: %d\n", owner);
- continue;
- }
- break;
- */
- case KD_EVENT_WINDOW_FOCUS:
- case KD_EVENT_WINDOW_CLOSE:
- case KD_EVENT_WINDOWPROPERTY_CHANGE:
- case KD_EVENT_WINDOW_REDRAW:
- if( ! ( eventMask & EVENT_WINDOW ) ) {
- DBG_PRINT( "event window ignored: src: %d\n", owner);
- continue;
- }
- break;
- }
-
- // FIXME: support resize and window re-positioning events
-
- switch(evt->type) {
- case KD_EVENT_WINDOW_FOCUS:
- {
- KDboolean hasFocus;
- kdGetWindowPropertybv(w, KD_WINDOWPROPERTY_FOCUS, &hasFocus);
- DBG_PRINT( "event window focus : src: %d\n", owner);
- }
- break;
- case KD_EVENT_WINDOW_CLOSE:
- {
- DBG_PRINT( "event window close : src: %d\n", owner);
- (*env)->CallVoidMethod(env, obj, windowDestroyNotifyID);
- // Called by Window.java: DestroyWindow(wnd);
- // (*env)->CallVoidMethod(env, obj, windowDestroyedID);
- }
- break;
- case KD_EVENT_WINDOWPROPERTY_CHANGE:
- {
- const KDEventWindowProperty* prop = &evt->data.windowproperty;
- switch (prop->pname) {
- case KD_WINDOWPROPERTY_SIZE:
- {
- KDint32 v[2];
- if(!kdGetWindowPropertyiv(w, KD_WINDOWPROPERTY_SIZE, v)) {
- DBG_PRINT( "event window size change : src: %d %dx%d\n", owner, v[0], v[1]);
- (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) v[0], (jint) v[1]);
- } else {
- DBG_PRINT( "event window size change error: src: %d %dx%d\n", owner, v[0], v[1]);
- }
- }
- break;
- case KD_WINDOWPROPERTY_FOCUS:
- DBG_PRINT( "event window focus: src: %d\n", owner);
- break;
- case KD_WINDOWPROPERTY_VISIBILITY:
- {
- KDboolean visible;
- kdGetWindowPropertybv(w, KD_WINDOWPROPERTY_VISIBILITY, &visible);
- DBG_PRINT( "event window visibility: src: %d, v:%d\n", owner, visible);
- }
- break;
- default:
- break;
- }
- }
- break;
- case KD_EVENT_INPUT_POINTER:
- {
- const KDEventInputPointer* ptr = &(evt->data.inputpointer);
- // button idx: evt->data.input.index
- // pressed = ev->data.input.value.i
- // time = ev->timestamp
- if(KD_INPUT_POINTER_SELECT==ptr->index) {
- DBG_PRINT( "event mouse click: src: %d, s:%d, (%d,%d)\n", owner, ptr->select, ptr->x, ptr->y);
- (*env)->CallVoidMethod(env, obj, sendMouseEventID,
- (ptr->select==0) ? (jint) EVENT_MOUSE_RELEASED : (jint) EVENT_MOUSE_PRESSED,
- (jint) 0,
- (jint) ptr->x, (jint) ptr->y, 1, 0);
- } else {
- DBG_PRINT( "event mouse: src: %d, s:%d, i:0x%X (%d,%d)\n", owner, ptr->select, ptr->index, ptr->x, ptr->y);
- (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
- 0,
- (jint) ptr->x, (jint) ptr->y, 0, 0);
- }
- }
- break;
- }
- }
-}
-
JNIEXPORT void JNICALL Java_com_sun_javafx_newt_kd_KDWindow_setFullScreen0
(JNIEnv *env, jobject obj, jlong window, jboolean fullscreen)
{
diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m
index f39a9f401..008a2417c 100644
--- a/src/newt/native/MacWindow.m
+++ b/src/newt/native/MacWindow.m
@@ -85,6 +85,7 @@ NS_ENDHANDLER
if(NULL!=newView) {
jobject globJavaWindowObject = (*env)->NewGlobalRef(env, javaWindowObject);
[newView setJavaWindowObject: globJavaWindowObject];
+ [newView setJNIEnv: env];
}
[win setContentView: newView];
@@ -92,11 +93,11 @@ NS_ENDHANDLER
}
/*
- * Class: com_sun_javafx_newt_macosx_MacWindow
+ * Class: com_sun_javafx_newt_macosx_MacDisplay
* Method: initIDs
* Signature: ()Z
*/
-JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_initIDs
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacDisplay_initNSApplication
(JNIEnv *env, jclass clazz)
{
static int initialized = 0;
@@ -122,6 +123,109 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_initIDs
// printf("Going to sleep for 10 seconds\n");
// sleep(10);
+ return (jboolean) JNI_TRUE;
+}
+
+/*
+ * Class: com_sun_javafx_newt_macosx_MacDisplay
+ * Method: dispatchMessages0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacDisplay_dispatchMessages0
+ (JNIEnv *env, jobject unused, jlong window, jint eventMask)
+{
+ NSEvent* event = NULL;
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+
+NS_DURING
+
+ NSWindow* win = NULL;
+ NewtView* view = NULL;
+ int num_events = 0;
+
+ // Periodically take a break
+ do {
+ // FIXME: ignoring event mask for the time being
+ event = [NSApp nextEventMatchingMask: NSAnyEventMask
+ untilDate: [NSDate distantPast]
+ inMode: NSDefaultRunLoopMode
+ dequeue: YES];
+ if (event != NULL) {
+ [NSApp sendEvent: event];
+
+ num_events++;
+ }
+ } while (num_events<100 && event != NULL);
+
+NS_HANDLER
+
+ // just ignore it ..
+
+NS_ENDHANDLER
+
+ [pool release];
+}
+
+/*
+ * Class: com_sun_javafx_newt_macosx_MacScreen
+ * Method: getWidthImpl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacScreen_getWidthImpl
+ (JNIEnv *env, jclass clazz, jint screen_idx)
+{
+ 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];
+ NSRect rect = [screen frame];
+
+ [pool release];
+
+ return (jint) (rect.size.width);
+}
+
+/*
+ * Class: com_sun_javafx_newt_macosx_MacScreen
+ * Method: getHeightImpl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacScreen_getHeightImpl
+ (JNIEnv *env, jclass clazz, jint screen_idx)
+{
+ 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];
+ NSRect rect = [screen frame];
+
+ [pool release];
+
+ return (jint) (rect.size.height);
+}
+
+/*
+ * Class: com_sun_javafx_newt_macosx_MacWindow
+ * Method: initIDs
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ static int initialized = 0;
+
+ if(initialized) return JNI_TRUE;
+ initialized = 1;
+
+ // 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");
+ // sleep(10);
+
return (jboolean) [NewtMacWindow initNatives: env forClass: clazz];
}
@@ -280,51 +384,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_setTitle0
/*
* Class: com_sun_javafx_newt_macosx_MacWindow
- * Method: dispatchMessages0
- * Signature: (JI)V
- */
-JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_dispatchMessages0
- (JNIEnv *env, jobject unused, jlong window, jint eventMask)
-{
- NSEvent* event = NULL;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
-
-NS_DURING
-
- NSWindow* win = (NSWindow *) ((intptr_t) window);
-
- if(NULL != win) {
- NewtView* view = (NewtView *) [win contentView];
- [view setJNIEnv: env];
-
- do {
- // FIXME: ignoring event mask for the time being
- event = [NSApp nextEventMatchingMask: NSAnyEventMask
- untilDate: [NSDate distantPast]
- inMode: NSDefaultRunLoopMode
- dequeue: YES];
- if (event != NULL) {
- win = (NSWindow*) [event window];
- view = (NewtView *) [win contentView];
- [view setJNIEnv: env];
-
- [NSApp sendEvent: event];
- }
- } while (event != NULL);
- }
-
-NS_HANDLER
-
- // just ignore it ..
-
-NS_ENDHANDLER
-
-
- [pool release];
-}
-
-/*
- * Class: com_sun_javafx_newt_macosx_MacWindow
* Method: contentView
* Signature: (J)J
*/
@@ -386,45 +445,3 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_setFrameTopLeft
[pool release];
}
-/*
- * Class: com_sun_javafx_newt_macosx_MacWindow
- * Method: getScreenWidth
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_getScreenWidth
- (JNIEnv *env, jclass clazz, jint screen_idx)
-{
- 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];
- NSRect rect = [screen frame];
-
- [pool release];
-
- return (jint) (rect.size.width);
-}
-
-/*
- * Class: com_sun_javafx_newt_macosx_MacWindow
- * Method: getScreenHeight
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_macosx_MacWindow_getScreenHeight
- (JNIEnv *env, jclass clazz, jint screen_idx)
-{
- 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];
- NSRect rect = [screen frame];
-
- [pool release];
-
- return (jint) (rect.size.height);
-}
-
diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c
index 908eb2ac0..67fbd3f07 100755
--- a/src/newt/native/WindowsWindow.c
+++ b/src/newt/native/WindowsWindow.c
@@ -778,61 +778,34 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message,
}
/*
- * Class: com_sun_javafx_newt_windows_WindowsScreen
- * Method: getScreenWidth
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getScreenWidth
- (JNIEnv *env, jobject obj, jint scrn_idx)
-{
- return (jint)GetSystemMetrics(SM_CXSCREEN);
-}
-
-/*
- * Class: com_sun_javafx_newt_windows_WindowsScreen
- * Method: getScreenWidth
- * Signature: (I)I
- */
-JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getScreenHeight
- (JNIEnv *env, jobject obj, jint scrn_idx)
-{
- return (jint)GetSystemMetrics(SM_CYSCREEN);
-}
-
-/*
- * Class: com_sun_javafx_newt_windows_WindowsWindow
- * Method: initIDs
- * Signature: ()Z
+ * Class: com_sun_javafx_newt_windows_WindowsDisplay
+ * Method: DispatchMessages
+ * Signature: ()V
*/
-JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initIDs
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_DispatchMessages
(JNIEnv *env, jclass clazz)
{
- sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
- positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
- focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(JZ)V");
- windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
- windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
- sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
- sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
- if (sizeChangedID == NULL ||
- positionChangedID == NULL ||
- focusChangedID == NULL ||
- windowDestroyNotifyID == NULL ||
- windowDestroyedID == NULL ||
- sendMouseEventID == NULL ||
- sendKeyEventID == NULL) {
- return JNI_FALSE;
- }
- BuildDynamicKeyMapTable();
- return JNI_TRUE;
+ int i = 0;
+ MSG msg;
+ BOOL gotOne;
+
+ // Periodically take a break
+ do {
+ gotOne = PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE);
+ if (gotOne) {
+ ++i;
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ } while (gotOne && i < 100);
}
/*
- * Class: com_sun_javafx_newt_windows_WindowsWindow
+ * Class: com_sun_javafx_newt_windows_WindowsDisplay
* Method: LoadLibraryW
* Signature: (Ljava/lang/String;)J
*/
-JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_LoadLibraryW
+JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_LoadLibraryW
(JNIEnv *env, jclass clazz, jstring dllName)
{
jchar* _dllName = GetNullTerminatedStringChars(env, dllName);
@@ -842,11 +815,11 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_LoadLibra
}
/*
- * Class: com_sun_javafx_newt_windows_WindowsWindow
+ * Class: com_sun_javafx_newt_windows_WindowsDisplay
* Method: RegisterWindowClass
* Signature: (Ljava/lang/String;J)I
*/
-JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_RegisterWindowClass
+JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_RegisterWindowClass
(JNIEnv *env, jclass clazz, jstring wndClassName, jlong hInstance)
{
ATOM res;
@@ -882,17 +855,67 @@ JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_RegisterWi
}
/*
- * Class: com_sun_javafx_newt_windows_WindowsWindow
+ * Class: com_sun_javafx_newt_windows_WindowsDisplay
* Method: CleanupWindowResources
* Signature: (java/lang/String;J)V
*/
-JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_CleanupWindowResources
- (JNIEnv *env, jobject obj, jint wndClassAtom, jlong hInstance)
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsDisplay_UnregisterWindowClass
+ (JNIEnv *env, jclass clazz, jint wndClassAtom, jlong hInstance)
{
UnregisterClass(MAKEINTATOM(wndClassAtom), (HINSTANCE) hInstance);
}
/*
+ * Class: com_sun_javafx_newt_windows_WindowsScreen
+ * Method: getWidthImpl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getWidthImpl
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ return (jint)GetSystemMetrics(SM_CXSCREEN);
+}
+
+/*
+ * Class: com_sun_javafx_newt_windows_WindowsScreen
+ * Method: getWidthImpl
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_windows_WindowsScreen_getHeightImpl
+ (JNIEnv *env, jobject obj, jint scrn_idx)
+{
+ return (jint)GetSystemMetrics(SM_CYSCREEN);
+}
+
+/*
+ * Class: com_sun_javafx_newt_windows_WindowsWindow
+ * Method: initIDs
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V");
+ positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
+ focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(JZ)V");
+ windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
+ windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
+ sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
+ sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
+ if (sizeChangedID == NULL ||
+ positionChangedID == NULL ||
+ focusChangedID == NULL ||
+ windowDestroyNotifyID == NULL ||
+ windowDestroyedID == NULL ||
+ sendMouseEventID == NULL ||
+ sendKeyEventID == NULL) {
+ return JNI_FALSE;
+ }
+ BuildDynamicKeyMapTable();
+ return JNI_TRUE;
+}
+
+/*
* Class: com_sun_javafx_newt_windows_WindowsWindow
* Method: CreateWindow
* Signature: (ILjava/lang/String;JJZIIII)J
@@ -1017,91 +1040,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_setVisible
/*
* Class: com_sun_javafx_newt_windows_WindowsWindow
- * Method: DispatchMessages
- * Signature: (JI)V
- */
-JNIEXPORT void JNICALL Java_com_sun_javafx_newt_windows_WindowsWindow_DispatchMessages
- (JNIEnv *env, jclass clazz, jlong window, jint eventMask)
-{
- int i = 0;
- MSG msg;
- BOOL gotOne;
- WindowUserData * wud;
-
-#if defined(UNDER_CE) || _MSC_VER <= 1200
- wud = (WindowUserData *) GetWindowLong((HWND)window, GWL_USERDATA);
-#else
- wud = (WindowUserData *) GetWindowLongPtr((HWND)window, GWLP_USERDATA);
-#endif
- if(NULL==wud) {
- fprintf(stderr, "INTERNAL ERROR in WindowsWindow::DispatchMessages window userdata NULL\n");
- exit(1);
- }
-
- wud->jenv = env;
-
- if(eventMask<0) {
- eventMask *= -1;
- /* FIXME: re-select input mask
- long xevent_mask_key = 0;
- long xevent_mask_ptr = 0;
- long xevent_mask_win = 0;
- if( 0 != ( eventMask & EVENT_MOUSE ) ) {
- xevent_mask_ptr |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask;
- }
- if( 0 != ( eventMask & EVENT_KEY ) ) {
- xevent_mask_key |= KeyPressMask|KeyReleaseMask;
- }
- if( 0 != ( eventMask & EVENT_WINDOW ) ) {
- xevent_mask_win |= ExposureMask;
- }
-
- XSelectInput(dpy, w, xevent_mask_win|xevent_mask_key|xevent_mask_ptr);
- */
- }
-
- // Periodically take a break
- do {
- gotOne = PeekMessage(&msg, (HWND) window, 0, 0, PM_REMOVE);
- if (gotOne) {
- ++i;
- switch (msg.message) {
- case WM_CLOSE:
- case WM_DESTROY:
- case WM_SIZE:
- if( ! ( eventMask & EVENT_WINDOW ) ) {
- continue;
- }
- break;
-
- case WM_CHAR:
- case WM_KEYDOWN:
- case WM_KEYUP:
- if( ! ( eventMask & EVENT_KEY ) ) {
- continue;
- }
- break;
-
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_MBUTTONDOWN:
- case WM_MBUTTONUP:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_MOUSEMOVE:
- if( ! ( eventMask & EVENT_MOUSE ) ) {
- continue;
- }
- break;
- }
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- } while (gotOne && i < 100);
-}
-
-/*
- * Class: com_sun_javafx_newt_windows_WindowsWindow
* Method: setSize0
* Signature: (JII)V
*/
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index c3d446f09..7ca3afe72 100755
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -34,6 +34,8 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <stdarg.h>
+#include <stdint.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -48,7 +50,7 @@
// #define VERBOSE_ON 1
#ifdef VERBOSE_ON
- #define DBG_PRINT(args...) fprintf(stderr, args)
+ #define DBG_PRINT(args...) fprintf(stderr, args); fflush(stderr);
#define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b))
@@ -121,12 +123,89 @@ static jint X11KeySym2NewtVKey(KeySym keySym) {
return keySym;
}
+static const char * const ClazzNameRuntimeException =
+ "java/lang/RuntimeException";
+static jclass runtimeExceptionClz=NULL;
+
+static const char * const ClazzNameNewtWindow =
+ "com/sun/javafx/newt/Window";
+static jclass newtWindowClz=NULL;
+
+static jmethodID sizeChangedID = NULL;
+static jmethodID positionChangedID = NULL;
+static jmethodID windowDestroyNotifyID = NULL;
+static jmethodID windowDestroyedID = NULL;
+static jmethodID windowCreatedID = NULL;
+static jmethodID sendMouseEventID = NULL;
+static jmethodID sendKeyEventID = NULL;
+
+static jmethodID displayCreatedID = NULL;
+
+static void _throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
+{
+ char buffer[512];
+ va_list ap;
+
+ va_start(ap, msg);
+ vsnprintf(buffer, sizeof(buffer), msg, ap);
+ va_end(ap);
+
+ (*env)->ThrowNew(env, runtimeExceptionClz, buffer);
+}
+
/**
* Display
*/
/*
* Class: com_sun_javafx_newt_x11_X11Display
+ * Method: initIDs
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Display_initIDs
+ (JNIEnv *env, jclass clazz)
+{
+ jclass c;
+
+ displayCreatedID = (*env)->GetMethodID(env, clazz, "displayCreated", "(JJ)V");
+ if (displayCreatedID == NULL) {
+ return JNI_FALSE;
+ }
+
+ if(NULL==newtWindowClz) {
+ c = (*env)->FindClass(env, ClazzNameNewtWindow);
+ if(NULL==c) {
+ fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameNewtWindow);
+ return JNI_FALSE;
+ }
+ newtWindowClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==newtWindowClz) {
+ fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameNewtWindow);
+ return JNI_FALSE;
+ }
+ }
+
+ if(NULL==runtimeExceptionClz) {
+ c = (*env)->FindClass(env, ClazzNameRuntimeException);
+ if(NULL==c) {
+ fprintf(stderr, "FatalError: NEWT X11Window: can't find %s\n", ClazzNameRuntimeException);
+ return JNI_FALSE;
+ }
+ runtimeExceptionClz = (jclass)(*env)->NewGlobalRef(env, c);
+ (*env)->DeleteLocalRef(env, c);
+ if(NULL==runtimeExceptionClz) {
+ fprintf(stderr, "FatalError: NEWT X11Window: can't use %s\n", ClazzNameRuntimeException);
+ return JNI_FALSE;
+ }
+ }
+
+ return JNI_TRUE;
+}
+
+
+/*
+ * Class: com_sun_javafx_newt_x11_X11Display
* Method: CreateDisplay
* Signature: (Ljava/lang/String;)J
*/
@@ -138,16 +217,229 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Display_CreateDisplay
if(displayName!=0) {
_displayName = (*env)->GetStringUTFChars(env, displayName, 0);
}
+ DBG_PRINT("open display connection for %s ..\n", ((NULL==_displayName)?"NULL":_displayName));
dpy = XOpenDisplay(_displayName);
+ if(dpy==NULL) {
+ _throwNewRuntimeException(env, "couldn't open display connection for %s\n", ((NULL==_displayName)?"NULL":_displayName));
+ }
if(_displayName!=0) {
(*env)->ReleaseStringChars(env, displayName, (const jchar *)_displayName);
}
- if(dpy==NULL) {
- fprintf(stderr, "couldn't open display connection..\n");
+
+ jlong javaObjectAtom = (jlong) XInternAtom(dpy, "JOGL_JAVA_OBJECT", False);
+ if(None==javaObjectAtom) {
+ XCloseDisplay(dpy);
+ _throwNewRuntimeException(env, "could not create Atom JOGL_JAVA_OBJECT, bail out!\n");
+ return 0;
}
+
+ jlong windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
+ if(None==windowDeleteAtom) {
+ XCloseDisplay(dpy);
+ _throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!\n");
+ return 0;
+ }
+
+ DBG_PRINT("X11Display_CreateDisplay dpy %p\n", dpy);
+
+ (*env)->CallVoidMethod(env, obj, displayCreatedID, javaObjectAtom, windowDeleteAtom);
+
return (jlong) (intptr_t) dpy;
}
+/*
+ * Class: com_sun_javafx_newt_x11_X11Display
+ * Method: DestroyDisplay
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DestroyDisplay
+ (JNIEnv *env, jobject obj, jlong display)
+{
+ Display * dpy = (Display *)(intptr_t)display;
+ DBG_PRINT("X11Display_DestroyDisplay dpy %p\n", dpy);
+ XCloseDisplay(dpy);
+}
+
+static int putPtrIn32Long(unsigned long * dst, uintptr_t src) {
+ int i=0;
+ dst[i++] = (unsigned long) ( ( src >> 0 ) & 0xFFFFFFFF ) ;
+ if(sizeof(uintptr_t) == 8) {
+ dst[i++] = (unsigned long) ( ( src >> 32 ) & 0xFFFFFFFF ) ;
+ }
+ return i;
+}
+
+static uintptr_t getPtrOut32Long(unsigned long * src) {
+ uintptr_t res = ( (uintptr_t) ( src[0] & 0xFFFFFFFF ) ) << 0 ;
+ if(sizeof(uintptr_t) == 8) {
+ res |= ( (uintptr_t) ( src[1] & 0xFFFFFFFF ) ) << 32 ;
+ }
+ return res;
+}
+
+static void setJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom, jobject jwindow) {
+ unsigned long jogl_java_object_data[2];
+ int nitems_32 = putPtrIn32Long( jogl_java_object_data, (uintptr_t) jwindow);
+
+ {
+ jobject test = (jobject) getPtrOut32Long(jogl_java_object_data);
+ if( ! (jwindow==test) ) {
+ _throwNewRuntimeException(env, "Internal Error .. Encoded Window ref not the same %p != %p !\n", jwindow, test);
+ }
+ }
+
+ XChangeProperty( dpy, window, (Atom)javaObjectAtom, (Atom)javaObjectAtom, 32, PropModeReplace,
+ (unsigned char *)&jogl_java_object_data, nitems_32);
+}
+
+static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, jlong javaObjectAtom) {
+ Atom actual_type_return;
+ int actual_format_return;
+ int nitems_32 = ( sizeof(uintptr_t) == 8 ) ? 2 : 1 ;
+ unsigned char * jogl_java_object_data_pp = NULL;
+ jobject jwindow;
+
+ {
+ unsigned long nitems_return = 0;
+ unsigned long bytes_after_return = 0;
+ jobject jwindow = NULL;
+ int res;
+
+ res = XGetWindowProperty(dpy, window, (Atom)javaObjectAtom, 0, nitems_32, False,
+ (Atom)javaObjectAtom, &actual_type_return, &actual_format_return,
+ &nitems_return, &bytes_after_return, &jogl_java_object_data_pp);
+
+ if ( Success != res ) {
+ _throwNewRuntimeException(env, "could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, bail out!\n",
+ res, nitems_return, bytes_after_return);
+ return NULL;
+ }
+
+ if(actual_type_return!=(Atom)javaObjectAtom || nitems_return<nitems_32 || NULL==jogl_java_object_data_pp) {
+ XFree(jogl_java_object_data_pp);
+ _throwNewRuntimeException(env, "could not fetch Atom JOGL_JAVA_OBJECT window property (res %d) nitems_return %ld, bytes_after_return %ld, actual_type_return %ld, JOGL_JAVA_OBJECT %ld, bail out!\n",
+ res, nitems_return, bytes_after_return, (long)actual_type_return, javaObjectAtom);
+ return NULL;
+ }
+ }
+ jwindow = (jobject) getPtrOut32Long( (unsigned long *) jogl_java_object_data_pp ) ;
+ XFree(jogl_java_object_data_pp);
+
+#ifdef VERBOSE_ON
+ if(JNI_FALSE == (*env)->IsInstanceOf(env, jwindow, newtWindowClz)) {
+ _throwNewRuntimeException(env, "fetched Atom JOGL_JAVA_OBJECT window is not a NEWT Window: javaWindow 0x%X !\n", jwindow);
+ }
+#endif
+ return jwindow;
+}
+
+/*
+ * Class: com_sun_javafx_newt_x11_X11Display
+ * Method: DispatchMessages
+ * Signature: (JIJJ)V
+ */
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DispatchMessages
+ (JNIEnv *env, jobject obj, jlong display, jlong javaObjectAtom, jlong wmDeleteAtom)
+{
+ Display * dpy = (Display *) (intptr_t) display;
+ int num_events = 0;
+
+ // Periodically take a break
+ while( num_events<100 && XPending(dpy)>0 ) {
+ jobject jwindow = NULL;
+ XEvent evt;
+ KeySym keySym;
+ char keyChar;
+ char text[255];
+
+ XNextEvent(dpy, &evt);
+ num_events++;
+
+ if( 0==evt.xany.window ) {
+ _throwNewRuntimeException(env, "event window NULL, bail out!\n");
+ }
+
+ if(dpy!=evt.xany.display) {
+ _throwNewRuntimeException(env, "wrong display");
+ continue;
+ }
+ jwindow = getJavaWindowProperty(env, dpy, evt.xany.window, javaObjectAtom);
+ if(NULL==jwindow) {
+ // just leave .. _throwNewRuntimeException(env, "could not fetch Java Window object, bail out!\n");
+ return;
+ }
+
+ // FIXME: support resize and window re-positioning events
+
+ switch(evt.type) {
+ case ButtonPress:
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
+ (jint) evt.xbutton.state,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ break;
+ case ButtonRelease:
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
+ (jint) evt.xbutton.state,
+ (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
+ break;
+ case MotionNotify:
+ (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
+ (jint) evt.xmotion.state,
+ (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
+ break;
+ case KeyPress:
+ if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
+ keyChar=text[0];
+ } else {
+ keyChar=0;
+ }
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
+ (jint) evt.xkey.state,
+ X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ break;
+ case KeyRelease:
+ if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
+ keyChar=text[0];
+ } else {
+ keyChar=0;
+ }
+ (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
+ (jint) evt.xkey.state,
+ X11KeySym2NewtVKey(keySym), (jchar) keyChar);
+ break;
+ case FocusIn:
+ case FocusOut:
+ break;
+ case DestroyNotify:
+ DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xdestroywindow.window);
+ (*env)->CallVoidMethod(env, jwindow, windowDestroyedID);
+ break;
+ case CreateNotify:
+ DBG_PRINT( "event . CreateNotify call 0x%X\n", evt.xcreatewindow.window);
+ (*env)->CallVoidMethod(env, jwindow, windowCreatedID);
+ break;
+ case VisibilityNotify:
+ DBG_PRINT( "event . VisibilityNotify call 0x%X\n", evt.xvisibility.window);
+ break;
+ case Expose:
+ DBG_PRINT( "event . Expose call 0x%X\n", evt.xexpose.window);
+ /* FIXME: Might want to send a repaint event .. */
+ break;
+ case UnmapNotify:
+ DBG_PRINT( "event . UnmapNotify call 0x%X\n", evt.xunmap.window);
+ break;
+ case ClientMessage:
+ if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) {
+ DBG_PRINT( "event . ClientMessage call 0x%X type 0x%X !!!\n", evt.xclient.window, evt.xclient.message_type);
+ (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID);
+ // Called by Window.java: CloseWindow();
+ }
+ break;
+ }
+ }
+}
+
+
/**
* Screen
*/
@@ -195,14 +487,6 @@ JNIEXPORT jint JNICALL Java_com_sun_javafx_newt_x11_X11Screen_getHeight0
* Window
*/
-static jmethodID sizeChangedID = NULL;
-static jmethodID positionChangedID = NULL;
-static jmethodID windowDestroyNotifyID = NULL;
-static jmethodID windowDestroyedID = NULL;
-static jmethodID windowCreatedID = NULL;
-static jmethodID sendMouseEventID = NULL;
-static jmethodID sendKeyEventID = NULL;
-
/*
* Class: com_sun_javafx_newt_x11_X11Window
* Method: initIDs
@@ -215,9 +499,10 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Window_initIDs
positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V");
windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V");
windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V");
- windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(JJ)V");
+ windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V");
sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V");
sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V");
+
if (sizeChangedID == NULL ||
positionChangedID == NULL ||
windowDestroyNotifyID == NULL ||
@@ -237,7 +522,8 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Window_initIDs
*/
JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
(JNIEnv *env, jobject obj, jlong display, jint screen_index,
- jlong visualID,
+ jlong visualID,
+ jlong javaObjectAtom, jlong windowDeleteAtom,
jint x, jint y, jint width, jint height)
{
Display * dpy = (Display *)(intptr_t)display;
@@ -283,11 +569,11 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
XFree(pVisualQuery);
pVisualQuery=NULL;
}
- DBG_PRINT( "trying given (screen %d, visualID: %d) found: %p\n", scrn_idx, (int)visualID, visual);
+ DBG_PRINT( "[CreateWindow] trying given (dpy %p, screen %d, visualID: %d) found: %p\n", dpy, scrn_idx, (int)visualID, visual);
if (visual==NULL)
{
- fprintf(stderr, "could not query Visual by given VisualID, bail out!\n");
+ _throwNewRuntimeException(env, "could not query Visual by given VisualID, bail out!\n");
return 0;
}
@@ -320,12 +606,31 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
visual,
attrMask,
&xswa);
- Atom wm_delete_window = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- XSetWMProtocols(dpy, window, &wm_delete_window, 1);
+
+ Atom wm_delete_atom = (Atom)windowDeleteAtom;
+ XSetWMProtocols(dpy, window, &wm_delete_atom, 1);
+
+ setJavaWindowProperty(env, dpy, window, javaObjectAtom, (*env)->NewGlobalRef(env, obj));
+
XClearWindow(dpy, window);
XSync(dpy, False);
- (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window, (jlong)wm_delete_window);
+ {
+ long xevent_mask = 0;
+ xevent_mask |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask;
+ xevent_mask |= KeyPressMask|KeyReleaseMask;
+ xevent_mask |= ExposureMask | StructureNotifyMask | SubstructureNotifyMask | VisibilityNotify ;
+ XSelectInput(dpy, window, xevent_mask);
+
+ /**
+ XGrabPointer(dpy, window, True, ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
+ GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
+ XGrabKeyboard(dpy, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+ */
+ }
+
+ DBG_PRINT( "[CreateWindow] created window %p on display %p\n", window, dpy);
+ (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window);
return (jlong) window;
}
@@ -336,10 +641,21 @@ JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Window_CreateWindow
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_CloseWindow
- (JNIEnv *env, jobject obj, jlong display, jlong window)
+ (JNIEnv *env, jobject obj, jlong display, jlong window, jlong javaObjectAtom)
{
Display * dpy = (Display *) (intptr_t) display;
Window w = (Window)window;
+ jobject jwindow;
+
+ jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom);
+ if(NULL==jwindow) {
+ _throwNewRuntimeException(env, "could not fetch Java Window object, bail out!\n");
+ return;
+ }
+ if ( JNI_FALSE == (*env)->IsSameObject(env, jwindow, obj) ) {
+ _throwNewRuntimeException(env, "Internal Error .. Window global ref not the same!\n");
+ }
+ (*env)->DeleteGlobalRef(env, jwindow);
XSync(dpy, False);
/**
@@ -383,176 +699,6 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setVisible0
}
}
-/*
- * Class: com_sun_javafx_newt_x11_X11Window
- * Method: DispatchMessages
- * Signature: (JJI)V
- */
-JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_DispatchMessages
- (JNIEnv *env, jobject obj, jlong display, jlong window, jint eventMask, jlong wmDeleteAtom)
-{
- Display * dpy = (Display *) (intptr_t) display;
- Window w = (Window)window;
- Atom wm_delete_window = (Atom)wmDeleteAtom;
-
- if(eventMask<0) {
- long xevent_mask_key = 0;
- long xevent_mask_ptr = 0;
- long xevent_mask_win = 0;
- eventMask *= -1;
- if( 0 != ( eventMask & EVENT_MOUSE ) ) {
- xevent_mask_ptr |= ButtonPressMask|ButtonReleaseMask|PointerMotionMask;
- }
- if( 0 != ( eventMask & EVENT_KEY ) ) {
- xevent_mask_key |= KeyPressMask|KeyReleaseMask;
- }
- if( 0 != ( eventMask & EVENT_WINDOW ) ) {
- xevent_mask_win |= ExposureMask | StructureNotifyMask | SubstructureNotifyMask | VisibilityNotify ;
- }
-
- XSelectInput(dpy, w, xevent_mask_win|xevent_mask_key|xevent_mask_ptr);
-
- /**
- if(0!=xevent_mask_ptr) {
- XGrabPointer(dpy, w, True, xevent_mask_ptr,
- GrabModeAsync, GrabModeAsync, w, None, CurrentTime);
- }
- if(0!=xevent_mask_key) {
- XGrabKeyboard(dpy, w, True, GrabModeAsync, GrabModeAsync, CurrentTime);
- } */
-
- }
-
- // Periodically take a break
- while( XPending(dpy)>0 ) {
- XEvent evt;
- KeySym keySym;
- char keyChar;
- char text[255];
-
- XNextEvent(dpy, &evt);
-
- switch(evt.type) {
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- if( ! ( eventMask & EVENT_MOUSE ) ) {
- continue;
- }
- break;
- case KeyPress:
- case KeyRelease:
- if( ! ( eventMask & EVENT_KEY ) ) {
- continue;
- }
- break;
- case FocusIn:
- case FocusOut:
- break;
- case DestroyNotify:
- case CreateNotify:
- case VisibilityNotify:
- case Expose:
- case UnmapNotify:
- if( ! ( eventMask & EVENT_WINDOW ) ) {
- continue;
- }
- break;
- }
-
- // FIXME: support resize and window re-positioning events
-
- switch(evt.type) {
- case ButtonPress:
- if(evt.xbutton.window==w) {
- (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED,
- (jint) evt.xbutton.state,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- }
- break;
- case ButtonRelease:
- if(evt.xbutton.window==w) {
- (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_RELEASED,
- (jint) evt.xbutton.state,
- (jint) evt.xbutton.x, (jint) evt.xbutton.y, (jint) evt.xbutton.button, 0 /*rotation*/);
- }
- break;
- case MotionNotify:
- if(evt.xmotion.window==w) {
- (*env)->CallVoidMethod(env, obj, sendMouseEventID, (jint) EVENT_MOUSE_MOVED,
- (jint) evt.xmotion.state,
- (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/);
- }
- break;
- case KeyPress:
- if(evt.xkey.window==w) {
- if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
- keyChar=text[0];
- } else {
- keyChar=0;
- }
- (*env)->CallVoidMethod(env, obj, sendKeyEventID, (jint) EVENT_KEY_PRESSED,
- (jint) evt.xkey.state,
- X11KeySym2NewtVKey(keySym), (jchar) keyChar);
- }
- break;
- case KeyRelease:
- if(evt.xkey.window==w) {
- if(XLookupString(&evt.xkey,text,255,&keySym,0)==1) {
- keyChar=text[0];
- } else {
- keyChar=0;
- }
- (*env)->CallVoidMethod(env, obj, sendKeyEventID, (jint) EVENT_KEY_RELEASED,
- (jint) evt.xkey.state,
- X11KeySym2NewtVKey(keySym), (jchar) keyChar);
- }
- break;
- case FocusIn:
- case FocusOut:
- if(evt.xfocus.window==w) {
- }
- break;
- case DestroyNotify:
- if(evt.xdestroywindow.window==w) {
- DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xdestroywindow.window);
- (*env)->CallVoidMethod(env, obj, windowDestroyedID);
- }
- break;
- case CreateNotify:
- if(evt.xcreatewindow.window==w) {
- DBG_PRINT( "event . DestroyNotify call 0x%X\n", evt.xcreatewindow.window);
- (*env)->CallVoidMethod(env, obj, windowCreatedID);
- }
- break;
- case VisibilityNotify:
- if(evt.xvisibility.window==w) {
- DBG_PRINT( "event . VisibilityNotify call 0x%X\n", evt.xvisibility.window);
- }
- break;
- case Expose:
- if(evt.xexpose.window==w) {
- DBG_PRINT( "event . Expose call 0x%X\n", evt.xexpose.window);
- /* FIXME: Might want to send a repaint event .. */
- }
- break;
- case UnmapNotify:
- if(evt.xunmap.window==w) {
- DBG_PRINT( "event . UnmapNotify call 0x%X\n", evt.xunmap.window);
- }
- break;
- case ClientMessage:
- if (evt.xclient.window==w && evt.xclient.send_event==True && evt.xclient.data.l[0]==wm_delete_window) {
- DBG_PRINT( "event . ClientMessage call 0x%X type 0x%X !!!\n", evt.xclient.window, evt.xclient.message_type);
- (*env)->CallVoidMethod(env, obj, windowDestroyNotifyID);
- // Called by Window.java: CloseWindow();
- }
- break;
-
- }
- }
-}
-
#define MWM_FULLSCREEN 1
#ifdef MWM_FULLSCREEN
@@ -612,7 +758,13 @@ JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Window_setSize0
XSync(dpy, False);
/** if(isVisible==JNI_TRUE) {
+ // this ..
XSetInputFocus(dpy, w, RevertToNone, CurrentTime);
+
+ // or this ..
+ unsigned long wmleader[1] = { (unsigned long) w};
+ Atom prop = XInternAtom( dpy, "WM_CLIENT_LEADER", False );
+ XChangeProperty( dpy, w, prop, prop, 32, PropModeReplace, (unsigned char *)&wmleader, 1);
} */
DBG_PRINT( "setSize0 . sizeChangedID call\n");