📄 glut_dstr.c
字号:
criterion[0].comparison = comparator; criterion[0].value = value; } *mask |= (1 << STEREO); return 1; } if (!strcmp(word, "samples")) { criterion[0].capability = SAMPLES; if (comparator == NONE) { criterion[0].comparison = LTE; criterion[0].value = 4; } else { criterion[0].comparison = comparator; criterion[0].value = value; } *mask |= (1 << SAMPLES); return 1; } if (!strcmp(word, "slow")) { criterion[0].capability = SLOW; if (comparator == NONE) { /* Just "slow" means permit fast visuals, but accept slow ones in preference. Presumably the slow ones must be higher quality or something else desirable. */ criterion[0].comparison = GTE; criterion[0].value = 0; } else { criterion[0].comparison = comparator; criterion[0].value = value; } *mask |= (1 << SLOW); return 1; } return -1;#if defined(_WIN32) case 'w': if (!strcmp(word, "win32pfd")) { criterion[0].capability = XVISUAL; if (comparator == NONE) { return -1; } else { criterion[0].comparison = comparator; criterion[0].value = value; return 1; } } return -1;#endif#if !defined(_WIN32) case 'x': if (!strcmp(word, "xvisual")) { if (comparator == NONE) { return -1; } else { criterion[0].capability = XVISUAL; criterion[0].comparison = comparator; criterion[0].value = value; /* Set everything in "mask" so that no default criteria get used. Assume the program really wants the xvisual specified. */ *mask |= ~0; return 1; } } /* Be a little over-eager to fill in the comparison and value so we won't have to replicate the code after each string match. */ if (comparator == NONE) { criterion[0].comparison = EQ; criterion[0].value = 1; } else { criterion[0].comparison = comparator; criterion[0].value = value; } if (!strcmp(word, "xstaticgray")) { criterion[0].capability = XSTATICGRAY; *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual class selected. */ return 1; } if (!strcmp(word, "xgrayscale")) { criterion[0].capability = XGRAYSCALE; *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual class selected. */ return 1; } if (!strcmp(word, "xstaticcolor")) { criterion[0].capability = XSTATICCOLOR; *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual class selected. */ return 1; } if (!strcmp(word, "xpseudocolor")) { criterion[0].capability = XPSEUDOCOLOR; *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual class selected. */ return 1; } if (!strcmp(word, "xtruecolor")) { criterion[0].capability = XTRUECOLOR; *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual class selected. */ return 1; } if (!strcmp(word, "xdirectcolor")) { criterion[0].capability = XDIRECTCOLOR; *mask |= (1 << XSTATICGRAY); /* Indicates _any_ visual class selected. */ return 1; } return -1;#endif default: return -1; }}static Criterion *parseModeString(char *mode, int *ncriteria, Bool * allowDoubleAsSingle, Criterion * requiredCriteria, int nRequired, int requiredMask){ Criterion *criteria = NULL; int n, mask, parsed, i; char *copy, *word; *allowDoubleAsSingle = False; copy = __glutStrdup(mode); /* Attempt to estimate how many criteria entries should be needed. */ n = 0; word = strtok(copy, " \t"); while (word) { n++; word = strtok(NULL, " \t"); } /* Overestimate by 4 times ("rgba" might add four criteria entries) plus add in possible defaults plus space for required criteria. */ criteria = (Criterion *) malloc((4 * n + 30 + nRequired) * sizeof(Criterion)); if (!criteria) { __glutFatalError("out of memory."); } /* Re-copy the copy of the mode string. */ strcpy(copy, mode); /* First add the required criteria (these match at the highest priority). Typically these will be used to force a specific level (layer), transparency, and/or visual type. */ mask = requiredMask; for (i = 0; i < nRequired; i++) { criteria[i] = requiredCriteria[i]; } n = nRequired; word = strtok(copy, " \t"); while (word) { parsed = parseCriteria(word, &criteria[n], &mask, allowDoubleAsSingle); if (parsed >= 0) { n += parsed; } else { __glutWarning("Unrecognized display string word: %s (ignoring)\n", word); } word = strtok(NULL, " \t"); }#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample) if (__glutIsSupportedByGLX("GLX_SGIS_multisample")) { if (!(mask & (1 << SAMPLES))) { criteria[n].capability = SAMPLES; criteria[n].comparison = EQ; criteria[n].value = 0; n++; } else { /* Multisample visuals are marked nonconformant. If multisampling was requeste and no conformant preference was set, assume that we will settle for a non-conformant visual to get multisampling. */ if (!(mask & (1 << CONFORMANT))) { criteria[n].capability = CONFORMANT; criteria[n].comparison = MIN; criteria[n].value = 0; n++; mask |= (1 << CONFORMANT); } } }#endif#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) if (__glutIsSupportedByGLX("GLX_EXT_visual_info")) { if (!(mask & (1 << TRANSPARENT))) { criteria[n].capability = TRANSPARENT; criteria[n].comparison = EQ; criteria[n].value = 0; n++; } }#endif#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_rating) if (__glutIsSupportedByGLX("GLX_EXT_visual_rating")) { if (!(mask & (1 << SLOW))) { criteria[n].capability = SLOW; criteria[n].comparison = EQ; criteria[n].value = 0; n++; } if (!(mask & (1 << CONFORMANT))) { criteria[n].capability = CONFORMANT; criteria[n].comparison = EQ; criteria[n].value = 1; n++; } }#endif if (!(mask & (1 << ACCUM_RED_SIZE))) { criteria[n].capability = ACCUM_RED_SIZE; criteria[n].comparison = MIN; criteria[n].value = 0; criteria[n + 1].capability = ACCUM_GREEN_SIZE; criteria[n + 1].comparison = MIN; criteria[n + 1].value = 0; criteria[n + 2].capability = ACCUM_BLUE_SIZE; criteria[n + 2].comparison = MIN; criteria[n + 2].value = 0; criteria[n + 3].capability = ACCUM_ALPHA_SIZE; criteria[n + 3].comparison = MIN; criteria[n + 3].value = 0; n += 4; } if (!(mask & (1 << AUX_BUFFERS))) { criteria[n].capability = AUX_BUFFERS; criteria[n].comparison = MIN; criteria[n].value = 0; n++; } if (!(mask & (1 << RGBA))) { criteria[n].capability = RGBA; criteria[n].comparison = EQ; criteria[n].value = 1; criteria[n + 1].capability = RED_SIZE; criteria[n + 1].comparison = GTE; criteria[n + 1].value = 1; criteria[n + 2].capability = GREEN_SIZE; criteria[n + 2].comparison = GTE; criteria[n + 2].value = 1; criteria[n + 3].capability = BLUE_SIZE; criteria[n + 3].comparison = GTE; criteria[n + 3].value = 1; criteria[n + 4].capability = ALPHA_SIZE; criteria[n + 4].comparison = MIN; criteria[n + 4].value = 0; n += 5; mask |= (1 << RGBA_MODE); }#if !defined(_WIN32) if (!(mask & (1 << XSTATICGRAY))) { assert(isMesaGLX != -1); if ((mask & (1 << RGBA_MODE)) && !isMesaGLX) { /* Normally, request an RGBA mode visual be TrueColor, except in the case of Mesa where we trust Mesa (and other code in GLUT) to handle any type of RGBA visual reasonably. */ if (mask & (1 << LUMINANCE_MODE)) { /* If RGBA luminance was requested, actually go for a StaticGray visual. */ criteria[n].capability = XSTATICGRAY; } else { criteria[n].capability = XTRUECOLOR; } criteria[n].value = 1; criteria[n].comparison = EQ; n++; } if (mask & (1 << CI_MODE)) { criteria[n].capability = XPSEUDOCOLOR; criteria[n].value = 1; criteria[n].comparison = EQ; n++; } }#endif if (!(mask & (1 << STEREO))) { criteria[n].capability = STEREO; criteria[n].comparison = EQ; criteria[n].value = 0; n++; } if (!(mask & (1 << DOUBLEBUFFER))) { criteria[n].capability = DOUBLEBUFFER; criteria[n].comparison = EQ; criteria[n].value = 0; *allowDoubleAsSingle = True; n++; } if (!(mask & (1 << DEPTH_SIZE))) { criteria[n].capability = DEPTH_SIZE; criteria[n].comparison = MIN; criteria[n].value = 0; n++; } if (!(mask & (1 << STENCIL_SIZE))) { criteria[n].capability = STENCIL_SIZE; criteria[n].comparison = MIN; criteria[n].value = 0; n++; } if (!(mask & (1 << LEVEL))) { criteria[n].capability = LEVEL; criteria[n].comparison = EQ; criteria[n].value = 0; n++; } if (n) { /* Since over-estimated the size needed; squeeze it down to reality. */ criteria = (Criterion *) realloc(criteria, n * sizeof(Criterion)); if (!criteria) { /* Should never happen since should be shrinking down! */ __glutFatalError("out of memory."); } } else { /* For portability, avoid "realloc(ptr,0)" call. */ free(criteria); criteria = NULL; } free(copy); *ncriteria = n; return criteria;}static FrameBufferMode *fbmodes = NULL;static int nfbmodes = 0;static XVisualInfo *getVisualInfoFromString(char *string, Bool * treatAsSingle, Criterion * requiredCriteria, int nRequired, int requiredMask, void **fbc){ Criterion *criteria; XVisualInfo *visinfo; Bool allowDoubleAsSingle; int ncriteria, i; if (!fbmodes) { fbmodes = loadVisuals(&nfbmodes); } criteria = parseModeString(string, &ncriteria, &allowDoubleAsSingle, requiredCriteria, nRequired, requiredMask); if (criteria == NULL) { __glutWarning("failed to parse mode string"); return NULL; }#ifdef TEST printCriteria(criteria, ncriteria);#endif visinfo = findMatch(fbmodes, nfbmodes, criteria, ncriteria, fbc); if (visinfo) { *treatAsSingle = 0; } else { if (allowDoubleAsSingle) { /* Rewrite criteria so that we now look for a double buffered visual which will then get treated as a single buffered visual. */ for (i = 0; i < ncriteria; i++) { if (criteria[i].capability == DOUBLEBUFFER && criteria[i].comparison == EQ && criteria[i].value == 0) { criteria[i].value = 1; } } visinfo = findMatch(fbmodes, nfbmodes, criteria, ncriteria, fbc); if (visinfo) { *treatAsSingle = 1; } } } free(criteria); if (visinfo) {#if defined(_WIN32) /* We could have a valid pixel format for drawing to a bitmap. However, we don't want to draw into a bitmap, we need one that can be used with a window, so make sure that this is true. */ if (!(visinfo->dwFlags & PFD_DRAW_TO_WINDOW)) return NULL;#endif return visinfo; } else { return NULL; }}/* CENTRY */void GLUTAPIENTRYglutInitDisplayString(const char *string){#ifdef _WIN32 XHDC = GetDC(GetDesktopWindow());#endif __glutDetermineVisualFromString = getVisualInfoFromString; if (__glutDisplayString) { free(__glutDisplayString); } if (string) { __glutDisplayString = __glutStrdup(string); if (!__glutDisplayString) __glutFatalError("out of memory."); } else { __glutDisplayString = NULL; }}/* ENDCENTRY */#ifdef TESTCriterion requiredWindowCriteria[] ={ {LEVEL, EQ, 0}, {TRANSPARENT, EQ, 0}};int numRequiredWindowCriteria = sizeof(requiredWindowCriteria) / sizeof(Criterion);int requiredWindowCriteriaMask = (1 << LEVEL) | (1 << TRANSPARENT);Criterion requiredOverlayCriteria[] ={ {LEVEL, EQ, 1}, {TRANSPARENT, EQ, 1}, {XPSEUDOCOLOR, EQ, 1}, {RGBA, EQ, 0}, {BUFFER_SIZE, GTE, 1}};int numRequiredOverlayCriteria = sizeof(requiredOverlayCriteria) / sizeof(Criterion);int requiredOverlayCriteriaMask =(1 << LEVEL) | (1 << TRANSPARENT) | (1 << XSTATICGRAY) | (1 << RGBA) | (1 << CI_MODE);intmain(int argc, char **argv){ Display *dpy; XVisualInfo *vinfo; Bool treatAsSingle; char *str, buffer[1024]; int tty = isatty(fileno(stdin)); int overlay = 0, showconfig = 0; void *fbc;#if !defined(_WIN32) dpy = XOpenDisplay(NULL); if (dpy == NULL) { printf("Could not connect to X server\n"); exit(1); } __glutDisplay = dpy; __glutScreen = DefaultScreen(__glutDisplay);#endif while (!feof(stdin)) { if (tty) printf("dstr> "); str = fgets(buffer, 1023, stdin); if (str) { printf("\n"); if (!strcmp("v", str)) { verbose = 1 - verbose; printf("verbose = %d\n\n", verbose); } else if (!strcmp("s", str)) { showconfig = 1 - showconfig; printf("showconfig = %d\n\n", showconfig); } else if (!strcmp("o", str)) { overlay = 1 - overlay; printf("overlay = %d\n\n", overlay); } else { if (overlay) { vinfo = getVisualInfoFromString(str, &treatAsSingle, requiredOverlayCriteria, numRequiredOverlayCriteria, requiredOverlayCriteriaMask, &fbc); } else { vinfo = getVisualInfoFromString(str, &treatAsSingle, requiredWindowCriteria, numRequiredWindowCriteria, requiredWindowCriteriaMask, &fbc); } if (vinfo) { printf("\n"); if (!tty) printf("Display string: %s", str);#ifdef _WIN32 printf("Visual = 0x%x\n", 0);#else printf("Visual = 0x%x%s\n", vinfo->visualid, fbc ? " (needs FBC)" : "");#endif if (treatAsSingle) { printf("Treat as SINGLE.\n"); } if (showconfig) { int glxCapable, bufferSize, level, renderType, doubleBuffer, stereo, auxBuffers, redSize, greenSize, blueSize, alphaSize, depthSize, stencilSize, acRedSize, acGreenSize, acBlueSize, acAlphaSize; glXGetConfig(dpy, vinfo, GLX_BUFFER_SIZE, &bufferSize); glXGetConfig(dpy, vinfo, GLX_LEVEL, &level); glXGetConfig(dpy, vinfo, GLX_RGBA, &renderType); glXGetConfig(dpy, vinfo, GLX_DOUBLEBUFFER, &doubleBuffer); glXGetConfig(dpy, vinfo, GLX_STEREO, &stereo); glXGetConfig(dpy, vinfo, GLX_AUX_BUFFERS, &auxBuffers); glXGetConfig(dpy, vinfo, GLX_RED_SIZE, &redSize); glXGetConfig(dpy, vinfo, GLX_GREEN_SIZE, &greenSize); glXGetConfig(dpy, vinfo, GLX_BLUE_SIZE, &blueSize); glXGetConfig(dpy, vinfo, GLX_ALPHA_SIZE, &alphaSize); glXGetConfig(dpy, vinfo, GLX_DEPTH_SIZE, &depthSize); glXGetConfig(dpy, vinfo, GLX_STENCIL_SIZE, &stencilSize); glXGetConfig(dpy, vinfo, GLX_ACCUM_RED_SIZE, &acRedSize); glXGetConfig(dpy, vinfo, GLX_ACCUM_GREEN_SIZE, &acGreenSize); glXGetConfig(dpy, vinfo, GLX_ACCUM_BLUE_SIZE, &acBlueSize); glXGetConfig(dpy, vinfo, GLX_ACCUM_ALPHA_SIZE, &acAlphaSize); printf("RGBA = (%d, %d, %d, %d)\n", redSize, greenSize, blueSize, alphaSize); printf("acc = (%d, %d, %d, %d)\n", acRedSize, acGreenSize, acBlueSize, acAlphaSize); printf("db = %d\n", doubleBuffer); printf("str = %d\n", stereo); printf("aux = %d\n", auxBuffers); printf("lvl = %d\n", level); printf("buf = %d\n", bufferSize); printf("rgba = %d\n", renderType); printf("z = %d\n", depthSize); printf("s = %d\n", stencilSize); } } else { printf("\n"); printf("No match.\n"); } printf("\n"); } } } printf("\n"); return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -