132001f49Smrg/* 232001f49Smrg * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 332001f49Smrg * 432001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a 532001f49Smrg * copy of this software and associated documentation files (the "Software"), 632001f49Smrg * to deal in the Software without restriction, including without limitation 732001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 832001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the 932001f49Smrg * Software is furnished to do so, subject to the following conditions: 1032001f49Smrg * 1132001f49Smrg * The above copyright notice and this permission notice shall be included 1232001f49Smrg * in all copies or substantial portions of the Software. 1332001f49Smrg * 1432001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 1532001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1632001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1732001f49Smrg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1832001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1932001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2032001f49Smrg */ 2132001f49Smrg 2232001f49Smrg 2332001f49Smrg/* 2432001f49Smrg * This program is a work-alike of the IRIX glxinfo program. 2532001f49Smrg * Command line options: 2632001f49Smrg * -t print wide table 2732001f49Smrg * -v print verbose information 2832001f49Smrg * -display DisplayName specify the X display to interogate 297ec3b29aSmrg * -B brief, print only the basics 3032001f49Smrg * -b only print ID of "best" visual on screen 0 3132001f49Smrg * -i use indirect rendering connection only 3232001f49Smrg * -l print interesting OpenGL limits (added 5 Sep 2002) 3332001f49Smrg * 3432001f49Smrg * Brian Paul 26 January 2000 3532001f49Smrg */ 3632001f49Smrg 3732001f49Smrg#define GLX_GLXEXT_PROTOTYPES 3832001f49Smrg#define GL_GLEXT_PROTOTYPES 3932001f49Smrg 4032001f49Smrg#include <assert.h> 4132001f49Smrg#include <X11/Xlib.h> 4232001f49Smrg#include <X11/Xutil.h> 4332001f49Smrg#include <GL/gl.h> 4432001f49Smrg#include <GL/glx.h> 4532001f49Smrg#include <stdio.h> 4632001f49Smrg#include <string.h> 4732001f49Smrg#include <stdlib.h> 4832001f49Smrg#include "glinfo_common.h" 4932001f49Smrg 5032001f49Smrg 5132001f49Smrg#ifndef GLX_NONE_EXT 5232001f49Smrg#define GLX_NONE_EXT 0x8000 5332001f49Smrg#endif 5432001f49Smrg 5532001f49Smrg#ifndef GLX_TRANSPARENT_RGB 5632001f49Smrg#define GLX_TRANSPARENT_RGB 0x8008 5732001f49Smrg#endif 5832001f49Smrg 5932001f49Smrg#ifndef GLX_RGBA_BIT 6032001f49Smrg#define GLX_RGBA_BIT 0x00000001 6132001f49Smrg#endif 6232001f49Smrg 6332001f49Smrg#ifndef GLX_COLOR_INDEX_BIT 6432001f49Smrg#define GLX_COLOR_INDEX_BIT 0x00000002 6532001f49Smrg#endif 6632001f49Smrg 6732001f49Smrg 6832001f49Smrgstruct visual_attribs 6932001f49Smrg{ 7032001f49Smrg /* X visual attribs */ 7132001f49Smrg int id; /* May be visual ID or FBConfig ID */ 7232001f49Smrg int vis_id; /* Visual ID. Only set for FBConfigs */ 7332001f49Smrg int klass; 7432001f49Smrg int depth; 7532001f49Smrg int redMask, greenMask, blueMask; 7632001f49Smrg int colormapSize; 7732001f49Smrg int bitsPerRGB; 7832001f49Smrg 7932001f49Smrg /* GL visual attribs */ 8032001f49Smrg int supportsGL; 8132001f49Smrg int drawableType; 8232001f49Smrg int transparentType; 8332001f49Smrg int transparentRedValue; 8432001f49Smrg int transparentGreenValue; 8532001f49Smrg int transparentBlueValue; 8632001f49Smrg int transparentAlphaValue; 8732001f49Smrg int transparentIndexValue; 8832001f49Smrg int bufferSize; 8932001f49Smrg int level; 9032001f49Smrg int render_type; 9132001f49Smrg int doubleBuffer; 9232001f49Smrg int stereo; 9332001f49Smrg int auxBuffers; 9432001f49Smrg int redSize, greenSize, blueSize, alphaSize; 9532001f49Smrg int depthSize; 9632001f49Smrg int stencilSize; 9732001f49Smrg int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize; 9832001f49Smrg int numSamples, numMultisample; 9932001f49Smrg int visualCaveat; 10032001f49Smrg int floatComponents; 10132001f49Smrg int packedfloatComponents; 10232001f49Smrg int srgb; 10332001f49Smrg}; 10432001f49Smrg 10532001f49Smrg 10632001f49Smrg/** 10732001f49Smrg * Version of the context that was created 10832001f49Smrg * 10932001f49Smrg * 20, 21, 30, 31, 32, etc. 11032001f49Smrg */ 11132001f49Smrgstatic int version; 11232001f49Smrg 11332001f49Smrg/** 11432001f49Smrg * GL Error checking/warning. 11532001f49Smrg */ 11632001f49Smrgstatic void 11732001f49SmrgCheckError(int line) 11832001f49Smrg{ 11932001f49Smrg int n; 12032001f49Smrg n = glGetError(); 12132001f49Smrg if (n) 12232001f49Smrg printf("Warning: GL error 0x%x at line %d\n", n, line); 12332001f49Smrg} 12432001f49Smrg 12532001f49Smrg 12632001f49Smrgstatic void 12732001f49Smrgprint_display_info(Display *dpy) 12832001f49Smrg{ 12932001f49Smrg printf("name of display: %s\n", DisplayString(dpy)); 13032001f49Smrg} 13132001f49Smrg 13232001f49Smrg 13332001f49Smrg/** 13432001f49Smrg * Choose a simple FB Config. 13532001f49Smrg */ 13632001f49Smrgstatic GLXFBConfig * 13732001f49Smrgchoose_fb_config(Display *dpy, int scrnum) 13832001f49Smrg{ 13932001f49Smrg int fbAttribSingle[] = { 14032001f49Smrg GLX_RENDER_TYPE, GLX_RGBA_BIT, 14132001f49Smrg GLX_RED_SIZE, 1, 14232001f49Smrg GLX_GREEN_SIZE, 1, 14332001f49Smrg GLX_BLUE_SIZE, 1, 14432001f49Smrg GLX_DOUBLEBUFFER, False, 14532001f49Smrg None }; 14632001f49Smrg int fbAttribDouble[] = { 14732001f49Smrg GLX_RENDER_TYPE, GLX_RGBA_BIT, 14832001f49Smrg GLX_RED_SIZE, 1, 14932001f49Smrg GLX_GREEN_SIZE, 1, 15032001f49Smrg GLX_BLUE_SIZE, 1, 15132001f49Smrg GLX_DOUBLEBUFFER, True, 15232001f49Smrg None }; 15332001f49Smrg GLXFBConfig *configs; 15432001f49Smrg int nConfigs; 15532001f49Smrg 15632001f49Smrg configs = glXChooseFBConfig(dpy, scrnum, fbAttribSingle, &nConfigs); 15732001f49Smrg if (!configs) 15832001f49Smrg configs = glXChooseFBConfig(dpy, scrnum, fbAttribDouble, &nConfigs); 15932001f49Smrg 16032001f49Smrg return configs; 16132001f49Smrg} 16232001f49Smrg 16332001f49Smrg 16432001f49Smrgstatic Bool CreateContextErrorFlag; 16532001f49Smrg 16632001f49Smrgstatic int 16732001f49Smrgcreate_context_error_handler(Display *dpy, XErrorEvent *error) 16832001f49Smrg{ 16932001f49Smrg (void) dpy; 17032001f49Smrg (void) error->error_code; 17132001f49Smrg CreateContextErrorFlag = True; 17232001f49Smrg return 0; 17332001f49Smrg} 17432001f49Smrg 17532001f49Smrg 17632001f49Smrg/** 17732001f49Smrg * Try to create a GLX context of the given version with flags/options. 17832001f49Smrg * Note: A version number is required in order to get a core profile 17932001f49Smrg * (at least w/ NVIDIA). 18032001f49Smrg */ 18132001f49Smrgstatic GLXContext 18232001f49Smrgcreate_context_flags(Display *dpy, GLXFBConfig fbconfig, int major, int minor, 18332001f49Smrg int contextFlags, int profileMask, Bool direct) 18432001f49Smrg{ 18532001f49Smrg#ifdef GLX_ARB_create_context 18632001f49Smrg static PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_func = 0; 18732001f49Smrg static Bool firstCall = True; 18832001f49Smrg int (*old_handler)(Display *, XErrorEvent *); 18932001f49Smrg GLXContext context; 19032001f49Smrg int attribs[20]; 19132001f49Smrg int n = 0; 19232001f49Smrg 19332001f49Smrg if (firstCall) { 19432001f49Smrg /* See if we have GLX_ARB_create_context_profile and get pointer to 19532001f49Smrg * glXCreateContextAttribsARB() function. 19632001f49Smrg */ 19732001f49Smrg const char *glxExt = glXQueryExtensionsString(dpy, 0); 19832001f49Smrg if (extension_supported("GLX_ARB_create_context_profile", glxExt)) { 19932001f49Smrg glXCreateContextAttribsARB_func = (PFNGLXCREATECONTEXTATTRIBSARBPROC) 20032001f49Smrg glXGetProcAddress((const GLubyte *) "glXCreateContextAttribsARB"); 20132001f49Smrg } 20232001f49Smrg firstCall = False; 20332001f49Smrg } 20432001f49Smrg 20532001f49Smrg if (!glXCreateContextAttribsARB_func) 20632001f49Smrg return 0; 20732001f49Smrg 20832001f49Smrg /* setup attribute array */ 20932001f49Smrg if (major) { 21032001f49Smrg attribs[n++] = GLX_CONTEXT_MAJOR_VERSION_ARB; 21132001f49Smrg attribs[n++] = major; 21232001f49Smrg attribs[n++] = GLX_CONTEXT_MINOR_VERSION_ARB; 21332001f49Smrg attribs[n++] = minor; 21432001f49Smrg } 21532001f49Smrg if (contextFlags) { 21632001f49Smrg attribs[n++] = GLX_CONTEXT_FLAGS_ARB; 21732001f49Smrg attribs[n++] = contextFlags; 21832001f49Smrg } 21932001f49Smrg#ifdef GLX_ARB_create_context_profile 22032001f49Smrg if (profileMask) { 22132001f49Smrg attribs[n++] = GLX_CONTEXT_PROFILE_MASK_ARB; 22232001f49Smrg attribs[n++] = profileMask; 22332001f49Smrg } 22432001f49Smrg#endif 22532001f49Smrg attribs[n++] = 0; 22632001f49Smrg 22732001f49Smrg /* install X error handler */ 22832001f49Smrg old_handler = XSetErrorHandler(create_context_error_handler); 22932001f49Smrg CreateContextErrorFlag = False; 23032001f49Smrg 23132001f49Smrg /* try creating context */ 23232001f49Smrg context = glXCreateContextAttribsARB_func(dpy, 23332001f49Smrg fbconfig, 23432001f49Smrg 0, /* share_context */ 23532001f49Smrg direct, 23632001f49Smrg attribs); 23732001f49Smrg 23832001f49Smrg /* restore error handler */ 23932001f49Smrg XSetErrorHandler(old_handler); 24032001f49Smrg 24132001f49Smrg if (CreateContextErrorFlag) 24232001f49Smrg context = 0; 24332001f49Smrg 24432001f49Smrg if (context && direct) { 24532001f49Smrg if (!glXIsDirect(dpy, context)) { 24632001f49Smrg glXDestroyContext(dpy, context); 24732001f49Smrg return 0; 24832001f49Smrg } 24932001f49Smrg } 25032001f49Smrg 25132001f49Smrg return context; 25232001f49Smrg#else 25332001f49Smrg return 0; 25432001f49Smrg#endif 25532001f49Smrg} 25632001f49Smrg 25732001f49Smrg 25832001f49Smrg/** 25932001f49Smrg * Try to create a GLX context of the newest version. 26032001f49Smrg */ 26132001f49Smrgstatic GLXContext 26232001f49Smrgcreate_context_with_config(Display *dpy, GLXFBConfig config, 26332001f49Smrg Bool coreProfile, Bool es2Profile, Bool direct) 26432001f49Smrg{ 26532001f49Smrg GLXContext ctx = 0; 26632001f49Smrg 26732001f49Smrg if (coreProfile) { 26832001f49Smrg /* Try to create a core profile, starting with the newest version of 26932001f49Smrg * GL that we're aware of. If we don't specify the version 27032001f49Smrg */ 27132001f49Smrg int i; 2727ec3b29aSmrg for (i = 0; gl_versions[i].major > 0; i++) { 27332001f49Smrg /* don't bother below GL 3.0 */ 27432001f49Smrg if (gl_versions[i].major == 3 && 27532001f49Smrg gl_versions[i].minor == 0) 27632001f49Smrg return 0; 27732001f49Smrg ctx = create_context_flags(dpy, config, 27832001f49Smrg gl_versions[i].major, 27932001f49Smrg gl_versions[i].minor, 28032001f49Smrg 0x0, 28132001f49Smrg GLX_CONTEXT_CORE_PROFILE_BIT_ARB, 28232001f49Smrg direct); 28332001f49Smrg if (ctx) 28432001f49Smrg return ctx; 28532001f49Smrg } 28632001f49Smrg /* couldn't get core profile context */ 28732001f49Smrg return 0; 28832001f49Smrg } 28932001f49Smrg 29032001f49Smrg if (es2Profile) { 29132001f49Smrg#ifdef GLX_CONTEXT_ES2_PROFILE_BIT_EXT 29232001f49Smrg if (extension_supported("GLX_EXT_create_context_es2_profile", 29332001f49Smrg glXQueryExtensionsString(dpy, 0))) { 29432001f49Smrg ctx = create_context_flags(dpy, config, 2, 0, 0x0, 29532001f49Smrg GLX_CONTEXT_ES2_PROFILE_BIT_EXT, 29632001f49Smrg direct); 29732001f49Smrg return ctx; 29832001f49Smrg } 29932001f49Smrg#endif 30032001f49Smrg return 0; 30132001f49Smrg } 30232001f49Smrg 30332001f49Smrg /* GLX should return a context of the latest GL version that supports 30432001f49Smrg * the full profile. 30532001f49Smrg */ 30632001f49Smrg ctx = glXCreateNewContext(dpy, config, GLX_RGBA_TYPE, NULL, direct); 30732001f49Smrg 30832001f49Smrg /* make sure the context is direct, if direct was requested */ 30932001f49Smrg if (ctx && direct) { 31032001f49Smrg if (!glXIsDirect(dpy, ctx)) { 31132001f49Smrg glXDestroyContext(dpy, ctx); 31232001f49Smrg return 0; 31332001f49Smrg } 31432001f49Smrg } 31532001f49Smrg 31632001f49Smrg return ctx; 31732001f49Smrg} 31832001f49Smrg 31932001f49Smrg 32032001f49Smrgstatic XVisualInfo * 32132001f49Smrgchoose_xvisinfo(Display *dpy, int scrnum) 32232001f49Smrg{ 32332001f49Smrg int attribSingle[] = { 32432001f49Smrg GLX_RGBA, 32532001f49Smrg GLX_RED_SIZE, 1, 32632001f49Smrg GLX_GREEN_SIZE, 1, 32732001f49Smrg GLX_BLUE_SIZE, 1, 32832001f49Smrg None }; 32932001f49Smrg int attribDouble[] = { 33032001f49Smrg GLX_RGBA, 33132001f49Smrg GLX_RED_SIZE, 1, 33232001f49Smrg GLX_GREEN_SIZE, 1, 33332001f49Smrg GLX_BLUE_SIZE, 1, 33432001f49Smrg GLX_DOUBLEBUFFER, 33532001f49Smrg None }; 33632001f49Smrg XVisualInfo *visinfo; 33732001f49Smrg 33832001f49Smrg visinfo = glXChooseVisual(dpy, scrnum, attribSingle); 33932001f49Smrg if (!visinfo) 34032001f49Smrg visinfo = glXChooseVisual(dpy, scrnum, attribDouble); 34132001f49Smrg 34232001f49Smrg return visinfo; 34332001f49Smrg} 34432001f49Smrg 34532001f49Smrg 3467ec3b29aSmrgstatic void 3477ec3b29aSmrgquery_renderer(void) 3487ec3b29aSmrg{ 3497ec3b29aSmrg#ifdef GLX_MESA_query_renderer 3507ec3b29aSmrg PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC queryInteger; 3517ec3b29aSmrg PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC queryString; 3527ec3b29aSmrg unsigned int v[3]; 3537ec3b29aSmrg 3547ec3b29aSmrg queryInteger = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) 3557ec3b29aSmrg glXGetProcAddressARB((const GLubyte *) 3567ec3b29aSmrg "glXQueryCurrentRendererIntegerMESA"); 3577ec3b29aSmrg queryString = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) 3587ec3b29aSmrg glXGetProcAddressARB((const GLubyte *) 3597ec3b29aSmrg "glXQueryCurrentRendererStringMESA"); 3607ec3b29aSmrg 3617ec3b29aSmrg printf("Extended renderer info (GLX_MESA_query_renderer):\n"); 3627ec3b29aSmrg queryInteger(GLX_RENDERER_VENDOR_ID_MESA, v); 3637ec3b29aSmrg printf(" Vendor: %s (0x%x)\n", 3647ec3b29aSmrg queryString(GLX_RENDERER_VENDOR_ID_MESA), *v); 3657ec3b29aSmrg queryInteger(GLX_RENDERER_DEVICE_ID_MESA, v); 3667ec3b29aSmrg printf(" Device: %s (0x%x)\n", 3677ec3b29aSmrg queryString(GLX_RENDERER_DEVICE_ID_MESA), *v); 3687ec3b29aSmrg queryInteger(GLX_RENDERER_VERSION_MESA, v); 3697ec3b29aSmrg printf(" Version: %d.%d.%d\n", v[0], v[1], v[2]); 3707ec3b29aSmrg queryInteger(GLX_RENDERER_ACCELERATED_MESA, v); 3717ec3b29aSmrg printf(" Accelerated: %s\n", *v ? "yes" : "no"); 3727ec3b29aSmrg queryInteger(GLX_RENDERER_VIDEO_MEMORY_MESA, v); 3737ec3b29aSmrg printf(" Video memory: %dMB\n", *v); 3747ec3b29aSmrg queryInteger(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA, v); 3757ec3b29aSmrg printf(" Unified memory: %s\n", *v ? "yes" : "no"); 3767ec3b29aSmrg queryInteger(GLX_RENDERER_PREFERRED_PROFILE_MESA, v); 3777ec3b29aSmrg printf(" Preferred profile: %s (0x%x)\n", 3787ec3b29aSmrg *v == GLX_CONTEXT_CORE_PROFILE_BIT_ARB ? "core" : 3797ec3b29aSmrg *v == GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB ? "compat" : 3807ec3b29aSmrg "unknown", *v); 3817ec3b29aSmrg queryInteger(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA, v); 3827ec3b29aSmrg printf(" Max core profile version: %d.%d\n", v[0], v[1]); 3837ec3b29aSmrg queryInteger(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA, v); 3847ec3b29aSmrg printf(" Max compat profile version: %d.%d\n", v[0], v[1]); 3857ec3b29aSmrg queryInteger(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA, v); 3867ec3b29aSmrg printf(" Max GLES1 profile version: %d.%d\n", v[0], v[1]); 3877ec3b29aSmrg queryInteger(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA, v); 3887ec3b29aSmrg printf(" Max GLES[23] profile version: %d.%d\n", v[0], v[1]); 3897ec3b29aSmrg#endif 3907ec3b29aSmrg} 3917ec3b29aSmrg 3927ec3b29aSmrg 39332001f49Smrgstatic Bool 3947ec3b29aSmrgprint_screen_info(Display *dpy, int scrnum, 3957ec3b29aSmrg const struct options *opts, 39632001f49Smrg Bool coreProfile, Bool es2Profile, Bool limits, 3977ec3b29aSmrg Bool coreWorked) 39832001f49Smrg{ 39932001f49Smrg Window win; 40032001f49Smrg XSetWindowAttributes attr; 40132001f49Smrg unsigned long mask; 40232001f49Smrg Window root; 40332001f49Smrg GLXContext ctx = NULL; 40432001f49Smrg XVisualInfo *visinfo; 40532001f49Smrg int width = 100, height = 100; 40632001f49Smrg GLXFBConfig *fbconfigs; 40732001f49Smrg const char *oglstring = coreProfile ? "OpenGL core profile" : 40832001f49Smrg es2Profile ? "OpenGL ES profile" : "OpenGL"; 40932001f49Smrg 41032001f49Smrg root = RootWindow(dpy, scrnum); 41132001f49Smrg 41232001f49Smrg /* 41332001f49Smrg * Choose FBConfig or XVisualInfo and create a context. 41432001f49Smrg */ 41532001f49Smrg fbconfigs = choose_fb_config(dpy, scrnum); 41632001f49Smrg if (fbconfigs) { 41732001f49Smrg ctx = create_context_with_config(dpy, fbconfigs[0], 4187ec3b29aSmrg coreProfile, es2Profile, 4197ec3b29aSmrg opts->allowDirect); 4207ec3b29aSmrg if (!ctx && opts->allowDirect && !coreProfile) { 42132001f49Smrg /* try indirect */ 42232001f49Smrg ctx = create_context_with_config(dpy, fbconfigs[0], 42332001f49Smrg coreProfile, es2Profile, False); 42432001f49Smrg } 42532001f49Smrg 42632001f49Smrg visinfo = glXGetVisualFromFBConfig(dpy, fbconfigs[0]); 42732001f49Smrg XFree(fbconfigs); 42832001f49Smrg } 42932001f49Smrg else if (!coreProfile && !es2Profile) { 43032001f49Smrg visinfo = choose_xvisinfo(dpy, scrnum); 43132001f49Smrg if (visinfo) 4327ec3b29aSmrg ctx = glXCreateContext(dpy, visinfo, NULL, opts->allowDirect); 43332001f49Smrg } else 43432001f49Smrg visinfo = NULL; 43532001f49Smrg 43632001f49Smrg if (!visinfo && !coreProfile && !es2Profile) { 43732001f49Smrg fprintf(stderr, "Error: couldn't find RGB GLX visual or fbconfig\n"); 43832001f49Smrg return False; 43932001f49Smrg } 44032001f49Smrg 44132001f49Smrg if (!ctx) { 44232001f49Smrg if (!coreProfile && !es2Profile) 44332001f49Smrg fprintf(stderr, "Error: glXCreateContext failed\n"); 44432001f49Smrg XFree(visinfo); 44532001f49Smrg return False; 44632001f49Smrg } 44732001f49Smrg 44832001f49Smrg /* 44932001f49Smrg * Create a window so that we can just bind the context. 45032001f49Smrg */ 45132001f49Smrg attr.background_pixel = 0; 45232001f49Smrg attr.border_pixel = 0; 45332001f49Smrg attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); 45432001f49Smrg attr.event_mask = StructureNotifyMask | ExposureMask; 45532001f49Smrg mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; 45632001f49Smrg win = XCreateWindow(dpy, root, 0, 0, width, height, 45732001f49Smrg 0, visinfo->depth, InputOutput, 45832001f49Smrg visinfo->visual, mask, &attr); 45932001f49Smrg 46032001f49Smrg if (glXMakeCurrent(dpy, win, ctx)) { 46132001f49Smrg const char *serverVendor = glXQueryServerString(dpy, scrnum, GLX_VENDOR); 46232001f49Smrg const char *serverVersion = glXQueryServerString(dpy, scrnum, GLX_VERSION); 46332001f49Smrg const char *serverExtensions = glXQueryServerString(dpy, scrnum, GLX_EXTENSIONS); 46432001f49Smrg const char *clientVendor = glXGetClientString(dpy, GLX_VENDOR); 46532001f49Smrg const char *clientVersion = glXGetClientString(dpy, GLX_VERSION); 46632001f49Smrg const char *clientExtensions = glXGetClientString(dpy, GLX_EXTENSIONS); 46732001f49Smrg const char *glxExtensions = glXQueryExtensionsString(dpy, scrnum); 46832001f49Smrg const char *glVendor = (const char *) glGetString(GL_VENDOR); 46932001f49Smrg const char *glRenderer = (const char *) glGetString(GL_RENDERER); 47032001f49Smrg const char *glVersion = (const char *) glGetString(GL_VERSION); 4717ec3b29aSmrg char *glExtensions = NULL; 4727ec3b29aSmrg int glxVersionMajor = 0; 4737ec3b29aSmrg int glxVersionMinor = 0; 47432001f49Smrg char *displayName = NULL; 47532001f49Smrg char *colon = NULL, *period = NULL; 47632001f49Smrg struct ext_functions extfuncs; 47732001f49Smrg 47832001f49Smrg CheckError(__LINE__); 47932001f49Smrg 48032001f49Smrg /* Get some ext functions */ 48132001f49Smrg extfuncs.GetProgramivARB = (GETPROGRAMIVARBPROC) 48232001f49Smrg glXGetProcAddressARB((GLubyte *) "glGetProgramivARB"); 48332001f49Smrg extfuncs.GetStringi = (GETSTRINGIPROC) 48432001f49Smrg glXGetProcAddressARB((GLubyte *) "glGetStringi"); 48532001f49Smrg extfuncs.GetConvolutionParameteriv = (GETCONVOLUTIONPARAMETERIVPROC) 48632001f49Smrg glXGetProcAddressARB((GLubyte *) "glGetConvolutionParameteriv"); 48732001f49Smrg 4887ec3b29aSmrg if (!glXQueryVersion(dpy, & glxVersionMajor, & glxVersionMinor)) { 4897ec3b29aSmrg fprintf(stderr, "Error: glXQueryVersion failed\n"); 4907ec3b29aSmrg exit(1); 4917ec3b29aSmrg } 4927ec3b29aSmrg 49332001f49Smrg /* Get list of GL extensions */ 4947ec3b29aSmrg if (coreProfile && extfuncs.GetStringi) 49532001f49Smrg glExtensions = build_core_profile_extension_list(&extfuncs); 4967ec3b29aSmrg if (!glExtensions) { 4977ec3b29aSmrg coreProfile = False; 49832001f49Smrg glExtensions = (char *) glGetString(GL_EXTENSIONS); 49932001f49Smrg } 50032001f49Smrg 50132001f49Smrg CheckError(__LINE__); 50232001f49Smrg 50332001f49Smrg if (!coreWorked) { 50432001f49Smrg /* Strip the screen number from the display name, if present. */ 50532001f49Smrg if (!(displayName = (char *) malloc(strlen(DisplayString(dpy)) + 1))) { 50632001f49Smrg fprintf(stderr, "Error: malloc() failed\n"); 50732001f49Smrg exit(1); 50832001f49Smrg } 50932001f49Smrg strcpy(displayName, DisplayString(dpy)); 51032001f49Smrg colon = strrchr(displayName, ':'); 51132001f49Smrg if (colon) { 51232001f49Smrg period = strchr(colon, '.'); 51332001f49Smrg if (period) 51432001f49Smrg *period = '\0'; 51532001f49Smrg } 51632001f49Smrg 51732001f49Smrg printf("display: %s screen: %d\n", displayName, scrnum); 51832001f49Smrg free(displayName); 51932001f49Smrg printf("direct rendering: "); 52032001f49Smrg if (glXIsDirect(dpy, ctx)) { 52132001f49Smrg printf("Yes\n"); 52232001f49Smrg } 52332001f49Smrg else { 5247ec3b29aSmrg if (!opts->allowDirect) { 52532001f49Smrg printf("No (-i specified)\n"); 52632001f49Smrg } 52732001f49Smrg else if (getenv("LIBGL_ALWAYS_INDIRECT")) { 52832001f49Smrg printf("No (LIBGL_ALWAYS_INDIRECT set)\n"); 52932001f49Smrg } 53032001f49Smrg else { 53132001f49Smrg printf("No (If you want to find out why, try setting " 53232001f49Smrg "LIBGL_DEBUG=verbose)\n"); 53332001f49Smrg } 53432001f49Smrg } 5357ec3b29aSmrg if (opts->mode != Brief) { 5367ec3b29aSmrg printf("server glx vendor string: %s\n", serverVendor); 5377ec3b29aSmrg printf("server glx version string: %s\n", serverVersion); 5387ec3b29aSmrg printf("server glx extensions:\n"); 5397ec3b29aSmrg print_extension_list(serverExtensions, opts->singleLine); 5407ec3b29aSmrg printf("client glx vendor string: %s\n", clientVendor); 5417ec3b29aSmrg printf("client glx version string: %s\n", clientVersion); 5427ec3b29aSmrg printf("client glx extensions:\n"); 5437ec3b29aSmrg print_extension_list(clientExtensions, opts->singleLine); 5447ec3b29aSmrg printf("GLX version: %u.%u\n", glxVersionMajor, glxVersionMinor); 5457ec3b29aSmrg printf("GLX extensions:\n"); 5467ec3b29aSmrg print_extension_list(glxExtensions, opts->singleLine); 5477ec3b29aSmrg } 5487ec3b29aSmrg if (strstr(glxExtensions, "GLX_MESA_query_renderer")) 5497ec3b29aSmrg query_renderer(); 5507ec3b29aSmrg print_gpu_memory_info(glExtensions); 55132001f49Smrg printf("OpenGL vendor string: %s\n", glVendor); 55232001f49Smrg printf("OpenGL renderer string: %s\n", glRenderer); 55332001f49Smrg } else 55432001f49Smrg printf("\n"); 55532001f49Smrg 55632001f49Smrg printf("%s version string: %s\n", oglstring, glVersion); 55732001f49Smrg 55832001f49Smrg version = (glVersion[0] - '0') * 10 + (glVersion[2] - '0'); 55932001f49Smrg 56032001f49Smrg CheckError(__LINE__); 56132001f49Smrg 56232001f49Smrg#ifdef GL_VERSION_2_0 56332001f49Smrg if (version >= 20) { 56432001f49Smrg char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION); 56532001f49Smrg printf("%s shading language version string: %s\n", oglstring, v); 56632001f49Smrg } 56732001f49Smrg#endif 56832001f49Smrg CheckError(__LINE__); 56932001f49Smrg#ifdef GL_VERSION_3_0 57032001f49Smrg if (version >= 30 && !es2Profile) { 57132001f49Smrg GLint flags; 57232001f49Smrg glGetIntegerv(GL_CONTEXT_FLAGS, &flags); 57332001f49Smrg printf("%s context flags: %s\n", oglstring, context_flags_string(flags)); 57432001f49Smrg } 57532001f49Smrg#endif 57632001f49Smrg CheckError(__LINE__); 57732001f49Smrg#ifdef GL_VERSION_3_2 57832001f49Smrg if (version >= 32 && !es2Profile) { 57932001f49Smrg GLint mask; 58032001f49Smrg glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); 58132001f49Smrg printf("%s profile mask: %s\n", oglstring, profile_mask_string(mask)); 58232001f49Smrg } 58332001f49Smrg#endif 58432001f49Smrg 58532001f49Smrg CheckError(__LINE__); 58632001f49Smrg 5877ec3b29aSmrg if (opts->mode != Brief) { 5887ec3b29aSmrg printf("%s extensions:\n", oglstring); 5897ec3b29aSmrg print_extension_list(glExtensions, opts->singleLine); 5907ec3b29aSmrg } 59132001f49Smrg 59232001f49Smrg if (limits) { 59332001f49Smrg print_limits(glExtensions, oglstring, version, &extfuncs); 59432001f49Smrg } 59532001f49Smrg 59632001f49Smrg if (coreProfile) 59732001f49Smrg free(glExtensions); 59832001f49Smrg } 59932001f49Smrg else { 60032001f49Smrg fprintf(stderr, "Error: glXMakeCurrent failed\n"); 60132001f49Smrg } 60232001f49Smrg 60332001f49Smrg glXDestroyContext(dpy, ctx); 60432001f49Smrg XFree(visinfo); 60532001f49Smrg XDestroyWindow(dpy, win); 60632001f49Smrg XSync(dpy, 1); 60732001f49Smrg return True; 60832001f49Smrg} 60932001f49Smrg 61032001f49Smrg 61132001f49Smrgstatic const char * 61232001f49Smrgvisual_class_name(int cls) 61332001f49Smrg{ 61432001f49Smrg switch (cls) { 61532001f49Smrg case StaticColor: 61632001f49Smrg return "StaticColor"; 61732001f49Smrg case PseudoColor: 61832001f49Smrg return "PseudoColor"; 61932001f49Smrg case StaticGray: 62032001f49Smrg return "StaticGray"; 62132001f49Smrg case GrayScale: 62232001f49Smrg return "GrayScale"; 62332001f49Smrg case TrueColor: 62432001f49Smrg return "TrueColor"; 62532001f49Smrg case DirectColor: 62632001f49Smrg return "DirectColor"; 62732001f49Smrg default: 62832001f49Smrg return ""; 62932001f49Smrg } 63032001f49Smrg} 63132001f49Smrg 63232001f49Smrgstatic const char * 63332001f49Smrgvisual_drawable_type(int type) 63432001f49Smrg{ 63532001f49Smrg const static struct bit_info bits[] = { 63632001f49Smrg { GLX_WINDOW_BIT, "window" }, 63732001f49Smrg { GLX_PIXMAP_BIT, "pixmap" }, 63832001f49Smrg { GLX_PBUFFER_BIT, "pbuffer" } 63932001f49Smrg }; 64032001f49Smrg 64132001f49Smrg return bitmask_to_string(bits, ELEMENTS(bits), type); 64232001f49Smrg} 64332001f49Smrg 64432001f49Smrgstatic const char * 64532001f49Smrgvisual_class_abbrev(int cls) 64632001f49Smrg{ 64732001f49Smrg switch (cls) { 64832001f49Smrg case StaticColor: 64932001f49Smrg return "sc"; 65032001f49Smrg case PseudoColor: 65132001f49Smrg return "pc"; 65232001f49Smrg case StaticGray: 65332001f49Smrg return "sg"; 65432001f49Smrg case GrayScale: 65532001f49Smrg return "gs"; 65632001f49Smrg case TrueColor: 65732001f49Smrg return "tc"; 65832001f49Smrg case DirectColor: 65932001f49Smrg return "dc"; 66032001f49Smrg default: 66132001f49Smrg return ""; 66232001f49Smrg } 66332001f49Smrg} 66432001f49Smrg 66532001f49Smrgstatic const char * 66632001f49Smrgvisual_render_type_name(int type) 66732001f49Smrg{ 66832001f49Smrg switch (type) { 66932001f49Smrg case GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT: 67032001f49Smrg return "ufloat"; 67132001f49Smrg case GLX_RGBA_FLOAT_BIT_ARB: 67232001f49Smrg return "float"; 67332001f49Smrg case GLX_RGBA_BIT: 67432001f49Smrg return "rgba"; 67532001f49Smrg case GLX_COLOR_INDEX_BIT: 67632001f49Smrg return "ci"; 67732001f49Smrg case GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT: 67832001f49Smrg return "rgba|ci"; 67932001f49Smrg default: 68032001f49Smrg return ""; 68132001f49Smrg } 68232001f49Smrg} 68332001f49Smrg 68432001f49Smrgstatic const char * 68532001f49Smrgcaveat_string(int caveat) 68632001f49Smrg{ 68732001f49Smrg switch (caveat) { 68832001f49Smrg#ifdef GLX_EXT_visual_rating 68932001f49Smrg case GLX_SLOW_VISUAL_EXT: 69032001f49Smrg return "Slow"; 69132001f49Smrg case GLX_NON_CONFORMANT_VISUAL_EXT: 69232001f49Smrg return "Ncon"; 69332001f49Smrg case GLX_NONE_EXT: 69432001f49Smrg /* fall-through */ 69532001f49Smrg#endif 69632001f49Smrg case 0: 69732001f49Smrg /* fall-through */ 69832001f49Smrg default: 69932001f49Smrg return "None"; 70032001f49Smrg } 70132001f49Smrg} 70232001f49Smrg 70332001f49Smrg 70432001f49Smrgstatic Bool 70532001f49Smrgget_visual_attribs(Display *dpy, XVisualInfo *vInfo, 70632001f49Smrg struct visual_attribs *attribs) 70732001f49Smrg{ 70832001f49Smrg const char *ext = glXQueryExtensionsString(dpy, vInfo->screen); 70932001f49Smrg int rgba; 71032001f49Smrg 71132001f49Smrg memset(attribs, 0, sizeof(struct visual_attribs)); 71232001f49Smrg 71332001f49Smrg attribs->id = vInfo->visualid; 71432001f49Smrg#if defined(__cplusplus) || defined(c_plusplus) 71532001f49Smrg attribs->klass = vInfo->c_class; 71632001f49Smrg#else 71732001f49Smrg attribs->klass = vInfo->class; 71832001f49Smrg#endif 71932001f49Smrg attribs->depth = vInfo->depth; 72032001f49Smrg attribs->redMask = vInfo->red_mask; 72132001f49Smrg attribs->greenMask = vInfo->green_mask; 72232001f49Smrg attribs->blueMask = vInfo->blue_mask; 72332001f49Smrg attribs->colormapSize = vInfo->colormap_size; 72432001f49Smrg attribs->bitsPerRGB = vInfo->bits_per_rgb; 72532001f49Smrg 72632001f49Smrg if (glXGetConfig(dpy, vInfo, GLX_USE_GL, &attribs->supportsGL) != 0 || 72732001f49Smrg !attribs->supportsGL) 72832001f49Smrg return False; 72932001f49Smrg glXGetConfig(dpy, vInfo, GLX_BUFFER_SIZE, &attribs->bufferSize); 73032001f49Smrg glXGetConfig(dpy, vInfo, GLX_LEVEL, &attribs->level); 73132001f49Smrg glXGetConfig(dpy, vInfo, GLX_RGBA, &rgba); 73232001f49Smrg if (rgba) 73332001f49Smrg attribs->render_type = GLX_RGBA_BIT; 73432001f49Smrg else 73532001f49Smrg attribs->render_type = GLX_COLOR_INDEX_BIT; 73632001f49Smrg 73732001f49Smrg glXGetConfig(dpy, vInfo, GLX_DRAWABLE_TYPE, &attribs->drawableType); 73832001f49Smrg glXGetConfig(dpy, vInfo, GLX_DOUBLEBUFFER, &attribs->doubleBuffer); 73932001f49Smrg glXGetConfig(dpy, vInfo, GLX_STEREO, &attribs->stereo); 74032001f49Smrg glXGetConfig(dpy, vInfo, GLX_AUX_BUFFERS, &attribs->auxBuffers); 74132001f49Smrg glXGetConfig(dpy, vInfo, GLX_RED_SIZE, &attribs->redSize); 74232001f49Smrg glXGetConfig(dpy, vInfo, GLX_GREEN_SIZE, &attribs->greenSize); 74332001f49Smrg glXGetConfig(dpy, vInfo, GLX_BLUE_SIZE, &attribs->blueSize); 74432001f49Smrg glXGetConfig(dpy, vInfo, GLX_ALPHA_SIZE, &attribs->alphaSize); 74532001f49Smrg glXGetConfig(dpy, vInfo, GLX_DEPTH_SIZE, &attribs->depthSize); 74632001f49Smrg glXGetConfig(dpy, vInfo, GLX_STENCIL_SIZE, &attribs->stencilSize); 74732001f49Smrg glXGetConfig(dpy, vInfo, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize); 74832001f49Smrg glXGetConfig(dpy, vInfo, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize); 74932001f49Smrg glXGetConfig(dpy, vInfo, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize); 75032001f49Smrg glXGetConfig(dpy, vInfo, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize); 75132001f49Smrg 75232001f49Smrg /* get transparent pixel stuff */ 75332001f49Smrg glXGetConfig(dpy, vInfo,GLX_TRANSPARENT_TYPE, &attribs->transparentType); 75432001f49Smrg if (attribs->transparentType == GLX_TRANSPARENT_RGB) { 75532001f49Smrg glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue); 75632001f49Smrg glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue); 75732001f49Smrg glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue); 75832001f49Smrg glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue); 75932001f49Smrg } 76032001f49Smrg else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) { 76132001f49Smrg glXGetConfig(dpy, vInfo, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue); 76232001f49Smrg } 76332001f49Smrg 76432001f49Smrg /* multisample attribs */ 76532001f49Smrg#ifdef GLX_ARB_multisample 76632001f49Smrg if (ext && strstr(ext, "GLX_ARB_multisample")) { 76732001f49Smrg glXGetConfig(dpy, vInfo, GLX_SAMPLE_BUFFERS_ARB, &attribs->numMultisample); 76832001f49Smrg glXGetConfig(dpy, vInfo, GLX_SAMPLES_ARB, &attribs->numSamples); 76932001f49Smrg } 77032001f49Smrg#endif 77132001f49Smrg else { 77232001f49Smrg attribs->numSamples = 0; 77332001f49Smrg attribs->numMultisample = 0; 77432001f49Smrg } 77532001f49Smrg 77632001f49Smrg#if defined(GLX_EXT_visual_rating) 77732001f49Smrg if (ext && strstr(ext, "GLX_EXT_visual_rating")) { 77832001f49Smrg glXGetConfig(dpy, vInfo, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat); 77932001f49Smrg } 78032001f49Smrg else { 78132001f49Smrg attribs->visualCaveat = GLX_NONE_EXT; 78232001f49Smrg } 78332001f49Smrg#else 78432001f49Smrg attribs->visualCaveat = 0; 78532001f49Smrg#endif 78632001f49Smrg 78732001f49Smrg#if defined(GLX_EXT_framebuffer_sRGB) 78832001f49Smrg if (ext && strstr(ext, "GLX_EXT_framebuffer_sRGB")) { 78932001f49Smrg glXGetConfig(dpy, vInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &attribs->srgb); 79032001f49Smrg } 79132001f49Smrg#endif 79232001f49Smrg 79332001f49Smrg return True; 79432001f49Smrg} 79532001f49Smrg 79632001f49Smrg#ifdef GLX_VERSION_1_3 79732001f49Smrg 79832001f49Smrgstatic int 79932001f49Smrgglx_token_to_visual_class(int visual_type) 80032001f49Smrg{ 80132001f49Smrg switch (visual_type) { 80232001f49Smrg case GLX_TRUE_COLOR: 80332001f49Smrg return TrueColor; 80432001f49Smrg case GLX_DIRECT_COLOR: 80532001f49Smrg return DirectColor; 80632001f49Smrg case GLX_PSEUDO_COLOR: 80732001f49Smrg return PseudoColor; 80832001f49Smrg case GLX_STATIC_COLOR: 80932001f49Smrg return StaticColor; 81032001f49Smrg case GLX_GRAY_SCALE: 81132001f49Smrg return GrayScale; 81232001f49Smrg case GLX_STATIC_GRAY: 81332001f49Smrg return StaticGray; 81432001f49Smrg case GLX_NONE: 81532001f49Smrg default: 81632001f49Smrg return None; 81732001f49Smrg } 81832001f49Smrg} 81932001f49Smrg 82032001f49Smrgstatic Bool 82132001f49Smrgget_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig, 82232001f49Smrg struct visual_attribs *attribs) 82332001f49Smrg{ 82432001f49Smrg const char *ext = glXQueryExtensionsString(dpy, 0); 82532001f49Smrg int visual_type; 82632001f49Smrg XVisualInfo *vInfo; 82732001f49Smrg 82832001f49Smrg memset(attribs, 0, sizeof(struct visual_attribs)); 82932001f49Smrg 83032001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_FBCONFIG_ID, &attribs->id); 83132001f49Smrg 83232001f49Smrg vInfo = glXGetVisualFromFBConfig(dpy, fbconfig); 83332001f49Smrg 83432001f49Smrg if (vInfo != NULL) { 83532001f49Smrg attribs->vis_id = vInfo->visualid; 83632001f49Smrg attribs->depth = vInfo->depth; 83732001f49Smrg attribs->redMask = vInfo->red_mask; 83832001f49Smrg attribs->greenMask = vInfo->green_mask; 83932001f49Smrg attribs->blueMask = vInfo->blue_mask; 84032001f49Smrg attribs->colormapSize = vInfo->colormap_size; 84132001f49Smrg attribs->bitsPerRGB = vInfo->bits_per_rgb; 84232001f49Smrg } 84332001f49Smrg 84432001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_X_VISUAL_TYPE, &visual_type); 84532001f49Smrg attribs->klass = glx_token_to_visual_class(visual_type); 84632001f49Smrg 84732001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_DRAWABLE_TYPE, &attribs->drawableType); 84832001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_BUFFER_SIZE, &attribs->bufferSize); 84932001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_LEVEL, &attribs->level); 85032001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_RENDER_TYPE, &attribs->render_type); 85132001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_DOUBLEBUFFER, &attribs->doubleBuffer); 85232001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_STEREO, &attribs->stereo); 85332001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_AUX_BUFFERS, &attribs->auxBuffers); 85432001f49Smrg 85532001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_RED_SIZE, &attribs->redSize); 85632001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_GREEN_SIZE, &attribs->greenSize); 85732001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_BLUE_SIZE, &attribs->blueSize); 85832001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_ALPHA_SIZE, &attribs->alphaSize); 85932001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_DEPTH_SIZE, &attribs->depthSize); 86032001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_STENCIL_SIZE, &attribs->stencilSize); 86132001f49Smrg 86232001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize); 86332001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize); 86432001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize); 86532001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize); 86632001f49Smrg 86732001f49Smrg /* get transparent pixel stuff */ 86832001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig,GLX_TRANSPARENT_TYPE, &attribs->transparentType); 86932001f49Smrg if (attribs->transparentType == GLX_TRANSPARENT_RGB) { 87032001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_RED_VALUE, &attribs->transparentRedValue); 87132001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_GREEN_VALUE, &attribs->transparentGreenValue); 87232001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_BLUE_VALUE, &attribs->transparentBlueValue); 87332001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_ALPHA_VALUE, &attribs->transparentAlphaValue); 87432001f49Smrg } 87532001f49Smrg else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) { 87632001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_TRANSPARENT_INDEX_VALUE, &attribs->transparentIndexValue); 87732001f49Smrg } 87832001f49Smrg 87932001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLE_BUFFERS, &attribs->numMultisample); 88032001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples); 88132001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat); 88232001f49Smrg 88332001f49Smrg#if defined(GLX_NV_float_buffer) 88432001f49Smrg if (ext && strstr(ext, "GLX_NV_float_buffer")) { 88532001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_FLOAT_COMPONENTS_NV, &attribs->floatComponents); 88632001f49Smrg } 88732001f49Smrg#endif 88832001f49Smrg#if defined(GLX_ARB_fbconfig_float) 88932001f49Smrg if (ext && strstr(ext, "GLX_ARB_fbconfig_float")) { 89032001f49Smrg if (attribs->render_type & GLX_RGBA_FLOAT_BIT_ARB) { 89132001f49Smrg attribs->floatComponents = True; 89232001f49Smrg } 89332001f49Smrg } 89432001f49Smrg#endif 89532001f49Smrg#if defined(GLX_EXT_fbconfig_packed_float) 89632001f49Smrg if (ext && strstr(ext, "GLX_EXT_fbconfig_packed_float")) { 89732001f49Smrg if (attribs->render_type & GLX_RGBA_UNSIGNED_FLOAT_BIT_EXT) { 89832001f49Smrg attribs->packedfloatComponents = True; 89932001f49Smrg } 90032001f49Smrg } 90132001f49Smrg#endif 90232001f49Smrg 90332001f49Smrg#if defined(GLX_EXT_framebuffer_sRGB) 90432001f49Smrg if (ext && strstr(ext, "GLX_EXT_framebuffer_sRGB")) { 90532001f49Smrg glXGetFBConfigAttrib(dpy, fbconfig, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &attribs->srgb); 90632001f49Smrg } 90732001f49Smrg#endif 90832001f49Smrg return True; 90932001f49Smrg} 91032001f49Smrg 91132001f49Smrg#endif 91232001f49Smrg 91332001f49Smrg 91432001f49Smrg 91532001f49Smrgstatic void 91632001f49Smrgprint_visual_attribs_verbose(const struct visual_attribs *attribs, 91732001f49Smrg int fbconfigs) 91832001f49Smrg{ 91932001f49Smrg if (fbconfigs) { 92032001f49Smrg printf("FBConfig ID: %x Visual ID=%x depth=%d class=%s, type=%s\n", 92132001f49Smrg attribs->id, attribs->vis_id, attribs->depth, 92232001f49Smrg visual_class_name(attribs->klass), 92332001f49Smrg visual_drawable_type(attribs->drawableType)); 92432001f49Smrg } 92532001f49Smrg else { 92632001f49Smrg printf("Visual ID: %x depth=%d class=%s, type=%s\n", 92732001f49Smrg attribs->id, attribs->depth, visual_class_name(attribs->klass), 92832001f49Smrg visual_drawable_type(attribs->drawableType)); 92932001f49Smrg } 93032001f49Smrg printf(" bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n", 93132001f49Smrg attribs->bufferSize, attribs->level, 93232001f49Smrg visual_render_type_name(attribs->render_type), 93332001f49Smrg attribs->doubleBuffer, attribs->stereo); 93432001f49Smrg printf(" rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d float=%c sRGB=%c\n", 93532001f49Smrg attribs->redSize, attribs->greenSize, 93632001f49Smrg attribs->blueSize, attribs->alphaSize, 93732001f49Smrg attribs->packedfloatComponents ? 'P' : attribs->floatComponents ? 'Y' : 'N', 93832001f49Smrg attribs->srgb ? 'Y' : 'N'); 93932001f49Smrg printf(" auxBuffers=%d depthSize=%d stencilSize=%d\n", 94032001f49Smrg attribs->auxBuffers, attribs->depthSize, attribs->stencilSize); 94132001f49Smrg printf(" accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n", 94232001f49Smrg attribs->accumRedSize, attribs->accumGreenSize, 94332001f49Smrg attribs->accumBlueSize, attribs->accumAlphaSize); 94432001f49Smrg printf(" multiSample=%d multiSampleBuffers=%d\n", 94532001f49Smrg attribs->numSamples, attribs->numMultisample); 94632001f49Smrg#ifdef GLX_EXT_visual_rating 94732001f49Smrg if (attribs->visualCaveat == GLX_NONE_EXT || attribs->visualCaveat == 0) 94832001f49Smrg printf(" visualCaveat=None\n"); 94932001f49Smrg else if (attribs->visualCaveat == GLX_SLOW_VISUAL_EXT) 95032001f49Smrg printf(" visualCaveat=Slow\n"); 95132001f49Smrg else if (attribs->visualCaveat == GLX_NON_CONFORMANT_VISUAL_EXT) 95232001f49Smrg printf(" visualCaveat=Nonconformant\n"); 95332001f49Smrg#endif 95432001f49Smrg if (attribs->transparentType == GLX_NONE) { 95532001f49Smrg printf(" Opaque.\n"); 95632001f49Smrg } 95732001f49Smrg else if (attribs->transparentType == GLX_TRANSPARENT_RGB) { 95832001f49Smrg printf(" Transparent RGB: Red=%d Green=%d Blue=%d Alpha=%d\n",attribs->transparentRedValue,attribs->transparentGreenValue,attribs->transparentBlueValue,attribs->transparentAlphaValue); 95932001f49Smrg } 96032001f49Smrg else if (attribs->transparentType == GLX_TRANSPARENT_INDEX) { 96132001f49Smrg printf(" Transparent index=%d\n",attribs->transparentIndexValue); 96232001f49Smrg } 96332001f49Smrg} 96432001f49Smrg 96532001f49Smrg 96632001f49Smrgstatic void 96732001f49Smrgprint_visual_attribs_short_header(void) 96832001f49Smrg{ 96932001f49Smrg printf(" visual x bf lv rg d st colorbuffer sr ax dp st accumbuffer ms cav\n"); 97032001f49Smrg printf(" id dep cl sp sz l ci b ro r g b a F gb bf th cl r g b a ns b eat\n"); 97132001f49Smrg printf("----------------------------------------------------------------------------\n"); 97232001f49Smrg} 97332001f49Smrg 97432001f49Smrg 97532001f49Smrgstatic void 97632001f49Smrgprint_visual_attribs_short(const struct visual_attribs *attribs) 97732001f49Smrg{ 97832001f49Smrg const char *caveat = caveat_string(attribs->visualCaveat); 97932001f49Smrg 98032001f49Smrg printf("0x%03x %2d %2s %2d %3d %2d %c%c %c %c %2d %2d %2d %2d %c %c %2d %2d %2d", 98132001f49Smrg attribs->id, 98232001f49Smrg attribs->depth, 98332001f49Smrg visual_class_abbrev(attribs->klass), 98432001f49Smrg attribs->transparentType != GLX_NONE, 98532001f49Smrg attribs->bufferSize, 98632001f49Smrg attribs->level, 98732001f49Smrg (attribs->render_type & GLX_RGBA_BIT) ? 'r' : ' ', 98832001f49Smrg (attribs->render_type & GLX_COLOR_INDEX_BIT) ? 'c' : ' ', 98932001f49Smrg attribs->doubleBuffer ? 'y' : '.', 99032001f49Smrg attribs->stereo ? 'y' : '.', 99132001f49Smrg attribs->redSize, attribs->greenSize, 99232001f49Smrg attribs->blueSize, attribs->alphaSize, 99332001f49Smrg attribs->packedfloatComponents ? 'u' : attribs->floatComponents ? 'f' : '.', 99432001f49Smrg attribs->srgb ? 's' : '.', 99532001f49Smrg attribs->auxBuffers, 99632001f49Smrg attribs->depthSize, 99732001f49Smrg attribs->stencilSize 99832001f49Smrg ); 99932001f49Smrg 100032001f49Smrg printf(" %2d %2d %2d %2d %2d %1d %s\n", 100132001f49Smrg attribs->accumRedSize, attribs->accumGreenSize, 100232001f49Smrg attribs->accumBlueSize, attribs->accumAlphaSize, 100332001f49Smrg attribs->numSamples, attribs->numMultisample, 100432001f49Smrg caveat 100532001f49Smrg ); 100632001f49Smrg} 100732001f49Smrg 100832001f49Smrg 100932001f49Smrgstatic void 101032001f49Smrgprint_visual_attribs_long_header(void) 101132001f49Smrg{ 101232001f49Smrg printf("Vis Vis Visual Trans buff lev render DB ste r g b a s aux dep ste accum buffer MS MS \n"); 101332001f49Smrg printf(" ID Depth Type parent size el type reo sz sz sz sz flt rgb buf th ncl r g b a num bufs caveats\n"); 101432001f49Smrg printf("--------------------------------------------------------------------------------------------------------------------\n"); 101532001f49Smrg} 101632001f49Smrg 101732001f49Smrg 101832001f49Smrgstatic void 101932001f49Smrgprint_visual_attribs_long(const struct visual_attribs *attribs) 102032001f49Smrg{ 102132001f49Smrg const char *caveat = caveat_string(attribs->visualCaveat); 102232001f49Smrg 102332001f49Smrg printf("0x%3x %2d %-11s %2d %3d %2d %4s %3d %3d %3d %3d %3d %3d", 102432001f49Smrg attribs->id, 102532001f49Smrg attribs->depth, 102632001f49Smrg visual_class_name(attribs->klass), 102732001f49Smrg attribs->transparentType != GLX_NONE, 102832001f49Smrg attribs->bufferSize, 102932001f49Smrg attribs->level, 103032001f49Smrg visual_render_type_name(attribs->render_type), 103132001f49Smrg attribs->doubleBuffer, 103232001f49Smrg attribs->stereo, 103332001f49Smrg attribs->redSize, attribs->greenSize, 103432001f49Smrg attribs->blueSize, attribs->alphaSize 103532001f49Smrg ); 103632001f49Smrg 103732001f49Smrg printf(" %c %c %3d %4d %2d %3d %3d %3d %3d %2d %2d %6s\n", 103832001f49Smrg attribs->floatComponents ? 'f' : '.', 103932001f49Smrg attribs->srgb ? 's' : '.', 104032001f49Smrg attribs->auxBuffers, 104132001f49Smrg attribs->depthSize, 104232001f49Smrg attribs->stencilSize, 104332001f49Smrg attribs->accumRedSize, attribs->accumGreenSize, 104432001f49Smrg attribs->accumBlueSize, attribs->accumAlphaSize, 104532001f49Smrg attribs->numSamples, attribs->numMultisample, 104632001f49Smrg caveat 104732001f49Smrg ); 104832001f49Smrg} 104932001f49Smrg 105032001f49Smrg 105132001f49Smrgstatic void 105232001f49Smrgprint_visual_info(Display *dpy, int scrnum, InfoMode mode) 105332001f49Smrg{ 105432001f49Smrg XVisualInfo theTemplate; 105532001f49Smrg XVisualInfo *visuals; 105632001f49Smrg int numVisuals, numGlxVisuals; 105732001f49Smrg long mask; 105832001f49Smrg int i; 105932001f49Smrg struct visual_attribs attribs; 106032001f49Smrg 106132001f49Smrg /* get list of all visuals on this screen */ 106232001f49Smrg theTemplate.screen = scrnum; 106332001f49Smrg mask = VisualScreenMask; 106432001f49Smrg visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals); 106532001f49Smrg 106632001f49Smrg numGlxVisuals = 0; 106732001f49Smrg for (i = 0; i < numVisuals; i++) { 106832001f49Smrg if (get_visual_attribs(dpy, &visuals[i], &attribs)) 106932001f49Smrg numGlxVisuals++; 107032001f49Smrg } 107132001f49Smrg 107232001f49Smrg if (numGlxVisuals == 0) 107332001f49Smrg return; 107432001f49Smrg 107532001f49Smrg printf("%d GLX Visuals\n", numGlxVisuals); 107632001f49Smrg 107732001f49Smrg if (mode == Normal) 107832001f49Smrg print_visual_attribs_short_header(); 107932001f49Smrg else if (mode == Wide) 108032001f49Smrg print_visual_attribs_long_header(); 108132001f49Smrg 108232001f49Smrg for (i = 0; i < numVisuals; i++) { 108332001f49Smrg if (!get_visual_attribs(dpy, &visuals[i], &attribs)) 108432001f49Smrg continue; 108532001f49Smrg 108632001f49Smrg if (mode == Verbose) 108732001f49Smrg print_visual_attribs_verbose(&attribs, False); 108832001f49Smrg else if (mode == Normal) 108932001f49Smrg print_visual_attribs_short(&attribs); 109032001f49Smrg else if (mode == Wide) 109132001f49Smrg print_visual_attribs_long(&attribs); 109232001f49Smrg } 109332001f49Smrg printf("\n"); 109432001f49Smrg 109532001f49Smrg XFree(visuals); 109632001f49Smrg} 109732001f49Smrg 109832001f49Smrg#ifdef GLX_VERSION_1_3 109932001f49Smrg 110032001f49Smrgstatic void 110132001f49Smrgprint_fbconfig_info(Display *dpy, int scrnum, InfoMode mode) 110232001f49Smrg{ 110332001f49Smrg int numFBConfigs = 0; 110432001f49Smrg struct visual_attribs attribs; 110532001f49Smrg GLXFBConfig *fbconfigs; 110632001f49Smrg int i; 110732001f49Smrg 110832001f49Smrg /* get list of all fbconfigs on this screen */ 110932001f49Smrg fbconfigs = glXGetFBConfigs(dpy, scrnum, &numFBConfigs); 111032001f49Smrg 111132001f49Smrg if (numFBConfigs == 0) { 111232001f49Smrg XFree(fbconfigs); 111332001f49Smrg return; 111432001f49Smrg } 111532001f49Smrg 111632001f49Smrg printf("%d GLXFBConfigs:\n", numFBConfigs); 111732001f49Smrg if (mode == Normal) 111832001f49Smrg print_visual_attribs_short_header(); 111932001f49Smrg else if (mode == Wide) 112032001f49Smrg print_visual_attribs_long_header(); 112132001f49Smrg 112232001f49Smrg for (i = 0; i < numFBConfigs; i++) { 112332001f49Smrg get_fbconfig_attribs(dpy, fbconfigs[i], &attribs); 112432001f49Smrg 112532001f49Smrg if (mode == Verbose) 112632001f49Smrg print_visual_attribs_verbose(&attribs, True); 112732001f49Smrg else if (mode == Normal) 112832001f49Smrg print_visual_attribs_short(&attribs); 112932001f49Smrg else if (mode == Wide) 113032001f49Smrg print_visual_attribs_long(&attribs); 113132001f49Smrg } 113232001f49Smrg printf("\n"); 113332001f49Smrg 113432001f49Smrg XFree(fbconfigs); 113532001f49Smrg} 113632001f49Smrg 113732001f49Smrg#endif 113832001f49Smrg 113932001f49Smrg/* 114032001f49Smrg * Stand-alone Mesa doesn't really implement the GLX protocol so it 114132001f49Smrg * doesn't really know the GLX attributes associated with an X visual. 114232001f49Smrg * The first time a visual is presented to Mesa's pseudo-GLX it 114332001f49Smrg * attaches ancilliary buffers to it (like depth and stencil). 114432001f49Smrg * But that usually only works if glXChooseVisual is used. 114532001f49Smrg * This function calls glXChooseVisual() to sort of "prime the pump" 114632001f49Smrg * for Mesa's GLX so that the visuals that get reported actually 114732001f49Smrg * reflect what applications will see. 114832001f49Smrg * This has no effect when using true GLX. 114932001f49Smrg */ 115032001f49Smrgstatic void 115132001f49Smrgmesa_hack(Display *dpy, int scrnum) 115232001f49Smrg{ 115332001f49Smrg static int attribs[] = { 115432001f49Smrg GLX_RGBA, 115532001f49Smrg GLX_RED_SIZE, 1, 115632001f49Smrg GLX_GREEN_SIZE, 1, 115732001f49Smrg GLX_BLUE_SIZE, 1, 115832001f49Smrg GLX_DEPTH_SIZE, 1, 115932001f49Smrg GLX_STENCIL_SIZE, 1, 116032001f49Smrg GLX_ACCUM_RED_SIZE, 1, 116132001f49Smrg GLX_ACCUM_GREEN_SIZE, 1, 116232001f49Smrg GLX_ACCUM_BLUE_SIZE, 1, 116332001f49Smrg GLX_ACCUM_ALPHA_SIZE, 1, 116432001f49Smrg GLX_DOUBLEBUFFER, 116532001f49Smrg None 116632001f49Smrg }; 116732001f49Smrg XVisualInfo *visinfo; 116832001f49Smrg 116932001f49Smrg visinfo = glXChooseVisual(dpy, scrnum, attribs); 117032001f49Smrg if (visinfo) 117132001f49Smrg XFree(visinfo); 117232001f49Smrg} 117332001f49Smrg 117432001f49Smrg 117532001f49Smrg/* 117632001f49Smrg * Examine all visuals to find the so-called best one. 117732001f49Smrg * We prefer deepest RGBA buffer with depth, stencil and accum 117832001f49Smrg * that has no caveats. 117932001f49Smrg */ 118032001f49Smrgstatic int 118132001f49Smrgfind_best_visual(Display *dpy, int scrnum) 118232001f49Smrg{ 118332001f49Smrg XVisualInfo theTemplate; 118432001f49Smrg XVisualInfo *visuals; 118532001f49Smrg int numVisuals; 118632001f49Smrg long mask; 118732001f49Smrg int i; 118832001f49Smrg struct visual_attribs bestVis; 118932001f49Smrg 119032001f49Smrg /* get list of all visuals on this screen */ 119132001f49Smrg theTemplate.screen = scrnum; 119232001f49Smrg mask = VisualScreenMask; 119332001f49Smrg visuals = XGetVisualInfo(dpy, mask, &theTemplate, &numVisuals); 119432001f49Smrg 119532001f49Smrg /* init bestVis with first visual info */ 119632001f49Smrg get_visual_attribs(dpy, &visuals[0], &bestVis); 119732001f49Smrg 119832001f49Smrg /* try to find a "better" visual */ 119932001f49Smrg for (i = 1; i < numVisuals; i++) { 120032001f49Smrg struct visual_attribs vis; 120132001f49Smrg 120232001f49Smrg get_visual_attribs(dpy, &visuals[i], &vis); 120332001f49Smrg 120432001f49Smrg /* always skip visuals with caveats */ 120532001f49Smrg if (vis.visualCaveat != GLX_NONE_EXT) 120632001f49Smrg continue; 120732001f49Smrg 120832001f49Smrg /* see if this vis is better than bestVis */ 120932001f49Smrg if ((!bestVis.supportsGL && vis.supportsGL) || 121032001f49Smrg (bestVis.visualCaveat != GLX_NONE_EXT) || 121132001f49Smrg (!(bestVis.render_type & GLX_RGBA_BIT) && (vis.render_type & GLX_RGBA_BIT)) || 121232001f49Smrg (!bestVis.doubleBuffer && vis.doubleBuffer) || 121332001f49Smrg (bestVis.redSize < vis.redSize) || 121432001f49Smrg (bestVis.greenSize < vis.greenSize) || 121532001f49Smrg (bestVis.blueSize < vis.blueSize) || 121632001f49Smrg (bestVis.alphaSize < vis.alphaSize) || 121732001f49Smrg (bestVis.depthSize < vis.depthSize) || 121832001f49Smrg (bestVis.stencilSize < vis.stencilSize) || 121932001f49Smrg (bestVis.accumRedSize < vis.accumRedSize)) { 122032001f49Smrg /* found a better visual */ 122132001f49Smrg bestVis = vis; 122232001f49Smrg } 122332001f49Smrg } 122432001f49Smrg 122532001f49Smrg XFree(visuals); 122632001f49Smrg 122732001f49Smrg return bestVis.id; 122832001f49Smrg} 122932001f49Smrg 123032001f49Smrg 123132001f49Smrgint 123232001f49Smrgmain(int argc, char *argv[]) 123332001f49Smrg{ 123432001f49Smrg Display *dpy; 123532001f49Smrg int numScreens, scrnum; 12367ec3b29aSmrg struct options opts; 123732001f49Smrg Bool coreWorked; 123832001f49Smrg 12397ec3b29aSmrg parse_args(argc, argv, &opts); 124032001f49Smrg 12417ec3b29aSmrg dpy = XOpenDisplay(opts.displayName); 124232001f49Smrg if (!dpy) { 12437ec3b29aSmrg fprintf(stderr, "Error: unable to open display %s\n", 12447ec3b29aSmrg XDisplayName(opts.displayName)); 124532001f49Smrg return -1; 124632001f49Smrg } 124732001f49Smrg 12487ec3b29aSmrg if (opts.findBest) { 124932001f49Smrg int b; 125032001f49Smrg mesa_hack(dpy, 0); 125132001f49Smrg b = find_best_visual(dpy, 0); 125232001f49Smrg printf("%d\n", b); 125332001f49Smrg } 125432001f49Smrg else { 125532001f49Smrg numScreens = ScreenCount(dpy); 125632001f49Smrg print_display_info(dpy); 125732001f49Smrg for (scrnum = 0; scrnum < numScreens; scrnum++) { 125832001f49Smrg mesa_hack(dpy, scrnum); 12597ec3b29aSmrg coreWorked = print_screen_info(dpy, scrnum, &opts, 12607ec3b29aSmrg True, False, opts.limits, False); 12617ec3b29aSmrg print_screen_info(dpy, scrnum, &opts, False, False, 12627ec3b29aSmrg opts.limits, coreWorked); 12637ec3b29aSmrg print_screen_info(dpy, scrnum, &opts, False, True, False, True); 126432001f49Smrg 126532001f49Smrg printf("\n"); 12667ec3b29aSmrg 12677ec3b29aSmrg if (opts.mode != Brief) { 12687ec3b29aSmrg print_visual_info(dpy, scrnum, opts.mode); 126932001f49Smrg#ifdef GLX_VERSION_1_3 12707ec3b29aSmrg print_fbconfig_info(dpy, scrnum, opts.mode); 127132001f49Smrg#endif 12727ec3b29aSmrg } 12737ec3b29aSmrg 127432001f49Smrg if (scrnum + 1 < numScreens) 127532001f49Smrg printf("\n\n"); 127632001f49Smrg } 127732001f49Smrg } 127832001f49Smrg 127932001f49Smrg XCloseDisplay(dpy); 128032001f49Smrg 128132001f49Smrg return 0; 128232001f49Smrg} 1283