diff options
| -rw-r--r-- | progs/xdemos/glxdpyinfo.c | 1073 | 
1 files changed, 1073 insertions, 0 deletions
| diff --git a/progs/xdemos/glxdpyinfo.c b/progs/xdemos/glxdpyinfo.c new file mode 100644 index 0000000000..9f834fd1d1 --- /dev/null +++ b/progs/xdemos/glxdpyinfo.c @@ -0,0 +1,1073 @@ +/* + * $TOG: xdpyinfo.c /main/35 1998/02/09 13:57:05 kaleb $ + *  + * xdpyinfo - print information about X display connecton + * + *  +Copyright 1988, 1998  The Open Group + +All Rights Reserved. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + * Author:  Jim Fulton, MIT X Consortium + * GLX and Overlay support added by Jamie Zawinski <jwz@jwz.org>, 11-Nov-99 + * + *      To compile: + *         cc -DHAVE_GLX glxdpyinfo.c -o glxdpyinfo -lGL -lX11 -lXext -lm + * + *      Other defines to consider: + *         -DHAVE_XIE -DHAVE_XTEST -DHAVE_XRECORD + */ + +#define HAVE_GLX  /* added by Brian Paul */ + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xproto.h> /* for CARD32 */ +#include <X11/extensions/multibuf.h> +#ifdef HAVE_XIE +#include <X11/extensions/XIElib.h> +#endif /* HAVE_XIE */ +#ifdef HAVE_XTEST +#include <X11/extensions/XTest.h> +#endif /* HAVE_XTEST */ +#include <X11/extensions/sync.h> +#include <X11/extensions/Xdbe.h> +#ifdef HAVE_XRECORD +#include <X11/extensions/record.h> +#endif /* HAVE_XRECORD */ +#ifdef MITSHM +#include <X11/extensions/XShm.h> +#endif +#include <X11/Xos.h> +#include <stdio.h> + +#ifdef HAVE_GLX +# include <GL/gl.h> +# include <GL/glx.h> +#endif /* HAVE_GLX */ + +#define HAVE_OVERLAY /* jwz: no compile-time deps, so do this all the time */ + +char *ProgramName; +Bool queryExtensions = False; + +static int StrCmp(a, b) +    char **a, **b; +{ +    return strcmp(*a, *b); +} + + +#ifdef HAVE_GLX  /* Added by jwz, 11-Nov-99 */ + +static void +print_glx_versions (dpy) +    Display *dpy; +{ +  /* Note: with Mesa 3.0, this lies: it prints the info from the +     client's GL library, rather than the info from the GLX server. + +     Note also that we can't protect these calls by only doing +     them when the GLX extension is present, because with Mesa, +     the server doesn't have that extension (but the GL library +     works anyway.) +   */ +      int scr = DefaultScreen (dpy); +      const char *vend, *vers; +      vend = glXQueryServerString (dpy, scr, GLX_VENDOR); +      if (!vend) return; +      vers = glXQueryServerString (dpy, scr, GLX_VERSION); +      printf ("GLX vendor:    %s (%s)\n", +              vend, (vers ? vers : "unknown version")); +} + +static void +print_glx_visual_info (dpy, vip) +    Display *dpy; +    XVisualInfo *vip; +{ +  int status, value = False; + +  status = glXGetConfig (dpy, vip, GLX_USE_GL, &value); +  if (status == GLX_NO_EXTENSION) +    /* dpy does not support the GLX extension. */ +    return; + +  if (status == GLX_BAD_VISUAL || value == False) +    { +      printf ("    GLX supported:     no\n"); +      return; +    } +  else +    { +      printf ("    GLX supported:     yes\n"); +    } +     +  if (!glXGetConfig (dpy, vip, GLX_LEVEL, &value) && +      value != 0) +    printf ("    GLX level:         %d\n", value); + +  if (!glXGetConfig (dpy, vip, GLX_RGBA, &value) && value) +    { +      int r=0, g=0, b=0, a=0; +      glXGetConfig (dpy, vip, GLX_RED_SIZE,   &r); +      glXGetConfig (dpy, vip, GLX_GREEN_SIZE, &g); +      glXGetConfig (dpy, vip, GLX_BLUE_SIZE,  &b); +      glXGetConfig (dpy, vip, GLX_ALPHA_SIZE, &a); +      printf ("    GLX type:          RGBA (%2d, %2d, %2d, %2d)\n", +              r, g, b, a); + +      r=0, g=0, b=0, a=0; +      glXGetConfig (dpy, vip, GLX_ACCUM_RED_SIZE,   &r); +      glXGetConfig (dpy, vip, GLX_ACCUM_GREEN_SIZE, &g); +      glXGetConfig (dpy, vip, GLX_ACCUM_BLUE_SIZE,  &b); +      glXGetConfig (dpy, vip, GLX_ACCUM_ALPHA_SIZE, &a); +      printf ("    GLX accum:         RGBA (%2d, %2d, %2d, %2d)\n", +              r, g, b, a); +    } +  else +    { +      value = 0; +      glXGetConfig (dpy, vip, GLX_BUFFER_SIZE, &value); +      printf ("    GLX type:          indexed (%d)\n", value); +    } + +# if 0  /* redundant */ +  if (!glXGetConfig (dpy, vip, GLX_X_VISUAL_TYPE_EXT, &value)) +      printf ("    GLX class:         %s\n", +              (value == GLX_TRUE_COLOR_EXT ? "TrueColor" : +               value == GLX_DIRECT_COLOR_EXT ? "DirectColor" : +               value == GLX_PSEUDO_COLOR_EXT ? "PseudoColor" : +               value == GLX_STATIC_COLOR_EXT ? "StaticColor" : +               value == GLX_GRAY_SCALE_EXT ? "Grayscale" : +               value == GLX_STATIC_GRAY_EXT ? "StaticGray" : "???")); +# endif + +# ifdef GLX_VISUAL_CAVEAT_EXT +  if (!glXGetConfig (dpy, vip, GLX_VISUAL_CAVEAT_EXT, &value) && +      value != GLX_NONE_EXT) +    printf ("    GLX rating:        %s\n", +            (value == GLX_NONE_EXT ? "none" : +             value == GLX_SLOW_VISUAL_EXT ? "slow" : +#   ifdef GLX_NON_CONFORMANT_EXT +             value == GLX_NON_CONFORMANT_EXT ? "non-conformant" : +#   endif +             "???")); +# endif + +  if (!glXGetConfig (dpy, vip, GLX_DOUBLEBUFFER, &value)) +    printf ("    GLX double-buffer: %s\n", (value ? "yes" : "no")); + +  if (!glXGetConfig (dpy, vip, GLX_STEREO, &value) && +      value) +    printf ("    GLX stereo:        %s\n", (value ? "yes" : "no")); + +  if (!glXGetConfig (dpy, vip, GLX_AUX_BUFFERS, &value) && +      value != 0) +    printf ("    GLX aux buffers:   %d\n", value); + +  if (!glXGetConfig (dpy, vip, GLX_DEPTH_SIZE, &value)) +    printf ("    GLX depth size:    %d\n", value); + +  if (!glXGetConfig (dpy, vip, GLX_STENCIL_SIZE, &value) && +      value != 0) +    printf ("    GLX stencil size:  %d\n", value); + +# ifdef GLX_SAMPLE_BUFFERS_SGIS +  if (!glXGetConfig (dpy, vip, GLX_SAMPLE_BUFFERS_SGIS, &value) && +      value != 0) +    { +      int bufs = value; +      if (!glXGetConfig (dpy, vip, GLX_SAMPLES_SGIS, &value)) +        printf ("    GLX multisamplers: %d (%d)\n", bufs, value); +    } +# endif + +  if (!glXGetConfig (dpy, vip, GLX_TRANSPARENT_TYPE_EXT, &value) && +      value != GLX_NONE_EXT) +    { +      if (value == GLX_NONE_EXT) +        printf ("    GLX transparency:  none\n"); +      else if (value == GLX_TRANSPARENT_INDEX_EXT) +        { +          if (!glXGetConfig (dpy, vip, GLX_TRANSPARENT_INDEX_VALUE_EXT,&value)) +            printf ("    GLX transparency:  indexed (%d)\n", value); +        } +      else if (value == GLX_TRANSPARENT_RGB_EXT) +        { +          int r=0, g=0, b=0, a=0; +          glXGetConfig (dpy, vip, GLX_TRANSPARENT_RED_VALUE_EXT,   &r); +          glXGetConfig (dpy, vip, GLX_TRANSPARENT_GREEN_VALUE_EXT, &g); +          glXGetConfig (dpy, vip, GLX_TRANSPARENT_BLUE_VALUE_EXT,  &b); +          glXGetConfig (dpy, vip, GLX_TRANSPARENT_ALPHA_VALUE_EXT, &a); +          printf ("    GLX transparency:  RGBA (%2d, %2d, %2d, %2d)\n", +                  r, g, b, a); +        } +    } +} +#endif /* HAVE_GLX */ + + +#ifdef HAVE_OVERLAY  /* Added by jwz, 11-Nov-99 */ + + /* If the server's root window contains a SERVER_OVERLAY_VISUALS property, +    then that identifies the visuals which correspond to the video hardware's +    overlay planes.  Windows created in these kinds of visuals may have +    transparent pixels that let other layers shine through. + +    This might not be an X Consortium standard, but it turns out that +    SGI, HP, DEC, and IBM all use this same mechanism.  So that's close +    enough for me. + +    Documentation on the SERVER_OVERLAY_VISUALS property can be found at: +    http://www.hp.com/xwindow/sharedInfo/Whitepapers/Visuals/server_overlay_visuals.html +  */ + +struct overlay +{ +  CARD32 visual_id; +  CARD32 transparency; /* 0: none; 1: pixel; 2: mask */ +  CARD32 value;                /* the transparent pixel */ +  CARD32 layer;                /* -1: underlay; 0: normal; 1: popup; 2: overlay */ +}; + +struct overlay_list +{ +  int count; +  struct overlay *list; +}; + +static struct overlay_list *overlays = 0; + +static void +find_overlay_info (dpy) +  Display *dpy; +{ +  int screen; +  Atom OVERLAY = XInternAtom (dpy, "SERVER_OVERLAY_VISUALS", False); + +  overlays = (struct overlay_list *) calloc (sizeof (struct overlay_list), +                                             ScreenCount (dpy)); + +  for (screen = 0; screen < ScreenCount (dpy); screen++) +    { +      Window window = RootWindow (dpy, screen); +      Atom actual_type; +      int actual_format; +      unsigned long nitems, bytes_after; +      struct overlay *data = 0; +      int result = XGetWindowProperty (dpy, window, OVERLAY, +                                       0, (65536 / sizeof (long)), False,  +                                       OVERLAY, &actual_type, &actual_format, +                                       &nitems, &bytes_after, +                                       (unsigned char **) &data); +      if (result == Success && +          actual_type == OVERLAY && +          actual_format == 32 && +          nitems > 0) +        { +          overlays[screen].count = (nitems / +                                    (sizeof(struct overlay) / sizeof(CARD32))); +          overlays[screen].list = data; +        } +      else if (data) +        XFree((char *) data); +    } +} + +static void +print_overlay_visual_info (vip) +    XVisualInfo *vip; +{ +  int i; +  int vis = vip->visualid; +  int scr = vip->screen; +  if (!overlays) return; +  for (i = 0; i < overlays[scr].count; i++) +    if (vis == overlays[scr].list[i].visual_id) +      { +        struct overlay *ov = &overlays[scr].list[i]; +        printf ("    Overlay info:      layer %ld (%s), ", +                (long) ov->layer, +                (ov->layer == -1 ? "underlay" : +                 ov->layer ==  0 ? "normal" : +                 ov->layer ==  1 ? "popup" : +                 ov->layer ==  2 ? "overlay" : "???")); +        if (ov->transparency == 1) +          printf ("transparent pixel %lu\n", (unsigned long) ov->value); +        else if (ov->transparency == 2) +          printf ("transparent mask 0x%x\n", (unsigned long) ov->value); +        else +          printf ("opaque\n"); +      } +} +#endif /* HAVE_OVERLAY */ + + +void +print_extension_info (dpy) +    Display *dpy; +{ +    int n = 0; +    char **extlist = XListExtensions (dpy, &n); + +    printf ("number of extensions:    %d\n", n); + +    if (extlist) { +	register int i; +	int opcode, event, error; + +	qsort(extlist, n, sizeof(char *), StrCmp); +	for (i = 0; i < n; i++) { +	    if (!queryExtensions) { +		printf ("    %s\n", extlist[i]); +		continue; +	    } +	    XQueryExtension(dpy, extlist[i], &opcode, &event, &error); +	    printf ("    %s  (opcode: %d", extlist[i], opcode); +	    if (event) +		printf (", base event: %d", event); +	    if (error) +		printf (", base error: %d", error); +	    printf(")\n"); +	} +	/* do not free, Xlib can depend on contents being unaltered */ +	/* XFreeExtensionList (extlist); */ +    } +} + +void +print_display_info (dpy) +    Display *dpy; +{ +    char dummybuf[40]; +    char *cp; +    int minkeycode, maxkeycode; +    int i, n; +    long req_size; +    XPixmapFormatValues *pmf; +    Window focuswin; +    int focusrevert; + +    printf ("name of display:    %s\n", DisplayString (dpy)); +    printf ("version number:    %d.%d\n", +	    ProtocolVersion (dpy), ProtocolRevision (dpy)); +    printf ("vendor string:    %s\n", ServerVendor (dpy)); +    printf ("vendor release number:    %d\n", VendorRelease (dpy)); + +#ifdef HAVE_GLX +    print_glx_versions (dpy); +#endif /* HAVE_GLX */ + +    req_size = XExtendedMaxRequestSize (dpy); +    if (!req_size) req_size = XMaxRequestSize (dpy); +    printf ("maximum request size:  %ld bytes\n", req_size * 4); +    printf ("motion buffer size:  %d\n", XDisplayMotionBufferSize (dpy)); + +    switch (BitmapBitOrder (dpy)) { +      case LSBFirst:    cp = "LSBFirst"; break; +      case MSBFirst:    cp = "MSBFirst"; break; +      default:     +	sprintf (dummybuf, "unknown order %d", BitmapBitOrder (dpy)); +	cp = dummybuf; +	break; +    } +    printf ("bitmap unit, bit order, padding:    %d, %s, %d\n", +	    BitmapUnit (dpy), cp, BitmapPad (dpy)); + +    switch (ImageByteOrder (dpy)) { +      case LSBFirst:    cp = "LSBFirst"; break; +      case MSBFirst:    cp = "MSBFirst"; break; +      default:     +	sprintf (dummybuf, "unknown order %d", ImageByteOrder (dpy)); +	cp = dummybuf; +	break; +    } +    printf ("image byte order:    %s\n", cp); + +    pmf = XListPixmapFormats (dpy, &n); +    printf ("number of supported pixmap formats:    %d\n", n); +    if (pmf) { +	printf ("supported pixmap formats:\n"); +	for (i = 0; i < n; i++) { +	    printf ("    depth %d, bits_per_pixel %d, scanline_pad %d\n", +		    pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad); +	} +	XFree ((char *) pmf); +    } + + +    /* +     * when we get interfaces to the PixmapFormat stuff, insert code here +     */ + +    XDisplayKeycodes (dpy, &minkeycode, &maxkeycode); +    printf ("keycode range:    minimum %d, maximum %d\n", +	    minkeycode, maxkeycode); + +    XGetInputFocus (dpy, &focuswin, &focusrevert); +    printf ("focus:  "); +    switch (focuswin) { +      case PointerRoot: +	printf ("PointerRoot\n"); +	break; +      case None: +	printf ("None\n"); +	break; +      default: +	printf("window 0x%lx, revert to ", focuswin); +	switch (focusrevert) { +	  case RevertToParent: +	    printf ("Parent\n"); +	    break; +	  case RevertToNone: +	    printf ("None\n"); +	    break; +	  case RevertToPointerRoot: +	    printf ("PointerRoot\n"); +	    break; +	  default:			/* should not happen */ +	    printf ("%d\n", focusrevert); +	    break; +	} +	break; +    } + +    print_extension_info (dpy); + +    printf ("default screen number:    %d\n", DefaultScreen (dpy)); +    printf ("number of screens:    %d\n", ScreenCount (dpy)); +} + +void +print_visual_info (vip) +    XVisualInfo *vip; +{ +    char errorbuf[40];			/* for sprintfing into */ +    char *class = NULL;			/* for printing */ + +    switch (vip->class) { +      case StaticGray:    class = "StaticGray"; break; +      case GrayScale:    class = "GrayScale"; break; +      case StaticColor:    class = "StaticColor"; break; +      case PseudoColor:    class = "PseudoColor"; break; +      case TrueColor:    class = "TrueColor"; break; +      case DirectColor:    class = "DirectColor"; break; +      default:     +	sprintf (errorbuf, "unknown class %d", vip->class); +	class = errorbuf; +	break; +    } + +    printf ("  visual:\n"); +    printf ("    visual id:    0x%lx\n", vip->visualid); +    printf ("    class:    %s\n", class); +    printf ("    depth:    %d plane%s\n", vip->depth,  +	    vip->depth == 1 ? "" : "s"); +    if (vip->class == TrueColor || vip->class == DirectColor) +	printf ("    available colormap entries:    %d per subfield\n", +		vip->colormap_size); +    else +	printf ("    available colormap entries:    %d\n", +		vip->colormap_size); +    printf ("    red, green, blue masks:    0x%lx, 0x%lx, 0x%lx\n", +	    vip->red_mask, vip->green_mask, vip->blue_mask); +    printf ("    significant bits in color specification:    %d bits\n", +	    vip->bits_per_rgb); +} + +void +print_screen_info (dpy, scr) +    Display *dpy; +    int scr; +{ +    Screen *s = ScreenOfDisplay (dpy, scr);  /* opaque structure */ +    XVisualInfo viproto;		/* fill in for getting info */ +    XVisualInfo *vip;			/* retured info */ +    int nvi;				/* number of elements returned */ +    int i;				/* temp variable: iterator */ +    char eventbuf[80];			/* want 79 chars per line + nul */ +    static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED"; +    double xres, yres; +    int ndepths = 0, *depths = NULL; +    unsigned int width, height; + + +    /* +     * there are 2.54 centimeters to an inch; so there are 25.4 millimeters. +     * +     *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch)) +     *         = N pixels / (M inch / 25.4) +     *         = N * 25.4 pixels / M inch +     */ + +    xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) /  +	    ((double) DisplayWidthMM(dpy,scr))); +    yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) /  +	    ((double) DisplayHeightMM(dpy,scr))); + +    printf ("\n"); +    printf ("screen #%d:\n", scr); +    printf ("  dimensions:    %dx%d pixels (%dx%d millimeters)\n", +	    DisplayWidth (dpy, scr), DisplayHeight (dpy, scr), +	    DisplayWidthMM(dpy, scr), DisplayHeightMM (dpy, scr)); +    printf ("  resolution:    %dx%d dots per inch\n",  +	    (int) (xres + 0.5), (int) (yres + 0.5)); +    depths = XListDepths (dpy, scr, &ndepths); +    if (!depths) ndepths = 0; +    printf ("  depths (%d):    ", ndepths); +    for (i = 0; i < ndepths; i++) { +	printf ("%d", depths[i]); +	if (i < ndepths - 1) {  +	    putchar (','); +	    putchar (' '); +	} +    } +    putchar ('\n'); +    if (depths) XFree ((char *) depths); +    printf ("  root window id:    0x%lx\n", RootWindow (dpy, scr)); +    printf ("  depth of root window:    %d plane%s\n", +	    DisplayPlanes (dpy, scr), +	    DisplayPlanes (dpy, scr) == 1 ? "" : "s"); +    printf ("  number of colormaps:    minimum %d, maximum %d\n", +	    MinCmapsOfScreen(s), MaxCmapsOfScreen(s)); +    printf ("  default colormap:    0x%lx\n", DefaultColormap (dpy, scr)); +    printf ("  default number of colormap cells:    %d\n", +	    DisplayCells (dpy, scr)); +    printf ("  preallocated pixels:    black %d, white %d\n", +	    BlackPixel (dpy, scr), WhitePixel (dpy, scr)); +    printf ("  options:    backing-store %s, save-unders %s\n", +	    (DoesBackingStore (s) == NotUseful) ? no : +	    ((DoesBackingStore (s) == Always) ? yes : when), +	    DoesSaveUnders (s) ? yes : no); +    XQueryBestSize (dpy, CursorShape, RootWindow (dpy, scr), 65535, 65535, +		    &width, &height); +    if (width == 65535 && height == 65535) +	printf ("  largest cursor:    unlimited\n"); +    else +	printf ("  largest cursor:    %dx%d\n", width, height); +    printf ("  current input event mask:    0x%lx\n", EventMaskOfScreen (s)); +    (void) print_event_mask (eventbuf, 79, 4, EventMaskOfScreen (s)); +		       + +    nvi = 0; +    viproto.screen = scr; +    vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi); +    printf ("  number of visuals:    %d\n", nvi); +    printf ("  default visual id:  0x%lx\n",  +	    XVisualIDFromVisual (DefaultVisual (dpy, scr))); +    for (i = 0; i < nvi; i++) { +	print_visual_info (vip+i); +#ifdef HAVE_OVERLAY +       print_overlay_visual_info (vip+i); +#endif /* HAVE_OVERLAY */ +#ifdef HAVE_GLX +       print_glx_visual_info (dpy, vip+i); +#endif /* HAVE_GLX */ +    } +    if (vip) XFree ((char *) vip); +} + +/* + * The following routine prints out an event mask, wrapping events at nice + * boundaries. + */ + +#define MASK_NAME_WIDTH 25 + +static struct _event_table { +    char *name; +    long value; +} event_table[] = { +    { "KeyPressMask             ", KeyPressMask }, +    { "KeyReleaseMask           ", KeyReleaseMask }, +    { "ButtonPressMask          ", ButtonPressMask }, +    { "ButtonReleaseMask        ", ButtonReleaseMask }, +    { "EnterWindowMask          ", EnterWindowMask }, +    { "LeaveWindowMask          ", LeaveWindowMask }, +    { "PointerMotionMask        ", PointerMotionMask }, +    { "PointerMotionHintMask    ", PointerMotionHintMask }, +    { "Button1MotionMask        ", Button1MotionMask }, +    { "Button2MotionMask        ", Button2MotionMask }, +    { "Button3MotionMask        ", Button3MotionMask }, +    { "Button4MotionMask        ", Button4MotionMask }, +    { "Button5MotionMask        ", Button5MotionMask }, +    { "ButtonMotionMask         ", ButtonMotionMask }, +    { "KeymapStateMask          ", KeymapStateMask }, +    { "ExposureMask             ", ExposureMask }, +    { "VisibilityChangeMask     ", VisibilityChangeMask }, +    { "StructureNotifyMask      ", StructureNotifyMask }, +    { "ResizeRedirectMask       ", ResizeRedirectMask }, +    { "SubstructureNotifyMask   ", SubstructureNotifyMask }, +    { "SubstructureRedirectMask ", SubstructureRedirectMask }, +    { "FocusChangeMask          ", FocusChangeMask }, +    { "PropertyChangeMask       ", PropertyChangeMask }, +    { "ColormapChangeMask       ", ColormapChangeMask }, +    { "OwnerGrabButtonMask      ", OwnerGrabButtonMask }, +    { NULL, 0 }}; + +int print_event_mask (buf, lastcol, indent, mask) +    char *buf;				/* string to write into */ +    int lastcol;			/* strlen(buf)+1 */ +    int indent;				/* amount by which to indent */ +    long mask;				/* event mask */ +{ +    struct _event_table *etp; +    int len; +    int bitsfound = 0; + +    buf[0] = buf[lastcol] = '\0';	/* just in case */ + +#define INDENT() { register int i; len = indent; \ +		   for (i = 0; i < indent; i++) buf[i] = ' '; } + +    INDENT (); + +    for (etp = event_table; etp->name; etp++) { +	if (mask & etp->value) { +	    if (len + MASK_NAME_WIDTH > lastcol) { +		puts (buf); +		INDENT (); +	    } +	    strcpy (buf+len, etp->name); +	    len += MASK_NAME_WIDTH; +	    bitsfound++; +	} +    } + +    if (bitsfound) puts (buf); + +#undef INDENT + +    return (bitsfound); +} + +void +print_standard_extension_info(dpy, extname, majorrev, minorrev) +    Display *dpy; +    char *extname; +    int majorrev, minorrev; +{ +    int opcode, event, error; + +    printf("%s version %d.%d ", extname, majorrev, minorrev); + +    XQueryExtension(dpy, extname, &opcode, &event, &error); +    printf ("opcode: %d", opcode); +    if (event) +	printf (", base event: %d", event); +    if (error) +	printf (", base error: %d", error); +    printf("\n"); +} + +int +print_multibuf_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    int i, j;			/* temp variable: iterator */ +    int nmono, nstereo;		/* count */ +    XmbufBufferInfo *mono_info = NULL, *stereo_info = NULL; /* arrays */ +    static char *fmt =  +	"    visual id, max buffers, depth:    0x%lx, %d, %d\n"; +    int scr = 0; +    int majorrev, minorrev; + +    if (!XmbufGetVersion(dpy, &majorrev, &minorrev)) +	return 0; + +    print_standard_extension_info(dpy, extname, majorrev, minorrev); + +    for (i = 0; i < ScreenCount (dpy); i++) +    { +	if (!XmbufGetScreenInfo (dpy, RootWindow(dpy, scr), &nmono, &mono_info, +				 &nstereo, &stereo_info)) { +	    fprintf (stderr, +		     "%s:  unable to get multibuffer info for screen %d\n", +		     ProgramName, scr); +	} else { +	    printf ("  screen %d number of mono multibuffer types:    %d\n", i, nmono); +	    for (j = 0; j < nmono; j++) { +		printf (fmt, mono_info[j].visualid, mono_info[j].max_buffers, +			mono_info[j].depth); +	    } +	    printf ("  number of stereo multibuffer types:    %d\n", nstereo); +	    for (j = 0; j < nstereo; j++) { +		printf (fmt, stereo_info[j].visualid, +			stereo_info[j].max_buffers, stereo_info[j].depth); +	    } +	    if (mono_info) XFree ((char *) mono_info); +	    if (stereo_info) XFree ((char *) stereo_info); +	} +    } +    return 1; +} /* end print_multibuf_info */ + + +/* XIE stuff */ + +#ifdef HAVE_XIE + +char *subset_names[] = { NULL, "FULL", "DIS" }; +char *align_names[] = { NULL, "Alignable", "Arbitrary" }; +char *group_names[] = { /* 0  */ "Default", +			    /* 2  */ "ColorAlloc", +			    /* 4  */ "Constrain", +			    /* 6  */ "ConvertFromRGB", +			    /* 8  */ "ConvertToRGB", +			    /* 10 */ "Convolve", +			    /* 12 */ "Decode", +			    /* 14 */ "Dither", +			    /* 16 */ "Encode", +			    /* 18 */ "Gamut", +			    /* 20 */ "Geometry", +			    /* 22 */ "Histogram", +			    /* 24 */ "WhiteAdjust" +			    }; + +int +print_xie_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    XieExtensionInfo *xieInfo; +    int i; +    int ntechs; +    XieTechnique *techs; +    XieTechniqueGroup prevGroup; + +    if (!XieInitialize(dpy, &xieInfo )) +	return 0; + +    print_standard_extension_info(dpy, extname, +	xieInfo->server_major_rev, xieInfo->server_minor_rev); + +    printf("  service class: %s\n", subset_names[xieInfo->service_class]); +    printf("  alignment: %s\n", align_names[xieInfo->alignment]); +    printf("  uncnst_mantissa: %d\n", xieInfo->uncnst_mantissa); +    printf("  uncnst_min_exp: %d\n", xieInfo->uncnst_min_exp); +    printf("  uncnst_max_exp: %d\n", xieInfo->uncnst_max_exp); +    printf("  cnst_levels:");  +    for (i = 0; i < xieInfo->n_cnst_levels; i++) +	printf(" %d", xieInfo->cnst_levels[i]); +    printf("\n"); + +    if (!XieQueryTechniques(dpy, xieValAll, &ntechs, &techs)) +	return 1; + +    prevGroup = -1; + +    for (i = 0; i < ntechs; i++) +    { +	if (techs[i].group != prevGroup) +	{ +	    printf("  technique group: %s\n", group_names[techs[i].group >> 1]); +	    prevGroup = techs[i].group; +	} +	printf("    %s\tspeed: %d  needs_param: %s  number: %d\n", +	       techs[i].name, +	       techs[i].speed, (techs[i].needs_param ? "True " : "False"), +	       techs[i].number); +    } +    return 1; +} /* end print_xie_info */ + +#endif /* HAVE_XIE */ + + +#ifdef HAVE_XTEST +int +print_xtest_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    int majorrev, minorrev, foo; + +    if (!XTestQueryExtension(dpy, &foo, &foo, &majorrev, &minorrev)) +	return 0; +    print_standard_extension_info(dpy, extname, majorrev, minorrev); +    return 1; +} +#endif /* HAVE_XTEST */ + +int +print_sync_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    int majorrev, minorrev; +    XSyncSystemCounter *syscounters; +    int ncounters, i; + +    if (!XSyncInitialize(dpy, &majorrev, &minorrev)) +	return 0; +    print_standard_extension_info(dpy, extname, majorrev, minorrev); + +    syscounters = XSyncListSystemCounters(dpy, &ncounters); +    printf("  system counters: %d\n", ncounters); +    for (i = 0; i < ncounters; i++) +    { +	printf("    %s  id: 0x%08x  resolution_lo: %d  resolution_hi: %d\n", +	       syscounters[i].name, syscounters[i].counter, +	       XSyncValueLow32(syscounters[i].resolution), +	       XSyncValueHigh32(syscounters[i].resolution)); +    } +    XSyncFreeSystemCounterList(syscounters); +    return 1; +} + +int +print_shape_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    int majorrev, minorrev; + +    if (!XShapeQueryVersion(dpy, &majorrev, &minorrev)) +	return 0; +    print_standard_extension_info(dpy, extname, majorrev, minorrev); +    return 1; +} + +#ifdef MITSHM +int +print_mitshm_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    int majorrev, minorrev; +    Bool sharedPixmaps; + +    if (!XShmQueryVersion(dpy, &majorrev, &minorrev, &sharedPixmaps)) +	return 0; +    print_standard_extension_info(dpy, extname, majorrev, minorrev); +    printf("  shared pixmaps: "); +    if (sharedPixmaps) +    { +	int format = XShmPixmapFormat(dpy); +	printf("yes, format: %d\n", format); +    } +    else +    { +	printf("no\n"); +    } +    return 1; +} +#endif /* MITSHM */ + +int +print_dbe_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    int majorrev, minorrev; +    XdbeScreenVisualInfo *svi; +    int numscreens = 0; +    int iscrn, ivis; + +    if (!XdbeQueryExtension(dpy, &majorrev, &minorrev)) +	return 0; + +    print_standard_extension_info(dpy, extname, majorrev, minorrev); +    svi = XdbeGetVisualInfo(dpy, (Drawable *)NULL, &numscreens); +    for (iscrn = 0; iscrn < numscreens; iscrn++) +    { +	printf("  Double-buffered visuals on screen %d\n", iscrn); +	for (ivis = 0; ivis < svi[iscrn].count; ivis++) +	{ +	    printf("    visual id 0x%lx  depth %d  perflevel %d\n", +		   svi[iscrn].visinfo[ivis].visual, +		   svi[iscrn].visinfo[ivis].depth, +		   svi[iscrn].visinfo[ivis].perflevel); +	} +    } +    XdbeFreeVisualInfo(svi); +    return 1; +} + +#ifdef HAVE_XRECORD +int +print_record_info(dpy, extname) +    Display *dpy; +    char *extname; +{ +    int majorrev, minorrev; + +    if (!XRecordQueryVersion(dpy, &majorrev, &minorrev)) +	return 0; +    print_standard_extension_info(dpy, extname, majorrev, minorrev); +    return 1; +} +#endif /* HAVE_XRECORD */ + +/* utilities to manage the list of recognized extensions */ + + +typedef int (*ExtensionPrintFunc)( +#if NeedFunctionPrototypes +    Display *, char * +#endif +); + +typedef struct { +    char *extname; +    ExtensionPrintFunc printfunc; +    Bool printit; +} ExtensionPrintInfo; + +ExtensionPrintInfo known_extensions[] = +{ +#ifdef MITSHM +    {"MIT-SHM",	print_mitshm_info, False}, +#endif /* MITSHM */ +    {MULTIBUFFER_PROTOCOL_NAME,	print_multibuf_info, False}, +    {"SHAPE", print_shape_info, False}, +    {SYNC_NAME, print_sync_info, False}, +#ifdef HAVE_XIE +    {xieExtName, print_xie_info, False}, +#endif /* HAVE_XIE */ +#ifdef HAVE_XTEST +    {XTestExtensionName, print_xtest_info, False}, +#endif /* HAVE_XTEST */ +    {"DOUBLE-BUFFER", print_dbe_info, False}, +#ifdef HAVE_XRECORD +    {"RECORD", print_record_info, False}     +#endif /* HAVE_XRECORD */ +    /* add new extensions here */ +    /* wish list: PEX XKB LBX */ +}; + +int num_known_extensions = sizeof known_extensions / sizeof known_extensions[0]; + +void +print_known_extensions(f) +    FILE *f; +{ +    int i; +    for (i = 0; i < num_known_extensions; i++) +    { +	fprintf(f, "%s ", known_extensions[i].extname); +    } +} + +void +mark_extension_for_printing(extname) +    char *extname; +{ +    int i; + +    if (strcmp(extname, "all") == 0) +    { +	for (i = 0; i < num_known_extensions; i++) +	    known_extensions[i].printit = True; +    } +    else +    { +	for (i = 0; i < num_known_extensions; i++) +	{ +	    if (strcmp(extname, known_extensions[i].extname) == 0) +	    { +		known_extensions[i].printit = True; +		return; +	    } +	} +	printf("%s extension not supported by %s\n", extname, ProgramName); +    } +} + +void +print_marked_extensions(dpy) +    Display *dpy; +{ +    int i; +    for (i = 0; i < num_known_extensions; i++) +    { +	if (known_extensions[i].printit) +	{ +	    printf("\n"); +	    if (! (*known_extensions[i].printfunc)(dpy, +					known_extensions[i].extname)) +	    { +		printf("%s extension not supported by server\n", +		       known_extensions[i].extname); +	    } +	} +    } +} + +static void usage () +{ +    fprintf (stderr, "usage:  %s [options]\n", ProgramName); +    fprintf (stderr, "-display displayname\tserver to query\n"); +    fprintf (stderr, "-queryExtensions\tprint info returned by XQueryExtension\n"); +    fprintf (stderr, "-ext all\t\tprint detailed info for all supported extensions\n"); +    fprintf (stderr, "-ext extension-name\tprint detailed info for extension-name if one of:\n     "); +    print_known_extensions(stderr); +    fprintf (stderr, "\n"); +    exit (1); +} + +int main (argc, argv) +    int argc; +    char *argv[]; +{ +    Display *dpy;			/* X connection */ +    char *displayname = NULL;		/* server to contact */ +    int i;				/* temp variable:  iterator */ +    Bool multibuf = False; +    int mbuf_event_base, mbuf_error_base; + +    ProgramName = argv[0]; + +    for (i = 1; i < argc; i++) { +	char *arg = argv[i]; +	int len = strlen(arg); +	 +	if (!strncmp("-display", arg, len)) { +	    if (++i >= argc) usage (); +	    displayname = argv[i]; +	} else if (!strncmp("-queryExtensions", arg, len)) { +	    queryExtensions = True; +	} else if (!strncmp("-ext", arg, len)) { +	    if (++i >= argc) usage (); +	    mark_extension_for_printing(argv[i]); +	} else +	    usage (); +    } + +    dpy = XOpenDisplay (displayname); +    if (!dpy) { +	fprintf (stderr, "%s:  unable to open display \"%s\".\n", +		 ProgramName, XDisplayName (displayname)); +	exit (1); +    } + +#ifdef HAVE_OVERLAY +       find_overlay_info (dpy); +#endif /* HAVE_OVERLAY */ + +    print_display_info (dpy); +    for (i = 0; i < ScreenCount (dpy); i++) { +	print_screen_info (dpy, i); +    } + +    print_marked_extensions(dpy); + +    XCloseDisplay (dpy); +    exit (0); +} | 
