wglinfo.c revision 32001f49
132001f49Smrg/*
232001f49Smrg * Copyright (C) 2009  VMware, Inc.
332001f49Smrg * Copyright (C) 1999-2006  Brian Paul
432001f49Smrg * All Rights Reserved.
532001f49Smrg *
632001f49Smrg * Permission is hereby granted, free of charge, to any person obtaining a
732001f49Smrg * copy of this software and associated documentation files (the "Software"),
832001f49Smrg * to deal in the Software without restriction, including without limitation
932001f49Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1032001f49Smrg * and/or sell copies of the Software, and to permit persons to whom the
1132001f49Smrg * Software is furnished to do so, subject to the following conditions:
1232001f49Smrg *
1332001f49Smrg * The above copyright notice and this permission notice shall be included
1432001f49Smrg * in all copies or substantial portions of the Software.
1532001f49Smrg *
1632001f49Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1732001f49Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1832001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1932001f49Smrg * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2032001f49Smrg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2132001f49Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2232001f49Smrg */
2332001f49Smrg
2432001f49Smrg
2532001f49Smrg/*
2632001f49Smrg * This program is a work-alike of the GLX glxinfo program.
2732001f49Smrg * Command line options:
2832001f49Smrg *  -t                     print wide table
2932001f49Smrg *  -v                     print verbose information
3032001f49Smrg *  -b                     only print ID of "best" visual on screen 0
3132001f49Smrg *  -l                     print interesting OpenGL limits (added 5 Sep 2002)
3232001f49Smrg */
3332001f49Smrg
3432001f49Smrg#include <windows.h>
3532001f49Smrg
3632001f49Smrg#include <GL/glew.h>
3732001f49Smrg#include <GL/wglew.h>
3832001f49Smrg#include <assert.h>
3932001f49Smrg#include <stdio.h>
4032001f49Smrg#include <string.h>
4132001f49Smrg#include <stdlib.h>
4232001f49Smrg#include "glinfo_common.h"
4332001f49Smrg
4432001f49Smrg
4532001f49Smrgtypedef enum
4632001f49Smrg{
4732001f49Smrg   Normal,
4832001f49Smrg   Wide,
4932001f49Smrg   Verbose
5032001f49Smrg} InfoMode;
5132001f49Smrg
5232001f49Smrg
5332001f49Smrg
5432001f49Smrgstatic LRESULT CALLBACK
5532001f49SmrgWndProc(HWND hWnd,
5632001f49Smrg        UINT uMsg,
5732001f49Smrg        WPARAM wParam,
5832001f49Smrg        LPARAM lParam )
5932001f49Smrg{
6032001f49Smrg   switch (uMsg) {
6132001f49Smrg   case WM_DESTROY:
6232001f49Smrg      PostQuitMessage(0);
6332001f49Smrg      break;
6432001f49Smrg   default:
6532001f49Smrg      return DefWindowProc(hWnd, uMsg, wParam, lParam);
6632001f49Smrg   }
6732001f49Smrg
6832001f49Smrg   return 0;
6932001f49Smrg}
7032001f49Smrg
7132001f49Smrg
7232001f49Smrgstatic void
7332001f49Smrgprint_screen_info(HDC _hdc, GLboolean limits, GLboolean singleLine)
7432001f49Smrg{
7532001f49Smrg   WNDCLASS wc;
7632001f49Smrg   HWND win;
7732001f49Smrg   HGLRC ctx;
7832001f49Smrg   int visinfo;
7932001f49Smrg   HDC hdc;
8032001f49Smrg   PIXELFORMATDESCRIPTOR pfd;
8132001f49Smrg   int version;
8232001f49Smrg   const char *oglString = "OpenGL";
8332001f49Smrg
8432001f49Smrg   memset(&wc, 0, sizeof wc);
8532001f49Smrg   wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
8632001f49Smrg   wc.hCursor = LoadCursor(NULL, IDC_ARROW);
8732001f49Smrg   wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
8832001f49Smrg   wc.lpfnWndProc = WndProc;
8932001f49Smrg   wc.lpszClassName = "wglinfo";
9032001f49Smrg   wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
9132001f49Smrg   RegisterClass(&wc);
9232001f49Smrg
9332001f49Smrg   win = CreateWindowEx(0,
9432001f49Smrg                        wc.lpszClassName,
9532001f49Smrg                        "wglinfo",
9632001f49Smrg                        WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
9732001f49Smrg                        CW_USEDEFAULT,
9832001f49Smrg                        CW_USEDEFAULT,
9932001f49Smrg                        CW_USEDEFAULT,
10032001f49Smrg                        CW_USEDEFAULT,
10132001f49Smrg                        NULL,
10232001f49Smrg                        NULL,
10332001f49Smrg                        wc.hInstance,
10432001f49Smrg                        NULL);
10532001f49Smrg   if (!win) {
10632001f49Smrg      fprintf(stderr, "Couldn't create window\n");
10732001f49Smrg      return;
10832001f49Smrg   }
10932001f49Smrg
11032001f49Smrg   hdc = GetDC(win);
11132001f49Smrg   if (!hdc) {
11232001f49Smrg      fprintf(stderr, "Couldn't obtain HDC\n");
11332001f49Smrg      return;
11432001f49Smrg   }
11532001f49Smrg
11632001f49Smrg   pfd.cColorBits = 3;
11732001f49Smrg   pfd.cRedBits = 1;
11832001f49Smrg   pfd.cGreenBits = 1;
11932001f49Smrg   pfd.cBlueBits = 1;
12032001f49Smrg   pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
12132001f49Smrg   pfd.iLayerType = PFD_MAIN_PLANE;
12232001f49Smrg   pfd.iPixelType = PFD_TYPE_RGBA;
12332001f49Smrg   pfd.nSize = sizeof(pfd);
12432001f49Smrg   pfd.nVersion = 1;
12532001f49Smrg
12632001f49Smrg   visinfo = ChoosePixelFormat(hdc, &pfd);
12732001f49Smrg   if (!visinfo) {
12832001f49Smrg      pfd.dwFlags |= PFD_DOUBLEBUFFER;
12932001f49Smrg      visinfo = ChoosePixelFormat(hdc, &pfd);
13032001f49Smrg   }
13132001f49Smrg
13232001f49Smrg   if (!visinfo) {
13332001f49Smrg      fprintf(stderr, "Error: couldn't find RGB WGL visual\n");
13432001f49Smrg      return;
13532001f49Smrg   }
13632001f49Smrg
13732001f49Smrg   SetPixelFormat(hdc, visinfo, &pfd);
13832001f49Smrg   ctx = wglCreateContext(hdc);
13932001f49Smrg   if (!ctx) {
14032001f49Smrg      fprintf(stderr, "Error: wglCreateContext failed\n");
14132001f49Smrg      return;
14232001f49Smrg   }
14332001f49Smrg
14432001f49Smrg   if (wglMakeCurrent(hdc, ctx)) {
14532001f49Smrg#if defined(WGL_ARB_extensions_string)
14632001f49Smrg      PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_func =
14732001f49Smrg         (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB");
14832001f49Smrg#endif
14932001f49Smrg      const char *glVendor = (const char *) glGetString(GL_VENDOR);
15032001f49Smrg      const char *glRenderer = (const char *) glGetString(GL_RENDERER);
15132001f49Smrg      const char *glVersion = (const char *) glGetString(GL_VERSION);
15232001f49Smrg      const char *glExtensions = (const char *) glGetString(GL_EXTENSIONS);
15332001f49Smrg      struct ext_functions extfuncs;
15432001f49Smrg
15532001f49Smrg#if defined(WGL_ARB_extensions_string)
15632001f49Smrg      if (wglGetExtensionsStringARB_func) {
15732001f49Smrg         const char *wglExtensions = wglGetExtensionsStringARB_func(hdc);
15832001f49Smrg         if(wglExtensions) {
15932001f49Smrg            printf("WGL extensions:\n");
16032001f49Smrg            print_extension_list(wglExtensions, singleLine);
16132001f49Smrg         }
16232001f49Smrg      }
16332001f49Smrg#endif
16432001f49Smrg      printf("OpenGL vendor string: %s\n", glVendor);
16532001f49Smrg      printf("OpenGL renderer string: %s\n", glRenderer);
16632001f49Smrg      printf("OpenGL version string: %s\n", glVersion);
16732001f49Smrg#ifdef GL_VERSION_2_0
16832001f49Smrg      if (glVersion[0] >= '2' && glVersion[1] == '.') {
16932001f49Smrg         char *v = (char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
17032001f49Smrg         printf("OpenGL shading language version string: %s\n", v);
17132001f49Smrg      }
17232001f49Smrg#endif
17332001f49Smrg
17432001f49Smrg      extfuncs.GetProgramivARB = (PFNGLGETPROGRAMIVARBPROC)
17532001f49Smrg         wglGetProcAddress("glGetProgramivARB");
17632001f49Smrg      extfuncs.GetStringi = (PFNGLGETSTRINGIPROC)
17732001f49Smrg         wglGetProcAddress("glGetStringi");
17832001f49Smrg      extfuncs.GetConvolutionParameteriv = (GETCONVOLUTIONPARAMETERIVPROC)
17932001f49Smrg         wglGetProcAddress("glGetConvolutionParameteriv");
18032001f49Smrg
18132001f49Smrg      version = (glVersion[0] - '0') * 10 + (glVersion[2] - '0');
18232001f49Smrg
18332001f49Smrg      printf("OpenGL extensions:\n");
18432001f49Smrg      print_extension_list(glExtensions, singleLine);
18532001f49Smrg      if (limits) {
18632001f49Smrg         print_limits(glExtensions, oglString, version, &extfuncs);
18732001f49Smrg      }
18832001f49Smrg   }
18932001f49Smrg   else {
19032001f49Smrg      fprintf(stderr, "Error: wglMakeCurrent failed\n");
19132001f49Smrg   }
19232001f49Smrg
19332001f49Smrg   DestroyWindow(win);
19432001f49Smrg}
19532001f49Smrg
19632001f49Smrg
19732001f49Smrgstatic const char *
19832001f49Smrgvisual_render_type_name(BYTE iPixelType)
19932001f49Smrg{
20032001f49Smrg   switch (iPixelType) {
20132001f49Smrg      case PFD_TYPE_RGBA:
20232001f49Smrg         return "rgba";
20332001f49Smrg      case PFD_TYPE_COLORINDEX:
20432001f49Smrg         return "ci";
20532001f49Smrg      default:
20632001f49Smrg         return "";
20732001f49Smrg   }
20832001f49Smrg}
20932001f49Smrg
21032001f49Smrgstatic void
21132001f49Smrgprint_visual_attribs_verbose(int iPixelFormat, LPPIXELFORMATDESCRIPTOR ppfd)
21232001f49Smrg{
21332001f49Smrg   printf("Visual ID: %x  generic=%d  native=%d\n",
21432001f49Smrg          iPixelFormat,
21532001f49Smrg          ppfd->dwFlags & PFD_GENERIC_FORMAT ? 1 : 0,
21632001f49Smrg          ppfd->dwFlags & PFD_DRAW_TO_WINDOW ? 1 : 0);
21732001f49Smrg   printf("    bufferSize=%d level=%d renderType=%s doubleBuffer=%d stereo=%d\n",
21832001f49Smrg          0 /* ppfd->bufferSize */, 0 /* ppfd->level */,
21932001f49Smrg	  visual_render_type_name(ppfd->iPixelType),
22032001f49Smrg          ppfd->dwFlags & PFD_DOUBLEBUFFER ? 1 : 0,
22132001f49Smrg          ppfd->dwFlags & PFD_STEREO ? 1 : 0);
22232001f49Smrg   printf("    rgba: cRedBits=%d cGreenBits=%d cBlueBits=%d cAlphaBits=%d\n",
22332001f49Smrg          ppfd->cRedBits, ppfd->cGreenBits,
22432001f49Smrg          ppfd->cBlueBits, ppfd->cAlphaBits);
22532001f49Smrg   printf("    cAuxBuffers=%d cDepthBits=%d cStencilBits=%d\n",
22632001f49Smrg          ppfd->cAuxBuffers, ppfd->cDepthBits, ppfd->cStencilBits);
22732001f49Smrg   printf("    accum: cRedBits=%d cGreenBits=%d cBlueBits=%d cAlphaBits=%d\n",
22832001f49Smrg          ppfd->cAccumRedBits, ppfd->cAccumGreenBits,
22932001f49Smrg          ppfd->cAccumBlueBits, ppfd->cAccumAlphaBits);
23032001f49Smrg   printf("    multiSample=%d  multiSampleBuffers=%d\n",
23132001f49Smrg          0 /* ppfd->numSamples */, 0 /* ppfd->numMultisample */);
23232001f49Smrg}
23332001f49Smrg
23432001f49Smrg
23532001f49Smrgstatic void
23632001f49Smrgprint_visual_attribs_short_header(void)
23732001f49Smrg{
23832001f49Smrg printf("   visual   x  bf lv rg d st colorbuffer ax dp st accumbuffer  ms  cav\n");
23932001f49Smrg printf(" id gen win sp sz l  ci b ro  r  g  b  a bf th cl  r  g  b  a ns b eat\n");
24032001f49Smrg printf("-----------------------------------------------------------------------\n");
24132001f49Smrg}
24232001f49Smrg
24332001f49Smrg
24432001f49Smrgstatic void
24532001f49Smrgprint_visual_attribs_short(int iPixelFormat, LPPIXELFORMATDESCRIPTOR ppfd)
24632001f49Smrg{
24732001f49Smrg   char *caveat = "None";
24832001f49Smrg
24932001f49Smrg   printf("0x%02x %2d  %2d %2d %2d %2d %c%c %c  %c %2d %2d %2d %2d %2d %2d %2d",
25032001f49Smrg          iPixelFormat,
25132001f49Smrg          ppfd->dwFlags & PFD_GENERIC_FORMAT ? 1 : 0,
25232001f49Smrg          ppfd->dwFlags & PFD_DRAW_TO_WINDOW ? 1 : 0,
25332001f49Smrg          0,
25432001f49Smrg          0 /* ppfd->bufferSize */,
25532001f49Smrg          0 /* ppfd->level */,
25632001f49Smrg          ppfd->iPixelType == PFD_TYPE_RGBA ? 'r' : ' ',
25732001f49Smrg          ppfd->iPixelType == PFD_TYPE_COLORINDEX ? 'c' : ' ',
25832001f49Smrg          ppfd->dwFlags & PFD_DOUBLEBUFFER ? 'y' : '.',
25932001f49Smrg          ppfd->dwFlags & PFD_STEREO ? 'y' : '.',
26032001f49Smrg          ppfd->cRedBits, ppfd->cGreenBits,
26132001f49Smrg          ppfd->cBlueBits, ppfd->cAlphaBits,
26232001f49Smrg          ppfd->cAuxBuffers,
26332001f49Smrg          ppfd->cDepthBits,
26432001f49Smrg          ppfd->cStencilBits
26532001f49Smrg          );
26632001f49Smrg
26732001f49Smrg   printf(" %2d %2d %2d %2d %2d %1d %s\n",
26832001f49Smrg          ppfd->cAccumRedBits, ppfd->cAccumGreenBits,
26932001f49Smrg          ppfd->cAccumBlueBits, ppfd->cAccumAlphaBits,
27032001f49Smrg          0 /* ppfd->numSamples */, 0 /* ppfd->numMultisample */,
27132001f49Smrg          caveat
27232001f49Smrg          );
27332001f49Smrg}
27432001f49Smrg
27532001f49Smrg
27632001f49Smrgstatic void
27732001f49Smrgprint_visual_attribs_long_header(void)
27832001f49Smrg{
27932001f49Smrg printf("Vis  Vis   Visual Trans  buff lev render DB ste  r   g   b   a  aux dep ste  accum buffers  MS   MS\n");
28032001f49Smrg printf(" ID Depth   Type  parent size el   type     reo sz  sz  sz  sz  buf th  ncl  r   g   b   a  num bufs\n");
28132001f49Smrg printf("----------------------------------------------------------------------------------------------------\n");
28232001f49Smrg}
28332001f49Smrg
28432001f49Smrg
28532001f49Smrgstatic void
28632001f49Smrgprint_visual_attribs_long(int iPixelFormat, LPPIXELFORMATDESCRIPTOR ppfd)
28732001f49Smrg{
28832001f49Smrg   printf("0x%2x %2d %11d %2d     %2d %2d  %4s %3d %3d %3d %3d %3d %3d",
28932001f49Smrg          iPixelFormat,
29032001f49Smrg          ppfd->dwFlags & PFD_GENERIC_FORMAT ? 1 : 0,
29132001f49Smrg          ppfd->dwFlags & PFD_DRAW_TO_WINDOW ? 1 : 0,
29232001f49Smrg          0,
29332001f49Smrg          0 /* ppfd->bufferSize */,
29432001f49Smrg          0 /* ppfd->level */,
29532001f49Smrg          visual_render_type_name(ppfd->iPixelType),
29632001f49Smrg          ppfd->dwFlags & PFD_DOUBLEBUFFER ? 1 : 0,
29732001f49Smrg          ppfd->dwFlags & PFD_STEREO ? 1 : 0,
29832001f49Smrg          ppfd->cRedBits, ppfd->cGreenBits,
29932001f49Smrg          ppfd->cBlueBits, ppfd->cAlphaBits
30032001f49Smrg          );
30132001f49Smrg
30232001f49Smrg   printf(" %3d %4d %2d %3d %3d %3d %3d  %2d  %2d\n",
30332001f49Smrg          ppfd->cAuxBuffers,
30432001f49Smrg          ppfd->cDepthBits,
30532001f49Smrg          ppfd->cStencilBits,
30632001f49Smrg          ppfd->cAccumRedBits, ppfd->cAccumGreenBits,
30732001f49Smrg          ppfd->cAccumBlueBits, ppfd->cAccumAlphaBits,
30832001f49Smrg          0 /* ppfd->numSamples */, 0 /* ppfd->numMultisample */
30932001f49Smrg          );
31032001f49Smrg}
31132001f49Smrg
31232001f49Smrg
31332001f49Smrgstatic void
31432001f49Smrgprint_visual_info(HDC hdc, InfoMode mode)
31532001f49Smrg{
31632001f49Smrg   PIXELFORMATDESCRIPTOR pfd;
31732001f49Smrg   int numVisuals, numWglVisuals;
31832001f49Smrg   int i;
31932001f49Smrg
32032001f49Smrg   numVisuals = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
32132001f49Smrg   if (numVisuals == 0)
32232001f49Smrg      return;
32332001f49Smrg
32432001f49Smrg   numWglVisuals = 0;
32532001f49Smrg   for (i = 0; i < numVisuals; i++) {
32632001f49Smrg      if(!DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd))
32732001f49Smrg	 continue;
32832001f49Smrg
32932001f49Smrg      //if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
33032001f49Smrg      //   continue;
33132001f49Smrg
33232001f49Smrg      ++numWglVisuals;
33332001f49Smrg   }
33432001f49Smrg
33532001f49Smrg   printf("%d WGL Visuals\n", numWglVisuals);
33632001f49Smrg
33732001f49Smrg   if (mode == Normal)
33832001f49Smrg      print_visual_attribs_short_header();
33932001f49Smrg   else if (mode == Wide)
34032001f49Smrg      print_visual_attribs_long_header();
34132001f49Smrg
34232001f49Smrg   for (i = 0; i < numVisuals; i++) {
34332001f49Smrg      if(!DescribePixelFormat(hdc, i, sizeof(PIXELFORMATDESCRIPTOR), &pfd))
34432001f49Smrg	 continue;
34532001f49Smrg
34632001f49Smrg      //if(!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
34732001f49Smrg      //   continue;
34832001f49Smrg
34932001f49Smrg      if (mode == Verbose)
35032001f49Smrg	 print_visual_attribs_verbose(i, &pfd);
35132001f49Smrg      else if (mode == Normal)
35232001f49Smrg         print_visual_attribs_short(i, &pfd);
35332001f49Smrg      else if (mode == Wide)
35432001f49Smrg         print_visual_attribs_long(i, &pfd);
35532001f49Smrg   }
35632001f49Smrg   printf("\n");
35732001f49Smrg}
35832001f49Smrg
35932001f49Smrg
36032001f49Smrg/*
36132001f49Smrg * Examine all visuals to find the so-called best one.
36232001f49Smrg * We prefer deepest RGBA buffer with depth, stencil and accum
36332001f49Smrg * that has no caveats.
36432001f49Smrg */
36532001f49Smrgstatic int
36632001f49Smrgfind_best_visual(HDC hdc)
36732001f49Smrg{
36832001f49Smrg#if 0
36932001f49Smrg   XVisualInfo theTemplate;
37032001f49Smrg   XVisualInfo *visuals;
37132001f49Smrg   int numVisuals;
37232001f49Smrg   long mask;
37332001f49Smrg   int i;
37432001f49Smrg   struct visual_attribs bestVis;
37532001f49Smrg
37632001f49Smrg   /* get list of all visuals on this screen */
37732001f49Smrg   theTemplate.screen = scrnum;
37832001f49Smrg   mask = VisualScreenMask;
37932001f49Smrg   visuals = XGetVisualInfo(hdc, mask, &theTemplate, &numVisuals);
38032001f49Smrg
38132001f49Smrg   /* init bestVis with first visual info */
38232001f49Smrg   get_visual_attribs(hdc, &visuals[0], &bestVis);
38332001f49Smrg
38432001f49Smrg   /* try to find a "better" visual */
38532001f49Smrg   for (i = 1; i < numVisuals; i++) {
38632001f49Smrg      struct visual_attribs vis;
38732001f49Smrg
38832001f49Smrg      get_visual_attribs(hdc, &visuals[i], &vis);
38932001f49Smrg
39032001f49Smrg      /* always skip visuals with caveats */
39132001f49Smrg      if (vis.visualCaveat != GLX_NONE_EXT)
39232001f49Smrg         continue;
39332001f49Smrg
39432001f49Smrg      /* see if this vis is better than bestVis */
39532001f49Smrg      if ((!bestVis.supportsGL && vis.supportsGL) ||
39632001f49Smrg          (bestVis.visualCaveat != GLX_NONE_EXT) ||
39732001f49Smrg          (bestVis.iPixelType != vis.iPixelType) ||
39832001f49Smrg          (!bestVis.doubleBuffer && vis.doubleBuffer) ||
39932001f49Smrg          (bestVis.cRedBits < vis.cRedBits) ||
40032001f49Smrg          (bestVis.cGreenBits < vis.cGreenBits) ||
40132001f49Smrg          (bestVis.cBlueBits < vis.cBlueBits) ||
40232001f49Smrg          (bestVis.cAlphaBits < vis.cAlphaBits) ||
40332001f49Smrg          (bestVis.cDepthBits < vis.cDepthBits) ||
40432001f49Smrg          (bestVis.cStencilBits < vis.cStencilBits) ||
40532001f49Smrg          (bestVis.cAccumRedBits < vis.cAccumRedBits)) {
40632001f49Smrg         /* found a better visual */
40732001f49Smrg         bestVis = vis;
40832001f49Smrg      }
40932001f49Smrg   }
41032001f49Smrg
41132001f49Smrg   return bestVis.id;
41232001f49Smrg#else
41332001f49Smrg   return 0;
41432001f49Smrg#endif
41532001f49Smrg}
41632001f49Smrg
41732001f49Smrg
41832001f49Smrgstatic void
41932001f49Smrgusage(void)
42032001f49Smrg{
42132001f49Smrg   printf("Usage: glxinfo [-v] [-t] [-h] [-i] [-b] [-display <dname>]\n");
42232001f49Smrg   printf("\t-v: Print visuals info in verbose form.\n");
42332001f49Smrg   printf("\t-t: Print verbose table.\n");
42432001f49Smrg   printf("\t-h: This information.\n");
42532001f49Smrg   printf("\t-b: Find the 'best' visual and print its number.\n");
42632001f49Smrg   printf("\t-l: Print interesting OpenGL limits.\n");
42732001f49Smrg   printf("\t-s: Print a single extension per line.\n");
42832001f49Smrg}
42932001f49Smrg
43032001f49Smrg
43132001f49Smrgint
43232001f49Smrgmain(int argc, char *argv[])
43332001f49Smrg{
43432001f49Smrg   HDC hdc;
43532001f49Smrg   InfoMode mode = Normal;
43632001f49Smrg   GLboolean findBest = GL_FALSE;
43732001f49Smrg   GLboolean limits = GL_FALSE;
43832001f49Smrg   GLboolean singleLine = GL_FALSE;
43932001f49Smrg   int i;
44032001f49Smrg
44132001f49Smrg   for (i = 1; i < argc; i++) {
44232001f49Smrg      if (strcmp(argv[i], "-t") == 0) {
44332001f49Smrg         mode = Wide;
44432001f49Smrg      }
44532001f49Smrg      else if (strcmp(argv[i], "-v") == 0) {
44632001f49Smrg         mode = Verbose;
44732001f49Smrg      }
44832001f49Smrg      else if (strcmp(argv[i], "-b") == 0) {
44932001f49Smrg         findBest = GL_TRUE;
45032001f49Smrg      }
45132001f49Smrg      else if (strcmp(argv[i], "-l") == 0) {
45232001f49Smrg         limits = GL_TRUE;
45332001f49Smrg      }
45432001f49Smrg      else if (strcmp(argv[i], "-h") == 0) {
45532001f49Smrg         usage();
45632001f49Smrg         return 0;
45732001f49Smrg      }
45832001f49Smrg      else if(strcmp(argv[i], "-s") == 0) {
45932001f49Smrg         singleLine = GL_TRUE;
46032001f49Smrg      }
46132001f49Smrg      else {
46232001f49Smrg         printf("Unknown option `%s'\n", argv[i]);
46332001f49Smrg         usage();
46432001f49Smrg         return 0;
46532001f49Smrg      }
46632001f49Smrg   }
46732001f49Smrg
46832001f49Smrg   hdc = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
46932001f49Smrg
47032001f49Smrg   if (findBest) {
47132001f49Smrg      int b;
47232001f49Smrg      b = find_best_visual(hdc);
47332001f49Smrg      printf("%d\n", b);
47432001f49Smrg   }
47532001f49Smrg   else {
47632001f49Smrg      print_screen_info(hdc, limits, singleLine);
47732001f49Smrg      printf("\n");
47832001f49Smrg      print_visual_info(hdc, mode);
47932001f49Smrg   }
48032001f49Smrg
48132001f49Smrg   return 0;
48232001f49Smrg}
483