diff options
Diffstat (limited to 'src/newt')
-rw-r--r-- | src/newt/classes/com/jogamp/newt/NewtFactory.java | 46 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java | 151 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/OffscreenWindow.java | 7 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 49 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java | 16 |
5 files changed, 191 insertions, 78 deletions
diff --git a/src/newt/classes/com/jogamp/newt/NewtFactory.java b/src/newt/classes/com/jogamp/newt/NewtFactory.java index d3be098c0..f38876128 100644 --- a/src/newt/classes/com/jogamp/newt/NewtFactory.java +++ b/src/newt/classes/com/jogamp/newt/NewtFactory.java @@ -34,14 +34,19 @@ package com.jogamp.newt; -import javax.media.nativewindow.*; - -import com.jogamp.common.os.Platform; +import javax.media.nativewindow.AbstractGraphicsConfiguration; +import javax.media.nativewindow.AbstractGraphicsDevice; +import javax.media.nativewindow.AbstractGraphicsScreen; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.NativeWindowFactory; +import jogamp.newt.Debug; import jogamp.newt.DisplayImpl; import jogamp.newt.ScreenImpl; import jogamp.newt.WindowImpl; -import jogamp.newt.Debug; + +import com.jogamp.common.os.Platform; public class NewtFactory { public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window"); @@ -141,35 +146,34 @@ public class NewtFactory { * * @param parentWindowObject either a NativeWindow instance */ - public static Window createWindow(NativeWindow nParentWindow, CapabilitiesImmutable caps) { + public static Window createWindow(NativeWindow parentWindow, CapabilitiesImmutable caps) { final String type = NativeWindowFactory.getNativeWindowType(true); - Screen screen = null; - Window parentWindow = null; + Window newtParentWindow = null; - if ( nParentWindow instanceof Window ) { + if ( parentWindow instanceof Window ) { // use parent NEWT Windows Display/Screen - parentWindow = (Window) nParentWindow ; - screen = parentWindow.getScreen(); + newtParentWindow = (Window) parentWindow ; + screen = newtParentWindow.getScreen(); } else { // create a Display/Screen compatible to the NativeWindow - AbstractGraphicsConfiguration nParentConfig = nParentWindow.getGraphicsConfiguration(); - if(null!=nParentConfig) { - AbstractGraphicsScreen nParentScreen = nParentConfig.getScreen(); - AbstractGraphicsDevice nParentDevice = nParentScreen.getDevice(); - Display display = NewtFactory.createDisplay(type, nParentDevice.getHandle(), true); - screen = NewtFactory.createScreen(display, nParentScreen.getIndex()); + AbstractGraphicsConfiguration parentConfig = parentWindow.getGraphicsConfiguration(); + if(null!=parentConfig) { + AbstractGraphicsScreen parentScreen = parentConfig.getScreen(); + AbstractGraphicsDevice parentDevice = parentScreen.getDevice(); + Display display = NewtFactory.createDisplay(type, parentDevice.getHandle(), true); + screen = NewtFactory.createScreen(display, parentScreen.getIndex()); } else { Display display = NewtFactory.createDisplay(type, null, true); // local display screen = NewtFactory.createScreen(display, 0); // screen 0 } } - final Window win = createWindowImpl(nParentWindow, screen, caps); + final Window win = createWindowImpl(parentWindow, screen, caps); - win.setSize(nParentWindow.getWidth(), nParentWindow.getHeight()); - if ( null != parentWindow ) { - parentWindow.addChild(win); - win.setVisible(parentWindow.isVisible()); + win.setSize(parentWindow.getWidth(), parentWindow.getHeight()); + if ( null != newtParentWindow ) { + newtParentWindow.addChild(win); + win.setVisible(newtParentWindow.isVisible()); } return win; } diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 31d42d21b..4aaffb61f 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -29,42 +29,52 @@ package com.jogamp.newt.awt; -import com.jogamp.newt.Display; -import java.lang.reflect.*; -import java.security.*; - import java.awt.Canvas; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.GraphicsConfiguration; import java.awt.KeyboardFocusManager; - +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.media.nativewindow.Capabilities; +import javax.media.nativewindow.CapabilitiesImmutable; +import javax.media.nativewindow.NativeSurface; +import javax.media.nativewindow.NativeSurfaceHolder; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; +import javax.media.nativewindow.NativeWindowHolder; import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.awt.AWTWindowClosingProtocol; -import jogamp.nativewindow.awt.AWTMisc; +import javax.swing.MenuSelectionManager; -import com.jogamp.newt.event.awt.AWTAdapter; -import com.jogamp.newt.event.WindowEvent; -import com.jogamp.newt.Window; -import com.jogamp.newt.event.WindowAdapter; -import com.jogamp.newt.event.WindowListener; +import jogamp.nativewindow.awt.AWTMisc; import jogamp.newt.Debug; import jogamp.newt.awt.event.AWTParentWindowAdapter; import jogamp.newt.awt.event.NewtFactoryAWT; -import javax.swing.MenuSelectionManager; +import com.jogamp.newt.Display; +import com.jogamp.newt.Window; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.event.WindowListener; +import com.jogamp.newt.event.awt.AWTAdapter; +import com.jogamp.newt.event.awt.AWTKeyAdapter; +import com.jogamp.newt.event.awt.AWTMouseAdapter; @SuppressWarnings("serial") -public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol { +public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProtocol, NativeSurfaceHolder, NativeWindowHolder { public static final boolean DEBUG = Debug.debug("Window"); NativeWindow nativeWindow = null; Window newtChild = null; + boolean isNewtChildOnscreen = true; int newtChildCloseOp; AWTAdapter awtAdapter = null; - + AWTAdapter awtMouseAdapter = null; + AWTAdapter awtKeyAdapter = null; + private AWTWindowClosingProtocol awtWindowClosingProtocol = new AWTWindowClosingProtocol(this, new Runnable() { public void run() { @@ -77,6 +87,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto */ public NewtCanvasAWT() { super(); + createNativeWindow(new Capabilities()); } /** @@ -84,6 +95,23 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto */ public NewtCanvasAWT(GraphicsConfiguration gc) { super(gc); + createNativeWindow(new Capabilities()); + } + + /** + * Instantiates a NewtCanvas without a NEWT child.<br> + */ + public NewtCanvasAWT(CapabilitiesImmutable caps) { + super(); + createNativeWindow(caps); + } + + /** + * Instantiates a NewtCanvas without a NEWT child.<br> + */ + public NewtCanvasAWT(GraphicsConfiguration gc, CapabilitiesImmutable caps) { + super(gc); + createNativeWindow(caps); } /** @@ -91,6 +119,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto */ public NewtCanvasAWT(Window child) { super(); + createNativeWindow(child.getRequestedCapabilities()); setNEWTChild(child); } @@ -99,9 +128,14 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto */ public NewtCanvasAWT(GraphicsConfiguration gc, Window child) { super(gc); + createNativeWindow(child.getRequestedCapabilities()); setNEWTChild(child); } + private final void createNativeWindow(CapabilitiesImmutable caps) { + nativeWindow = NewtFactoryAWT.getNativeWindow(this, caps); + } + class FocusAction implements Window.FocusRunnable { public boolean run() { if ( EventQueue.isDispatchThread() ) { @@ -128,7 +162,9 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto System.err.println("FocusActionImpl.run() "+Display.getThreadName()); } NewtCanvasAWT.this.requestFocusAWTParent(); - KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); + if(isNewtChildOnscreen) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); + } } } FocusActionImpl focusActionImpl = new FocusActionImpl(); @@ -142,13 +178,13 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } }; - /** sets a new NEWT child, provoking reparenting on the NEWT level. */ - /*package */ NewtCanvasAWT setNEWTChild(Window child) { + /** sets a new NEWT child, provoking reparenting. */ + private NewtCanvasAWT setNEWTChild(Window child) { if(newtChild!=child) { newtChild = child; - if(null!=nativeWindow) { - java.awt.Container cont = AWTMisc.getContainer(this); + if(isDisplayable()) { // reparent right away, addNotify has been called already + final java.awt.Container cont = AWTMisc.getContainer(this); reparentWindow( (null!=child) ? true : false, cont ); } } @@ -163,6 +199,9 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto /** @return this AWT Canvas NativeWindow representation, may be null in case {@link #removeNotify()} has been called, * or {@link #addNotify()} hasn't been called yet.*/ public NativeWindow getNativeWindow() { return nativeWindow; } + + /** See {@link #getNativeWindow()} */ + public NativeSurface getNativeSurface() { return nativeWindow; } public int getDefaultCloseOperation() { return awtWindowClosingProtocol.getDefaultCloseOperation(); @@ -172,11 +211,31 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto return awtWindowClosingProtocol.setDefaultCloseOperation(op); } + private final void configureNewtChildInputEventHandler() { + if(null==awtMouseAdapter && null != newtChild.getGraphicsConfiguration()) { + isNewtChildOnscreen = newtChild.getGraphicsConfiguration().getChosenCapabilities().isOnscreen(); + if(!isNewtChildOnscreen) { + // offscreen childs require AWT event fwd for key/mouse + awtMouseAdapter = new AWTMouseAdapter(newtChild).addTo(this); + awtKeyAdapter = new AWTKeyAdapter(newtChild).addTo(this); + } + } + } + /* package */ void configureNewtChild(boolean attach) { if(null!=awtAdapter) { awtAdapter.removeFrom(this); awtAdapter=null; } + if(null!=awtMouseAdapter) { + awtMouseAdapter.removeFrom(this); + awtMouseAdapter = null; + } + if(null!=awtKeyAdapter) { + awtKeyAdapter.removeFrom(this); + awtKeyAdapter = null; + } + if( null != newtChild ) { if(attach) { awtAdapter = new AWTParentWindowAdapter(newtChild).addTo(this); @@ -232,21 +291,34 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto newtChild.setFocusAction(null); // no AWT focus traversal .. if(add) { - nativeWindow = NewtFactoryAWT.getNativeWindow(this, newtChild.getRequestedCapabilities()); - if(null!=nativeWindow) { - if(DEBUG) { - System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild); - } - final int w = cont.getWidth(); - final int h = cont.getHeight(); - setSize(w, h); - newtChild.setSize(w, h); - newtChild.reparentWindow(nativeWindow); - newtChild.setVisible(true); - configureNewtChild(true); - newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener - newtChild.windowRepaint(0, 0, w, h); + NewtFactoryAWT.updateGraphicsConfiguration(nativeWindow, this); + if(DEBUG) { + System.err.println("NewtCanvasAWT.reparentWindow: "+newtChild); + } + final int w; + final int h; + if(isPreferredSizeSet()) { + java.awt.Dimension d = getPreferredSize(); + w = d.width; + h = d.height; + } else { + final java.awt.Dimension min; + if(this.isMinimumSizeSet()) { + min = getMinimumSize(); + } else { + min = new java.awt.Dimension(0, 0); + } + java.awt.Insets ins = cont.getInsets(); + w = Math.max(min.width, cont.getWidth() - ins.left - ins.right); + h = Math.max(min.height, cont.getHeight() - ins.top - ins.bottom); } + setSize(w, h); + newtChild.setSize(w, h); + newtChild.reparentWindow(nativeWindow); + newtChild.setVisible(true); + configureNewtChild(true); + newtChild.sendWindowEvent(WindowEvent.EVENT_WINDOW_RESIZED); // trigger a resize/relayout to listener + newtChild.windowRepaint(0, 0, w, h); } else { configureNewtChild(false); nativeWindow = null; @@ -273,7 +345,8 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto System.err.println("NewtCanvasAWT.destroy(): "+newtChild+", from "+cont); } configureNewtChild(false); - nativeWindow = null; + nativeWindow.destroy(); + nativeWindow=null; newtChild.setVisible(false); newtChild.reparentWindow(null); newtChild.destroy(); @@ -288,6 +361,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto public void paint(Graphics g) { awtWindowClosingProtocol.addClosingListenerOneShot(); if(null!=newtChild) { + configureNewtChildInputEventHandler(); newtChild.windowRepaint(0, 0, getWidth(), getHeight()); } } @@ -295,18 +369,21 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto public void update(Graphics g) { awtWindowClosingProtocol.addClosingListenerOneShot(); if(null!=newtChild) { + configureNewtChildInputEventHandler(); newtChild.windowRepaint(0, 0, getWidth(), getHeight()); } } - final void requestFocusAWTParent() { + private final void requestFocusAWTParent() { super.requestFocusInWindow(); } - final void requestFocusNEWTChild() { + private final void requestFocusNEWTChild() { if(null!=newtChild) { newtChild.setFocusAction(null); - KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); + if(isNewtChildOnscreen) { + KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner(); + } newtChild.requestFocus(); newtChild.setFocusAction(focusAction); } diff --git a/src/newt/classes/jogamp/newt/OffscreenWindow.java b/src/newt/classes/jogamp/newt/OffscreenWindow.java index a7a930691..d6402c6bb 100644 --- a/src/newt/classes/jogamp/newt/OffscreenWindow.java +++ b/src/newt/classes/jogamp/newt/OffscreenWindow.java @@ -86,13 +86,6 @@ public class OffscreenWindow extends WindowImpl implements SurfaceChangeable { } @Override - public void setSize(int width, int height) { - if(!isNativeValid()) { - super.setSize(width, height); - } - } - - @Override public void setPosition(int x, int y) { // nop } diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 919c32f13..823868f2b 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -308,6 +308,30 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return isNativeValid() ; } + private void recreate(boolean skipCreate) { + if(DEBUG_IMPLEMENTATION) { + System.err.println("Window.recreate() START ("+getThreadName()+", "+this+")"); + } + if(!isNativeValid()) { + throw new InternalError("XXX"); + } + ScreenImpl retainedScreen = screen; + retainedScreen.addReference(); // +1 - retain over destroy + destroy(); + setScreen(retainedScreen); + retainedScreen.removeReference(); // -1 - release + if(!skipCreate) { + setVisible(true); // native creation + } + } + + private void setScreen(ScreenImpl newScreen) { // never null ! + removeScreenReference(); + screen = newScreen; + screen.addReference(); + screenReferenceAdded = false; + } + private void removeScreenReference() { if(screenReferenceAdded) { // be nice, probably already called recursive via @@ -821,6 +845,11 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } public void setSize(int width, int height) { + /** FIXME: freezes due to many resize events by eg AWT + if( isNativeValid() && !getGraphicsConfiguration().getChosenCapabilities().isOnscreen() ) { + recreate(true); // skip create, create is done here .. + } + */ runOnEDTIfAvail(true, new SetSizeActionImpl(width, height)); } @@ -927,7 +956,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private ReparentActionImpl(NativeWindow newParentWindow, boolean forceDestroyCreate) { this.newParentWindow = newParentWindow; - this.forceDestroyCreate = forceDestroyCreate; + this.forceDestroyCreate = forceDestroyCreate | DEBUG_TEST_REPARENT_INCOMPATIBLE; this.reparentAction = -1; // ensure it's set } @@ -935,13 +964,6 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return reparentAction; } - private void setScreen(ScreenImpl newScreen) { // never null ! - WindowImpl.this.removeScreenReference(); - screen = newScreen; - screen.addReference(); - screenReferenceAdded = false; - } - public final void run() { boolean animatorPaused = false; if(null!=lifecycleHook) { @@ -973,7 +995,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer long newParentWindowHandle = 0 ; if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.reparent: START ("+getThreadName()+") windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", DEBUG_TEST_REPARENT_INCOMPATIBLE "+DEBUG_TEST_REPARENT_INCOMPATIBLE+" "+x+"/"+y+" "+width+"x"+height); + System.err.println("Window.reparent: START ("+getThreadName()+") valid "+isNativeValid()+", windowHandle "+toHexString(windowHandle)+" parentWindowHandle "+toHexString(parentWindowHandle)+", visible "+wasVisible+", old parentWindow: "+Display.hashCodeNullSafe(parentWindow)+", new parentWindow: "+Display.hashCodeNullSafe(newParentWindow)+", forceDestroyCreate "+forceDestroyCreate+", "+x+"/"+y+" "+width+"x"+height); } if(null!=lifecycleHook) { @@ -1024,8 +1046,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } else { reparentAction = ACTION_NATIVE_CREATION_PENDING; } - } else if ( DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate || - !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) { + } else if ( forceDestroyCreate || !NewtFactory.isScreenCompatible(newParentWindow, getScreen()) ) { // Destroy this window, may create a new compatible Screen/Display, // and mark it for creation. destroy(); @@ -1056,7 +1077,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer if( 0 == parentWindowHandle ) { // Already Top Window reparentAction = ACTION_UNCHANGED; - } else if( !isNativeValid() || DEBUG_TEST_REPARENT_INCOMPATIBLE || forceDestroyCreate ) { + } else if( !isNativeValid() || forceDestroyCreate ) { // Destroy this window and mark it for [pending] creation. destroy(); if( 0<width*height ) { @@ -1219,6 +1240,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } public int reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { + if(isNativeValid()) { + // force recreation if offscreen, since it may become onscreen + forceDestroyCreate |= !getGraphicsConfiguration().getChosenCapabilities().isOnscreen(); + } ReparentActionImpl reparentAction = new ReparentActionImpl(newParent, forceDestroyCreate); runOnEDTIfAvail(true, reparentAction); return reparentAction.getStrategy(); diff --git a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java b/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java index aa98d3a37..1d11887fb 100644 --- a/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java +++ b/src/newt/classes/jogamp/newt/awt/event/NewtFactoryAWT.java @@ -34,6 +34,8 @@ import javax.media.nativewindow.*; import javax.media.nativewindow.awt.*; import com.jogamp.newt.NewtFactory; + +import jogamp.nativewindow.jawt.JAWTWindow; import jogamp.newt.Debug; public class NewtFactoryAWT extends NewtFactory { @@ -62,12 +64,24 @@ public class NewtFactoryAWT extends NewtFactory { } public static NativeWindow getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested) { - DefaultGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, capsRequested, capsRequested); + AWTGraphicsConfiguration config = AWTGraphicsConfiguration.create(awtComp, null, capsRequested); NativeWindow awtNative = NativeWindowFactory.getNativeWindow(awtComp, config); // a JAWTWindow if(DEBUG_IMPLEMENTATION) { System.err.println("NewtFactoryAWT.getNativeWindow: "+awtComp+" -> "+awtNative); } return awtNative; } + + public static void updateGraphicsConfiguration(NativeWindow nw, java.awt.Component awtComp) { + if(! ( nw instanceof JAWTWindow ) ) { + throw new NativeWindowException("Not an AWT NativeWindow: "+nw); + } + final AWTGraphicsConfiguration awtConfig = (AWTGraphicsConfiguration) nw.getGraphicsConfiguration(); + awtConfig.updateGraphicsConfiguration(awtComp); + if(DEBUG_IMPLEMENTATION) { + System.err.println("NewtFactoryAWT.updateGraphicsConfiguration: "+awtComp+" -> "+nw); + } + } + } |