#include #include #include #include #include #include #include #define GLX_VERSION_1_0 /* No query capability in GLX 1.0, so hard code for now */ /* #define GLX_VERSION_1_1 */ /* Use this define when IBM Releases GLX 1.1 */ /* #define GLU_VERSION_1_1 */ /* Use this define when IBM Releases GLU 1.1 */ #define IBMSHM #ifdef XWINDOWS /* * Kludge to get access to the smt ptr in the display struct which is not * normally visible to clients. It must be defined before including Xlib.h. * This is the only reliable way for us to tell if we are running with SMT or * not. Its ugly, but it works, as long as know your library is built with * SMT support. */ #define SMT 1 #include #include #include #include #endif #include "Env.h" #include #include "aux.h" static char *GetShortVendorName(char *input); static int GetHostMemorySize(void); static char *GetHostVendor(void); static char *GetHostModel(void); static char *GetHostCPU(void); static char *GetHostOperatingSystem(void); static char *GetHostOperatingSystemRelease(void); static char *GetHostName(void); static char *GetOpenGLClientVendor(void); static char *GetOpenGLClientVersion(void); static char *GetOpenGLClientExtensions(void); static char *GetHostCPUCount(void); static char *GetHostPrimaryCacheSize(void); static char *GetHostSecondaryCacheSize(void); static char *GetWindowSystem(void); static char *GetDriverVersion(void); #if defined(XWINDOWS) static int GetOpenGLBufferConfig(Display *dpy, XVisualInfo *visInfo, EnvironmentInfo *info); static int GetXEnvironInfo(EnvironmentInfo *info); #endif /****************************************************************************** * * StringSearch - search for pattern in string * * Description: * StringSearch returns a pointer to the first occurance of pattern found in * the subject or NULL if the pattern is not found. It implements the * Knuth-Morris-Pratt pattern matching algorithm. If m is the length of the * pattern and n is the length of the subject, the complexity of the KMP * algorithm is (m+n), much better than the (m*n) complexity of the naive * nested loop algorithm. - John Dennis * * Returns: * pointer to the first occurance of pattern found the subject or NULL * * Side Effects: * None * * Errors: * None * * Revision History: * Revision 0: Author: John R. Dennis Date: Thu Aug 4 15:49:59 1994 * Initial Release * *****************************************************************************/ char * StringSearch(char *subject, char *pattern) { #define MAX_FLINK (256) int *flink, *dynamicFlink = NULL, staticFlink[MAX_FLINK]; int patternLen = strlen(pattern); int subjectLen = strlen(subject); int found = 0; int i,j; if (patternLen > MAX_FLINK) { /* -1 for NULL terminator */ dynamicFlink = malloc(patternLen * sizeof(int)); if (dynamicFlink == NULL) { fprintf(stderr, "malloc failure, line %d, file: %s, exiting...\n", __LINE__, __FILE__); exit(1); } flink = dynamicFlink; } else { flink = staticFlink; } /* Step 1: Constuct Flowchart */ flink[0] = -1; /* -1 == read next char */ for(i = 1; i < patternLen; i++) { j = flink[i-1]; while((j >= 0) && (pattern[j] != pattern[i-1])) { j = flink[j]; } flink[i] = j+1; } /* Step 2: Scan Algorithm */ for (i = j = 0; i < subjectLen; i++, j++) { while((j >= 0) && (pattern[j] != subject[i])) { j = flink[j]; } if (j == patternLen-1) { found = 1; goto exit; } } exit: if (dynamicFlink != NULL) free(dynamicFlink); if (!found) return(NULL); else return(&subject[i-patternLen+1]); #undef MAX_FLINK } /****************************************************************************** * * GetShortVendorName - return short vendor string * * Description: * some vendor strings are verbose. This function will return a shortest * vendor name it can given an arbitrary vendor string. The returned string * is allocated with malloc, it should be freed when no longer in use. The * input string is not freed or modified by this function. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * *****************************************************************************/ static char * GetShortVendorName(char *input) { int i; char *s1 = NULL; /* s1 is temp work string */ char *s2 = NULL; /* s2 is string to return */ /* duplicate input string so that we can modify it */ s1 = strdup(input); /* upcase string */ for (i = 0; s1[i]; i++) if (islower(s1[i])) s1[i] = toupper(s1[i]); /* return a short name if possible, some vendor names are verbose */ if (StringSearch(s1, "DEC") || StringSearch(s1, "DECWINDOWS") || StringSearch(s1, "Digital Equipment Corporation") || StringSearch(s1, "DigitalEquipmentCorporation")) s2 = strdup("DEC"); else if (StringSearch(s1, "SGI") || StringSearch(s1, "SILCON GRAPHICS")) s2 = strdup("SGI"); else if (StringSearch(s1, "IBM") || StringSearch(s1, "INTERNATIONAL BUSINESS MACHINES")) s2 = strdup("IBM"); else s2 = strdup(s1); free(s1); return(s2); } /****************************************************************************** * * GetHostMemorySize - Return kilobytes of memory installed on host platform * * Description: * Returns the number of kilobytes of memory installed on host platform * * Returns: * kilobytes of host platform memory * * Side Effects: * None * * Errors: * return 0 if unable to determine memory configuration * * Revision History: * Revision 0: Author: John R. Dennis Date: Thu Aug 4 15:55:19 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Mon Feb 27 13:40:00 1995 * Change to AIX specific function to get memory size. * *****************************************************************************/ static int GetHostMemorySize(void) { #define MAXCMD (1024) FILE *inputPipe; int status; char sizerBuf[MAXCMD]; int mem = 0; /* This returns number of MB char cmd[] = "lsattr -F 'value' -l sys0 -a realmem |/usr/bin/awk '{printf(\"%d MB\", $1/1024)}' "; */ char cmd[] = "lsattr -F 'value' -l sys0 -a realmem |/usr/bin/awk '{printf(\"%d\", $1)}' "; inputPipe= popen(cmd, "r"); if (inputPipe == NULL) { fprintf(stderr, "could not open pipe for %s\n", cmd); } fgets(sizerBuf, MAXCMD, inputPipe); status = pclose(inputPipe); if (status != 0) { fprintf(stderr, "cmd \"%s\" returned error %d\n", cmd, status); } /* printf( "Memory size: %s\n", sizerBuf ); */ mem = atoi(sizerBuf); /* printf( "Memory size: %d KB\n", mem ); */ return(mem); } /****************************************************************************** * * GetHostVendor - return string naming the system vendor * * Description: * return the name of the system vendor as a string. This is to identify * manufacturer of the system. The string is allocated with malloc, it should * be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Mon Feb 27 14:12:00 1995 * Change to be AIX Specific. * *****************************************************************************/ static char * GetHostVendor(void) { return(strdup("IBM")); } /****************************************************************************** * * GetHostModel - return string naming the host model * * Description: * return string identifying the host platform's model designation. The string * is allocated with malloc, it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Mon Feb 27 14:13:00 1995 * Change to be AIX Specific. * *****************************************************************************/ static char * GetHostModel(void) { /* * There is no system entry point in AIX that returns the name of the processor. The * structure utsname contains the cpuid (chararter 8,9) which can then be correlated * to a given host cpu model via a lookup table. This table will need to be updated * at each release of new processor models. I don't know of a better way than this * right now. */ static char Host[100]; struct utsname un; char cmd[20]; char id[20]; int cpuid; FILE *inputPipe; int status; uname(&un); /* Get the structure which contains the cpu id number */ sprintf( cmd, "echo 0X%2.2s\n", un.machine+8 ); /* fields 8&9 are 2 digit id */ sprintf( id, "0X%2.2s" , un.machine+8 ); inputPipe=popen(cmd, "r"); if (inputPipe == NULL) { strcpy(Host, "unknown (id=-1)"); /* If failed to get cpu id, print -1 */ return Host; } fscanf(inputPipe, "%X",&cpuid); /* Read the CPU id as Hex. */ status = pclose(inputPipe); /* Map "cpuid" from "uname" to real product names */ /* NOTE: As new CPU Models are added, need to update this list. */ switch ( cpuid ) { case 0x4D: strcpy( Host, "RISC System/6000 Model 40P"); break; case 0x43: strcpy( Host, "RISC System/6000 Model M20"); break; case 0x45: strcpy( Host, "RISC System/6000 Model 220"); break; case 0x41: strcpy( Host, "RISC System/6000 Model 220"); break; case 0x47: strcpy( Host, "RISC System/6000 Model 230"); break; case 0x46: strcpy( Host, "RISC System/6000 Model 25T"); break; case 0x49: strcpy( Host, "RISC System/6000 Model 25T80"); break; case 0x31: strcpy( Host, "RISC System/6000 Model 320"); break; case 0x35: strcpy( Host, "RISC System/6000 Model 32H"); break; case 0x37: strcpy( Host, "RISC System/6000 Model 340"); break; case 0x38: strcpy( Host, "RISC System/6000 Model 350"); break; case 0x77: strcpy( Host, "RISC System/6000 Model 355"); break; case 0x76: strcpy( Host, "RISC System/6000 Model 36T/365"); break; case 0x75: strcpy( Host, "RISC System/6000 Model 37T/375"); break; case 0x58: strcpy( Host, "RISC System/6000 Model 3AT"); break; case 0x57: strcpy( Host, "RISC System/6000 Model 3BT"); break; case 0x59: strcpy( Host, "RISC System/6000 Model 3CT"); break; case 0x42: strcpy( Host, "RISC System/6000 Model 41T"); break; case 0x91: strcpy( Host, "RISC System/6000 Model 42T"); break; case 0x30: strcpy( Host, "RISC System/6000 Model 520"); break; case 0x34: strcpy( Host, "RISC System/6000 Model 52H"); break; case 0x10: strcpy( Host, "RISC System/6000 Model 530/730"); break; case 0x18: strcpy( Host, "RISC System/6000 Model 53H"); break; case 0x14: strcpy( Host, "RISC System/6000 Model 540"); break; case 0x1C: strcpy( Host, "RISC System/6000 Model 550"); break; case 0x5C: strcpy( Host, "RISC System/6000 Model 560"); break; case 0x67: strcpy( Host, "RISC System/6000 Model 570"); break; case 0x66: strcpy( Host, "RISC System/6000 Model 580"); break; case 0x70: strcpy( Host, "RISC System/6000 Model 590"); break; case 0x20: strcpy( Host, "RISC System/6000 Model 930"); break; case 0x2E: strcpy( Host, "RISC System/6000 Model 950"); break; case 0x63: strcpy( Host, "RISC System/6000 Model 970B"); break; case 0x64: strcpy( Host, "RISC System/6000 Model 980"); break; default: sprintf( Host, "unknown (CPU_id=%s)",id); break; } return(strdup(Host)); /* Return the string we have created to the Host Model */ } /****************************************************************************** * * GetHostCPU - return string naming the host CPU * * Description: * return string identifying the host platform's CPU. The string * is allocated with malloc, it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Mon Feb 27 18:36:00 1995 * Change to be AIX Specific. Will use the info in /usr/include/sys/systemcfg.h * *****************************************************************************/ static char * GetHostCPU(void) { static char hostcpu[50]; /* Values for implementation field */ #define POWER_RS1 0x0001 /* RS1 class CPU */ #define POWER_RSC 0x0002 /* RSC class CPU */ #define POWER_RS2 0x0004 /* RS2 class CPU */ #define POWER_601 0x0008 /* 601 class CPU */ #define POWER_603 0x0020 /* 603 class CPU */ #define POWER_604 0x0010 /* 604 class CPU */ #define POWER_620 0x0040 /* 620 class CPU */ switch ( _system_configuration.implementation ) { case POWER_RS1 : strcpy( hostcpu, "POWER"); break; case POWER_RSC : strcpy( hostcpu, "POWER RSC"); break; case POWER_RS2 : strcpy( hostcpu, "POWER2"); break; case POWER_601 : strcpy( hostcpu, "PowerPC 601"); break; case POWER_603 : strcpy( hostcpu, "PowerPC 603"); break; case POWER_604 : strcpy( hostcpu, "PowerPC 604"); break; case POWER_620 : strcpy( hostcpu, "PowerPC 620"); break; default : sprintf( hostcpu, "unknown (CPU_Class=%s)", _system_configuration.implementation); break; } return(strdup(hostcpu)); } /****************************************************************************** * * GetHostCPUCount - return string indicating number of host CPU's * * Description: * return string indicating number of host CPU's. The string "unknown" is * returned if the count is not determinable. The string is allocated with * malloc, it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Feb 27 14:18:41 EST 1995 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 01 15:16:47 EST 1995 * Initial Release * *****************************************************************************/ static char * GetHostCPUCount(void) { static char NumberCPUs[5]; /* character string to return */ /* _system_configuration.ncpus = 1 = UniProcessor, n = n-way MP */ sprintf( NumberCPUs, "%d",_system_configuration.ncpus); return(strdup(NumberCPUs)); } /****************************************************************************** * * GetHostPrimaryCacheSize - return string indicating host's primary cache (KB) * * Description: * return string indicating the number of kilobytes of primary cache on the * host's CPU, or "unknown" if not determinable. The string * is allocated with malloc, it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Feb 27 14:18:41 EST 1995 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 01 13:16:12 EST 1995 * Change to AIX specific code. Make use of the structure in * /usr/include/sys/systemcfg.h. There is more information in the * AIX version 4.1 than in 3.2. * *****************************************************************************/ static char * GetHostPrimaryCacheSize(void) { static char L1CacheSize[50]; int dcache_size; int icache_size; dcache_size = (_system_configuration.dcache_size / 1024); /* conv dcache size bytes to KB */ icache_size = (_system_configuration.icache_size / 1024); /* conv icache size bytes to KB */ switch ( _system_configuration.cache_attrib ) { case 0 : strcpy( L1CacheSize, "No Cache Present"); break; case 1 : sprintf( L1CacheSize, "%d/%d (D/I)",dcache_size,icache_size); break; /* seperate data & instr caches */ case 3 : sprintf( L1CacheSize, "%d (D+I)",dcache_size); break; /* combined data & instr cache */ default : sprintf( L1CacheSize, "unknown (cache_attrib=%s)", _system_configuration.cache_attrib); break; } return(strdup(L1CacheSize)); } /****************************************************************************** * * GetHostSecondaryCacheSize - return string indicating host's secondary cache (KB) * * Description: * return string indicating the number of kilobytes of secondary cache on the * host's CPU, or "unknown" if not determinable. The string * is allocated with malloc, it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Feb 27 14:18:41 EST 1995 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 01 14:01:12 EST 1995 * Change to AIX specific code. Make use of the structure in * /usr/include/sys/systemcfg.h. * *****************************************************************************/ static char * GetHostSecondaryCacheSize(void) { static char L2CacheSize[50]; /* character string to return i.e. 512KB */ int L2_cache_size; /* integer value of cache size */ L2_cache_size = (_system_configuration.L2_cache_size / 1024); /* conv L2 cache size bytes to KB */ sprintf( L2CacheSize, "%d",L2_cache_size); return(strdup(L2CacheSize)); } /****************************************************************************** * * GetWindowSystem - return string naming the windowing system * * Description: * return string identifying the windowing system in use on the target * device. The string is allocated with malloc, it should be freed when no * longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * *****************************************************************************/ static char * GetWindowSystem(void) { char buf[128]; #if defined(XWINDOWS) sprintf(buf, "X Window System V%d", X_PROTOCOL); return(strdup(buf)); #elif defined(WIN32) return(strdup("Win32")); #else return(strdup("unknown")); #endif } /****************************************************************************** * * GetDriverVersion - return string identifying the graphics driver * * Description: * Return string identifying the graphics driver version. If there is no * graphics driver than the string "NA" is returned. If a graphics driver * exists, but the function cannot identify it then the string "unknown" is * returned. The string is allocated with malloc, it should be freed when no * longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Feb 27 15:00:18 EST 1995 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 01 13:16:32 EST 1995 * Change to AIX specific. * *****************************************************************************/ static char * GetDriverVersion(void) { return(strdup("NA")); /* AIX does not have 'graphics drivers' */ /* The closest thing is system side libraries and */ /* microcode, but this is given by the operating */ /* system and PTFs which are present. */ } /****************************************************************************** * * GetHostOperatingSystem - return string naming the host CPU operating system * * Description: * return the type of the host operating system as a string. This is to * identify what type of operating system this program is running under. The * string is allocated with malloc, it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Tue Feb 28 17:18:00 1995 * Make AIX specific. * *****************************************************************************/ static char * GetHostOperatingSystem(void) { struct utsname uName; int status; status = uname(&uName); if (status < 0) { return(strdup("unknown")); } else { return(strdup(uName.sysname)); } } /****************************************************************************** * * GetHostOperatingSystemRelease - return string naming operating system release * * Description: * return the release/version of the host operating system as a string. This * is to identify what version of the operating system this program is * running under. The string is allocated with malloc, it should be freed * when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Tue Feb 28 17:50:00 1995 * Make AIX specific. * *****************************************************************************/ static char * GetHostOperatingSystemRelease(void) { struct utsname uName; int status; int releaseLen, versionLen; char *s; status = uname(&uName); if (status < 0) { return(strdup("unknown")); } else { releaseLen = strlen(uName.release); versionLen = strlen(uName.version); /* 1 extra char for dot, 1 extra char for null terminator */ s = malloc(releaseLen + versionLen + 2); *s = 0; strcpy(s, uName.version); /* Should print version release i.e. 3.2 or 4.1 */ strcat(s, "."); strcat(s, uName.release); return(s); } } /****************************************************************************** * * GetHostName - return string naming the host * * Description: * return the name of this host as a string. This is to identify which * platform this program is running on. The string is allocated with malloc, * it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Tue Feb 28 17:19:00 1995 * Make AIX specific. * *****************************************************************************/ static char * GetHostName(void) { struct utsname uName; int status; status = uname(&uName); if (status < 0) { return(strdup("unknown")); } else { return(strdup(uName.nodename)); } } /****************************************************************************** * * GetDateTime - get the current month, day, year, hour, minute * * Description: * Get the current day, month, year, hour, minute. Each is a pointer to an * integer. If the pointer is NULL then no value is returned for that * parameter, otherwise an assignment is made to the integer pointed to by * the parameter. * * month: in the range [1-12] 1=January, 12=December * day: in the range [1-31] * year: as a 4 digit number, e.g. 1994 * hour: in the range [0-23] * min: in the range [0-59] * * Returns: * 0 for success, error code otherwise * * Side Effects: * None * * Errors: * return non-zero on failure * * Revision History: * Revision 0: Author: John R. Dennis Date: Wed Aug 17 13:08:36 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 01 14:46:46 1995 * Made AIX specific change; sys_errlist[errno] not defined in AIX * so just use errno. * *****************************************************************************/ int GetDateTime(int *month, int *day, int *year, int *hour, int *minute) { time_t timeT; struct tm *timeTm; time(&timeT); timeTm = localtime(&timeT); if (timeTm == NULL) { fprintf(stderr, "Error calling localtime: %d\n", errno); return(errno); } if (month) *month = timeTm->tm_mon + 1; if (day) *day = timeTm->tm_mday; if (year) *year = timeTm->tm_year + 1900; if (hour) *hour = timeTm->tm_hour; if (minute) *minute = timeTm->tm_min; return(0); } /****************************************************************************** * * GetOpenGLClientVendor - return string naming the client library vendor * * Description: * return the name of the vendor supplying the OpenGL client library. The * string is allocated with malloc,it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 1 13:01:03 1995 * Make code AIX specific. When GLX 1.1 is available, uncomment the * #define GLX_VERSION_1_1 at the top of this file. * *****************************************************************************/ static char * GetOpenGLClientVendor(void) { #if defined(XWINDOWS) Display *dpy; dpy = auxXDisplay(); #if defined(GLX_VERSION_1_0) return(strdup("IBM")); #endif #if defined(GLX_VERSION_1_1) return(GetShortVendorName((char *)glXGetClientString(dpy, GLX_VENDOR))); #endif #else return(strdup("IBM")); #endif } /****************************************************************************** * * GetOpenGLClientVersion - return string naming the client library version * * Description: * return the version of the OpenGL client library. The string is allocated * with malloc,it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 1 13:01:03 1995 * Make code AIX specific. When GLX 1.1 is available, uncomment the * #define GLX_VERSION_1_1 at the top of this file. * *****************************************************************************/ static char * GetOpenGLClientVersion(void) { #if defined(XWINDOWS) Display *dpy; dpy = auxXDisplay(); #if defined(GLX_VERSION_1_1) return((char *)glXGetClientString(dpy, GLX_VERSION)); #else return(strdup("1.0")); #endif #else return(strdup("unknown")); #endif } /****************************************************************************** * * GetOpenGLClientExtensions - return string naming the client extensions * * Description: * return the extensions supported in the OpenGL client library. The string * is allocated with malloc,it should be freed when no longer in use. * * Returns: * pointer to allocated string * * Side Effects: * string allocation, string should be freed when no longer needed. * * Errors: * no errors, if function fails the string "unknown" is returned * * Revision History: * Revision 0: Author: John R. Dennis Date: Mon Aug 8 16:30:53 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 1 17:38:03 1995 * Make code AIX specific. When GLX 1.1 is available, uncomment the * #define GLX_VERSION_1_1 at the top of this file. * *****************************************************************************/ static char * GetOpenGLClientExtensions(void) { #if defined(XWINDOWS) Display *dpy; dpy = auxXDisplay(); #if defined(GLX_VERSION_1_1) return((char *)glXGetClientString(dpy, GLX_EXTENSIONS)); #else return(strdup("None")); /* No GLX Extensions for Version 1.0 */ #endif #else return(strdup("unknown")); #endif } /****************************************************************************** * * GetOpenGLBufferInfo - inquire the OpenGL buffer configuration * * Description: * Given a specfic rendering target and visual description, return the OpenGL * buffer configuration. This information includes: * * Returns: * 0 for success, error code otherwise * * Side Effects: * None * * Errors: * None * * Revision History: * Revision 0: Author: John R. Dennis Date: Thu Aug 18 10:18:45 1994 * Initial Release * *****************************************************************************/ #if defined(XWINDOWS) static int GetOpenGLBufferConfig(Display *dpy, XVisualInfo *visInfo, EnvironmentInfo *info) { BufferConfig *config = &info->bufConfig; glXGetConfig(dpy, visInfo, GLX_DOUBLEBUFFER, &config->doubleBuffer); glXGetConfig(dpy, visInfo, GLX_STEREO, &config->stereo); glXGetConfig(dpy, visInfo, GLX_RGBA, &config->rgba); if (config->rgba) { glXGetConfig(dpy, visInfo, GLX_RED_SIZE, &config->redSize); glXGetConfig(dpy, visInfo, GLX_GREEN_SIZE, &config->greenSize); glXGetConfig(dpy, visInfo, GLX_BLUE_SIZE, &config->blueSize); glXGetConfig(dpy, visInfo, GLX_ALPHA_SIZE, &config->alphaSize); glXGetConfig(dpy, visInfo, GLX_ACCUM_RED_SIZE, &config->accumRedSize); glXGetConfig(dpy, visInfo, GLX_ACCUM_GREEN_SIZE, &config->accumGreenSize); glXGetConfig(dpy, visInfo, GLX_ACCUM_BLUE_SIZE, &config->accumBlueSize); glXGetConfig(dpy, visInfo, GLX_ACCUM_ALPHA_SIZE, &config->accumAlphaSize); config->indexSize = -1; } else { config->redSize = -1; config->greenSize = -1; config->blueSize = -1; config->alphaSize = -1; config->accumRedSize = -1; config->accumGreenSize = -1; config->accumBlueSize = -1; config->accumAlphaSize = -1; glXGetConfig(dpy, visInfo, GLX_BUFFER_SIZE, &config->indexSize); } glXGetConfig(dpy, visInfo, GLX_DEPTH_SIZE, &config->depthSize); glXGetConfig(dpy, visInfo, GLX_STENCIL_SIZE, &config->stencilSize); glXGetConfig(dpy, visInfo, GLX_AUX_BUFFERS, &config->auxBuffers); glXGetConfig(dpy, visInfo, GLX_LEVEL, &config->level); #if defined(XWINDOWS) config->visualId = visInfo->visualid; #if defined(__cplusplus) || defined(c_plusplus) config->visualClass = visInfo->c_class; #else config->visualClass = visInfo->class; #endif #endif } #elif defined(SOME_OTHER_WINDOW_SYSTEM) #else #error "unknown window system" #endif /****************************************************************************** * * GetXEnvironInfo - Get all enironment info specfic to X Windows * * Description: * * * Returns: * 0 success, error code otherwise * * Side Effects: * None * * Errors: * errors with bad configurations * * Revision History: * Revision 0: Author: John R. Dennis Date: Thu Aug 18 16:51:10 1994 * Initial Release * Revision 1: Author: Rob Putney Date: Wed Mar 01 15:13:16 1995 * Change to AIX specific; problem with dpy structre, 'pSmt' not * part of structure. * *****************************************************************************/ #if defined(XWINDOWS) static int GetXEnvironInfo(EnvironmentInfo *info) { Display *dpy; Window win; int i, status; int screen; Screen *pScreen; XWindowAttributes winAttr; XVisualInfo visualTemplate, *visInfo; VisualID visualId; int nVisuals; char buf[256]; int glxMajorVersion, glxMinorVersion; char *s; dpy = auxXDisplay(); if (!dpy) { fprintf(stderr, "GetXEnvironInfo: no display set\n"); return(1); } win = auxXWindow(); if (!win) { fprintf(stderr, "GetXEnvironInfo: no window set\n"); return(1); } status = XGetWindowAttributes(dpy, win, &winAttr); if (!status) { fprintf(stderr, "Error calling XGetWindowAttributes\n"); } /* XXX - should we be using aux functions to get screen number, visual id? */ /* Find the screen number given a screen ptr. */ pScreen = winAttr.screen; for (screen = 0; screen < ScreenCount(dpy); screen++) { if (pScreen == &dpy->screens[screen]) { break; } } if (screen >= ScreenCount(dpy)) { fprintf(stderr, "Error, cannot find screen\n"); } /* Find the visualInfo given a visualId */ visualId = winAttr.visual->visualid; visualTemplate.visualid = visualId; visualTemplate.screen = screen; visInfo = XGetVisualInfo(dpy,VisualScreenMask|VisualIDMask, &visualTemplate, &nVisuals); if (visInfo == NULL || nVisuals != 1) { fprintf(stderr, "Error calling XGetVisualInfo\n"); } else { GetOpenGLBufferConfig(dpy, visInfo, info); } info->windowWidth = winAttr.width; info->windowHeight = winAttr.height; info->screenNumber = screen; info->display = strdup(DisplayString(dpy)); if (glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion)) { sprintf(buf, "%d.%d", glxMajorVersion, glxMinorVersion); } else { sprintf(buf, "GLX not available"); } info->glxVersion = strdup(buf); #if defined(GLX_VERSION_1_1) s = (char *)glXQueryServerString(dpy, screen, GLX_VENDOR); info->glServerVendor = s ? GetShortVendorName(s) : strdup("unknown"); #else info->glServerVendor = GetShortVendorName(ServerVendor(dpy)); #endif #if defined(GLX_VERSION_1_1) s = (char *) glXQueryServerString(dpy, screen, GLX_VERSION); info->glServerVersion = strdup(s ? s : "unknown"); #else info->glServerVersion = strdup(info->glxVersion); #endif #if defined(GLX_VERSION_1_1) s = (char *) glXQueryServerString(dpy, screen, GLX_EXTENSIONS); info->glServerExtensions = strdup(s ? s : "unknown"); #else info->glServerExtensions = strdup("unknown"); #endif #if defined(GLX_VERSION_1_1) s = (char *)glXQueryExtensionsString(dpy, screen); info->glxExtensions = strdup(s ? s : "unknown"); #else info->glxExtensions = strdup("unknown"); #endif info->screenWidth = DisplayWidth(dpy, screen); info->screenHeight = DisplayHeight(dpy, screen); /* if (dpy->pSmt) { info->sharedMemConnection = TRUE; */ if (dpy->shmTrans) { info->sharedMemConnection = TRUE; } else { info->sharedMemConnection = FALSE; } XFree((void *)visInfo); return(0); } #elif defined(SOME_OTHER_WINDOW_SYSTEM) #else #error "unknown window system" #endif /****************************************************************************** * * GetEnvironment - return info about environment test was run in * * Description: * This function fills in an environment info record with every pertinent * piece of information about the condiditons under which the test was run. * * Returns: * 0 success, error code otherwise * * Side Effects: * None * * Errors: * errors generally only with bad configurations, too many to list * * Revision History: * Revision 0: Author: John R. Dennis Date: Thu Aug 18 16:52:35 1994 * Initial Release * *****************************************************************************/ int GetEnvironment(EnvironmentInfo *info) { GLenum windType; FreeEnvironmentData(info); GetDateTime(&info->month, &info->day, &info->year, NULL, NULL); info->host = GetHostName(); info->hostOperatingSystem = GetHostOperatingSystem(); info->hostOperatingSystemVersion = GetHostOperatingSystemRelease(); info->hostVendor = GetHostVendor(); info->hostModel = GetHostModel(); info->hostCPU = GetHostCPU(); info->hostCPUCount = GetHostCPUCount(); info->hostPrimaryCacheSize = GetHostPrimaryCacheSize(); info->hostSecondaryCacheSize = GetHostSecondaryCacheSize(); info->windowSystem = GetWindowSystem(); info->driverVersion = GetDriverVersion(); info->hostMemorySize = GetHostMemorySize() / 1024; /* kilobytes to MB */ info->glVendor = GetShortVendorName((char *)glGetString(GL_VENDOR)); info->glVersion = strdup((char *)glGetString(GL_VERSION)); info->glRenderer = strdup((char *)glGetString(GL_RENDERER)); info->glExtensions = strdup((char *)glGetString(GL_EXTENSIONS)); info->glClientVendor = GetOpenGLClientVendor(); info->glClientVersion = GetOpenGLClientVersion(); info->glClientExtensions = GetOpenGLClientExtensions(); #ifdef GLU_VERSION_1_1 info->gluVersion = strdup((char *)gluGetString(GLU_VERSION));; info->gluExtensions = strdup((char *)gluGetString(GLU_EXTENSIONS));; #else info->gluVersion = strdup("1.0"); /* Hard code this for now */ info->gluExtensions = strdup("None"); /* No gluGetString in 1.0 */ #endif #if defined(XWINDOWS) GetXEnvironInfo(info); #endif /* * Direct rendering is a "request", not a guarantee. We need to check the * direct render bit for each test because the GL context is only set up * in the above conditional block. If we didn't check it for each test * then the value for direct rendering store in the test descriptor would * be the "request" value, not the actual value. */ windType = auxGetDisplayMode(); if (windType & AUX_DIRECT) info->directRender = True; else info->directRender = False; } /****************************************************************************** * * FreeEnvironmentData - frees all dynamic data in EnvironmentInfo struct * * Description: * Free all the dynamically allocated data in an EnvironmentInfo struct. Each * pointer in the struct is assigned the value of NULL after its data has * been freed. The struct itself is not freed. * * Returns: * void * * Side Effects: * free dynamically allocated memory * * Errors: * None * * Revision History: * Revision 0: Author: John R. Dennis Date: Tue Sep 13 17:31:19 1994 * Initial Release * *****************************************************************************/ void FreeEnvironmentData(EnvironmentInfo *info) { if (info->host != NULL) free(info->host); if (info->hostOperatingSystem != NULL) free(info->hostOperatingSystem); if (info->hostOperatingSystemVersion != NULL) free(info->hostOperatingSystemVersion); if (info->hostVendor != NULL) free(info->hostVendor); if (info->hostModel != NULL) free(info->hostModel); if (info->hostCPU != NULL) free(info->hostCPU); if (info->hostCPUCount != NULL) free(info->hostCPUCount); if (info->hostPrimaryCacheSize != NULL) free(info->hostPrimaryCacheSize); if (info->hostSecondaryCacheSize != NULL) free(info->hostSecondaryCacheSize); if (info->windowSystem != NULL) free(info->windowSystem); if (info->driverVersion != NULL) free(info->driverVersion); if (info->glVendor != NULL) free(info->glVendor); if (info->glVersion != NULL) free(info->glVersion); if (info->glRenderer != NULL) free(info->glRenderer); if (info->glExtensions != NULL) free(info->glExtensions); if (info->glClientVendor != NULL) free(info->glClientVendor); if (info->glClientVersion != NULL) free(info->glClientVersion); if (info->glClientExtensions != NULL) free(info->glClientExtensions); if (info->gluVersion != NULL) free(info->gluVersion); if (info->gluExtensions != NULL) free(info->gluExtensions); #if defined(XWINDOWS) if (info->display != NULL) free(info->display); if (info->glServerVendor != NULL) free(info->glServerVendor); if (info->glServerVersion != NULL) free(info->glServerVersion); if (info->glServerExtensions != NULL) free(info->glServerExtensions); if (info->glxVersion != NULL) free(info->glxVersion); if (info->glxExtensions != NULL) free(info->glxExtensions); #endif NullEnvironmentData(info); } /****************************************************************************** * * NullEnvironmentData - sets all dynamic data ptrs in EnvironmentInfo to NULL * * Description: * Sets all the pointers to dynamically allocated data in an EnvironmentInfo * struct to NULL. The data pointed to by the pointers are not freed, use the * function FreeEnvironmentData for that purpose. * * Returns: * void * * Side Effects: * None * * Errors: * None * * Revision History: * Revision 0: Author: John R. Dennis Date: Tue Sep 13 17:31:19 1994 * Initial Release * *****************************************************************************/ void NullEnvironmentData(EnvironmentInfo *info) { info->host = NULL; info->hostOperatingSystem = NULL; info->hostOperatingSystemVersion = NULL; info->hostVendor = NULL; info->hostModel = NULL; info->hostCPU = NULL; info->hostCPUCount = NULL; info->hostPrimaryCacheSize = NULL; info->hostSecondaryCacheSize = NULL; info->windowSystem = NULL; info->driverVersion = NULL; info->glVendor = NULL; info->glVersion = NULL; info->glRenderer = NULL; info->glExtensions = NULL; info->glClientVendor = NULL; info->glClientVersion = NULL; info->glClientExtensions = NULL; info->gluVersion = NULL; info->gluExtensions = NULL; #if defined(XWINDOWS) info->display = NULL; info->glServerVendor = NULL; info->glServerVersion = NULL; info->glServerExtensions = NULL; info->glxVersion = NULL; info->glxExtensions = NULL; #endif } /****************************************************************************** * * PrintEnvironment - print contents of EnvironmentInfo struct * * Description: * Print the contents of EnvironmentInfo struct. The stream parameter Points * to a FILE structure specifying an open stream to which output will be * written. The title parameter is a pointer to a string which will be output * before any of the EnvironmentInfo data is output, The title string may be * NULL in which case no title string will be written. The leader parameter * is a pointer to a string which will be output before each field in the * EnvironmentInfo struct. The nameWidth parameter is an integer parameter * specifying how pad the name of each field. This can be used to cause the * values to line up in a column. A positive value left justifies, a negative * value right justifies. The suffix parameter is a pointer to a string which * will be output after all of the EnvironmentInfo data is output, The suffix * string may be NULL in which case no suffix string will be written. * * Returns: * void * * Side Effects: * file stream output * * Errors: * None * * Revision History: * Revision 0: Author: John R. Dennis Date: Wed Sep 14 09:02:57 1994 * Initial Release * *****************************************************************************/ void PrintEnvironment(FILE *stream, EnvironmentInfo *info, char *title, char *leader, int nameWidth, char *suffix) { if (title) fprintf(stream, "%s", title); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Month", info->month); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Day", info->day); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Year", info->year); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Host", info->host); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Operating System", info->hostOperatingSystem); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Operating System Version", info->hostOperatingSystemVersion); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Host Vendor", info->hostVendor); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Host Model", info->hostModel); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Host CPU", info->hostCPU); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Host CPU Count", info->hostCPUCount); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Host Memory Size (MB)", info->hostMemorySize); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Host Primary Cache Size (KB)", info->hostPrimaryCacheSize); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Host Secondary Cache Size (KB)", info->hostSecondaryCacheSize); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Window System", info->windowSystem); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Driver Version", info->driverVersion); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Vendor", info->glVendor); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Version", info->glVersion); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Extensions", info->glExtensions); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Renderer", info->glRenderer); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Client Vendor", info->glClientVendor); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Client Version", info->glClientVersion); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Client Extensions", info->glClientExtensions); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "GLU Version", info->gluVersion); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "GLU Extensions", info->gluExtensions); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Direct Rendering", info->directRender ? "True" : "False"); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Double Buffer", info->bufConfig.doubleBuffer ? "True" : "False"); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Stereo", info->bufConfig.stereo ? "True" : "False"); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "RGBA", info->bufConfig.rgba ? "True" : "False"); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Color Index Size", info->bufConfig.indexSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Red Size", info->bufConfig.redSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Green Size", info->bufConfig.greenSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Blue Size", info->bufConfig.blueSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Alpha Size", info->bufConfig.alphaSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Accum Red Size", info->bufConfig.accumRedSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Accum Green Size", info->bufConfig.accumGreenSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Accum Blue Size", info->bufConfig.accumBlueSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Accum Alpha Size", info->bufConfig.accumAlphaSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Depth Size", info->bufConfig.depthSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Stencil Size", info->bufConfig.stencilSize); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Auxiliary Buffer Count", info->bufConfig.auxBuffers); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Frame BufferLevel", info->bufConfig.level); #if defined(XWINDOWS) fprintf(stream, "%s%*s%#X\n", leader, nameWidth, "Visual ID", info->bufConfig.visualId); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Visual Class", info->bufConfig.visualClass == StaticGray ? "StaticGray" : info->bufConfig.visualClass == GrayScale ? "GrayScale" : info->bufConfig.visualClass == StaticColor ? "StaticColor" : info->bufConfig.visualClass == PseudoColor ? "PseudoColor" : info->bufConfig.visualClass == TrueColor ? "TrueColor" : info->bufConfig.visualClass == DirectColor ? "DirectColor" : "unknown"); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Window Width (pixels)", info->windowWidth); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Window Height (pixels)", info->windowHeight); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Screen Width (pixels)", info->screenWidth); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Screen Height (pixels)", info->screenHeight); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Display", info->display); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Server Vendor", info->glServerVendor); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Server Version", info->glServerVersion); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "OpenGL Server Extensions", info->glServerExtensions); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "GLX Server Version", info->glxVersion); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "GLX Server Extensions", info->glxExtensions); fprintf(stream, "%s%*s%d\n", leader, nameWidth, "Screen Number", info->screenNumber); fprintf(stream, "%s%*s%s\n", leader, nameWidth, "Shared Memory Connection", info->sharedMemConnection ? "True" : "False"); #endif if (suffix) fprintf(stream, "%s", suffix); }