📄 glut_gamemode.c
字号:
/* Copyright (c) Mark J. Kilgard, 1998. *//* 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. */#ifdef __VMS#include <GL/vms_x_fix.h>#endif#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "glutint.h"#ifndef _WIN32#include <X11/Xlib.h>#include <X11/Xatom.h>/* SGI optimization introduced in IRIX 6.3 to avoid X server round trips for interning common X atoms. */#if defined(_SGI_EXTRA_PREDEFINES) && !defined(NO_FAST_ATOMS)#include <X11/SGIFastAtom.h>#else#define XSGIFastInternAtom(dpy,string,fast_name,how) XInternAtom(dpy,string,how)#endif#endif /* not _WIN32 */int __glutDisplaySettingsChanged = 0;static DisplayMode *dmodes, *currentDm = NULL;static int ndmodes = -1;GLUTwindow *__glutGameModeWindow = NULL;#ifdef TESTstatic char *compstr[] ={ "none", "=", "!=", "<=", ">=", ">", "<", "~"};static char *capstr[] ={ "width", "height", "bpp", "hertz", "num"};#endifvoid__glutCloseDownGameMode(void){ if (__glutDisplaySettingsChanged) {#ifdef _WIN32 /* Assumes that display settings have been changed, that is __glutDisplaySettingsChanged is true. */ ChangeDisplaySettings(NULL, 0);#endif __glutDisplaySettingsChanged = 0; } __glutGameModeWindow = NULL;}void GLUTAPIENTRYglutLeaveGameMode(void){ if (__glutGameModeWindow == NULL) { __glutWarning("not in game mode so cannot leave game mode"); return; } __glutDestroyWindow(__glutGameModeWindow, __glutGameModeWindow); XFlush(__glutDisplay); __glutGameModeWindow = NULL;}#ifdef _WIN32/* Same values as from MSDN's SetDisp.c example. */#define MIN_WIDTH 400#define MIN_FREQUENCY 60static voidinitGameModeSupport(void){ DEVMODE dm; DWORD mode; int i; if (ndmodes >= 0) { /* ndmodes is initially -1 to indicate no dmodes allocated yet. */ return; } /* Determine how many display modes there are. */ ndmodes = 0; mode = 0; while (EnumDisplaySettings(NULL, mode, &dm)) { if (dm.dmPelsWidth >= MIN_WIDTH && (dm.dmDisplayFrequency == 0 || dm.dmDisplayFrequency >= MIN_FREQUENCY)) { ndmodes++; } mode++; } /* Allocate memory for a list of all the display modes. */ dmodes = (DisplayMode*) malloc(ndmodes * sizeof(DisplayMode)); /* Now that we know how many display modes to expect, enumerate them again and save the information in the list we allocated above. */ i = 0; mode = 0; while (EnumDisplaySettings(NULL, mode, &dm)) { /* Try to reject any display settings that seem unplausible. */ if (dm.dmPelsWidth >= MIN_WIDTH && (dm.dmDisplayFrequency == 0 || dm.dmDisplayFrequency >= MIN_FREQUENCY)) { dmodes[i].devmode = dm; dmodes[i].valid = 1; /* XXX Not used for now. */ dmodes[i].cap[DM_WIDTH] = dm.dmPelsWidth; dmodes[i].cap[DM_HEIGHT] = dm.dmPelsHeight; dmodes[i].cap[DM_PIXEL_DEPTH] = dm.dmBitsPerPel; if (dm.dmDisplayFrequency == 0) { /* Guess a reasonable guess. */ /* Lame Windows 95 version of EnumDisplaySettings. */ dmodes[i].cap[DM_HERTZ] = 60; } else { dmodes[i].cap[DM_HERTZ] = dm.dmDisplayFrequency; } i++; } mode++; } assert(i == ndmodes);}#else/* X Windows version of initGameModeSupport. */static voidinitGameModeSupport(void){ if (ndmodes >= 0) { /* ndmodes is initially -1 to indicate no dmodes allocated yet. */ return; } /* Determine how many display modes there are. */ ndmodes = 0;}#endif/* This routine is based on similiar code in glut_dstr.c */static DisplayMode *findMatch(DisplayMode * dmodes, int ndmodes, Criterion * criteria, int ncriteria){ DisplayMode *found; int *bestScore, *thisScore; int i, j, numok, result = 0, worse, better; found = NULL; numok = 1; /* "num" capability is indexed from 1, not 0. */ /* XXX alloca canidate. */ bestScore = (int *) malloc(ncriteria * sizeof(int)); if (!bestScore) { __glutFatalError("out of memory."); } for (j = 0; j < ncriteria; j++) { /* Very negative number. */ bestScore[j] = -32768; } /* XXX alloca canidate. */ thisScore = (int *) malloc(ncriteria * sizeof(int)); if (!thisScore) { __glutFatalError("out of memory."); } for (i = 0; i < ndmodes; i++) { if (dmodes[i].valid) { worse = 0; better = 0; for (j = 0; j < ncriteria; j++) { int cap, cvalue, dvalue; cap = criteria[j].capability; cvalue = criteria[j].value; if (cap == NUM) { dvalue = numok; } else { dvalue = dmodes[i].cap[cap]; }#ifdef TEST if (verbose) printf(" %s %s %d to %d\n", capstr[cap], compstr[criteria[j].comparison], cvalue, dvalue);#endif switch (criteria[j].comparison) { case EQ: result = cvalue == dvalue; thisScore[j] = 1; break; case NEQ: result = cvalue != dvalue; thisScore[j] = 1; break; case LT: result = dvalue < cvalue; thisScore[j] = dvalue - cvalue; break; case GT: result = dvalue > cvalue; thisScore[j] = dvalue - cvalue; break; case LTE: result = dvalue <= cvalue; thisScore[j] = dvalue - cvalue; break; case GTE: result = (dvalue >= cvalue); thisScore[j] = dvalue - cvalue; break; case MIN: result = dvalue >= cvalue; thisScore[j] = cvalue - dvalue; break; }#ifdef TEST if (verbose) printf(" result=%d score=%d bestScore=%d\n", result, thisScore[j], bestScore[j]);#endif if (result) { if (better || thisScore[j] > bestScore[j]) { better = 1; } else if (thisScore[j] == bestScore[j]) { /* Keep looking. */ } else { goto nextDM; } } else { if (cap == NUM) { worse = 1; } else { goto nextDM; } } } if (better && !worse) { found = &dmodes[i]; for (j = 0; j < ncriteria; j++) { bestScore[j] = thisScore[j]; } } numok++; nextDM:; } } free(bestScore); free(thisScore); return found;}/** * Parses strings in the form of: * 800x600 * 800x600:16 * 800x600@60 * 800x600:16@60 * @60 * :16 * :16@60 * NOTE that @ before : is not parsed. */static intspecialCaseParse(char *word, Criterion * criterion, int mask){ char *xstr, *response; int got; int width, height, bpp, hertz; switch(word[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* The WWWxHHH case. */ if (mask & (1 << DM_WIDTH)) { return -1; } xstr = strpbrk(&word[1], "x"); if (xstr) { width = (int) strtol(word, &response, 0); if (response == word || response[0] != 'x') { /* Not a valid number OR needs to be followed by 'x'. */ return -1; } height = (int) strtol(&xstr[1], &response, 0); if (response == &xstr[1]) { /* Not a valid number. */ return -1; } criterion[0].capability = DM_WIDTH; criterion[0].comparison = EQ; criterion[0].value = width; criterion[1].capability = DM_HEIGHT; criterion[1].comparison = EQ; criterion[1].value = height; got = specialCaseParse(response, &criterion[2], 1 << DM_WIDTH); if (got >= 0) { return got + 2; } else { return -1; } } return -1; case ':': /* The :BPP case. */ if (mask & (1 << DM_PIXEL_DEPTH)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -