2 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
3 * Copyright (c) 2010 JogAmp Community. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * - Redistribution of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * - Redistribution in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * Neither the name of Sun Microsystems, Inc. or the names of
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
20 * This software is provided "AS IS," without a warranty of any kind. ALL
21 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
24 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
25 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
26 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
27 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
28 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
29 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
30 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
31 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
35 package jogamp.newt.driver.awt;
37 import java.awt.BorderLayout;
38 import java.awt.Container;
39 import java.awt.Dimension;
40 import java.awt.Frame;
41 import java.awt.Insets;
43 import javax.media.nativewindow.NativeSurface;
44 import javax.media.nativewindow.NativeWindow;
45 import javax.media.nativewindow.NativeWindowException;
46 import javax.media.nativewindow.util.Point;
48 import jogamp.nativewindow.awt.AWTMisc;
49 import jogamp.newt.WindowImpl;
51 import com.jogamp.common.os.Platform;
52 import com.jogamp.nativewindow.awt.AWTGraphicsConfiguration;
53 import com.jogamp.nativewindow.awt.AWTGraphicsDevice;
54 import com.jogamp.nativewindow.awt.AWTGraphicsScreen;
55 import com.jogamp.newt.event.WindowEvent;
56 import com.jogamp.newt.event.WindowUpdateEvent;
57 import com.jogamp.newt.event.awt.AWTKeyAdapter;
58 import com.jogamp.newt.event.awt.AWTMouseAdapter;
59 import com.jogamp.newt.event.awt.AWTWindowAdapter;
61 /** An implementation of the Newt Window class built using the
62 AWT. This is provided for convenience of porting to platforms
63 supporting Java SE. */
65 public class WindowDriver extends WindowImpl {
67 public WindowDriver() {
71 public static Class<?>[] getCustomConstructorArgumentTypes() {
72 return new Class<?>[] { Container.class } ;
75 public WindowDriver(Container container) {
77 this.awtContainer = container;
78 if(container instanceof Frame) {
79 awtFrame = (Frame) container;
83 private boolean owningFrame;
84 private Container awtContainer = null;
85 /** same instance as container, just for impl. convenience */
86 private Frame awtFrame = null;
87 private AWTCanvas awtCanvas;
90 protected void requestFocusImpl(boolean reparented) {
91 awtContainer.requestFocus();
95 protected void setTitleImpl(final String title) {
96 if (awtFrame != null) {
97 awtFrame.setTitle(title);
101 private final AWTCanvas.UpstreamScalable upstreamScalable = new AWTCanvas.UpstreamScalable() {
103 public int[] getReqPixelScale() {
104 return WindowDriver.this.reqPixelScale;
108 public void setHasPixelScale(final int[] pixelScale) {
109 System.arraycopy(pixelScale, 0, WindowDriver.this.hasPixelScale, 0, 2);
114 protected void createNativeImpl() {
115 if(0!=getParentWindowHandle()) {
116 throw new RuntimeException("Window parenting not supported in AWT, use AWTWindow(Frame) cstr for wrapping instead");
119 if(null==awtContainer) {
120 awtFrame = new Frame();
121 awtContainer = awtFrame;
125 defineSize(awtContainer.getWidth(), awtContainer.getHeight());
126 definePosition(awtContainer.getX(), awtContainer.getY());
129 awtFrame.setTitle(getTitle());
131 awtContainer.setLayout(new BorderLayout());
133 if( null == awtCanvas ) {
134 awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser, upstreamScalable);
136 // canvas.addComponentListener(listener);
137 awtContainer.add(awtCanvas, BorderLayout.CENTER);
140 new AWTMouseAdapter(this).addTo(awtCanvas); // fwd all AWT Mouse events to here
141 new AWTKeyAdapter(this).addTo(awtCanvas); // fwd all AWT Key events to here
144 new AWTWindowAdapter(new LocalWindowListener(), this).addTo(awtCanvas); // fwd all AWT Window events to here
147 reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), getReconfigureFlags(FLAG_CHANGE_VISIBILITY | FLAG_CHANGE_DECORATION, true));
148 // throws exception if failed ..
150 final NativeWindow nw = awtCanvas.getNativeWindow();
152 setGraphicsConfiguration( awtCanvas.getAWTGraphicsConfiguration() );
153 setWindowHandle( nw.getWindowHandle() );
158 protected void closeNativeImpl() {
160 if(null!=awtContainer) {
161 awtContainer.setVisible(false);
162 awtContainer.remove(awtCanvas);
163 awtContainer.setEnabled(false);
164 awtCanvas.setEnabled(false);
166 if(owningFrame && null!=awtFrame) {
176 public boolean hasDeviceChanged() {
177 boolean res = awtCanvas.hasDeviceChanged();
179 final AWTGraphicsConfiguration cfg = awtCanvas.getAWTGraphicsConfiguration();
181 throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this);
183 setGraphicsConfiguration(cfg);
185 // propagate new info ..
186 ((ScreenDriver)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)cfg.getScreen());
187 ((DisplayDriver)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)cfg.getScreen().getDevice());
189 ((ScreenDriver)getScreen()).updateVirtualScreenOriginAndSize();
195 protected void updateInsetsImpl(javax.media.nativewindow.util.Insets insets) {
196 final Insets contInsets = awtContainer.getInsets();
197 insets.set(contInsets.left, contInsets.right, contInsets.top, contInsets.bottom);
200 private void setCanvasSizeImpl(int width, int height) {
201 final Dimension szClient = new Dimension(width, height);
202 final java.awt.Window awtWindow = AWTMisc.getWindow(awtCanvas);
203 final Container c= null != awtWindow ? awtWindow : awtContainer;
204 awtCanvas.setMinimumSize(szClient);
205 awtCanvas.setPreferredSize(szClient);
206 if(DEBUG_IMPLEMENTATION) {
207 final Insets insets = c.getInsets();
208 final Dimension szContainer = new Dimension(width + insets.left + insets.right,
209 height + insets.top + insets.bottom);
210 System.err.println(getThreadName()+": AWTWindow setCanvasSize: szClient "+szClient+", szCont "+szContainer+", insets "+insets);
212 awtCanvas.setSize(szClient);
213 awtCanvas.invalidate();
214 if(null != awtWindow) {
217 awtContainer.validate();
220 private void setFrameSizeImpl(int width, int height) {
221 final Insets insets = awtContainer.getInsets();
222 final Dimension szContainer = new Dimension(width + insets.left + insets.right,
223 height + insets.top + insets.bottom);
224 if(DEBUG_IMPLEMENTATION) {
225 final Dimension szClient = new Dimension(width, height);
226 System.err.println(getThreadName()+": AWTWindow setFrameSize: szClient "+szClient+", szCont "+szContainer+", insets "+insets);
228 awtContainer.setSize(szContainer);
229 awtCanvas.invalidate();
230 awtContainer.validate();
234 protected boolean reconfigureWindowImpl(int x, int y, int width, int height, int flags) {
235 if(DEBUG_IMPLEMENTATION) {
236 System.err.println("AWTWindow reconfig: "+x+"/"+y+" "+width+"x"+height+", "+
237 getReconfigureFlagsAsString(null, flags));
239 if(0 != ( FLAG_CHANGE_DECORATION & flags) && null!=awtFrame) {
240 if(!awtContainer.isDisplayable()) {
241 awtFrame.setUndecorated(isUndecorated());
243 if(DEBUG_IMPLEMENTATION) {
244 System.err.println(getThreadName()+": AWTWindow can't undecorate already created frame");
249 if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
250 if( 0 != ( FLAG_IS_VISIBLE & flags) ) {
251 setCanvasSizeImpl(width, height);
252 awtContainer.setVisible( true );
254 awtContainer.setVisible( false );
256 } else if( awtCanvas.getWidth() != width || awtCanvas.getHeight() != height ) {
257 if( Platform.OSType.MACOS == Platform.getOSType() && awtCanvas.isOffscreenLayerSurfaceEnabled() ) {
258 setFrameSizeImpl(width, height);
260 setCanvasSizeImpl(width, height);
263 defineSize(width, height); // we are on AWT-EDT .. change values immediately
265 if( awtContainer.getX() != x || awtContainer.getY() != y ) {
266 awtContainer.setLocation(x, y);
269 if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) ) {
270 if( 0 != ( FLAG_IS_VISIBLE & flags ) ) {
271 if( !hasDeviceChanged() ) {
273 final AWTGraphicsConfiguration cfg = awtCanvas.getAWTGraphicsConfiguration();
275 throw new NativeWindowException("Error: !hasDeviceChanged && null == GraphicsConfiguration: "+this);
277 setGraphicsConfiguration(cfg);
280 visibleChanged(false, 0 != ( FLAG_IS_VISIBLE & flags));
287 protected Point getLocationOnScreenImpl(int x, int y) {
288 java.awt.Point ap = awtCanvas.getLocationOnScreen();
290 return new Point((int)(ap.getX()+0.5),(int)(ap.getY()+0.5));
294 public NativeSurface getWrappedSurface() {
295 return ( null != awtCanvas ) ? awtCanvas.getNativeWindow() : null;
298 class LocalWindowListener implements com.jogamp.newt.event.WindowListener {
300 public void windowMoved(com.jogamp.newt.event.WindowEvent e) {
301 if(null!=awtContainer) {
302 WindowDriver.this.positionChanged(false, awtContainer.getX(), awtContainer.getY());
306 public void windowResized(com.jogamp.newt.event.WindowEvent e) {
307 if(null!=awtCanvas) {
308 if(DEBUG_IMPLEMENTATION) {
309 System.err.println("Window Resized: "+awtCanvas);
311 WindowDriver.this.sizeChanged(false, awtCanvas.getWidth(), awtCanvas.getHeight(), true);
312 WindowDriver.this.windowRepaint(false, 0, 0, getSurfaceWidth(), getSurfaceHeight());
316 public void windowDestroyNotify(WindowEvent e) {
317 WindowDriver.this.windowDestroyNotify(false);
320 public void windowDestroyed(WindowEvent e) {
321 // Not fwd by AWTWindowAdapter, synthesized by NEWT
324 public void windowGainedFocus(WindowEvent e) {
325 WindowDriver.this.focusChanged(false, true);
328 public void windowLostFocus(WindowEvent e) {
329 WindowDriver.this.focusChanged(false, false);
332 public void windowRepaint(WindowUpdateEvent e) {
333 if(null!=awtCanvas) {
334 if(DEBUG_IMPLEMENTATION) {
335 System.err.println("Window Repaint: "+awtCanvas);
337 WindowDriver.this.windowRepaint(false, 0, 0, getSurfaceWidth(), getSurfaceHeight());