1 /* xscreensaver, Copyright (c) 1999-2009 by Jamie Zawinski <jwz@jwz.org>
3 * Permission to use, copy, modify, distribute, and sell this software and its
4 * documentation for any purpose is hereby granted without fee, provided that
5 * the above copyright notice appear in all copies and that both that
6 * copyright notice and this permission notice appear in supporting
7 * documentation. No representations are made about the suitability of this
8 * software for any purpose. It is provided "as is" without express or
12 /* This file contains code for picking the best visual for GL programs by
13 actually asking the GL library to figure it out for us. The code in
14 visual.c might do a good job of this on most systems, but not on most
15 high end 3D cards (e.g., Silicon Graphics or nVidia.)
17 There exists information about visuals which is available to GL, but
18 which is not available via Xlib calls. So the only way to know
19 which visual to use (other than impirically) is to actually call
31 extern char *progname;
34 get_gl_visual (Screen *screen)
37 Display *dpy = DisplayOfScreen (screen);
38 int screen_num = screen_number (screen);
40 # define R GLX_RED_SIZE
41 # define G GLX_GREEN_SIZE
42 # define B GLX_BLUE_SIZE
43 # define A GLX_ALPHA_SIZE
44 # define D GLX_DEPTH_SIZE
45 # define I GLX_BUFFER_SIZE
46 # define DB GLX_DOUBLEBUFFER
47 # define ST GLX_STENCIL_SIZE
50 { GLX_RGBA, R,8, G,8, B,8, A,8, D,8, DB, ST,1, 0 }, /* rgb double, stencil */
51 { GLX_RGBA, R,8, G,8, B,8, D,8, DB, ST,1, 0 }, /* rgb double, stencil */
52 { GLX_RGBA, R,4, G,4, B,4, D,4, DB, ST,1, 0 },
53 { GLX_RGBA, R,2, G,2, B,2, D,2, DB, ST,1, 0 },
54 { GLX_RGBA, R,8, G,8, B,8, D,8, DB, 0 }, /* rgb double */
55 { GLX_RGBA, R,4, G,4, B,4, D,4, DB, 0 },
56 { GLX_RGBA, R,2, G,2, B,2, D,2, DB, 0 },
57 { GLX_RGBA, R,8, G,8, B,8, D,8, 0 }, /* rgb single */
58 { GLX_RGBA, R,4, G,4, B,4, D,4, 0 },
59 { GLX_RGBA, R,2, G,2, B,2, D,2, 0 },
60 { I, 8, D,8, DB, 0 }, /* cmap double */
62 { I, 8, D,8, 0 }, /* cmap single */
64 { GLX_RGBA, R,1, G,1, B,1, D,1, 0 } /* monochrome */
68 for (i = 0; i < sizeof(attrs)/sizeof(*attrs); i++)
70 XVisualInfo *vi = glXChooseVisual (dpy, screen_num, attrs[i]);
73 Visual *v = vi->visual;
75 /* describe_gl_visual (stderr, screen, v, False); */
86 describe_gl_visual (FILE *f, Screen *screen, Visual *visual,
89 describe_visual (f, screen, visual, private_cmap_p);
96 Display *dpy = DisplayOfScreen (screen);
97 XVisualInfo vi_in, *vi_out;
100 vi_in.screen = screen_number (screen);
101 vi_in.visualid = XVisualIDFromVisual (visual);
102 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
104 if (! vi_out) abort ();
106 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
108 if (status == GLX_NO_EXTENSION)
109 /* dpy does not support the GLX extension. */
112 if (status == GLX_BAD_VISUAL || value == False)
113 /* this visual does not support GLX. */
116 if (!glXGetConfig (dpy, vi_out, GLX_LEVEL, &value) &&
118 printf (" GLX level: %d\n", value);
120 if (!glXGetConfig (dpy, vi_out, GLX_RGBA, &value) && value)
122 int r=0, g=0, b=0, a=0;
123 glXGetConfig (dpy, vi_out, GLX_RED_SIZE, &r);
124 glXGetConfig (dpy, vi_out, GLX_GREEN_SIZE, &g);
125 glXGetConfig (dpy, vi_out, GLX_BLUE_SIZE, &b);
126 glXGetConfig (dpy, vi_out, GLX_ALPHA_SIZE, &a);
127 printf (" GLX type: RGBA (%2d, %2d, %2d, %2d)\n",
131 glXGetConfig (dpy, vi_out, GLX_ACCUM_RED_SIZE, &r);
132 glXGetConfig (dpy, vi_out, GLX_ACCUM_GREEN_SIZE, &g);
133 glXGetConfig (dpy, vi_out, GLX_ACCUM_BLUE_SIZE, &b);
134 glXGetConfig (dpy, vi_out, GLX_ACCUM_ALPHA_SIZE, &a);
135 printf (" GLX accum: RGBA (%2d, %2d, %2d, %2d)\n",
141 glXGetConfig (dpy, vi_out, GLX_BUFFER_SIZE, &value);
142 printf (" GLX type: indexed (%d)\n", value);
145 # ifndef GLX_NONE_EXT /* Hooray for gratuitious name changes. */
146 # define GLX_NONE_EXT GLX_NONE
147 # define GLX_TRANSPARENT_TYPE_EXT GLX_TRANSPARENT_TYPE
148 # define GLX_TRANSPARENT_INDEX_EXT GLX_TRANSPARENT_INDEX
149 # define GLX_TRANSPARENT_INDEX_VALUE_EXT GLX_TRANSPARENT_INDEX_VALUE
150 # define GLX_TRANSPARENT_RGB_EXT GLX_TRANSPARENT_RGB
151 # define GLX_TRANSPARENT_RED_VALUE_EXT GLX_TRANSPARENT_RED_VALUE
152 # define GLX_TRANSPARENT_GREEN_VALUE_EXT GLX_TRANSPARENT_GREEN_VALUE
153 # define GLX_TRANSPARENT_BLUE_VALUE_EXT GLX_TRANSPARENT_BLUE_VALUE
154 # define GLX_TRANSPARENT_ALPHA_VALUE_EXT GLX_TRANSPARENT_ALPHA_VALUE
157 # ifdef GLX_VISUAL_CAVEAT_EXT
158 if (!glXGetConfig (dpy, vi_out, GLX_VISUAL_CAVEAT_EXT, &value) &&
159 value != GLX_NONE_EXT)
160 # ifdef GLX_NON_CONFORMANT_EXT
161 printf (" GLX rating: %s\n",
162 (value == GLX_NONE_EXT ? "none" :
163 value == GLX_SLOW_VISUAL_EXT ? "slow" :
164 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
167 printf (" GLX rating: %s\n",
168 (value == GLX_NONE_EXT ? "none" :
169 value == GLX_SLOW_VISUAL_EXT ? "slow" :
171 # endif /* GLX_NON_CONFORMANT_EXT */
172 # endif /* GLX_VISUAL_CAVEAT_EXT */
174 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
175 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
177 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
179 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
181 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
183 printf (" GLX aux buffers: %d\n", value);
185 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
186 printf (" GLX depth size: %d\n", value);
188 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
190 printf (" GLX stencil size: %d\n", value);
192 # ifdef GLX_SAMPLE_BUFFERS_SGIS
193 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
197 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLES_SGIS, &value))
198 printf (" GLX multisamplers: %d (%d)\n", bufs, value);
200 # endif /* GLX_SAMPLE_BUFFERS_SGIS */
202 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
203 value != GLX_NONE_EXT)
205 if (value == GLX_NONE_EXT)
206 printf (" GLX transparency: none\n");
207 else if (value == GLX_TRANSPARENT_INDEX_EXT)
209 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
211 printf (" GLX transparency: indexed (%d)\n", value);
213 else if (value == GLX_TRANSPARENT_RGB_EXT)
215 int r=0, g=0, b=0, a=0;
216 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
217 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
218 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
219 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
220 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
230 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
237 Display *dpy = DisplayOfScreen (screen);
238 XVisualInfo vi_in, *vi_out;
242 vi_in.screen = screen_number (screen);
243 vi_in.visualid = XVisualIDFromVisual (visual);
244 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
246 if (! vi_out) abort ();
248 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
250 id = (unsigned int) vi_out->visualid;
251 XFree ((char *) vi_out);
253 if (status == GLX_NO_EXTENSION)
255 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
256 progname, DisplayString (dpy));
259 else if (status == GLX_BAD_VISUAL || value == False)
262 "%s: %s's visual 0x%x does not support the GLX extension.\n",
263 progname, window_desc, id);
273 fprintf (out, "%s: GL support was not compiled in to this program.\n",
277 #endif /* !HAVE_GL */