diff options
Diffstat (limited to 'src')
24 files changed, 238 insertions, 183 deletions
diff --git a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java index 54d9b4e80..9fcddbbfa 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/GLContextImpl.java @@ -641,7 +641,7 @@ public abstract class GLContextImpl extends GLContext { // private Object createInstance(GLProfile glp, String suffix, Class[] cstrArgTypes, Object[] cstrArgs) { - return ReflectionUtil.createInstance(glp.getGLImplBaseClassName()+suffix, getClass().getClassLoader(), cstrArgTypes, cstrArgs); + return ReflectionUtil.createInstance(glp.getGLImplBaseClassName()+suffix, cstrArgTypes, cstrArgs, getClass().getClassLoader()); } /** Create the GL for this context. */ diff --git a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java index e71a78ffb..9694e5607 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/macosx/cgl/MacOSXCGLDrawableFactory.java @@ -78,8 +78,8 @@ public class MacOSXCGLDrawableFactory extends GLDrawableFactoryImpl { new MacOSXCGLGraphicsConfigurationFactory(); try { - ReflectionUtil.createInstance("com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory", getClass().getClassLoader(), - new Object[] {}); + ReflectionUtil.createInstance("com.jogamp.opengl.impl.macosx.cgl.awt.MacOSXAWTCGLGraphicsConfigurationFactory", + new Object[] {}, getClass().getClassLoader()); } catch (JogampRuntimeException jre) { /* n/a .. */ } } diff --git a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java index 353ed8ac3..85444b61c 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/windows/wgl/WindowsWGLDrawableFactory.java @@ -80,8 +80,8 @@ public class WindowsWGLDrawableFactory extends GLDrawableFactoryImpl { // The act of constructing them causes them to be registered new WindowsWGLGraphicsConfigurationFactory(); try { - ReflectionUtil.createInstance("com.jogamp.opengl.impl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory", getClass().getClassLoader(), - new Object[] {}); + ReflectionUtil.createInstance("com.jogamp.opengl.impl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory", + new Object[] {}, getClass().getClassLoader()); } catch (JogampRuntimeException jre) { /* n/a .. */ } try { diff --git a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java index c08c7c73f..98be19263 100644 --- a/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java +++ b/src/jogl/classes/com/jogamp/opengl/impl/x11/glx/X11GLXDrawableFactory.java @@ -78,8 +78,8 @@ public class X11GLXDrawableFactory extends GLDrawableFactoryImpl { // The act of constructing them causes them to be registered new X11GLXGraphicsConfigurationFactory(); try { - ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory", getClass().getClassLoader(), - new Object[] {}); + ReflectionUtil.createInstance("com.jogamp.opengl.impl.x11.glx.awt.X11AWTGLXGraphicsConfigurationFactory", + new Object[] {}, getClass().getClassLoader()); } catch (JogampRuntimeException jre) { /* n/a .. */ } // init shared resources .. diff --git a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java index 1b5c56c95..10a32fd1d 100644 --- a/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java +++ b/src/jogl/classes/javax/media/opengl/GLAutoDrawable.java @@ -167,7 +167,7 @@ public interface GLAutoDrawable extends GLDrawable { * <p> * This method shall be called by an animator implementation only,<br> * e.g. {@link com.jogamp.opengl.util.Animator#start()}, passing the animator thread,<br> - * and {@link com.jogamp.opengl.util.Animator#start()}, passing <code>null</code>.</p><br> + * and {@link com.jogamp.opengl.util.Animator#stop()}, passing <code>null</code>.</p><br> * <p> * Impacts {@link #display()} and {@link #invoke(boolean, GLRunnable)} semantics.</p><br> * diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java index 2ee2cb02c..938fb9681 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/NativeWindowFactoryImpl.java @@ -87,7 +87,9 @@ public class NativeWindowFactoryImpl extends NativeWindowFactory { throw new IllegalArgumentException("OS " + getNativeOSName(false) + " not yet supported"); } - nativeWindowConstructor = ReflectionUtil.getConstructor(windowClassName, getClass().getClassLoader(), new Class[] { Object.class, AbstractGraphicsConfiguration.class }); + nativeWindowConstructor = ReflectionUtil.getConstructor( + windowClassName, new Class[] { Object.class, AbstractGraphicsConfiguration.class }, + getClass().getClassLoader()); } catch (Exception e) { throw (IllegalArgumentException) new IllegalArgumentException().initCause(e); } diff --git a/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java index a3782d1e6..236ef0754 100644 --- a/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java +++ b/src/nativewindow/classes/com/jogamp/nativewindow/impl/RecursiveToolkitLock.java @@ -9,7 +9,7 @@ public class RecursiveToolkitLock { private Thread owner = null; private int recursionCount = 0; private Exception lockedStack = null; - private static final long timeout = 30000; // maximum wait 3s + private static final long timeout = 3000; // maximum wait 3s private static final boolean TRACE_LOCK = false; public Exception getLockedStack() { diff --git a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java index 75d5c33bc..0a1a91876 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/GraphicsConfigurationFactory.java @@ -78,7 +78,8 @@ public abstract class GraphicsConfigurationFactory { if (NativeWindowFactory.TYPE_X11.equals(NativeWindowFactory.getNativeWindowType(true))) { try { GraphicsConfigurationFactory factory = (GraphicsConfigurationFactory) - ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", GraphicsConfigurationFactory.class.getClassLoader(), new Object[] {}); + ReflectionUtil.createInstance("com.jogamp.nativewindow.impl.x11.X11GraphicsConfigurationFactory", new Object[] {}, + GraphicsConfigurationFactory.class.getClassLoader()); registerFactory(javax.media.nativewindow.x11.X11GraphicsDevice.class, factory); } catch (Exception e) { throw new RuntimeException(e); diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java index eb52e7211..f716e8ac9 100644 --- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java +++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java @@ -116,7 +116,7 @@ public abstract class NativeWindowFactory { ClassLoader cl = NativeWindowFactory.class.getClassLoader(); if( TYPE_X11.equals(nativeWindowingTypePure) ) { - ReflectionUtil.callStaticMethod( X11UtilClassName, cl, "initSingleton", new Class[] { }, new Object[] { } ); + ReflectionUtil.callStaticMethod( X11UtilClassName, "initSingleton", new Class[] { }, new Object[] { }, cl ); } registeredFactories = Collections.synchronizedMap(new HashMap()); diff --git a/src/newt/classes/com/jogamp/newt/OffscreenWindow.java b/src/newt/classes/com/jogamp/newt/OffscreenWindow.java index 0f75fbfa9..e85714d4f 100644 --- a/src/newt/classes/com/jogamp/newt/OffscreenWindow.java +++ b/src/newt/classes/com/jogamp/newt/OffscreenWindow.java @@ -107,9 +107,8 @@ public class OffscreenWindow extends Window implements SurfaceChangeable { // nop return false; } - protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { + protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { shouldNotCallThis(); - return false; } } diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 0cd5b31bc..9c724314e 100755 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -303,6 +303,30 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer } protected void requestFocusImpl() {} + /** + * May set to a {@link FocusRunnable}, {@link FocusRunnable#run()} before Newt requests the native focus. + * This allows notifying a covered window toolkit like AWT that the focus is requested, + * hence focus traversal can be made transparent. + */ + public void setFocusAction(FocusRunnable focusAction) { + this.focusAction = focusAction; + } + protected boolean focusAction() { + if(null!=focusAction) { + return focusAction.run(); + } + return false; + } + protected FocusRunnable focusAction = null; + + public static interface FocusRunnable { + /** + * @return false if NEWT shall proceed requesting the focus, + * true if NEWT shall not request the focus. + */ + public boolean run(); + } + // // NativeWindow impl // @@ -888,22 +912,31 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer w = screen.getWidth(); h = screen.getHeight(); } else { - x = nfs_x; - y = nfs_y; + if(0!=parentWindowHandle) { + x=0; + y=0; + } else { + x = nfs_x; + y = nfs_y; + } w = nfs_width; h = nfs_height; } if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { System.out.println("X11Window fs: "+fullscreen+" "+x+"/"+y+" "+w+"x"+h+", "+isUndecorated()); } - this.fullscreen = setFullscreenImpl(fullscreen, x, y, w, h); + this.fullscreen = fullscreen; + setFullscreenImpl(fullscreen, x, y, w, h); } - return this.fullscreen; } finally { windowUnlock(); } + if( isVisible() ) { + windowRepaint(0, 0, getWidth(), getHeight()); + } + return this.fullscreen; } - protected abstract boolean setFullscreenImpl(boolean fullscreen, int x, int y, int widht, int height); + protected abstract void setFullscreenImpl(boolean fullscreen, int x, int y, int widht, int height); // // Child Window Management @@ -1495,6 +1528,9 @@ public abstract class Window implements NativeWindow, NEWTEventConsumer invalidate(); } + public boolean getPropagateRepaint() { + return propagateRepaint; + } public void setPropagateRepaint(boolean v) { propagateRepaint = v; } diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index b2dd719bc..6fd924e66 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -36,10 +36,11 @@ import java.lang.reflect.*; import java.security.*; import java.awt.Button; -import java.awt.Frame; import java.awt.Canvas; +import java.awt.Component; +import java.awt.EventQueue; +import java.awt.Frame; import java.awt.Graphics; -import java.awt.KeyboardFocusManager; import javax.media.nativewindow.*; @@ -59,7 +60,6 @@ public class NewtCanvasAWT extends java.awt.Canvas { NativeWindow parent = null; Window newtChild = null; AWTAdapter awtAdapter = null; - boolean hasSwingContainer = false; /** * Instantiates a NewtCanvas without a NEWT child.<br> @@ -75,84 +75,39 @@ public class NewtCanvasAWT extends java.awt.Canvas { super(); setNEWTChild(child); } - - class UnfocusRunnable implements Runnable { - boolean focusTraversed = false; - public void run() { - KeyboardFocusManager focusManager = - KeyboardFocusManager.getCurrentKeyboardFocusManager(); - java.awt.Component comp1 = focusManager.getPermanentFocusOwner(); - java.awt.Component comp2 = focusManager.getFocusOwner(); - if(DEBUG_IMPLEMENTATION) { - System.out.println("AWT Unfocus: traversed "+focusTraversed+" (1)"); - System.out.println("PRE PermenetFocusOwner: "+comp1); - System.out.println("PRE FocusOwner: "+comp2); - } - if(null!=comp1) { - if(!focusTraversed && null==comp2) { - comp1.requestFocus(); - focusTraversed=true; - if(DEBUG_IMPLEMENTATION) { - System.out.println("AWT Unfocus: traversed "+focusTraversed+" (*)"); - } - } else { - focusTraversed=false; - } - - if(DEBUG_IMPLEMENTATION) { - comp1 = focusManager.getPermanentFocusOwner(); - comp2 = focusManager.getFocusOwner(); - System.out.println("MID PermenetFocusOwner: "+comp1); - System.out.println("MID FocusOwner: "+comp2); - } - focusManager.clearGlobalFocusOwner(); + class FocusAction implements Window.FocusRunnable { + public boolean run() { + if ( EventQueue.isDispatchThread() ) { + focusActionImpl.run(); + } else { + try { + EventQueue.invokeAndWait(focusActionImpl); + } catch (Exception e) { + throw new NativeWindowException(e); + } + } + return focusActionImpl.result; + } + class FocusActionImpl implements Runnable { + public final boolean result = false; // NEWT shall always proceed requesting the native focus + public void run() { if(DEBUG_IMPLEMENTATION) { - comp1 = focusManager.getPermanentFocusOwner(); - comp2 = focusManager.getFocusOwner(); - System.out.println("POST PermenetFocusOwner: "+comp1); - System.out.println("POST FocusOwner: "+comp2); - } - - if(focusTraversed && null!=newtChild) { - newtChild.requestFocus(); + System.out.println("FocusActionImpl.run() "+Window.getThreadName()); } + NewtCanvasAWT.this.requestFocusAWT(); } } + FocusActionImpl focusActionImpl = new FocusActionImpl(); } - UnfocusRunnable unfocusRunnable = new UnfocusRunnable(); + FocusAction focusAction = new FocusAction(); - class FocusListener extends WindowAdapter { - public synchronized void windowGainedFocus(WindowEvent e) { - if(DEBUG_IMPLEMENTATION) { - System.out.println("NewtCanvasAWT focus on: AWT focus "+ NewtCanvasAWT.this.hasFocus()+ - ", focusable "+NewtCanvasAWT.this.isFocusable()+", onEDT "+hasSwingContainer); - } - if(hasSwingContainer) { - java.awt.EventQueue.invokeLater(unfocusRunnable); - } else { - unfocusRunnable.run(); - } - } - public synchronized void windowLostFocus(WindowEvent e) { - if(DEBUG_IMPLEMENTATION) { - System.out.println("NewtCanvasAWT focus off: AWT focus "+ NewtCanvasAWT.this.hasFocus()); - } - } - } - FocusListener focusListener = new FocusListener(); - /** sets a new NEWT child, provoking reparenting on the NEWT level. */ public NewtCanvasAWT setNEWTChild(Window child) { if(newtChild!=child) { - if(null!=newtChild) { - newtChild.removeWindowListener(focusListener); - } newtChild = child; - if(null!=newtChild) { - newtChild.addWindowListener(focusListener); - } + newtChild.setFocusAction(focusAction); if(null!=parent) { java.awt.Container cont = getContainer(this); // reparent right away, addNotify has been called already @@ -181,16 +136,6 @@ public class NewtCanvasAWT extends java.awt.Canvas { } } - static boolean hasSwingContainer(java.awt.Component comp) { - while( null != comp ) { - if( comp instanceof javax.swing.JComponent ) { - return true; - } - comp = comp.getParent(); - } - return false; - } - static java.awt.Container getContainer(java.awt.Component comp) { while( null != comp ) { if( comp instanceof java.awt.Container ) { @@ -204,13 +149,12 @@ public class NewtCanvasAWT extends java.awt.Canvas { public void addNotify() { super.addNotify(); disableBackgroundErase(); - hasSwingContainer = hasSwingContainer(this); 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()+", swingContainer "+hasSwingContainer+" -> "+cont); + ", displayable "+isDisplayable()+" -> "+cont); } reparentWindow(true, cont); } @@ -269,6 +213,49 @@ public class NewtCanvasAWT extends java.awt.Canvas { } } + void requestFocusAWT() { + super.requestFocus(); + } + + public void requestFocus() { + super.requestFocus(); + if(null!=newtChild) { + newtChild.setFocusAction(null); + newtChild.requestFocus(); + newtChild.setFocusAction(focusAction); + } + } + + public boolean requestFocus(boolean temporary) { + boolean res = super.requestFocus(temporary); + if(res && null!=newtChild) { + newtChild.setFocusAction(null); + newtChild.requestFocus(); + newtChild.setFocusAction(focusAction); + } + return res; + } + + public boolean requestFocusInWindow() { + boolean res = super.requestFocusInWindow(); + if(res && null!=newtChild) { + newtChild.setFocusAction(null); + newtChild.requestFocus(); + newtChild.setFocusAction(focusAction); + } + return res; + } + + public boolean requestFocusInWindow(boolean temporary) { + boolean res = super.requestFocusInWindow(temporary); + if(res && null!=newtChild) { + newtChild.setFocusAction(null); + newtChild.requestFocus(); + newtChild.setFocusAction(focusAction); + } + return res; + } + // Disables the AWT's erasing of this Canvas's background on Windows // in Java SE 6. This internal API is not available in previous // releases, but the system property 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 43087289a..9f0944ea0 100644 --- a/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java +++ b/src/newt/classes/com/jogamp/newt/event/awt/AWTParentWindowAdapter.java @@ -57,7 +57,6 @@ public class AWTParentWindowAdapter if(DEBUG_IMPLEMENTATION) { System.out.println("AWT: focusGained: START "+ e.getComponent()); } - newtWindow.requestFocus(); } public void focusLost(java.awt.event.FocusEvent e) { 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 6f936d2c6..56e5a4240 100644 --- a/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/awt/AWTWindow.java @@ -240,7 +240,7 @@ public class AWTWindow extends Window { } } - protected boolean setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) { + protected void setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) { /** An AWT event on setSize() would bring us in a deadlock situation, hence invokeLater() */ runOnEDT(false, new Runnable() { public void run() { @@ -257,7 +257,6 @@ public class AWTWindow extends Window { container.setSize(w, h); } }); - return fullscreen; } public Object getWrappedWindow() { 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 1b8a62a9c..14621807a 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 @@ -109,11 +109,10 @@ public class Window extends com.jogamp.newt.Window { } } - protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { + protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { if(0!=surfaceHandle) { SetBounds0(surfaceHandle, screen.getWidth(), screen.getHeight(), x, y, w, h); } - return fullscreen; } protected void requestFocusImpl() { diff --git a/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java index 0fde19cd4..699b675dd 100755 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacDisplay.java @@ -99,17 +99,15 @@ public class MacDisplay extends Display { if(wait) { ReflectionUtil.callStaticMethod( "java.awt.EventQueue", - cl, "invokeAndWait", new Class[] { java.lang.Runnable.class }, - new Object[] { r } ); + new Object[] { r }, cl ); } else { ReflectionUtil.callStaticMethod( "java.awt.EventQueue", - cl, "invokeLater", new Class[] { java.lang.Runnable.class }, - new Object[] { r } ); + new Object[] { r }, cl ); } } catch (Exception e) { throw new NativeWindowException(e); 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 9f47aa49f..8f5041253 100755 --- a/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/macosx/MacWindow.java @@ -280,7 +280,7 @@ public class MacWindow extends Window { } } - protected boolean setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) { + protected void setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) { nsViewLock.lock(); try { if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { @@ -293,7 +293,6 @@ public class MacWindow extends Window { } finally { nsViewLock.unlock(); } - return fullscreen; } private void insetsChanged(int left, int top, int right, int bottom) { diff --git a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java index 7d3a0ac8c..ca06699f5 100755 --- a/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/opengl/broadcom/egl/Window.java @@ -87,10 +87,9 @@ public class Window extends com.jogamp.newt.Window { System.err.println("BCEGL Window.setPositionImpl n/a in BroadcomEGL"); } - protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { + protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { // n/a in BroadcomEGL System.err.println("setFullscreen n/a in BroadcomEGL"); - return false; } public boolean surfaceSwap() { 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 0c7254376..2f534548b 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 @@ -100,14 +100,13 @@ public class KDWindow extends Window { System.err.println("setPosition n/a in KD"); } - protected boolean setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) { + protected void setFullscreenImpl(final boolean fullscreen, final int x, final int y, final int w, final int h) { if(0!=eglWindowHandle) { setFullScreen0(eglWindowHandle, fullscreen); if(!fullscreen) { setSize0(eglWindowHandle, w, h); } } - return true; } //---------------------------------------------------------------------- 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 47f79f46a..69cd62201 100755 --- a/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java +++ b/src/newt/classes/com/jogamp/newt/impl/windows/WindowsWindow.java @@ -162,9 +162,8 @@ public class WindowsWindow extends Window { setPosition0(parentWindowHandle, windowHandle, x , y /*, width, height*/); } - protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { + protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { setFullscreen0(fullscreen?0:parentWindowHandle, windowHandle, x, y, w, h, isUndecorated(fullscreen)); - return fullscreen; } protected boolean reparentWindowImpl() { @@ -176,7 +175,7 @@ public class WindowsWindow extends Window { protected void requestFocusImpl() { if (windowHandle != 0L) { - requestFocus0(fullscreen?0:parentWindowHandle, windowHandle); + requestFocus0(windowHandle); } } @@ -207,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 parentWindowHandle, long windowHandle); + private native void requestFocus0(long windowHandle); private void insetsChanged(int left, int top, int right, int bottom) { if (left != -1 && top != -1 && right != -1 && bottom != -1) { 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 6890b29fa..7a770f770 100755 --- a/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java +++ b/src/newt/classes/com/jogamp/newt/impl/x11/X11Window.java @@ -102,10 +102,9 @@ public class X11Window extends Window { setPosition0(parentWindowHandle, getDisplayHandle(), windowHandle, x, y); } - protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { + protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { setPosSizeDecor0(fullscreen?0:parentWindowHandle, getDisplayHandle(), getScreenIndex(), windowHandle, x, y, w, h, isUndecorated(fullscreen), isVisible()); - return fullscreen; } protected boolean reparentWindowImpl() { diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index e66ed1e34..99b4314a3 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -305,6 +305,9 @@ public class GLWindow extends Window implements GLAutoDrawable { public void requestFocus() { window.requestFocus(); } + public void setFocusAction(FocusRunnable focusAction) { + window.setFocusAction(focusAction); + } public Insets getInsets() { return window.getInsets(); @@ -327,9 +330,8 @@ public class GLWindow extends Window implements GLAutoDrawable { public boolean setFullscreen(boolean fullscreen) { return window.setFullscreen(fullscreen); } - protected boolean setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { + protected void setFullscreenImpl(boolean fullscreen, int x, int y, int w, int h) { shouldNotCallThis(); - return false; } public boolean isVisible() { diff --git a/src/newt/native/WindowsWindow.c b/src/newt/native/WindowsWindow.c index a1dab2678..cda6a4086 100755 --- a/src/newt/native/WindowsWindow.c +++ b/src/newt/native/WindowsWindow.c @@ -119,6 +119,7 @@ static jmethodID windowDestroyedID = NULL; static jmethodID windowRepaintID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; +static jmethodID focusActionID = NULL; static RECT* UpdateInsets(JNIEnv *env, HWND hwnd, jobject window); @@ -596,23 +597,27 @@ static int WmKeyUp(JNIEnv *env, jobject window, UINT wkey, UINT repCnt, return 0; } -static void NewtWindows_requestFocus (HWND hwnd, BOOL topLevel, BOOL reparented) { - DBG_PRINT("*** WindowsWindow: requestFocus.0 window %p\n", (void*)hwnd); - if (IsWindow(hwnd)) { - 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); +static void NewtWindows_requestFocus (JNIEnv *env, jobject window, HWND hwnd, BOOL reparented) { + HWND pHwnd = GetParent(hwnd); + HWND current = GetFocus(); + DBG_PRINT("*** WindowsWindow: requestFocus.0 parent %p, window %p, isCurrent %d\n", + (void*) pHwnd, (void*)hwnd, current==hwnd); + if(reparented || current!=hwnd) { + if( JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) { + UINT flags = SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; + if(reparented) { + flags |= SWP_FRAMECHANGED; + } + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, flags); + SetForegroundWindow(hwnd); // Slightly Higher Priority + SetFocus(hwnd);// Sets Keyboard Focus To Window + if(NULL!=pHwnd) { + SetActiveWindow(hwnd); + } + DBG_PRINT("*** WindowsWindow: requestFocus.X1\n"); + } else { + DBG_PRINT("*** WindowsWindow: requestFocus.X0\n"); } - DBG_PRINT("*** WindowsWindow: requestFocus.X\n"); } } @@ -800,7 +805,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, case WM_LBUTTONDOWN: - NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + DBG_PRINT("*** WindowsWindow: LBUTTONDOWN\n"); + NewtWindows_requestFocus ( env, window, wnd, FALSE ); // request focus on this window, if not already .. (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), @@ -819,7 +825,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_MBUTTONDOWN: - NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + DBG_PRINT("*** WindowsWindow: MBUTTONDOWN\n"); + NewtWindows_requestFocus ( env, window, wnd, FALSE ); // request focus on this window, if not already .. (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), @@ -838,7 +845,8 @@ static LRESULT CALLBACK wndProc(HWND wnd, UINT message, break; case WM_RBUTTONDOWN: - NewtWindows_requestFocus ( wnd, FALSE, FALSE ); // request focus on this window, if not already .. + DBG_PRINT("*** WindowsWindow: RBUTTONDOWN\n"); + NewtWindows_requestFocus ( env, window, wnd, FALSE ); // request focus on this window, if not already .. (*env)->CallVoidMethod(env, window, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, GetModifiers(), @@ -1069,6 +1077,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI windowRepaintID = (*env)->GetMethodID(env, clazz, "windowRepaint", "(IIII)V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z"); + if (insetsChangedID == NULL || sizeChangedID == NULL || positionChangedID == NULL || @@ -1078,7 +1088,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_initI windowDestroyedID == NULL || windowRepaintID == NULL || sendMouseEventID == NULL || - sendKeyEventID == NULL) + sendKeyEventID == NULL || + focusActionID == NULL) { return JNI_FALSE; } @@ -1148,13 +1159,6 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_CreateWi #endif UpdateInsets(env, window, obj); - - ShowWindow(window, SW_SHOWNORMAL); - if(NULL!=parentWindow) { - NewtWindows_requestFocus ( window, FALSE, FALSE ); // request focus on this window, if not already .. - } /* else { - // top level already capable of receiving [keyboard] events - } */ } #ifdef UNICODE @@ -1224,13 +1228,13 @@ JNIEXPORT jlong JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_MonitorF JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setVisible0 (JNIEnv *_env, jclass clazz, jlong window, jboolean visible) { - HWND hWnd = (HWND) (intptr_t) window; - DBG_PRINT("*** WindowsWindow: setVisible window %p, visible: %d\n", hWnd, (int)visible); + HWND hwnd = (HWND) (intptr_t) window; + DBG_PRINT("*** WindowsWindow: setVisible window %p, visible: %d\n", hwnd, (int)visible); if (visible) { - SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); - ShowWindow(hWnd, SW_SHOW); + SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE); + ShowWindow(hwnd, SW_SHOW); } else { - ShowWindow(hWnd, SW_HIDE); + ShowWindow(hwnd, SW_HIDE); } } @@ -1301,14 +1305,14 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setPositi } } -static void NewtWindows_reparentWindow(HWND hwndP, HWND hwnd, jint x, jint y, jint width, jint height, jboolean bIsUndecorated) +static void NewtWindows_reparentWindow(JNIEnv *env, jobject obj, HWND hwndP, HWND hwnd, BOOL visible, + jint x, jint y, jint width, jint height, jboolean bIsUndecorated) { UINT flags; HWND hWndInsertAfter; 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); + DBG_PRINT("*** WindowsWindow: reparentWindow.1 parent %p, window %p, %d/%d %dx%d undeco %d\n", (void*)hwndP, (void*)hwnd, x, y, width, height, bIsUndecorated); if (!IsWindow(hwnd)) { DBG_PRINT("*** WindowsWindow: reparentWindow failure: Passed window %p is invalid\n", (void*)hwnd); return; @@ -1318,8 +1322,8 @@ static void NewtWindows_reparentWindow(HWND hwndP, HWND hwnd, jint x, jint y, ji return; } - if (isVisible) { - windowStyle |= WS_VISIBLE; + if(visible) { + windowStyle |= WS_VISIBLE ; } // order of call sequence: (MS documentation) @@ -1346,10 +1350,6 @@ static void NewtWindows_reparentWindow(HWND hwndP, HWND hwnd, jint x, jint y, ji DBG_PRINT("*** WindowsWindow: reparentWindow.4\n"); } - if(isVisible) { - NewtWindows_requestFocus ( hwnd, ( NULL == hwndP ) ? TRUE : FALSE, TRUE ); - } - DBG_PRINT("*** WindowsWindow: reparentWindow.X\n"); } @@ -1365,13 +1365,12 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc HWND hwndP = (HWND) (intptr_t) parent; HWND hwnd = (HWND) (intptr_t) window; HWND hWndInsertAfter; - DWORD windowStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; BOOL isVisible = IsWindowVisible(hwnd); 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); - NewtWindows_reparentWindow(hwndP, hwnd, x, y, width, height, bIsUndecorated); + NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated); if ( NULL == hwndP ) { flags = SWP_SHOWWINDOW; @@ -1380,9 +1379,12 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_setFullsc flags = SWP_NOACTIVATE | SWP_NOZORDER; hWndInsertAfter = 0; } - SetWindowPos(hwnd, hWndInsertAfter, x, y, width, height, flags); + if(isVisible) { + NewtWindows_requestFocus ( env, obj, hwnd, TRUE ); // request focus on this window, if not already .. + } + DBG_PRINT("*** WindowsWindow: setFullscreen.X\n"); (*env)->CallVoidMethod(env, obj, sizeChangedID, (jint) width, (jint) height); // resize necessary .. } @@ -1397,8 +1399,14 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_windows_WindowsWindow_reparentW { HWND hwndP = (HWND) (intptr_t) parent; HWND hwnd = (HWND) (intptr_t) window; + BOOL isVisible = IsWindowVisible(hwnd); + + NewtWindows_reparentWindow(env, obj, hwndP, hwnd, FALSE, x, y, width, height, bIsUndecorated); + + if(isVisible) { + NewtWindows_requestFocus ( env, obj, hwnd, TRUE ); // request focus on this window, if not already .. + } - NewtWindows_reparentWindow(hwndP, hwnd, x, y, width, height, bIsUndecorated); } /* @@ -1425,8 +1433,9 @@ 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 parent, jlong window) + (JNIEnv *env, jobject obj, jlong window) { - NewtWindows_requestFocus ( (HWND) (intptr_t) window, (0 == parent) ? TRUE : FALSE, FALSE ) ; + DBG_PRINT("*** WindowsWindow: RequestFocus0\n"); + NewtWindows_requestFocus ( env, obj, (HWND) (intptr_t) window, FALSE ) ; } diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c index dbf833633..60caab662 100755 --- a/src/newt/native/X11Window.c +++ b/src/newt/native/X11Window.c @@ -161,6 +161,7 @@ static jmethodID windowRepaintID = NULL; static jmethodID windowCreatedID = NULL; static jmethodID sendMouseEventID = NULL; static jmethodID sendKeyEventID = NULL; +static jmethodID focusActionID = NULL; static jmethodID displayCompletedID = NULL; @@ -372,18 +373,42 @@ static jobject getJavaWindowProperty(JNIEnv *env, Display *dpy, Window window, j return jwindow; } -static void NewtWindows_requestFocus0 (Display *dpy, Window w, XWindowAttributes *xwa) { - // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable - if(xwa->map_state == IsViewable) { - XSetInputFocus(dpy, w, RevertToParent, CurrentTime); +/** +static Window NewtWindows_getParent (Display *dpy, Window w) { + Window root_return=0; + Window parent_return=0; + Window *children_return=NULL; + unsigned int nchildren_return=0; + + Status res = XQueryTree(dpy, w, &root_return, &parent_return, &children_return, &nchildren_return); + if(NULL!=children_return) { + XFree(children_return); + } + if(0!=res) { + return parent_return; + } + return 0; +} */ + +static void NewtWindows_requestFocus0 (JNIEnv *env, jobject window, Display *dpy, Window w, XWindowAttributes *xwa) { + Window focus_return; + int revert_to_return; + XGetInputFocus(dpy, &focus_return, &revert_to_return); + if(focus_return!=w) { + // Avoid 'BadMatch' errors from XSetInputFocus, ie if window is not viewable + if( JNI_FALSE == (*env)->CallBooleanMethod(env, window, focusActionID) ) { + if(xwa->map_state == IsViewable) { + XSetInputFocus(dpy, w, RevertToParent, CurrentTime); + } + } } } -static void NewtWindows_requestFocus1 (Display *dpy, Window w) { +static void NewtWindows_requestFocus1 (JNIEnv *env, jobject window, Display *dpy, Window w) { XWindowAttributes xwa; XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_requestFocus0 (dpy, w, &xwa); + NewtWindows_requestFocus0 (env, window, dpy, w, &xwa); XSync(dpy, False); } @@ -505,7 +530,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Display_DispatchMessages switch(evt.type) { case ButtonPress: - NewtWindows_requestFocus1 ( dpy, evt.xany.window ); + NewtWindows_requestFocus1 ( env, jwindow, dpy, evt.xany.window ); (*env)->CallVoidMethod(env, jwindow, sendMouseEventID, (jint) EVENT_MOUSE_PRESSED, (jint) evt.xbutton.state, @@ -674,6 +699,7 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 windowCreatedID = (*env)->GetMethodID(env, clazz, "windowCreated", "(J)V"); sendMouseEventID = (*env)->GetMethodID(env, clazz, "sendMouseEvent", "(IIIIII)V"); sendKeyEventID = (*env)->GetMethodID(env, clazz, "sendKeyEvent", "(IIIC)V"); + focusActionID = (*env)->GetMethodID(env, clazz, "focusAction", "()Z"); if (sizeChangedID == NULL || positionChangedID == NULL || @@ -684,7 +710,8 @@ JNIEXPORT jboolean JNICALL Java_com_jogamp_newt_impl_x11_X11Window_initIDs0 windowRepaintID == NULL || windowCreatedID == NULL || sendMouseEventID == NULL || - sendKeyEventID == NULL) { + sendKeyEventID == NULL || + focusActionID == NULL) { return JNI_FALSE; } return JNI_TRUE; @@ -941,7 +968,9 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosition0 } static void NewtWindows_reparentWindow - (Display * dpy, Screen * scrn, Window w, XWindowAttributes *xwa, jlong jparent, jint x, jint y, jboolean undecorated, jboolean isVisible) + (JNIEnv *env, jobject obj, + 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); @@ -990,7 +1019,7 @@ static void NewtWindows_reparentWindow XSync(dpy, False); */ if(JNI_TRUE == isVisible) { - NewtWindows_requestFocus0 ( dpy, w, xwa ); + NewtWindows_requestFocus0 ( env, obj, dpy, w, xwa ); XSync(dpy, False); } @@ -1023,7 +1052,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_setPosSizeDecor0 XSync(dpy, False); XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); + NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); XSync(dpy, False); memset(&xwc, 0, sizeof(XWindowChanges)); @@ -1058,7 +1087,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0 XSync(dpy, False); XGetWindowAttributes(dpy, w, &xwa); - NewtWindows_reparentWindow(dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); + NewtWindows_reparentWindow(env, obj, dpy, scrn, w, &xwa, jparent, x, y, undecorated, isVisible); XSync(dpy, False); DBG_PRINT( "X11: reparentWindow0 X\n"); @@ -1072,7 +1101,7 @@ JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_reparentWindow0 JNIEXPORT void JNICALL Java_com_jogamp_newt_impl_x11_X11Window_requestFocus0 (JNIEnv *env, jobject obj, jlong display, jlong window) { - NewtWindows_requestFocus1 ( (Display *) (intptr_t) display, (Window)window ) ; + NewtWindows_requestFocus1 ( env, obj, (Display *) (intptr_t) display, (Window)window ) ; } /* |