diff options
Diffstat (limited to 'src/newt/classes')
19 files changed, 825 insertions, 341 deletions
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; } |