blob: ce133d012dc6193de7b82dc4d676065e6c3d1715 [file] [log] [blame]
Brian Paul21666e32002-10-05 18:30:13 +00001
2/*
3 * OpenGL pbuffers utility functions.
4 *
5 * Brian Paul
Brian Paulf72e4422005-01-04 00:58:29 +00006 * Original code: April 1997
Brian Paul21666e32002-10-05 18:30:13 +00007 * Updated on 5 October 2002
Brian Paulf72e4422005-01-04 00:58:29 +00008 * Updated again on 3 January 2005 to use GLX 1.3 functions in preference
9 * to the GLX_SGIX_fbconfig/pbuffer extensions.
Brian Paul21666e32002-10-05 18:30:13 +000010 */
11
Brian Paul21666e32002-10-05 18:30:13 +000012#include <stdio.h>
13#include <string.h>
14#include "pbutil.h"
15
16
Brian Paulf72e4422005-01-04 00:58:29 +000017/**
Brian Paul21666e32002-10-05 18:30:13 +000018 * Test if we pixel buffers are available for a particular X screen.
19 * Input: dpy - the X display
20 * screen - screen number
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040021 * Return: 0 = fbconfigs not available.
22 * 1 = fbconfigs are available via GLX 1.3.
23 * 2 = fbconfigs and pbuffers are available via GLX_SGIX_fbconfig
Brian Paul21666e32002-10-05 18:30:13 +000024 */
25int
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040026QueryFBConfig(Display *dpy, int screen)
Brian Paul21666e32002-10-05 18:30:13 +000027{
Brian Paulf72e4422005-01-04 00:58:29 +000028#if defined(GLX_VERSION_1_3)
29 {
30 /* GLX 1.3 supports pbuffers */
31 int glxVersionMajor, glxVersionMinor;
32 if (!glXQueryVersion(dpy, &glxVersionMajor, &glxVersionMinor)) {
33 /* GLX not available! */
34 return 0;
35 }
36 if (glxVersionMajor * 100 + glxVersionMinor >= 103) {
37 return 1;
38 }
39 /* fall-through */
Brian Paul21666e32002-10-05 18:30:13 +000040 }
Brian Paul21666e32002-10-05 18:30:13 +000041#endif
Brian Paulf72e4422005-01-04 00:58:29 +000042
Brian Paulf72e4422005-01-04 00:58:29 +000043 /* Try the SGIX extensions */
44 {
45 char *extensions;
46 extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040047 if (extensions && strstr(extensions,"GLX_SGIX_fbconfig")) {
48 return 2;
Brian Paulf72e4422005-01-04 00:58:29 +000049 }
Brian Paulf72e4422005-01-04 00:58:29 +000050 }
Brian Paulf72e4422005-01-04 00:58:29 +000051
52 return 0;
Brian Paul21666e32002-10-05 18:30:13 +000053}
54
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040055/**
56 * Test if we pixel buffers are available for a particular X screen.
57 * Input: dpy - the X display
58 * screen - screen number
59 * Return: 0 = pixel buffers not available.
60 * 1 = pixel buffers are available via GLX 1.3.
61 * 2 = pixel buffers are available via GLX_SGIX_fbconfig/pbuffer.
62 */
63int
64QueryPbuffers(Display *dpy, int screen)
65{
66 int ret;
Brian Paul21666e32002-10-05 18:30:13 +000067
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040068 ret = QueryFBConfig(dpy, screen);
69 if (ret == 2) {
70 char *extensions;
71 extensions = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS);
72 if (extensions && strstr(extensions, "GLX_SGIX_pbuffer"))
73 return 2;
74 else
75 return 0;
76 }
77 else
78 return ret;
79}
Brian Paul21666e32002-10-05 18:30:13 +000080
Brian Paulf72e4422005-01-04 00:58:29 +000081FBCONFIG *
82ChooseFBConfig(Display *dpy, int screen, const int attribs[], int *nConfigs)
83{
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040084 int fbcSupport = QueryPbuffers(dpy, screen);
Brian Paulf72e4422005-01-04 00:58:29 +000085#if defined(GLX_VERSION_1_3)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040086 if (fbcSupport == 1) {
Brian Paulf72e4422005-01-04 00:58:29 +000087 return glXChooseFBConfig(dpy, screen, attribs, nConfigs);
88 }
89#endif
90#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -040091 if (fbcSupport == 2) {
Brian Paulf72e4422005-01-04 00:58:29 +000092 return glXChooseFBConfigSGIX(dpy, screen, (int *) attribs, nConfigs);
93 }
94#endif
95 return NULL;
96}
Brian Paul21666e32002-10-05 18:30:13 +000097
98
Brian Paulba5ceda2005-01-07 01:17:42 +000099FBCONFIG *
100GetAllFBConfigs(Display *dpy, int screen, int *nConfigs)
101{
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400102 int fbcSupport = QueryFBConfig(dpy, screen);
Brian Paulba5ceda2005-01-07 01:17:42 +0000103#if defined(GLX_VERSION_1_3)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400104 if (fbcSupport == 1) {
Brian Paulba5ceda2005-01-07 01:17:42 +0000105 return glXGetFBConfigs(dpy, screen, nConfigs);
106 }
107#endif
108#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400109 if (fbcSupport == 2) {
Brian Paulc3984fc2005-04-06 22:40:39 +0000110 /* The GLX_SGIX_fbconfig extensions says to pass NULL to get list
111 * of all available configurations.
112 */
113 return glXChooseFBConfigSGIX(dpy, screen, NULL, nConfigs);
Brian Paulba5ceda2005-01-07 01:17:42 +0000114 }
115#endif
116 return NULL;
117}
118
Brian Paulf72e4422005-01-04 00:58:29 +0000119
120XVisualInfo *
121GetVisualFromFBConfig(Display *dpy, int screen, FBCONFIG config)
122{
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400123 int fbcSupport = QueryFBConfig(dpy, screen);
Brian Paulf72e4422005-01-04 00:58:29 +0000124#if defined(GLX_VERSION_1_3)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400125 if (fbcSupport == 1) {
Brian Paulf72e4422005-01-04 00:58:29 +0000126 return glXGetVisualFromFBConfig(dpy, config);
127 }
128#endif
129#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400130 if (fbcSupport == 2) {
Brian Paulf72e4422005-01-04 00:58:29 +0000131 return glXGetVisualFromFBConfigSGIX(dpy, config);
132 }
133#endif
134 return NULL;
135}
136
137
138/**
139 * Either use glXGetFBConfigAttrib() or glXGetFBConfigAttribSGIX()
140 * to query an fbconfig attribute.
141 */
142static int
Brian Paulff53a4e2005-01-10 23:15:59 +0000143GetFBConfigAttrib(Display *dpy, int screen,
Brian Paulf72e4422005-01-04 00:58:29 +0000144#if defined(GLX_VERSION_1_3)
145 const GLXFBConfig config,
146#elif defined(GLX_SGIX_fbconfig)
147 const GLXFBConfigSGIX config,
148#endif
149 int attrib
150 )
151{
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400152 int fbcSupport = QueryFBConfig(dpy, screen);
Brian Paulff53a4e2005-01-10 23:15:59 +0000153 int value = 0;
Brian Paulf72e4422005-01-04 00:58:29 +0000154
155#if defined(GLX_VERSION_1_3)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400156 if (fbcSupport == 1) {
Brian Paulf72e4422005-01-04 00:58:29 +0000157 /* ok */
158 if (glXGetFBConfigAttrib(dpy, config, attrib, &value) != 0) {
159 value = 0;
160 }
161 return value;
162 }
163 /* fall-through */
164#endif
165
166#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400167 if (fbcSupport == 2) {
Brian Paulff53a4e2005-01-10 23:15:59 +0000168 if (glXGetFBConfigAttribSGIX(dpy, config, attrib, &value) != 0) {
169 value = 0;
170 }
171 return value;
Brian Paulf72e4422005-01-04 00:58:29 +0000172 }
Brian Paulf72e4422005-01-04 00:58:29 +0000173#endif
174
Brian Paulff53a4e2005-01-10 23:15:59 +0000175 return value;
Brian Paulf72e4422005-01-04 00:58:29 +0000176}
177
178
179
180/**
Brian Paul21666e32002-10-05 18:30:13 +0000181 * Print parameters for a GLXFBConfig to stdout.
182 * Input: dpy - the X display
Brian Paulf72e4422005-01-04 00:58:29 +0000183 * screen - the X screen number
Brian Paul21666e32002-10-05 18:30:13 +0000184 * fbConfig - the fbconfig handle
185 * horizFormat - if true, print in horizontal format
186 */
187void
Brian Paulf72e4422005-01-04 00:58:29 +0000188PrintFBConfigInfo(Display *dpy, int screen, FBCONFIG config, Bool horizFormat)
Brian Paul21666e32002-10-05 18:30:13 +0000189{
Brian Paulf72e4422005-01-04 00:58:29 +0000190 PBUFFER pBuffer;
Brian Paul21666e32002-10-05 18:30:13 +0000191 int width=2, height=2;
192 int bufferSize, level, doubleBuffer, stereo, auxBuffers;
193 int redSize, greenSize, blueSize, alphaSize;
194 int depthSize, stencilSize;
195 int accumRedSize, accumBlueSize, accumGreenSize, accumAlphaSize;
196 int sampleBuffers, samples;
197 int drawableType, renderType, xRenderable, xVisual, id;
198 int maxWidth, maxHeight, maxPixels;
199 int optWidth, optHeight;
Brian Paulff53a4e2005-01-10 23:15:59 +0000200 int floatComponents = 0;
Brian Paul21666e32002-10-05 18:30:13 +0000201
Brian Paulf72e4422005-01-04 00:58:29 +0000202 /* do queries using the GLX 1.3 tokens (same as the SGIX tokens) */
Brian Paulff53a4e2005-01-10 23:15:59 +0000203 bufferSize = GetFBConfigAttrib(dpy, screen, config, GLX_BUFFER_SIZE);
204 level = GetFBConfigAttrib(dpy, screen, config, GLX_LEVEL);
205 doubleBuffer = GetFBConfigAttrib(dpy, screen, config, GLX_DOUBLEBUFFER);
206 stereo = GetFBConfigAttrib(dpy, screen, config, GLX_STEREO);
207 auxBuffers = GetFBConfigAttrib(dpy, screen, config, GLX_AUX_BUFFERS);
208 redSize = GetFBConfigAttrib(dpy, screen, config, GLX_RED_SIZE);
209 greenSize = GetFBConfigAttrib(dpy, screen, config, GLX_GREEN_SIZE);
210 blueSize = GetFBConfigAttrib(dpy, screen, config, GLX_BLUE_SIZE);
211 alphaSize = GetFBConfigAttrib(dpy, screen, config, GLX_ALPHA_SIZE);
212 depthSize = GetFBConfigAttrib(dpy, screen, config, GLX_DEPTH_SIZE);
213 stencilSize = GetFBConfigAttrib(dpy, screen, config, GLX_STENCIL_SIZE);
214 accumRedSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_RED_SIZE);
215 accumGreenSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_GREEN_SIZE);
216 accumBlueSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_BLUE_SIZE);
217 accumAlphaSize = GetFBConfigAttrib(dpy, screen, config, GLX_ACCUM_ALPHA_SIZE);
218 sampleBuffers = GetFBConfigAttrib(dpy, screen, config, GLX_SAMPLE_BUFFERS);
219 samples = GetFBConfigAttrib(dpy, screen, config, GLX_SAMPLES);
220 drawableType = GetFBConfigAttrib(dpy, screen, config, GLX_DRAWABLE_TYPE);
221 renderType = GetFBConfigAttrib(dpy, screen, config, GLX_RENDER_TYPE);
222 xRenderable = GetFBConfigAttrib(dpy, screen, config, GLX_X_RENDERABLE);
223 xVisual = GetFBConfigAttrib(dpy, screen, config, GLX_X_VISUAL_TYPE);
Brian Paul21666e32002-10-05 18:30:13 +0000224 if (!xRenderable || !(drawableType & GLX_WINDOW_BIT_SGIX))
225 xVisual = -1;
Brian Paul21666e32002-10-05 18:30:13 +0000226
Brian Paulff53a4e2005-01-10 23:15:59 +0000227 id = GetFBConfigAttrib(dpy, screen, config, GLX_FBCONFIG_ID);
228 maxWidth = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_WIDTH);
229 maxHeight = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_HEIGHT);
230 maxPixels = GetFBConfigAttrib(dpy, screen, config, GLX_MAX_PBUFFER_PIXELS);
Brian Paulf72e4422005-01-04 00:58:29 +0000231#if defined(GLX_SGIX_pbuffer)
Brian Paulff53a4e2005-01-10 23:15:59 +0000232 optWidth = GetFBConfigAttrib(dpy, screen, config, GLX_OPTIMAL_PBUFFER_WIDTH_SGIX);
233 optHeight = GetFBConfigAttrib(dpy, screen, config, GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX);
Brian Paulf72e4422005-01-04 00:58:29 +0000234#else
235 optWidth = optHeight = 0;
236#endif
237#if defined(GLX_NV_float_buffer)
Brian Paulff53a4e2005-01-10 23:15:59 +0000238 floatComponents = GetFBConfigAttrib(dpy, screen, config, GLX_FLOAT_COMPONENTS_NV);
Brian Paulf72e4422005-01-04 00:58:29 +0000239#endif
Brian Paul21666e32002-10-05 18:30:13 +0000240
Brian Paulf72e4422005-01-04 00:58:29 +0000241 /* See if we can create a pbuffer with this config */
242 pBuffer = CreatePbuffer(dpy, screen, config, width, height, False, False);
Brian Paul21666e32002-10-05 18:30:13 +0000243
244 if (horizFormat) {
Brian Paulff53a4e2005-01-10 23:15:59 +0000245 printf("0x%-9x ", id);
Brian Paul21666e32002-10-05 18:30:13 +0000246 if (xVisual==GLX_STATIC_GRAY) printf("StaticGray ");
247 else if (xVisual==GLX_GRAY_SCALE) printf("GrayScale ");
248 else if (xVisual==GLX_STATIC_COLOR) printf("StaticColor ");
249 else if (xVisual==GLX_PSEUDO_COLOR) printf("PseudoColor ");
250 else if (xVisual==GLX_TRUE_COLOR) printf("TrueColor ");
251 else if (xVisual==GLX_DIRECT_COLOR) printf("DirectColor ");
252 else printf(" -none- ");
253 printf(" %3d %3d %s %s %s %2s ", bufferSize, level,
Brian Paulff53a4e2005-01-10 23:15:59 +0000254 (renderType & GLX_RGBA_BIT_SGIX) ? "y" : ".",
255 (renderType & GLX_COLOR_INDEX_BIT_SGIX) ? "y" : ".",
256 doubleBuffer ? "y" : ".",
257 stereo ? "y" : ".");
Brian Paul21666e32002-10-05 18:30:13 +0000258 printf("%2d %2d %2d %2d ", redSize, greenSize, blueSize, alphaSize);
259 printf("%2d %2d ", depthSize, stencilSize);
260 printf("%2d %2d %2d %2d", accumRedSize, accumGreenSize, accumBlueSize,
261 accumAlphaSize);
262 printf(" %2d %2d", sampleBuffers, samples);
Brian Paulff53a4e2005-01-10 23:15:59 +0000263 printf(" %s %c", pBuffer ? "y" : ".",
264 ".y"[floatComponents]);
Brian Paul21666e32002-10-05 18:30:13 +0000265 printf("\n");
266 }
267 else {
268 printf("Id 0x%x\n", id);
269 printf(" Buffer Size: %d\n", bufferSize);
270 printf(" Level: %d\n", level);
271 printf(" Double Buffer: %s\n", doubleBuffer ? "yes" : "no");
272 printf(" Stereo: %s\n", stereo ? "yes" : "no");
273 printf(" Aux Buffers: %d\n", auxBuffers);
274 printf(" Red Size: %d\n", redSize);
275 printf(" Green Size: %d\n", greenSize);
276 printf(" Blue Size: %d\n", blueSize);
277 printf(" Alpha Size: %d\n", alphaSize);
278 printf(" Depth Size: %d\n", depthSize);
279 printf(" Stencil Size: %d\n", stencilSize);
280 printf(" Accum Red Size: %d\n", accumRedSize);
281 printf(" Accum Green Size: %d\n", accumGreenSize);
282 printf(" Accum Blue Size: %d\n", accumBlueSize);
283 printf(" Accum Alpha Size: %d\n", accumAlphaSize);
284 printf(" Sample Buffers: %d\n", sampleBuffers);
285 printf(" Samples/Pixel: %d\n", samples);
286 printf(" Drawable Types: ");
Brian Paulf72e4422005-01-04 00:58:29 +0000287 if (drawableType & GLX_WINDOW_BIT) printf("Window ");
288 if (drawableType & GLX_PIXMAP_BIT) printf("Pixmap ");
289 if (drawableType & GLX_PBUFFER_BIT) printf("PBuffer");
Brian Paul21666e32002-10-05 18:30:13 +0000290 printf("\n");
291 printf(" Render Types: ");
292 if (renderType & GLX_RGBA_BIT_SGIX) printf("RGBA ");
293 if (renderType & GLX_COLOR_INDEX_BIT_SGIX) printf("CI ");
294 printf("\n");
295 printf(" X Renderable: %s\n", xRenderable ? "yes" : "no");
Brian Paulf72e4422005-01-04 00:58:29 +0000296
Brian Paul21666e32002-10-05 18:30:13 +0000297 printf(" Pbuffer: %s\n", pBuffer ? "yes" : "no");
Brian Paulf72e4422005-01-04 00:58:29 +0000298 printf(" Max Pbuffer width: %d\n", maxWidth);
299 printf(" Max Pbuffer height: %d\n", maxHeight);
300 printf(" Max Pbuffer pixels: %d\n", maxPixels);
301 printf(" Optimum Pbuffer width: %d\n", optWidth);
302 printf(" Optimum Pbuffer height: %d\n", optHeight);
303
304 printf(" Float Components: %s\n", floatComponents ? "yes" : "no");
Brian Paul21666e32002-10-05 18:30:13 +0000305 }
306
307 if (pBuffer) {
Brian Paulf72e4422005-01-04 00:58:29 +0000308 DestroyPbuffer(dpy, screen, pBuffer);
Brian Paul21666e32002-10-05 18:30:13 +0000309 }
310}
311
312
313
Brian Paulc6178292005-04-06 22:41:46 +0000314GLXContext
315CreateContext(Display *dpy, int screen, FBCONFIG config)
316{
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400317 int fbcSupport = QueryFBConfig(dpy, screen);
Brian Paulc6178292005-04-06 22:41:46 +0000318#if defined(GLX_VERSION_1_3)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400319 if (fbcSupport == 1) {
Brian Paulc6178292005-04-06 22:41:46 +0000320 /* GLX 1.3 */
321 GLXContext c;
322 c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, True);
323 if (!c) {
324 /* try indirect */
325 c = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, False);
326 }
327 return c;
328 }
329#endif
330#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
Kristian Høgsbergaad5c0f2007-10-17 17:03:33 -0400331 if (fbcSupport == 2) {
Brian Paulc6178292005-04-06 22:41:46 +0000332 GLXContext c;
333 c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, True);
334 if (!c) {
335 c = glXCreateContextWithConfigSGIX(dpy, config, GLX_RGBA_TYPE_SGIX, NULL, False);
336 }
337 return c;
338 }
339#endif
340 return 0;
341}
342
343
344void
345DestroyContext(Display *dpy, GLXContext ctx)
346{
347 glXDestroyContext(dpy, ctx);
348}
349
350
Brian Paul21666e32002-10-05 18:30:13 +0000351/* This is only used by CreatePbuffer() */
352static int XErrorFlag = 0;
Brian Paulf72e4422005-01-04 00:58:29 +0000353static int HandleXError(Display *dpy, XErrorEvent *event)
Brian Paul21666e32002-10-05 18:30:13 +0000354{
355 XErrorFlag = 1;
356 return 0;
357}
358
359
Brian Paulf72e4422005-01-04 00:58:29 +0000360/**
Brian Paul18a94902004-02-02 15:38:26 +0000361 * Create a Pbuffer. Use an X error handler to deal with potential
362 * BadAlloc errors.
Brian Paul21666e32002-10-05 18:30:13 +0000363 *
364 * Input: dpy - the X display
365 * fbConfig - an FBConfig as returned by glXChooseFBConfigSGIX().
366 * width, height - size of pixel buffer to request, in pixels.
Brian Paulf72e4422005-01-04 00:58:29 +0000367 * pbAttribs - list of optional pixel buffer attributes
368 * Return: a Pbuffer or None.
Brian Paul21666e32002-10-05 18:30:13 +0000369 */
Brian Paulf72e4422005-01-04 00:58:29 +0000370PBUFFER
371CreatePbuffer(Display *dpy, int screen, FBCONFIG config,
372 int width, int height, Bool largest, Bool preserve)
Brian Paul21666e32002-10-05 18:30:13 +0000373{
Brian Paulf72e4422005-01-04 00:58:29 +0000374 int (*oldHandler)(Display *, XErrorEvent *);
375 PBUFFER pBuffer = None;
376 int pbSupport = QueryPbuffers(dpy, screen);
Brian Paul21666e32002-10-05 18:30:13 +0000377
378 /* Catch X protocol errors with our own error handler */
Brian Paulf72e4422005-01-04 00:58:29 +0000379 oldHandler = XSetErrorHandler(HandleXError);
Brian Paul21666e32002-10-05 18:30:13 +0000380 XErrorFlag = 0;
Brian Paulf72e4422005-01-04 00:58:29 +0000381
382#if defined(GLX_VERSION_1_3)
383 if (pbSupport == 1) {
384 /* GLX 1.3 */
385 int attribs[100], i = 0;
386 attribs[i++] = GLX_PBUFFER_WIDTH;
387 attribs[i++] = width;
388 attribs[i++] = GLX_PBUFFER_HEIGHT;
389 attribs[i++] = height;
390 attribs[i++] = GLX_PRESERVED_CONTENTS;
391 attribs[i++] = preserve;
392 attribs[i++] = GLX_LARGEST_PBUFFER;
393 attribs[i++] = largest;
394 attribs[i++] = 0;
395 pBuffer = glXCreatePbuffer(dpy, config, attribs);
396 }
397 else
398#endif
399#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
400 if (pbSupport == 2) {
401 int attribs[100], i = 0;
402 attribs[i++] = GLX_PRESERVED_CONTENTS;
403 attribs[i++] = preserve;
404 attribs[i++] = GLX_LARGEST_PBUFFER;
405 attribs[i++] = largest;
406 attribs[i++] = 0;
407 pBuffer = glXCreateGLXPbufferSGIX(dpy, config, width, height, attribs);
408 }
409 else
410#endif
411 {
412 pBuffer = None;
413 }
Brian Paul21666e32002-10-05 18:30:13 +0000414
Kristian Høgsbergc095f7e2007-08-30 13:00:20 -0400415 XSync(dpy, False);
Brian Paul21666e32002-10-05 18:30:13 +0000416 /* Restore original X error handler */
Brian Paulf72e4422005-01-04 00:58:29 +0000417 (void) XSetErrorHandler(oldHandler);
Brian Paul21666e32002-10-05 18:30:13 +0000418
419 /* Return pbuffer (may be None) */
Brian Paulf72e4422005-01-04 00:58:29 +0000420 if (!XErrorFlag && pBuffer != None) {
Brian Paul21666e32002-10-05 18:30:13 +0000421 /*printf("config %d worked!\n", i);*/
422 return pBuffer;
423 }
424 else {
425 return None;
426 }
427}
428
429
Brian Paulf72e4422005-01-04 00:58:29 +0000430void
431DestroyPbuffer(Display *dpy, int screen, PBUFFER pbuffer)
432{
433 int pbSupport = QueryPbuffers(dpy, screen);
434#if defined(GLX_VERSION_1_3)
435 if (pbSupport == 1) {
436 glXDestroyPbuffer(dpy, pbuffer);
437 return;
438 }
439#endif
440#if defined(GLX_SGIX_fbconfig) && defined(GLX_SGIX_pbuffer)
441 if (pbSupport == 2) {
442 glXDestroyGLXPbufferSGIX(dpy, pbuffer);
443 return;
444 }
445#endif
446}