Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
macx_dstr.m
/* Copyright (c) Mark J. Kilgard, 1994. */ |
/* Copyright (c) Dietmar Planitzer, 2002 */ |
/* This program is freely distributable without licensing fees |
and is provided without guarantee or warrantee expressed or |
implied. This program is -not- in the public domain. */ |
#import <OpenGL/OpenGL.h> |
#import <OpenGL/CGLTypes.h> |
#import "macx_glut.h" |
char *__glutDisplayString = NULL; |
// #define TEST 1 |
#ifdef TEST |
static int verbose = 0; |
static char *compstr[] = |
{ |
"none", "=", "!=", "<=", ">=", ">", "<", "~" |
}; |
static char *capstr[] = |
{ |
"rgba", "bufsize", "double", "stereo", "auxbufs", "red", "green", "blue", "alpha", |
"depth", "stencil", "acred", "acgreen", "acblue", "acalpha", "level", "xvisual", |
"transparent", "samples", "xstaticgray", "xgrayscale", "xstaticcolor", "xpseudocolor", |
"xtruecolor", "xdirectcolor", "slow", "conformant", "num" |
}; |
static void printCriteria(Criterion *criteria, int ncriteria) |
{ |
int i; |
printf("Criteria: %d\n", ncriteria); |
for (i = 0; i < ncriteria; i++) { |
printf(" %s %s %d\n", |
capstr[criteria[i].capability], |
compstr[criteria[i].comparison], |
criteria[i].value); |
} |
} |
#endif /* TEST */ |
////////////////////////// |
static int gWeightsLoaded = 0; |
static int gMinStencil = INT_MAX, gMaxStencil = 0; |
static int gMinDepth = INT_MAX, gMaxDepth = 0; |
static int gMaxAuxBufs = 0; |
static int gMinSamples = INT_MAX, gMaxSamples = 0; |
static int gMaxColor = 0, gMaxAlpha = 0; |
static int gMaxAccumColor = 0, gMaxAccumAlpha = 0; |
#define MAX_BITS 17 |
static char gBitTable[MAX_BITS] = { |
0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 24, 32, 48, 64, |
96, 128 |
}; |
#define MAX_BITS2 24 |
#define COLOR_BITS 0 |
#define ALPHA_BITS 1 |
static char gBitTable2[MAX_BITS2][2] = { |
{0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {0,0}, {4,0}, {4,4}, |
{4,8}, {5,0}, {5,1}, {5,8}, {6,0}, {6,8}, {8,0}, {8,8}, |
{8,8}, {10,0}, {10,2}, {10,8}, {12,0}, {12,12}, {16,0}, |
{16,16} |
}; |
static int maskToMinWeight(int mask) |
{ |
int i; |
int n = INT_MAX; |
for(i = 0; i < MAX_BITS; i++) { |
if(mask & (1L << i)) { |
n = MIN(n, (int) gBitTable[i]); |
} |
} |
return n; |
} |
static int maskToMaxWeight(int mask) |
{ |
int i; |
int n = 0; |
for(i = 0; i < MAX_BITS; i++) { |
if(mask & (1L << i)) { |
n = MAX(n, (int) gBitTable[i]); |
} |
} |
return n; |
} |
static void maskToMaxWeight2(int mask, int *clr, int *alp) |
{ |
int i; |
int n = 0; |
for(i = 0; i < MAX_BITS2; i++) { |
if(mask & (1L << i)) { |
n = MAX(n, (int) gBitTable2[i][COLOR_BITS]); |
} |
} |
*clr = n; |
n = 0; |
for(i = 0; i < MAX_BITS2; i++) { |
if(mask & (1L << i)) { |
n = MAX(n, (int) gBitTable2[i][ALPHA_BITS]); |
} |
} |
*alp = n; |
} |
static void loadMinMaxWeights(void) |
{ |
int n, color, alpha; |
CGLError err; |
CGLRendererInfoObj rend; |
int i, nrend, value; |
/* get renderer info */ |
err = CGLQueryRendererInfo(CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), &rend, &nrend); |
if(err) { |
__glutFatalError("failed to acquire renderer infos (%d)", err); |
} |
/* determine min and max weights for stencil, depth, aux buffers... */ |
n = 0; |
for(i = 0; i < nrend; i++) { |
CGLDescribeRenderer(rend, i, kCGLRPWindow, &value); |
if(value) { |
CGLDescribeRenderer(rend, i, kCGLRPColorModes, &value); |
maskToMaxWeight2(value, &color, &alpha); |
gMaxColor = MAX(color, gMaxColor); |
gMaxAlpha = MAX(alpha, gMaxAlpha); |
CGLDescribeRenderer(rend, i, kCGLRPAccumModes, &value); |
maskToMaxWeight2(value, &color, &alpha); |
gMaxAccumColor = MAX(color, gMaxAccumColor); |
gMaxAccumAlpha = MAX(alpha, gMaxAccumAlpha); |
CGLDescribeRenderer(rend, i, kCGLRPDepthModes, &value); |
gMinDepth = MIN(maskToMinWeight(value), gMinDepth); |
gMaxDepth = MAX(maskToMaxWeight(value), gMaxDepth); |
CGLDescribeRenderer(rend, i, kCGLRPStencilModes, &value); |
gMinStencil = MIN(maskToMinWeight(value), gMinStencil); |
gMaxStencil = MAX(maskToMaxWeight(value), gMaxStencil); |
CGLDescribeRenderer(rend, i, kCGLRPMaxAuxBuffers, &value); |
gMaxAuxBufs = MAX(value, gMaxAuxBufs); |
CGLDescribeRenderer(rend, i, kCGLRPMaxSampleBuffers, &value); |
if(value > 0) { |
CGLDescribeRenderer(rend, i, kCGLRPMaxSamples, &value); |
gMinSamples = MIN(value, gMinSamples); |
gMaxSamples = MAX(value, gMaxSamples); |
} |
} |
} |
if(gMinSamples == INT_MAX) { |
gMinSamples = 0; |
gMaxSamples = 0; |
} |
/* free renderer info */ |
CGLDestroyRendererInfo(rend); |
} |
////////////////////////// |
static BOOL requestsBestFormat(Criterion *criteria) |
{ |
switch(criteria->comparison) { |
case CMP_EQ: |
case CMP_LTE: |
return (1 == criteria->value); |
case CMP_LT: |
return (2 == criteria->value); |
} |
return NO; |
} |
static int weightForCriterion(Criterion *criteria, int minWeight, int maxWeight) |
{ |
switch(criteria->comparison) { |
case CMP_EQ: |
return criteria->value; |
case CMP_NEQ: |
return maxWeight - criteria->value; |
case CMP_LT: |
case CMP_LTE: |
return minWeight; |
case CMP_GT: |
case CMP_GTE: |
return maxWeight; |
case CMP_MIN: |
return criteria->value; |
} |
return 0; |
} |
static NSOpenGLPixelFormat *findMatch(Criterion *criteria, int ncriteria, int mask, BOOL gameMode) |
{ |
NSOpenGLPixelFormatAttribute list[64]; |
int i, n; |
int redWeight = 0, greenWeight = 0, blueWeight = 0, alphaWeight = 0; |
int redWeightA = 0, greenWeightA = 0, blueWeightA = 0, alphaWeightA = 0; |
if((mask & (1 << CI_MODE)) || (mask & (1 << LUMINANCE_MODE))) |
return nil; |
if(!(mask & (1 << RGBA_MODE))) |
return nil; |
/* Build a pixel format attribute list based on criterion weights */ |
n = 0; |
for(i = 0; i < ncriteria; i++) { |
switch(criteria[i].capability) { |
case DOUBLEBUFFER: |
if(weightForCriterion(&criteria[i], 0, 1) > 0) |
list[n++] = NSOpenGLPFADoubleBuffer; |
break; |
case STEREO: |
if(weightForCriterion(&criteria[i], 0, 1) > 0) |
list[n++] = NSOpenGLPFAStereo; |
break; |
case AUX_BUFFERS: |
list[n++] = NSOpenGLPFAAuxBuffers; |
list[n++] = weightForCriterion(&criteria[i], 0, gMaxAuxBufs); |
break; |
case RED_SIZE: |
redWeight = weightForCriterion(&criteria[i], 0, gMaxColor); |
break; |
case GREEN_SIZE: |
greenWeight = weightForCriterion(&criteria[i], 0, gMaxColor); |
break; |
case BLUE_SIZE: |
blueWeight = weightForCriterion(&criteria[i], 0, gMaxColor); |
break; |
case ALPHA_SIZE: |
alphaWeight = weightForCriterion(&criteria[i], 0, gMaxAlpha); |
break; |
case DEPTH_SIZE: |
list[n++] = NSOpenGLPFADepthSize; |
list[n++] = weightForCriterion(&criteria[i], gMinDepth, gMaxDepth); |
break; |
case STENCIL_SIZE: |
list[n++] = NSOpenGLPFAStencilSize; |
list[n++] = weightForCriterion(&criteria[i], gMinStencil, gMaxStencil); |
break; |
case ACCUM_RED_SIZE: |
redWeightA = weightForCriterion(&criteria[i], 0, gMaxAccumColor); |
break; |
case ACCUM_GREEN_SIZE: |
greenWeightA = weightForCriterion(&criteria[i], 0, gMaxAccumColor); |
break; |
case ACCUM_BLUE_SIZE: |
blueWeightA = weightForCriterion(&criteria[i], 0, gMaxAccumColor); |
break; |
case ACCUM_ALPHA_SIZE: |
alphaWeightA = weightForCriterion(&criteria[i], 0, gMaxAccumAlpha); |
break; |
case SAMPLES: |
if(weightForCriterion(&criteria[i], gMinSamples, gMaxSamples) > 0) { |
list[n++] = kCGLPFASampleBuffers; // since app kit does not export these yet |
list[n++] = 1; |
list[n++] = kCGLPFASamples; // since app kit does not export these yet |
list[n++] = weightForCriterion(&criteria[i], gMinSamples, gMaxSamples); |
list[n++] = NSOpenGLPFANoRecovery; |
} |
break; |
case SLOW: |
if(weightForCriterion(&criteria[i], 0, 1) == 0) |
list[n++] = NSOpenGLPFAAccelerated; |
break; |
case CONFORMANT: |
if(weightForCriterion(&criteria[i], 0, 1) > 0) |
list[n++] = NSOpenGLPFACompliant; |
break; |
case NUM: |
/* We only accept framebuffer config 1 (best) */ |
if(!requestsBestFormat(&criteria[i])) |
return nil; |
case NO_RECOVERY: |
if(weightForCriterion(&criteria[i], 0, 1) > 0) |
list[n++] = NSOpenGLPFANoRecovery; |
break; |
default: |
/* do nothing */ |
break; |
} |
} |
if (redWeight || greenWeight || blueWeight || alphaWeight) { // if they are trying to set any color or alpha size |
list[n++] = NSOpenGLPFAColorSize; |
if ((redWeight > 5) || (greenWeight > 5) || (blueWeight> 5) || (alphaWeight > 1)) { |
list[n++] = 32; |
} else { |
list[n++] = 16; |
} |
list[n++] = NSOpenGLPFAClosestPolicy; |
} |
if (redWeightA || greenWeightA || blueWeightA || alphaWeightA) { // if they are trying to set any color or alpha size |
list[n++] = NSOpenGLPFAAccumSize; |
if ((redWeightA > 8) || (greenWeightA > 8) || (blueWeightA > 8) || (alphaWeightA > 8)) { |
list[n++] = 64; |
} else { |
list[n++] = 32; |
} |
} |
if(gameMode) { |
list[n++] = NSOpenGLPFAScreenMask; |
list[n++] = CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay); |
list[n++] = NSOpenGLPFAColorSize; |
list[n++] = __glutGetCurrentDMDepth (); |
list[n++] = NSOpenGLPFAClosestPolicy; // add any time color depth is used |
} |
list[n] = 0; |
#ifdef TEST |
__glutDumpPixelFormatAttributes(list); |
#endif |
return [[[NSOpenGLPixelFormat alloc] initWithAttributes: list] autorelease]; |
} |
/////////////////////////////////// |
static int parseCriteria(char *word, Criterion *criterion, int *mask, BOOL *allowDoubleAsSingle) |
{ |
char * cstr, *vstr, *response; |
int comparator, value = 0; |
int rgb, rgba, acc, acca, count, i; |
cstr = strpbrk(word, "=><!~"); |
if (cstr) { |
switch (cstr[0]) { |
case '=': |
comparator = CMP_EQ; |
vstr = &cstr[1]; |
break; |
case '~': |
comparator = CMP_MIN; |
vstr = &cstr[1]; |
break; |
case '>': |
if (cstr[1] == '=') { |
comparator = CMP_GTE; |
vstr = &cstr[2]; |
} else { |
comparator = CMP_GT; |
vstr = &cstr[1]; |
} |
break; |
case '<': |
if (cstr[1] == '=') { |
comparator = CMP_LTE; |
vstr = &cstr[2]; |
} else { |
comparator = CMP_LT; |
vstr = &cstr[1]; |
} |
break; |
case '!': |
if (cstr[1] == '=') { |
comparator = CMP_NEQ; |
vstr = &cstr[2]; |
} else { |
return -1; |
} |
break; |
default: |
return -1; |
} |
value = (int) strtol(vstr, &response, 0); |
if (response == vstr) { |
/* Not a valid number. */ |
return -1; |
} |
*cstr = '\0'; |
} else { |
comparator = CMP_NONE; |
} |
switch (word[0]) { |
case 'a': |
if (!strcmp(word, "alpha")) { |
criterion[0].capability = ALPHA_SIZE; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_GTE; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << RGBA); |
*mask |= (1 << ALPHA_SIZE); |
*mask |= (1 << RGBA_MODE); |
return 1; |
} |
acca = !strcmp(word, "acca"); |
acc = !strcmp(word, "acc"); |
if (acc || acca) { |
criterion[0].capability = ACCUM_RED_SIZE; |
criterion[1].capability = ACCUM_GREEN_SIZE; |
criterion[2].capability = ACCUM_BLUE_SIZE; |
criterion[3].capability = ACCUM_ALPHA_SIZE; |
if (acca) { |
count = 4; |
} else { |
count = 3; |
criterion[3].comparison = CMP_MIN; |
criterion[3].value = 0; |
} |
if (comparator == CMP_NONE) { |
comparator = CMP_GTE; |
value = 8; |
} |
for (i = 0; i < count; i++) { |
criterion[i].comparison = comparator; |
criterion[i].value = value; |
} |
*mask |= (1 << ACCUM_RED_SIZE); |
return 4; |
} |
if (!strcmp(word, "auxbufs")) { |
criterion[0].capability = AUX_BUFFERS; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_MIN; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << AUX_BUFFERS); |
return 1; |
} |
return -1; |
case 'b': |
if (!strcmp(word, "blue")) { |
criterion[0].capability = BLUE_SIZE; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_GTE; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << RGBA); |
*mask |= (1 << RGBA_MODE); |
return 1; |
} |
if (!strcmp(word, "buffer")) { |
criterion[0].capability = BUFFER_SIZE; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_GTE; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
return 1; |
} |
return -1; |
case 'c': |
if (!strcmp(word, "conformant")) { |
criterion[0].capability = CONFORMANT; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << CONFORMANT); |
return 1; |
} |
return -1; |
case 'd': |
if (!strcmp(word, "depth")) { |
criterion[0].capability = DEPTH_SIZE; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_GTE; |
criterion[0].value = 12; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << DEPTH_SIZE); |
return 1; |
} |
if (!strcmp(word, "double")) { |
criterion[0].capability = DOUBLEBUFFER; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << DOUBLEBUFFER); |
return 1; |
} |
return -1; |
case 'g': |
if (!strcmp(word, "green")) { |
criterion[0].capability = GREEN_SIZE; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_GTE; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << RGBA); |
*mask |= (1 << RGBA_MODE); |
return 1; |
} |
return -1; |
case 'i': |
if (!strcmp(word, "index")) { |
criterion[0].capability = RGBA; |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 0; |
*mask |= (1 << RGBA); |
*mask |= (1 << CI_MODE); |
criterion[1].capability = BUFFER_SIZE; |
if (comparator == CMP_NONE) { |
criterion[1].comparison = CMP_GTE; |
criterion[1].value = 1; |
} else { |
criterion[1].comparison = comparator; |
criterion[1].value = value; |
} |
return 2; |
} |
return -1; |
case 'l': |
if (!strcmp(word, "luminance")) { |
criterion[0].capability = RGBA; |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 1; |
criterion[1].capability = RED_SIZE; |
if (comparator == CMP_NONE) { |
criterion[1].comparison = CMP_GTE; |
criterion[1].value = 1; |
} else { |
criterion[1].comparison = comparator; |
criterion[1].value = value; |
} |
criterion[2].capability = GREEN_SIZE; |
criterion[2].comparison = CMP_EQ; |
criterion[2].value = 0; |
criterion[3].capability = BLUE_SIZE; |
criterion[3].comparison = CMP_EQ; |
criterion[3].value = 0; |
*mask |= (1 << RGBA); |
*mask |= (1 << RGBA_MODE); |
*mask |= (1 << LUMINANCE_MODE); |
return 4; |
} |
return -1; |
case 'n': |
if (!strcmp(word, "num")) { |
criterion[0].capability = NUM; |
if (comparator == CMP_NONE) { |
return -1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
return 1; |
} |
} |
else if(!strcmp(word, "no_recovery")) { |
criterion[0].capability = NO_RECOVERY; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << NO_RECOVERY); |
return 1; |
} |
return -1; |
case 'r': |
if (!strcmp(word, "red")) { |
criterion[0].capability = RED_SIZE; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_GTE; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << RGBA); |
*mask |= (1 << RGBA_MODE); |
return 1; |
} |
rgba = !strcmp(word, "rgba"); |
rgb = !strcmp(word, "rgb"); |
if (rgb || rgba) { |
criterion[0].capability = RGBA; |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 1; |
/* do not add color sizes |
criterion[1].capability = RED_SIZE; |
criterion[2].capability = GREEN_SIZE; |
criterion[3].capability = BLUE_SIZE; |
criterion[4].capability = ALPHA_SIZE; |
if (rgba) { |
count = 5; |
} else { |
count = 4; |
criterion[4].comparison = CMP_MIN; |
criterion[4].value = 0; |
} |
if (comparator == CMP_NONE) { |
comparator = CMP_GTE; |
value = 1; |
} |
for (i = 1; i < count; i++) { |
criterion[i].comparison = comparator; |
criterion[i].value = value; |
} |
*/ |
*mask |= (1 << RGBA); |
*mask |= (1 << RGBA_MODE); |
return 1; |
} |
return -1; |
case 's': |
if (!strcmp(word, "stencil")) { |
criterion[0].capability = STENCIL_SIZE; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_MIN; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << STENCIL_SIZE); |
return 1; |
} |
if (!strcmp(word, "single")) { |
criterion[0].capability = DOUBLEBUFFER; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 0; |
*allowDoubleAsSingle = YES; |
*mask |= (1 << DOUBLEBUFFER); |
return 1; |
} else { |
return -1; |
} |
} |
if (!strcmp(word, "stereo")) { |
criterion[0].capability = STEREO; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_EQ; |
criterion[0].value = 1; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << STEREO); |
return 1; |
} |
if (!strcmp(word, "samples")) { |
criterion[0].capability = SAMPLES; |
if (comparator == CMP_NONE) { |
criterion[0].comparison = CMP_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 == CMP_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 = CMP_GTE; |
criterion[0].value = 0; |
} else { |
criterion[0].comparison = comparator; |
criterion[0].value = value; |
} |
*mask |= (1 << SLOW); |
return 1; |
} |
return -1; |
default: |
return -1; |
} |
} |
static Criterion *parseModeString(char *mode, int *ncriteria, BOOL *allowDoubleAsSingle, int *pmask) |
{ |
Criterion * criteria = NULL; |
int n = 0, mask = 0, parsed; |
char * copy, *word; |
*allowDoubleAsSingle = NO; |
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) * sizeof(Criterion)); |
if (!criteria) { |
__glutFatalError("out of memory."); |
} |
/* Re-copy the copy of the mode string. */ |
strcpy(copy, mode); |
n = 0; |
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"); |
} |
/* do not add "default" criteria */ |
/* |
if (!(mask & (1 << SAMPLES))) { |
criteria[n].capability = SAMPLES; |
criteria[n].comparison = CMP_EQ; |
criteria[n].value = 0; |
n++; |
} |
if (!(mask & (1 << ACCUM_RED_SIZE))) { |
criteria[n].capability = ACCUM_RED_SIZE; |
criteria[n].comparison = CMP_MIN; |
criteria[n].value = 0; |
criteria[n + 1].capability = ACCUM_GREEN_SIZE; |
criteria[n + 1].comparison = CMP_MIN; |
criteria[n + 1].value = 0; |
criteria[n + 2].capability = ACCUM_BLUE_SIZE; |
criteria[n + 2].comparison = CMP_MIN; |
criteria[n + 2].value = 0; |
criteria[n + 3].capability = ACCUM_ALPHA_SIZE; |
criteria[n + 3].comparison = CMP_MIN; |
criteria[n + 3].value = 0; |
n += 4; |
} |
if (!(mask & (1 << AUX_BUFFERS))) { |
criteria[n].capability = AUX_BUFFERS; |
criteria[n].comparison = CMP_MIN; |
criteria[n].value = 0; |
n++; |
} |
if (!(mask & (1 << RGBA))) { |
criteria[n].capability = RGBA; |
criteria[n].comparison = CMP_EQ; |
criteria[n].value = 1; |
criteria[n + 1].capability = RED_SIZE; |
criteria[n + 1].comparison = CMP_GTE; |
criteria[n + 1].value = 1; |
criteria[n + 2].capability = GREEN_SIZE; |
criteria[n + 2].comparison = CMP_GTE; |
criteria[n + 2].value = 1; |
criteria[n + 3].capability = BLUE_SIZE; |
criteria[n + 3].comparison = CMP_GTE; |
criteria[n + 3].value = 1; |
criteria[n + 4].capability = ALPHA_SIZE; |
criteria[n + 4].comparison = CMP_MIN; |
criteria[n + 4].value = 0; |
n += 5; |
mask |= (1 << RGBA_MODE); |
} |
if (!(mask & (1 << STEREO))) { |
criteria[n].capability = STEREO; |
criteria[n].comparison = CMP_EQ; |
criteria[n].value = 0; |
n++; |
} |
if (!(mask & (1 << DOUBLEBUFFER))) { |
criteria[n].capability = DOUBLEBUFFER; |
criteria[n].comparison = CMP_EQ; |
criteria[n].value = 0; |
*allowDoubleAsSingle = YES; |
n++; |
} |
if (!(mask & (1 << DEPTH_SIZE))) { |
criteria[n].capability = DEPTH_SIZE; |
criteria[n].comparison = CMP_MIN; |
criteria[n].value = 0; |
n++; |
} |
if (!(mask & (1 << STENCIL_SIZE))) { |
criteria[n].capability = STENCIL_SIZE; |
criteria[n].comparison = CMP_MIN; |
criteria[n].value = 0; |
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."); |
} |
free(copy); |
*ncriteria = n; |
*pmask = mask; |
return criteria; |
} |
NSOpenGLPixelFormat *__glutDeterminePixelFormatFromString(char *string, BOOL *treatAsSingle, BOOL gameMode) |
{ |
Criterion * criteria; |
NSOpenGLPixelFormat * pixFmt = nil; |
BOOL allowDoubleAsSingle; |
int ncriteria, i, mask; |
if(!gWeightsLoaded) { |
loadMinMaxWeights(); |
gWeightsLoaded = 1; |
} |
criteria = parseModeString(string, &ncriteria, &allowDoubleAsSingle, &mask); |
if (criteria == NULL) { |
__glutWarning("failed to parse mode string"); |
return NULL; |
} |
#ifdef TEST |
printCriteria(criteria, ncriteria); |
#endif |
pixFmt = findMatch(criteria, ncriteria, mask, gameMode); |
if(pixFmt) { |
*treatAsSingle = NO; |
} 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 == CMP_EQ |
&& criteria[i].value == 0) { |
criteria[i].value = 1; |
} |
} |
pixFmt = findMatch(criteria, ncriteria, mask, gameMode); |
if(pixFmt) { |
*treatAsSingle = YES; |
} |
} |
} |
free(criteria); |
return pixFmt; |
} |
/* CENTRY */ |
void APIENTRY glutInitDisplayString(const char *string) |
{ |
if (__glutDisplayString) { |
free(__glutDisplayString); |
} |
if (string) { |
__glutDisplayString = __glutStrdup(string); |
if (!__glutDisplayString) |
__glutFatalError("out of memory."); |
} else { |
__glutDisplayString = NULL; |
} |
} |
/* ENDCENTRY */ |
Copyright © 2008 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2008-02-08