summaryrefslogtreecommitdiff
path: root/app/xdpyinfo/xdpyinfo.c
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-25 20:39:09 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-25 20:39:09 +0000
commit2387c426e6dfc2b0a2d0aa5585dbeb580f5ea91e (patch)
tree12721540663213a17c4c6a294f8f9473621fd503 /app/xdpyinfo/xdpyinfo.c
parentdc4a2107be04f29ad06d6e60e102370bf68739cd (diff)
Importing from X.Org 7.2RC2
Diffstat (limited to 'app/xdpyinfo/xdpyinfo.c')
-rw-r--r--app/xdpyinfo/xdpyinfo.c1534
1 files changed, 1534 insertions, 0 deletions
diff --git a/app/xdpyinfo/xdpyinfo.c b/app/xdpyinfo/xdpyinfo.c
new file mode 100644
index 000000000..5bc348ac1
--- /dev/null
+++ b/app/xdpyinfo/xdpyinfo.c
@@ -0,0 +1,1534 @@
+/*
+ * $Xorg: xdpyinfo.c,v 1.5 2001/02/09 02:05:41 xorgcvs Exp $
+ *
+ * xdpyinfo - print information about X display connecton
+ *
+ *
+Copyright 1988, 1998 The Open Group
+Copyright 2005 Hitachi, Ltd.
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+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
+ */
+
+/* $XFree86: xc/programs/xdpyinfo/xdpyinfo.c,v 3.29 2003/04/14 20:38:10 herrb Exp $ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+# if HAVE_X11_EXTENSIONS_MULTIBUF_H
+# define MULTIBUFFER
+# endif
+
+# if HAVE_X11_EXTENSIONS_XSHM_H
+# define MITSHM
+# endif
+
+# if HAVE_X11_EXTENSIONS_XKB_H && HAVE_X11_XKBLIB_H
+# define XKB
+# endif
+
+# if HAVE_X11_EXTENSIONS_XF86VMODE_H && HAVE_X11_EXTENSIONS_XF86VMSTR_H
+# define XF86VIDMODE
+# endif
+
+# if HAVE_X11_EXTENSIONS_XF86DGA_H && HAVE_X11_EXTENSIONS_XF86DGASTR_H
+# define XFreeXDGA
+# endif
+
+# if HAVE_X11_EXTENSIONS_XF86MISC_H && HAVE_X11_EXTENSIONS_XF86MSCSTR_H
+# define XF86MISC
+# endif
+
+# if HAVE_X11_EXTENSIONS_XINPUT_H
+# define XINPUT
+# endif
+
+# if HAVE_X11_EXTENSIONS_XRENDER_H
+# define XRENDER
+# endif
+
+# if HAVE_X11_EXTENSIONS_XINERAMA_H
+# define PANORAMIX
+# endif
+
+# if HAVE_X11_EXTENSIONS_DMXEXT_H
+# define DMX
+# endif
+
+# if HAVE_X11_EXTENSIONS_PRINT_H
+# define INCLUDE_XPRINT_SUPPORT
+# endif
+
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifdef MULTIBUFFER
+#include <X11/extensions/multibuf.h>
+#endif
+#include <X11/extensions/XTest.h>
+#include <X11/extensions/sync.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/Xdbe.h>
+#include <X11/extensions/record.h>
+#include <X11/extensions/shape.h>
+#ifdef MITSHM
+#include <X11/extensions/XShm.h>
+#endif
+#ifdef XKB
+#include <X11/extensions/XKB.h>
+#include <X11/XKBlib.h>
+#endif
+#ifdef XF86VIDMODE
+#include <X11/extensions/xf86vmode.h>
+#include <X11/extensions/xf86vmstr.h>
+#endif
+#ifdef XFreeXDGA
+#include <X11/extensions/xf86dga.h>
+#include <X11/extensions/xf86dgastr.h>
+#endif
+#ifdef XF86MISC
+#include <X11/extensions/xf86misc.h>
+#include <X11/extensions/xf86mscstr.h>
+#endif
+#ifdef XINPUT
+#include <X11/extensions/XInput.h>
+#endif
+#ifdef XRENDER
+#include <X11/extensions/Xrender.h>
+#endif
+#ifdef PANORAMIX
+#include <X11/extensions/Xinerama.h>
+#endif
+#ifdef DMX
+#include <X11/extensions/dmxext.h>
+#endif
+#ifdef INCLUDE_XPRINT_SUPPORT
+#include <X11/extensions/Print.h>
+#endif /* INCLUDE_XPRINT_SUPPORT */
+#include <X11/Xos.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Turn a NULL pointer string into an empty string */
+#define NULLSTR(x) (((x)!=NULL)?(x):(""))
+
+char *ProgramName;
+Bool queryExtensions = False;
+
+static int print_event_mask(char *buf, int lastcol, int indent, long mask);
+
+static int StrCmp(const void *a, const void *b)
+{
+ return strcmp(*(char **)a, *(char **)b);
+}
+
+static void
+print_extension_info(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); */
+ }
+}
+
+static void
+print_display_info(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));
+
+ if (strstr(ServerVendor (dpy), "XFree86")) {
+ int vendrel = VendorRelease(dpy);
+
+ printf("XFree86 version: ");
+ if (vendrel < 336) {
+ /*
+ * vendrel was set incorrectly for 3.3.4 and 3.3.5, so handle
+ * those cases here.
+ */
+ printf("%d.%d.%d", vendrel / 100,
+ (vendrel / 10) % 10,
+ vendrel % 10);
+ } else if (vendrel < 3900) {
+ /* 3.3.x versions, other than the exceptions handled above */
+ printf("%d.%d", vendrel / 1000,
+ (vendrel / 100) % 10);
+ if (((vendrel / 10) % 10) || (vendrel % 10)) {
+ printf(".%d", (vendrel / 10) % 10);
+ if (vendrel % 10) {
+ printf(".%d", vendrel % 10);
+ }
+ }
+ } else if (vendrel < 40000000) {
+ /* 4.0.x versions */
+ printf("%d.%d", vendrel / 1000,
+ (vendrel / 10) % 10);
+ if (vendrel % 10) {
+ printf(".%d", vendrel % 10);
+ }
+ } else {
+ /* post-4.0.x */
+ printf("%d.%d.%d", vendrel / 10000000,
+ (vendrel / 100000) % 100,
+ (vendrel / 1000) % 100);
+ if (vendrel % 1000) {
+ printf(".%d", vendrel % 1000);
+ }
+ }
+ printf("\n");
+ }
+
+ if (strstr(ServerVendor (dpy), "X.Org")) {
+ int vendrel = VendorRelease(dpy);
+
+ printf("X.Org version: ");
+ printf("%d.%d.%d", vendrel / 10000000,
+ (vendrel / 100000) % 100,
+ (vendrel / 1000) % 100);
+ if (vendrel % 1000)
+ printf(".%d", vendrel % 1000);
+ printf("\n");
+ }
+
+ if (strstr(ServerVendor (dpy), "DMX")) {
+ int vendrel = VendorRelease(dpy);
+ int major, minor, year, month, day;
+
+ major = vendrel / 100000000;
+ vendrel -= major * 100000000;
+ minor = vendrel / 1000000;
+ vendrel -= minor * 1000000;
+ year = vendrel / 10000;
+ vendrel -= year * 10000;
+ month = vendrel / 100;
+ vendrel -= month * 100;
+ day = vendrel;
+
+ /* Add other epoch tests here */
+ if (major > 0 && minor > 0) year += 2000;
+
+ /* Do some sanity tests in case there is
+ * another server with the same vendor
+ * string. That server could easily use
+ * values < 100000000, which would have
+ * the effect of keeping our major
+ * number 0. */
+ if (major > 0 && major <= 20
+ && minor >= 0 && minor <= 99
+ && year >= 2000
+ && month >= 1 && month <= 12
+ && day >= 1 && day <= 31)
+ printf("DMX version: %d.%d.%04d%02d%02d\n",
+ major, minor, year, month, day);
+ }
+
+ 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: %ld\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));
+}
+
+static void
+print_visual_info(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);
+}
+
+/* xc/programs/twm/twm.c has a copy of |hasExtension()|, please
+ * keep both versions in sync... */
+static
+Bool hasExtension(Display *dpy, char *extname)
+{
+ int num_extensions,
+ i;
+ char **extensions;
+ extensions = XListExtensions(dpy, &num_extensions);
+ for (i = 0; i < num_extensions &&
+ (strcmp(extensions[i], extname) != 0); i++);
+ XFreeExtensionList(extensions);
+ return i != num_extensions;
+}
+
+#ifdef INCLUDE_XPRINT_SUPPORT
+/* xc/programs/twm/twm.c has a copy of |IsPrintScreen()|, please
+ * keep both versions in sync... */
+static
+Bool IsPrintScreen(Screen *s)
+{
+ Display *dpy = XDisplayOfScreen(s);
+ int i;
+
+ /* Check whether this is a screen of a print DDX */
+ if (hasExtension(dpy, XP_PRINTNAME)) {
+ Screen **pscreens;
+ int pscrcount;
+
+ pscreens = XpQueryScreens(dpy, &pscrcount);
+ for( i = 0 ; (i < pscrcount) && pscreens ; i++ ) {
+ if (s == pscreens[i]) {
+ return True;
+ }
+ }
+ XFree(pscreens);
+ }
+ return False;
+}
+#endif /* INCLUDE_XPRINT_SUPPORT */
+
+static void
+print_screen_info(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;
+ Bool isPrintScreen = False; /* Initalise this if |INCLUDE_XPRINT_SUPPORT| is not set */
+
+ /*
+ * 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);
+
+#ifdef INCLUDE_XPRINT_SUPPORT
+ /* Check whether this is a screen of a print DDX */
+ isPrintScreen = IsPrintScreen(s);
+ printf (" print screen: %s\n", isPrintScreen?"yes":"no");
+#endif /* INCLUDE_XPRINT_SUPPORT */
+
+ if (isPrintScreen) {
+ /* Print resolution is set on a per-printer basis (per-document
+ * or per-page), the screen itself has no "default" resolution */
+ printf (" maximum dimensions: %dx%d pixels\n",
+ XDisplayWidth (dpy, scr), XDisplayHeight (dpy, scr));
+ }
+ else
+ {
+ printf (" dimensions: %dx%d pixels (%dx%d millimeters)\n",
+ XDisplayWidth (dpy, scr), XDisplayHeight (dpy, scr),
+ XDisplayWidthMM(dpy, scr), XDisplayHeightMM (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 %ld, white %ld\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);
+ }
+ 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 }};
+
+static int
+print_event_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);
+}
+
+static void
+print_standard_extension_info(Display *dpy, char *extname,
+ int majorrev, int 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");
+}
+
+#ifdef MULTIBUFFER
+static int
+print_multibuf_info(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 */
+#endif
+
+static int
+print_xtest_info(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;
+}
+
+static int
+print_sync_info(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, (unsigned int)syscounters[i].counter,
+ XSyncValueLow32(syscounters[i].resolution),
+ XSyncValueHigh32(syscounters[i].resolution));
+ }
+ XSyncFreeSystemCounterList(syscounters);
+ return 1;
+}
+
+static int
+print_shape_info(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 XFreeXDGA
+static int
+print_dga_info(Display *dpy, char *extname)
+{
+ int majorrev, minorrev, width, bank, ram, offset, flags;
+
+ if (!XF86DGAQueryVersion(dpy, &majorrev, &minorrev))
+ return 0;
+ print_standard_extension_info(dpy, extname, majorrev, minorrev);
+
+ if (!XF86DGAQueryDirectVideo(dpy, DefaultScreen(dpy), &flags)
+ || ! (flags & XF86DGADirectPresent) )
+ {
+ printf(" DGA not available on screen %d.\n", DefaultScreen(dpy));
+ return 1;
+ }
+
+ if (!XF86DGAGetVideoLL(dpy, DefaultScreen(dpy), &offset,
+ &width, &bank, &ram))
+ return 0;
+ printf(" Base address = 0x%X, Width = %d, Bank size = %d,"
+ " RAM size = %dk\n", offset, width, bank, ram);
+
+ return 1;
+}
+#endif
+
+#ifdef XF86VIDMODE
+#define V_PHSYNC 0x001
+#define V_NHSYNC 0x002
+#define V_PVSYNC 0x004
+#define V_NVSYNC 0x008
+#define V_INTERLACE 0x010
+#define V_DBLSCAN 0x020
+#define V_CSYNC 0x040
+#define V_PCSYNC 0x080
+#define V_NCSYNC 0x100
+
+static int
+print_XF86VidMode_info(Display *dpy, char *extname)
+{
+ int majorrev, minorrev, modecount, dotclock, i;
+ XF86VidModeMonitor monitor;
+ XF86VidModeModeLine modeline;
+ XF86VidModeModeInfo **modelines;
+
+ if (!XF86VidModeQueryVersion(dpy, &majorrev, &minorrev))
+ return 0;
+ print_standard_extension_info(dpy, extname, majorrev, minorrev);
+
+ if (!XF86VidModeGetMonitor(dpy, DefaultScreen(dpy), &monitor))
+ return 0;
+ printf(" Monitor Information:\n");
+ printf(" Vendor: %s, Model: %s\n", monitor.vendor, monitor.model);
+ printf(" Num hsync: %d, Num vsync: %d\n", monitor.nhsync, monitor.nvsync);
+ for (i = 0; i < monitor.nhsync; i++) {
+ printf(" hsync range %d: %6.2f - %6.2f\n", i, monitor.hsync[i].lo,
+ monitor.hsync[i].hi);
+ }
+ for (i = 0; i < monitor.nvsync; i++) {
+ printf(" vsync range %d: %6.2f - %6.2f\n", i, monitor.vsync[i].lo,
+ monitor.vsync[i].hi);
+ }
+
+ if ((majorrev > 0) || (majorrev == 0 && minorrev > 5)) {
+ if (!XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &modecount,
+ &modelines))
+ return 0;
+ printf(" Available Video Mode Settings:\n");
+ printf(" Clock Hdsp Hbeg Hend Httl Vdsp Vbeg Vend Vttl Flags\n");
+ for (i = 0; i < modecount; i++) {
+ printf(" %6.2f %4d %4d %4d %4d %4d %4d %4d %4d ",
+ (float)modelines[i]->dotclock/1000.0,
+ modelines[i]->hdisplay, modelines[i]->hsyncstart,
+ modelines[i]->hsyncend, modelines[i]->htotal,
+ modelines[i]->vdisplay, modelines[i]->vsyncstart,
+ modelines[i]->vsyncend, modelines[i]->vtotal);
+ if (modelines[i]->flags & V_PHSYNC) printf(" +hsync");
+ if (modelines[i]->flags & V_NHSYNC) printf(" -hsync");
+ if (modelines[i]->flags & V_PVSYNC) printf(" +vsync");
+ if (modelines[i]->flags & V_NVSYNC) printf(" -vsync");
+ if (modelines[i]->flags & V_INTERLACE) printf(" interlace");
+ if (modelines[i]->flags & V_CSYNC) printf(" composite");
+ if (modelines[i]->flags & V_PCSYNC) printf(" +csync");
+ if (modelines[i]->flags & V_PCSYNC) printf(" -csync");
+ if (modelines[i]->flags & V_DBLSCAN) printf(" doublescan");
+ printf("\n");
+ }
+
+ if (!XF86VidModeGetModeLine(dpy, DefaultScreen(dpy),
+ &dotclock, &modeline))
+ return 0;
+ printf(" Current Video Mode Setting:\n");
+ printf(" %6.2f %4d %4d %4d %4d %4d %4d %4d %4d ",
+ (float)dotclock/1000.0,
+ modeline.hdisplay, modeline.hsyncstart,
+ modeline.hsyncend, modeline.htotal,
+ modeline.vdisplay, modeline.vsyncstart,
+ modeline.vsyncend, modeline.vtotal);
+ if (modeline.flags & V_PHSYNC) printf(" +hsync");
+ if (modeline.flags & V_NHSYNC) printf(" -hsync");
+ if (modeline.flags & V_PVSYNC) printf(" +vsync");
+ if (modeline.flags & V_NVSYNC) printf(" -vsync");
+ if (modeline.flags & V_INTERLACE) printf(" interlace");
+ if (modeline.flags & V_CSYNC) printf(" composite");
+ if (modeline.flags & V_PCSYNC) printf(" +csync");
+ if (modeline.flags & V_PCSYNC) printf(" -csync");
+ if (modeline.flags & V_DBLSCAN) printf(" doublescan");
+ printf("\n");
+ }
+
+ return 1;
+}
+#endif
+
+#ifdef XF86MISC
+
+char *kbdtable[] = { "Unknown", "84-key", "101-key", "Other", "Xqueue" };
+char *msetable[] = { "None", "Microsoft", "MouseSystems", "MMSeries",
+ "Logitech", "BusMouse", "Mouseman", "PS/2", "MMHitTab",
+ "GlidePoint", "IntelliMouse", "ThinkingMouse",
+ "IMPS/2", "ThinkingMousePS/2", "MouseManPlusPS/2",
+ "GlidePointPS/2", "NetMousePS/2", "NetScrollPS/2",
+ "SysMouse", "Auto" };
+char *flgtable[] = { "None", "ClearDTR", "ClearRTS",
+ "ClearDTR and ClearRTS" };
+
+static int
+print_XF86Misc_info(Display *dpy, char *extname)
+{
+ int majorrev, minorrev;
+ XF86MiscMouseSettings mouseinfo;
+ XF86MiscKbdSettings kbdinfo;
+
+ if (!XF86MiscQueryVersion(dpy, &majorrev, &minorrev))
+ return 0;
+ print_standard_extension_info(dpy, extname, majorrev, minorrev);
+
+ if ((majorrev > 0) || (majorrev == 0 && minorrev > 0)) {
+ if (!XF86MiscGetKbdSettings(dpy, &kbdinfo))
+ return 0;
+ printf(" Keyboard Settings- Type: %s, Rate: %d, Delay: %d, ServerNumLock: %s\n",
+ kbdtable[kbdinfo.type], kbdinfo.rate, kbdinfo.delay,
+ (kbdinfo.servnumlock? "yes": "no"));
+
+ if (!XF86MiscGetMouseSettings(dpy, &mouseinfo))
+ return 0;
+ printf(" Mouse Settings- Device: %s, Type: ",
+ strlen(mouseinfo.device) == 0 ? "None": mouseinfo.device);
+ if (mouseinfo.type == MTYPE_XQUEUE)
+ printf("Xqueue\n");
+ else if (mouseinfo.type == MTYPE_OSMOUSE)
+ printf("OSMouse\n");
+ else if (mouseinfo.type <= MTYPE_AUTOMOUSE)
+ printf("%s\n", msetable[mouseinfo.type+1]);
+ else
+ printf("Unknown\n");
+ printf(" BaudRate: %d, SampleRate: %d, Resolution: %d\n",
+ mouseinfo.baudrate, mouseinfo.samplerate, mouseinfo.resolution);
+ printf(" Emulate3Buttons: %s, Emulate3Timeout: %d ms\n",
+ mouseinfo.emulate3buttons? "yes": "no", mouseinfo.emulate3timeout);
+ printf(" ChordMiddle: %s, Flags: %s\n",
+ mouseinfo.chordmiddle? "yes": "no",
+ flgtable[(mouseinfo.flags & MF_CLEAR_DTR? 1: 0)
+ +(mouseinfo.flags & MF_CLEAR_RTS? 1: 0)] );
+ printf(" Buttons: %d\n", mouseinfo.buttons);
+ }
+
+ return 1;
+}
+#endif
+
+#ifdef MITSHM
+static int
+print_mitshm_info(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 */
+
+#ifdef XKB
+static int
+print_xkb_info(Display *dpy, char *extname)
+{
+ int opcode, eventbase, errorbase, majorrev, minorrev;
+
+ if (!XkbQueryExtension(dpy, &opcode, &eventbase, &errorbase,
+ &majorrev, &minorrev)) {
+ return 0;
+ }
+ printf("%s version %d.%d ", extname, majorrev, minorrev);
+
+ printf ("opcode: %d", opcode);
+ if (eventbase)
+ printf (", base event: %d", eventbase);
+ if (errorbase)
+ printf (", base error: %d", errorbase);
+ printf("\n");
+
+ return 1;
+}
+#endif
+
+static int
+print_dbe_info(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;
+}
+
+static int
+print_record_info(Display *dpy, char *extname)
+{
+ int majorrev, minorrev;
+
+ if (!XRecordQueryVersion(dpy, &majorrev, &minorrev))
+ return 0;
+ print_standard_extension_info(dpy, extname, majorrev, minorrev);
+ return 1;
+}
+
+#ifdef XINPUT
+static int
+print_xinput_info(Display *dpy, char *extname)
+{
+ int loop, num_extensions, num_devices;
+ char **extensions;
+ XDeviceInfo *devices;
+ XExtensionVersion *ext;
+
+ ext = XGetExtensionVersion(dpy, extname);
+
+ if (!ext || (ext == (XExtensionVersion*) NoSuchExtension))
+ return 0;
+
+ print_standard_extension_info(dpy, extname, ext->major_version,
+ ext->minor_version);
+
+ extensions = XListExtensions(dpy, &num_extensions);
+ for (loop = 0; loop < num_extensions &&
+ (strcmp(extensions[loop], extname) != 0); loop++);
+ XFreeExtensionList(extensions);
+ if (loop != num_extensions) {
+ printf(" Extended devices :\n");
+ devices = XListInputDevices(dpy, &num_devices);
+ for(loop=0; loop<num_devices; loop++) {
+ printf(" \"%s\" [", devices[loop].name ? devices[loop].name : "<noname>");
+ switch(devices[loop].use) {
+ case IsXPointer:
+ printf("XPointer]\n");
+ break;
+ case IsXKeyboard:
+ printf("XKeyboard]\n");
+ break;
+ case IsXExtensionDevice:
+ printf("XExtensionDevice]\n");
+ break;
+ default:
+ printf("invalid value]\n");
+ break;
+ }
+ }
+ XFreeDeviceList(devices);
+ return 1;
+ }
+ else
+ return 0;
+}
+#endif
+
+#ifdef XRENDER
+static int
+print_xrender_info(Display *dpy, char *extname)
+{
+ int loop, num_extensions;
+ char **extensions;
+ XRenderPictFormat *pictform;
+ int count;
+ int major, minor;
+ int i, j;
+ XVisualInfo viproto; /* fill in for getting info */
+ XVisualInfo *vip; /* retured info */
+ int nvi; /* number of elements returned */
+ int ndepths = 0, *depths = NULL;
+#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
+ XFilters *filters;
+ int f;
+#endif
+
+ if (!XRenderQueryVersion (dpy, &major, &minor))
+ return 0;
+
+ print_standard_extension_info(dpy, extname, major, minor);
+
+ extensions = XListExtensions(dpy, &num_extensions);
+ for (loop = 0; loop < num_extensions &&
+ (strcmp(extensions[loop], extname) != 0); loop++);
+ XFreeExtensionList(extensions);
+ if (loop != num_extensions) {
+ printf (" Render formats :\n");
+ for (count = 0; (pictform = XRenderFindFormat (dpy, 0, 0, count)); count++)
+ {
+ printf (" pict format:\n");
+ printf ("\tformat id: 0x%lx\n", pictform->id);
+ printf ("\ttype: %s\n",
+ pictform->type == PictTypeIndexed ? "Indexed" : "Direct");
+ printf ("\tdepth: %d\n", pictform->depth);
+ if (pictform->type == PictTypeDirect) {
+ printf("\talpha: %2d mask 0x%x\n", pictform->direct.alpha, pictform->direct.alphaMask);
+ printf("\tred: %2d mask 0x%x\n", pictform->direct.red, pictform->direct.redMask);
+ printf("\tgreen: %2d mask 0x%x\n", pictform->direct.green, pictform->direct.greenMask);
+ printf("\tblue: %2d mask 0x%x\n", pictform->direct.blue, pictform->direct.blueMask);
+ }
+ else
+ printf("\tcolormap 0x%lx\n", pictform->colormap);
+ }
+ printf (" Screen formats :\n");
+ for (i = 0; i < ScreenCount (dpy); i++) {
+ nvi = 0;
+ viproto.screen = i;
+ vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi);
+ printf (" Screen %d", i);
+#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
+ switch (XRenderQuerySubpixelOrder (dpy, i)) {
+ case SubPixelUnknown: printf (" (sub-pixel order Unknown)"); break;
+ case SubPixelHorizontalRGB: printf (" (sub-pixel order Horizontal RGB)"); break;
+ case SubPixelHorizontalBGR: printf (" (sub-pixel order Horizontal BGR)"); break;
+ case SubPixelVerticalRGB: printf (" (sub-pixel order Vertical RGB)"); break;
+ case SubPixelVerticalBGR: printf (" (sub-pixel order Vertical BGR)"); break;
+ case SubPixelNone: printf (" (sub-pixel order None)"); break;
+ }
+ printf ("\n");
+ filters = XRenderQueryFilters (dpy, RootWindow (dpy, i));
+ if (filters)
+ {
+ printf (" filters: ");
+ for (f = 0; f < filters->nfilter; f++)
+ {
+ printf ("%s", filters->filter[f]);
+ if (f < filters->nalias && filters->alias[f] != FilterAliasNone)
+ printf ("(%s)", filters->filter[filters->alias[f]]);
+ if (f < filters->nfilter - 1)
+ printf (", ");
+ }
+ XFree (filters);
+ }
+#endif
+ printf ("\n");
+ for (j = 0; j < nvi; j++)
+ {
+ printf (" visual format:\n");
+ printf (" visual id: 0x%lx\n", vip[j].visualid);
+ pictform = XRenderFindVisualFormat (dpy, vip[j].visual);
+ if (pictform)
+ printf(" pict format id: 0x%lx\n", pictform->id);
+ else
+ printf(" pict format id: None\n");
+ }
+ if (vip) XFree ((char *) vip);
+ depths = XListDepths (dpy, i, &ndepths);
+ if (!depths) ndepths = 0;
+ for (j = 0; j < ndepths; j++)
+ {
+ XRenderPictFormat templ;
+
+ templ.depth = depths[j];
+ printf (" depth formats:\n");
+ printf (" depth %d\n", depths[j]);
+ for (count = 0; (pictform = XRenderFindFormat (dpy, PictFormatDepth, &templ, count)); count++)
+ printf(" pict format id: 0x%lx\n", pictform->id);
+ }
+ }
+ return 1;
+ }
+ else
+ return 0;
+}
+#endif /* XRENDER */
+
+
+#ifdef PANORAMIX
+
+static int
+print_xinerama_info(Display *dpy, char *extname)
+{
+ int majorrev, minorrev;
+
+ if (!XineramaQueryVersion (dpy, &majorrev, &minorrev))
+ return 0;
+
+ print_standard_extension_info(dpy, extname, majorrev, minorrev);
+
+ if (!XineramaIsActive(dpy)) {
+ printf(" Xinerama is inactive.\n");
+ } else {
+ int i, count = 0;
+ XineramaScreenInfo *xineramaScreens = XineramaQueryScreens(dpy, &count);
+
+ for (i = 0; i < count; i++) {
+ XineramaScreenInfo *xs = &xineramaScreens[i];
+ printf(" head #%d: %dx%d @ %d,%d\n", xs->screen_number,
+ xs->width, xs->height, xs->x_org, xs->y_org);
+ }
+
+ XFree(xineramaScreens);
+ }
+
+ return 1;
+}
+
+#endif /* PANORAMIX */
+
+#ifdef DMX
+static const char *core(DMXInputAttributes *iinfo)
+{
+ if (iinfo->isCore) return "core";
+ else if (iinfo->sendsCore) return "extension (sends core)";
+ else return "extension";
+}
+
+static int print_dmx_info(Display *dpy, char *extname)
+{
+ int event_base, error_base;
+ int major_version, minor_version, patch_version;
+ DMXScreenAttributes sinfo;
+ DMXInputAttributes iinfo;
+ int count;
+ int i;
+
+ if (!DMXQueryExtension(dpy, &event_base, &error_base)
+ || !DMXQueryVersion(dpy, &major_version, &minor_version,
+ &patch_version)) return 0;
+ print_standard_extension_info(dpy, extname, major_version, minor_version);
+ printf(" Version stamp: %d\n", patch_version);
+
+ if (!DMXGetScreenCount(dpy, &count)) return 1;
+ printf(" Screen count: %d\n", count);
+ for (i = 0; i < count; i++) {
+ if (DMXGetScreenAttributes(dpy, i, &sinfo)) {
+ printf(" %2d %s %ux%u+%d+%d %d @%dx%d\n",
+ i, sinfo.displayName,
+ sinfo.screenWindowWidth, sinfo.screenWindowHeight,
+ sinfo.screenWindowXoffset, sinfo.screenWindowYoffset,
+ sinfo.logicalScreen,
+ sinfo.rootWindowXorigin, sinfo.rootWindowYorigin);
+ }
+ }
+
+ if (major_version != 1
+ || minor_version < 1
+ || !DMXGetInputCount(dpy, &count))
+ return 1;
+
+ printf(" Input count = %d\n", count);
+ for (i = 0; i < count; i++) {
+#ifdef XINPUT
+ Display *backend;
+ char *backendname = NULL;
+#endif
+ if (DMXGetInputAttributes(dpy, i, &iinfo)) {
+ switch (iinfo.inputType) {
+ case DMXLocalInputType:
+ printf(" %2d local %s", i, core(&iinfo));
+ break;
+ case DMXConsoleInputType:
+ printf(" %2d console %s %s", i, core(&iinfo),
+ iinfo.name);
+ break;
+ case DMXBackendInputType:
+#ifdef XINPUT
+ if (iinfo.physicalId >= 0) {
+ if ((backend = XOpenDisplay(iinfo.name))) {
+ XExtensionVersion *ext
+ = XGetExtensionVersion(backend, INAME);
+ if (ext
+ && ext != (XExtensionVersion *)NoSuchExtension) {
+
+ int count, i;
+ XDeviceInfo *devInfo = XListInputDevices(backend,
+ &count);
+ if (devInfo) {
+ for (i = 0; i < count; i++) {
+ if ((unsigned)iinfo.physicalId
+ == devInfo[i].id
+ && devInfo[i].name) {
+ backendname = strdup(devInfo[i].name);
+ break;
+ }
+ }
+ XFreeDeviceList(devInfo);
+ }
+ }
+ XCloseDisplay(backend);
+ }
+ }
+#endif
+ printf(" %2d backend %s o%d/%s",i, core(&iinfo),
+ iinfo.physicalScreen, iinfo.name);
+ if (iinfo.physicalId >= 0) printf("/id%d", iinfo.physicalId);
+#ifdef XINPUT
+ if (backendname) {
+ printf("=%s", backendname);
+ free(backendname);
+ }
+#endif
+ break;
+ }
+ }
+ printf("\n");
+ }
+ return 1;
+}
+
+#endif /* DMX */
+
+#ifdef INCLUDE_XPRINT_SUPPORT
+static
+void print_xprint_attrpool(const char *name, const char *attrpool)
+{
+ int c;
+ const char *s = attrpool;
+
+ printf(" %s:\n ", name);
+
+ while( (c = *s++) != '\0' )
+ {
+ if (c == '\n') {
+ printf("\n ");
+ }
+ else
+ {
+ fputc(c, stdout);
+ }
+ }
+ fputc('\n', stdout);
+}
+
+static int
+print_xprint_info(Display *dpy, char *extname)
+{
+
+ short majorrev,
+ minorrev;
+ int xp_event_base,
+ xp_error_base;
+ XPPrinterList printerlist;
+ Screen **pscreens;
+ int plcount,
+ pscrcount,
+ i;
+
+ if (XpQueryVersion(dpy, &majorrev, &minorrev) == False) {
+ return 0;
+ }
+
+ print_standard_extension_info(dpy, extname, majorrev, minorrev);
+
+ if (XpQueryExtension(dpy, &xp_event_base, &xp_error_base) == False) {
+ printf(" XpQueryExtension() failed.\n");
+ return 0;
+ }
+
+ /* Print event info */
+ printf(" xp_event_base=%d, xp_error_base=%d\n", xp_event_base, xp_error_base);
+
+ /* Print info which screens support the Xprint extension */
+ printf(" Print screens = {");
+ pscreens = XpQueryScreens(dpy, &pscrcount);
+ for( i = 0 ; i < pscrcount ; i++ ) {
+ printf("%s%d", ((i > 0)?(", "):("")), (int)XScreenNumberOfScreen(pscreens[i]));
+ }
+ XFree(pscreens);
+ printf("}\n");
+
+ /* Enumerate the list of printers */
+ printerlist = XpGetPrinterList(dpy, NULL, &plcount);
+ /* Print number of printers, then each printer name and description */
+ printf(" Found %d printers on this server.\n", plcount);
+ for( i = 0 ; i < plcount ; i++) {
+ printf(" printer %d: name='%s', descr='%s'\n",
+ i, NULLSTR(printerlist[i].name), NULLSTR(printerlist[i].desc));
+ }
+
+ /* Enumerate the list of printers with details */
+ for( i = 0 ; i < plcount ; i++) {
+ char *printername = printerlist[i].name;
+ XPContext pcontext;
+ char *s;
+
+ printf(" Attributes of printer '%s':\n", NULLSTR(printername));
+
+ pcontext = XpCreateContext(dpy, printername);
+ if (pcontext == None) {
+ printf(" Error: Could not open printer.\n");
+ continue;
+ }
+
+ s=XpGetAttributes(dpy, pcontext, XPJobAttr); print_xprint_attrpool("XPJobAttr", s); XFree(s);
+ s=XpGetAttributes(dpy, pcontext, XPDocAttr); print_xprint_attrpool("XPDocAttr", s); XFree(s);
+ s=XpGetAttributes(dpy, pcontext, XPPageAttr); print_xprint_attrpool("XPPageAttr", s); XFree(s);
+ s=XpGetAttributes(dpy, pcontext, XPPrinterAttr); print_xprint_attrpool("XPPrinterAttr", s); XFree(s);
+ s=XpGetAttributes(dpy, pcontext, XPServerAttr); print_xprint_attrpool("XPServerAttr", s); XFree(s);
+
+ XpDestroyContext(dpy, pcontext);
+ }
+
+ XpFreePrinterList(printerlist);
+
+ return 1;
+}
+#endif /* INCLUDE_XPRINT_SUPPORT */
+
+/* utilities to manage the list of recognized extensions */
+
+
+typedef int (*ExtensionPrintFunc)(
+ Display *, char *
+);
+
+typedef struct {
+ char *extname;
+ ExtensionPrintFunc printfunc;
+ Bool printit;
+} ExtensionPrintInfo;
+
+ExtensionPrintInfo known_extensions[] =
+{
+#ifdef MITSHM
+ {"MIT-SHM", print_mitshm_info, False},
+#endif /* MITSHM */
+#ifdef XKB
+ {XkbName, print_xkb_info, False},
+#endif /* XKB */
+#ifdef MULTIBUFFER
+ {MULTIBUFFER_PROTOCOL_NAME, print_multibuf_info, False},
+#endif
+ {"SHAPE", print_shape_info, False},
+ {SYNC_NAME, print_sync_info, False},
+#ifdef XFreeXDGA
+ {XF86DGANAME, print_dga_info, False},
+#endif /* XFreeXDGA */
+#ifdef XF86VIDMODE
+ {XF86VIDMODENAME, print_XF86VidMode_info, False},
+#endif /* XF86VIDMODE */
+#ifdef XF86MISC
+ {XF86MISCNAME, print_XF86Misc_info, False},
+#endif /* XF86MISC */
+ {XTestExtensionName, print_xtest_info, False},
+ {"DOUBLE-BUFFER", print_dbe_info, False},
+ {"RECORD", print_record_info, False},
+#ifdef XINPUT
+ {INAME, print_xinput_info, False},
+#endif
+#ifdef XRENDER
+ {RENDER_NAME, print_xrender_info, False},
+#endif
+#ifdef PANORAMIX
+ {"XINERAMA", print_xinerama_info, False},
+#endif
+#ifdef DMX
+ {"DMX", print_dmx_info, False},
+#endif
+#ifdef INCLUDE_XPRINT_SUPPORT
+ {XP_PRINTNAME, print_xprint_info, False},
+#endif /* INCLUDE_XPRINT_SUPPORT */
+ /* add new extensions here */
+};
+
+int num_known_extensions = sizeof known_extensions / sizeof known_extensions[0];
+
+static void
+print_known_extensions(FILE *f)
+{
+ int i, col;
+ for (i = 0, col = 6; i < num_known_extensions; i++)
+ {
+ if ((col += strlen(known_extensions[i].extname)+1) > 79)
+ {
+ col = 6;
+ fprintf(f, "\n ");
+ }
+ fprintf(f, "%s ", known_extensions[i].extname);
+ }
+}
+
+static void
+mark_extension_for_printing(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);
+ }
+}
+
+static void
+print_marked_extensions(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(void)
+{
+ 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(int argc, char *argv[])
+{
+ Display *dpy; /* X connection */
+ char *displayname = NULL; /* server to contact */
+ int i; /* temp variable: iterator */
+
+ 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);
+ }
+
+ print_display_info (dpy);
+ for (i = 0; i < ScreenCount (dpy); i++) {
+ print_screen_info (dpy, i);
+ }
+
+ print_marked_extensions(dpy);
+
+ XCloseDisplay (dpy);
+ exit (0);
+}