summaryrefslogtreecommitdiffstats
path: root/src/classes/com/sun/opengl/impl/x11
diff options
context:
space:
mode:
Diffstat (limited to 'src/classes/com/sun/opengl/impl/x11')
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java83
-rwxr-xr-xsrc/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java212
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11GLContext.java301
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11GLDrawable.java172
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java439
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11OffscreenGLContext.java74
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java143
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11OnscreenGLContext.java95
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11OnscreenGLDrawable.java191
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11PbufferGLContext.java151
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java264
-rw-r--r--src/classes/com/sun/opengl/impl/x11/X11SunJDKReflection.java101
12 files changed, 2226 insertions, 0 deletions
diff --git a/src/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java
new file mode 100755
index 000000000..4d329ba24
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLContext.java
@@ -0,0 +1,83 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11ExternalGLContext extends X11GLContext {
+ private boolean firstMakeCurrent = true;
+ private boolean created = true;
+
+ public X11ExternalGLContext() {
+ super(null, null);
+ lockAWT();
+ try {
+ context = GLX.glXGetCurrentContext();
+ } finally {
+ unlockAWT();
+ }
+ GLContextShareSet.contextCreated(this);
+ resetGLFunctionAvailability();
+ }
+
+ protected void create() {
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (firstMakeCurrent) {
+ firstMakeCurrent = false;
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ }
+
+ protected void destroyImpl() throws GLException {
+ created = false;
+ GLContextShareSet.contextDestroyed(this);
+ }
+
+ public boolean isCreated() {
+ return created;
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java
new file mode 100755
index 000000000..371930013
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11ExternalGLDrawable.java
@@ -0,0 +1,212 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11ExternalGLDrawable extends X11GLDrawable {
+ private int fbConfigID;
+ private int renderType;
+ private int screen;
+ private long readDrawable;
+
+ public X11ExternalGLDrawable() {
+ super(null, null, null);
+ lockAWT();
+ try {
+ display = GLX.glXGetCurrentDisplay();
+ drawable = GLX.glXGetCurrentDrawable();
+ readDrawable = GLX.glXGetCurrentReadDrawable();
+
+ // Need GLXFBConfig ID in order to properly create new contexts
+ // on this drawable
+ long context = GLX.glXGetCurrentContext();
+ int[] val = new int[1];
+ GLX.glXQueryContext(display, context, GLX.GLX_FBCONFIG_ID, val, 0);
+ fbConfigID = val[0];
+ renderType = GLX.GLX_RGBA_TYPE;
+ GLX.glXQueryContext(display, context, GLX.GLX_RENDER_TYPE, val, 0);
+ if ((val[0] & GLX.GLX_RGBA_BIT) == 0) {
+ if (DEBUG) {
+ System.err.println("X11ExternalGLDrawable: WARNING: forcing GLX_RGBA_TYPE for newly created contexts");
+ }
+ }
+ GLX.glXQueryContext(display, context, GLX.GLX_SCREEN, val, 0);
+ screen = val[0];
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new Context(shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ throw new GLException("Should not call this");
+ }
+
+ public int getWidth() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getHeight() {
+ throw new GLException("Should not call this");
+ }
+
+ public void destroy() {
+ }
+
+ class Context extends X11GLContext {
+ Context(GLContext shareWith) {
+ super(X11ExternalGLDrawable.this, shareWith);
+ this.drawable = drawable;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (drawable.getDrawable() == 0) {
+ // parent drawable not properly initialized
+ // FIXME: signal error?
+ if (DEBUG) {
+ System.err.println("parent drawable not properly initialized");
+ }
+ return CONTEXT_NOT_CURRENT;
+ }
+
+ // Note that we have to completely override makeCurrentImpl
+ // because the underlying makeCurrent call differs from the norm
+ lockAWT();
+ try {
+ boolean created = false;
+ if (context == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!GLX.glXMakeContextCurrent(drawable.getDisplay(),
+ drawable.getDrawable(),
+ readDrawable,
+ context)) {
+ throw new GLException("Error making context current");
+ } else {
+ mostRecentDisplay = drawable.getDisplay();
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(drawable.getDisplay()) +
+ ", drawable " + toHexString(drawable.getDrawable()) +
+ ", context " + toHexString(context) + ") succeeded");
+ }
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ lockAWT();
+ try {
+ if (!GLX.glXMakeContextCurrent(drawable.getDisplay(), 0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ protected void create() {
+ // We already have the GLXFBConfig ID for the context. All we
+ // need to do is use it to choose the GLXFBConfig and then
+ // create a context with it.
+ int[] iattributes = new int[] {
+ GLX.GLX_FBCONFIG_ID,
+ fbConfigID,
+ 0,
+ 0
+ };
+ float[] fattributes = new float[0];
+ int[] nelementsTmp = new int[1];
+ GLXFBConfig[] fbConfigs = GLX.glXChooseFBConfig(display, screen, iattributes, 0, nelementsTmp, 0);
+ int nelements = nelementsTmp[0];
+ if (nelements <= 0) {
+ throw new GLException("context creation error: couldn't find a suitable frame buffer configuration");
+ }
+ if (nelements != 1) {
+ throw new GLException("context creation error: shouldn't get more than one GLXFBConfig");
+ }
+ // Note that we currently don't allow selection of anything but
+ // the first GLXFBConfig in the returned list (there should be only one)
+ GLXFBConfig fbConfig = fbConfigs[0];
+ // Create a gl context for the drawable
+ X11GLContext other = (X11GLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ // FIXME: how to determine "direct" bit?
+ context = GLX.glXCreateNewContext(display, fbConfig, renderType, share, true);
+ if (context == 0) {
+ String detail = " display=" + toHexString(display) +
+ " fbconfig=" + fbConfig +
+ " fbconfigID=" + toHexString(fbConfigID) +
+ " renderType=" + toHexString(renderType) +
+ " share=" + toHexString(share);
+ throw new GLException("context creation error: glXCreateNewContext() failed: " + detail);
+ }
+ GLContextShareSet.contextCreated(this);
+
+ if (DEBUG) {
+ System.err.println("Created context " + toHexString(context) +
+ " for GLXDrawable " + toHexString(drawable.getDrawable()));
+ }
+ }
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11GLContext.java b/src/classes/com/sun/opengl/impl/x11/X11GLContext.java
new file mode 100644
index 000000000..ed9736f22
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11GLContext.java
@@ -0,0 +1,301 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import java.nio.*;
+import java.util.*;
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public abstract class X11GLContext extends GLContextImpl {
+ protected X11GLDrawable drawable;
+ protected long context;
+ private boolean glXQueryExtensionsStringInitialized;
+ private boolean glXQueryExtensionsStringAvailable;
+ private static final Map/*<String, String>*/ functionNameMap;
+ private GLXExt glXExt;
+ // Table that holds the addresses of the native C-language entry points for
+ // GLX extension functions.
+ private GLXExtProcAddressTable glXExtProcAddressTable;
+ // Cache the most recent value of the "display" variable (which we
+ // only guarantee to be valid in between makeCurrent / free pairs)
+ // so that we can implement displayImpl() (which must be done when
+ // the context is not current)
+ protected long mostRecentDisplay;
+
+ static {
+ functionNameMap = new HashMap();
+ functionNameMap.put("glAllocateMemoryNV", "glXAllocateMemoryNV");
+ functionNameMap.put("glFreeMemoryNV", "glXFreeMemoryNV");
+ }
+
+ public X11GLContext(X11GLDrawable drawable,
+ GLContext shareWith) {
+ super(shareWith);
+ this.drawable = drawable;
+ }
+
+ public Object getPlatformGLExtensions() {
+ return getGLXExt();
+ }
+
+ public GLXExt getGLXExt() {
+ if (glXExt == null) {
+ glXExt = new GLXExtImpl(this);
+ }
+ return glXExt;
+ }
+
+ public GLDrawable getGLDrawable() {
+ return drawable;
+ }
+
+ protected String mapToRealGLFunctionName(String glFunctionName) {
+ String lookup = (String) functionNameMap.get(glFunctionName);
+ if (lookup != null) {
+ return lookup;
+ }
+ return glFunctionName;
+ }
+
+ protected String mapToRealGLExtensionName(String glExtensionName) {
+ return glExtensionName;
+ }
+
+ /** Helper routine which usually just turns around and calls
+ * createContext (except for pbuffers, which use a different context
+ * creation mechanism). Should only be called by {@link
+ * makeCurrentImpl()}.
+ */
+ protected abstract void create();
+
+ /**
+ * Creates and initializes an appropriate OpenGL context. Should only be
+ * called by {@link create()}.
+ */
+ protected void createContext(boolean onscreen) {
+ XVisualInfo vis = drawable.chooseVisual(onscreen);
+ X11GLContext other = (X11GLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ context = GLX.glXCreateContext(drawable.getDisplay(), vis, share, onscreen);
+ if (context == 0) {
+ throw new GLException("Unable to create OpenGL context");
+ }
+ GLContextShareSet.contextCreated(this);
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ // FIXME: in offscreen (non-pbuffer) case this is run without the
+ // AWT lock held
+ boolean created = false;
+ if (context == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!GLX.glXMakeCurrent(drawable.getDisplay(), drawable.getDrawable(), context)) {
+ throw new GLException("Error making context current");
+ } else {
+ mostRecentDisplay = drawable.getDisplay();
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(drawable.getDisplay()) +
+ ", drawable " + toHexString(drawable.getDrawable()) +
+ ", context " + toHexString(context) + ") succeeded");
+ }
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ }
+
+ protected void releaseImpl() throws GLException {
+ if (!GLX.glXMakeCurrent(drawable.getDisplay(), 0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ }
+
+ protected void destroyImpl() throws GLException {
+ lockAWT();
+ if (context != 0) {
+ GLX.glXDestroyContext(mostRecentDisplay, context);
+ if (DEBUG) {
+ System.err.println("!!! Destroyed OpenGL context " + context);
+ }
+ context = 0;
+ mostRecentDisplay = 0;
+ GLContextShareSet.contextDestroyed(this);
+ }
+ unlockAWT();
+ }
+
+ public boolean isCreated() {
+ return (context != 0);
+ }
+
+ protected void resetGLFunctionAvailability() {
+ super.resetGLFunctionAvailability();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Initializing GLX extension address table");
+ }
+ resetProcAddressTable(getGLXExtProcAddressTable());
+ }
+
+ public GLXExtProcAddressTable getGLXExtProcAddressTable() {
+ if (glXExtProcAddressTable == null) {
+ // FIXME: cache ProcAddressTables by capability bits so we can
+ // share them among contexts with the same capabilities
+ glXExtProcAddressTable = new GLXExtProcAddressTable();
+ }
+ return glXExtProcAddressTable;
+ }
+
+ public synchronized String getPlatformExtensionsString() {
+ if (drawable.getDisplay() == 0) {
+ throw new GLException("Context not current");
+ }
+ if (!glXQueryExtensionsStringInitialized) {
+ glXQueryExtensionsStringAvailable =
+ (GLDrawableFactoryImpl.getFactoryImpl().dynamicLookupFunction("glXQueryExtensionsString") != 0);
+ glXQueryExtensionsStringInitialized = true;
+ }
+ if (glXQueryExtensionsStringAvailable) {
+ lockAWT();
+ try {
+ String ret = GLX.glXQueryExtensionsString(drawable.getDisplay(), GLX.DefaultScreen(drawable.getDisplay()));
+ if (DEBUG) {
+ System.err.println("!!! GLX extensions: " + ret);
+ }
+ return ret;
+ } finally {
+ unlockAWT();
+ }
+ } else {
+ return "";
+ }
+ }
+
+ protected boolean isFunctionAvailable(String glFunctionName)
+ {
+ boolean available = super.isFunctionAvailable(glFunctionName);
+
+ // Sanity check for implementations that use proc addresses for run-time
+ // linking: if the function IS available, then make sure there's a proc
+ // address for it if it's an extension or not part of the OpenGL 1.1 core
+ // (post GL 1.1 functions are run-time linked on windows).
+ assert(!available ||
+ (getGLProcAddressTable().getAddressFor(mapToRealGLFunctionName(glFunctionName)) != 0 ||
+ FunctionAvailabilityCache.isPartOfGLCore("1.1", mapToRealGLFunctionName(glFunctionName)))
+ );
+
+ return available;
+ }
+
+ public boolean isExtensionAvailable(String glExtensionName) {
+ if (glExtensionName.equals("GL_ARB_pbuffer") ||
+ glExtensionName.equals("GL_ARB_pixel_format")) {
+ return GLDrawableFactory.getFactory().canCreateGLPbuffer();
+ }
+ return super.isExtensionAvailable(glExtensionName);
+ }
+
+
+ public void setSwapInterval(int interval) {
+ // FIXME: make the context current first? Currently assumes that
+ // will not be necessary. Make the caller do this?
+ GLXExt glXExt = getGLXExt();
+ if (glXExt.isExtensionAvailable("GLX_SGI_swap_control")) {
+ glXExt.glXSwapIntervalSGI(interval);
+ }
+ }
+
+ public ByteBuffer glAllocateMemoryNV(int arg0, float arg1, float arg2, float arg3) {
+ return getGLXExt().glXAllocateMemoryNV(arg0, arg1, arg2, arg3);
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ public void bindPbufferToTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ public void releasePbufferFromTexture() {
+ throw new GLException("Should not call this");
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ protected long getContext() {
+ return context;
+ }
+
+ // These synchronization primitives prevent the AWT from making
+ // requests from the X server asynchronously to this code.
+ protected void lockAWT() {
+ X11GLDrawableFactory.lockAWT();
+ }
+
+ protected void unlockAWT() {
+ X11GLDrawableFactory.unlockAWT();
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11GLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11GLDrawable.java
new file mode 100644
index 000000000..1d4f5389b
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11GLDrawable.java
@@ -0,0 +1,172 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import java.awt.Component;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public abstract class X11GLDrawable extends GLDrawableImpl {
+ protected static final boolean DEBUG = Debug.debug("X11GLDrawable");
+
+ protected long display;
+ protected long drawable;
+ protected long visualID;
+ protected Component component;
+ protected GLCapabilities capabilities;
+ protected GLCapabilitiesChooser chooser;
+
+ public X11GLDrawable(Component component,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ this.component = component;
+ this.capabilities = (capabilities == null) ? null :
+ ((GLCapabilities) capabilities.clone());
+ this.chooser = chooser;
+ }
+
+ public void setRealized(boolean val) {
+ throw new GLException("Should not call this (should only be called for onscreen GLDrawables)");
+ }
+
+ public void destroy() {
+ throw new GLException("Should not call this (should only be called for offscreen GLDrawables)");
+ }
+
+ public void swapBuffers() throws GLException {
+ }
+
+ public long getDisplay() {
+ return display;
+ }
+
+ public long getDrawable() {
+ return drawable;
+ }
+
+ //---------------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ protected XVisualInfo chooseVisual(boolean onscreen) {
+ if (display == 0) {
+ throw new GLException("null display");
+ }
+
+ // FIXME
+ if (onscreen) {
+ // The visual has already been chosen by the time we get here;
+ // it's specified by the GraphicsConfiguration of the
+ // GLCanvas. Fortunately, the JAWT supplies the visual ID for
+ // the component in a portable fashion, so all we have to do is
+ // use XGetVisualInfo with a VisualIDMask to get the
+ // corresponding XVisualInfo to pass into glXChooseVisual.
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ // FIXME: probably not 64-bit clean
+ template.visualid((int) visualID);
+ lockAWT();
+ XVisualInfo[] infos = GLX.XGetVisualInfo(display, GLX.VisualIDMask, template, count, 0);
+ unlockAWT();
+ if (infos == null || infos.length == 0) {
+ throw new GLException("Error while getting XVisualInfo for visual ID " + visualID);
+ }
+ // FIXME: the storage for the infos array is leaked (should
+ // clean it up somehow when we're done with the visual we're
+ // returning)
+ return infos[0];
+ } else {
+ // It isn't clear to me whether we need this much code to handle
+ // the offscreen case, where we're creating a pixmap into which
+ // to render...this is what we (incorrectly) used to do for the
+ // onscreen case
+
+ int screen = 0; // FIXME: provide way to specify this?
+ XVisualInfo vis = null;
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ template.screen(screen);
+ XVisualInfo[] infos = null;
+ GLCapabilities[] caps = null;
+ lockAWT();
+ try {
+ infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count, 0);
+ if (infos == null) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ caps = new GLCapabilities[infos.length];
+ for (int i = 0; i < infos.length; i++) {
+ caps[i] = X11GLDrawableFactory.xvi2GLCapabilities(display, infos[i]);
+ }
+ } finally {
+ unlockAWT();
+ }
+ int chosen = chooser.chooseCapabilities(capabilities, caps, -1);
+ if (chosen < 0 || chosen >= caps.length) {
+ throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ }
+ if (DEBUG) {
+ System.err.println("Chosen visual (" + chosen + "):");
+ System.err.println(caps[chosen]);
+ }
+ vis = infos[chosen];
+ if (vis == null) {
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ }
+ // FIXME: the storage for the infos array is leaked (should
+ // clean it up somehow when we're done with the visual we're
+ // returning)
+
+ return vis;
+ }
+ }
+
+
+ // These synchronization primitives prevent the AWT from making
+ // requests from the X server asynchronously to this code.
+ protected void lockAWT() {
+ X11GLDrawableFactory.lockAWT();
+ }
+
+ protected void unlockAWT() {
+ X11GLDrawableFactory.unlockAWT();
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
new file mode 100644
index 000000000..f4523c95e
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11GLDrawableFactory.java
@@ -0,0 +1,439 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import java.awt.Component;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.awt.GraphicsEnvironment;
+import java.security.*;
+import java.util.ArrayList;
+import java.util.List;
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11GLDrawableFactory extends GLDrawableFactoryImpl {
+ private static final boolean DEBUG = Debug.debug("X11GLDrawableFactory");
+
+ // There is currently a bug on Linux/AMD64 distributions in glXGetProcAddressARB
+ private static boolean isLinuxAMD64;
+
+ static {
+ NativeLibLoader.load();
+
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ String os = System.getProperty("os.name").toLowerCase();
+ String arch = System.getProperty("os.arch").toLowerCase();
+ if (os.startsWith("linux") && arch.equals("amd64")) {
+ isLinuxAMD64 = true;
+ }
+ return null;
+ }
+ });
+ }
+
+ public X11GLDrawableFactory() {
+ // Must initialize GLX support eagerly in case a pbuffer is the
+ // first thing instantiated
+ resetProcAddressTable(GLX.getGLXProcAddressTable());
+ }
+
+ private static final int MAX_ATTRIBS = 128;
+
+ public GraphicsConfiguration chooseGraphicsConfiguration(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser,
+ GraphicsDevice device) {
+ if (capabilities == null) {
+ capabilities = new GLCapabilities();
+ }
+ if (chooser == null) {
+ chooser = new DefaultGLCapabilitiesChooser();
+ }
+ if (device == null) {
+ device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
+ }
+
+ int screen = X11SunJDKReflection.graphicsDeviceGetScreen(device);
+ // 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
+
+ int[] attribs = glCapabilities2AttribList(capabilities, isMultisampleAvailable());
+ XVisualInfo[] infos = null;
+ GLCapabilities[] caps = null;
+ int recommendedIndex = -1;
+ lockAWT();
+ try {
+ long display = getDisplayConnection();
+ XVisualInfo recommendedVis = GLX.glXChooseVisual(display, screen, attribs, 0);
+ int[] count = new int[1];
+ XVisualInfo template = new XVisualInfo();
+ template.screen(screen);
+ infos = GLX.XGetVisualInfo(display, GLX.VisualScreenMask, template, count, 0);
+ if (infos == null) {
+ throw new GLException("Error while enumerating available XVisualInfos");
+ }
+ caps = new GLCapabilities[infos.length];
+ for (int i = 0; i < infos.length; i++) {
+ caps[i] = xvi2GLCapabilities(display, infos[i]);
+ // Attempt to find the visual chosen by glXChooseVisual
+ if (recommendedVis != null && recommendedVis.visualid() == infos[i].visualid()) {
+ recommendedIndex = i;
+ }
+ }
+ } finally {
+ unlockAWT();
+ }
+ int chosen = chooser.chooseCapabilities(capabilities, caps, recommendedIndex);
+ if (chosen < 0 || chosen >= caps.length) {
+ throw new GLException("GLCapabilitiesChooser specified invalid index (expected 0.." + (caps.length - 1) + ")");
+ }
+ XVisualInfo vis = infos[chosen];
+ if (vis == null) {
+ throw new GLException("GLCapabilitiesChooser chose an invalid visual");
+ }
+ // FIXME: need to look at glue code and see type of this field
+ long visualID = vis.visualid();
+ // FIXME: the storage for the infos array, as well as that for the
+ // recommended visual, is leaked; should free them here with XFree()
+
+ // Now figure out which GraphicsConfiguration corresponds to this
+ // visual by matching the visual ID
+ GraphicsConfiguration[] configs = device.getConfigurations();
+ for (int i = 0; i < configs.length; i++) {
+ GraphicsConfiguration config = configs[i];
+ if (config != null) {
+ if (X11SunJDKReflection.graphicsConfigurationGetVisualID(config) == visualID) {
+ return config;
+ }
+ }
+ }
+
+ // Either we weren't able to reflectively introspect on the
+ // X11GraphicsConfig or something went wrong in the steps above;
+ // we're going to return null without signaling an error condition
+ // in this case (although we should distinguish between the two
+ // and possibly report more of an error in the latter case)
+ return null;
+ }
+
+ public GLDrawable getGLDrawable(Object target,
+ GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ if (target == null) {
+ throw new IllegalArgumentException("Null target");
+ }
+ if (!(target instanceof Component)) {
+ throw new IllegalArgumentException("GLDrawables not supported for objects of type " +
+ target.getClass().getName() + " (only Components are supported in this implementation)");
+ }
+ return new X11OnscreenGLDrawable((Component) target);
+ }
+
+ public GLDrawableImpl createOffscreenDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ return new X11OffscreenGLDrawable(capabilities, chooser);
+ }
+
+ private boolean pbufferSupportInitialized = false;
+ private boolean canCreateGLPbuffer = false;
+ public boolean canCreateGLPbuffer() {
+ 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()) {
+ 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 GLContext createExternalGLContext() {
+ return new X11ExternalGLContext();
+ }
+
+ public boolean canCreateExternalGLDrawable() {
+ return canCreateGLPbuffer();
+ }
+
+ public GLDrawable createExternalGLDrawable() {
+ return new X11ExternalGLDrawable();
+ }
+
+ public long dynamicLookupFunction(String glFuncName) {
+ long res = 0;
+ if (!isLinuxAMD64) {
+ res = GLX.glXGetProcAddressARB(glFuncName);
+ }
+ if (res == 0) {
+ // GLU routines aren't known to the OpenGL function lookup
+ res = GLX.dlsym(glFuncName);
+ }
+ return res;
+ }
+
+ public static GLCapabilities xvi2GLCapabilities(long display, XVisualInfo info) {
+ int[] tmp = new int[1];
+ int val = glXGetConfig(display, info, GLX.GLX_USE_GL, tmp, 0);
+ if (val == 0) {
+ // Visual does not support OpenGL
+ return null;
+ }
+ val = glXGetConfig(display, info, GLX.GLX_RGBA, tmp, 0);
+ if (val == 0) {
+ // Visual does not support RGBA
+ return null;
+ }
+ GLCapabilities res = new GLCapabilities();
+ res.setDoubleBuffered(glXGetConfig(display, info, GLX.GLX_DOUBLEBUFFER, tmp, 0) != 0);
+ res.setStereo (glXGetConfig(display, info, GLX.GLX_STEREO, tmp, 0) != 0);
+ // Note: use of hardware acceleration is determined by
+ // glXCreateContext, not by the XVisualInfo. Optimistically claim
+ // that all GLCapabilities have the capability to be hardware
+ // accelerated.
+ res.setHardwareAccelerated(true);
+ res.setDepthBits (glXGetConfig(display, info, GLX.GLX_DEPTH_SIZE, tmp, 0));
+ res.setStencilBits (glXGetConfig(display, info, GLX.GLX_STENCIL_SIZE, tmp, 0));
+ res.setRedBits (glXGetConfig(display, info, GLX.GLX_RED_SIZE, tmp, 0));
+ res.setGreenBits (glXGetConfig(display, info, GLX.GLX_GREEN_SIZE, tmp, 0));
+ res.setBlueBits (glXGetConfig(display, info, GLX.GLX_BLUE_SIZE, tmp, 0));
+ res.setAlphaBits (glXGetConfig(display, info, GLX.GLX_ALPHA_SIZE, tmp, 0));
+ res.setAccumRedBits (glXGetConfig(display, info, GLX.GLX_ACCUM_RED_SIZE, tmp, 0));
+ 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 (isMultisampleAvailable()) {
+ res.setSampleBuffers(glXGetConfig(display, info, GLX.GLX_SAMPLE_BUFFERS_ARB, tmp, 0) != 0);
+ res.setNumSamples (glXGetConfig(display, info, GLX.GLX_SAMPLES_ARB, tmp, 0));
+ }
+ return res;
+ }
+
+ public static int[] glCapabilities2AttribList(GLCapabilities caps,
+ boolean isMultisampleAvailable) {
+ int colorDepth = (caps.getRedBits() +
+ caps.getGreenBits() +
+ caps.getBlueBits());
+ if (colorDepth < 15) {
+ throw new GLException("Bit depths < 15 (i.e., non-true-color) not supported");
+ }
+ int[] res = new int[MAX_ATTRIBS];
+ int idx = 0;
+ res[idx++] = GLX.GLX_RGBA;
+ if (caps.getDoubleBuffered()) {
+ res[idx++] = GLX.GLX_DOUBLEBUFFER;
+ }
+ if (caps.getStereo()) {
+ res[idx++] = GLX.GLX_STEREO;
+ }
+ res[idx++] = GLX.GLX_RED_SIZE;
+ res[idx++] = caps.getRedBits();
+ res[idx++] = GLX.GLX_GREEN_SIZE;
+ res[idx++] = caps.getGreenBits();
+ res[idx++] = GLX.GLX_BLUE_SIZE;
+ res[idx++] = caps.getBlueBits();
+ res[idx++] = GLX.GLX_ALPHA_SIZE;
+ res[idx++] = caps.getAlphaBits();
+ res[idx++] = GLX.GLX_DEPTH_SIZE;
+ res[idx++] = caps.getDepthBits();
+ res[idx++] = GLX.GLX_STENCIL_SIZE;
+ res[idx++] = caps.getStencilBits();
+ res[idx++] = GLX.GLX_ACCUM_RED_SIZE;
+ res[idx++] = caps.getAccumRedBits();
+ res[idx++] = GLX.GLX_ACCUM_GREEN_SIZE;
+ res[idx++] = caps.getAccumGreenBits();
+ res[idx++] = GLX.GLX_ACCUM_BLUE_SIZE;
+ res[idx++] = caps.getAccumBlueBits();
+ if (isMultisampleAvailable && caps.getSampleBuffers()) {
+ res[idx++] = GLXExt.GLX_SAMPLE_BUFFERS_ARB;
+ res[idx++] = GL.GL_TRUE;
+ res[idx++] = GLXExt.GLX_SAMPLES_ARB;
+ res[idx++] = caps.getNumSamples();
+ }
+ res[idx++] = 0;
+ return res;
+ }
+
+ // JAWT access
+ private static JAWT jawt;
+ public static JAWT getJAWT() {
+ if (jawt == null) {
+ JAWT j = new JAWT();
+ j.version(JAWTFactory.JAWT_VERSION_1_4);
+ if (!JAWTFactory.JAWT_GetAWT(j)) {
+ throw new RuntimeException("Unable to initialize JAWT");
+ }
+ jawt = j;
+ }
+ return jawt;
+ }
+
+ public static void lockAWT() {
+ if (!Java2D.isOGLPipelineActive() || !Java2D.isQueueFlusherThread()) {
+ getJAWT().Lock();
+ }
+ }
+
+ public static void unlockAWT() {
+ if (!Java2D.isOGLPipelineActive() || !Java2D.isQueueFlusherThread()) {
+ getJAWT().Unlock();
+ }
+ }
+
+ public void lockAWTForJava2D() {
+ lockAWT();
+ }
+ public void unlockAWTForJava2D() {
+ unlockAWT();
+ }
+
+ // Display connection for use by visual selection algorithm and by all offscreen surfaces
+ private static long staticDisplay;
+ public static long getDisplayConnection() {
+ if (staticDisplay == 0) {
+ lockAWT();
+ try {
+ staticDisplay = GLX.XOpenDisplay(null);
+ } finally {
+ unlockAWT();
+ }
+ if (staticDisplay == 0) {
+ throw new GLException("Unable to open default display, needed for visual selection and offscreen surface handling");
+ }
+ }
+ return staticDisplay;
+ }
+
+ private static boolean checkedMultisample;
+ private static boolean multisampleAvailable;
+ public static boolean isMultisampleAvailable() {
+ if (!checkedMultisample) {
+ long display = getDisplayConnection();
+ String exts = GLX.glXGetClientString(display, GLX.GLX_EXTENSIONS);
+ if (exts != null) {
+ multisampleAvailable = (exts.indexOf("GLX_ARB_multisample") >= 0);
+ }
+ checkedMultisample = true;
+ }
+ return multisampleAvailable;
+ }
+
+ private static String glXGetConfigErrorCode(int err) {
+ switch (err) {
+ case GLX.GLX_NO_EXTENSION: return "GLX_NO_EXTENSION";
+ case GLX.GLX_BAD_SCREEN: return "GLX_BAD_SCREEN";
+ case GLX.GLX_BAD_ATTRIBUTE: return "GLX_BAD_ATTRIBUTE";
+ case GLX.GLX_BAD_VISUAL: return "GLX_BAD_VISUAL";
+ default: return "Unknown error code " + err;
+ }
+ }
+
+ public static int glXGetConfig(long display, XVisualInfo info, int attrib, int[] tmp, int tmp_offset) {
+ if (display == 0) {
+ throw new GLException("No display connection");
+ }
+ int res = GLX.glXGetConfig(display, info, attrib, tmp, tmp_offset);
+ if (res != 0) {
+ throw new GLException("glXGetConfig failed: error code " + glXGetConfigErrorCode(res));
+ }
+ return tmp[tmp_offset];
+ }
+
+ private void maybeDoSingleThreadedWorkaround(Runnable action) {
+ if (Threading.isSingleThreaded() &&
+ !Threading.isOpenGLThread()) {
+ Threading.invokeOnOpenGLThread(action);
+ } else {
+ action.run();
+ }
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLContext.java b/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLContext.java
new file mode 100644
index 000000000..e1c8eb3d1
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLContext.java
@@ -0,0 +1,74 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11OffscreenGLContext extends X11GLContext {
+ private X11OffscreenGLDrawable drawable;
+
+ public X11OffscreenGLContext(X11OffscreenGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public int getOffscreenContextPixelDataType() {
+ return GL.GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ if (drawable.isDoubleBuffered()) {
+ return GL.GL_BACK;
+ }
+ return GL.GL_FRONT;
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ // There doesn't seem to be a way to do this in the construction
+ // of the Pixmap or GLXPixmap
+ return true;
+ }
+
+ protected void create() {
+ createContext(false);
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java
new file mode 100644
index 000000000..2d7dedd7f
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11OffscreenGLDrawable.java
@@ -0,0 +1,143 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11OffscreenGLDrawable extends X11GLDrawable {
+ private long pixmap;
+ private boolean isDoubleBuffered;
+ // Width and height of the underlying bitmap
+ private int width;
+ private int height;
+
+ public X11OffscreenGLDrawable(GLCapabilities capabilities,
+ GLCapabilitiesChooser chooser) {
+ super(null, capabilities, chooser);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OffscreenGLContext(this, shareWith);
+ }
+
+ public void setSize(int newWidth, int newHeight) {
+ width = newWidth;
+ height = newHeight;
+ if (pixmap != 0) {
+ destroy();
+ }
+ create();
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ private void create() {
+ display = X11GLDrawableFactory.getDisplayConnection();
+ XVisualInfo vis = chooseVisual(false);
+ int bitsPerPixel = vis.depth();
+
+ lockAWT();
+ try {
+ int screen = GLX.DefaultScreen(display);
+ pixmap = GLX.XCreatePixmap(display, (int) GLX.RootWindow(display, screen), width, height, bitsPerPixel);
+ if (pixmap == 0) {
+ throw new GLException("XCreatePixmap failed");
+ }
+ drawable = GLX.glXCreateGLXPixmap(display, vis, pixmap);
+ if (drawable == 0) {
+ GLX.XFreePixmap(display, pixmap);
+ pixmap = 0;
+ throw new GLException("glXCreateGLXPixmap failed");
+ }
+ isDoubleBuffered = (X11GLDrawableFactory.glXGetConfig(display, vis, GLX.GLX_DOUBLEBUFFER, new int[1], 0) != 0);
+ if (DEBUG) {
+ System.err.println("Created pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(display));
+ }
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ public void destroy() {
+ if (pixmap != 0) {
+ if (DEBUG) {
+ System.err.println("Destroying pixmap " + toHexString(pixmap) +
+ ", GLXPixmap " + toHexString(drawable) +
+ ", display " + toHexString(display));
+ }
+
+ // Must destroy pixmap and GLXPixmap
+ lockAWT();
+
+ if (DEBUG) {
+ long cur = GLX.glXGetCurrentContext();
+ if (cur != 0) {
+ System.err.println("WARNING: found context " + toHexString(cur) + " current during pixmap destruction");
+ }
+ }
+
+ // FIXME: workaround for crashes on NVidia hardware when
+ // destroying pixmap (no context is current at the point of the
+ // crash, at least from the point of view of
+ // glXGetCurrentContext)
+ GLX.glXMakeCurrent(display, 0, 0);
+
+ GLX.glXDestroyGLXPixmap(display, drawable);
+ GLX.XFreePixmap(display, pixmap);
+ unlockAWT();
+ drawable = 0;
+ pixmap = 0;
+ display = 0;
+ }
+ }
+
+ public boolean isDoubleBuffered() {
+ return isDoubleBuffered;
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11OnscreenGLContext.java b/src/classes/com/sun/opengl/impl/x11/X11OnscreenGLContext.java
new file mode 100644
index 000000000..d6b79cb8f
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11OnscreenGLContext.java
@@ -0,0 +1,95 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import java.util.*;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11OnscreenGLContext extends X11GLContext {
+ protected X11OnscreenGLDrawable drawable;
+
+ public X11OnscreenGLContext(X11OnscreenGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ try {
+ int lockRes = drawable.lockSurface();
+ if (lockRes == X11OnscreenGLDrawable.LOCK_SURFACE_NOT_READY) {
+ return CONTEXT_NOT_CURRENT;
+ }
+ if (lockRes == X11OnscreenGLDrawable.LOCK_SURFACE_CHANGED) {
+ if (context != 0) {
+ GLX.glXDestroyContext(mostRecentDisplay, context);
+ GLContextShareSet.contextDestroyed(this);
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Destroyed OpenGL context " + toHexString(context) + " due to JAWT_LOCK_SURFACE_CHANGED");
+ }
+ context = 0;
+ }
+ }
+ int ret = super.makeCurrentImpl();
+ return ret;
+ } catch (RuntimeException e) {
+ try {
+ drawable.unlockSurface();
+ } catch (Exception e2) {
+ // do nothing if unlockSurface throws
+ }
+ throw(e);
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ try {
+ super.releaseImpl();
+ } finally {
+ drawable.unlockSurface();
+ }
+ }
+
+ protected void create() {
+ createContext(true);
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11OnscreenGLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11OnscreenGLDrawable.java
new file mode 100644
index 000000000..49000fc14
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11OnscreenGLDrawable.java
@@ -0,0 +1,191 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import java.awt.Component;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11OnscreenGLDrawable extends X11GLDrawable {
+ public static final int LOCK_SURFACE_NOT_READY = 1;
+ public static final int LOCK_SURFACE_CHANGED = 2;
+ public static final int LOCK_SUCCESS = 3;
+
+ // Variables for lockSurface/unlockSurface
+ private JAWT_DrawingSurface ds;
+ private JAWT_DrawingSurfaceInfo dsi;
+ private JAWT_X11DrawingSurfaceInfo x11dsi;
+
+ // Indicates whether the component (if an onscreen context) has been
+ // realized. Plausibly, before the component is realized the JAWT
+ // should return an error or NULL object from some of its
+ // operations; this appears to be the case on Win32 but is not true
+ // at least with Sun's current X11 implementation (1.4.x), which
+ // crashes with no other error reported if the DrawingSurfaceInfo is
+ // fetched from a locked DrawingSurface during the validation as a
+ // result of calling show() on the main thread. To work around this
+ // we prevent any JAWT or OpenGL operations from being done until
+ // addNotify() is called on the component.
+ protected boolean realized;
+
+ public X11OnscreenGLDrawable(Component component) {
+ super(component, null, null);
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11OnscreenGLContext(this, shareWith);
+ }
+
+ public void setRealized(boolean realized) {
+ this.realized = realized;
+ }
+
+ public void setSize(int width, int height) {
+ component.setSize(width, height);
+ }
+
+ public int getWidth() {
+ return component.getWidth();
+ }
+
+ public int getHeight() {
+ return component.getHeight();
+ }
+
+ public void swapBuffers() throws GLException {
+ lockAWT();
+ try {
+ boolean didLock = false;
+
+ if (drawable == 0) {
+ if (lockSurface() == LOCK_SURFACE_NOT_READY) {
+ return;
+ }
+
+ didLock = true;
+ }
+
+ GLX.glXSwapBuffers(display, drawable);
+
+ if (didLock) {
+ unlockSurface();
+ }
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ public int lockSurface() throws GLException {
+ if (!realized) {
+ return LOCK_SURFACE_NOT_READY;
+ }
+ if (drawable != 0) {
+ throw new GLException("Surface already locked");
+ }
+ ds = getJAWT().GetDrawingSurface(component);
+ if (ds == null) {
+ // Widget not yet realized
+ return LOCK_SURFACE_NOT_READY;
+ }
+ int res = ds.Lock();
+ if ((res & JAWTFactory.JAWT_LOCK_ERROR) != 0) {
+ throw new GLException("Unable to lock surface");
+ }
+ // See whether the surface changed and if so destroy the old
+ // OpenGL context so it will be recreated (NOTE: removeNotify
+ // should handle this case, but it may be possible that race
+ // conditions can cause this code to be triggered -- should test
+ // more)
+ int ret = LOCK_SUCCESS;
+ if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
+ ret = LOCK_SURFACE_CHANGED;
+ }
+ dsi = ds.GetDrawingSurfaceInfo();
+ if (dsi == null) {
+ // Widget not yet realized
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ x11dsi = (JAWT_X11DrawingSurfaceInfo) dsi.platformInfo();
+ display = x11dsi.display();
+ drawable = x11dsi.drawable();
+ visualID = x11dsi.visualID();
+ if (display == 0 || drawable == 0) {
+ // Widget not yet realized
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ x11dsi = null;
+ display = 0;
+ drawable = 0;
+ visualID = 0;
+ return LOCK_SURFACE_NOT_READY;
+ }
+ return ret;
+ }
+
+ public void unlockSurface() {
+ if (drawable == 0) {
+ throw new GLException("Surface already unlocked");
+ }
+ ds.FreeDrawingSurfaceInfo(dsi);
+ ds.Unlock();
+ getJAWT().FreeDrawingSurface(ds);
+ ds = null;
+ dsi = null;
+ x11dsi = null;
+ display = 0;
+ drawable = 0;
+ visualID = 0;
+ }
+
+ //----------------------------------------------------------------------
+ // Internals only below this point
+ //
+
+ private JAWT getJAWT() {
+ return X11GLDrawableFactory.getJAWT();
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11PbufferGLContext.java b/src/classes/com/sun/opengl/impl/x11/X11PbufferGLContext.java
new file mode 100644
index 000000000..0cb945de7
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11PbufferGLContext.java
@@ -0,0 +1,151 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11PbufferGLContext extends X11GLContext {
+ private X11PbufferGLDrawable drawable;
+
+ public X11PbufferGLContext(X11PbufferGLDrawable drawable,
+ GLContext shareWith) {
+ super(drawable, shareWith);
+ this.drawable = drawable;
+ }
+
+ public void bindPbufferToTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+ public void releasePbufferFromTexture() {
+ // FIXME: figure out how to implement this
+ throw new GLException("Not yet implemented");
+ }
+
+ protected int makeCurrentImpl() throws GLException {
+ if (drawable.getDrawable() == 0) {
+ // pbuffer not instantiated (yet?)
+ if (DEBUG) {
+ System.err.println("pbuffer not instantiated");
+ }
+ return CONTEXT_NOT_CURRENT;
+ }
+
+ // Note that we have to completely override makeCurrentImpl
+ // because the underlying makeCurrent call differs for pbuffers
+ lockAWT();
+ try {
+ boolean created = false;
+ if (context == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println(getThreadName() + ": !!! Created GL context for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!GLX.glXMakeContextCurrent(drawable.getDisplay(),
+ drawable.getDrawable(),
+ drawable.getDrawable(),
+ context)) {
+ throw new GLException("Error making context current");
+ } else {
+ mostRecentDisplay = drawable.getDisplay();
+ if (DEBUG && VERBOSE) {
+ System.err.println(getThreadName() + ": glXMakeCurrent(display " + toHexString(drawable.getDisplay()) +
+ ", drawable " + toHexString(drawable.getDrawable()) +
+ ", context " + toHexString(context) + ") succeeded");
+ }
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ return CONTEXT_CURRENT_NEW;
+ }
+ return CONTEXT_CURRENT;
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ protected void releaseImpl() throws GLException {
+ lockAWT();
+ try {
+ if (!GLX.glXMakeContextCurrent(drawable.getDisplay(), 0, 0, 0)) {
+ throw new GLException("Error freeing OpenGL context");
+ }
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ public int getFloatingPointMode() {
+ return drawable.getFloatingPointMode();
+ }
+
+ protected void create() {
+ if (DEBUG) {
+ System.err.println("Creating context for pbuffer " + drawable.getWidth() +
+ " x " + drawable.getHeight());
+ }
+
+ // Create a gl context for the p-buffer.
+ X11GLContext other = (X11GLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ context = GLX.glXCreateNewContext(drawable.getDisplay(), drawable.getFBConfig(), GLXExt.GLX_RGBA_TYPE, share, true);
+ if (context == 0) {
+ throw new GLException("pbuffer creation error: glXCreateNewContext() failed");
+ }
+ GLContextShareSet.contextCreated(this);
+
+ if (DEBUG) {
+ System.err.println("Created context for pbuffer " + drawable.getWidth() +
+ " x " + drawable.getHeight());
+ }
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java b/src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java
new file mode 100644
index 000000000..2a1248405
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11PbufferGLDrawable.java
@@ -0,0 +1,264 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import javax.media.opengl.*;
+import com.sun.opengl.impl.*;
+
+public class X11PbufferGLDrawable extends X11GLDrawable {
+ private int initWidth;
+ private int initHeight;
+
+ // drawable in superclass is a GLXPbuffer
+ private GLXFBConfig fbConfig;
+ private int width;
+ private int height;
+
+ protected static final int MAX_PFORMATS = 256;
+ protected static final int MAX_ATTRIBS = 256;
+
+ public X11PbufferGLDrawable(GLCapabilities capabilities, int initialWidth, int initialHeight) {
+ super(null, capabilities, null);
+ this.initWidth = initialWidth;
+ this.initHeight = initialHeight;
+ if (initWidth <= 0 || initHeight <= 0) {
+ throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+ initWidth + ", " + initHeight + "))");
+ }
+
+ if (DEBUG) {
+ System.out.println("Pbuffer caps on init: " + capabilities +
+ (capabilities.getOffscreenRenderToTexture() ? " [rtt]" : "") +
+ (capabilities.getOffscreenRenderToTextureRectangle() ? " [rect]" : "") +
+ (capabilities.getOffscreenFloatingPointBuffers() ? " [float]" : ""));
+ }
+
+ createPbuffer(X11GLDrawableFactory.getDisplayConnection());
+ }
+
+ public GLContext createContext(GLContext shareWith) {
+ return new X11PbufferGLContext(this, shareWith);
+ }
+
+ public void destroy() {
+ lockAWT();
+ if (drawable != 0) {
+ GLX.glXDestroyPbuffer(display, drawable);
+ }
+ unlockAWT();
+ display = 0;
+ }
+
+ public void setSize(int width, int height) {
+ // FIXME
+ throw new GLException("Not yet implemented");
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ 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.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;
+
+ // Since we are trying to create a pbuffer, the GLXFBConfig we
+ // request (and subsequently use) must be "p-buffer capable".
+ iattributes[niattribs++] = GLXExt.GLX_DRAWABLE_TYPE;
+ iattributes[niattribs++] = GLXExt.GLX_PBUFFER_BIT;
+
+ iattributes[niattribs++] = GLXExt.GLX_RENDER_TYPE;
+ iattributes[niattribs++] = GLXExt.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_DEPTH_SIZE;
+ iattributes[niattribs++] = capabilities.getDepthBits();
+
+ iattributes[niattribs++] = GLX.GLX_RED_SIZE;
+ iattributes[niattribs++] = capabilities.getRedBits();
+
+ iattributes[niattribs++] = GLX.GLX_GREEN_SIZE;
+ iattributes[niattribs++] = capabilities.getGreenBits();
+
+ iattributes[niattribs++] = GLX.GLX_BLUE_SIZE;
+ iattributes[niattribs++] = capabilities.getBlueBits();
+
+ 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.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();
+ }
+
+ int screen = 0; // FIXME: provide way to specify this?
+
+ if (capabilities.getOffscreenFloatingPointBuffers()) {
+ 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;
+ }
+
+ // 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
+
+ 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");
+ }
+ int nelements = nelementsTmp[0];
+ if (nelements <= 0) {
+ throw new GLException("pbuffer creation error: couldn't find a suitable frame buffer configuration");
+ }
+ // Note that we currently don't allow selection of anything but
+ // the first GLXFBConfig in the returned list
+ GLXFBConfig fbConfig = fbConfigs[0];
+
+ 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;
+
+ iattributes[niattribs++] = GLXExt.GLX_PBUFFER_WIDTH;
+ iattributes[niattribs++] = initWidth;
+ iattributes[niattribs++] = GLXExt.GLX_PBUFFER_HEIGHT;
+ iattributes[niattribs++] = initHeight;
+
+ 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");
+ }
+
+ // 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, GLXExt.GLX_WIDTH, tmp, 0);
+ width = tmp[0];
+ GLX.glXQueryDrawable(display, drawable, GLXExt.GLX_HEIGHT, tmp, 0);
+ height = tmp[0];
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ } finally {
+ unlockAWT();
+ }
+ }
+
+ public int getFloatingPointMode() {
+ // Floating-point pbuffers currently require NVidia hardware on X11
+ return GLPbuffer.NV_FLOAT;
+ }
+
+ public GLXFBConfig getFBConfig() {
+ return fbConfig;
+ }
+
+ private int queryFBConfig(long display, GLXFBConfig fbConfig, int attrib) {
+ int[] tmp = new int[1];
+ if (GLX.glXGetFBConfigAttrib(display, fbConfig, attrib, tmp, 0) != 0) {
+ throw new GLException("glXGetFBConfigAttrib failed");
+ }
+ return tmp[0];
+ }
+}
diff --git a/src/classes/com/sun/opengl/impl/x11/X11SunJDKReflection.java b/src/classes/com/sun/opengl/impl/x11/X11SunJDKReflection.java
new file mode 100644
index 000000000..0760399ab
--- /dev/null
+++ b/src/classes/com/sun/opengl/impl/x11/X11SunJDKReflection.java
@@ -0,0 +1,101 @@
+/*
+ * 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
+ * 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.
+ *
+ * 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.
+ */
+
+package com.sun.opengl.impl.x11;
+
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
+import java.lang.reflect.*;
+import java.security.*;
+
+/** This class encapsulates the reflection routines necessary to peek
+ inside a few data structures in the AWT implementation on X11 for
+ the purposes of correctly enumerating the available visuals. */
+
+public class X11SunJDKReflection {
+ private static Class x11GraphicsDeviceClass;
+ private static Method x11GraphicsDeviceGetScreenMethod;
+ private static Class x11GraphicsConfigClass;
+ private static Method x11GraphicsConfigGetVisualMethod;
+ private static boolean initted;
+
+ static {
+ AccessController.doPrivileged(new PrivilegedAction() {
+ public Object run() {
+ try {
+ x11GraphicsDeviceClass = Class.forName("sun.awt.X11GraphicsDevice");
+ x11GraphicsDeviceGetScreenMethod = x11GraphicsDeviceClass.getDeclaredMethod("getScreen", new Class[] {});
+ x11GraphicsDeviceGetScreenMethod.setAccessible(true);
+
+ x11GraphicsConfigClass = Class.forName("sun.awt.X11GraphicsConfig");
+ x11GraphicsConfigGetVisualMethod = x11GraphicsConfigClass.getDeclaredMethod("getVisual", new Class[] {});
+ x11GraphicsConfigGetVisualMethod.setAccessible(true);
+ initted = true;
+ } catch (Exception e) {
+ // Either not a Sun JDK or the interfaces have changed since 1.4.2 / 1.5
+ }
+ return null;
+ }
+ });
+ }
+
+ public static int graphicsDeviceGetScreen(GraphicsDevice device) {
+ if (!initted) {
+ return 0;
+ }
+
+ try {
+ return ((Integer) x11GraphicsDeviceGetScreenMethod.invoke(device, new Object[] {})).intValue();
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+
+ public static int graphicsConfigurationGetVisualID(GraphicsConfiguration config) {
+ if (!initted) {
+ return 0;
+ }
+
+ try {
+ return ((Integer) x11GraphicsConfigGetVisualMethod.invoke(config, new Object[] {})).intValue();
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+}