From 2bcbaedd3be76960f6cdce40bd650ce58f9078c5 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Fri, 12 Jun 2009 12:34:29 +0000 Subject: - Adding CR + TAB to toString() methods for better visibility, use a unix style capable viewer/editor for the debug methods .. - Multihead code is working now for - GLCanvas, GLJPanel - Newt: GLWindow, AWTWindow and WindowsWindow WindowsWindow is using the MonitorFromWindow(HWND) win32 method to detect a monitor change, same as AWT's implementation. AWT does the detection within getGraphicsConfiguration(). Added documention in GLAutoDrawable inkl. the fixed protocol for such a case (regeneration cycle). The interesting thing here is, that in my test environment, the windows NV driver keeps up the previous HDC pixelformat even within a new HDC (all same HWND), if the HWND is dragged from a 32bpp-screen to a 16bpp-screen and vice versa. But for the sake of other driver behaviors, this implementation shall fix the multihead support on windows and other non Xinerama driven arrangements. Another good thing of the in deep investigation was to fix the documentation and other bus, as follows: - FIX GLDrawableHelper.dispose(): Don't remove the event listeners, since dispose() does not mean EOL. - FIX remove all actions of NativeWindow.LOCK_SURFACE_CHANGED, due to the unreliable (never worked here for me) behavior. Also .. acting on a surface change from within a GLDrawable is already to low level, and misses all the appropriate actions. See GLAutoDrawable for the spec. - FIX all GLDrawable implementations update the graphics configuration on setVisible(true), except MacOSX, which does it on create context. The latter is ok with the spec .. - FIX removed the windows NO_FREE hack, since it could introduce a non released context .. which is not good. The context state shall be completely handled by GLContext - FIX GLDrawableImpl.setVisible(false): removed nativewindow invalidate() call - this is wrong, due to the spec. A window may survive many cycles of setVisible(). - FIX GLCOntextImpl lock the lock as soon as possible in destroy() - Add native method WindowsWindow.MonitorFromWindow(..) git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JOGL_2_SANDBOX@1932 232f8b59-042b-4e1e-8c03-345bb8c30851 --- src/newt/classes/com/sun/javafx/newt/Window.java | 31 ++- .../classes/com/sun/javafx/newt/awt/AWTCanvas.java | 217 +++++++++++++++++++++ .../com/sun/javafx/newt/awt/AWTDisplay.java | 4 + .../classes/com/sun/javafx/newt/awt/AWTScreen.java | 4 + .../classes/com/sun/javafx/newt/awt/AWTWindow.java | 80 ++++---- .../com/sun/javafx/newt/opengl/GLWindow.java | 35 +++- .../com/sun/javafx/newt/windows/WindowsWindow.java | 33 ++++ 7 files changed, 350 insertions(+), 54 deletions(-) create mode 100644 src/newt/classes/com/sun/javafx/newt/awt/AWTCanvas.java (limited to 'src/newt/classes') diff --git a/src/newt/classes/com/sun/javafx/newt/Window.java b/src/newt/classes/com/sun/javafx/newt/Window.java index 10a31f451..c2ab88b32 100755 --- a/src/newt/classes/com/sun/javafx/newt/Window.java +++ b/src/newt/classes/com/sun/javafx/newt/Window.java @@ -247,7 +247,7 @@ public abstract class Window implements NativeWindow public synchronized void destroy() { if(DEBUG_WINDOW_EVENT) { - System.out.println("Window.destroy() start"); + System.out.println("Window.destroy() start "+Thread.currentThread().getName()); } windowListeners = new ArrayList(); mouseListeners = new ArrayList(); @@ -255,15 +255,15 @@ public abstract class Window implements NativeWindow closeNative(); invalidate(); if(DEBUG_WINDOW_EVENT) { - System.out.println("Window.destroy() end"); + System.out.println("Window.destroy() end "+Thread.currentThread().getName()); } } public void invalidate() { - invalidate(false); - } - - public void invalidate(boolean internal) { + if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { + Exception e = new Exception("!!! Window Invalidate "+Thread.currentThread().getName()); + e.printStackTrace(); + } screen = null; windowHandle = 0; fullscreen=false; @@ -297,6 +297,13 @@ public abstract class Window implements NativeWindow return windowHandle; // default: return window handle } + /** Special method to dispose a surface handle, + in case of a device change _and_ where there + is a different semantics of window handle and surface handle. + This is currently only true for Windows. */ + public void disposeSurfaceHandle() { + } + public AbstractGraphicsConfiguration getGraphicsConfiguration() { return config; } @@ -337,6 +344,12 @@ public abstract class Window implements NativeWindow private boolean autoDrawableMember = false; + /** If the implementation is capable of detecting a device change + return true and clear the status/reason of the change. */ + public boolean hasDeviceChanged() { + return false; + } + /** * If set to true, * certain action will be performed by the owning @@ -348,7 +361,7 @@ public abstract class Window implements NativeWindow protected void windowDestroyNotify() { if(DEBUG_WINDOW_EVENT) { - System.out.println("Window.windowDestroyeNotify start"); + System.out.println("Window.windowDestroyeNotify start "+Thread.currentThread().getName()); } sendWindowEvent(WindowEvent.EVENT_WINDOW_DESTROY_NOTIFY); @@ -358,13 +371,13 @@ public abstract class Window implements NativeWindow } if(DEBUG_WINDOW_EVENT) { - System.out.println("Window.windowDestroyeNotify end"); + System.out.println("Window.windowDestroyeNotify end "+Thread.currentThread().getName()); } } protected void windowDestroyed() { if(DEBUG_WINDOW_EVENT) { - System.out.println("Window.windowDestroyed"); + System.out.println("Window.windowDestroyed "+Thread.currentThread().getName()); } invalidate(); } diff --git a/src/newt/classes/com/sun/javafx/newt/awt/AWTCanvas.java b/src/newt/classes/com/sun/javafx/newt/awt/AWTCanvas.java new file mode 100644 index 000000000..4bcb2b2cb --- /dev/null +++ b/src/newt/classes/com/sun/javafx/newt/awt/AWTCanvas.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN + * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR + * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR + * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR + * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR + * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE + * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, + * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF + * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + */ + +package com.sun.javafx.newt.awt; + +import com.sun.javafx.newt.Window; + +import java.awt.Canvas; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.GraphicsConfiguration; + +import javax.media.nativewindow.*; +import javax.media.nativewindow.awt.*; +import com.sun.javafx.newt.impl.Debug; + +public class AWTCanvas extends Canvas { + private GraphicsDevice device; + private GraphicsConfiguration chosen; + private AWTGraphicsConfiguration awtConfig; + + private Capabilities capabilities; + + private boolean displayConfigChanged=false; + + public AWTCanvas(Capabilities capabilities) { + super(); + + if(null==capabilities) { + throw new NativeWindowException("Capabilities null"); + } + this.capabilities=capabilities; + } + + public AWTGraphicsConfiguration getAWTGraphicsConfiguration() { + return awtConfig; + } + + public boolean hasDeviceChanged() { + boolean res = displayConfigChanged; + displayConfigChanged=false; + return res; + } + + public void addNotify() { + super.addNotify(); + + GraphicsConfiguration gc = super.getGraphicsConfiguration(); + if(null!=gc) { + device = gc.getDevice(); + } + + /* + * Save the chosen capabilities for use in getGraphicsConfiguration(). + */ + awtConfig = chooseGraphicsConfiguration(capabilities, device); + if(Window.DEBUG_IMPLEMENTATION) { + Exception e = new Exception("Created Config: "+awtConfig); + e.printStackTrace(); + } + if(null!=awtConfig) { + // update .. + chosen = awtConfig.getGraphicsConfiguration(); + } + if(null==awtConfig) { + throw new NativeWindowException("Error: AWTGraphicsConfiguration is null"); + } + } + + /** + * Overridden to choose a GraphicsConfiguration on a parent container's + * GraphicsDevice because both devices + */ + public GraphicsConfiguration getGraphicsConfiguration() { + /* + * Workaround for problems with Xinerama and java.awt.Component.checkGD + * when adding to a container on a different graphics device than the + * one that this Canvas is associated with. + * + * GC will be null unless: + * - A native peer has assigned it. This means we have a native + * peer, and are already comitted to a graphics configuration. + * - This canvas has been added to a component hierarchy and has + * an ancestor with a non-null GC, but the native peer has not + * yet been created. This means we can still choose the GC on + * all platforms since the peer hasn't been created. + */ + final GraphicsConfiguration gc = super.getGraphicsConfiguration(); + /* + * chosen is only non-null on platforms where the GLDrawableFactory + * returns a non-null GraphicsConfiguration (in the GLCanvas + * constructor). + * + * if gc is from this Canvas' native peer then it should equal chosen, + * otherwise it is from an ancestor component that this Canvas is being + * added to, and we go into this block. + */ + if (gc != null && chosen != null && !chosen.equals(gc)) { + /* + * Check for compatibility with gc. If they differ by only the + * device then return a new GCconfig with the super-class' GDevice + * (and presumably the same visual ID in Xinerama). + * + */ + if (!chosen.getDevice().getIDstring().equals(gc.getDevice().getIDstring())) { + /* + * Here we select a GraphicsConfiguration on the alternate + * device that is presumably identical to the chosen + * configuration, but on the other device. + * + * Should really check to ensure that we select a configuration + * with the same X visual ID for Xinerama screens, otherwise the + * GLDrawable may have the wrong visual ID (I don't think this + * ever gets updated). May need to add a method to + * X11GLDrawableFactory to do this in a platform specific + * manner. + * + * However, on platforms where we can actually get into this + * block, both devices should have the same visual list, and the + * same configuration should be selected here. + */ + AWTGraphicsConfiguration config = chooseGraphicsConfiguration((Capabilities)awtConfig.getRequestedCapabilities(), gc.getDevice()); + final GraphicsConfiguration compatible = (null!=config)?config.getGraphicsConfiguration():null; + if(Window.DEBUG_IMPLEMENTATION) { + Exception e = new Exception("Call Stack: "+Thread.currentThread().getName()); + e.printStackTrace(); + System.err.println("!!! Created Config (n): HAVE GC "+chosen); + System.err.println("!!! Created Config (n): THIS GC "+gc); + System.err.println("!!! Created Config (n): Choosen GC "+compatible); + System.err.println("!!! Created Config (n): HAVE CF "+awtConfig); + System.err.println("!!! Created Config (n): Choosen CF "+config); + System.err.println("!!! Created Config (n): EQUALS CAPS "+config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities())); + } + + if (compatible != null) { + /* + * Save the new GC for equals test above, and to return to + * any outside callers of this method. + */ + chosen = compatible; + if( !config.getChosenCapabilities().equals(awtConfig.getChosenCapabilities())) { + displayConfigChanged=true; + } + awtConfig = config; + } + } + + /* + * If a compatible GC was not found in the block above, this will + * return the GC that was selected in the constructor (and might + * cause an exception in Component.checkGD when adding to a + * container, but in this case that would be the desired behavior). + * + */ + return chosen; + } else if (gc == null) { + /* + * The GC is null, which means we have no native peer, and are not + * part of a (realized) component hierarchy. So we return the + * desired visual that was selected in the constructor (possibly + * null). + */ + return chosen; + } + + /* + * Otherwise we have not explicitly selected a GC in the constructor, so + * just return what Canvas would have. + */ + return gc; + } + + private static AWTGraphicsConfiguration chooseGraphicsConfiguration(Capabilities capabilities, + GraphicsDevice device) { + AbstractGraphicsScreen aScreen = AWTGraphicsScreen.createScreenDevice(device); + AWTGraphicsConfiguration config = (AWTGraphicsConfiguration) + GraphicsConfigurationFactory.getFactory(AWTGraphicsDevice.class).chooseGraphicsConfiguration(capabilities, + null, + aScreen); + if (config == null) { + throw new NativeWindowException("Error: Couldn't fetch AWTGraphicsConfiguration"); + } + + return config; + } + +} diff --git a/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java b/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java index f6f4a6fe8..099125630 100644 --- a/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java +++ b/src/newt/classes/com/sun/javafx/newt/awt/AWTDisplay.java @@ -46,5 +46,9 @@ public class AWTDisplay extends Display { aDevice = (AWTGraphicsDevice) AWTGraphicsDevice.createDevice(null); // default } + protected void setAWTGraphicsDevice(AWTGraphicsDevice d) { + aDevice = d; + } + protected void closeNative() { } } diff --git a/src/newt/classes/com/sun/javafx/newt/awt/AWTScreen.java b/src/newt/classes/com/sun/javafx/newt/awt/AWTScreen.java index 93e57d72f..73436c3be 100644 --- a/src/newt/classes/com/sun/javafx/newt/awt/AWTScreen.java +++ b/src/newt/classes/com/sun/javafx/newt/awt/AWTScreen.java @@ -45,6 +45,10 @@ public class AWTScreen extends Screen { aScreen = new AWTGraphicsScreen((AWTGraphicsDevice)display.getGraphicsDevice()); } + protected void setAWTGraphicsScreen(AWTGraphicsScreen s) { + aScreen = s; + } + protected void closeNative() { } } diff --git a/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java b/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java index cb8c56d55..35413f132 100644 --- a/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java +++ b/src/newt/classes/com/sun/javafx/newt/awt/AWTWindow.java @@ -62,12 +62,11 @@ public class AWTWindow extends Window { } private Frame frame; - private Canvas canvas; + private AWTCanvas canvas; private LinkedList/**/ events = new LinkedList(); private boolean gotDisplaySize; private int displayWidth; private int displayHeight; - private volatile boolean awtCreated=false; public void setTitle(String title) { super.setTitle(title); @@ -76,47 +75,26 @@ public class AWTWindow extends Window { } } - Object syncObj = new Object(); - - protected void createNative(Capabilities caps) { - config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen()); - if (config == null) { - throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); - } + protected void createNative(final Capabilities caps) { runOnEDT(new Runnable() { public void run() { - synchronized (syncObj) { - frame = new Frame(getTitle()); - frame.setUndecorated(isUndecorated()); - frame.setLayout(new BorderLayout()); - canvas = new Canvas( ((AWTGraphicsConfiguration) config).getGraphicsConfiguration() ); - Listener listener = new Listener(); - canvas.addMouseListener(listener); - canvas.addMouseMotionListener(listener); - canvas.addKeyListener(listener); - canvas.addComponentListener(listener); - frame.add(canvas, BorderLayout.CENTER); - frame.setSize(width, height); - frame.setLocation(x, y); - frame.addComponentListener(new MoveListener()); - frame.addWindowListener(new WindowEventListener()); - awtCreated=true; - syncObj.notifyAll(); - } + frame = new Frame(getTitle()); + frame.setUndecorated(isUndecorated()); + frame.setLayout(new BorderLayout()); + canvas = new AWTCanvas(caps); + Listener listener = new Listener(); + canvas.addMouseListener(listener); + canvas.addMouseMotionListener(listener); + canvas.addKeyListener(listener); + canvas.addComponentListener(listener); + frame.add(canvas, BorderLayout.CENTER); + frame.setSize(width, height); + frame.setLocation(x, y); + frame.addComponentListener(new MoveListener()); + frame.addWindowListener(new WindowEventListener()); } }); - - // make sure we are finished .. - while(!awtCreated) { - synchronized (syncObj) { - if(!awtCreated) { - try { - syncObj.wait(); - } catch (InterruptedException e) {} - } - } - } } protected void closeNative() { @@ -128,6 +106,20 @@ public class AWTWindow extends Window { }); } + public boolean hasDeviceChanged() { + boolean res = canvas.hasDeviceChanged(); + if(res) { + config = canvas.getAWTGraphicsConfiguration(); + if (config == null) { + throw new NativeWindowException("Error Device change null GraphicsConfiguration: "+this); + } + // propagate new info .. + ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)config.getScreen()); + ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)config.getScreen().getDevice()); + } + return res; + } + public int getDisplayWidth() { getDisplaySize(); return displayWidth; @@ -154,6 +146,16 @@ public class AWTWindow extends Window { frame.setVisible(visible); } }); + + config = canvas.getAWTGraphicsConfiguration(); + + if (config == null) { + throw new NativeWindowException("Error choosing GraphicsConfiguration creating window: "+this); + } + + // propagate new info .. + ((AWTScreen)getScreen()).setAWTGraphicsScreen((AWTGraphicsScreen)config.getScreen()); + ((AWTDisplay)getScreen().getDisplay()).setAWTGraphicsDevice((AWTGraphicsDevice)config.getScreen().getDevice()); } public void setSize(final int width, final int height) { @@ -238,7 +240,7 @@ public class AWTWindow extends Window { default: throw new NativeWindowException("Unknown event type " + w.getType()); } - if(DEBUG_MOUSE_EVENT) { + if(Window.DEBUG_MOUSE_EVENT) { System.out.println("dispatchMessages: in event:"+w.getEvent()); } } diff --git a/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java b/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java index cd784c858..6dfd57441 100644 --- a/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/sun/javafx/newt/opengl/GLWindow.java @@ -153,7 +153,7 @@ public class GLWindow extends Window implements GLAutoDrawable { protected void dispose(boolean regenerate) { if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - Exception e1 = new Exception("GLWindow.destroy("+regenerate+") 1: "+this); + Exception e1 = new Exception("GLWindow.dispose("+regenerate+") "+Thread.currentThread().getName()+", 1: "+this); e1.printStackTrace(); } @@ -166,22 +166,39 @@ public class GLWindow extends Window implements GLAutoDrawable { drawable.setRealized(false); } + if(null!=window) { + window.disposeSurfaceHandle(); + } + if(regenerate) { + if(null==window) { + throw new GLException("GLWindow.dispose(true): null window"); + } + + // recreate GLDrawable, to reflect the new graphics configurations + NativeWindow nw; + if (window.getWrappedWindow() != null) { + nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration()); + } else { + nw = window; + } + drawable = factory.createGLDrawable(nw); drawable.setRealized(true); if(getSurfaceHandle()==0) { throw new GLException("SurfaceHandle==NULL after setRealize(true) "+this); } context = drawable.createContext(null); + sendReshape = true; // ensure a reshape event is send .. } if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - System.out.println("GLWindow.dispose("+regenerate+") fin: "+this); + System.out.println("GLWindow.dispose("+regenerate+") "+Thread.currentThread().getName()+", fin: "+this); } } public synchronized void destroy() { if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - Exception e1 = new Exception("GLWindow.destroy 1: "+this); + Exception e1 = new Exception("GLWindow.destroy "+Thread.currentThread().getName()+", 1: "+this); e1.printStackTrace(); } @@ -200,7 +217,7 @@ public class GLWindow extends Window implements GLAutoDrawable { } if(Window.DEBUG_WINDOW_EVENT || window.DEBUG_IMPLEMENTATION) { - System.out.println("GLWindow.destroy fin: "+this); + System.out.println("GLWindow.destroy "+Thread.currentThread().getName()+", fin: "+this); } drawable = null; @@ -288,9 +305,11 @@ public class GLWindow extends Window implements GLAutoDrawable { public void setVisible(boolean visible) { window.setVisible(visible); if (visible && context == null) { - NativeWindow nw = window; + NativeWindow nw; if (window.getWrappedWindow() != null) { - nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), nw.getGraphicsConfiguration()); + nw = NativeWindowFactory.getNativeWindow(window.getWrappedWindow(), window.getGraphicsConfiguration()); + } else { + nw = window; } GLCapabilities glCaps = (GLCapabilities) nw.getGraphicsConfiguration().getNativeGraphicsConfiguration().getChosenCapabilities(); factory = GLDrawableFactory.getFactory(glCaps.getGLProfile()); @@ -300,6 +319,7 @@ public class GLWindow extends Window implements GLAutoDrawable { throw new GLException("SurfaceHandle==NULL after setRealize(true) "+this); } context = drawable.createContext(null); + sendReshape = true; // ensure a reshape event is send .. } } @@ -449,6 +469,9 @@ public class GLWindow extends Window implements GLAutoDrawable { public void display() { if(getSurfaceHandle()!=0) { pumpMessages(); + if(window.hasDeviceChanged()) { + dispose(true); + } if (sendDestroy) { destroy(); sendDestroy=false; diff --git a/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java b/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java index abb26a009..ddaf973c5 100755 --- a/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java +++ b/src/newt/classes/com/sun/javafx/newt/windows/WindowsWindow.java @@ -40,6 +40,7 @@ import com.sun.javafx.newt.impl.*; public class WindowsWindow extends Window { + private long hmon; private long hdc; private long windowHandleClose; @@ -58,10 +59,41 @@ public class WindowsWindow extends Window { public long getSurfaceHandle() { if (hdc == 0) { hdc = GetDC(windowHandle); + hmon = MonitorFromWindow(windowHandle); + if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { + Exception e = new Exception("!!! Window new surface handle "+Thread.currentThread().getName()+ + ",HDC 0x"+Long.toHexString(hdc)+", HMON 0x"+Long.toHexString(hmon)); + e.printStackTrace(); + } } return hdc; } + public boolean hasDeviceChanged() { + long _hmon = MonitorFromWindow(windowHandle); + if (hmon != _hmon) { + if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { + Exception e = new Exception("!!! Window Device Changed "+Thread.currentThread().getName()+ + ", HMON 0x"+Long.toHexString(hmon)+" -> 0x"+Long.toHexString(_hmon)); + e.printStackTrace(); + } + hmon = _hmon; + return true; + } + return false; + } + + public void disposeSurfaceHandle() { + if (hdc != 0) { + ReleaseDC(windowHandle, hdc); + hdc=0; + if(DEBUG_IMPLEMENTATION || DEBUG_WINDOW_EVENT) { + Exception e = new Exception("!!! Window surface handle disposed "+Thread.currentThread().getName()); + e.printStackTrace(); + } + } + } + protected void createNative(Capabilities caps) { long wndClass = getWindowClass(); config = GraphicsConfigurationFactory.getFactory(getScreen().getDisplay().getGraphicsDevice()).chooseGraphicsConfiguration(caps, null, getScreen().getGraphicsScreen()); @@ -188,6 +220,7 @@ public class WindowsWindow extends Window { private native void DestroyWindow(long windowHandle); private native long GetDC(long windowHandle); private native void ReleaseDC(long windowHandle, long hdc); + private native long MonitorFromWindow(long windowHandle); private native void setVisible0(long windowHandle, boolean visible); private static native void DispatchMessages(long windowHandle, int eventMask); private native void setSize0(long windowHandle, int width, int height); -- cgit v1.2.3