/**************************************************************************** ** ** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. ** ** This file is part of an example program for Qt. This example ** program may be used, distributed and modified without limitation. ** *****************************************************************************/ #define QT_CLEAN_NAMESPACE // avoid clashes with Xmd.h #include #include #include "glinfo.h" #include #include #include #ifndef GLX_NONE_EXT #define GLX_NONE_EXT 0x8000 #endif typedef struct visualAttribs { /* X visual attribs */ int id; int c_class; int depth; int redMask, greenMask, blueMask; int colormapSize; int bitsPerRGB; /* GL visual attribs */ int supportsGL; int transparent; int bufferSize; int level; int rgba; int doubleBuffer; int stereo; int auxBuffers; int redSize, greenSize, blueSize, alphaSize; int depthSize; int stencilSize; int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize; int numSamples, numMultisample; int visualCaveat; } VisualAttribs; static void screenInfo( Display *dpy, int scrnum, QString &infotext ) { const char *serverVendor = glXQueryServerString( dpy, scrnum, GLX_VENDOR ); const char *serverVersion = glXQueryServerString( dpy, scrnum, GLX_VERSION ); const char *serverExtensions = glXQueryServerString( dpy, scrnum, GLX_EXTENSIONS ); const char *clientVendor = glXGetClientString( dpy, GLX_VENDOR ); const char *clientVersion = glXGetClientString( dpy, GLX_VERSION ); const char *clientExtensions = glXGetClientString( dpy, GLX_EXTENSIONS ); const char *glxExtensions = glXQueryExtensionsString( dpy, scrnum ); const char *glVendor = (const char *) glGetString( GL_VENDOR ); const char *glRenderer = (const char *) glGetString( GL_RENDERER ); const char *glVersion = (const char *) glGetString( GL_VERSION ); const char *glExtensions = (const char *) glGetString( GL_EXTENSIONS ); const char *gluVersion = (const char *) gluGetString( (GLenum) GLU_VERSION ); const char *gluExtensions = (const char *) gluGetString( (GLenum) GLU_EXTENSIONS ); infotext.sprintf( "%sServer GLX vendor string: %s\n", infotext.ascii(), serverVendor ); infotext.sprintf( "%sServer GLX version string: %s\n", infotext.ascii(), serverVersion ); infotext.sprintf( "%sServer GLX extensions:\n", infotext.ascii() ); infotext += QString( serverExtensions ).replace( ' ', '\n' ) + "\n\n"; infotext.sprintf( "%sClient GLX vendor string: %s\n", infotext.ascii(), clientVendor ); infotext.sprintf( "%sClient GLX version string: %s\n", infotext.ascii(), clientVersion ); infotext.sprintf( "%sClient GLX extensions:\n", infotext.ascii() ); infotext += QString( clientExtensions ).replace( ' ', '\n' ) + "\n\n"; infotext.sprintf( "%sGLX extensions:\n", infotext.ascii() ); infotext += QString( glxExtensions ).replace( ' ', '\n' ) + "\n\n"; infotext.sprintf( "%sOpenGL vendor string: %s\n", infotext.ascii(), glVendor ); infotext.sprintf( "%sOpenGL renderer string: %s\n", infotext.ascii(), glRenderer ); infotext.sprintf( "%sOpenGL version string: %s\n", infotext.ascii(), glVersion ); infotext.sprintf( "%sOpenGL extensions:\n", infotext.ascii() ); infotext += QString( glExtensions ).replace( ' ', '\n' ) + "\n\n"; infotext.sprintf( "%sGLU version: %s\n", infotext.ascii(), gluVersion ); infotext.sprintf( "%sGLU extensions:\n", infotext.ascii() ); infotext += QString( gluExtensions ).replace( ' ', '\n' ) + "\n\n"; } static const char * visualClassName( int cls ) { switch ( cls ) { case StaticColor: return "StaticColor"; case PseudoColor: return "PseudoColor"; case StaticGray: return "StaticGray"; case GrayScale: return "GrayScale"; case TrueColor: return "TrueColor"; case DirectColor: return "DirectColor"; default: return ""; } } static const char * caveatString( int caveat ) { switch ( caveat ) { #if defined(GLX_EXT_visual_rating) case GLX_NONE_EXT: return "None"; case GLX_SLOW_VISUAL_EXT: return "Slow"; case GLX_NON_CONFORMANT_VISUAL_EXT: return "Nonconformant"; #endif default: return ""; } } static void visualAttribs( Display * dpy, XVisualInfo * vi, VisualAttribs * attribs ) { memset( attribs, 0, sizeof( VisualAttribs ) ); attribs->id = vi->visualid; attribs->c_class = vi->c_class; attribs->depth = vi->depth; attribs->redMask = vi->red_mask; attribs->greenMask = vi->green_mask; attribs->blueMask = vi->blue_mask; attribs->colormapSize = vi->colormap_size; attribs->bitsPerRGB = vi->bits_per_rgb; if ( glXGetConfig( dpy, vi, GLX_USE_GL, &attribs->supportsGL ) != 0 ) return; attribs->accumAlphaSize = 0; glXGetConfig( dpy, vi, GLX_BUFFER_SIZE, &attribs->bufferSize ); glXGetConfig( dpy, vi, GLX_LEVEL, &attribs->level ); glXGetConfig( dpy, vi, GLX_RGBA, &attribs->rgba ); glXGetConfig( dpy, vi, GLX_DOUBLEBUFFER, &attribs->doubleBuffer ); glXGetConfig( dpy, vi, GLX_STEREO, &attribs->stereo ); glXGetConfig( dpy, vi, GLX_AUX_BUFFERS, &attribs->auxBuffers ); glXGetConfig( dpy, vi, GLX_RED_SIZE, &attribs->redSize ); glXGetConfig( dpy, vi, GLX_GREEN_SIZE, &attribs->greenSize ); glXGetConfig( dpy, vi, GLX_BLUE_SIZE, &attribs->blueSize ); glXGetConfig( dpy, vi, GLX_ALPHA_SIZE, &attribs->alphaSize ); glXGetConfig( dpy, vi, GLX_DEPTH_SIZE, &attribs->depthSize ); glXGetConfig( dpy, vi, GLX_STENCIL_SIZE, &attribs->stencilSize ); glXGetConfig( dpy, vi, GLX_ACCUM_RED_SIZE, &attribs->accumRedSize ); glXGetConfig( dpy, vi, GLX_ACCUM_GREEN_SIZE, &attribs->accumGreenSize ); glXGetConfig( dpy, vi, GLX_ACCUM_BLUE_SIZE, &attribs->accumBlueSize ); glXGetConfig( dpy, vi, GLX_ACCUM_ALPHA_SIZE, &attribs->accumAlphaSize ); attribs->transparent = 0; // transparent pixel missing attribs->numSamples = 0; // multisample tests missing attribs->numMultisample = 0; #if defined(GLX_EXT_visual_rating) const char *ext = glXQueryExtensionsString( dpy, vi->screen ); if ( ext && strstr( ext, "GLX_EXT_visual_rating" ) ) glXGetConfig(dpy, vi, GLX_VISUAL_CAVEAT_EXT, &attribs->visualCaveat); else attribs->visualCaveat = GLX_NONE_EXT; #else attribs->visualCaveat = 0; #endif } static void visualInfo( Display *dpy, int scrnum, QString &configs ) { QString str; XVisualInfo *visuals, temp; int numVisuals; long mask; int i; /* get list of all visuals on this screen */ temp.screen = scrnum; mask = VisualScreenMask; visuals = XGetVisualInfo( dpy, mask, &temp, &numVisuals ); VisualAttribs attribs; configs.append( "Vis Vis Visual Trans buff lev render DB ste r g b a aux dep ste accum buffers MS MS\n" " ID Depth Type parent size el type reo sz sz sz sz buf th ncl r g b a num bufs Caveat\n" "-----------------------------------------------------------------------------------------------------------\n" ); for ( i = 0; i < numVisuals; i++ ) { visualAttribs( dpy, &visuals[i], &attribs ); str.sprintf( "0x%2x %2d %-12s %d %2d %d %-4s %d %d %d %d %d %d" " %d %2d %d %2d %2d %2d %2d %d %d %s\n", attribs.id, attribs.depth, visualClassName( attribs.c_class ), attribs.transparent, attribs.bufferSize, attribs.level, attribs.rgba ? "rgba" : "ci", attribs.doubleBuffer, attribs.stereo, attribs.redSize, attribs.greenSize, attribs.blueSize, attribs.alphaSize, attribs.auxBuffers, attribs.depthSize, attribs.stencilSize, attribs.accumRedSize, attribs.accumGreenSize, attribs.accumBlueSize, attribs.accumAlphaSize, attribs.numSamples, attribs.numMultisample, caveatString( attribs.visualCaveat ) ); configs.append( str ); } XFree( visuals ); } GLInfo::GLInfo() { QGLWidget gl((QWidget *) 0); gl.makeCurrent(); Display *dpy; char *displayName = 0; int numScreens, scrNum; dpy = gl.x11Display(); if ( !dpy ) { tqWarning( "Error: unable to open display %s\n", displayName ); } numScreens = ScreenCount( dpy ); infotext.sprintf( "Display name: %s\nDirect rendering: %s\n", DisplayString( dpy ), gl.format().directRendering() ? "Yes" : "No" ); for ( scrNum = 0; scrNum < numScreens; scrNum++ ) { screenInfo( dpy, scrNum, infotext ); visualInfo( dpy, scrNum, infotext ); if ( scrNum + 1 < numScreens ) infotext.append( "\n\n" ); } } QString GLInfo::info() { return infotext; }