aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java61
-rw-r--r--src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java6
-rw-r--r--src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java15
-rw-r--r--src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java50
-rw-r--r--src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java6
-rw-r--r--src/jogl/classes/javax/media/opengl/GLProfile.java3
-rw-r--r--src/nativewindow/classes/com/sun/nativewindow/impl/LockingNativeWindowFactory.java (renamed from src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11NativeWindowFactory.java)8
-rw-r--r--src/nativewindow/classes/com/sun/nativewindow/impl/jvm/JVMUtil.java78
-rw-r--r--src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java126
-rw-r--r--src/nativewindow/classes/com/sun/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java2
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java61
-rw-r--r--src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java6
-rw-r--r--src/nativewindow/native/JVM_Tool.c51
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/NewtFactory.java2
-rwxr-xr-xsrc/newt/classes/com/sun/javafx/newt/x11/X11Display.java22
-rwxr-xr-xsrc/newt/native/X11Window.c52
16 files changed, 331 insertions, 218 deletions
diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java
index b3d25b52c..8f21fef42 100644
--- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java
+++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/GLXUtil.java
@@ -39,63 +39,18 @@ import javax.media.nativewindow.NativeWindowFactory;
import com.sun.nativewindow.impl.x11.*;
public class GLXUtil {
- private static final boolean DEBUG = Debug.debug("GLXUtil");
-
- private GLXUtil() {}
-
- // ATI's proprietary drivers apparently send GLX tokens even for
- // direct contexts, so we need to disable the context optimizations
- // in this case
- private static boolean isVendorATI;
-
- // Display connection for use by visual selection algorithm and by all offscreen surfaces
- private static boolean multisampleAvailable=false;
-
- private static volatile boolean isInit=false;
-
- private static synchronized void init() {
- if (!isInit) {
- synchronized (GLXUtil.class) {
- if (!isInit) {
- long locDisplay = X11Util.getThreadLocalDefaultDisplay();
- if(locDisplay!=0) {
- if (DEBUG) {
- int screen = X11Lib.DefaultScreen(locDisplay);
- System.err.println("!!! GLX server vendor : " +
- GLX.glXQueryServerString(locDisplay, screen, GLX.GLX_VENDOR));
- System.err.println("!!! GLX server version: " +
- GLX.glXQueryServerString(locDisplay, screen, GLX.GLX_VERSION));
- System.err.println("!!! GLX client vendor : " +
- GLX.glXGetClientString(locDisplay, GLX.GLX_VENDOR));
- System.err.println("!!! GLX client version: " +
- GLX.glXGetClientString(locDisplay, GLX.GLX_VERSION));
- }
- String vendor = GLX.glXGetClientString(locDisplay, GLX.GLX_VENDOR);
- if (vendor != null && vendor.startsWith("ATI")) {
- isVendorATI = true;
- }
- String exts = GLX.glXGetClientString(locDisplay, GLX.GLX_EXTENSIONS);
- if (exts != null) {
- multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0);
- }
- isInit=true;
- } else {
- throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling");
- }
- }
- }
+ public static boolean isMultisampleAvailable(long display) {
+ String exts = GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS);
+ if (exts != null) {
+ return (exts.indexOf("GLX_ARB_multisample") >= 0);
}
- }
-
- public static boolean isMultisampleAvailable() {
- init();
- return multisampleAvailable;
+ return false;
}
/** Workaround for apparent issue with ATI's proprietary drivers
where direct contexts still send GLX tokens for GL calls */
- public static boolean isVendorATI() {
- init();
- return isVendorATI;
+ public static boolean isVendorATI(long display) {
+ String vendor = GLX.glXGetClientString(display, GLX.GLX_VENDOR);
+ return vendor != null && vendor.startsWith("ATI") ;
}
}
diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java
index 921d305a8..7029b81b0 100644
--- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java
+++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXContext.java
@@ -134,6 +134,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
GLCapabilities glCaps = (GLCapabilities) config.getChosenCapabilities();
long display = config.getScreen().getDevice().getHandle();
+ isVendorATI = GLXUtil.isVendorATI(display);
if(config.getFBConfigID()<0) {
// not able to use FBConfig
@@ -424,8 +425,7 @@ public abstract class X11GLXContext extends GLContextImpl {
}
public boolean isOptimizable() {
- return (super.isOptimizable() &&
- !GLXUtil.isVendorATI());
+ return (super.isOptimizable() && !isVendorATI);
}
//----------------------------------------------------------------------
@@ -436,4 +436,6 @@ public abstract class X11GLXContext extends GLContextImpl {
return context;
}
+ private boolean isVendorATI = false;
+
}
diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
index 404881329..83f671cb4 100644
--- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
+++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfiguration.java
@@ -288,7 +288,10 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
// FBConfig
- public static GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg) {
+ // sgothel: The synchronized was added, due to bugs within the GLX implementation on my platform
+ // in regards to multithreading (FIXME).
+
+ public synchronized static GLCapabilities GLXFBConfig2GLCapabilities(GLProfile glp, long display, long fbcfg, boolean isMultisampleEnabled) {
int[] tmp = new int[1];
int val;
val = glXGetFBConfig(display, fbcfg, GLX.GLX_RENDER_TYPE, tmp, 0);
@@ -309,7 +312,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setAccumGreenBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
res.setAccumBlueBits (glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
res.setAccumAlphaBits(glXGetFBConfig(display, fbcfg, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
- if (GLXUtil.isMultisampleAvailable()) {
+ if (isMultisampleEnabled) {
res.setSampleBuffers(glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
res.setNumSamples (glXGetFBConfig(display, fbcfg, GLX.GLX_SAMPLES, tmp, 0));
}
@@ -333,7 +336,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return res;
}
- private static String glXGetFBConfigErrorCode(int err) {
+ private synchronized static String glXGetFBConfigErrorCode(int err) {
switch (err) {
case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
@@ -341,7 +344,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
}
}
- public static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) {
+ public synchronized static int glXGetFBConfig(long display, long cfg, int attrib, int[] tmp, int tmp_offset) {
if (display == 0) {
throw new GLException("No display connection");
}
@@ -376,7 +379,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
return res;
}
- public static GLCapabilities XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info) {
+ public static GLCapabilities XVisualInfo2GLCapabilities(GLProfile glp, long display, XVisualInfo info, boolean isMultisampleEnabled) {
int[] tmp = new int[1];
int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
if (val == 0) {
@@ -404,7 +407,7 @@ public class X11GLXGraphicsConfiguration extends X11GraphicsConfiguration implem
res.setAccumGreenBits(glXGetConfig(display, info, GLX.GLX_ACCUM_GREEN_SIZE, tmp, 0));
res.setAccumBlueBits (glXGetConfig(display, info, GLX.GLX_ACCUM_BLUE_SIZE, tmp, 0));
res.setAccumAlphaBits(glXGetConfig(display, info, GLX.GLX_ACCUM_ALPHA_SIZE, tmp, 0));
- if (GLXUtil.isMultisampleAvailable()) {
+ if (isMultisampleEnabled) {
res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS, tmp, 0) != 0);
res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES, tmp, 0));
}
diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
index 1e2f2f185..9acf580c4 100644
--- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/X11GLXGraphicsConfigurationFactory.java
@@ -74,26 +74,27 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
long fbcfg = 0;
int fbid = -1;
- long display = x11Screen.getDevice().getHandle();
- int screen = x11Screen.getIndex();
-
// Utilizing FBConfig
//
GLCapabilities capsFB = null;
NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
try {
+ long display = x11Screen.getDevice().getHandle();
+ int screen = x11Screen.getIndex();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+
long visID = X11Lib.DefaultVisualID(display, x11Screen.getIndex());
xvis = X11GLXGraphicsConfiguration.XVisualID2XVisualInfo(display, visID);
- caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis);
+ caps = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, xvis, isMultisampleAvailable);
- int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, GLXUtil.isMultisampleAvailable(), usePBuffer, 0, 0);
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(caps, true, isMultisampleAvailable, usePBuffer, 0, 0);
int[] count = { -1 };
java.nio.LongBuffer fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
if (fbcfgsL == null || fbcfgsL.limit()<1) {
throw new Exception("Could not fetch FBConfig for "+caps);
}
fbcfg = fbcfgsL.get(0);
- capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg);
+ capsFB = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfg, isMultisampleAvailable);
int[] tmpID = new int[1];
fbid = X11GLXGraphicsConfiguration.glXGetFBConfig(display, fbcfg, GLX.GLX_FBCONFIG_ID, tmpID, 0);
@@ -102,10 +103,10 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
if (xvis==null) {
throw new GLException("Error: Choosen FBConfig has no visual");
}
- } catch (Throwable t) {
- } finally {
+ } catch (Throwable t) {
+ } finally {
NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
- }
+ }
return new X11GLXGraphicsConfiguration(x11Screen, (null!=capsFB)?capsFB:caps, caps, null, xvis, fbcfg, fbid);
}
@@ -163,12 +164,6 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
GLCapabilitiesChooser chooser,
X11GraphicsScreen x11Screen,
boolean usePBuffer) {
- int screen = x11Screen.getIndex();
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
-
- int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, GLXUtil.isMultisampleAvailable(), usePBuffer, 0, 0);
- int[] count = { -1 };
int recommendedIndex = -1;
GLCapabilities[] caps = null;
java.nio.LongBuffer fbcfgsL = null;
@@ -181,6 +176,13 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
//
NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
try {
+ int screen = x11Screen.getIndex();
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, true, isMultisampleAvailable, usePBuffer, 0, 0);
+ int[] count = { -1 };
+
fbcfgsL = GLX.glXChooseFBConfigCopied(display, screen, attribs, 0, count, 0);
if (fbcfgsL == null || fbcfgsL.limit()<1) {
if(DEBUG) {
@@ -191,7 +193,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
recommendedIndex = 0; // 1st match is always recommended ..
caps = new GLCapabilities[fbcfgsL.limit()];
for (int i = 0; i < fbcfgsL.limit(); i++) {
- caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i));
+ caps[i] = X11GLXGraphicsConfiguration.GLXFBConfig2GLCapabilities(glProfile, display, fbcfgsL.get(i), isMultisampleAvailable);
}
if(null==chooser) {
@@ -228,22 +230,15 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
protected static X11GLXGraphicsConfiguration chooseGraphicsConfigurationXVisual(GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
X11GraphicsScreen x11Screen) {
-
if (chooser == null) {
chooser = new DefaultGLCapabilitiesChooser();
}
- int screen = x11Screen.getIndex();
- AbstractGraphicsDevice absDevice = x11Screen.getDevice();
- long display = absDevice.getHandle();
-
// Until we have a rock-solid visual selection algorithm written
// in pure Java, we're going to provide the underlying window
// system's selection to the chooser as a hint
GLProfile glProfile = capabilities.getGLProfile();
- int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, GLXUtil.isMultisampleAvailable(), false, 0, 0);
- XVisualInfo[] infos = null;
GLCapabilities[] caps = null;
int recommendedIndex = -1;
XVisualInfo retXVisualInfo = null;
@@ -251,6 +246,13 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
try {
+ int screen = x11Screen.getIndex();
+ AbstractGraphicsDevice absDevice = x11Screen.getDevice();
+ long display = absDevice.getHandle();
+ boolean isMultisampleAvailable = GLXUtil.isMultisampleAvailable(display);
+ int[] attribs = X11GLXGraphicsConfiguration.GLCapabilities2AttribList(capabilities, false, isMultisampleAvailable, false, 0, 0);
+ XVisualInfo[] infos = null;
+
XVisualInfo recommendedVis = GLX.glXChooseVisualCopied(display, screen, attribs, 0);
if (DEBUG) {
System.err.print("!!! glXChooseVisual recommended ");
@@ -269,7 +271,7 @@ public class X11GLXGraphicsConfigurationFactory extends GraphicsConfigurationFac
}
caps = new GLCapabilities[infos.length];
for (int i = 0; i < infos.length; i++) {
- caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i]);
+ caps[i] = X11GLXGraphicsConfiguration.XVisualInfo2GLCapabilities(glProfile, display, infos[i], isMultisampleAvailable);
// Attempt to find the visual chosen by glXChooseVisual
if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) {
recommendedIndex = i;
diff --git a/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java b/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
index 78ff306aa..604bde46b 100644
--- a/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
+++ b/src/jogl/classes/com/sun/opengl/impl/x11/glx/awt/X11AWTGLXGraphicsConfigurationFactory.java
@@ -94,8 +94,10 @@ public class X11AWTGLXGraphicsConfigurationFactory extends GraphicsConfiguration
if(DEBUG) {
System.err.println("X11AWTGLXGraphicsConfigurationFactory: using a thread local X11 display");
}
- } else if(DEBUG) {
- System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle));
+ } else {
+ if(DEBUG) {
+ System.err.println("X11AWTGLXGraphicsConfigurationFactory: using AWT X11 display 0x"+Long.toHexString(displayHandle));
+ }
}
((AWTGraphicsDevice)awtScreen.getDevice()).setHandle(displayHandle);
x11Device = new X11GraphicsDevice(displayHandle);
diff --git a/src/jogl/classes/javax/media/opengl/GLProfile.java b/src/jogl/classes/javax/media/opengl/GLProfile.java
index 385006b75..ead5f6396 100644
--- a/src/jogl/classes/javax/media/opengl/GLProfile.java
+++ b/src/jogl/classes/javax/media/opengl/GLProfile.java
@@ -42,6 +42,7 @@ import java.util.HashMap;
import java.security.*;
import com.sun.opengl.impl.*;
import com.sun.nativewindow.impl.NWReflection;
+import com.sun.nativewindow.impl.jvm.JVMUtil;
/**
* Specifies the the OpenGL profile.
@@ -613,6 +614,8 @@ public class GLProfile implements Cloneable {
* Throws an GLException if no profile could be found at all.
*/
static {
+ JVMUtil.initSingleton();
+
boolean hasDesktopGL = false;
boolean hasDesktopGLES12 = false;
boolean hasNativeOSFactory = false;
diff --git a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11NativeWindowFactory.java b/src/nativewindow/classes/com/sun/nativewindow/impl/LockingNativeWindowFactory.java
index 1c67d6184..880fd8c7d 100644
--- a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11NativeWindowFactory.java
+++ b/src/nativewindow/classes/com/sun/nativewindow/impl/LockingNativeWindowFactory.java
@@ -30,14 +30,12 @@
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
-package com.sun.nativewindow.impl.x11;
+package com.sun.nativewindow.impl;
import javax.media.nativewindow.*;
-import com.sun.nativewindow.impl.*;
-public class X11NativeWindowFactory extends NativeWindowFactoryImpl {
- // On X11 platforms we need to do some locking; this basic
- // implementation should suffice for some simple window toolkits
+public class LockingNativeWindowFactory extends NativeWindowFactoryImpl {
+ // Provides a generic basic and recursive locking mechanism for your discretion.
private ToolkitLock toolkitLock = new ToolkitLock() {
private Thread owner;
private int recursionCount;
diff --git a/src/nativewindow/classes/com/sun/nativewindow/impl/jvm/JVMUtil.java b/src/nativewindow/classes/com/sun/nativewindow/impl/jvm/JVMUtil.java
new file mode 100644
index 000000000..a4bffb100
--- /dev/null
+++ b/src/nativewindow/classes/com/sun/nativewindow/impl/jvm/JVMUtil.java
@@ -0,0 +1,78 @@
+/*
+ * 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.nativewindow.impl.jvm;
+
+import java.nio.ByteBuffer;
+import com.sun.nativewindow.impl.*;
+
+/**
+ * Currently this tool works around the Hotspot race condition bugs:
+ <PRE>
+ 4395095 JNI access to java.nio DirectBuffer constructor/accessor
+ 6852404 Race condition in JNI Direct Buffer access and creation routines
+ </PRE>
+ *
+ * Make sure to initialize this class as soon as possible,
+ * before doing any multithreading work.
+ *
+ */
+public class JVMUtil {
+ private static final boolean DEBUG = Debug.debug("JVMUtil");
+
+ static {
+ initSingleton();
+ }
+
+ private static volatile boolean isInit = false;
+
+ public static synchronized void initSingleton() {
+ if(isInit) return;
+ isInit=true;
+
+ NativeLibLoaderBase.loadNativeWindow("jvm");
+
+ ByteBuffer buffer = InternalBufferUtil.newByteBuffer(64);
+ if( ! initialize(buffer) ) {
+ throw new RuntimeException("Failed to initialize the JVMUtil "+Thread.currentThread().getName());
+ }
+ if(DEBUG) {
+ Exception e = new Exception("JVMUtil.initSingleton() .. initialized "+Thread.currentThread().getName());
+ e.printStackTrace();
+ }
+ }
+
+ private JVMUtil() {}
+
+ private static native boolean initialize(java.nio.ByteBuffer buffer);
+}
+
diff --git a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java b/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java
index acd55a823..11343f3e1 100644
--- a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java
+++ b/src/nativewindow/classes/com/sun/nativewindow/impl/x11/X11Util.java
@@ -33,6 +33,7 @@
package com.sun.nativewindow.impl.x11;
import java.util.HashMap;
+import java.util.Map;
import javax.media.nativewindow.*;
@@ -54,35 +55,112 @@ public class X11Util {
private X11Util() {}
- private static ThreadLocal currentDisplayAssociation = new ThreadLocal();
+ private static ThreadLocal currentDisplayMap = new ThreadLocal();
- /** Returns the global static default display connection, read the toolkit lock/unlock
- * requirements {@link X11Util above} for synchronization. */
- public static boolean isXineramaEnabledOnThreadLocalDefaultDisplay() {
- long dpy = getThreadLocalDefaultDisplay();
- return X11Lib.XineramaEnabled(dpy);
+ public static class NamedDisplay implements Cloneable {
+ private String name;
+ private long handle;
+
+ protected NamedDisplay(String name, long handle) {
+ this.name=name;
+ this.handle=handle;
+ }
+
+ public String getName() { return name; }
+ public long getHandle() { return handle; }
+
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
+ }
+
+ /** Returns a clone of the thread local display map, you may {@link Object#wait()} on it */
+ public static Map getCurrentDisplayMap() {
+ return (Map) ((HashMap)getCurrentDisplayMapImpl()).clone();
}
- /** Returns this thread current default display. */
+ /** Returns this thread current default display. If it doesn not exist, it is being created */
public static long getThreadLocalDefaultDisplay() {
- Long dpyL = (Long) currentDisplayAssociation.get();
- if(null==dpyL) {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().lock();
- try {
- long dpy = X11Lib.XOpenDisplay(null);
- if(0==dpy) {
- throw new NativeWindowException("Unable to create a default display connection on Thread "+Thread.currentThread().getName());
- }
- dpyL = new Long(dpy);
- currentDisplayAssociation.set( dpyL );
- if(DEBUG) {
- Exception e = new Exception("Created new TLS display connection 0x"+Long.toHexString(dpy)+" for thread "+Thread.currentThread().getName());
- e.printStackTrace();
- }
- } finally {
- NativeWindowFactory.getDefaultFactory().getToolkitLock().unlock();
+ return getThreadLocalDisplay(null);
+ }
+
+ /** Returns this thread named display. If it doesn not exist, it is being created */
+ public static long getThreadLocalDisplay(String name) {
+ NamedDisplay namedDpy = getCurrentDisplay(name);
+ if(null==namedDpy) {
+ long dpy = X11Lib.XOpenDisplay(name);
+ if(0==dpy) {
+ throw new NativeWindowException("X11Util.Display: Unable to create a display("+name+") connection in Thread "+Thread.currentThread().getName());
+ }
+ namedDpy = new NamedDisplay(name, dpy);
+ setCurrentDisplay( namedDpy );
+ if(DEBUG) {
+ Exception e = new Exception("X11Util.Display: Created new TLS display("+name+") connection 0x"+Long.toHexString(dpy)+" in thread "+Thread.currentThread().getName());
+ e.printStackTrace();
}
}
- return dpyL.longValue();
+ return namedDpy.getHandle();
}
+
+ /** Closes this thread named display. It returns the handle of the closed display or 0, if it does not exist. */
+ public static long closeThreadLocalDisplay(String name) {
+ NamedDisplay namedDpy = removeCurrentDisplay(name);
+ if(null==namedDpy) {
+ if(DEBUG) {
+ Exception e = new Exception("X11Util.Display: Display("+name+") with given handle is not mapped to TLS in thread "+Thread.currentThread().getName());
+ e.printStackTrace();
+ }
+ return 0;
+ }
+ long dpy = namedDpy.getHandle();
+ X11Lib.XCloseDisplay(dpy);
+ if(DEBUG) {
+ Exception e = new Exception("X11Util.Display: Closed TLS Display("+name+") with handle 0x"+Long.toHexString(dpy)+" in thread "+Thread.currentThread().getName());
+ e.printStackTrace();
+ }
+ return dpy;
+ }
+
+ private static Map getCurrentDisplayMapImpl() {
+ Map displayMap = (Map) currentDisplayMap.get();
+ if(null==displayMap) {
+ displayMap = new HashMap();
+ currentDisplayMap.set( displayMap );
+ }
+ return displayMap;
+ }
+
+ /** maps the given display to the thread local display map
+ * and notifies all threads synchronized to this display map. */
+ private static NamedDisplay setCurrentDisplay(NamedDisplay newDisplay) {
+ Map displayMap = getCurrentDisplayMapImpl();
+ NamedDisplay oldDisplay = null;
+ synchronized(displayMap) {
+ String name = (null==newDisplay.getName())?"nil":newDisplay.getName();
+ oldDisplay = (NamedDisplay) displayMap.put(name, newDisplay);
+ displayMap.notifyAll();
+ }
+ return oldDisplay;
+ }
+
+ /** removes the mapping of the given name from the thread local display map
+ * and notifies all threads synchronized to this display map. */
+ private static NamedDisplay removeCurrentDisplay(String name) {
+ Map displayMap = getCurrentDisplayMapImpl();
+ NamedDisplay oldDisplay = null;
+ synchronized(displayMap) {
+ if(null==name) name="nil";
+ oldDisplay = (NamedDisplay) displayMap.remove(name);
+ displayMap.notifyAll();
+ }
+ return oldDisplay;
+ }
+
+ /** Returns the thread local display mapped to the given name */
+ private static NamedDisplay getCurrentDisplay(String name) {
+ if(null==name) name="nil";
+ Map displayMap = getCurrentDisplayMapImpl();
+ return (NamedDisplay) displayMap.get(name);
+ }
+
}
diff --git a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java b/src/nativewindow/classes/com/sun/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java
index 53b82ce08..dff733735 100644
--- a/src/nativewindow/classes/com/sun/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java
+++ b/src/nativewindow/classes/com/sun/nativewindow/impl/x11/awt/X11AWTNativeWindowFactory.java
@@ -42,7 +42,7 @@ import com.sun.nativewindow.impl.jawt.*;
import com.sun.nativewindow.impl.jawt.x11.*;
import com.sun.nativewindow.impl.x11.*;
-public class X11AWTNativeWindowFactory extends X11NativeWindowFactory {
+public class X11AWTNativeWindowFactory extends NativeWindowFactoryImpl {
// When running the AWT on X11 platforms, we use the AWT native
// interface (JAWT) to lock and unlock the toolkit
diff --git a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
index 39ec18bc4..d12c43230 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/NativeWindowFactory.java
@@ -37,6 +37,7 @@ import java.security.*;
import java.util.*;
import com.sun.nativewindow.impl.*;
+import com.sun.nativewindow.impl.jvm.JVMUtil;
/** Provides a pluggable mechanism for arbitrary window toolkits to
adapt their components to the {@link NativeWindow} interface,
@@ -94,6 +95,8 @@ public abstract class NativeWindowFactory {
}
static {
+ JVMUtil.initSingleton();
+
// Gather the windowing OS first
nativeOSNamePure = System.getProperty("os.name");
nativeOSNameCustom = System.getProperty("nativewindow.ws.name");
@@ -124,15 +127,11 @@ public abstract class NativeWindowFactory {
} catch (Exception e) { }
}
- boolean toolkitLockDisabled = Boolean.getBoolean("nativewindow.toolkitlock.disabled"); // test ..
+ boolean toolkitLockDisabled = Boolean.getBoolean("java.awt.headless");
- if(TYPE_X11.equals(nativeWindowingTypeCustom) && !toolkitLockDisabled) {
+ if( !toolkitLockDisabled && TYPE_X11.equals(nativeWindowingTypeCustom) ) {
NativeWindowFactory _factory = null;
- // FIXME: there are regressions in functionality in the
- // JOGL 2 rewrite compared to JOGL 1.1.1 which are
- // described in the writeup below.
- //
// There are certain operations that may be done by
// user-level native code which must share the display
// connection with the underlying window toolkit. In JOGL,
@@ -145,33 +144,11 @@ public abstract class NativeWindowFactory {
// makes X calls from multiple threads: for example, the
// AWT Toolkit thread and one or more Event Dispatch
// Threads.
- // CHECK: OK
- //
- // In the JOGL API, there are other operations that use an
- // X display connection which do not involve locking an
- // on-screen window created by the toolkit: visual
- // selection, pbuffers, external contexts and external
- // drawables.
//
- // The JOGL GLPbuffer implementation uses its own display
- // connection via "XOpenDisplay(null)". This was true even
- // in JOGL 1.1.1. It is believed, but not 100% clear,
- // whether X implementations are robust enough to handle
- // the opening of a new display connection in a
- // multithreaded fashion with no synchronization.
- // (Semantically this should be allowed, but practically,
- // it is unclear.) Currently the JOGL implementation locks
- // the ToolkitLock around pbuffer-related operations.
- // CHECK: OK - Using X11GraphicsScreen.createDefault() now,
- // utilizing one display per thread.
- // However, locking code is still intact.
- // FIXME: Shall it really have one new display per
- // Pbuffer ?
- //
- // Even if the pbuffer case is over-synchronized, there
- // are definitely cases where synchronization with the
- // toolkit is required. From recollection, visual
- // selection is performed outside of the cover of the
+ // There are cases where synchronization with the
+ // toolkit is required in case of a shared resource pattern,
+ // e.g. with AWT. From recollection, visual selection is
+ // performed outside of the cover of the
// toolkit's lock, and the toolkit's display connection is
// used for this operation, so for correctness the toolkit
// must be locked during glXChooseFBConfig /
@@ -208,26 +185,6 @@ public abstract class NativeWindowFactory {
} catch (Exception e) { }
}
- // If it turns out that the AWT is not available, for
- // example on embedded profiles (CDC / FP), then
- // synchronization is still needed, for example among
- // multiple threads that might create pbuffers
- // or for threads using the static default display to query information.
- // The X11NativeWindowFactory provides a simple reentrant lock
- // for this purpose. It is expected that third-party
- // toolkits will either replace this factory, and thereby
- // the implementation of this lock, if stronger
- // interoperability is desired, for example full support
- // for external GLDrawables.
- if (null ==_factory) {
- // Try the non-AWT X11 native window factory
- try {
- Constructor factoryConstructor =
- NWReflection.getConstructor("com.sun.nativewindow.impl.x11.X11NativeWindowFactory", new Class[] {});
- _factory = (NativeWindowFactory) factoryConstructor.newInstance(null);
- } catch (Exception e) { }
- }
-
if (null !=_factory) {
factory = _factory;
}
diff --git a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
index 03121dfaa..34bc48f99 100644
--- a/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
+++ b/src/nativewindow/classes/javax/media/nativewindow/x11/X11GraphicsScreen.java
@@ -46,7 +46,7 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
/** Constructs a new X11GraphicsScreen corresponding to the given native screen index. */
public X11GraphicsScreen(X11GraphicsDevice device, int screen) {
- super(device, fetchScreen(screen));
+ super(device, fetchScreen(device, screen));
}
public static AbstractGraphicsScreen createScreenDevice(long display, int screenIdx) {
@@ -73,8 +73,8 @@ public class X11GraphicsScreen extends DefaultGraphicsScreen implements Cloneabl
}
}
- private static int fetchScreen(int screen) {
- if(!com.sun.nativewindow.impl.x11.X11Util.isXineramaEnabledOnThreadLocalDefaultDisplay()) {
+ private static int fetchScreen(X11GraphicsDevice device, int screen) {
+ if(!X11Lib.XineramaEnabled(device.getHandle())) {
return screen;
}
return 0;
diff --git a/src/nativewindow/native/JVM_Tool.c b/src/nativewindow/native/JVM_Tool.c
new file mode 100644
index 000000000..e04032aa2
--- /dev/null
+++ b/src/nativewindow/native/JVM_Tool.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2003 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
+ * MIDROSYSTEMS, 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.
+ *
+ * You acknowledge that this software is not designed or intended for use
+ * in the design, construction, operation or maintenance of any nuclear
+ * facility.
+ *
+ * Sun gratefully acknowledges that this software was originally authored
+ * and developed by Kenneth Bradley Russell and Christopher John Kline.
+ */
+
+#include <jni.h>
+
+JNIEXPORT jboolean JNICALL
+Java_com_sun_nativewindow_impl_jvm_JVMUtil_initialize(JNIEnv *env, jclass _unused, jobject nioBuffer) {
+ int res;
+ void * ptr = NULL;
+ if (nioBuffer != NULL) {
+ ptr = (void *) (*env)->GetDirectBufferAddress(env, nioBuffer);
+ }
+ return ( NULL==ptr ) ? JNI_FALSE : JNI_TRUE ;
+}
+
diff --git a/src/newt/classes/com/sun/javafx/newt/NewtFactory.java b/src/newt/classes/com/sun/javafx/newt/NewtFactory.java
index c9b230355..5eae559aa 100755
--- a/src/newt/classes/com/sun/javafx/newt/NewtFactory.java
+++ b/src/newt/classes/com/sun/javafx/newt/NewtFactory.java
@@ -36,11 +36,13 @@ package com.sun.javafx.newt;
import javax.media.nativewindow.*;
import java.util.ArrayList;
import java.util.Iterator;
+import com.sun.nativewindow.impl.jvm.JVMUtil;
public abstract class NewtFactory {
// Work-around for initialization order problems on Mac OS X
// between native Newt and (apparently) Fmod
static {
+ JVMUtil.initSingleton();
Window.init(NativeWindowFactory.getNativeWindowType(true));
}
diff --git a/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java b/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java
index 99c0f599c..050b9b24d 100755
--- a/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java
+++ b/src/newt/classes/com/sun/javafx/newt/x11/X11Display.java
@@ -33,10 +33,11 @@
package com.sun.javafx.newt.x11;
-import com.sun.javafx.newt.*;
-import com.sun.javafx.newt.impl.*;
import javax.media.nativewindow.*;
import javax.media.nativewindow.x11.*;
+import com.sun.javafx.newt.*;
+import com.sun.javafx.newt.impl.*;
+import com.sun.nativewindow.impl.x11.X11Util;
public class X11Display extends Display {
static {
@@ -65,15 +66,23 @@ public class X11Display extends Display {
}
protected void createNative() {
- long handle= CreateDisplay(name);
+ long handle= X11Util.getThreadLocalDisplay(name);
if (handle == 0 ) {
throw new RuntimeException("Error creating display: "+name);
}
+ try {
+ CompleteDisplay(handle);
+ } catch(RuntimeException e) {
+ X11Util.closeThreadLocalDisplay(name);
+ throw e;
+ }
aDevice = new X11GraphicsDevice(handle);
}
protected void closeNative() {
- DestroyDisplay(getHandle());
+ if(0==X11Util.closeThreadLocalDisplay(name)) {
+ throw new NativeWindowException(this+" was not mapped");
+ }
}
protected void dispatchMessages() {
@@ -88,12 +97,11 @@ public class X11Display extends Display {
//
private static native boolean initIDs();
- private native long CreateDisplay(String name);
- private native void DestroyDisplay(long handle);
+ private native void CompleteDisplay(long handle);
private native void DispatchMessages(long display, long javaObjectAtom, long windowDeleteAtom);
- private void displayCreated(long javaObjectAtom, long windowDeleteAtom) {
+ private void displayCompleted(long javaObjectAtom, long windowDeleteAtom) {
this.javaObjectAtom=javaObjectAtom;
this.windowDeleteAtom=windowDeleteAtom;
}
diff --git a/src/newt/native/X11Window.c b/src/newt/native/X11Window.c
index c239dd780..8651a8cea 100755
--- a/src/newt/native/X11Window.c
+++ b/src/newt/native/X11Window.c
@@ -156,7 +156,7 @@ static jmethodID windowCreatedID = NULL;
static jmethodID sendMouseEventID = NULL;
static jmethodID sendKeyEventID = NULL;
-static jmethodID displayCreatedID = NULL;
+static jmethodID displayCompletedID = NULL;
static void _throwNewRuntimeException(JNIEnv *env, const char* msg, ...)
{
@@ -184,8 +184,8 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Display_initIDs
{
jclass c;
- displayCreatedID = (*env)->GetMethodID(env, clazz, "displayCreated", "(JJ)V");
- if (displayCreatedID == NULL) {
+ displayCompletedID = (*env)->GetMethodID(env, clazz, "displayCompleted", "(JJ)V");
+ if (displayCompletedID == NULL) {
return JNI_FALSE;
}
@@ -223,60 +223,34 @@ JNIEXPORT jboolean JNICALL Java_com_sun_javafx_newt_x11_X11Display_initIDs
/*
* Class: com_sun_javafx_newt_x11_X11Display
- * Method: CreateDisplay
- * Signature: (Ljava/lang/String;)J
+ * Method: CompleteDisplay
+ * Signature: (J)V
*/
-JNIEXPORT jlong JNICALL Java_com_sun_javafx_newt_x11_X11Display_CreateDisplay
- (JNIEnv *env, jobject obj, jstring displayName)
+JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_CompleteDisplay
+ (JNIEnv *env, jobject obj, jlong display)
{
- Display * dpy = NULL;
- const char * _displayName = NULL;
+ Display * dpy = (Display *)(intptr_t)display;
jlong javaObjectAtom;
jlong windowDeleteAtom;
- if(displayName!=0) {
- _displayName = (*env)->GetStringUTFChars(env, displayName, 0);
- }
- DBG_PRINT1("open display connection for %s ..\n", ((NULL==_displayName)?"NULL":_displayName));
- dpy = XOpenDisplay(_displayName);
if(dpy==NULL) {
- _throwNewRuntimeException(env, "couldn't open display connection for %s\n", ((NULL==_displayName)?"NULL":_displayName));
- }
- if(_displayName!=0) {
- (*env)->ReleaseStringChars(env, displayName, (const jchar *)_displayName);
+ _throwNewRuntimeException(env, "given display connection is NULL\n");
}
javaObjectAtom = (jlong) XInternAtom(dpy, "JOGL_JAVA_OBJECT", False);
if(None==javaObjectAtom) {
- XCloseDisplay(dpy);
_throwNewRuntimeException(env, "could not create Atom JOGL_JAVA_OBJECT, bail out!\n");
- return 0;
+ return;
}
windowDeleteAtom = (jlong) XInternAtom(dpy, "WM_DELETE_WINDOW", False);
if(None==windowDeleteAtom) {
- XCloseDisplay(dpy);
_throwNewRuntimeException(env, "could not create Atom WM_DELETE_WINDOW, bail out!\n");
- return 0;
+ return;
}
- DBG_PRINT1("X11Display_CreateDisplay dpy %p\n", dpy);
-
- (*env)->CallVoidMethod(env, obj, displayCreatedID, javaObjectAtom, windowDeleteAtom);
+ DBG_PRINT1("X11Display_completeDisplay dpy %p\n", dpy);
- return (jlong) (intptr_t) dpy;
-}
-
-/*
- * Class: com_sun_javafx_newt_x11_X11Display
- * Method: DestroyDisplay
- * Signature: (J)V
- */
-JNIEXPORT void JNICALL Java_com_sun_javafx_newt_x11_X11Display_DestroyDisplay
- (JNIEnv *env, jobject obj, jlong display)
-{
- Display * dpy = (Display *)(intptr_t)display;
- DBG_PRINT1("X11Display_DestroyDisplay dpy %p\n", dpy);
- XCloseDisplay(dpy);
+ (*env)->CallVoidMethod(env, obj, displayCompletedID, javaObjectAtom, windowDeleteAtom);
}
static int putPtrIn32Long(unsigned long * dst, uintptr_t src) {