diff options
author | Sven Gothel <[email protected]> | 2010-06-10 09:35:06 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2010-06-10 09:35:06 +0200 |
commit | 1d333a771ce0bc7c8594e21d031703f698f06a46 (patch) | |
tree | 933d470582896320855fa1d98c1a917edc412c24 /src/newt | |
parent | 4512900ddcb9ce9a498411d257b1b6d6010ec006 (diff) |
Fix: Locking/Threading; Common IntIntHashMap and Buffers; Fix: glMap*Buffer*; GLX/WGL/CgGL: All runtime dynamic; Misc ..
TODO: Compile and test on MacOSX ..
Fix:
=====
Multithreading/Locking:
See jogl/doc/Implementation/MultiThreading.txt
- Locking layer is not platform agnostic, ie GLContextImpl, GLDrawableImpl, ..
and NEWT: Window/Display
- No more use of JAWT global lock necessary, removed.
- No need for X11 Display lock, on the contrary,
this made the NV driver hang.
- Use common window/surface lock
- All NativeWindow surfaceLock's are recursive now
glMapBuffer: If size is 0, don't do cont with the native call.
glMapBufferRange: Fix capacity.
glNamedBufferDataEXT: Track the size.
glMapNamedBufferEXT: Manual impl. - use the tracked size
glXGetVisualFromFBConfig, glXChooseFBConfig, glXChooseVisual: Instead of
ignoring and implement a renamed version (*Copied), we just use ManualImplementation
for the proper copy-result code.
DesktopGLDynamicLookupHelper: Initialize _hasGLBinding* attributes
in the determing loadGLJNILibrary() method, which is called by super().
Otherwise static init will overwrite them after the super() call.
X11GLXDrawableFactory: Don't release anything at shutdown (removed sharedContext.destroy()),
since this caused a freeze/SEGV sometimes.
Fixed NEWT's reparentWindow() functionality incl NewtCanvasAWT usage.
- Native: if not visible, don't focus, etc
- NewtCanvasAWT: Use the container size to start with
- Run the command on the EDT
Using GlueGen's new DynamicLibraryBundle utility:
- X11, Windows and MacOSX OpenGL adapted to DynamicLibraryBundleInfo.
- X11GLXDynamicLookupHelper -> X11GLXDynamicLibraryBundleInfo
- Remove all path from lib names.
- GL order: libGL.so.1, libGL.so, GL
- shallLinkGlobal: true -> to server some 'old' DRI systems
-> http://dri.sourceforge.net/doc/DRIuserguide.html
- shallLookupGlobal: false
- Try both : glXGetProcAddressARB and glXGetProcAddress
- Using bootstrap: GLX.glXGetProcAddress(long glxGetProcAddressHandle, String glFuncName)
Found the issue with LIBGL_DRIVERS_PATH, ie if not set
no valid GL instance can be found (ie ATI fglrx/DRI).
This may happen if using a differen user than the desktop user
for whom the env var is set within some /etc/X11/Xsession.d/ script.
Enhancements:
=============
GLBufferSizeTracker: Use IntIntHashMap and add DirectState size tracking.
GLBufferStateTracker: Use IntIntHashMap.
GLStateTracker: Use IntIntHashMap.
GLDynamicLookupHelper: More generic (global loading/lookup and GetProcAddress function name list),
remove redundant code.
FIXME:
MacOSXCGLDynamicLookupHelper:
- Not tested
- Not using NSImage lookup anymore as recommended by OSX API Doc,
so dlsym is used always (to be tested)
WindowsWGLDynamicLookupHelper:
- Not tested
GLX/WGL/CgGL is all runtime-dynamic as now, ie loaded and looked-up at runtime,
no compile time dependencies to GL anymore, nor a need to specify CgGL.
Split up WGL in GDI and WGL, to allow proper dynamic runtime linkage of OpenGL32
while using static binding to GDI32
NEWT events generated by native code are enqueued and not send directly.
This should ease locking mechanisms .. if any are necessary.
NEWT: More platform specific code moved to *Impl method,
simplifying the generic code of the superclass and impl protocol.
Cleanup:
=========
Replace all InternalBufferUtil's with com.jogamp.common.nio.Buffers
Removed all InternalBufferUtil's from repository
Removed GLContextImpl notion of 'optimized' surface locking,
where the surface gets unlocked during makeCurrent/release.
This just makes no sense and would impact multithreading in a horrible way.
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) ; } |