summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKenneth Russel <[email protected]>2005-07-18 22:15:42 +0000
committerKenneth Russel <[email protected]>2005-07-18 22:15:42 +0000
commit8f5492988de9fddf61623b7274915c777ad3a97d (patch)
tree79528bb981dbaa88f2f970d555b2fb06b7f8335a
parent5e36587af91f43faff49f4ff61c40cf084bae298 (diff)
Moved support for instantiating GLPbuffers from X11OnscreenGLContext
to X11GLContextFactory. git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/branches/JSR-231@327 232f8b59-042b-4e1e-8c03-345bb8c30851
-rw-r--r--src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java2
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContext.java31
-rw-r--r--src/net/java/games/jogl/impl/x11/X11GLContextFactory.java86
-rw-r--r--src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java8
-rw-r--r--src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java229
5 files changed, 216 insertions, 140 deletions
diff --git a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
index 1ea4c8b95..112afd2e4 100644
--- a/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
+++ b/src/net/java/games/jogl/impl/windows/WindowsGLContextFactory.java
@@ -179,7 +179,7 @@ public class WindowsGLContextFactory extends GLContextFactory {
final int initialWidth,
final int initialHeight,
final GLContext shareWith) {
- if (!canCreateGLPbuffer) {
+ if (!canCreateGLPbuffer(capabilities, initialWidth, initialHeight)) {
throw new GLException("Pbuffer support not available with current graphics card");
}
final List returnList = new ArrayList();
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContext.java b/src/net/java/games/jogl/impl/x11/X11GLContext.java
index 66520ada3..fd22d0ee5 100644
--- a/src/net/java/games/jogl/impl/x11/X11GLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11GLContext.java
@@ -52,7 +52,6 @@ public abstract class X11GLContext extends GLContextImpl {
private boolean glXQueryExtensionsStringInitialized;
private boolean glXQueryExtensionsStringAvailable;
private static final Map/*<String, String>*/ functionNameMap;
- private boolean isGLX13;
// Table that holds the addresses of the native C-language entry points for
// OpenGL functions.
private GLProcAddressTable glProcAddressTable;
@@ -207,34 +206,6 @@ public abstract class X11GLContext extends GLContextImpl {
if (!haveResetGLXProcAddressTable) {
resetProcAddressTable(GLX.getGLXProcAddressTable());
}
-
- // Figure out whether we are running GLX version 1.3 or above and
- // therefore have pbuffer support
- if (drawable.getDisplay() == 0) {
- throw new GLException("Expected non-null DISPLAY for querying GLX version");
- }
- int[] major = new int[1];
- int[] minor = new int[1];
- if (!GLX.glXQueryVersion(drawable.getDisplay(), major, 0, minor, 0)) {
- throw new GLException("glXQueryVersion failed");
- }
- if (DEBUG) {
- System.err.println("!!! GLX version: major " + major[0] +
- ", minor " + minor[0]);
- }
-
- // Work around bugs in ATI's Linux drivers where they report they
- // only implement GLX version 1.2 but actually do support pbuffers
- if (major[0] == 1 && minor[0] == 2) {
- GL gl = getGL();
- String str = gl.glGetString(GL.GL_VENDOR);
- if (str != null && str.indexOf("ATI") >= 0) {
- isGLX13 = true;
- return;
- }
- }
-
- isGLX13 = ((major[0] > 1) || (minor[0] > 2));
}
public GLProcAddressTable getGLProcAddressTable() {
@@ -289,7 +260,7 @@ public abstract class X11GLContext extends GLContextImpl {
public boolean isExtensionAvailable(String glExtensionName) {
if (glExtensionName.equals("GL_ARB_pbuffer") ||
glExtensionName.equals("GL_ARB_pixel_format")) {
- return isGLX13;
+ return X11GLContextFactory.getFactory().canCreateGLPbuffer(null, 0, 0);
}
return super.isExtensionAvailable(glExtensionName);
}
diff --git a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
index 78d03a28a..109f74e44 100644
--- a/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
+++ b/src/net/java/games/jogl/impl/x11/X11GLContextFactory.java
@@ -40,12 +40,18 @@
package net.java.games.jogl.impl.x11;
import java.awt.Component;
+import java.awt.EventQueue;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
import net.java.games.jogl.*;
import net.java.games.jogl.impl.*;
public class X11GLContextFactory extends GLContextFactory {
+ private static final boolean DEBUG = Debug.debug("X11GLContextFactory");
+
static {
NativeLibLoader.load();
}
@@ -137,6 +143,72 @@ public class X11GLContextFactory extends GLContextFactory {
return new X11OffscreenGLDrawable(capabilities, chooser);
}
+ private boolean pbufferSupportInitialized = false;
+ private boolean canCreateGLPbuffer = false;
+ public boolean canCreateGLPbuffer(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ if (!pbufferSupportInitialized) {
+ Runnable r = new Runnable() {
+ public void run() {
+ long display = getDisplayConnection();
+ lockAWT();
+ try {
+ int[] major = new int[1];
+ int[] minor = new int[1];
+ if (!GLX.glXQueryVersion(display, major, 0, minor, 0)) {
+ throw new GLException("glXQueryVersion failed");
+ }
+ if (DEBUG) {
+ System.err.println("!!! GLX version: major " + major[0] +
+ ", minor " + minor[0]);
+ }
+
+ int screen = 0; // FIXME: provide way to specify this?
+
+ // Work around bugs in ATI's Linux drivers where they report they
+ // only implement GLX version 1.2 but actually do support pbuffers
+ if (major[0] == 1 && minor[0] == 2) {
+ String str = GLX.glXQueryServerString(display, screen, GLX.GLX_VENDOR);
+ if (str != null && str.indexOf("ATI") >= 0) {
+ canCreateGLPbuffer = true;
+ }
+ } else {
+ canCreateGLPbuffer = ((major[0] > 1) || (minor[0] > 2));
+ }
+
+ pbufferSupportInitialized = true;
+ } finally {
+ unlockAWT();
+ }
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ }
+ return canCreateGLPbuffer;
+ }
+
+ public GLPbuffer createGLPbuffer(final GLCapabilities capabilities,
+ final int initialWidth,
+ final int initialHeight,
+ final GLContext shareWith) {
+ if (!canCreateGLPbuffer(capabilities, initialWidth, initialHeight)) {
+ throw new GLException("Pbuffer support not available with current graphics card");
+ }
+ final List returnList = new ArrayList();
+ Runnable r = new Runnable() {
+ public void run() {
+ X11PbufferGLDrawable pbufferDrawable = new X11PbufferGLDrawable(capabilities,
+ initialWidth,
+ initialHeight);
+ GLPbufferImpl pbuffer = new GLPbufferImpl(pbufferDrawable, shareWith);
+ returnList.add(pbuffer);
+ }
+ };
+ maybeDoSingleThreadedWorkaround(r);
+ return (GLPbuffer) returnList.get(0);
+ }
+
public static GLCapabilities xvi2GLCapabilities(long display, XVisualInfo info) {
int[] tmp = new int[1];
int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
@@ -292,4 +364,18 @@ public class X11GLContextFactory extends GLContextFactory {
}
return tmp[tmp_offset];
}
+
+ private void maybeDoSingleThreadedWorkaround(Runnable action) {
+ if (SingleThreadedWorkaround.doWorkaround() && !EventQueue.isDispatchThread()) {
+ try {
+ EventQueue.invokeAndWait(action);
+ } catch (InvocationTargetException e) {
+ throw new GLException(e.getTargetException());
+ } catch (InterruptedException e) {
+ throw new GLException(e);
+ }
+ } else {
+ action.run();
+ }
+ }
}
diff --git a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
index 7a661e9e3..cc4375117 100644
--- a/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/x11/X11OnscreenGLContext.java
@@ -56,15 +56,21 @@ public class X11OnscreenGLContext extends X11GLContext {
}
public boolean canCreatePbufferContext() {
+ return false;
+ /*
return isExtensionAvailable("GL_ARB_pbuffer");
+ */
}
public GLDrawableImpl createPbufferDrawable(GLCapabilities capabilities,
int initialWidth,
int initialHeight) {
+ throw new GLException("No longer supported");
+ /*
X11PbufferGLDrawable buf = new X11PbufferGLDrawable(capabilities, initialWidth, initialHeight);
pbuffersToInstantiate.add(buf);
return buf;
+ */
}
protected int makeCurrentImpl() throws GLException {
@@ -84,6 +90,7 @@ public class X11OnscreenGLContext extends X11GLContext {
}
}
int ret = super.makeCurrentImpl();
+ /*
if ((ret == CONTEXT_CURRENT) ||
(ret == CONTEXT_CURRENT_NEW)) {
// Instantiate any pending pbuffers
@@ -96,6 +103,7 @@ public class X11OnscreenGLContext extends X11GLContext {
}
}
}
+ */
return ret;
} catch (RuntimeException e) {
try {
diff --git a/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java b/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java
index fc37f331b..775bf649f 100644
--- a/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java
+++ b/src/net/java/games/jogl/impl/x11/X11PbufferGLDrawable.java
@@ -69,6 +69,8 @@ public class X11PbufferGLDrawable extends X11GLDrawable {
(capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") +
(capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : ""));
}
+
+ createPbuffer(X11GLContextFactory.getDisplayConnection());
}
public GLContext createContext(GLContext shareWith) {
@@ -97,141 +99,150 @@ public class X11PbufferGLDrawable extends X11GLDrawable {
return height;
}
- public void createPbuffer(GL gl, long display) {
- if (display == 0) {
- throw new GLException("Null display");
- }
+ public void createPbuffer(long display) {
+ lockAWT();
+ try {
+ if (display == 0) {
+ throw new GLException("Null display");
+ }
- if (capabilities.getOffscreenRenderToTexture()) {
- throw new GLException("Render-to-texture pbuffers not supported yet on X11");
- }
+ if (capabilities.getOffscreenRenderToTexture()) {
+ throw new GLException("Render-to-texture pbuffers not supported yet on X11");
+ }
- if (capabilities.getOffscreenRenderToTextureRectangle()) {
- throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11");
- }
+ if (capabilities.getOffscreenRenderToTextureRectangle()) {
+ throw new GLException("Render-to-texture-rectangle pbuffers not supported yet on X11");
+ }
- int[] iattributes = new int [2*MAX_ATTRIBS];
- float[] fattributes = new float[2*MAX_ATTRIBS];
- int nfattribs = 0;
- int niattribs = 0;
+ int[] iattributes = new int [2*MAX_ATTRIBS];
+ float[] fattributes = new float[2*MAX_ATTRIBS];
+ int nfattribs = 0;
+ int niattribs = 0;
- // Since we are trying to create a pbuffer, the GLXFBConfig we
- // request (and subsequently use) must be "p-buffer capable".
- iattributes[niattribs++] = GL.GLX_DRAWABLE_TYPE;
- iattributes[niattribs++] = GL.GLX_PBUFFER_BIT;
+ // Since we are trying to create a pbuffer, the GLXFBConfig we
+ // request (and subsequently use) must be "p-buffer capable".
+ iattributes[niattribs++] = GL.GLX_DRAWABLE_TYPE;
+ iattributes[niattribs++] = GL.GLX_PBUFFER_BIT;
- iattributes[niattribs++] = GL.GLX_RENDER_TYPE;
- iattributes[niattribs++] = GL.GLX_RGBA_BIT;
+ iattributes[niattribs++] = GL.GLX_RENDER_TYPE;
+ iattributes[niattribs++] = GL.GLX_RGBA_BIT;
- iattributes[niattribs++] = GLX.GLX_DOUBLEBUFFER;
- if (capabilities.getDoubleBuffered()) {
- iattributes[niattribs++] = GL.GL_TRUE;
- } else {
- iattributes[niattribs++] = GL.GL_FALSE;
- }
+ iattributes[niattribs++] = GLX.GLX_DOUBLEBUFFER;
+ if (capabilities.getDoubleBuffered()) {
+ iattributes[niattribs++] = GL.GL_TRUE;
+ } else {
+ iattributes[niattribs++] = GL.GL_FALSE;
+ }
- iattributes[niattribs++] = GLX.GLX_DEPTH_SIZE;
- iattributes[niattribs++] = capabilities.getDepthBits();
+ iattributes[niattribs++] = GLX.GLX_DEPTH_SIZE;
+ iattributes[niattribs++] = capabilities.getDepthBits();
- iattributes[niattribs++] = GLX.GLX_RED_SIZE;
- iattributes[niattribs++] = capabilities.getRedBits();
+ iattributes[niattribs++] = GLX.GLX_RED_SIZE;
+ iattributes[niattribs++] = capabilities.getRedBits();
- iattributes[niattribs++] = GLX.GLX_GREEN_SIZE;
- iattributes[niattribs++] = capabilities.getGreenBits();
+ iattributes[niattribs++] = GLX.GLX_GREEN_SIZE;
+ iattributes[niattribs++] = capabilities.getGreenBits();
- iattributes[niattribs++] = GLX.GLX_BLUE_SIZE;
- iattributes[niattribs++] = capabilities.getBlueBits();
+ iattributes[niattribs++] = GLX.GLX_BLUE_SIZE;
+ iattributes[niattribs++] = capabilities.getBlueBits();
- iattributes[niattribs++] = GLX.GLX_ALPHA_SIZE;
- iattributes[niattribs++] = capabilities.getAlphaBits();
+ iattributes[niattribs++] = GLX.GLX_ALPHA_SIZE;
+ iattributes[niattribs++] = capabilities.getAlphaBits();
- if (capabilities.getStencilBits() > 0) {
- iattributes[niattribs++] = GLX.GLX_STENCIL_SIZE;
- iattributes[niattribs++] = capabilities.getStencilBits();
- }
+ if (capabilities.getStencilBits() > 0) {
+ iattributes[niattribs++] = GLX.GLX_STENCIL_SIZE;
+ iattributes[niattribs++] = capabilities.getStencilBits();
+ }
- if (capabilities.getAccumRedBits() > 0 ||
- capabilities.getAccumGreenBits() > 0 ||
- capabilities.getAccumBlueBits() > 0) {
- iattributes[niattribs++] = GLX.GLX_ACCUM_RED_SIZE;
- iattributes[niattribs++] = capabilities.getAccumRedBits();
- iattributes[niattribs++] = GLX.GLX_ACCUM_GREEN_SIZE;
- iattributes[niattribs++] = capabilities.getAccumGreenBits();
- iattributes[niattribs++] = GLX.GLX_ACCUM_BLUE_SIZE;
- iattributes[niattribs++] = capabilities.getAccumBlueBits();
- }
+ if (capabilities.getAccumRedBits() > 0 ||
+ capabilities.getAccumGreenBits() > 0 ||
+ capabilities.getAccumBlueBits() > 0) {
+ iattributes[niattribs++] = GLX.GLX_ACCUM_RED_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumRedBits();
+ iattributes[niattribs++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumGreenBits();
+ iattributes[niattribs++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ iattributes[niattribs++] = capabilities.getAccumBlueBits();
+ }
- if (capabilities.getOffscreenFloatingPointBuffers()) {
- if (!gl.isExtensionAvailable("GLX_NV_float_buffer")) {
- throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware");
+ int screen = 0; // FIXME: provide way to specify this?
+
+ if (capabilities.getOffscreenFloatingPointBuffers()) {
+ // FIXME:
+ String glXExtensions = GLX.glXQueryExtensionsString(display, screen);
+ if (glXExtensions == null ||
+ glXExtensions.indexOf("GLX_NV_float_buffer") < 0) {
+ throw new GLException("Floating-point pbuffers on X11 currently require NVidia hardware");
+ }
+ iattributes[niattribs++] = GLX.GLX_FLOAT_COMPONENTS_NV;
+ iattributes[niattribs++] = GL.GL_TRUE;
}
- iattributes[niattribs++] = GLX.GLX_FLOAT_COMPONENTS_NV;
- iattributes[niattribs++] = GL.GL_TRUE;
- }
- // FIXME: add FSAA support? Don't want to get into a situation
- // where we have to retry the glXChooseFBConfig call if it fails
- // due to a lack of an antialiased visual...
+ // FIXME: add FSAA support? Don't want to get into a situation
+ // where we have to retry the glXChooseFBConfig call if it fails
+ // due to a lack of an antialiased visual...
- iattributes[niattribs++] = 0; // null-terminate
+ iattributes[niattribs++] = 0; // null-terminate
- int screen = 0; // FIXME: provide way to specify this?
- int[] nelementsTmp = new int[1];
- GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0);
- if (fbConfigs == null || fbConfigs.length == 0 || fbConfigs[0] == null) {
- throw new GLException("pbuffer creation error: glXChooseFBConfig() failed");
- }
- // Note that we currently don't allow selection of anything but
- // the first GLXFBConfig in the returned list
- GLXFBConfig fbConfig = fbConfigs[0];
- int nelements = nelementsTmp[0];
- if (nelements <= 0) {
- throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration");
- }
+ int[] nelementsTmp = new int[1];
+ GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0);
+ if (fbConfigs == null || fbConfigs.length == 0 || fbConfigs[0] == null) {
+ throw new GLException("pbuffer creation error: glXChooseFBConfig() failed");
+ }
+ // Note that we currently don't allow selection of anything but
+ // the first GLXFBConfig in the returned list
+ GLXFBConfig fbConfig = fbConfigs[0];
+ int nelements = nelementsTmp[0];
+ if (nelements <= 0) {
+ throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration");
+ }
- if (DEBUG) {
- System.err.println("Found " + fbConfigs.length + " matching GLXFBConfigs");
- System.err.println("Parameters of default one:");
- System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE)));
- System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0));
- System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE));
- System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE));
- System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE));
- System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE));
- System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE));
- System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER));
- }
+ if (DEBUG) {
+ System.err.println("Found " + fbConfigs.length + " matching GLXFBConfigs");
+ System.err.println("Parameters of default one:");
+ System.err.println("render type: 0x" + Integer.toHexString(queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE)));
+ System.err.println("rgba: " + ((queryFBConfig(display, fbConfig, GLX.GLX_RENDER_TYPE) & GLX.GLX_RGBA_BIT) != 0));
+ System.err.println("r: " + queryFBConfig(display, fbConfig, GLX.GLX_RED_SIZE));
+ System.err.println("g: " + queryFBConfig(display, fbConfig, GLX.GLX_GREEN_SIZE));
+ System.err.println("b: " + queryFBConfig(display, fbConfig, GLX.GLX_BLUE_SIZE));
+ System.err.println("a: " + queryFBConfig(display, fbConfig, GLX.GLX_ALPHA_SIZE));
+ System.err.println("depth: " + queryFBConfig(display, fbConfig, GLX.GLX_DEPTH_SIZE));
+ System.err.println("double buffered: " + queryFBConfig(display, fbConfig, GLX.GLX_DOUBLEBUFFER));
+ }
- // Create the p-buffer.
- niattribs = 0;
+ // Create the p-buffer.
+ niattribs = 0;
- iattributes[niattribs++] = GL.GLX_PBUFFER_WIDTH;
- iattributes[niattribs++] = initWidth;
- iattributes[niattribs++] = GL.GLX_PBUFFER_HEIGHT;
- iattributes[niattribs++] = initHeight;
+ iattributes[niattribs++] = GL.GLX_PBUFFER_WIDTH;
+ iattributes[niattribs++] = initWidth;
+ iattributes[niattribs++] = GL.GLX_PBUFFER_HEIGHT;
+ iattributes[niattribs++] = initHeight;
- iattributes[niattribs++] = 0;
+ iattributes[niattribs++] = 0;
- long tmpBuffer = GLX.glXCreatePbuffer(display, fbConfig, iattributes, 0);
- if (tmpBuffer == 0) {
- // FIXME: query X error code for detail error message
- throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
- }
+ long tmpBuffer = GLX.glXCreatePbuffer(display, fbConfig, iattributes, 0);
+ if (tmpBuffer == 0) {
+ // FIXME: query X error code for detail error message
+ throw new GLException("pbuffer creation error: glXCreatePbuffer() failed");
+ }
- // Set up instance variables
- this.display = display;
- drawable = tmpBuffer;
- this.fbConfig = fbConfig;
+ // Set up instance variables
+ this.display = display;
+ drawable = tmpBuffer;
+ this.fbConfig = fbConfig;
- // Determine the actual width and height we were able to create.
- int[] tmp = new int[1];
- GLX.glXQueryDrawable(display, drawable, GL.GLX_WIDTH, tmp, 0);
- width = tmp[0];
- GLX.glXQueryDrawable(display, drawable, GL.GLX_HEIGHT, tmp, 0);
- height = tmp[0];
+ // Determine the actual width and height we were able to create.
+ int[] tmp = new int[1];
+ GLX.glXQueryDrawable(display, drawable, GL.GLX_WIDTH, tmp, 0);
+ width = tmp[0];
+ GLX.glXQueryDrawable(display, drawable, GL.GLX_HEIGHT, tmp, 0);
+ height = tmp[0];
- if (DEBUG) {
- System.err.println("Created pbuffer " + width + " x " + height);
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ } finally {
+ unlockAWT();
}
}