diff options
Diffstat (limited to 'src/newt')
17 files changed, 625 insertions, 567 deletions
diff --git a/src/newt/classes/com/jogamp/newt/Display.java b/src/newt/classes/com/jogamp/newt/Display.java index 8710f82ba..c804b3d2d 100755 --- a/src/newt/classes/com/jogamp/newt/Display.java +++ b/src/newt/classes/com/jogamp/newt/Display.java @@ -33,8 +33,9 @@ package com.jogamp.newt; -import com.jogamp.newt.event.*; import javax.media.nativewindow.*; +import com.jogamp.nativewindow.impl.RecursiveToolkitLock; +import com.jogamp.newt.event.*; import com.jogamp.newt.impl.Debug; import com.jogamp.newt.util.EDTUtil; import java.util.*; @@ -112,7 +113,7 @@ public abstract class Display { Map displayMap = getCurrentDisplayMap(); Set entrySet = displayMap.entrySet(); Iterator i = entrySet.iterator(); - System.err.println(prefix+" DisplayMap[] entries: "+entrySet.size()+" - "+Thread.currentThread()); + System.err.println(prefix+" DisplayMap[] entries: "+entrySet.size()+" - "+getThreadName()); for(int j=0; i.hasNext(); j++) { Map.Entry entry = (Map.Entry) i.next(); System.err.println(" ["+j+"] "+entry.getKey()+" -> "+entry.getValue()); @@ -142,12 +143,12 @@ public abstract class Display { display.type=type; display.refCount=0; if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") NEW: refCount "+display.refCount+", "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") NEW: refCount "+display.refCount+", "+display+" "+getThreadName()); } } else { tmpDisplay = null; if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") REUSE: refCount "+display.refCount+", "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") REUSE: refCount "+display.refCount+", "+display+" "+getThreadName()); } } synchronized(display) { @@ -163,7 +164,7 @@ public abstract class Display { } setCurrentDisplay(display); if(DEBUG) { - System.err.println("Display.create("+getFQName(type, name)+") CreateNative: "+display+" "+Thread.currentThread()); + System.err.println("Display.create("+getFQName(type, name)+") CreateNative: "+display+" "+getThreadName()); } } } @@ -192,7 +193,7 @@ public abstract class Display { new Runnable() { public void run() { if(null!=f_dpy.getGraphicsDevice()) { - f_dpy.pumpMessagesImpl(); + f_dpy.dispatchMessages(); } } } ); edt = edtUtil.start(); } @@ -220,7 +221,7 @@ public abstract class Display { if(0==refCount) { removeCurrentDisplay(type, name); if(DEBUG) { - System.err.println("Display.destroy("+getFQName()+") REMOVE: "+this+" "+Thread.currentThread()); + System.err.println("Display.destroy("+getFQName()+") REMOVE: "+this+" "+getThreadName()); } final Display f_dpy = this; final EDTUtil f_edt = edtUtil; @@ -240,7 +241,7 @@ public abstract class Display { aDevice = null; } else { if(DEBUG) { - System.err.println("Display.destroy("+getFQName()+") KEEP: refCount "+refCount+", "+this+" "+Thread.currentThread()); + System.err.println("Display.destroy("+getFQName()+") KEEP: refCount "+refCount+", "+this+" "+getThreadName()); } } if(DEBUG) { @@ -267,7 +268,7 @@ public abstract class Display { protected String validateDisplayName(String name, long handle) { if(null==name && 0!=handle) { - name="wrapping-0x"+Long.toHexString(handle); + name="wrapping-"+toHexString(handle); } return ( null == name ) ? nilString : name ; } @@ -290,11 +291,6 @@ public abstract class Display { } public synchronized void pumpMessages() { - pumpMessagesImpl(); - } - - private void pumpMessagesImpl() { - if(0==refCount) return; dispatchMessages(); } @@ -302,27 +298,73 @@ public abstract class Display { return "NEWT-Display["+getFQName()+", refCount "+refCount+", hasEDT "+(null!=edtUtil)+", "+aDevice+"]"; } + public static String getThreadName() { + return Thread.currentThread().getName(); + } + + public static String toHexString(int hex) { + return "0x" + Integer.toHexString(hex); + } + + public static String toHexString(long hex) { + return "0x" + Long.toHexString(hex); + } + + protected abstract void dispatchMessagesNative(); + private Object eventsLock = new Object(); private LinkedList/*<NEWTEvent>*/ events = new LinkedList(); + private boolean events2Wait = false; protected void dispatchMessages() { + if(0==refCount) return; // we should not exist .. + if(!events.isEmpty()) { - synchronized(events) { - while (!events.isEmpty()) { - NEWTEvent e = (NEWTEvent) events.removeFirst(); - Object source = e.getSource(); - if(source instanceof Window) { - ((Window)source).sendEvent(e); - } else { - throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + if(events2Wait) { + synchronized(eventsLock) { + while (!events.isEmpty()) { + NEWTEvent e = (NEWTEvent) events.removeFirst(); + Object source = e.getSource(); + if(source instanceof Window) { + ((Window)source).sendEvent(e); + } else { + throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + } + } + events2Wait = false; // clear + eventsLock.notifyAll(); + } + } else { + // swap events list to free ASAP + LinkedList/*<NEWTEvent>*/ _events = null; + synchronized(eventsLock) { + if(!events.isEmpty()) { + _events = events; + events = new LinkedList(); + } + eventsLock.notifyAll(); + } + if( null != _events ) { + while (!_events.isEmpty()) { + NEWTEvent e = (NEWTEvent) _events.removeFirst(); + Object source = e.getSource(); + if(source instanceof Window) { + ((Window)source).sendEvent(e); + } else { + throw new RuntimeException("Event source not a NEWT Window: "+source.getClass().getName()+", "+source); + } } } - events.notifyAll(); } } - dispatchMessagesNative(); + // lock(); + try { + dispatchMessagesNative(); + } finally { + // unlock(); + } } public void enqueueEvent(NEWTEvent e) { @@ -330,17 +372,18 @@ public abstract class Display { } public void enqueueEvent(boolean wait, NEWTEvent e) { - synchronized(events) { + synchronized(eventsLock) { if(DEBUG) { System.out.println("Display.enqueueEvent: START - wait "+wait+", "+e); } + events2Wait = wait; events.addLast(e); } if(wait && !events.isEmpty()) { - synchronized(events) { + synchronized(eventsLock) { while(!events.isEmpty()) { try { - events.wait(); + eventsLock.wait(); } catch (InterruptedException ie) { ie.printStackTrace(); } @@ -352,12 +395,13 @@ public abstract class Display { } } + public void lock() { + aDevice.lock(); + } - /** Default impl. nop - Currently only X11 needs a Display lock */ - protected void lockDisplay() { } - - /** Default impl. nop - Currently only X11 needs a Display lock */ - protected void unlockDisplay() { } + public void unlock() { + aDevice.unlock(); + } protected EDTUtil edtUtil = null; protected Thread edt = null; diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 87f0bf0eb..89c1bd146 100755 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -132,14 +132,6 @@ public abstract class Window implements NativeWindow } } - public static String toHexString(int hex) { - return "0x" + Integer.toHexString(hex); - } - - public static String toHexString(long hex) { - return "0x" + Long.toHexString(hex); - } - protected Screen screen; protected NativeWindow parentNativeWindow; @@ -162,14 +154,15 @@ public abstract class Window implements NativeWindow return 0 != windowHandle ; } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.createNative() START ("+Thread.currentThread()+", "+this+")"); + System.err.println("Window.createNative() START ("+getThreadName()+", "+this+")"); } if(validateParentWindowHandle()) { + Display dpy = getScreen().getDisplay(); createNativeImpl(); setVisibleImpl(true); } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.createNative() END ("+Thread.currentThread()+", "+this+")"); + System.err.println("Window.createNative() END ("+getThreadName()+", "+this+")"); } return 0 != windowHandle ; } @@ -185,26 +178,27 @@ public abstract class Window implements NativeWindow private static long getNativeWindowHandle(NativeWindow nativeWindow) { long handle = 0; if(null!=nativeWindow) { - boolean ok = true; + boolean locked=false; try { - nativeWindow.lockSurface(); + if( NativeWindow.LOCK_SURFACE_NOT_READY < nativeWindow.lockSurface() ) { + locked=true; + handle = nativeWindow.getWindowHandle(); + if(0==handle) { + throw new NativeWindowException("Parent native window handle is NULL, after succesful locking: "+nativeWindow); + } + } } catch (NativeWindowException nwe) { - // parent native window not ready .. just skip action for now - ok = false; if(DEBUG_IMPLEMENTATION) { System.err.println("Window.getNativeWindowHandle: not successful yet: "+nwe); } - } - if(ok) { - handle = nativeWindow.getWindowHandle(); - nativeWindow.unlockSurface(); - if(0==handle) { - throw new NativeWindowException("Parent native window handle is NULL, after succesful locking: "+nativeWindow); - } - if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.getNativeWindowHandle: "+nativeWindow); + } finally { + if(locked) { + nativeWindow.unlockSurface(); } } + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.getNativeWindowHandle: locked "+locked+", "+nativeWindow); + } } return handle; } @@ -281,7 +275,11 @@ public abstract class Window implements NativeWindow title = ""; } this.title = title; + if(0 != windowHandle) { + setTitleImpl(title); + } } + protected void setTitleImpl(String title) {} public void setUndecorated(boolean value) { undecorated = value; @@ -296,7 +294,11 @@ public abstract class Window implements NativeWindow } public void requestFocus() { + if(0 != windowHandle) { + requestFocusImpl(); + } } + protected void requestFocusImpl() {} // // NativeWindow impl @@ -306,35 +308,35 @@ public abstract class Window implements NativeWindow public int lockSurface() { // We leave the ToolkitLock lock to the specializtion's discretion, // ie the implicit JAWTWindow in case of AWTWindow - if(isDestroyed() || !isNativeWindowValid()) { - return LOCK_SURFACE_NOT_READY; - } - surfaceLock.lock(); - screen.getDisplay().lockDisplay(); + + windowLock.lock(); + + // if(windowLock.getRecursionCount() == 0) { // allow recursion to lock again, always + if(isDestroyed() || !isNativeWindowValid()) { + windowLock.unlock(); + return LOCK_SURFACE_NOT_READY; + } + // } return LOCK_SUCCESS; } /** Recursive and unblocking unlockSurface() implementation */ public void unlockSurface() throws NativeWindowException { - surfaceLock.unlock( new Runnable() { - public void run() { - screen.getDisplay().unlockDisplay(); - } - } ); + windowLock.unlock(); // We leave the ToolkitLock unlock to the specializtion's discretion, // ie the implicit JAWTWindow in case of AWTWindow } public boolean isSurfaceLocked() { - return surfaceLock.isLocked(); + return windowLock.isLocked(); } public Thread getSurfaceLockOwner() { - return surfaceLock.getOwner(); + return windowLock.getOwner(); } public Exception getLockedStack() { - return surfaceLock.getLockedStack(); + return windowLock.getLockedStack(); } /** @@ -352,6 +354,19 @@ public abstract class Window implements NativeWindow destroy(false); } + /** + * @param deep If true, all resources, ie listeners, parent handles, size, position + * and the referenced NEWT screen and display, will be destroyed as well. Be aware that if you call + * this method with deep = true, you will not be able to regenerate the Window. + * @see #destroy() + * @see #invalidate(boolean) + */ + public void destroy(boolean deep) { + if(!isDestroyed()) { + runOnEDTIfAvail(true, new DestroyAction(deep)); + } + } + class DestroyAction implements Runnable { boolean deep; public DestroyAction(boolean deep) { @@ -361,7 +376,7 @@ public abstract class Window implements NativeWindow windowLock(); try { if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.destroy(deep: "+deep+") START "+Thread.currentThread()+", "+this); + System.err.println("Window.destroy(deep: "+deep+") START "+getThreadName()+", "+this); } // Childs first .. @@ -397,22 +412,23 @@ public abstract class Window implements NativeWindow } } Display dpy = null; + Screen scr = null; if( null != screen && 0 != windowHandle ) { - Screen scr = screen; - dpy = (null!=screen) ? screen.getDisplay() : null; + scr = screen; + dpy = screen.getDisplay(); closeNative(); } invalidate(deep); if(deep) { - if(null!=screen) { - screen.destroy(); + if(null!=scr) { + scr.destroy(); } if(null!=dpy) { dpy.destroy(); } } if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.destroy(deep: "+deep+") END "+Thread.currentThread()+", "+this); + System.err.println("Window.destroy(deep: "+deep+") END "+getThreadName()+", "+this); } } finally { windowUnlock(); @@ -421,19 +437,6 @@ public abstract class Window implements NativeWindow } /** - * @param deep If true, all resources, ie listeners, parent handles, size, position - * and the referenced NEWT screen and display, will be destroyed as well. Be aware that if you call - * this method with deep = true, you will not be able to regenerate the Window. - * @see #destroy() - * @see #invalidate(boolean) - */ - public void destroy(boolean deep) { - if(!isDestroyed()) { - runOnEDTIfAvail(true, new DestroyAction(deep)); - } - } - - /** * <p> * render all native window information invalid, * as if the native window was destroyed.<br></p> @@ -461,7 +464,7 @@ public abstract class Window implements NativeWindow windowLock(); try{ if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { - String msg = new String("!!! Window Invalidate(deep: "+deep+") "+Thread.currentThread()); + String msg = new String("!!! Window Invalidate(deep: "+deep+") "+getThreadName()); System.err.println(msg); //Exception e = new Exception(msg); //e.printStackTrace(); @@ -600,23 +603,23 @@ public abstract class Window implements NativeWindow protected void windowDestroyNotify() { if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyNotify START "+Thread.currentThread()); + System.err.println("Window.windowDestroyNotify START "+getThreadName()); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); if(handleDestroyNotify && !isDestroyed()) { destroy(); } if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyeNotify END "+Thread.currentThread()); + System.err.println("Window.windowDestroyeNotify END "+getThreadName()); } } protected void windowDestroyed() { if(DEBUG_WINDOW_EVENT) { - System.err.println("Window.windowDestroyed "+Thread.currentThread()); + System.err.println("Window.windowDestroyed "+getThreadName()); } invalidate(); } @@ -626,6 +629,68 @@ public abstract class Window implements NativeWindow return false; } + class ReparentAction implements Runnable { + NativeWindow newParent; + Screen newScreen; + public ReparentAction(NativeWindow newParent, Screen newScreen) { + this.newParent = newParent; + this.newScreen = newScreen; + } + public void run() { + windowLock(); + try{ + if ( 0 == windowHandle && null != newScreen ) { + screen = newScreen; + } + long newParentHandle = 0 ; + if(null!=newParent) { + newParentHandle = getNativeWindowHandle(newParent); + if ( 0 == newParentHandle ) { + return; // bail out .. not ready yet + } + } + + if(DEBUG_IMPLEMENTATION) { + System.err.println("reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow)); + } + + if(null!=parentNativeWindow && parentNativeWindow instanceof Window) { + ((Window)parentNativeWindow).getInnerWindow().removeChild(Window.this); + } + parentNativeWindow = newParent; + if(parentNativeWindow instanceof Window) { + ((Window)parentNativeWindow).getInnerWindow().addChild(Window.this); + } + + if(newParentHandle != parentWindowHandle) { + parentWindowHandle = newParentHandle; + if(0!=parentWindowHandle) { + // reset position to 0/0 within parent space + // FIXME .. cache position ? + x = 0; + y = 0; + } + boolean reparentRes = false; + reparentRes = reparentWindowImpl(); + if(!reparentRes) { + parentWindowHandle = 0; + + // do it the hard way .. reconstruction with setVisible(true) + if( 0 != windowHandle ) { + destroy(false); + } + } + } + + if(DEBUG_IMPLEMENTATION) { + System.err.println("reparentWindow: END ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); + } + } finally { + windowUnlock(); + } + } + } + /** * Change this window's parent window.<br> * <P> @@ -639,54 +704,11 @@ public abstract class Window implements NativeWindow * this Screen is being used. */ public void reparentWindow(NativeWindow newParent, Screen newScreen) { - windowLock(); - try{ - if ( 0 == windowHandle && null != newScreen ) { - screen = newScreen; - } - long newParentHandle = 0 ; - if(null!=newParent) { - newParentHandle = getNativeWindowHandle(newParent); - if ( 0 == newParentHandle ) { - return; // bail out .. not ready yet - } - } - - if(DEBUG_IMPLEMENTATION) { - System.err.println("reparent: START ("+Thread.currentThread()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+" -> "+toHexString(newParentHandle)+", visible "+visible+", parentNativeWindow "+(null!=parentNativeWindow)); - } - - if(null!=parentNativeWindow && parentNativeWindow instanceof Window) { - ((Window)parentNativeWindow).getInnerWindow().removeChild(this); - } - parentNativeWindow = newParent; - if(parentNativeWindow instanceof Window) { - ((Window)parentNativeWindow).getInnerWindow().addChild(this); - } - - if(newParentHandle != parentWindowHandle) { - parentWindowHandle = newParentHandle; - if(0!=parentWindowHandle) { - // reset position to 0/0 within parent space - // FIXME .. cache position ? - x = 0; - y = 0; - } - if(!reparentWindowImpl()) { - parentWindowHandle = 0; - - // do it the hard way .. reconstruction with setVisible(true) - if( 0 != windowHandle ) { - destroy(false); - } - } - } - - if(DEBUG_IMPLEMENTATION) { - System.err.println("reparentWindow: END ("+Thread.currentThread()+") windowHandle "+toHexString(windowHandle)+", visible: "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); + if(!isDestroyed()) { + runOnEDTIfAvail(true, new ReparentAction(newParent, newScreen)); + if( isVisible() ) { + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener } - } finally { - windowUnlock(); } } @@ -733,7 +755,7 @@ public abstract class Window implements NativeWindow } if(DEBUG_IMPLEMENTATION) { - System.err.println("Window setVisible: END ("+Thread.currentThread()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible); + System.err.println("Window setVisible: END ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+Window.this.visible); } } finally { windowUnlock(); @@ -768,7 +790,7 @@ public abstract class Window implements NativeWindow */ public void setVisible(boolean visible) { if(DEBUG_IMPLEMENTATION) { - String msg = new String("Window setVisible: START ("+Thread.currentThread()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); + String msg = new String("Window setVisible: START ("+getThreadName()+") "+x+"/"+y+" "+width+"x"+height+", fs "+fullscreen+", windowHandle "+toHexString(windowHandle)+", visible: "+this.visible+" -> "+visible+", parentWindowHandle "+toHexString(parentWindowHandle)+", parentNativeWindow "+(null!=parentNativeWindow)); //System.err.println(msg); Exception ee = new Exception(msg); ee.printStackTrace(); @@ -1000,49 +1022,19 @@ public abstract class Window implements NativeWindow // // MouseListener/Event Support // - - public void addMouseListener(MouseListener l) { - if(l == null) { - return; - } - synchronized(mouseListeners) { - ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); - newMouseListeners.add(l); - mouseListeners = newMouseListeners; - } - } - - public void removeMouseListener(MouseListener l) { - if (l == null) { - return; - } - synchronized(mouseListeners) { - ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); - newMouseListeners.remove(l); - mouseListeners = newMouseListeners; - } - } - - public MouseListener[] getMouseListeners() { - synchronized(mouseListeners) { - return (MouseListener[]) mouseListeners.toArray(); - } - } - private ArrayList mouseListeners = new ArrayList(); private int mouseButtonPressed = 0; // current pressed mouse button number private long lastMousePressed = 0; // last time when a mouse button was pressed private int lastMouseClickCount = 0; // last mouse button click count public static final int ClickTimeout = 300; - /** Be aware that this method synthesizes the events: MouseClicked and MouseDragged */ - protected void sendMouseEvent(int eventType, int modifiers, + protected void enqueueMouseEvent(int eventType, int modifiers, int x, int y, int button, int rotation) { if(x<0||y<0||x>=width||y>=height) { return; // .. invalid .. } if(DEBUG_MOUSE_EVENT) { - System.err.println("sendMouseEvent: "+MouseEvent.getEventTypeString(eventType)+ + System.err.println("enqueueMouseEvent: "+MouseEvent.getEventTypeString(eventType)+ ", mod "+modifiers+", pos "+x+"/"+y+", button "+button); } if(button<0||button>MouseEvent.BUTTON_NUMBER) { @@ -1086,12 +1078,41 @@ public abstract class Window implements NativeWindow } else { e = new MouseEvent(eventType, this, when, modifiers, x, y, 0, button, 0); } - sendMouseEvent(e); + screen.getDisplay().enqueueEvent(e); if(null!=eClicked) { if(DEBUG_MOUSE_EVENT) { - System.err.println("sendMouseEvent: synthesized MOUSE_CLICKED event"); + System.err.println("enqueueMouseEvent: synthesized MOUSE_CLICKED event"); } - sendMouseEvent(eClicked); + screen.getDisplay().enqueueEvent(eClicked); + } + } + + + public void addMouseListener(MouseListener l) { + if(l == null) { + return; + } + synchronized(mouseListeners) { + ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); + newMouseListeners.add(l); + mouseListeners = newMouseListeners; + } + } + + public void removeMouseListener(MouseListener l) { + if (l == null) { + return; + } + synchronized(mouseListeners) { + ArrayList newMouseListeners = (ArrayList) mouseListeners.clone(); + newMouseListeners.remove(l); + mouseListeners = newMouseListeners; + } + } + + public MouseListener[] getMouseListeners() { + synchronized(mouseListeners) { + return (MouseListener[]) mouseListeners.toArray(); } } @@ -1141,6 +1162,12 @@ public abstract class Window implements NativeWindow // KeyListener/Event Support // + protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + screen.getDisplay().enqueueEvent( + new KeyEvent(eventType, this, System.currentTimeMillis(), + modifiers, keyCode, keyChar) ); + } + public void addKeyListener(KeyListener l) { if(l == null) { return; @@ -1171,11 +1198,6 @@ public abstract class Window implements NativeWindow private ArrayList keyListeners = new ArrayList(); - protected void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { - sendKeyEvent(new KeyEvent(eventType, this, System.currentTimeMillis(), - modifiers, keyCode, keyChar) ); - } - protected void sendKeyEvent(KeyEvent e) { if(DEBUG_KEY_EVENT) { System.err.println("sendKeyEvent: "+e); @@ -1205,6 +1227,11 @@ public abstract class Window implements NativeWindow // // WindowListener/Event Support // + protected void enqueueWindowEvent(int eventType) { + WindowEvent event = new WindowEvent(eventType, this, System.currentTimeMillis()); + screen.getDisplay().enqueueEvent( event ); + // sendWindowEvent ( event ); // FIXME: Think about performance/lag .. ? + } private ArrayList windowListeners = new ArrayList(); @@ -1236,10 +1263,6 @@ public abstract class Window implements NativeWindow } } - protected void sendWindowEvent(int eventType) { - sendWindowEvent( new WindowEvent(eventType, this, System.currentTimeMillis()) ); - } - protected void sendWindowEvent(WindowEvent e) { if(DEBUG_WINDOW_EVENT) { System.err.println("sendWindowEvent: "+e); @@ -1365,8 +1388,7 @@ public abstract class Window implements NativeWindow return sb.toString(); } - private RecursiveToolkitLock surfaceLock = new RecursiveToolkitLock(); - private RecursiveToolkitLock windowLock = new RecursiveToolkitLock(); + protected RecursiveToolkitLock windowLock = new RecursiveToolkitLock(); private static final boolean TRACE_LOCK = false; @@ -1387,8 +1409,23 @@ public abstract class Window implements NativeWindow protected final boolean windowIsLocked() { return getInnerWindow().windowLock.isLocked(); } + protected RecursiveToolkitLock getWindowLock() { + return getInnerWindow().windowLock; + } protected final void shouldNotCallThis() { throw new NativeWindowException("Should not call this"); } + + public static String getThreadName() { + return Display.getThreadName(); + } + + public static String toHexString(int hex) { + return Display.toHexString(hex); + } + + public static String toHexString(long hex) { + return Display.toHexString(hex); + } } diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 23269a93b..a84e571e4 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -55,7 +55,6 @@ public class NewtCanvasAWT extends java.awt.Canvas { /** * Instantiates a NewtCanvas without a NEWT child.<br> - * @see #setNEWTChild(Window) */ public NewtCanvasAWT() { super(); @@ -74,8 +73,9 @@ public class NewtCanvasAWT extends java.awt.Canvas { if(newtChild!=child) { newtChild = child; if(null!=parent) { + java.awt.Container cont = getContainer(this); // reparent right away, addNotify has been called already - reparentWindow( (null!=newtChild) ? true : false ); + reparentWindow( (null!=newtChild) ? true : false, cont ); } } return this; @@ -100,26 +100,38 @@ public class NewtCanvasAWT extends java.awt.Canvas { } } + static java.awt.Container getContainer(java.awt.Component comp) { + while( null != comp && !(comp instanceof java.awt.Container) ) { + comp = comp.getParent(); + } + if(comp instanceof java.awt.Container) { + return (java.awt.Container) comp; + } + return null; + } + public void addNotify() { super.addNotify(); disableBackgroundErase(); + java.awt.Container cont = getContainer(this); if(DEBUG_IMPLEMENTATION) { // if ( isShowing() == false ) -> Container was not visible yet. // if ( isShowing() == true ) -> Container is already visible. - System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+", displayable "+isDisplayable()); + System.err.println("NewtCanvasAWT.addNotify: "+newtChild+", "+this+", visible "+isVisible()+", showing "+isShowing()+", displayable "+isDisplayable()+" -> "+cont); } - reparentWindow(true); + reparentWindow(true, cont); } public void removeNotify() { + java.awt.Container cont = getContainer(this); if(DEBUG_IMPLEMENTATION) { - System.err.println("NewtCanvasAWT.removeNotify: "+newtChild); + System.err.println("NewtCanvasAWT.removeNotify: "+newtChild+", from "+cont); } - reparentWindow(false); + reparentWindow(false, cont); super.removeNotify(); } - void reparentWindow(boolean add) { + void reparentWindow(boolean add, java.awt.Container cont) { if(null==newtChild) { return; // nop } @@ -129,20 +141,18 @@ public class NewtCanvasAWT extends java.awt.Canvas { parent = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities()); } if(null!=parent) { - // 1st choice - NEWT size := AWT size - // 2nd choice - AWT size := NEWT size - if(0>=getWidth()*getHeight()) { - setSize(newtChild.getWidth(), newtChild.getHeight()); // #2 + if(DEBUG_IMPLEMENTATION) { + System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild); } + setSize(cont.getWidth(), cont.getHeight()); + newtChild.setSize(cont.getWidth(), cont.getHeight()); + Screen screen = null; if( !newtChild.isNativeWindowValid() ) { screen = NewtFactoryAWT.createCompatibleScreen(parent); } newtChild.reparentWindow(parent, screen); - if ( 0 < getWidth() * getHeight() ) { - newtChild.setSize(getWidth(), getHeight()); // #1 - newtChild.setVisible(true); - } + newtChild.setVisible(true); setWindowAdapter(true); } } else { diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java index 33c291e96..7905a728c 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java @@ -57,6 +57,9 @@ public class AWTParentWindowAdapter // Need to resize the NEWT child window // the resized event will be send via the native window feedback. final java.awt.Component comp = e.getComponent(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: componentResized: "+comp); + } newtWindow.runOnEDTIfAvail(false, new Runnable() { public void run() { if( 0 < comp.getWidth() * comp.getHeight() ) { @@ -87,7 +90,7 @@ public class AWTParentWindowAdapter if( 0 != ( java.awt.event.HierarchyEvent.SHOWING_CHANGED & bits ) ) { final boolean showing = changed.isShowing(); if(DEBUG_IMPLEMENTATION) { - System.out.println("hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed); + System.out.println("AWT: hierarchyChanged SHOWING_CHANGED: showing "+showing+", "+changed); } if(!newtWindow.isDestroyed()) { newtWindow.runOnEDTIfAvail(false, new Runnable() { @@ -100,7 +103,7 @@ public class AWTParentWindowAdapter if( 0 != ( java.awt.event.HierarchyEvent.DISPLAYABILITY_CHANGED & bits ) ) { final boolean displayability = changed.isDisplayable(); if(DEBUG_IMPLEMENTATION) { - System.out.println("hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed); + System.out.println("AWT: hierarchyChanged DISPLAYABILITY_CHANGED: displayability "+displayability+", "+changed); } } } diff --git a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java index 570b0678a..ee7ca97ad 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTWindowAdapter.java @@ -105,6 +105,10 @@ public class AWTWindowAdapter } public void componentShown(java.awt.event.ComponentEvent e) { + final java.awt.Component comp = e.getComponent(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: componentShown: "+comp); + } /** if(null==newtListener) { if(!newtWindow.isDestroyed()) { @@ -118,6 +122,10 @@ public class AWTWindowAdapter } public void componentHidden(java.awt.event.ComponentEvent e) { + final java.awt.Component comp = e.getComponent(); + if(DEBUG_IMPLEMENTATION) { + System.out.println("AWT: componentHidden: "+comp); + } /** if(null==newtListener) { if(!newtWindow.isDestroyed()) { diff --git a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java index f97625320..a06b7160c 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java @@ -84,8 +84,7 @@ public class AWTWindow extends Window { // non fullscreen dimensions .. private int nfs_width, nfs_height, nfs_x, nfs_y; - public void setTitle(final String title) { - super.setTitle(title); + protected void setTitleImpl(final String title) { runOnEDT(true, new Runnable() { public void run() { if (frame != null) { @@ -265,17 +264,17 @@ public class AWTWindow extends Window { return canvas; } - protected void sendWindowEvent(int eventType) { - super.sendWindowEvent(eventType); + protected void enqueueWindowEvent(int eventType) { + super.enqueueWindowEvent(eventType); } - protected void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { - super.sendKeyEvent(eventType, modifiers, keyCode, keyChar); + protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + super.enqueueKeyEvent(eventType, modifiers, keyCode, keyChar); } - protected void sendMouseEvent(int eventType, int modifiers, + protected void enqueueMouseEvent(int eventType, int modifiers, int x, int y, int button, int rotation) { - super.sendMouseEvent(eventType, modifiers, x, y, button, rotation); + super.enqueueMouseEvent(eventType, modifiers, x, y, button, rotation); } private void runOnEDT(boolean wait, Runnable r) { diff --git a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java index 74cb53f7e..1b8a62a9c 100644 --- a/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/intel/gdl/Window.java @@ -116,7 +116,7 @@ public class Window extends com.jogamp.newt.Window { return fullscreen; } - public void requestFocus() { + protected void requestFocusImpl() { ((Display)screen.getDisplay()).setFocus(this); } diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java index b6328b02f..8a656a5a8 100755 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java @@ -231,8 +231,8 @@ public class MacWindow extends Window { } } - public void setTitle(String title) { - super.setTitle(title); + protected void setTitleImpl(final String title) { + // FIXME: move nsViewLock up to window lock nsViewLock.lock(); try { if (windowHandle != 0) { @@ -243,8 +243,8 @@ public class MacWindow extends Window { } } - public void requestFocus() { - super.requestFocus(); + protected void requestFocusImpl() { + // FIXME: move nsViewLock up to window lock nsViewLock.lock(); try { if (windowHandle != 0) { @@ -309,7 +309,7 @@ public class MacWindow extends Window { if (DEBUG_IMPLEMENTATION) { System.out.println(" Posted WINDOW_RESIZED event"); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } } @@ -340,15 +340,15 @@ public class MacWindow extends Window { if (DEBUG_IMPLEMENTATION) { System.out.println(" Posted WINDOW_MOVED event"); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); } } private void focusChanged(boolean focusGained) { if (focusGained) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } else { - sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); } } @@ -435,12 +435,12 @@ public class MacWindow extends Window { return keyChar; } - protected void sendKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { + protected void enqueueKeyEvent(int eventType, int modifiers, int keyCode, char keyChar) { int key = convertKeyChar(keyChar); - if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.sendKeyEvent "+Thread.currentThread().getName()); + if(DEBUG_IMPLEMENTATION) System.out.println("MacWindow.enqueueKeyEvent "+Thread.currentThread().getName()); // Note that we send the key char for the key code on this // platform -- we do not get any useful key codes out of the system - super.sendKeyEvent(eventType, modifiers, key, keyChar); + super.enqueueKeyEvent(eventType, modifiers, key, keyChar); } private void createWindow(final boolean recreate, final int x, final int y, final int width, final int height, final boolean fullscreen) { @@ -482,9 +482,9 @@ public class MacWindow extends Window { ie.printStackTrace(); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } protected static native boolean initIDs0(); diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java index 54623996c..0d12a4a0a 100755 --- a/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/opengl/kd/KDWindow.java @@ -135,7 +135,7 @@ public class KDWindow extends Window { } else { ((KDScreen)screen).setScreenSize(width, height); } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } private long eglWindowHandle; diff --git a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java index 5e1b5a43c..aedb4ed7d 100755 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -53,35 +53,21 @@ public class WindowsWindow extends Window { public WindowsWindow() { } - Thread hdcOwner = null; - - public synchronized int lockSurface() throws NativeWindowException { + public int lockSurface() throws NativeWindowException { int res = super.lockSurface(); - if(LOCK_SUCCESS==res && 0!=windowHandle) { - if(hdc!=0) { - throw new NativeWindowException("NEWT Surface handle set HDC "+toHexString(hdc)+" - "+Thread.currentThread().getName()+" ; "+this); - } + if( LOCK_SUCCESS == res && 0 != windowHandle && 0 == hdc ) { hdc = GetDC0(windowHandle); hmon = MonitorFromWindow0(windowHandle); - hdcOwner = Thread.currentThread(); } return res; } - public synchronized void unlockSurface() { - // prevalidate, before we change data .. - Thread cur = Thread.currentThread(); - if ( getSurfaceLockOwner() != cur ) { - getLockedStack().printStackTrace(); - throw new NativeWindowException(cur+": Not owner, owner is "+getSurfaceLockOwner()); - } - if (0!=hdc && 0!=windowHandle) { - if(hdcOwner != cur) { - throw new NativeWindowException("NEWT Surface handle set HDC "+toHexString(hdc)+" by other thread "+hdcOwner+", this "+cur+" ; "+this); - } + public void unlockSurface() { + getWindowLock().validateLocked(); + + if ( 0 != hdc && 0 != windowHandle && getWindowLock().getRecursionCount() == 0) { ReleaseDC0(windowHandle, hdc); hdc=0; - hdcOwner=null; } super.unlockSurface(); } @@ -187,23 +173,14 @@ public class WindowsWindow extends Window { return true; } - // @Override - public void requestFocus() { - super.requestFocus(); + protected void requestFocusImpl() { if (windowHandle != 0L) { - requestFocus0(windowHandle); + requestFocus0(fullscreen?0:parentWindowHandle, windowHandle); } } - // @Override - public void setTitle(String title) { - if (title == null) { - title = ""; - } - if (0!=windowHandle && !title.equals(getTitle())) { - super.setTitle(title); - setTitle0(windowHandle, title); - } + protected void setTitleImpl(final String title) { + setTitle0(windowHandle, title); } public Insets getInsets() { @@ -229,7 +206,7 @@ public class WindowsWindow extends Window { private native void setFullscreen0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated); private native void reparentWindow0(long parentWindowHandle, long windowHandle, int x, int y, int width, int height, boolean isUndecorated); private static native void setTitle0(long windowHandle, String title); - private static native void requestFocus0(long windowHandle); + private static native void requestFocus0(long parentWindowHandle, long windowHandle); private void insetsChanged(int left, int top, int right, int bottom) { if (left != -1 && top != -1 && right != -1 && bottom != -1) { @@ -248,7 +225,7 @@ public class WindowsWindow extends Window { nfs_width=width; nfs_height=height; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } } @@ -260,7 +237,7 @@ public class WindowsWindow extends Window { nfs_x=x; nfs_y=y; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); } } @@ -272,9 +249,9 @@ public class WindowsWindow extends Window { */ private void focusChanged(long focusOwner, boolean focusGained) { if (focusGained) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } else { - sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); } } } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java index 54fe0542b..6701d6c8e 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Display.java @@ -40,6 +40,7 @@ import com.jogamp.newt.impl.*; import com.jogamp.nativewindow.impl.x11.X11Util; public class X11Display extends Display { + static { NEWTJNILibLoader.loadNEWT(); @@ -65,7 +66,7 @@ public class X11Display extends Display { } protected void createNative() { - long handle= X11Util.createThreadLocalDisplay(name); + long handle = X11Util.createThreadLocalDisplay(name); if( 0 == handle ) { throw new RuntimeException("Error creating display: "+name); } @@ -89,16 +90,6 @@ public class X11Display extends Display { DispatchMessages0(getHandle(), javaObjectAtom, windowDeleteAtom); } - protected void lockDisplay() { - super.lockDisplay(); - X11Util.XLockDisplay(getHandle()); - } - - protected void unlockDisplay() { - X11Util.XUnlockDisplay(getHandle()); - super.unlockDisplay(); - } - protected long getJavaObjectAtom() { return javaObjectAtom; } protected long getWindowDeleteAtom() { return windowDeleteAtom; } diff --git a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java index a51eee241..e7fc96019 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -58,21 +58,20 @@ public class X11Window extends Window { X11GraphicsConfiguration x11config = (X11GraphicsConfiguration) config; long visualID = x11config.getVisualID(); long w = CreateWindow0(parentWindowHandle, - display.getHandle(), screen.getIndex(), visualID, - display.getJavaObjectAtom(), display.getWindowDeleteAtom(), - x, y, width, height, isUndecorated()); + display.getHandle(), screen.getIndex(), visualID, + display.getJavaObjectAtom(), display.getWindowDeleteAtom(), + x, y, width, height, isUndecorated()); if (w == 0 || w!=windowHandle) { throw new NativeWindowException("Error creating window: "+w); } windowHandleClose = windowHandle; - displayHandleClose = display.getHandle(); } protected void closeNative() { - if(0!=displayHandleClose && 0!=windowHandleClose && null!=getScreen() ) { + if(0!=windowHandleClose && null!=getScreen() ) { X11Display display = (X11Display) getScreen().getDisplay(); try { - CloseWindow0(displayHandleClose, windowHandleClose, display.getJavaObjectAtom()); + CloseWindow0(display.getHandle(), windowHandleClose, display.getJavaObjectAtom()); } catch (Throwable t) { if(DEBUG_IMPLEMENTATION) { Exception e = new Exception("closeNative failed - "+Thread.currentThread().getName(), t); @@ -80,14 +79,12 @@ public class X11Window extends Window { } } finally { windowHandleClose = 0; - displayHandleClose = 0; } } } protected void windowDestroyed() { windowHandleClose = 0; - displayHandleClose = 0; super.windowDestroyed(); } @@ -101,41 +98,31 @@ public class X11Window extends Window { } protected void setPositionImpl(int x, int y) { - // this x/y will be set by windowChanged, called by X11 setPosition0(parentWindowHandle, getDisplayHandle(), windowHandle, x, y); } protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { - setPosSizeDecor0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, w, h, isUndecorated(fullscreen)); + setPosSizeDecor0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, + x, y, w, h, isUndecorated(fullscreen), isVisible()); return fullscreen; } protected boolean reparentWindowImpl() { if(0!=windowHandle) { - reparentWindow0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, isUndecorated()); - // X11 reparent unmaps the window - setVisibleImpl(visible); + reparentWindow0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, + x, y, isUndecorated(), isVisible()); } return true; } - // @Override - public void requestFocus() { - super.requestFocus(); + protected void requestFocusImpl() { if (windowHandle != 0L) { requestFocus0(getDisplayHandle(), windowHandle); } } - // @Override - public void setTitle(String title) { - if (title == null) { - title = ""; - } - if (0!=windowHandle && !title.equals(getTitle())) { - super.setTitle(title); - setTitle0(getDisplayHandle(), windowHandle, title); - } + protected void setTitleImpl(String title) { + setTitle0(getDisplayHandle(), windowHandle, title); } @@ -151,12 +138,12 @@ public class X11Window extends Window { private native void setVisible0(long display, long windowHandle, boolean visible); private native void setSize0(long display, long windowHandle, int width, int height); private native void setPosSizeDecor0(long parentWindowHandle, long display, int screen_index, long windowHandle, - int x, int y, int width, int height, boolean undecorated); + int x, int y, int width, int height, boolean undecorated, boolean isVisible); private native void setTitle0(long display, long windowHandle, String title); private native void requestFocus0(long display, long windowHandle); private native void setPosition0(long parentWindowHandle, long display, long windowHandle, int x, int y); private native void reparentWindow0(long parentWindowHandle, long display, int screen_index, long windowHandle, - int x, int y, boolean undecorated); + int x, int y, boolean undecorated, boolean isVisible); private void windowChanged(int newX, int newY, int newWidth, int newHeight) { if(width != newWidth || height != newHeight) { @@ -169,7 +156,7 @@ public class X11Window extends Window { nfs_width=width; nfs_height=height; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); } if( 0==parentWindowHandle && ( x != newX || y != newY ) ) { if(DEBUG_IMPLEMENTATION) { @@ -181,7 +168,7 @@ public class X11Window extends Window { nfs_x=x; nfs_y=y; } - sendWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_MOVED); } } @@ -190,9 +177,9 @@ public class X11Window extends Window { */ private void focusChanged(boolean focusGained) { if (focusGained) { - sendWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_GAINED_FOCUS); } else { - sendWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); + enqueueWindowEvent(WindowEvent.EVENT_WINDOW_LOST_FOCUS); } } @@ -208,5 +195,4 @@ public class X11Window extends Window { } private long windowHandleClose; - private long displayHandleClose; } diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index dec41b427..7a223026e 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -161,29 +161,13 @@ public class GLWindow extends Window implements GLAutoDrawable { shouldNotCallThis(); } - protected void dispose() { - if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - Exception e1 = new Exception("GLWindow.dispose() "+Thread.currentThread()+", start: "+this); - e1.printStackTrace(); - } - - if ( null != context && context.isCreated() && null != drawable && drawable.isRealized() ) { - helper.invokeGL(drawable, context, disposeAction, null); - } - - if (context != null) { - context.destroy(); - context = null; - } - if (drawable != null) { - drawable.setRealized(false); - drawable = null; - } - - if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - System.out.println("GLWindow.dispose() "+Thread.currentThread()+", fin: "+this); + class DisposeAction implements Runnable { + public void run() { + // Lock: Covered by DestroyAction .. + helper.dispose(GLWindow.this); } } + private DisposeAction disposeAction = new DisposeAction(); class DestroyAction implements Runnable { boolean deep; @@ -191,12 +175,35 @@ public class GLWindow extends Window implements GLAutoDrawable { this.deep = deep; } public void run() { + // Lock: Have to cover whole workflow (dispose all, context, drawable and window) windowLock(); try { if(null==window || window.isDestroyed()) { return; // nop } - dispose(); + if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { + Exception e1 = new Exception("GLWindow.destroy("+deep+") "+Thread.currentThread()+", start: "+GLWindow.this); + e1.printStackTrace(); + } + + if ( null != context && context.isCreated() && null != drawable && drawable.isRealized() ) { + // Catch dispose GLExceptions by GLEventListener, just 'print' them + // so we can continue with the destruction. + try { + helper.invokeGL(drawable, context, disposeAction, null); + } catch (GLException gle) { + gle.printStackTrace(); + } + } + + if (context != null && null != drawable && drawable.isRealized() ) { + context.destroy(); + context = null; + } + if (drawable != null) { + drawable.setRealized(false); + drawable = null; + } if(null!=window) { window.destroy(deep); @@ -205,6 +212,9 @@ public class GLWindow extends Window implements GLAutoDrawable { if(deep) { helper=null; } + if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { + System.out.println("GLWindow.destroy("+deep+") "+Thread.currentThread()+", fin: "+GLWindow.this); + } } finally { windowUnlock(); } @@ -243,6 +253,7 @@ public class GLWindow extends Window implements GLAutoDrawable { this.visible = visible; } public void run() { + // Lock: Have to cover whole workflow (window, may do nativeCreation, drawable and context) windowLock(); try{ window.setVisible(visible); @@ -489,7 +500,12 @@ public class GLWindow extends Window implements GLAutoDrawable { if(forceReshape) { sendReshape = true; } - helper.invokeGL(drawable, context, displayAction, initAction); + windowLock(); + try{ + helper.invokeGL(drawable, context, displayAction, initAction); + } finally { + windowUnlock(); + } } } } @@ -506,6 +522,7 @@ public class GLWindow extends Window implements GLAutoDrawable { public void swapBuffers() { if(drawable!=null && context != null) { + // Lock: Locked Surface/Window by MakeCurrent/Release if (context != GLContext.getCurrent()) { // Assume we should try to make the context current before swapping the buffers helper.invokeGL(drawable, context, swapBuffersAction, initAction); @@ -517,6 +534,7 @@ public class GLWindow extends Window implements GLAutoDrawable { class InitAction implements Runnable { public void run() { + // Lock: Locked Surface/Window by MakeCurrent/Release helper.init(GLWindow.this); startTime = System.currentTimeMillis(); curTime = startTime; @@ -528,15 +546,9 @@ public class GLWindow extends Window implements GLAutoDrawable { } private InitAction initAction = new InitAction(); - class DisposeAction implements Runnable { - public void run() { - helper.dispose(GLWindow.this); - } - } - private DisposeAction disposeAction = new DisposeAction(); - class DisplayAction implements Runnable { public void run() { + // Lock: Locked Surface/Window by display _and_ MakeCurrent/Release if (sendReshape) { int width = getWidth(); int height = getHeight(); @@ -635,6 +647,10 @@ public class GLWindow extends Window implements GLAutoDrawable { return null!=drawable ? drawable.getNativeWindow() : null; } + public long getHandle() { + return null!=drawable ? drawable.getHandle() : 0; + } + //---------------------------------------------------------------------- // GLDrawable methods that are not really needed // diff --git a/src/newt/native/KDWindow.c b/src/newt/native/KDWindow.c index b67b8dbd3..82f2ba7df 100755 --- a/src/newt/native/KDWindow.c +++ b/src/newt/native/KDWindow.c @@ -96,8 +96,8 @@ static jmethodID windowCreatedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; /** * Display @@ -180,13 +180,13 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDDisplay_DispatchMes // 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, + (*env)->CallVoidMethod(env, javaWindow, enqueueMouseEventID, (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, + (*env)->CallVoidMethod(env, javaWindow, enqueueMouseEventID, (jint) EVENT_MOUSE_MOVED, 0, (jint) ptr->x, (jint) ptr->y, 0, 0); } @@ -213,14 +213,14 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_opengl_kd_KDWindow_initIDs 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"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); if (windowCreatedID == NULL || sizeChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || - sendMouseEventID == NULL || - sendKeyEventID == NULL) { + enqueueMouseEventID == NULL || + enqueueKeyEventID == NULL) { DBG_PRINT( "initIDs failed\n" ); return JNI_FALSE; } diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index d8d59a7af..ae658b908 100755 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -109,8 +109,8 @@ jint GetDeltaY(NSEvent *event, jint javaMods) { @end -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; static jmethodID insetsChangedID = NULL; static jmethodID sizeChangedID = NULL; static jmethodID positionChangedID = NULL; @@ -122,15 +122,15 @@ static jmethodID windowDestroyedID = NULL; + (BOOL) initNatives: (JNIEnv*) env forClass: (jclass) clazz { - sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); - sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(II)V"); insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(IIII)V"); positionChangedID = (*env)->GetMethodID(env, clazz, "positionChanged", "(II)V"); focusChangedID = (*env)->GetMethodID(env, clazz, "focusChanged", "(Z)V"); windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()V"); - if (sendMouseEventID && sendKeyEventID && sizeChangedID && insetsChangedID && + if (enqueueMouseEventID && enqueueKeyEventID && sizeChangedID && insetsChangedID && positionChangedID && focusChangedID && windowDestroyedID && windowDestroyNotifyID) { return YES; @@ -206,7 +206,7 @@ static jint mods2JavaMods(NSUInteger mods) return javaMods; } -- (void) sendKeyEvent: (NSEvent*) event eventType: (jint) evType +- (void) enqueueKeyEvent: (NSEvent*) event eventType: (jint) evType { NSView* nsview = [self contentView]; if( ! [nsview isMemberOfClass:[NewtView class]] ) { @@ -229,23 +229,23 @@ static jint mods2JavaMods(NSUInteger mods) // Note: the key code in the NSEvent does not map to anything we can use jchar keyChar = (jchar) [chars characterAtIndex: i]; - (*env)->CallVoidMethod(env, javaWindowObject, sendKeyEventID, + (*env)->CallVoidMethod(env, javaWindowObject, enqueueKeyEventID, evType, javaMods, keyCode, keyChar); } } - (void) keyDown: (NSEvent*) theEvent { - [self sendKeyEvent: theEvent eventType: EVENT_KEY_PRESSED]; + [self enqueueKeyEvent: theEvent eventType: EVENT_KEY_PRESSED]; } - (void) keyUp: (NSEvent*) theEvent { - [self sendKeyEvent: theEvent eventType: EVENT_KEY_RELEASED]; - [self sendKeyEvent: theEvent eventType: EVENT_KEY_TYPED]; + [self enqueueKeyEvent: theEvent eventType: EVENT_KEY_RELEASED]; + [self enqueueKeyEvent: theEvent eventType: EVENT_KEY_TYPED]; } -- (void) sendMouseEvent: (NSEvent*) event eventType: (jint) evType +- (void) enqueueMouseEvent: (NSEvent*) event eventType: (jint) evType { NSView* nsview = [self contentView]; if( ! [nsview isMemberOfClass:[NewtView class]] ) { @@ -302,7 +302,7 @@ static jint mods2JavaMods(NSUInteger mods) // ignore 0 increment wheel scroll events return; } - (*env)->CallVoidMethod(env, javaWindowObject, sendMouseEventID, + (*env)->CallVoidMethod(env, javaWindowObject, enqueueMouseEventID, evType, javaMods, (jint) location.x, (jint) (contentRect.size.height - location.y), @@ -311,70 +311,70 @@ static jint mods2JavaMods(NSUInteger mods) - (void) mouseEntered: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_ENTERED]; } - (void) mouseExited: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_EXITED]; } - (void) mouseMoved: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) scrollWheel: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_WHEEL_MOVED]; } - (void) mouseDown: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; } - (void) mouseDragged: (NSEvent*) theEvent { // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) mouseUp: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; } - (void) rightMouseDown: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; } - (void) rightMouseDragged: (NSEvent*) theEvent { // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) rightMouseUp: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; } - (void) otherMouseDown: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_PRESSED]; } - (void) otherMouseDragged: (NSEvent*) theEvent { // Note use of MOUSE_MOVED event type because mouse dragged events are synthesized by Java - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_MOVED]; } - (void) otherMouseUp: (NSEvent*) theEvent { - [self sendMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; + [self enqueueMouseEvent: theEvent eventType: EVENT_MOUSE_RELEASED]; } - (void)windowDidResize: (NSNotification*) notification diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index 37fd9c621..5e3311d3b 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -115,8 +115,8 @@ static jmethodID positionChangedID = NULL; static jmethodID focusChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; static jmethodID sendPaintEventID = NULL; static RECT* UpdateInsets(JNIEnv *env, HWND hwnd, jobject window); @@ -506,7 +506,7 @@ static int WmChar(JNIEnv *env, jobject window, UINT character, UINT repCnt, if (character == VK_RETURN) { character = J_VK_ENTER; } - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_TYPED, GetModifiers(), (jint) -1, @@ -551,7 +551,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, character = WindowsKeyToJavaChar(wkey, modifiers, SAVE); */ - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_PRESSED, modifiers, (jint) jkey, @@ -562,7 +562,7 @@ static int WmKeyDown(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, WM_KEYDOWN. */ if (jkey == J_VK_DELETE) { - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_TYPED, GetModifiers(), (jint) -1, @@ -586,7 +586,7 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, character = WindowsKeyToJavaChar(wkey, modifiers, SAVE); */ - (*env)->CallVoidMethod(env, window, sendKeyEventID, + (*env)->CallVoidMethod(env, window, enqueueKeyEventID, (jint) EVENT_KEY_RELEASED, modifiers, (jint) jkey, @@ -595,11 +595,23 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, return 0; } -static void NewtWindows_requestFocus (HWND hwnd) { +static void NewtWindows_requestFocus (HWND hwnd, BOOL topLevel, BOOL reparented) { + DBG_PRINT("*** WindowsWindow: requestFocus.0 window %p\n", (void*)hwnd); if (IsWindow(hwnd)) { - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); + UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; + if(reparented) { + flags |= SWP_FRAMECHANGED; + } + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags); + DBG_PRINT("*** WindowsWindow: requestFocus.1\n"); SetForegroundWindow(hwnd); // Slightly Higher Priority + DBG_PRINT("*** WindowsWindow: requestFocus.2\n"); SetFocus(hwnd);// Sets Keyboard Focus To TheWindow + DBG_PRINT("*** WindowsWindow: requestFocus.3\n"); + if(topLevel) { + SetActiveWindow(hwnd); + } + DBG_PRINT("*** WindowsWindow: requestFocus.X\n"); } } @@ -786,8 +798,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, case WM_LBUTTONDOWN: - NewtWindows_requestFocus ( wnd ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, sendMouseEventID, + NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -796,7 +808,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_LBUTTONUP: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -805,8 +817,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MBUTTONDOWN: - NewtWindows_requestFocus ( wnd ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, sendMouseEventID, + NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -815,7 +827,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MBUTTONUP: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -824,8 +836,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_RBUTTONDOWN: - NewtWindows_requestFocus ( wnd ); // request focus on this window, if not already .. - (*env)->CallVoidMethod(env, window, sendMouseEventID, + NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -834,7 +846,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_RBUTTONUP: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_RELEASED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -843,7 +855,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MOUSEMOVE: - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_MOVED, GetModifiers(), (jint) LOWORD(lParam), (jint) HIWORD(lParam), @@ -859,7 +871,7 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, eventPt.x = x; eventPt.y = y; ScreenToClient(wnd, &eventPt); - (*env)->CallVoidMethod(env, window, sendMouseEventID, + (*env)->CallVoidMethod(env, window, enqueueMouseEventID, (jint) EVENT_MOUSE_WHEEL_MOVED, GetModifiers(), (jint) eventPt.x, (jint) eventPt.y, @@ -1046,8 +1058,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI 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"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); sendPaintEventID = (*env)->GetMethodID(env, clazz, "sendPaintEvent", "(IIIII)V"); if (sizeChangedID == NULL || insetsChangedID == NULL || @@ -1055,9 +1067,9 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI focusChangedID == NULL || windowDestroyNotifyID == NULL || windowDestroyedID == NULL || - sendMouseEventID == NULL || + enqueueMouseEventID == NULL || sendPaintEventID == NULL || - sendKeyEventID == NULL) + enqueueKeyEventID == NULL) { return JNI_FALSE; } @@ -1130,7 +1142,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi ShowWindow(window, SW_SHOWNORMAL); if(NULL!=parentWindow) { - NewtWindows_requestFocus ( window ); // request focus on this window, if not already .. + NewtWindows_requestFocus ( window, FALSE, FALSE ); // request focus on this window, if not already .. } /* else { // top level already capable of receiving [keyboard] events } */ @@ -1154,6 +1166,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_DestroyWindow0 (JNIEnv *env, jobject obj, jlong window) { + DBG_PRINT("*** WindowsWindow: DestroyWindow window %p\n", window); DestroyWindow((HWND) (intptr_t) window); } @@ -1279,25 +1292,34 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setPositi } } -/* - * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: setFullscreen - * Signature: (JIIIIZ)V - */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullscreen0 - (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) +static void NewtWindows_reparentWindow(HWND hwndP, HWND hwnd, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) { UINT flags; - HWND hwndP = (HWND) (intptr_t) parent; - HWND hwnd = (HWND) (intptr_t) window; HWND hWndInsertAfter; - DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN ; + BOOL isVisible = IsWindowVisible(hwnd); + + DBG_PRINT("*** WindowsWindow: reparentWindow.1 parent %p, window %p, %d/%d %dx%d undeco %d visible %d\n", (void*)hwndP, (void*)hwnd, x, y, width, height, bIsUndecorated, isVisible); + if (!IsWindow(hwnd)) { + DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed window %p is invalid\n", (void*)hwnd); + return; + } + if (NULL!=hwndP && !IsWindow(hwndP)) { + DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed parent window %p is invalid\n", (void*)hwndP); + return; + } + + if (isVisible) { + windowStyle |= WS_VISIBLE; + } // order of call sequence: (MS documentation) - // SetParent(.., NULL), SetWindowLong ( WS_POPUP ) - // SetParent(.., PARENT), SetWindowLong ( WS_CHILD ) + // TOP: SetParent(.., NULL); Clear WS_CHILD [, Set WS_POPUP] + // CHILD: Set WS_CHILD [, Clear WS_POPUP]; SetParent(.., PARENT) + // if ( NULL == hwndP ) { SetParent(hwnd, NULL); + DBG_PRINT("*** WindowsWindow: reparentWindow.2\n"); } if(NULL!=hwndP) { @@ -1308,32 +1330,26 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc windowStyle |= WS_OVERLAPPEDWINDOW; } SetWindowLong(hwnd, GWL_STYLE, windowStyle); + DBG_PRINT("*** WindowsWindow: reparentWindow.3\n"); if ( NULL != hwndP ) { SetParent(hwnd, hwndP ); + DBG_PRINT("*** WindowsWindow: reparentWindow.4\n"); } - if ( NULL == hwndP ) { - flags = SWP_SHOWWINDOW; - hWndInsertAfter = HWND_TOPMOST; - } else { - flags = SWP_NOACTIVATE | SWP_NOZORDER; - hWndInsertAfter = 0; + if(isVisible) { + NewtWindows_requestFocus ( hwnd, ( NULL == hwndP ) ? TRUE : FALSE, TRUE ); } - SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags); - - NewtWindows_requestFocus ( hwnd ); - - (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); + DBG_PRINT("*** WindowsWindow: reparentWindow.X\n"); } /* * Class: com_jogamp_newt_impl_windows_WindowsWindow - * Method: reparentWindow0 + * Method: setFullscreen * Signature: (JIIIIZ)V */ -JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentWindow0 +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullscreen0 (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) { UINT flags; @@ -1341,28 +1357,13 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentW HWND hwnd = (HWND) (intptr_t) window; HWND hWndInsertAfter; DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; + BOOL isVisible = IsWindowVisible(hwnd); - // order of call sequence: (MS documentation) - // SetParent(.., NULL), SetWindowLong ( WS_POPUP ) - // SetParent(.., PARENT), SetWindowLong ( WS_CHILD ) - if ( NULL == hwndP ) { - SetParent(hwnd, NULL); - } + DBG_PRINT("*** WindowsWindow: setFullscreen.1 parent %p, window %p, %d/%d %dx%d undeco %d visible\n", + parent, window, x, y, width, height, bIsUndecorated, isVisible); - if(NULL!=hwndP) { - windowStyle |= WS_CHILD ; - } else if (bIsUndecorated) { - windowStyle |= WS_POPUP | WS_SYSMENU | WS_MAXIMIZEBOX | WS_MINIMIZEBOX; - } else { - windowStyle |= WS_OVERLAPPEDWINDOW; - } - SetWindowLong(hwnd, GWL_STYLE, windowStyle); + NewtWindows_reparentWindow(hwndP, hwnd, x, y, width, height, bIsUndecorated); - if ( NULL != hwndP ) { - SetParent(hwnd, hwndP ); - } - - /** if ( NULL == hwndP ) { flags = SWP_SHOWWINDOW; hWndInsertAfter = HWND_TOPMOST; @@ -1372,11 +1373,23 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentW } SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags); - */ - NewtWindows_requestFocus ( hwnd ); + DBG_PRINT("*** WindowsWindow: setFullscreen.X\n"); + (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); // resize necessary .. +} + +/* + * Class: com_jogamp_newt_impl_windows_WindowsWindow + * Method: reparentWindow0 + * Signature: (JIIIIZ)V + */ +JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentWindow0 + (JNIEnv *env, jobject obj, jlong parent, jlong window, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) +{ + HWND hwndP = (HWND) (intptr_t) parent; + HWND hwnd = (HWND) (intptr_t) window; - // (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); + NewtWindows_reparentWindow(hwndP, hwnd, x, y, width, height, bIsUndecorated); } /* @@ -1403,8 +1416,8 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setTitle0 * Signature: (J)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_requestFocus0 - (JNIEnv *env, jclass clazz, jlong window) + (JNIEnv *env, jclass clazz, jlong parent, jlong window) { - NewtWindows_requestFocus ( (HWND) (intptr_t) window ) ; + NewtWindows_requestFocus ( (HWND) (intptr_t) window, (0 == parent) ? TRUE : FALSE, FALSE ) ; } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index f77f54cd1..a521d2dbd 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -58,18 +58,7 @@ // #define VERBOSE_ON 1 #ifdef VERBOSE_ON - // Workaround for ancient compiler on Solaris/SPARC - // #define DBG_PRINT(args...) fprintf(stderr, args); - #define DBG_PRINT0(str) fprintf(stderr, str); - #define DBG_PRINT1(str, arg1) fprintf(stderr, str, arg1); - #define DBG_PRINT2(str, arg1, arg2) fprintf(stderr, str, arg1, arg2); - #define DBG_PRINT3(str, arg1, arg2, arg3) fprintf(stderr, str, arg1, arg2, arg3); - #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) fprintf(stderr, str, arg1, arg2, arg3, arg4); - #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5); - #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6); - #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7); - #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); - #define DBG_PRINT9(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) fprintf(stderr, str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); + #define DBG_PRINT(...) fprintf(stderr, __VA_ARGS__); fflush(stderr) #define DUMP_VISUAL_INFO(a,b) _dumpVisualInfo((a),(b)) @@ -95,18 +84,7 @@ #else - // Workaround for ancient compiler on Solaris/SPARC - // #define DBG_PRINT(args...) - #define DBG_PRINT0(str) - #define DBG_PRINT1(str, arg1) - #define DBG_PRINT2(str, arg1, arg2) - #define DBG_PRINT3(str, arg1, arg2, arg3) - #define DBG_PRINT4(str, arg1, arg2, arg3, arg4) - #define DBG_PRINT5(str, arg1, arg2, arg3, arg4, arg5) - #define DBG_PRINT6(str, arg1, arg2, arg3, arg4, arg5, arg6) - #define DBG_PRINT7(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7) - #define DBG_PRINT8(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) - #define DBG_PRINT9(str, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) + #define DBG_PRINT(...) #define DUMP_VISUAL_INFO(a,b) @@ -179,8 +157,8 @@ static jmethodID visibleChangedID = NULL; static jmethodID windowDestroyNotifyID = NULL; static jmethodID windowDestroyedID = NULL; static jmethodID windowCreatedID = NULL; -static jmethodID sendMouseEventID = NULL; -static jmethodID sendKeyEventID = NULL; +static jmethodID enqueueMouseEventID = NULL; +static jmethodID enqueueKeyEventID = NULL; static jmethodID displayCompletedID = NULL; @@ -189,10 +167,6 @@ static void _throwNewRuntimeException(Display * unlockDisplay, JNIEnv *env, cons char buffer[512]; va_list ap; - if(NULL!=unlockDisplay) { - XUnlockDisplay(unlockDisplay); - } - va_start(ap, msg); vsnprintf(buffer, sizeof(buffer), msg, ap); va_end(ap); @@ -293,7 +267,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0 if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; javaObjectAtom = (jlong) XInternAtom(dpy, "JOGL_JAVA_OBJECT", False); if(None==javaObjectAtom) { @@ -308,9 +281,8 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_CompleteDisplay0 } // XSetCloseDownMode(dpy, RetainTemporary); // Just a try .. - XUnlockDisplay(dpy) ; - DBG_PRINT1("X11: X11Display_completeDisplay dpy %p\n", dpy); + DBG_PRINT("X11: X11Display_completeDisplay dpy %p\n", dpy); (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom); } @@ -409,13 +381,9 @@ static void NewtWindows_requestFocus0 (Display *dpy, Window w, XWindowAttributes static void NewtWindows_requestFocus1 (Display *dpy, Window w) { XWindowAttributes xwa; - XLockDisplay(dpy) ; - XGetWindowAttributes(dpy, w, &xwa); NewtWindows_requestFocus0 (dpy, w, &xwa); XSync(dpy, False); - - XUnlockDisplay(dpy) ; } /** @@ -480,14 +448,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages char keyChar; char text[255]; - XLockDisplay(dpy) ; - // num_events = XPending(dpy); // I/O Flush .. // num_events = XEventsQueued(dpy, QueuedAfterFlush); // I/O Flush only of no already queued events are available // num_events = XEventsQueued(dpy, QueuedAlready); // no I/O Flush at all, doesn't work on some cards (eg ATI) if ( 0 >= XEventsQueued(dpy, QueuedAfterFlush) ) { - XUnlockDisplay(dpy) ; - // DBG_PRINT1( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); + // DBG_PRINT( "X11: DispatchMessages 0x%X - Leave 1\n", dpy); return; } @@ -504,7 +469,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages return ; } - DBG_PRINT3( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); + DBG_PRINT( "X11: DispatchMessages dpy %p, win %p, Event %d\n", (void*)dpy, (void*)evt.xany.window, evt.type); displayDispatchErrorHandlerEnable(1, env); @@ -521,8 +486,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages if(NULL==jwindow) { fprintf(stderr, "Warning: NEWT X11 DisplayDispatch %p, Couldn't handle event %d for X11 window %p\n", (void*)dpy, evt.type, (void*)evt.xany.window); - - XUnlockDisplay(dpy) ; continue; } @@ -539,49 +502,47 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages break; } - XUnlockDisplay(dpy) ; - switch(evt.type) { case ButtonPress: NewtWindows_requestFocus1 ( dpy, evt.xany.window ); - (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (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, + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (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, + (*env)->CallVoidMethod(env, jwindow, enqueueMouseEventID, (jint) EVENT_MOUSE_MOVED, (jint) evt.xmotion.state, (jint) evt.xmotion.x, (jint) evt.xmotion.y, (jint) 0, 0 /*rotation*/); break; case KeyPress: - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_PRESSED, + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_PRESSED, (jint) evt.xkey.state, X11KeySym2NewtVKey(keySym), (jchar) keyChar); break; case KeyRelease: - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_RELEASED, + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_RELEASED, (jint) evt.xkey.state, X11KeySym2NewtVKey(keySym), (jchar) keyChar); - (*env)->CallVoidMethod(env, jwindow, sendKeyEventID, (jint) EVENT_KEY_TYPED, + (*env)->CallVoidMethod(env, jwindow, enqueueKeyEventID, (jint) EVENT_KEY_TYPED, (jint) evt.xkey.state, (jint) -1, (jchar) keyChar); break; case DestroyNotify: - DBG_PRINT1( "X11: event . DestroyNotify call 0x%X\n", (unsigned int)evt.xdestroywindow.window); + DBG_PRINT( "X11: event . DestroyNotify call 0x%X\n", (unsigned int)evt.xdestroywindow.window); (*env)->CallVoidMethod(env, jwindow, windowDestroyedID); break; case CreateNotify: - DBG_PRINT1( "X11: event . CreateNotify call 0x%X\n", (unsigned int)evt.xcreatewindow.window); + DBG_PRINT( "X11: event . CreateNotify call 0x%X\n", (unsigned int)evt.xcreatewindow.window); (*env)->CallVoidMethod(env, jwindow, windowCreatedID); break; case ConfigureNotify: - DBG_PRINT8( "X11: event . ConfigureNotify call 0x%X (parent 0x%X, above 0x%X) %d/%d %dx%d %d\n", + DBG_PRINT( "X11: event . ConfigureNotify call 0x%X (parent 0x%X, above 0x%X) %d/%d %dx%d %d\n", (unsigned int)evt.xconfigure.window, (unsigned int)evt.xconfigure.event, (unsigned int)evt.xconfigure.above, evt.xconfigure.x, evt.xconfigure.y, evt.xconfigure.width, evt.xconfigure.height, evt.xconfigure.override_redirect); @@ -591,43 +552,43 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages break; case ClientMessage: if (evt.xclient.send_event==True && evt.xclient.data.l[0]==(Atom)wmDeleteAtom) { - DBG_PRINT2( "X11: event . ClientMessage call 0x%X type 0x%X !!!\n", (unsigned int)evt.xclient.window, (unsigned int)evt.xclient.message_type); + DBG_PRINT( "X11: event . ClientMessage call 0x%X type 0x%X !!!\n", (unsigned int)evt.xclient.window, (unsigned int)evt.xclient.message_type); (*env)->CallVoidMethod(env, jwindow, windowDestroyNotifyID); // Called by Window.java: CloseWindow(); } break; case FocusIn: - DBG_PRINT1( "X11: event . FocusIn call 0x%X\n", (unsigned int)evt.xvisibility.window); + DBG_PRINT( "X11: event . FocusIn call 0x%X\n", (unsigned int)evt.xvisibility.window); (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_TRUE); break; case FocusOut: - DBG_PRINT1( "X11: event . FocusOut call 0x%X\n", (unsigned int)evt.xvisibility.window); + DBG_PRINT( "X11: event . FocusOut call 0x%X\n", (unsigned int)evt.xvisibility.window); (*env)->CallVoidMethod(env, jwindow, focusChangedID, JNI_FALSE); break; case MapNotify: - DBG_PRINT1( "X11: event . MapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); + DBG_PRINT( "X11: event . MapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_TRUE); break; case UnmapNotify: - DBG_PRINT1( "X11: event . UnmapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); + DBG_PRINT( "X11: event . UnmapNotify call 0x%X\n", (unsigned int)evt.xunmap.window); // FIXME (*env)->CallVoidMethod(env, jwindow, visibleChangedID, JNI_FALSE); break; // unhandled events .. yet .. case VisibilityNotify: - DBG_PRINT1( "X11: event . VisibilityNotify call 0x%X\n", (unsigned int)evt.xvisibility.window); + DBG_PRINT( "X11: event . VisibilityNotify call 0x%X\n", (unsigned int)evt.xvisibility.window); break; case Expose: - DBG_PRINT1( "X11: event . Expose call 0x%X\n", (unsigned int)evt.xexpose.window); + DBG_PRINT( "X11: event . Expose call 0x%X\n", (unsigned int)evt.xexpose.window); /* FIXME: Might want to send a repaint event .. */ break; default: - DBG_PRINT3("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window); + DBG_PRINT("X11: event . unhandled %d 0x%X call 0x%X\n", evt.type, evt.type, (unsigned int)evt.xunmap.window); } } } @@ -648,10 +609,11 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_GetScreen0 Display * dpy = (Display *)(intptr_t)display; Screen * scrn= NULL; + DBG_PRINT("X11: X11Screen_GetScreen0 dpy %p START\n", dpy); + if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy); scrn = ScreenOfDisplay(dpy,screen_index); if(scrn==NULL) { @@ -660,7 +622,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Screen_GetScreen0 if(scrn==NULL) { fprintf(stderr, "couldn't get screen ..\n"); } - XUnlockDisplay(dpy) ; + DBG_PRINT("X11: X11Screen_GetScreen0 scrn %p DONE\n", scrn); return (jlong) (intptr_t) scrn; } @@ -697,8 +659,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 windowDestroyNotifyID = (*env)->GetMethodID(env, clazz, "windowDestroyNotify", "()V"); windowDestroyedID = (*env)->GetMethodID(env, clazz, "windowDestroyed", "()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"); + enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(IIIIII)V"); + enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(IIIC)V"); if (windowChangedID == NULL || focusChangedID == NULL || @@ -706,8 +668,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 windowDestroyNotifyID == NULL || windowDestroyedID == NULL || windowCreatedID == NULL || - sendMouseEventID == NULL || - sendKeyEventID == NULL) { + enqueueMouseEventID == NULL || + enqueueKeyEventID == NULL) { return JNI_FALSE; } return JNI_TRUE; @@ -751,15 +713,13 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 return 0; } - XLockDisplay(dpy) ; - XSync(dpy, False); scrn = ScreenOfDisplay(dpy, scrn_idx); if(0==windowParent) { windowParent = XRootWindowOfScreen(scrn); } - DBG_PRINT7( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d\n", + DBG_PRINT( "X11: CreateWindow dpy %p, parent %p, %x/%d %dx%d, undeco %d\n", (void*)dpy, (void*)windowParent, x, y, width, height, undecorated); // try given VisualID on screen @@ -775,7 +735,7 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 XFree(pVisualQuery); pVisualQuery=NULL; } - DBG_PRINT5( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", + DBG_PRINT( "X11: [CreateWindow] trying given (dpy %p, screen %d, visualID: %d, parent %p) found: %p\n", dpy, scrn_idx, (int)visualID, (void*)windowParent, visual); if (visual==NULL) @@ -831,12 +791,10 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CreateWindow0 XSelectInput(dpy, window, xevent_mask); } - NewtWindows_setDecorations (dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); - + NewtWindows_setDecorations(dpy, window, ( JNI_TRUE == undecorated ) ? False : True ); XSync(dpy, False); - XUnlockDisplay(dpy) ; - DBG_PRINT2( "X11: [CreateWindow] created window 0x%X on display %p\n", (unsigned int)window, dpy); + DBG_PRINT( "X11: [CreateWindow] created window 0x%X on display %p\n", (unsigned int)window, dpy); (*env)->CallVoidMethod(env, obj, windowCreatedID, (jlong) window); return (jlong) window; @@ -857,9 +815,8 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; - DBG_PRINT2( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); + DBG_PRINT( "X11: CloseWindow START dpy %p, win %p\n", (void*)dpy, (void*)w); jwindow = getJavaWindowProperty(env, dpy, w, javaObjectAtom, True); if(NULL==jwindow) { @@ -878,8 +835,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_CloseWindow0 XDestroyWindow(dpy, w); XSync(dpy, False); - DBG_PRINT0( "X11: CloseWindow END\n"); - XUnlockDisplay(dpy) ; + DBG_PRINT( "X11: CloseWindow END\n"); (*env)->CallVoidMethod(env, obj, windowDestroyedID); } @@ -894,12 +850,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; - DBG_PRINT1( "X11: setVisible0 vis %d\n", visible); + DBG_PRINT( "X11: setVisible0 vis %d\n", visible); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; if(visible==JNI_TRUE) { XMapRaised(dpy, w); @@ -907,7 +862,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setVisible0 XUnmapWindow(dpy, w); } XSync(dpy, False); - XUnlockDisplay(dpy) ; } /* @@ -922,12 +876,11 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 Window w = (Window)window; XWindowChanges xwc; - DBG_PRINT2( "X11: setSize0 %dx%d\n", width, height); + DBG_PRINT( "X11: setSize0 %dx%d\n", width, height); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; memset(&xwc, 0, sizeof(XWindowChanges)); xwc.width=width; @@ -935,7 +888,6 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setSize0 XConfigureWindow(dpy, w, CWWidth|CWHeight, &xwc); XSync(dpy, False); - XUnlockDisplay(dpy) ; } /* @@ -950,47 +902,60 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 Window w = (Window)window; XWindowChanges xwc; - DBG_PRINT2( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y); + DBG_PRINT( "X11: setPos0 . XConfigureWindow %d/%d\n", x, y); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; xwc.y=y; XConfigureWindow(dpy, w, CWX|CWY, &xwc); XSync(dpy, False); - - XUnlockDisplay(dpy) ; } static void NewtWindows_reparentWindow - (Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent, jint x, jint y, jboolean undecorated) + (Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent, jint x, jint y, jboolean undecorated, jboolean isVisible) { Window parent = (0!=jparent)?(Window)jparent:XRootWindowOfScreen(scrn); - DBG_PRINT7( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n", + DBG_PRINT( "X11: reparentWindow dpy %p, parent %p/%p, win %p, %d/%d undec %d\n", (void*)dpy, (void*) jparent, (void*)parent, (void*)w, x, y, undecorated); - // let parent ignore reparent request - NewtWindows_setOverrideRedirect0 (dpy, w, xwa, True); - if(JNI_TRUE == undecorated) { + if(0 != jparent) { + // move into parent .. NewtWindows_setDecorations (dpy, w, False); + XSync(dpy, False); + NewtWindows_setOverrideRedirect0 (dpy, w, xwa, True); + XSync(dpy, False); + } + + if(JNI_TRUE == isVisible) { + XUnmapWindow(dpy, w); + XSync(dpy, False); } - XSync(dpy, False); XReparentWindow( dpy, w, parent, x, y ); - XRaiseWindow(dpy, w); XSync(dpy, False); - NewtWindows_setOverrideRedirect0 (dpy, w, xwa, ( 0 != jparent ) ? True : False ); - if(JNI_FALSE == undecorated) { - NewtWindows_setDecorations (dpy, w, True); + if(0 == jparent) + { + // move out of parent .. + NewtWindows_setOverrideRedirect0 (dpy, w, xwa, (0 == jparent) ? False : True); + XSync(dpy, False); + NewtWindows_setDecorations (dpy, w, (JNI_TRUE == undecorated) ? False : True); + XSync(dpy, False); } - XSync(dpy, False); - DBG_PRINT0( "X11: reparentWindow X\n"); + if(JNI_TRUE == isVisible) { + XRaiseWindow(dpy, w); + XSync(dpy, False); + + XMapWindow(dpy, w); + XSync(dpy, False); + } + + DBG_PRINT( "X11: reparentWindow X\n"); } /* @@ -1000,7 +965,7 @@ static void NewtWindows_reparentWindow */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, - jint x, jint y, jint width, jint height, jboolean undecorated) + jint x, jint y, jint width, jint height, jboolean undecorated, jboolean isVisible) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; @@ -1009,18 +974,18 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 XWindowChanges xwc; XWindowAttributes xwa; - DBG_PRINT8( "X11: setPosSizeDecor0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d\n", - (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated); + DBG_PRINT( "X11: setPosSizeDecor0 dpy %p, parent %p, win %p, %d/%d %dx%d undec %d, visible %d\n", + (void*)dpy, (void*) jparent, (void*)w, x, y, width, height, undecorated, isVisible); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; XSync(dpy, False); XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated); + NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); + XSync(dpy, False); memset(&xwc, 0, sizeof(XWindowChanges)); xwc.x=x; @@ -1028,11 +993,12 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 xwc.width=width; xwc.height=height; XConfigureWindow(dpy, w, CWX|CWY|CWWidth|CWHeight, &xwc); - XSync(dpy, False); - NewtWindows_requestFocus0 ( dpy, w, &xwa ); - XSync(dpy, False); - XUnlockDisplay(dpy) ; + if(JNI_TRUE == isVisible) { + XGetWindowAttributes(dpy, w, &xwa); + NewtWindows_requestFocus0 ( dpy, w, &xwa ); + XSync(dpy, False); + } } /* @@ -1041,28 +1007,28 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 * Signature: (JJIJIIZ)V */ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0 - (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y, jboolean undecorated) + (JNIEnv *env, jobject obj, jlong jparent, jlong display, jint screen_index, jlong window, jint x, jint y, + jboolean undecorated, jboolean isVisible) { Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; Screen * scrn = ScreenOfDisplay(dpy, (int)screen_index); XWindowAttributes xwa; - DBG_PRINT6( "X11: reparentWindow0 dpy %p, parent %p, win %p, %d/%d undec %d\n", - (void*)dpy, (void*) jparent, (void*)w, x, y, undecorated); + DBG_PRINT( "X11: reparentWindow0 dpy %p, parent %p, win %p, %d/%d undec %d, visible %d\n", + (void*)dpy, (void*) jparent, (void*)w, x, y, undecorated, isVisible); if(dpy==NULL) { _FatalError(env, "invalid display connection.."); } - XLockDisplay(dpy) ; XSync(dpy, False); XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated); + NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); + XSync(dpy, False); - XUnlockDisplay(dpy) ; - DBG_PRINT0( "X11: reparentWindow0 X\n"); + DBG_PRINT( "X11: reparentWindow0 X\n"); } /* @@ -1087,15 +1053,19 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0 Display * dpy = (Display *) (intptr_t) display; Window w = (Window)window; - XLockDisplay(dpy) ; #if 1 const char* title_str; if (NULL != title) { title_str = (*env)->GetStringUTFChars(env, title, NULL); if(NULL != title_str) { + DBG_PRINT( "X11: setTitle: <%s> SET\n", title_str); XStoreName(dpy, w, title_str); (*env)->ReleaseStringUTFChars(env, title, title_str); + } else { + DBG_PRINT( "X11: setTitle: NULL - NOT SET (1)\n"); } + } else { + DBG_PRINT( "X11: setTitle: NULL TITLE\n"); } #else char *str_list[] = { NULL }; @@ -1105,18 +1075,22 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setTitle0 if (str_list[0] != NULL) { memset(&text_prop, 0, sizeof(XTextProperty)); if ( Success != XmbTextListToTextProperty(dpy, str_list, 1, XStringStyle, &text_prop) ) { - DBG_PRINT0( "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); + DBG_PRINT( "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); fprintf(stderr, "X11: setTitle.XmbTextListToTextProperty not completly successfull\n"); } if(NULL!=text_prop.value) { + DBG_PRINT( "X11: setTitle: <%s> SET\n", str_list[0]); XSetWMName(dpy, w, &text_prop); XFree(text_prop.value); + } else { + DBG_PRINT( "X11: setTitle: <%s> NOT SET (1)\n", str_list[0]); } free(str_list[0]); + } else { + DBG_PRINT( "X11: setTitle: NULL\n"); } } #endif - XUnlockDisplay(dpy) ; } |