* to the GLX_SGIX_fbconfig/pbuffer extensions.
*/
-
#include <stdio.h>
#include <string.h>
#include "pbutil.h"
* Test if we pixel buffers are available for a particular X screen.
* Input: dpy - the X display
* screen - screen number
- * Return: 0 = pixel buffers not available.
- * 1 = pixel buffers are available via GLX 1.3.
- * 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
+ * Return: 0 = fbconfigs not available.
+ * 1 = fbconfigs are available via GLX 1.3.
+ * 2 = fbconfigs and pbuffers are available via GLX_SGIX_fbconfig
*/
int
-QueryPbuffers(Display *dpy, int screen)
+QueryFBConfig(Display *dpy, int screen)
{
#if defined(GLX_VERSION_1_3)
{
}
#endif
-#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
/* Try the SGIX extensions */
{
char *extensions;
extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
- if (!extensions ||
- !strstr(extensions,"GLX_SGIX_fbconfig") ||
- !strstr(extensions,"GLX_SGIX_pbuffer")) {
- return 0;
+ if (extensions && strstr(extensions,"GLX_SGIX_fbconfig")) {
+ return 2;
}
- return 2;
}
-#endif
return 0;
}
+/**
+ * Test if we pixel buffers are available for a particular X screen.
+ * Input: dpy - the X display
+ * screen - screen number
+ * Return: 0 = pixel buffers not available.
+ * 1 = pixel buffers are available via GLX 1.3.
+ * 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
+ */
+int
+QueryPbuffers(Display *dpy, int screen)
+{
+ int ret;
+ ret = QueryFBConfig(dpy, screen);
+ if (ret == 2) {
+ char *extensions;
+ extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
+ if (extensions && strstr(extensions, "GLX_SGIX_pbuffer"))
+ return 2;
+ else
+ return 0;
+ }
+ else
+ return ret;
+}
FBCONFIG *
ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryPbuffers(dpy, screen);
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
return glXChooseFBConfig(dpy, screen, attribs, nConfigs);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
+ if (fbcSupport == 2) {
return glXChooseFBConfigSGIX(dpy, screen, (int *) attribs, nConfigs);
}
#endif
FBCONFIG *
GetAllFBConfigs(Display *dpy, int screen, int *nConfigs)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
return glXGetFBConfigs(dpy, screen, nConfigs);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
- /* this *seems* to work, but may not be perfect */
- static int fbAttribs[] = {
- GLX_RENDER_TYPE, 0,
- GLX_DRAWABLE_TYPE, 0,
- None
- };
- return glXChooseFBConfigSGIX(dpy, screen, fbAttribs, nConfigs);
+ if (fbcSupport == 2) {
+ /* The GLX_SGIX_fbconfig extensions says to pass NULL to get list
+ * of all available configurations.
+ */
+ return glXChooseFBConfigSGIX(dpy, screen, NULL, nConfigs);
}
#endif
return NULL;
XVisualInfo *
GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config)
{
- int pbSupport = QueryPbuffers(dpy, screen);
+ int fbcSupport = QueryFBConfig(dpy, screen);
#if defined(GLX_VERSION_1_3)
- if (pbSupport == 1) {
+ if (fbcSupport == 1) {
return glXGetVisualFromFBConfig(dpy, config);
}
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (pbSupport == 2) {
+ if (fbcSupport == 2) {
return glXGetVisualFromFBConfigSGIX(dpy, config);
}
#endif
* to query an fbconfig attribute.
*/
static int
-GetFBConfigAttrib(Display *dpy,
+GetFBConfigAttrib(Display *dpy, int screen,
#if defined(GLX_VERSION_1_3)
const GLXFBConfig config,
#elif defined(GLX_SGIX_fbconfig)
int attrib
)
{
- int value;
+ int fbcSupport = QueryFBConfig(dpy, screen);
+ int value = 0;
#if defined(GLX_VERSION_1_3)
- int glxVersionMajor, glxVersionMinor;
- if (glXQueryVersion(dpy, &glxVersionMajor, &glxVersionMinor)
- && glxVersionMajor * 100 + glxVersionMinor >= 103) {
+ if (fbcSupport == 1) {
/* ok */
if (glXGetFBConfigAttrib(dpy, config, attrib, &value) != 0) {
value = 0;
#endif
#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
- if (glXGetFBConfigAttribSGIX(dpy, config, attrib, &value) != 0) {
- value = 0;
+ if (fbcSupport == 2) {
+ if (glXGetFBConfigAttribSGIX(dpy, config, attrib, &value) != 0) {
+ value = 0;
+ }
+ return value;
}
- return value;
#endif
- return 0;
+ return value;
}
int drawableType, renderType, xRenderable, xVisual, id;
int maxWidth, maxHeight, maxPixels;
int optWidth, optHeight;
- int floatComponents;
+ int floatComponents = 0;
/* do queries using the GLX 1.3 tokens (same as the SGIX tokens) */
- bufferSize = GetFBConfigAttrib(dpy, config, GLX_BUFFER_SIZE);
- level = GetFBConfigAttrib(dpy, config, GLX_LEVEL);
- doubleBuffer = GetFBConfigAttrib(dpy, config, GLX_DOUBLEBUFFER);
- stereo = GetFBConfigAttrib(dpy, config, GLX_STEREO);
- auxBuffers = GetFBConfigAttrib(dpy, config, GLX_AUX_BUFFERS);
- redSize = GetFBConfigAttrib(dpy, config, GLX_RED_SIZE);
- greenSize = GetFBConfigAttrib(dpy, config, GLX_GREEN_SIZE);
- blueSize = GetFBConfigAttrib(dpy, config, GLX_BLUE_SIZE);
- alphaSize = GetFBConfigAttrib(dpy, config, GLX_ALPHA_SIZE);
- depthSize = GetFBConfigAttrib(dpy, config, GLX_DEPTH_SIZE);
- stencilSize = GetFBConfigAttrib(dpy, config, GLX_STENCIL_SIZE);
- accumRedSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_RED_SIZE);
- accumGreenSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_GREEN_SIZE);
- accumBlueSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_BLUE_SIZE);
- accumAlphaSize = GetFBConfigAttrib(dpy, config, GLX_ACCUM_ALPHA_SIZE);
- sampleBuffers = GetFBConfigAttrib(dpy, config, GLX_SAMPLE_BUFFERS);
- samples = GetFBConfigAttrib(dpy, config, GLX_SAMPLES);
- drawableType = GetFBConfigAttrib(dpy, config, GLX_DRAWABLE_TYPE);
- renderType = GetFBConfigAttrib(dpy, config, GLX_RENDER_TYPE);
- xRenderable = GetFBConfigAttrib(dpy, config, GLX_X_RENDERABLE);
- xVisual = GetFBConfigAttrib(dpy, config, GLX_X_VISUAL_TYPE);
+ bufferSize = GetFBConfigAttrib(dpy, screen, config, GLX_BUFFER_SIZE);
+ level = GetFBConfigAttrib(dpy, screen, config, GLX_LEVEL);
+ doubleBuffer = GetFBConfigAttrib(dpy, screen, config, GLX_DOUBLEBUFFER);
+ stereo = GetFBConfigAttrib(dpy, screen, config, GLX_STEREO);
+ auxBuffers = GetFBConfigAttrib(dpy, screen, config, GLX_AUX_BUFFERS);
+ redSize = GetFBConfigAttrib(dpy, screen, config, GLX_RED_SIZE);
+ greenSize = GetFBConfigAttrib(dpy, screen, config, GLX_GREEN_SIZE);
+ blueSize = GetFBConfigAttrib(dpy, screen, config, GLX_BLUE_SIZE);
+ alphaSize = GetFBConfigAttrib(dpy, screen, config, GLX_ALPHA_SIZE);
+ depthSize = GetFBConfigAttrib(dpy, screen, config, GLX_DEPTH_SIZE);
+ stencilSize = GetFBConfigAttrib(dpy, screen, config, GLX_STENCIL_SIZE);
+ accumRedSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_RED_SIZE);
+ accumGreenSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_GREEN_SIZE);
+ accumBlueSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_BLUE_SIZE);
+ accumAlphaSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_ALPHA_SIZE);
+ sampleBuffers = GetFBConfigAttrib(dpy, screen, config, GLX_SAMPLE_BUFFERS);
+ samples = GetFBConfigAttrib(dpy, screen, config, GLX_SAMPLES);
+ drawableType = GetFBConfigAttrib(dpy, screen, config, GLX_DRAWABLE_TYPE);
+ renderType = GetFBConfigAttrib(dpy, screen, config, GLX_RENDER_TYPE);
+ xRenderable = GetFBConfigAttrib(dpy, screen, config, GLX_X_RENDERABLE);
+ xVisual = GetFBConfigAttrib(dpy, screen, config, GLX_X_VISUAL_TYPE);
if (!xRenderable || !(drawableType & GLX_WINDOW_BIT_SGIX))
xVisual = -1;
- id = GetFBConfigAttrib(dpy, config, GLX_FBCONFIG_ID);
- maxWidth = GetFBConfigAttrib(dpy, config, GLX_MAX_PBUFFER_WIDTH);
- maxHeight = GetFBConfigAttrib(dpy, config, GLX_MAX_PBUFFER_HEIGHT);
- maxPixels = GetFBConfigAttrib(dpy, config, GLX_MAX_PBUFFER_PIXELS);
+ id = GetFBConfigAttrib(dpy, screen, config, GLX_FBCONFIG_ID);
+ maxWidth = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_WIDTH);
+ maxHeight = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_HEIGHT);
+ maxPixels = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_PIXELS);
#if defined(GLX_SGIX_pbuffer)
- optWidth = GetFBConfigAttrib(dpy, config, GLX_OPTIMAL_PBUFFER_WIDTH_SGIX);
- optHeight = GetFBConfigAttrib(dpy, config, GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX);
+ optWidth = GetFBConfigAttrib(dpy, screen, config, GLX_OPTIMAL_PBUFFER_WIDTH_SGIX);
+ optHeight = GetFBConfigAttrib(dpy, screen, config, GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX);
#else
optWidth = optHeight = 0;
#endif
#if defined(GLX_NV_float_buffer)
- floatComponents = GetFBConfigAttrib(dpy, config, GLX_FLOAT_COMPONENTS_NV);
+ floatComponents = GetFBConfigAttrib(dpy, screen, config, GLX_FLOAT_COMPONENTS_NV);
#endif
/* See if we can create a pbuffer with this config */
pBuffer = CreatePbuffer(dpy, screen, config, width, height, False, False);
if (horizFormat) {
- printf("0x%03x ", id);
+ printf("0x%-9x ", id);
if (xVisual==GLX_STATIC_GRAY) printf("StaticGray ");
else if (xVisual==GLX_GRAY_SCALE) printf("GrayScale ");
else if (xVisual==GLX_STATIC_COLOR) printf("StaticColor ");
else if (xVisual==GLX_DIRECT_COLOR) printf("DirectColor ");
else printf(" -none- ");
printf(" %3d %3d %s %s %s %2s ", bufferSize, level,
- (renderType & GLX_RGBA_BIT_SGIX) ? "y" : "n",
- (renderType & GLX_COLOR_INDEX_BIT_SGIX) ? "y" : "n",
- doubleBuffer ? "y" : "n",
- stereo ? "y" : "n");
+ (renderType & GLX_RGBA_BIT_SGIX) ? "y" : ".",
+ (renderType & GLX_COLOR_INDEX_BIT_SGIX) ? "y" : ".",
+ doubleBuffer ? "y" : ".",
+ stereo ? "y" : ".");
printf("%2d %2d %2d %2d ", redSize, greenSize, blueSize, alphaSize);
printf("%2d %2d ", depthSize, stencilSize);
printf("%2d %2d %2d %2d", accumRedSize, accumGreenSize, accumBlueSize,
accumAlphaSize);
printf(" %2d %2d", sampleBuffers, samples);
- printf(" %s %c", pBuffer ? "y" : "n",
- "ny"[floatComponents]);
+ printf(" %s %c", pBuffer ? "y" : ".",
+ ".y"[floatComponents]);
printf("\n");
}
else {
+GLXContext
+CreateContext(Display *dpy, int screen, FBCONFIG config)
+{
+ int fbcSupport = QueryFBConfig(dpy, screen);
+#if defined(GLX_VERSION_1_3)
+ if (fbcSupport == 1) {
+ /* GLX 1.3 */
+ GLXContext c;
+ c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, True);
+ if (!c) {
+ /* try indirect */
+ c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, False);
+ }
+ return c;
+ }
+#endif
+#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
+ if (fbcSupport == 2) {
+ GLXContext c;
+ c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, True);
+ if (!c) {
+ c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, False);
+ }
+ return c;
+ }
+#endif
+ return 0;
+}
+
+
+void
+DestroyContext(Display *dpy, GLXContext ctx)
+{
+ glXDestroyContext(dpy, ctx);
+}
+
+
/* This is only used by CreatePbuffer() */
static int XErrorFlag = 0;
static int HandleXError(Display *dpy, XErrorEvent *event)
pBuffer = None;
}
+ XSync(dpy, False);
/* Restore original X error handler */
(void) XSetErrorHandler(oldHandler);