1 | /* $Id: glut_dstr.c,v 1.2 2000-02-09 08:46:09 jeroen Exp $ */
|
---|
2 | /* Copyright (c) Mark J. Kilgard, 1997. */
|
---|
3 |
|
---|
4 | /* This program is freely distributable without licensing fees
|
---|
5 | and is provided without guarantee or warrantee expressed or
|
---|
6 | implied. This program is -not- in the public domain. */
|
---|
7 |
|
---|
8 | #include <assert.h>
|
---|
9 | #include <stdlib.h>
|
---|
10 | #include <stdio.h>
|
---|
11 | #include <string.h>
|
---|
12 |
|
---|
13 | #include "glutint.h"
|
---|
14 | #if defined(__WIN32OS2__)
|
---|
15 | #include "pfddefs.h"
|
---|
16 | #endif
|
---|
17 |
|
---|
18 | /* glxcaps matches the criteria macros listed in glutint.h, but
|
---|
19 | only list the first set (those that correspond to GLX visual
|
---|
20 | attributes). */
|
---|
21 | static int glxcap[NUM_GLXCAPS] =
|
---|
22 | {
|
---|
23 | GLX_RGBA,
|
---|
24 | GLX_BUFFER_SIZE,
|
---|
25 | GLX_DOUBLEBUFFER,
|
---|
26 | GLX_STEREO,
|
---|
27 | GLX_AUX_BUFFERS,
|
---|
28 | GLX_RED_SIZE,
|
---|
29 | GLX_GREEN_SIZE,
|
---|
30 | GLX_BLUE_SIZE,
|
---|
31 | GLX_ALPHA_SIZE,
|
---|
32 | GLX_DEPTH_SIZE,
|
---|
33 | GLX_STENCIL_SIZE,
|
---|
34 | GLX_ACCUM_RED_SIZE,
|
---|
35 | GLX_ACCUM_GREEN_SIZE,
|
---|
36 | GLX_ACCUM_BLUE_SIZE,
|
---|
37 | GLX_ACCUM_ALPHA_SIZE,
|
---|
38 | GLX_LEVEL,
|
---|
39 | };
|
---|
40 |
|
---|
41 | #ifdef TEST
|
---|
42 |
|
---|
43 | #if !defined(_WIN32) && !defined(__WIN32OS2__)
|
---|
44 | char *__glutProgramName = "dstr";
|
---|
45 | Display *__glutDisplay;
|
---|
46 | int __glutScreen;
|
---|
47 | XVisualInfo *(*__glutDetermineVisualFromString) (char *string, Bool * treatAsSingle,
|
---|
48 | Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc) = NULL;
|
---|
49 | char *__glutDisplayString = NULL;
|
---|
50 | #endif
|
---|
51 | static int verbose = 0;
|
---|
52 |
|
---|
53 | static char *compstr[] =
|
---|
54 | {
|
---|
55 | "none", "=", "!=", "<=", ">=", ">", "<", "~"
|
---|
56 | };
|
---|
57 | static char *capstr[] =
|
---|
58 | {
|
---|
59 | "rgba", "bufsize", "double", "stereo", "auxbufs", "red", "green", "blue", "alpha",
|
---|
60 | "depth", "stencil", "acred", "acgreen", "acblue", "acalpha", "level", "xvisual",
|
---|
61 | "transparent", "samples", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor",
|
---|
62 | "xtruecolor", "xdirectcolor", "slow", "conformant", "num"
|
---|
63 | };
|
---|
64 |
|
---|
65 | static void
|
---|
66 | printCriteria(Criterion * criteria, int ncriteria)
|
---|
67 | {
|
---|
68 | int i;
|
---|
69 | printf("Criteria: %d\n", ncriteria);
|
---|
70 | for (i = 0; i < ncriteria; i++) {
|
---|
71 | printf(" %s %s %d\n",
|
---|
72 | capstr[criteria[i].capability],
|
---|
73 | compstr[criteria[i].comparison],
|
---|
74 | criteria[i].value);
|
---|
75 | }
|
---|
76 | }
|
---|
77 |
|
---|
78 | #endif /* TEST */
|
---|
79 |
|
---|
80 | static int isMesaGLX = -1;
|
---|
81 |
|
---|
82 | static int
|
---|
83 | determineMesaGLX(void)
|
---|
84 | {
|
---|
85 | #ifdef GLX_VERSION_1_1
|
---|
86 | const char *vendor, *version, *ch;
|
---|
87 |
|
---|
88 | vendor = glXGetClientString(__glutDisplay, GLX_VENDOR);
|
---|
89 | if (!strcmp(vendor, "Brian Paul")) {
|
---|
90 | version = glXGetClientString(__glutDisplay, GLX_VERSION);
|
---|
91 | for (ch = version; *ch != ' ' && *ch != '\0'; ch++);
|
---|
92 | for (; *ch == ' ' && *ch != '\0'; ch++);
|
---|
93 |
|
---|
94 | #define MESA_NAME "Mesa " /* Trailing space is intentional. */
|
---|
95 |
|
---|
96 | if (!strncmp(MESA_NAME, ch, sizeof(MESA_NAME) - 1)) {
|
---|
97 | return 1;
|
---|
98 | }
|
---|
99 | }
|
---|
100 | #else
|
---|
101 | /* Recent versions for Mesa should support GLX 1.1 and
|
---|
102 | therefore glXGetClientString. If we get into this case,
|
---|
103 | we would be compiling against a true OpenGL not supporting
|
---|
104 | GLX 1.1, and the resulting compiled library won't work well
|
---|
105 | with Mesa then. */
|
---|
106 | #endif
|
---|
107 | return 0;
|
---|
108 | }
|
---|
109 |
|
---|
110 | static XVisualInfo **
|
---|
111 | getMesaVisualList(int *n)
|
---|
112 | {
|
---|
113 | XVisualInfo **vlist, *vinfo;
|
---|
114 | int attribs[23];
|
---|
115 | int i, x, cnt;
|
---|
116 |
|
---|
117 | vlist = (XVisualInfo **) malloc((32 + 16) * sizeof(XVisualInfo *));
|
---|
118 | if (!vlist)
|
---|
119 | __glutFatalError("out of memory.");
|
---|
120 |
|
---|
121 | cnt = 0;
|
---|
122 | for (i = 0; i < 32; i++) {
|
---|
123 | x = 0;
|
---|
124 | attribs[x] = GLX_RGBA;
|
---|
125 | x++;
|
---|
126 | attribs[x] = GLX_RED_SIZE;
|
---|
127 | x++;
|
---|
128 | attribs[x] = 1;
|
---|
129 | x++;
|
---|
130 | attribs[x] = GLX_GREEN_SIZE;
|
---|
131 | x++;
|
---|
132 | attribs[x] = 1;
|
---|
133 | x++;
|
---|
134 | attribs[x] = GLX_BLUE_SIZE;
|
---|
135 | x++;
|
---|
136 | attribs[x] = 1;
|
---|
137 | x++;
|
---|
138 | if (i & 1) {
|
---|
139 | attribs[x] = GLX_DEPTH_SIZE;
|
---|
140 | x++;
|
---|
141 | attribs[x] = 1;
|
---|
142 | x++;
|
---|
143 | }
|
---|
144 | if (i & 2) {
|
---|
145 | attribs[x] = GLX_STENCIL_SIZE;
|
---|
146 | x++;
|
---|
147 | attribs[x] = 1;
|
---|
148 | x++;
|
---|
149 | }
|
---|
150 | if (i & 4) {
|
---|
151 | attribs[x] = GLX_ACCUM_RED_SIZE;
|
---|
152 | x++;
|
---|
153 | attribs[x] = 1;
|
---|
154 | x++;
|
---|
155 | attribs[x] = GLX_ACCUM_GREEN_SIZE;
|
---|
156 | x++;
|
---|
157 | attribs[x] = 1;
|
---|
158 | x++;
|
---|
159 | attribs[x] = GLX_ACCUM_BLUE_SIZE;
|
---|
160 | x++;
|
---|
161 | attribs[x] = 1;
|
---|
162 | x++;
|
---|
163 | }
|
---|
164 | if (i & 8) {
|
---|
165 | attribs[x] = GLX_ALPHA_SIZE;
|
---|
166 | x++;
|
---|
167 | attribs[x] = 1;
|
---|
168 | x++;
|
---|
169 | if (i & 4) {
|
---|
170 | attribs[x] = GLX_ACCUM_ALPHA_SIZE;
|
---|
171 | x++;
|
---|
172 | attribs[x] = 1;
|
---|
173 | x++;
|
---|
174 | }
|
---|
175 | }
|
---|
176 | if (i & 16) {
|
---|
177 | attribs[x] = GLX_DOUBLEBUFFER;
|
---|
178 | x++;
|
---|
179 | }
|
---|
180 | attribs[x] = None;
|
---|
181 | x++;
|
---|
182 | assert(x <= sizeof(attribs) / sizeof(attribs[0]));
|
---|
183 | vinfo = glXChooseVisual(__glutDisplay, __glutScreen, attribs);
|
---|
184 | if (vinfo) {
|
---|
185 | vlist[cnt] = vinfo;
|
---|
186 | cnt++;
|
---|
187 | }
|
---|
188 | }
|
---|
189 | for (i = 0; i < 16; i++) {
|
---|
190 | x = 0;
|
---|
191 | if (i & 1) {
|
---|
192 | attribs[x] = GLX_DEPTH_SIZE;
|
---|
193 | x++;
|
---|
194 | attribs[x] = 1;
|
---|
195 | x++;
|
---|
196 | }
|
---|
197 | if (i & 2) {
|
---|
198 | attribs[x] = GLX_STENCIL_SIZE;
|
---|
199 | x++;
|
---|
200 | attribs[x] = 1;
|
---|
201 | x++;
|
---|
202 | }
|
---|
203 | if (i & 4) {
|
---|
204 | attribs[x] = GLX_DOUBLEBUFFER;
|
---|
205 | x++;
|
---|
206 | }
|
---|
207 | if (i & 8) {
|
---|
208 | attribs[x] = GLX_LEVEL;
|
---|
209 | x++;
|
---|
210 | attribs[x] = 1;
|
---|
211 | x++;
|
---|
212 | #if defined(GLX_TRANSPARENT_TYPE_EXT) && defined(GLX_TRANSPARENT_INDEX_EXT)
|
---|
213 | attribs[x] = GLX_TRANSPARENT_TYPE_EXT;
|
---|
214 | x++;
|
---|
215 | attribs[x] = GLX_TRANSPARENT_INDEX_EXT;
|
---|
216 | x++;
|
---|
217 | #endif
|
---|
218 | }
|
---|
219 | attribs[x] = None;
|
---|
220 | x++;
|
---|
221 | assert(x <= sizeof(attribs) / sizeof(attribs[0]));
|
---|
222 | vinfo = glXChooseVisual(__glutDisplay, __glutScreen, attribs);
|
---|
223 | if (vinfo) {
|
---|
224 | vlist[cnt] = vinfo;
|
---|
225 | cnt++;
|
---|
226 | }
|
---|
227 | }
|
---|
228 |
|
---|
229 | *n = cnt;
|
---|
230 | return vlist;
|
---|
231 | }
|
---|
232 |
|
---|
233 | static FrameBufferMode *
|
---|
234 | loadVisuals(int *nitems_return)
|
---|
235 | {
|
---|
236 | XVisualInfo *vinfo, **vlist, _template;
|
---|
237 | FrameBufferMode *fbmodes, *mode;
|
---|
238 | int n, i, j, rc, glcapable;
|
---|
239 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
---|
240 | int multisample;
|
---|
241 | #endif
|
---|
242 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
|
---|
243 | int visual_info;
|
---|
244 | #endif
|
---|
245 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating)
|
---|
246 | int visual_rating;
|
---|
247 | #endif
|
---|
248 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
---|
249 | int fbconfig;
|
---|
250 | #endif
|
---|
251 |
|
---|
252 | isMesaGLX = determineMesaGLX();
|
---|
253 | if (isMesaGLX) {
|
---|
254 | vlist = getMesaVisualList(&n);
|
---|
255 | } else {
|
---|
256 | #if !defined(_WIN32) && !defined(__WIN32OS2__)
|
---|
257 | _template.screen = __glutScreen;
|
---|
258 | vinfo = XGetVisualInfo(__glutDisplay, VisualScreenMask, &_template, &n);
|
---|
259 | #else
|
---|
260 | vinfo = XGetVisualInfo(__glutDisplay, 0, &_template, &n);
|
---|
261 | #endif
|
---|
262 | if (vinfo == NULL) {
|
---|
263 | *nitems_return = 0;
|
---|
264 | return NULL;
|
---|
265 | }
|
---|
266 | assert(n > 0);
|
---|
267 |
|
---|
268 | /* Make an array of XVisualInfo* pointers to help the Mesa
|
---|
269 | case because each glXChooseVisual call returns a
|
---|
270 | distinct XVisualInfo*, not a handy array like
|
---|
271 | XGetVisualInfo. (Mesa expects us to return the _exact_
|
---|
272 | pointer returned by glXChooseVisual so we could not just
|
---|
273 | copy the returned structure.) */
|
---|
274 | vlist = (XVisualInfo **) malloc(n * sizeof(XVisualInfo *));
|
---|
275 | if (!vlist)
|
---|
276 | __glutFatalError("out of memory.");
|
---|
277 | for (i = 0; i < n; i++) {
|
---|
278 | vlist[i] = &vinfo[i];
|
---|
279 | }
|
---|
280 | }
|
---|
281 |
|
---|
282 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
---|
283 | multisample = __glutIsSupportedByGLX("GLX_SGIS_multisample");
|
---|
284 | #endif
|
---|
285 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
|
---|
286 | visual_info = __glutIsSupportedByGLX("GLX_EXT_visual_info");
|
---|
287 | #endif
|
---|
288 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating)
|
---|
289 | visual_rating = __glutIsSupportedByGLX("GLX_EXT_visual_rating");
|
---|
290 | #endif
|
---|
291 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
---|
292 | fbconfig = __glutIsSupportedByGLX("GLX_SGIX_fbconfig");
|
---|
293 | #endif
|
---|
294 |
|
---|
295 | fbmodes = (FrameBufferMode *) malloc(n * sizeof(FrameBufferMode));
|
---|
296 | if (fbmodes == NULL) {
|
---|
297 | *nitems_return = -1;
|
---|
298 | return NULL;
|
---|
299 | }
|
---|
300 | for (i = 0; i < n; i++) {
|
---|
301 | mode = &fbmodes[i];
|
---|
302 | mode->vi = vlist[i];
|
---|
303 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
---|
304 | mode->fbc = NULL;
|
---|
305 | #endif
|
---|
306 | rc = glXGetConfig(__glutDisplay, vlist[i], GLX_USE_GL, &glcapable);
|
---|
307 | if (rc == 0 && glcapable) {
|
---|
308 | mode->valid = 1; /* Assume the best until proven
|
---|
309 | otherwise. */
|
---|
310 | for (j = 0; j < NUM_GLXCAPS; j++) {
|
---|
311 | rc = glXGetConfig(__glutDisplay, vlist[i], glxcap[j], &mode->cap[j]);
|
---|
312 | if (rc != 0) {
|
---|
313 | mode->valid = 0;
|
---|
314 | }
|
---|
315 | }
|
---|
316 | #if defined(_WIN32) || defined(__WIN32OS2__)
|
---|
317 | mode->cap[XVISUAL] = ChoosePixelFormat(XHDC, vlist[i]);
|
---|
318 | #else
|
---|
319 | mode->cap[XVISUAL] = (int) vlist[i]->visualid;
|
---|
320 | #endif
|
---|
321 | mode->cap[XSTATICGRAY] = 0;
|
---|
322 | mode->cap[XGRAYSCALE] = 0;
|
---|
323 | mode->cap[XSTATICCOLOR] = 0;
|
---|
324 | mode->cap[XPSEUDOCOLOR] = 0;
|
---|
325 | mode->cap[XTRUECOLOR] = 0;
|
---|
326 | mode->cap[XDIRECTCOLOR] = 0;
|
---|
327 | #if !defined(_WIN32) && !defined(__WIN32OS2__)
|
---|
328 | #if defined(__cplusplus) || defined(c_plusplus)
|
---|
329 | switch (vlist[i]->c_class) {
|
---|
330 | #else
|
---|
331 | switch (vlist[i]->class) {
|
---|
332 | #endif
|
---|
333 | case StaticGray:
|
---|
334 | mode->cap[XSTATICGRAY] = 1;
|
---|
335 | break;
|
---|
336 | case GrayScale:
|
---|
337 | mode->cap[XGRAYSCALE] = 1;
|
---|
338 | break;
|
---|
339 | case StaticColor:
|
---|
340 | mode->cap[XSTATICCOLOR] = 1;
|
---|
341 | break;
|
---|
342 | case PseudoColor:
|
---|
343 | mode->cap[XPSEUDOCOLOR] = 1;
|
---|
344 | break;
|
---|
345 | case TrueColor:
|
---|
346 | mode->cap[XTRUECOLOR] = 1;
|
---|
347 | break;
|
---|
348 | case DirectColor:
|
---|
349 | mode->cap[XDIRECTCOLOR] = 1;
|
---|
350 | break;
|
---|
351 | }
|
---|
352 | #endif
|
---|
353 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating)
|
---|
354 | if (visual_rating) {
|
---|
355 | int rating;
|
---|
356 |
|
---|
357 | /* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0
|
---|
358 | 564 for Alpha did not properly define GLX_VISUAL_CAVEAT_EXT
|
---|
359 | in <GL/glx.h> despite claiming to support
|
---|
360 | GLX_EXT_visual_rating. */
|
---|
361 | #ifndef GLX_VISUAL_CAVEAT_EXT
|
---|
362 | #define GLX_VISUAL_CAVEAT_EXT 0x20
|
---|
363 | #endif
|
---|
364 |
|
---|
365 | rc = glXGetConfig(__glutDisplay,
|
---|
366 | vlist[i], GLX_VISUAL_CAVEAT_EXT, &rating);
|
---|
367 | if (rc != 0) {
|
---|
368 | mode->cap[SLOW] = 0;
|
---|
369 | mode->cap[CONFORMANT] = 1;
|
---|
370 | } else {
|
---|
371 | switch (rating) {
|
---|
372 | case GLX_SLOW_VISUAL_EXT:
|
---|
373 | mode->cap[SLOW] = 1;
|
---|
374 | mode->cap[CONFORMANT] = 1;
|
---|
375 | break;
|
---|
376 |
|
---|
377 | /* IRIX 5.3 for the R10K Indigo2 may have shipped without this
|
---|
378 | properly defined in /usr/include/GL/glxtokens.h */
|
---|
379 | #ifndef GLX_NON_CONFORMANT_VISUAL_EXT
|
---|
380 | #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
|
---|
381 | #endif
|
---|
382 |
|
---|
383 | case GLX_NON_CONFORMANT_VISUAL_EXT:
|
---|
384 | mode->cap[SLOW] = 0;
|
---|
385 | mode->cap[CONFORMANT] = 0;
|
---|
386 | break;
|
---|
387 | case GLX_NONE_EXT:
|
---|
388 | default: /* XXX Hopefully this is a good default
|
---|
389 | assumption. */
|
---|
390 | mode->cap[SLOW] = 0;
|
---|
391 | mode->cap[CONFORMANT] = 1;
|
---|
392 | break;
|
---|
393 | }
|
---|
394 | }
|
---|
395 | } else {
|
---|
396 | mode->cap[TRANSPARENT] = 0;
|
---|
397 | }
|
---|
398 | #else
|
---|
399 | mode->cap[SLOW] = 0;
|
---|
400 | mode->cap[CONFORMANT] = 1;
|
---|
401 | #endif
|
---|
402 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
|
---|
403 | if (visual_info) {
|
---|
404 | int transparent;
|
---|
405 |
|
---|
406 | /* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0
|
---|
407 | 564 for Alpha did not properly define
|
---|
408 | GLX_TRANSPARENT_TYPE_EXT in <GL/glx.h> despite claiming to
|
---|
409 | support GLX_EXT_visual_info. */
|
---|
410 | #ifndef GLX_TRANSPARENT_TYPE_EXT
|
---|
411 | #define GLX_TRANSPARENT_TYPE_EXT 0x23
|
---|
412 | #endif
|
---|
413 |
|
---|
414 | rc = glXGetConfig(__glutDisplay,
|
---|
415 | vlist[i], GLX_TRANSPARENT_TYPE_EXT, &transparent);
|
---|
416 | if (rc != 0) {
|
---|
417 | mode->cap[TRANSPARENT] = 0;
|
---|
418 | } else {
|
---|
419 | mode->cap[TRANSPARENT] = (transparent != GLX_NONE_EXT);
|
---|
420 | }
|
---|
421 | } else {
|
---|
422 | mode->cap[TRANSPARENT] = 0;
|
---|
423 | }
|
---|
424 | #else
|
---|
425 | mode->cap[TRANSPARENT] = 0;
|
---|
426 | #endif
|
---|
427 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
---|
428 | if (multisample) {
|
---|
429 | rc = glXGetConfig(__glutDisplay,
|
---|
430 | vlist[i], GLX_SAMPLES_SGIS, &mode->cap[SAMPLES]);
|
---|
431 | if (rc != 0) {
|
---|
432 | mode->cap[SAMPLES] = 0;
|
---|
433 | }
|
---|
434 | } else {
|
---|
435 | mode->cap[SAMPLES] = 0;
|
---|
436 | }
|
---|
437 | #else
|
---|
438 | mode->cap[SAMPLES] = 0;
|
---|
439 | #endif
|
---|
440 | } else {
|
---|
441 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
---|
442 | if (fbconfig) {
|
---|
443 | GLXFBConfigSGIX fbc;
|
---|
444 | int fbconfigID, drawType, renderType;
|
---|
445 |
|
---|
446 | fbc = glXGetFBConfigFromVisualSGIX(__glutDisplay, vlist[i]);
|
---|
447 | if (fbc) {
|
---|
448 | rc = glXGetFBConfigAttribSGIX(__glutDisplay, fbc,
|
---|
449 | GLX_FBCONFIG_ID_SGIX, &fbconfigID);
|
---|
450 | if ((rc == 0) && (fbconfigID != None)) {
|
---|
451 | rc = glXGetFBConfigAttribSGIX(__glutDisplay, fbc,
|
---|
452 | GLX_DRAWABLE_TYPE_SGIX, &drawType);
|
---|
453 | if ((rc == 0) && (drawType & GLX_WINDOW_BIT_SGIX)) {
|
---|
454 | rc = glXGetFBConfigAttribSGIX(__glutDisplay, fbc,
|
---|
455 | GLX_RENDER_TYPE_SGIX, &renderType);
|
---|
456 | if ((rc == 0) && (renderType & GLX_RGBA_BIT_SGIX)) {
|
---|
457 | mode->fbc = fbc;
|
---|
458 | mode->valid = 1; /* Assume the best until
|
---|
459 | proven otherwise. */
|
---|
460 |
|
---|
461 | assert(glxcap[0] == GLX_RGBA);
|
---|
462 | mode->cap[0] = 1;
|
---|
463 |
|
---|
464 | /* Start with "j = 1" to skip the GLX_RGBA attribute. */
|
---|
465 | for (j = 1; j < NUM_GLXCAPS; j++) {
|
---|
466 | rc = glXGetFBConfigAttribSGIX(__glutDisplay,
|
---|
467 | fbc, glxcap[j], &mode->cap[j]);
|
---|
468 | if (rc != 0) {
|
---|
469 | mode->valid = 0;
|
---|
470 | }
|
---|
471 | }
|
---|
472 |
|
---|
473 | mode->cap[XVISUAL] = (int) vlist[i]->visualid;
|
---|
474 | mode->cap[XSTATICGRAY] = 0;
|
---|
475 | mode->cap[XGRAYSCALE] = 0;
|
---|
476 | mode->cap[XSTATICCOLOR] = 0;
|
---|
477 | mode->cap[XPSEUDOCOLOR] = 0;
|
---|
478 | mode->cap[XTRUECOLOR] = 0;
|
---|
479 | mode->cap[XDIRECTCOLOR] = 0;
|
---|
480 | #if defined(__cplusplus) || defined(c_plusplus)
|
---|
481 | switch (vlist[i]->c_class) {
|
---|
482 | #else
|
---|
483 | switch (vlist[i]->class) {
|
---|
484 | #endif
|
---|
485 | case StaticGray:
|
---|
486 | mode->cap[XSTATICGRAY] = 1;
|
---|
487 | break;
|
---|
488 | case GrayScale:
|
---|
489 | mode->cap[XGRAYSCALE] = 1;
|
---|
490 | break;
|
---|
491 | case StaticColor:
|
---|
492 | mode->cap[XSTATICCOLOR] = 1;
|
---|
493 | break;
|
---|
494 | case PseudoColor:
|
---|
495 | mode->cap[XPSEUDOCOLOR] = 1;
|
---|
496 | break;
|
---|
497 | case TrueColor:
|
---|
498 | mode->cap[XTRUECOLOR] = 1;
|
---|
499 | break;
|
---|
500 | case DirectColor:
|
---|
501 | mode->cap[XDIRECTCOLOR] = 1;
|
---|
502 | break;
|
---|
503 | }
|
---|
504 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating)
|
---|
505 | if (visual_rating) {
|
---|
506 | int rating;
|
---|
507 |
|
---|
508 | /* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0
|
---|
509 | 564 for Alpha did not properly define GLX_VISUAL_CAVEAT_EXT
|
---|
510 | in <GL/glx.h> despite claiming to support
|
---|
511 | GLX_EXT_visual_rating. */
|
---|
512 | #ifndef GLX_VISUAL_CAVEAT_EXT
|
---|
513 | #define GLX_VISUAL_CAVEAT_EXT 0x20
|
---|
514 | #endif
|
---|
515 |
|
---|
516 | rc = glXGetFBConfigAttribSGIX(__glutDisplay,
|
---|
517 | fbc, GLX_VISUAL_CAVEAT_EXT, &rating);
|
---|
518 | if (rc != 0) {
|
---|
519 | mode->cap[SLOW] = 0;
|
---|
520 | mode->cap[CONFORMANT] = 1;
|
---|
521 | } else {
|
---|
522 | switch (rating) {
|
---|
523 | case GLX_SLOW_VISUAL_EXT:
|
---|
524 | mode->cap[SLOW] = 1;
|
---|
525 | mode->cap[CONFORMANT] = 1;
|
---|
526 | break;
|
---|
527 |
|
---|
528 | /* IRIX 5.3 for the R10K Indigo2 may have shipped without this
|
---|
529 | properly defined in /usr/include/GL/glxtokens.h */
|
---|
530 | #ifndef GLX_NON_CONFORMANT_VISUAL_EXT
|
---|
531 | #define GLX_NON_CONFORMANT_VISUAL_EXT 0x800D
|
---|
532 | #endif
|
---|
533 |
|
---|
534 | case GLX_NON_CONFORMANT_VISUAL_EXT:
|
---|
535 | mode->cap[SLOW] = 0;
|
---|
536 | mode->cap[CONFORMANT] = 0;
|
---|
537 | break;
|
---|
538 | case GLX_NONE_EXT:
|
---|
539 | default: /* XXX Hopefully this is a good
|
---|
540 | default assumption. */
|
---|
541 | mode->cap[SLOW] = 0;
|
---|
542 | mode->cap[CONFORMANT] = 1;
|
---|
543 | break;
|
---|
544 | }
|
---|
545 | }
|
---|
546 | } else {
|
---|
547 | mode->cap[TRANSPARENT] = 0;
|
---|
548 | }
|
---|
549 | #else
|
---|
550 | mode->cap[SLOW] = 0;
|
---|
551 | mode->cap[CONFORMANT] = 1;
|
---|
552 | #endif
|
---|
553 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
|
---|
554 | if (visual_info) {
|
---|
555 | int transparent;
|
---|
556 |
|
---|
557 | /* babcock@cs.montana.edu reported that DEC UNIX (OSF1) V4.0
|
---|
558 | 564 for Alpha did not properly define
|
---|
559 | GLX_TRANSPARENT_TYPE_EXT in <GL/glx.h> despite claiming to
|
---|
560 | support GLX_EXT_visual_info. */
|
---|
561 | #ifndef GLX_TRANSPARENT_TYPE_EXT
|
---|
562 | #define GLX_TRANSPARENT_TYPE_EXT 0x23
|
---|
563 | #endif
|
---|
564 |
|
---|
565 | rc = glXGetFBConfigAttribSGIX(__glutDisplay,
|
---|
566 | fbc, GLX_TRANSPARENT_TYPE_EXT, &transparent);
|
---|
567 | if (rc != 0) {
|
---|
568 | mode->cap[TRANSPARENT] = 0;
|
---|
569 | } else {
|
---|
570 | mode->cap[TRANSPARENT] = (transparent != GLX_NONE_EXT);
|
---|
571 | }
|
---|
572 | } else {
|
---|
573 | mode->cap[TRANSPARENT] = 0;
|
---|
574 | }
|
---|
575 | #else
|
---|
576 | mode->cap[TRANSPARENT] = 0;
|
---|
577 | #endif
|
---|
578 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
---|
579 | if (multisample) {
|
---|
580 | rc = glXGetFBConfigAttribSGIX(__glutDisplay,
|
---|
581 | fbc, GLX_SAMPLES_SGIS, &mode->cap[SAMPLES]);
|
---|
582 | if (rc != 0) {
|
---|
583 | mode->cap[SAMPLES] = 0;
|
---|
584 | }
|
---|
585 | } else {
|
---|
586 | mode->cap[SAMPLES] = 0;
|
---|
587 | }
|
---|
588 | #else
|
---|
589 | mode->cap[SAMPLES] = 0;
|
---|
590 | #endif
|
---|
591 |
|
---|
592 | } else {
|
---|
593 | /* Fbconfig is not RGBA; GLUT only uses RGBA
|
---|
594 | FBconfigs. */
|
---|
595 | /* XXX Code could be exteneded to handle color
|
---|
596 | index FBconfigs, but seems a color index
|
---|
597 | window-renderable FBconfig would also be
|
---|
598 | advertised as an X visual. */
|
---|
599 | mode->valid = 0;
|
---|
600 | }
|
---|
601 | } else {
|
---|
602 | /* Fbconfig does not support window rendering;
|
---|
603 | not a valid FBconfig for GLUT windows. */
|
---|
604 | mode->valid = 0;
|
---|
605 | }
|
---|
606 | } else {
|
---|
607 | /* FBconfig ID is None (zero); not a valid
|
---|
608 | FBconfig. */
|
---|
609 | mode->valid = 0;
|
---|
610 | }
|
---|
611 | } else {
|
---|
612 | /* FBconfig ID is None (zero); not a valid FBconfig. */
|
---|
613 | mode->valid = 0;
|
---|
614 | }
|
---|
615 | } else {
|
---|
616 | /* No SGIX_fbconfig GLX sever implementation support. */
|
---|
617 | mode->valid = 0;
|
---|
618 | }
|
---|
619 | #else
|
---|
620 | /* No SGIX_fbconfig GLX extension API support. */
|
---|
621 | mode->valid = 0;
|
---|
622 | #endif
|
---|
623 | }
|
---|
624 | }
|
---|
625 |
|
---|
626 | free(vlist);
|
---|
627 | *nitems_return = n;
|
---|
628 | return fbmodes;
|
---|
629 | }
|
---|
630 |
|
---|
631 | static XVisualInfo *
|
---|
632 | findMatch(FrameBufferMode * fbmodes, int nfbmodes,
|
---|
633 | Criterion * criteria, int ncriteria, void **fbc)
|
---|
634 | {
|
---|
635 | FrameBufferMode *found;
|
---|
636 | int *bestScore, *thisScore;
|
---|
637 | int i, j, numok, result, worse, better;
|
---|
638 |
|
---|
639 | found = NULL;
|
---|
640 | numok = 1; /* "num" capability is indexed from 1,
|
---|
641 | not 0. */
|
---|
642 |
|
---|
643 | /* XXX alloca canidate. */
|
---|
644 | bestScore = (int *) malloc(ncriteria * sizeof(int));
|
---|
645 | if (!bestScore)
|
---|
646 | __glutFatalError("out of memory.");
|
---|
647 | for (j = 0; j < ncriteria; j++) {
|
---|
648 | /* Very negative number. */
|
---|
649 | bestScore[j] = -32768;
|
---|
650 | }
|
---|
651 |
|
---|
652 | /* XXX alloca canidate. */
|
---|
653 | thisScore = (int *) malloc(ncriteria * sizeof(int));
|
---|
654 | if (!thisScore)
|
---|
655 | __glutFatalError("out of memory.");
|
---|
656 |
|
---|
657 | for (i = 0; i < nfbmodes; i++) {
|
---|
658 | if (fbmodes[i].valid) {
|
---|
659 | #ifdef TEST
|
---|
660 | #if !defined(_WIN32) && !defined(__WIN32OS2__)
|
---|
661 | if (verbose)
|
---|
662 | printf("Visual 0x%x\n", fbmodes[i].vi->visualid);
|
---|
663 | #endif
|
---|
664 | #endif
|
---|
665 |
|
---|
666 | worse = 0;
|
---|
667 | better = 0;
|
---|
668 |
|
---|
669 | for (j = 0; j < ncriteria; j++) {
|
---|
670 | int cap, cvalue, fbvalue;
|
---|
671 |
|
---|
672 | cap = criteria[j].capability;
|
---|
673 | cvalue = criteria[j].value;
|
---|
674 | if (cap == NUM) {
|
---|
675 | fbvalue = numok;
|
---|
676 | } else {
|
---|
677 | fbvalue = fbmodes[i].cap[cap];
|
---|
678 | }
|
---|
679 | #ifdef TEST
|
---|
680 | if (verbose)
|
---|
681 | printf(" %s %s %d to %d\n",
|
---|
682 | capstr[cap], compstr[criteria[j].comparison], cvalue, fbvalue);
|
---|
683 | #endif
|
---|
684 | switch (criteria[j].comparison) {
|
---|
685 | case EQ:
|
---|
686 | result = cvalue == fbvalue;
|
---|
687 | thisScore[j] = 1;
|
---|
688 | break;
|
---|
689 | case NEQ:
|
---|
690 | result = cvalue != fbvalue;
|
---|
691 | thisScore[j] = 1;
|
---|
692 | break;
|
---|
693 | case LT:
|
---|
694 | result = fbvalue < cvalue;
|
---|
695 | thisScore[j] = fbvalue - cvalue;
|
---|
696 | break;
|
---|
697 | case GT:
|
---|
698 | result = fbvalue > cvalue;
|
---|
699 | thisScore[j] = fbvalue - cvalue;
|
---|
700 | break;
|
---|
701 | case LTE:
|
---|
702 | result = fbvalue <= cvalue;
|
---|
703 | thisScore[j] = fbvalue - cvalue;
|
---|
704 | break;
|
---|
705 | case GTE:
|
---|
706 | result = (fbvalue >= cvalue);
|
---|
707 | thisScore[j] = fbvalue - cvalue;
|
---|
708 | break;
|
---|
709 | case MIN_:
|
---|
710 | result = fbvalue >= cvalue;
|
---|
711 | thisScore[j] = cvalue - fbvalue;
|
---|
712 | break;
|
---|
713 | }
|
---|
714 |
|
---|
715 | #ifdef TEST
|
---|
716 | if (verbose)
|
---|
717 | printf(" result=%d score=%d bestScore=%d\n", result, thisScore[j], bestScore[j]);
|
---|
718 | #endif
|
---|
719 |
|
---|
720 | if (result) {
|
---|
721 | if (better || thisScore[j] > bestScore[j]) {
|
---|
722 | better = 1;
|
---|
723 | } else if (thisScore[j] == bestScore[j]) {
|
---|
724 | /* Keep looking. */
|
---|
725 | } else {
|
---|
726 | goto nextFBM;
|
---|
727 | }
|
---|
728 | } else {
|
---|
729 | if (cap == NUM) {
|
---|
730 | worse = 1;
|
---|
731 | } else {
|
---|
732 | goto nextFBM;
|
---|
733 | }
|
---|
734 | }
|
---|
735 |
|
---|
736 | }
|
---|
737 |
|
---|
738 | if (better && !worse) {
|
---|
739 | found = &fbmodes[i];
|
---|
740 | for (j = 0; j < ncriteria; j++) {
|
---|
741 | bestScore[j] = thisScore[j];
|
---|
742 | }
|
---|
743 | }
|
---|
744 | numok++;
|
---|
745 |
|
---|
746 | nextFBM:;
|
---|
747 |
|
---|
748 | }
|
---|
749 | }
|
---|
750 | free(bestScore);
|
---|
751 | free(thisScore);
|
---|
752 | if (found) {
|
---|
753 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
---|
754 | *fbc = found->fbc;
|
---|
755 | #endif
|
---|
756 | return found->vi;
|
---|
757 | } else {
|
---|
758 | return NULL;
|
---|
759 | }
|
---|
760 | }
|
---|
761 |
|
---|
762 | static int
|
---|
763 | parseCriteria(char *word, Criterion * criterion, int *mask,
|
---|
764 | Bool * allowDoubleAsSingle)
|
---|
765 | {
|
---|
766 | char *cstr, *vstr, *response;
|
---|
767 | int comparator, value;
|
---|
768 | int rgb, rgba, acc, acca, count, i;
|
---|
769 |
|
---|
770 | cstr = strpbrk(word, "=><!~");
|
---|
771 | if (cstr) {
|
---|
772 | switch (cstr[0]) {
|
---|
773 | case '=':
|
---|
774 | comparator = EQ;
|
---|
775 | vstr = &cstr[1];
|
---|
776 | break;
|
---|
777 | case '~':
|
---|
778 | comparator = MIN_;
|
---|
779 | vstr = &cstr[1];
|
---|
780 | break;
|
---|
781 | case '>':
|
---|
782 | if (cstr[1] == '=') {
|
---|
783 | comparator = GTE;
|
---|
784 | vstr = &cstr[2];
|
---|
785 | } else {
|
---|
786 | comparator = GT;
|
---|
787 | vstr = &cstr[1];
|
---|
788 | }
|
---|
789 | break;
|
---|
790 | case '<':
|
---|
791 | if (cstr[1] == '=') {
|
---|
792 | comparator = LTE;
|
---|
793 | vstr = &cstr[2];
|
---|
794 | } else {
|
---|
795 | comparator = LT;
|
---|
796 | vstr = &cstr[1];
|
---|
797 | }
|
---|
798 | break;
|
---|
799 | case '!':
|
---|
800 | if (cstr[1] == '=') {
|
---|
801 | comparator = NEQ;
|
---|
802 | vstr = &cstr[2];
|
---|
803 | } else {
|
---|
804 | return -1;
|
---|
805 | }
|
---|
806 | break;
|
---|
807 | default:
|
---|
808 | return -1;
|
---|
809 | }
|
---|
810 | value = (int) strtol(vstr, &response, 0);
|
---|
811 | if (response == vstr) {
|
---|
812 | /* Not a valid number. */
|
---|
813 | return -1;
|
---|
814 | }
|
---|
815 | *cstr = '\0';
|
---|
816 | } else {
|
---|
817 | comparator = NONE;
|
---|
818 | }
|
---|
819 | switch (word[0]) {
|
---|
820 | case 'a':
|
---|
821 | if (!strcmp(word, "alpha")) {
|
---|
822 | criterion[0].capability = ALPHA_SIZE;
|
---|
823 | if (comparator == NONE) {
|
---|
824 | criterion[0].comparison = GTE;
|
---|
825 | criterion[0].value = 1;
|
---|
826 | } else {
|
---|
827 | criterion[0].comparison = comparator;
|
---|
828 | criterion[0].value = value;
|
---|
829 | }
|
---|
830 | *mask |= (1 << RGBA);
|
---|
831 | *mask |= (1 << ALPHA_SIZE);
|
---|
832 | *mask |= (1 << RGBA_MODE);
|
---|
833 | return 1;
|
---|
834 | }
|
---|
835 | acca = !strcmp(word, "acca");
|
---|
836 | acc = !strcmp(word, "acc");
|
---|
837 | if (acc || acca) {
|
---|
838 | criterion[0].capability = ACCUM_RED_SIZE;
|
---|
839 | criterion[1].capability = ACCUM_GREEN_SIZE;
|
---|
840 | criterion[2].capability = ACCUM_BLUE_SIZE;
|
---|
841 | criterion[3].capability = ACCUM_ALPHA_SIZE;
|
---|
842 | if (acca) {
|
---|
843 | count = 4;
|
---|
844 | } else {
|
---|
845 | count = 3;
|
---|
846 | criterion[3].comparison = MIN_;
|
---|
847 | criterion[3].value = 0;
|
---|
848 | }
|
---|
849 | if (comparator == NONE) {
|
---|
850 | comparator = GTE;
|
---|
851 | value = 8;
|
---|
852 | }
|
---|
853 | for (i = 0; i < count; i++) {
|
---|
854 | criterion[i].comparison = comparator;
|
---|
855 | criterion[i].value = value;
|
---|
856 | }
|
---|
857 | *mask |= (1 << ACCUM_RED_SIZE);
|
---|
858 | return 4;
|
---|
859 | }
|
---|
860 | if (!strcmp(word, "auxbufs")) {
|
---|
861 | criterion[0].capability = AUX_BUFFERS;
|
---|
862 | if (comparator == NONE) {
|
---|
863 | criterion[0].comparison = MIN_;
|
---|
864 | criterion[0].value = 1;
|
---|
865 | } else {
|
---|
866 | criterion[0].comparison = comparator;
|
---|
867 | criterion[0].value = value;
|
---|
868 | }
|
---|
869 | *mask |= (1 << AUX_BUFFERS);
|
---|
870 | return 1;
|
---|
871 | }
|
---|
872 | return -1;
|
---|
873 | case 'b':
|
---|
874 | if (!strcmp(word, "blue")) {
|
---|
875 | criterion[0].capability = BLUE_SIZE;
|
---|
876 | if (comparator == NONE) {
|
---|
877 | criterion[0].comparison = GTE;
|
---|
878 | criterion[0].value = 1;
|
---|
879 | } else {
|
---|
880 | criterion[0].comparison = comparator;
|
---|
881 | criterion[0].value = value;
|
---|
882 | }
|
---|
883 | *mask |= (1 << RGBA);
|
---|
884 | *mask |= (1 << RGBA_MODE);
|
---|
885 | return 1;
|
---|
886 | }
|
---|
887 | if (!strcmp(word, "buffer")) {
|
---|
888 | criterion[0].capability = BUFFER_SIZE;
|
---|
889 | if (comparator == NONE) {
|
---|
890 | criterion[0].comparison = GTE;
|
---|
891 | criterion[0].value = 1;
|
---|
892 | } else {
|
---|
893 | criterion[0].comparison = comparator;
|
---|
894 | criterion[0].value = value;
|
---|
895 | }
|
---|
896 | return 1;
|
---|
897 | }
|
---|
898 | return -1;
|
---|
899 | case 'c':
|
---|
900 | if (!strcmp(word, "conformant")) {
|
---|
901 | criterion[0].capability = CONFORMANT;
|
---|
902 | if (comparator == NONE) {
|
---|
903 | criterion[0].comparison = EQ;
|
---|
904 | criterion[0].value = 1;
|
---|
905 | } else {
|
---|
906 | criterion[0].comparison = comparator;
|
---|
907 | criterion[0].value = value;
|
---|
908 | }
|
---|
909 | *mask |= (1 << CONFORMANT);
|
---|
910 | return 1;
|
---|
911 | }
|
---|
912 | return -1;
|
---|
913 | case 'd':
|
---|
914 | if (!strcmp(word, "depth")) {
|
---|
915 | criterion[0].capability = DEPTH_SIZE;
|
---|
916 | if (comparator == NONE) {
|
---|
917 | criterion[0].comparison = GTE;
|
---|
918 | criterion[0].value = 12;
|
---|
919 | } else {
|
---|
920 | criterion[0].comparison = comparator;
|
---|
921 | criterion[0].value = value;
|
---|
922 | }
|
---|
923 | *mask |= (1 << DEPTH_SIZE);
|
---|
924 | return 1;
|
---|
925 | }
|
---|
926 | if (!strcmp(word, "double")) {
|
---|
927 | criterion[0].capability = DOUBLEBUFFER;
|
---|
928 | if (comparator == NONE) {
|
---|
929 | criterion[0].comparison = EQ;
|
---|
930 | criterion[0].value = 1;
|
---|
931 | } else {
|
---|
932 | criterion[0].comparison = comparator;
|
---|
933 | criterion[0].value = value;
|
---|
934 | }
|
---|
935 | *mask |= (1 << DOUBLEBUFFER);
|
---|
936 | return 1;
|
---|
937 | }
|
---|
938 | return -1;
|
---|
939 | case 'g':
|
---|
940 | if (!strcmp(word, "green")) {
|
---|
941 | criterion[0].capability = GREEN_SIZE;
|
---|
942 | if (comparator == NONE) {
|
---|
943 | criterion[0].comparison = GTE;
|
---|
944 | criterion[0].value = 1;
|
---|
945 | } else {
|
---|
946 | criterion[0].comparison = comparator;
|
---|
947 | criterion[0].value = value;
|
---|
948 | }
|
---|
949 | *mask |= (1 << RGBA);
|
---|
950 | *mask |= (1 << RGBA_MODE);
|
---|
951 | return 1;
|
---|
952 | }
|
---|
953 | return -1;
|
---|
954 | case 'i':
|
---|
955 | if (!strcmp(word, "index")) {
|
---|
956 | criterion[0].capability = RGBA;
|
---|
957 | criterion[0].comparison = EQ;
|
---|
958 | criterion[0].value = 0;
|
---|
959 | *mask |= (1 << RGBA);
|
---|
960 | *mask |= (1 << CI_MODE);
|
---|
961 | criterion[1].capability = BUFFER_SIZE;
|
---|
962 | if (comparator == NONE) {
|
---|
963 | criterion[1].comparison = GTE;
|
---|
964 | criterion[1].value = 1;
|
---|
965 | } else {
|
---|
966 | criterion[1].comparison = comparator;
|
---|
967 | criterion[1].value = value;
|
---|
968 | }
|
---|
969 | return 2;
|
---|
970 | }
|
---|
971 | return -1;
|
---|
972 | case 'l':
|
---|
973 | if (!strcmp(word, "luminance")) {
|
---|
974 | criterion[0].capability = RGBA;
|
---|
975 | criterion[0].comparison = EQ;
|
---|
976 | criterion[0].value = 1;
|
---|
977 |
|
---|
978 | criterion[1].capability = RED_SIZE;
|
---|
979 | if (comparator == NONE) {
|
---|
980 | criterion[1].comparison = GTE;
|
---|
981 | criterion[1].value = 1;
|
---|
982 | } else {
|
---|
983 | criterion[1].comparison = comparator;
|
---|
984 | criterion[1].value = value;
|
---|
985 | }
|
---|
986 |
|
---|
987 | criterion[2].capability = GREEN_SIZE;
|
---|
988 | criterion[2].comparison = EQ;
|
---|
989 | criterion[2].value = 0;
|
---|
990 |
|
---|
991 | criterion[3].capability = BLUE_SIZE;
|
---|
992 | criterion[3].comparison = EQ;
|
---|
993 | criterion[3].value = 0;
|
---|
994 |
|
---|
995 | *mask |= (1 << RGBA);
|
---|
996 | *mask |= (1 << RGBA_MODE);
|
---|
997 | *mask |= (1 << LUMINANCE_MODE);
|
---|
998 | return 4;
|
---|
999 | }
|
---|
1000 | return -1;
|
---|
1001 | case 'n':
|
---|
1002 | if (!strcmp(word, "num")) {
|
---|
1003 | criterion[0].capability = NUM;
|
---|
1004 | if (comparator == NONE) {
|
---|
1005 | return -1;
|
---|
1006 | } else {
|
---|
1007 | criterion[0].comparison = comparator;
|
---|
1008 | criterion[0].value = value;
|
---|
1009 | return 1;
|
---|
1010 | }
|
---|
1011 | }
|
---|
1012 | return -1;
|
---|
1013 | case 'r':
|
---|
1014 | if (!strcmp(word, "red")) {
|
---|
1015 | criterion[0].capability = RED_SIZE;
|
---|
1016 | if (comparator == NONE) {
|
---|
1017 | criterion[0].comparison = GTE;
|
---|
1018 | criterion[0].value = 1;
|
---|
1019 | } else {
|
---|
1020 | criterion[0].comparison = comparator;
|
---|
1021 | criterion[0].value = value;
|
---|
1022 | }
|
---|
1023 | *mask |= (1 << RGBA);
|
---|
1024 | *mask |= (1 << RGBA_MODE);
|
---|
1025 | return 1;
|
---|
1026 | }
|
---|
1027 | rgba = !strcmp(word, "rgba");
|
---|
1028 | rgb = !strcmp(word, "rgb");
|
---|
1029 | if (rgb || rgba) {
|
---|
1030 | criterion[0].capability = RGBA;
|
---|
1031 | criterion[0].comparison = EQ;
|
---|
1032 | criterion[0].value = 1;
|
---|
1033 |
|
---|
1034 | criterion[1].capability = RED_SIZE;
|
---|
1035 | criterion[2].capability = GREEN_SIZE;
|
---|
1036 | criterion[3].capability = BLUE_SIZE;
|
---|
1037 | criterion[4].capability = ALPHA_SIZE;
|
---|
1038 | if (rgba) {
|
---|
1039 | count = 5;
|
---|
1040 | } else {
|
---|
1041 | count = 4;
|
---|
1042 | criterion[4].comparison = MIN_;
|
---|
1043 | criterion[4].value = 0;
|
---|
1044 | }
|
---|
1045 | if (comparator == NONE) {
|
---|
1046 | comparator = GTE;
|
---|
1047 | value = 1;
|
---|
1048 | }
|
---|
1049 | for (i = 1; i < count; i++) {
|
---|
1050 | criterion[i].comparison = comparator;
|
---|
1051 | criterion[i].value = value;
|
---|
1052 | }
|
---|
1053 | *mask |= (1 << RGBA);
|
---|
1054 | *mask |= (1 << RGBA_MODE);
|
---|
1055 | return 5;
|
---|
1056 | }
|
---|
1057 | return -1;
|
---|
1058 | case 's':
|
---|
1059 | if (!strcmp(word, "stencil")) {
|
---|
1060 | criterion[0].capability = STENCIL_SIZE;
|
---|
1061 | if (comparator == NONE) {
|
---|
1062 | criterion[0].comparison = MIN_;
|
---|
1063 | criterion[0].value = 1;
|
---|
1064 | } else {
|
---|
1065 | criterion[0].comparison = comparator;
|
---|
1066 | criterion[0].value = value;
|
---|
1067 | }
|
---|
1068 | *mask |= (1 << STENCIL_SIZE);
|
---|
1069 | return 1;
|
---|
1070 | }
|
---|
1071 | if (!strcmp(word, "single")) {
|
---|
1072 | criterion[0].capability = DOUBLEBUFFER;
|
---|
1073 | if (comparator == NONE) {
|
---|
1074 | criterion[0].comparison = EQ;
|
---|
1075 | criterion[0].value = 0;
|
---|
1076 | *allowDoubleAsSingle = True;
|
---|
1077 | *mask |= (1 << DOUBLEBUFFER);
|
---|
1078 | return 1;
|
---|
1079 | } else {
|
---|
1080 | return -1;
|
---|
1081 | }
|
---|
1082 | }
|
---|
1083 | if (!strcmp(word, "stereo")) {
|
---|
1084 | criterion[0].capability = STEREO;
|
---|
1085 | if (comparator == NONE) {
|
---|
1086 | criterion[0].comparison = EQ;
|
---|
1087 | criterion[0].value = 1;
|
---|
1088 | } else {
|
---|
1089 | criterion[0].comparison = comparator;
|
---|
1090 | criterion[0].value = value;
|
---|
1091 | }
|
---|
1092 | *mask |= (1 << STEREO);
|
---|
1093 | return 1;
|
---|
1094 | }
|
---|
1095 | if (!strcmp(word, "samples")) {
|
---|
1096 | criterion[0].capability = SAMPLES;
|
---|
1097 | if (comparator == NONE) {
|
---|
1098 | criterion[0].comparison = LTE;
|
---|
1099 | criterion[0].value = 4;
|
---|
1100 | } else {
|
---|
1101 | criterion[0].comparison = comparator;
|
---|
1102 | criterion[0].value = value;
|
---|
1103 | }
|
---|
1104 | *mask |= (1 << SAMPLES);
|
---|
1105 | return 1;
|
---|
1106 | }
|
---|
1107 | if (!strcmp(word, "slow")) {
|
---|
1108 | criterion[0].capability = SLOW;
|
---|
1109 | if (comparator == NONE) {
|
---|
1110 | /* Just "slow" means permit fast visuals, but accept
|
---|
1111 | slow ones in preference. Presumably the slow ones
|
---|
1112 | must be higher quality or something else desirable. */
|
---|
1113 | criterion[0].comparison = GTE;
|
---|
1114 | criterion[0].value = 0;
|
---|
1115 | } else {
|
---|
1116 | criterion[0].comparison = comparator;
|
---|
1117 | criterion[0].value = value;
|
---|
1118 | }
|
---|
1119 | *mask |= (1 << SLOW);
|
---|
1120 | return 1;
|
---|
1121 | }
|
---|
1122 | return -1;
|
---|
1123 | #if defined(_WIN32) || defined(__WIN32OS2__)
|
---|
1124 | case 'w':
|
---|
1125 | if (!strcmp(word, "win32pfd")) {
|
---|
1126 | criterion[0].capability = XVISUAL;
|
---|
1127 | if (comparator == NONE) {
|
---|
1128 | return -1;
|
---|
1129 | } else {
|
---|
1130 | criterion[0].comparison = comparator;
|
---|
1131 | criterion[0].value = value;
|
---|
1132 | return 1;
|
---|
1133 | }
|
---|
1134 | }
|
---|
1135 | return -1;
|
---|
1136 | #endif
|
---|
1137 | #if !defined(_WIN32) && !defined(__WIN32OS2__)
|
---|
1138 | case 'x':
|
---|
1139 | if (!strcmp(word, "xvisual")) {
|
---|
1140 | if (comparator == NONE) {
|
---|
1141 | return -1;
|
---|
1142 | } else {
|
---|
1143 | criterion[0].capability = XVISUAL;
|
---|
1144 | criterion[0].comparison = comparator;
|
---|
1145 | criterion[0].value = value;
|
---|
1146 | /* Set everything in "mask" so that no default criteria
|
---|
1147 | get used. Assume the program really wants the
|
---|
1148 | xvisual specified. */
|
---|
1149 | *mask |= ~0;
|
---|
1150 | return 1;
|
---|
1151 | }
|
---|
1152 | }
|
---|
1153 | /* Be a little over-eager to fill in the comparison and
|
---|
1154 | value so we won't have to replicate the code after each
|
---|
1155 | string match. */
|
---|
1156 | if (comparator == NONE) {
|
---|
1157 | criterion[0].comparison = EQ;
|
---|
1158 | criterion[0].value = 1;
|
---|
1159 | } else {
|
---|
1160 | criterion[0].comparison = comparator;
|
---|
1161 | criterion[0].value = value;
|
---|
1162 | }
|
---|
1163 |
|
---|
1164 | if (!strcmp(word, "xstaticgray")) {
|
---|
1165 | criterion[0].capability = XSTATICGRAY;
|
---|
1166 | *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual
|
---|
1167 | class selected. */
|
---|
1168 | return 1;
|
---|
1169 | }
|
---|
1170 | if (!strcmp(word, "xgrayscale")) {
|
---|
1171 | criterion[0].capability = XGRAYSCALE;
|
---|
1172 | *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual
|
---|
1173 | class selected. */
|
---|
1174 | return 1;
|
---|
1175 | }
|
---|
1176 | if (!strcmp(word, "xstaticcolor")) {
|
---|
1177 | criterion[0].capability = XSTATICCOLOR;
|
---|
1178 | *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual
|
---|
1179 | class selected. */
|
---|
1180 | return 1;
|
---|
1181 | }
|
---|
1182 | if (!strcmp(word, "xpseudocolor")) {
|
---|
1183 | criterion[0].capability = XPSEUDOCOLOR;
|
---|
1184 | *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual
|
---|
1185 | class selected. */
|
---|
1186 | return 1;
|
---|
1187 | }
|
---|
1188 | if (!strcmp(word, "xtruecolor")) {
|
---|
1189 | criterion[0].capability = XTRUECOLOR;
|
---|
1190 | *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual
|
---|
1191 | class selected. */
|
---|
1192 | return 1;
|
---|
1193 | }
|
---|
1194 | if (!strcmp(word, "xdirectcolor")) {
|
---|
1195 | criterion[0].capability = XDIRECTCOLOR;
|
---|
1196 | *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual
|
---|
1197 | class selected. */
|
---|
1198 | return 1;
|
---|
1199 | }
|
---|
1200 | return -1;
|
---|
1201 | #endif
|
---|
1202 | default:
|
---|
1203 | return -1;
|
---|
1204 | }
|
---|
1205 | }
|
---|
1206 |
|
---|
1207 | static Criterion *
|
---|
1208 | parseModeString(char *mode, int *ncriteria, Bool * allowDoubleAsSingle,
|
---|
1209 | Criterion * requiredCriteria, int nRequired, int requiredMask)
|
---|
1210 | {
|
---|
1211 | Criterion *criteria = NULL;
|
---|
1212 | int n, mask, parsed, i;
|
---|
1213 | char *copy, *word;
|
---|
1214 |
|
---|
1215 | *allowDoubleAsSingle = False;
|
---|
1216 | copy = __glutStrdup(mode);
|
---|
1217 | /* Attempt to estimate how many criteria entries should be
|
---|
1218 | needed. */
|
---|
1219 | n = 0;
|
---|
1220 | word = strtok(copy, " \t");
|
---|
1221 | while (word) {
|
---|
1222 | n++;
|
---|
1223 | word = strtok(NULL, " \t");
|
---|
1224 | }
|
---|
1225 | /* Overestimate by 4 times ("rgba" might add four criteria
|
---|
1226 | entries) plus add in possible defaults plus space for
|
---|
1227 | required criteria. */
|
---|
1228 | criteria = (Criterion *) malloc((4 * n + 30 + nRequired) * sizeof(Criterion));
|
---|
1229 | if (!criteria) {
|
---|
1230 | __glutFatalError("out of memory.");
|
---|
1231 | }
|
---|
1232 |
|
---|
1233 | /* Re-copy the copy of the mode string. */
|
---|
1234 | strcpy(copy, mode);
|
---|
1235 |
|
---|
1236 | /* First add the required criteria (these match at the
|
---|
1237 | highest priority). Typically these will be used to force a
|
---|
1238 | specific level (layer), transparency, and/or visual type. */
|
---|
1239 | mask = requiredMask;
|
---|
1240 | for (i = 0; i < nRequired; i++) {
|
---|
1241 | criteria[i] = requiredCriteria[i];
|
---|
1242 | }
|
---|
1243 | n = nRequired;
|
---|
1244 |
|
---|
1245 | word = strtok(copy, " \t");
|
---|
1246 | while (word) {
|
---|
1247 | parsed = parseCriteria(word, &criteria[n], &mask, allowDoubleAsSingle);
|
---|
1248 | if (parsed >= 0) {
|
---|
1249 | n += parsed;
|
---|
1250 | } else {
|
---|
1251 | __glutWarning("Unrecognized display string word: %s (ignoring)\n", word);
|
---|
1252 | }
|
---|
1253 | word = strtok(NULL, " \t");
|
---|
1254 | }
|
---|
1255 |
|
---|
1256 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
|
---|
1257 | if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) {
|
---|
1258 | if (!(mask & (1 << SAMPLES))) {
|
---|
1259 | criteria[n].capability = SAMPLES;
|
---|
1260 | criteria[n].comparison = EQ;
|
---|
1261 | criteria[n].value = 0;
|
---|
1262 | n++;
|
---|
1263 | } else {
|
---|
1264 | /* Multisample visuals are marked nonconformant. If
|
---|
1265 | multisampling was requeste and no conformant
|
---|
1266 | preference was set, assume that we will settle for a
|
---|
1267 | non-conformant visual to get multisampling. */
|
---|
1268 | if (!(mask & (1 << CONFORMANT))) {
|
---|
1269 | criteria[n].capability = CONFORMANT;
|
---|
1270 | criteria[n].comparison = MIN_;
|
---|
1271 | criteria[n].value = 0;
|
---|
1272 | n++;
|
---|
1273 | mask |= (1 << CONFORMANT);
|
---|
1274 | }
|
---|
1275 | }
|
---|
1276 | }
|
---|
1277 | #endif
|
---|
1278 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
|
---|
1279 | if (__glutIsSupportedByGLX("GLX_EXT_visual_info")) {
|
---|
1280 | if (!(mask & (1 << TRANSPARENT))) {
|
---|
1281 | criteria[n].capability = TRANSPARENT;
|
---|
1282 | criteria[n].comparison = EQ;
|
---|
1283 | criteria[n].value = 0;
|
---|
1284 | n++;
|
---|
1285 | }
|
---|
1286 | }
|
---|
1287 | #endif
|
---|
1288 | #if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating)
|
---|
1289 | if (__glutIsSupportedByGLX("GLX_EXT_visual_rating")) {
|
---|
1290 | if (!(mask & (1 << SLOW))) {
|
---|
1291 | criteria[n].capability = SLOW;
|
---|
1292 | criteria[n].comparison = EQ;
|
---|
1293 | criteria[n].value = 0;
|
---|
1294 | n++;
|
---|
1295 | }
|
---|
1296 | if (!(mask & (1 << CONFORMANT))) {
|
---|
1297 | criteria[n].capability = CONFORMANT;
|
---|
1298 | criteria[n].comparison = EQ;
|
---|
1299 | criteria[n].value = 1;
|
---|
1300 | n++;
|
---|
1301 | }
|
---|
1302 | }
|
---|
1303 | #endif
|
---|
1304 | if (!(mask & (1 << ACCUM_RED_SIZE))) {
|
---|
1305 | criteria[n].capability = ACCUM_RED_SIZE;
|
---|
1306 | criteria[n].comparison = MIN_;
|
---|
1307 | criteria[n].value = 0;
|
---|
1308 | criteria[n + 1].capability = ACCUM_GREEN_SIZE;
|
---|
1309 | criteria[n + 1].comparison = MIN_;
|
---|
1310 | criteria[n + 1].value = 0;
|
---|
1311 | criteria[n + 2].capability = ACCUM_BLUE_SIZE;
|
---|
1312 | criteria[n + 2].comparison = MIN_;
|
---|
1313 | criteria[n + 2].value = 0;
|
---|
1314 | criteria[n + 3].capability = ACCUM_ALPHA_SIZE;
|
---|
1315 | criteria[n + 3].comparison = MIN_;
|
---|
1316 | criteria[n + 3].value = 0;
|
---|
1317 | n += 4;
|
---|
1318 | }
|
---|
1319 | if (!(mask & (1 << AUX_BUFFERS))) {
|
---|
1320 | criteria[n].capability = AUX_BUFFERS;
|
---|
1321 | criteria[n].comparison = MIN_;
|
---|
1322 | criteria[n].value = 0;
|
---|
1323 | n++;
|
---|
1324 | }
|
---|
1325 | if (!(mask & (1 << RGBA))) {
|
---|
1326 | criteria[n].capability = RGBA;
|
---|
1327 | criteria[n].comparison = EQ;
|
---|
1328 | criteria[n].value = 1;
|
---|
1329 | criteria[n + 1].capability = RED_SIZE;
|
---|
1330 | criteria[n + 1].comparison = GTE;
|
---|
1331 | criteria[n + 1].value = 1;
|
---|
1332 | criteria[n + 2].capability = GREEN_SIZE;
|
---|
1333 | criteria[n + 2].comparison = GTE;
|
---|
1334 | criteria[n + 2].value = 1;
|
---|
1335 | criteria[n + 3].capability = BLUE_SIZE;
|
---|
1336 | criteria[n + 3].comparison = GTE;
|
---|
1337 | criteria[n + 3].value = 1;
|
---|
1338 | criteria[n + 4].capability = ALPHA_SIZE;
|
---|
1339 | criteria[n + 4].comparison = MIN_;
|
---|
1340 | criteria[n + 4].value = 0;
|
---|
1341 | n += 5;
|
---|
1342 | mask |= (1 << RGBA_MODE);
|
---|
1343 | }
|
---|
1344 | #if !defined(_WIN32) && !defined(__WIN32OS2__)
|
---|
1345 | if (!(mask & (1 << XSTATICGRAY))) {
|
---|
1346 | assert(isMesaGLX != -1);
|
---|
1347 | if ((mask & (1 << RGBA_MODE)) && !isMesaGLX) {
|
---|
1348 | /* Normally, request an RGBA mode visual be TrueColor,
|
---|
1349 | except in the case of Mesa where we trust Mesa (and
|
---|
1350 | other code in GLUT) to handle any type of RGBA visual
|
---|
1351 | reasonably. */
|
---|
1352 | if (mask & (1 << LUMINANCE_MODE)) {
|
---|
1353 | /* If RGBA luminance was requested, actually go for
|
---|
1354 | a StaticGray visual. */
|
---|
1355 | criteria[n].capability = XSTATICGRAY;
|
---|
1356 | } else {
|
---|
1357 | criteria[n].capability = XTRUECOLOR;
|
---|
1358 | }
|
---|
1359 | criteria[n].value = 1;
|
---|
1360 | criteria[n].comparison = EQ;
|
---|
1361 |
|
---|
1362 | n++;
|
---|
1363 | }
|
---|
1364 | if (mask & (1 << CI_MODE)) {
|
---|
1365 | criteria[n].capability = XPSEUDOCOLOR;
|
---|
1366 | criteria[n].value = 1;
|
---|
1367 | criteria[n].comparison = EQ;
|
---|
1368 | n++;
|
---|
1369 | }
|
---|
1370 | }
|
---|
1371 | #endif
|
---|
1372 | if (!(mask & (1 << STEREO))) {
|
---|
1373 | criteria[n].capability = STEREO;
|
---|
1374 | criteria[n].comparison = EQ;
|
---|
1375 | criteria[n].value = 0;
|
---|
1376 | n++;
|
---|
1377 | }
|
---|
1378 | if (!(mask & (1 << DOUBLEBUFFER))) {
|
---|
1379 | criteria[n].capability = DOUBLEBUFFER;
|
---|
1380 | criteria[n].comparison = EQ;
|
---|
1381 | criteria[n].value = 0;
|
---|
1382 | *allowDoubleAsSingle = True;
|
---|
1383 | n++;
|
---|
1384 | }
|
---|
1385 | if (!(mask & (1 << DEPTH_SIZE))) {
|
---|
1386 | criteria[n].capability = DEPTH_SIZE;
|
---|
1387 | criteria[n].comparison = MIN_;
|
---|
1388 | criteria[n].value = 0;
|
---|
1389 | n++;
|
---|
1390 | }
|
---|
1391 | if (!(mask & (1 << STENCIL_SIZE))) {
|
---|
1392 | criteria[n].capability = STENCIL_SIZE;
|
---|
1393 | criteria[n].comparison = MIN_;
|
---|
1394 | criteria[n].value = 0;
|
---|
1395 | n++;
|
---|
1396 | }
|
---|
1397 | if (!(mask & (1 << LEVEL))) {
|
---|
1398 | criteria[n].capability = LEVEL;
|
---|
1399 | criteria[n].comparison = EQ;
|
---|
1400 | criteria[n].value = 0;
|
---|
1401 | n++;
|
---|
1402 | }
|
---|
1403 | if (n) {
|
---|
1404 | /* Since over-estimated the size needed; squeeze it down to
|
---|
1405 | reality. */
|
---|
1406 | criteria = (Criterion *) realloc(criteria, n * sizeof(Criterion));
|
---|
1407 | if (!criteria) {
|
---|
1408 | /* Should never happen since should be shrinking down! */
|
---|
1409 | __glutFatalError("out of memory.");
|
---|
1410 | }
|
---|
1411 | } else {
|
---|
1412 | /* For portability, avoid "realloc(ptr,0)" call. */
|
---|
1413 | free(criteria);
|
---|
1414 | criteria = NULL;
|
---|
1415 | }
|
---|
1416 |
|
---|
1417 | free(copy);
|
---|
1418 | *ncriteria = n;
|
---|
1419 | return criteria;
|
---|
1420 | }
|
---|
1421 |
|
---|
1422 | static FrameBufferMode *fbmodes = NULL;
|
---|
1423 | static int nfbmodes = 0;
|
---|
1424 |
|
---|
1425 | static XVisualInfo *
|
---|
1426 | getVisualInfoFromString(char *string, Bool * treatAsSingle,
|
---|
1427 | Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc)
|
---|
1428 | {
|
---|
1429 | Criterion *criteria;
|
---|
1430 | XVisualInfo *visinfo;
|
---|
1431 | Bool allowDoubleAsSingle;
|
---|
1432 | int ncriteria, i;
|
---|
1433 |
|
---|
1434 | if (!fbmodes) {
|
---|
1435 | fbmodes = loadVisuals(&nfbmodes);
|
---|
1436 | }
|
---|
1437 | criteria = parseModeString(string, &ncriteria,
|
---|
1438 | &allowDoubleAsSingle, requiredCriteria, nRequired, requiredMask);
|
---|
1439 | if (criteria == NULL) {
|
---|
1440 | __glutWarning("failed to parse mode string");
|
---|
1441 | return NULL;
|
---|
1442 | }
|
---|
1443 | #ifdef TEST
|
---|
1444 | printCriteria(criteria, ncriteria);
|
---|
1445 | #endif
|
---|
1446 | visinfo = findMatch(fbmodes, nfbmodes, criteria, ncriteria, fbc);
|
---|
1447 | if (visinfo) {
|
---|
1448 | *treatAsSingle = 0;
|
---|
1449 | } else {
|
---|
1450 | if (allowDoubleAsSingle) {
|
---|
1451 | /* Rewrite criteria so that we now look for a double
|
---|
1452 | buffered visual which will then get treated as a
|
---|
1453 | single buffered visual. */
|
---|
1454 | for (i = 0; i < ncriteria; i++) {
|
---|
1455 | if (criteria[i].capability == DOUBLEBUFFER
|
---|
1456 | && criteria[i].comparison == EQ
|
---|
1457 | && criteria[i].value == 0) {
|
---|
1458 | criteria[i].value = 1;
|
---|
1459 | }
|
---|
1460 | }
|
---|
1461 | visinfo = findMatch(fbmodes, nfbmodes, criteria, ncriteria, fbc);
|
---|
1462 | if (visinfo) {
|
---|
1463 | *treatAsSingle = 1;
|
---|
1464 | }
|
---|
1465 | }
|
---|
1466 | }
|
---|
1467 | free(criteria);
|
---|
1468 |
|
---|
1469 | if (visinfo) {
|
---|
1470 | #if defined(_WIN32) || defined(__WIN32OS2__)
|
---|
1471 | /* We could have a valid pixel format for drawing to a
|
---|
1472 | bitmap. However, we don't want to draw into a bitmap, we
|
---|
1473 | need one that can be used with a window, so make sure
|
---|
1474 | that this is true. */
|
---|
1475 | if (!(visinfo->dwFlags & PFD_DRAW_TO_WINDOW))
|
---|
1476 | return NULL;
|
---|
1477 | #endif
|
---|
1478 | return visinfo;
|
---|
1479 | } else {
|
---|
1480 | return NULL;
|
---|
1481 | }
|
---|
1482 | }
|
---|
1483 |
|
---|
1484 | /* CENTRY */
|
---|
1485 | void APIENTRY
|
---|
1486 | glutInitDisplayString(const char *string)
|
---|
1487 | {
|
---|
1488 | #if defined(_WIN32) || defined(__WIN32OS2__)
|
---|
1489 | XHDC = GetDC(GetDesktopWindow());
|
---|
1490 | #endif
|
---|
1491 |
|
---|
1492 | __glutDetermineVisualFromString = getVisualInfoFromString;
|
---|
1493 | if (__glutDisplayString) {
|
---|
1494 | free(__glutDisplayString);
|
---|
1495 | }
|
---|
1496 | if (string) {
|
---|
1497 | __glutDisplayString = __glutStrdup(string);
|
---|
1498 | if (!__glutDisplayString)
|
---|
1499 | __glutFatalError("out of memory.");
|
---|
1500 | } else {
|
---|
1501 | __glutDisplayString = NULL;
|
---|
1502 | }
|
---|
1503 | }
|
---|
1504 | /* ENDCENTRY */
|
---|
1505 |
|
---|
1506 | #ifdef TEST
|
---|
1507 |
|
---|
1508 | Criterion requiredWindowCriteria[] =
|
---|
1509 | {
|
---|
1510 | {LEVEL, EQ, 0},
|
---|
1511 | {TRANSPARENT, EQ, 0}
|
---|
1512 | };
|
---|
1513 | int numRequiredWindowCriteria = sizeof(requiredWindowCriteria) / sizeof(Criterion);
|
---|
1514 | int requiredWindowCriteriaMask = (1 << LEVEL) | (1 << TRANSPARENT);
|
---|
1515 |
|
---|
1516 | Criterion requiredOverlayCriteria[] =
|
---|
1517 | {
|
---|
1518 | {LEVEL, EQ, 1},
|
---|
1519 | {TRANSPARENT, EQ, 1},
|
---|
1520 | {XPSEUDOCOLOR, EQ, 1},
|
---|
1521 | {RGBA, EQ, 0},
|
---|
1522 | {BUFFER_SIZE, GTE, 1}
|
---|
1523 | };
|
---|
1524 | int numRequiredOverlayCriteria = sizeof(requiredOverlayCriteria) / sizeof(Criterion);
|
---|
1525 | int requiredOverlayCriteriaMask =
|
---|
1526 | (1 << LEVEL) | (1 << TRANSPARENT) | (1 << XSTATICGRAY) | (1 << RGBA) | (1 << CI_MODE);
|
---|
1527 |
|
---|
1528 | int
|
---|
1529 | main(int argc, char **argv)
|
---|
1530 | {
|
---|
1531 | Display *dpy;
|
---|
1532 | XVisualInfo *vinfo;
|
---|
1533 | Bool treatAsSingle;
|
---|
1534 | char *str, buffer[1024];
|
---|
1535 | int tty = isatty(fileno(stdin));
|
---|
1536 | int overlay = 0, showconfig = 0;
|
---|
1537 | #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
|
---|
1538 | GLXFBConfigSGIX fbc;
|
---|
1539 | #else
|
---|
1540 | void *fbc;
|
---|
1541 | #endif
|
---|
1542 |
|
---|
1543 | #if !defined(_WIN32) && !defined(__WIN32OS2__)
|
---|
1544 | dpy = XOpenDisplay(NULL);
|
---|
1545 | if (dpy == NULL) {
|
---|
1546 | printf("Could not connect to X server\n");
|
---|
1547 | exit(1);
|
---|
1548 | }
|
---|
1549 | __glutDisplay = dpy;
|
---|
1550 | __glutScreen = DefaultScreen(__glutDisplay);
|
---|
1551 | #endif
|
---|
1552 | while (!feof(stdin)) {
|
---|
1553 | if (tty)
|
---|
1554 | printf("dstr> ");
|
---|
1555 | str = gets(buffer);
|
---|
1556 | if (str) {
|
---|
1557 | printf("\n");
|
---|
1558 | if (!strcmp("v", str)) {
|
---|
1559 | verbose = 1 - verbose;
|
---|
1560 | printf("verbose = %d\n\n", verbose);
|
---|
1561 | } else if (!strcmp("s", str)) {
|
---|
1562 | showconfig = 1 - showconfig;
|
---|
1563 | printf("showconfig = %d\n\n", showconfig);
|
---|
1564 | } else if (!strcmp("o", str)) {
|
---|
1565 | overlay = 1 - overlay;
|
---|
1566 | printf("overlay = %d\n\n", overlay);
|
---|
1567 | } else {
|
---|
1568 | if (overlay) {
|
---|
1569 | vinfo = getVisualInfoFromString(str, &treatAsSingle,
|
---|
1570 | requiredOverlayCriteria, numRequiredOverlayCriteria, requiredOverlayCriteriaMask, (void**) &fbc);
|
---|
1571 | } else {
|
---|
1572 | vinfo = getVisualInfoFromString(str, &treatAsSingle,
|
---|
1573 | requiredWindowCriteria, numRequiredWindowCriteria, requiredWindowCriteriaMask, (void**) &fbc);
|
---|
1574 | }
|
---|
1575 | if (vinfo) {
|
---|
1576 | printf("\n");
|
---|
1577 | if (!tty)
|
---|
1578 | printf("Display string: %s", str);
|
---|
1579 | #ifdef _WIN32 || defined(__WIN32OS2__)
|
---|
1580 | printf("Visual = 0x%x\n", 0);
|
---|
1581 | #else
|
---|
1582 | printf("Visual = 0x%x%s\n", vinfo->visualid, fbc ? " (needs FBC)" : "");
|
---|
1583 | #endif
|
---|
1584 | if (treatAsSingle) {
|
---|
1585 | printf("Treat as SINGLE.\n");
|
---|
1586 | }
|
---|
1587 | if (showconfig) {
|
---|
1588 | int glxCapable, bufferSize, level, renderType, doubleBuffer,
|
---|
1589 | stereo, auxBuffers, redSize, greenSize, blueSize,
|
---|
1590 | alphaSize, depthSize, stencilSize, acRedSize, acGreenSize,
|
---|
1591 | acBlueSize, acAlphaSize;
|
---|
1592 |
|
---|
1593 | glXGetConfig(dpy, vinfo, GLX_BUFFER_SIZE, &bufferSize);
|
---|
1594 | glXGetConfig(dpy, vinfo, GLX_LEVEL, &level);
|
---|
1595 | glXGetConfig(dpy, vinfo, GLX_RGBA, &renderType);
|
---|
1596 | glXGetConfig(dpy, vinfo, GLX_DOUBLEBUFFER, &doubleBuffer);
|
---|
1597 | glXGetConfig(dpy, vinfo, GLX_STEREO, &stereo);
|
---|
1598 | glXGetConfig(dpy, vinfo, GLX_AUX_BUFFERS, &auxBuffers);
|
---|
1599 | glXGetConfig(dpy, vinfo, GLX_RED_SIZE, &redSize);
|
---|
1600 | glXGetConfig(dpy, vinfo, GLX_GREEN_SIZE, &greenSize);
|
---|
1601 | glXGetConfig(dpy, vinfo, GLX_BLUE_SIZE, &blueSize);
|
---|
1602 | glXGetConfig(dpy, vinfo, GLX_ALPHA_SIZE, &alphaSize);
|
---|
1603 | glXGetConfig(dpy, vinfo, GLX_DEPTH_SIZE, &depthSize);
|
---|
1604 | glXGetConfig(dpy, vinfo, GLX_STENCIL_SIZE, &stencilSize);
|
---|
1605 | glXGetConfig(dpy, vinfo, GLX_ACCUM_RED_SIZE, &acRedSize);
|
---|
1606 | glXGetConfig(dpy, vinfo, GLX_ACCUM_GREEN_SIZE, &acGreenSize);
|
---|
1607 | glXGetConfig(dpy, vinfo, GLX_ACCUM_BLUE_SIZE, &acBlueSize);
|
---|
1608 | glXGetConfig(dpy, vinfo, GLX_ACCUM_ALPHA_SIZE, &acAlphaSize);
|
---|
1609 | printf("RGBA = (%d, %d, %d, %d)\n", redSize, greenSize, blueSize, alphaSize);
|
---|
1610 | printf("acc = (%d, %d, %d, %d)\n", acRedSize, acGreenSize, acBlueSize, acAlphaSize);
|
---|
1611 | printf("db = %d\n", doubleBuffer);
|
---|
1612 | printf("str = %d\n", stereo);
|
---|
1613 | printf("aux = %d\n", auxBuffers);
|
---|
1614 | printf("lvl = %d\n", level);
|
---|
1615 | printf("buf = %d\n", bufferSize);
|
---|
1616 | printf("rgba = %d\n", renderType);
|
---|
1617 | printf("z = %d\n", depthSize);
|
---|
1618 | printf("s = %d\n", stencilSize);
|
---|
1619 | }
|
---|
1620 | } else {
|
---|
1621 | printf("\n");
|
---|
1622 | printf("No match.\n");
|
---|
1623 | }
|
---|
1624 | printf("\n");
|
---|
1625 | }
|
---|
1626 | }
|
---|
1627 | }
|
---|
1628 | printf("\n");
|
---|
1629 | return 0;
|
---|
1630 | }
|
---|
1631 | #endif
|
---|