2 * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
3 * Copyright (C) 1991-2000 Silicon Graphics, Inc. All Rights Reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice including the dates of first publication and
13 * either this permission notice or a reference to
14 * http://oss.sgi.com/projects/FreeB/
15 * shall be included in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * SILICON GRAPHICS, INC. BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
22 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Except as contained in this notice, the name of Silicon Graphics, Inc.
26 * shall not be used in advertising or otherwise to promote the sale, use or
27 * other dealings in this Software without prior written authorization from
28 * Silicon Graphics, Inc.
31 #ifdef HAVE_DMX_CONFIG_H
32 #include <dmx-config.h>
37 #include <GL/glxproto.h>
38 #include <X11/extensions/Xext.h>
39 #include <X11/extensions/extutil.h>
42 #include "dmx_glxvisuals.h"
45 GetGLXVisualConfigs(Display
* dpy
, int screen
, int *nconfigs
)
47 xGLXGetVisualConfigsReq
*req
;
48 xGLXGetVisualConfigsReply reply
;
49 __GLXvisualConfig
*config
, *configs
;
50 GLint i
, j
, nvisuals
, nprops
;
52 int majorOpcode
, dummy
;
55 if (!XQueryExtension(dpy
, "GLX", &majorOpcode
, &dummy
, &dummy
)) {
59 /* Send the glXGetVisualConfigs request */
61 GetReq(GLXGetVisualConfigs
, req
);
62 req
->reqType
= majorOpcode
;
63 req
->glxCode
= X_GLXGetVisualConfigs
;
65 if (!_XReply(dpy
, (xReply
*) &reply
, 0, False
)) {
66 /* Something is busted. Punt. */
72 nvisuals
= (int) reply
.numVisuals
;
74 /* This screen does not support GL rendering */
80 /* Check number of properties per visual */
81 nprops
= (int) reply
.numProps
;
82 if (nprops
< __GLX_MIN_CONFIG_PROPS
) {
83 /* Huh? Not in protocol defined limits. Punt */
88 if (nprops
< (INT_MAX
/ __GLX_SIZE_CARD32
))
89 props
= Xmalloc(nprops
* __GLX_SIZE_CARD32
);
98 /* Allocate memory for our config structure */
99 if (nvisuals
< (INT_MAX
/ sizeof(__GLXvisualConfig
)))
100 config
= Xcalloc(nvisuals
, sizeof(__GLXvisualConfig
));
110 num_good_visuals
= 0;
112 /* Convert config structure into our format */
113 for (i
= 0; i
< nvisuals
; i
++) {
115 /* Read config structure */
116 _XRead(dpy
, (char *) props
, (nprops
* __GLX_SIZE_CARD32
));
118 /* fill in default values */
119 config
->visualRating
= GLX_NONE_EXT
;
120 config
->transparentPixel
= GLX_NONE_EXT
;
122 /* Copy in the first set of properties */
123 config
->vid
= props
[0];
124 config
->class = props
[1];
126 config
->rgba
= (Bool
) props
[2];
128 config
->redSize
= props
[3];
129 config
->greenSize
= props
[4];
130 config
->blueSize
= props
[5];
131 config
->alphaSize
= props
[6];
133 config
->accumRedSize
= props
[7];
134 config
->accumGreenSize
= props
[8];
135 config
->accumBlueSize
= props
[9];
136 config
->accumAlphaSize
= props
[10];
138 config
->doubleBuffer
= (Bool
) props
[11];
139 config
->stereo
= (Bool
) props
[12];
141 config
->bufferSize
= props
[13];
142 config
->depthSize
= props
[14];
143 config
->stencilSize
= props
[15];
145 config
->auxBuffers
= props
[16];
146 config
->level
= props
[17];
148 /* Process remaining properties */
150 for (j
= __GLX_MIN_CONFIG_PROPS
; j
< nprops
; j
+= 2) {
155 case GLX_SAMPLES_SGIS
:
156 config
->multiSampleSize
= value
;
158 case GLX_SAMPLE_BUFFERS_SGIS
:
159 config
->nMultiSampleBuffers
= value
;
162 case GLX_TRANSPARENT_TYPE_EXT
:
163 config
->transparentPixel
= value
;
165 case GLX_TRANSPARENT_INDEX_VALUE_EXT
:
166 config
->transparentIndex
= value
;
168 case GLX_TRANSPARENT_RED_VALUE_EXT
:
169 config
->transparentRed
= value
;
171 case GLX_TRANSPARENT_GREEN_VALUE_EXT
:
172 config
->transparentGreen
= value
;
174 case GLX_TRANSPARENT_BLUE_VALUE_EXT
:
175 config
->transparentBlue
= value
;
177 case GLX_TRANSPARENT_ALPHA_VALUE_EXT
:
178 config
->transparentAlpha
= value
;
181 case GLX_VISUAL_CAVEAT_EXT
:
182 config
->visualRating
= value
;
185 /* visualSelectGroup is an internal used property */
186 case GLX_VISUAL_SELECT_GROUP_SGIX
:
187 config
->visualSelectGroup
= value
;
191 /* Ignore properties we don't recognize */
197 // filter out overlay visuals (dmx does not support overlays)
199 if (config
->level
== 0) {
208 nvisuals
= num_good_visuals
;
211 for (i
= 0; i
< nvisuals
; i
++) {
212 /* XXX hack to fill-in mask info (need a better way to do this) */
214 XVisualInfo
*vis
, template;
217 template.screen
= screen
;
218 template.visualid
= config
->vid
;
219 vis
= XGetVisualInfo(dpy
, VisualScreenMask
| VisualIDMask
,
223 config
->redMask
= vis
->red_mask
;
224 config
->greenMask
= vis
->green_mask
;
225 config
->blueMask
= vis
->blue_mask
;
226 config
->alphaMask
= 0; /* XXX */
236 *nconfigs
= nvisuals
;
241 GetGLXFBConfigs(Display
* dpy
, int glxMajorOpcode
, int *nconfigs
)
243 xGLXGetFBConfigsReq
*req
;
244 xGLXGetFBConfigsReply reply
;
245 __GLXFBConfig
*config
, *fbconfigs
;
246 GLint i
, j
, numFBConfigs
, numAttribs
;
248 int screen
= DefaultScreen(dpy
);
249 int numValidConfigs
= 0;
251 /* Send the glXGetFBConfigs request */
253 GetReq(GLXGetFBConfigs
, req
);
254 req
->reqType
= glxMajorOpcode
;
255 req
->glxCode
= X_GLXGetFBConfigs
;
256 req
->screen
= screen
;
260 if (!_XReply(dpy
, (xReply
*) &reply
, 0, False
)) {
261 /* Something is busted. Punt. */
267 numFBConfigs
= (int) reply
.numFBConfigs
;
269 /* This screen does not support GL rendering */
275 numAttribs
= (int) reply
.numAttribs
;
282 if (numAttribs
< (INT_MAX
/ (2 * __GLX_SIZE_CARD32
)))
283 attrs
= Xmalloc(2 * numAttribs
* __GLX_SIZE_CARD32
);
292 /* Allocate memory for our config structure */
293 if (numFBConfigs
< (INT_MAX
/ sizeof(__GLXFBConfig
)))
294 config
= Xcalloc(numFBConfigs
, sizeof(__GLXFBConfig
));
305 /* Convert attribute list into our format */
306 for (i
= 0; i
< numFBConfigs
; i
++) {
308 /* Fill in default properties */
309 config
->transparentType
= GLX_NONE_EXT
;
310 config
->visualCaveat
= GLX_NONE_EXT
;
313 config
->minGreen
= 0.;
314 config
->maxGreen
= 1.;
315 config
->minBlue
= 0.;
316 config
->maxBlue
= 1.;
317 config
->minAlpha
= 0.;
318 config
->maxAlpha
= 1.;
320 /* Read attribute list */
321 _XRead(dpy
, (char *) attrs
, (2 * numAttribs
* __GLX_SIZE_CARD32
));
324 for (j
= 0; j
< numAttribs
; j
++) {
325 int attribute
= *p
++;
329 /* core attributes */
330 case GLX_FBCONFIG_ID
:
333 case GLX_BUFFER_SIZE
:
334 config
->indexBits
= value
;
337 config
->level
= value
;
339 case GLX_DOUBLEBUFFER
:
340 config
->doubleBufferMode
= value
;
343 config
->stereoMode
= value
;
345 case GLX_AUX_BUFFERS
:
346 config
->maxAuxBuffers
= value
;
349 config
->redBits
= value
;
352 config
->greenBits
= value
;
355 config
->blueBits
= value
;
358 config
->alphaBits
= value
;
361 config
->depthBits
= value
;
363 case GLX_STENCIL_SIZE
:
364 config
->stencilBits
= value
;
366 case GLX_ACCUM_RED_SIZE
:
367 config
->accumRedBits
= value
;
369 case GLX_ACCUM_GREEN_SIZE
:
370 config
->accumGreenBits
= value
;
372 case GLX_ACCUM_BLUE_SIZE
:
373 config
->accumBlueBits
= value
;
375 case GLX_ACCUM_ALPHA_SIZE
:
376 config
->accumAlphaBits
= value
;
378 case GLX_RENDER_TYPE
:
379 config
->renderType
= value
;
381 case GLX_DRAWABLE_TYPE
:
382 config
->drawableType
= value
;
384 case GLX_X_VISUAL_TYPE
:
385 config
->visualType
= value
;
387 case GLX_CONFIG_CAVEAT
:
388 config
->visualCaveat
= value
;
390 case GLX_TRANSPARENT_TYPE
:
391 config
->transparentType
= value
;
393 case GLX_TRANSPARENT_INDEX_VALUE
:
394 config
->transparentIndex
= value
;
396 case GLX_TRANSPARENT_RED_VALUE
:
397 config
->transparentRed
= value
;
399 case GLX_TRANSPARENT_GREEN_VALUE
:
400 config
->transparentGreen
= value
;
402 case GLX_TRANSPARENT_BLUE_VALUE
:
403 config
->transparentBlue
= value
;
405 case GLX_TRANSPARENT_ALPHA_VALUE
:
406 config
->transparentAlpha
= value
;
408 case GLX_MAX_PBUFFER_WIDTH
:
409 config
->maxPbufferWidth
= value
;
411 case GLX_MAX_PBUFFER_HEIGHT
:
412 config
->maxPbufferHeight
= value
;
414 case GLX_MAX_PBUFFER_PIXELS
:
415 config
->maxPbufferPixels
= value
;
418 config
->associatedVisualId
= value
;
421 /* visualSelectGroup is an internal used property */
422 case GLX_VISUAL_SELECT_GROUP_SGIX
:
423 config
->visualSelectGroup
= value
;
426 /* SGIS_multisample attributes */
427 case GLX_SAMPLES_SGIS
:
428 config
->multiSampleSize
= value
;
430 case GLX_SAMPLE_BUFFERS_SGIS
:
431 config
->nMultiSampleBuffers
= value
;
434 /* SGIX_pbuffer specific attributes */
435 case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX
:
436 config
->optimalPbufferWidth
= value
;
438 case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX
:
439 config
->optimalPbufferHeight
= value
;
443 /* Ignore attributes we don't recognize */
448 /* Fill in derived values */
449 config
->screen
= screen
;
451 /* The rgbMode should be true for any mode which has distinguishible
452 * R, G and B components
454 config
->rgbMode
= (config
->renderType
455 & (GLX_RGBA_BIT
| GLX_RGBA_FLOAT_BIT_ARB
456 | GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT
)) != 0;
457 config
->colorIndexMode
= !config
->rgbMode
;
459 config
->haveAccumBuffer
=
460 config
->accumRedBits
> 0 ||
461 config
->accumGreenBits
> 0 || config
->accumBlueBits
> 0;
462 /* Can't have alpha without color */
464 config
->haveDepthBuffer
= config
->depthBits
> 0;
465 config
->haveStencilBuffer
= config
->stencilBits
> 0;
467 /* overlay visuals are not valid for now */
468 if (!config
->level
) {
477 for (i
= 0; i
< numValidConfigs
; i
++) {
479 /* XXX hack to fill-in mask info (need a better way to do this) */
480 if (config
->associatedVisualId
!= 0) {
481 XVisualInfo
*vis
, template;
484 template.screen
= screen
;
485 template.visualid
= config
->associatedVisualId
;
486 vis
= XGetVisualInfo(dpy
, VisualScreenMask
| VisualIDMask
,
490 config
->redMask
= (GLuint
) vis
->red_mask
;
491 config
->greenMask
= (GLuint
) vis
->green_mask
;
492 config
->blueMask
= (GLuint
) vis
->blue_mask
;
493 config
->alphaMask
= 0; /* XXX */
504 *nconfigs
= numValidConfigs
;
509 GetGLXVisualConfigsFromFBConfigs(__GLXFBConfig
* fbconfigs
, int nfbconfigs
,
510 XVisualInfo
* visuals
, int nvisuals
,
511 __GLXvisualConfig
* glxConfigs
,
512 int nGlxConfigs
, int *nconfigs
)
514 __GLXvisualConfig
*configs
= NULL
;
517 if (!fbconfigs
|| !nfbconfigs
|| !nconfigs
)
521 /* Allocate memory for our config structure */
522 configs
= (__GLXvisualConfig
*)
523 Xmalloc(nfbconfigs
* sizeof(__GLXvisualConfig
));
527 memset(configs
, 0, nfbconfigs
* sizeof(__GLXvisualConfig
));
529 for (i
= 0; i
< nfbconfigs
; i
++) {
530 __GLXFBConfig
*fbcfg
= &fbconfigs
[i
];
532 if (fbcfg
->associatedVisualId
> 0) {
533 __GLXvisualConfig
*cfg
= configs
+ (*nconfigs
);
535 XVisualInfo
*vinfo
= NULL
;
537 for (j
= 0; j
< nvisuals
; j
++) {
538 if (visuals
[j
].visualid
== fbcfg
->associatedVisualId
) {
546 /* skip 16 bit colormap visuals */
547 if (vinfo
->depth
== 16 &&
548 vinfo
->class != TrueColor
&& vinfo
->class != DirectColor
) {
555 * if the same visualid exists in the glx configs,
556 * copy the glx attributes from the glx config
558 for (j
= 0; j
< nGlxConfigs
; j
++) {
559 if (glxConfigs
[j
].vid
== vinfo
->visualid
)
562 if (j
< nGlxConfigs
) {
563 memcpy(cfg
, &glxConfigs
[j
], sizeof(__GLXvisualConfig
));
568 * make glx attributes from the FB config attributes
570 cfg
->vid
= fbcfg
->associatedVisualId
;
571 cfg
->class = vinfo
->class;
572 cfg
->rgba
= !(fbcfg
->renderType
& GLX_COLOR_INDEX_BIT_SGIX
);
573 cfg
->redSize
= fbcfg
->redBits
;
574 cfg
->greenSize
= fbcfg
->greenBits
;
575 cfg
->blueSize
= fbcfg
->blueBits
;
576 cfg
->alphaSize
= fbcfg
->alphaBits
;
577 cfg
->redMask
= fbcfg
->redMask
;
578 cfg
->greenMask
= fbcfg
->greenMask
;
579 cfg
->blueMask
= fbcfg
->blueMask
;
580 cfg
->alphaMask
= fbcfg
->alphaMask
;
581 cfg
->accumRedSize
= fbcfg
->accumRedBits
;
582 cfg
->accumGreenSize
= fbcfg
->accumGreenBits
;
583 cfg
->accumBlueSize
= fbcfg
->accumBlueBits
;
584 cfg
->accumAlphaSize
= fbcfg
->accumAlphaBits
;
585 cfg
->doubleBuffer
= fbcfg
->doubleBufferMode
;
586 cfg
->stereo
= fbcfg
->stereoMode
;
587 if (vinfo
->class == TrueColor
|| vinfo
->class == DirectColor
) {
588 cfg
->bufferSize
= (fbcfg
->rgbMode
? (fbcfg
->redBits
+
595 cfg
->bufferSize
= vinfo
->depth
;
597 cfg
->depthSize
= fbcfg
->depthBits
;
598 cfg
->stencilSize
= fbcfg
->stencilBits
;
599 cfg
->auxBuffers
= fbcfg
->maxAuxBuffers
;
600 cfg
->level
= fbcfg
->level
;
601 cfg
->visualRating
= fbcfg
->visualCaveat
;
602 cfg
->transparentPixel
= fbcfg
->transparentType
;
603 cfg
->transparentRed
= fbcfg
->transparentRed
;
604 cfg
->transparentGreen
= fbcfg
->transparentGreen
;
605 cfg
->transparentBlue
= fbcfg
->transparentBlue
;
606 cfg
->transparentAlpha
= fbcfg
->transparentAlpha
;
607 cfg
->transparentIndex
= fbcfg
->transparentIndex
;
608 cfg
->multiSampleSize
= fbcfg
->multiSampleSize
;
609 cfg
->nMultiSampleBuffers
= fbcfg
->nMultiSampleBuffers
;
610 cfg
->visualSelectGroup
= fbcfg
->visualSelectGroup
;