1 /* xscreensaver, Copyright (c) 1999-2007 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 # ifdef GLX_VISUAL_CAVEAT_EXT
146 if (!glXGetConfig (dpy, vi_out, GLX_VISUAL_CAVEAT_EXT, &value) &&
147 value != GLX_NONE_EXT)
148 # ifdef GLX_NON_CONFORMANT_EXT
149 printf (" GLX rating: %s\n",
150 (value == GLX_NONE_EXT ? "none" :
151 value == GLX_SLOW_VISUAL_EXT ? "slow" :
152 value == GLX_NON_CONFORMANT_EXT ? "non-conformant" :
155 printf (" GLX rating: %s\n",
156 (value == GLX_NONE_EXT ? "none" :
157 value == GLX_SLOW_VISUAL_EXT ? "slow" :
159 # endif /* GLX_NON_CONFORMANT_EXT */
160 # endif /* GLX_VISUAL_CAVEAT_EXT */
162 if (!glXGetConfig (dpy, vi_out, GLX_DOUBLEBUFFER, &value))
163 printf (" GLX double-buffer: %s\n", (value ? "yes" : "no"));
165 if (!glXGetConfig (dpy, vi_out, GLX_STEREO, &value) &&
167 printf (" GLX stereo: %s\n", (value ? "yes" : "no"));
169 if (!glXGetConfig (dpy, vi_out, GLX_AUX_BUFFERS, &value) &&
171 printf (" GLX aux buffers: %d\n", value);
173 if (!glXGetConfig (dpy, vi_out, GLX_DEPTH_SIZE, &value))
174 printf (" GLX depth size: %d\n", value);
176 if (!glXGetConfig (dpy, vi_out, GLX_STENCIL_SIZE, &value) &&
178 printf (" GLX stencil size: %d\n", value);
180 # ifdef GLX_SAMPLE_BUFFERS_SGIS
181 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLE_BUFFERS_SGIS, &value) &&
185 if (!glXGetConfig (dpy, vi_out, GLX_SAMPLES_SGIS, &value))
186 printf (" GLX multisamplers: %d (%d)\n", bufs, value);
188 # endif /* GLX_SAMPLE_BUFFERS_SGIS */
190 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_TYPE_EXT, &value) &&
191 value != GLX_NONE_EXT)
193 if (value == GLX_NONE_EXT)
194 printf (" GLX transparency: none\n");
195 else if (value == GLX_TRANSPARENT_INDEX_EXT)
197 if (!glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_INDEX_VALUE_EXT,
199 printf (" GLX transparency: indexed (%d)\n", value);
201 else if (value == GLX_TRANSPARENT_RGB_EXT)
203 int r=0, g=0, b=0, a=0;
204 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_RED_VALUE_EXT, &r);
205 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g);
206 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_BLUE_VALUE_EXT, &b);
207 glXGetConfig (dpy, vi_out, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a);
208 printf (" GLX transparency: RGBA (%2d, %2d, %2d, %2d)\n",
218 validate_gl_visual (FILE *out, Screen *screen, const char *window_desc,
225 Display *dpy = DisplayOfScreen (screen);
226 XVisualInfo vi_in, *vi_out;
230 vi_in.screen = screen_number (screen);
231 vi_in.visualid = XVisualIDFromVisual (visual);
232 vi_out = XGetVisualInfo (dpy, (VisualScreenMask | VisualIDMask),
234 if (! vi_out) abort ();
236 status = glXGetConfig (dpy, vi_out, GLX_USE_GL, &value);
238 id = (unsigned int) vi_out->visualid;
239 XFree ((char *) vi_out);
241 if (status == GLX_NO_EXTENSION)
243 fprintf (out, "%s: display \"%s\" does not support the GLX extension.\n",
244 progname, DisplayString (dpy));
247 else if (status == GLX_BAD_VISUAL || value == False)
250 "%s: %s's visual 0x%x does not support the GLX extension.\n",
251 progname, window_desc, id);
261 fprintf (out, "%s: GL support was not compiled in to this program.\n",
265 #endif /* !HAVE_GL */