"Initial commit to Gerrit"
[profile/ivi/xorg-utils.git] / xdpyinfo / xdpyinfo.c
1 /*
2  * $Xorg: xdpyinfo.c,v 1.5 2001/02/09 02:05:41 xorgcvs Exp $
3  * 
4  * xdpyinfo - print information about X display connection
5  *
6  * 
7 Copyright 1988, 1998  The Open Group
8 Copyright 2005 Hitachi, Ltd.
9
10 Permission to use, copy, modify, distribute, and sell this software and its
11 documentation for any purpose is hereby granted without fee, provided that
12 the above copyright notice appear in all copies and that both that
13 copyright notice and this permission notice appear in supporting
14 documentation.
15
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
22 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 Except as contained in this notice, the name of The Open Group shall not be
27 used in advertising or otherwise to promote the sale, use or other dealings
28 in this Software without prior written authorization from The Open Group.
29  *
30  * Author:  Jim Fulton, MIT X Consortium
31  */
32
33 /* $XFree86: xc/programs/xdpyinfo/xdpyinfo.c,v 3.29 2003/04/14 20:38:10 herrb Exp $ */
34
35 #ifdef HAVE_CONFIG_H
36 # include "config.h"
37 # if HAVE_X11_EXTENSIONS_MULTIBUF_H
38 #  define MULTIBUFFER
39 # endif
40
41 # if HAVE_X11_EXTENSIONS_XSHM_H
42 #  define MITSHM
43 # endif
44
45 # if HAVE_X11_EXTENSIONS_XKB_H && HAVE_X11_XKBLIB_H
46 #  define XKB
47 # endif
48
49 # if HAVE_X11_EXTENSIONS_XF86VMODE_H && \
50         (HAVE_X11_EXTENSIONS_XF86VMSTR_H || HAVE_X11_EXTENSIONS_XF86VMPROTO_H)
51 #  define XF86VIDMODE
52 # endif
53
54 # if (HAVE_X11_EXTENSIONS_XXF86DGA_H && HAVE_X11_EXTENSIONS_XF86DGAPROTO_H) \
55   || (HAVE_X11_EXTENSIONS_XF86DGA_H && HAVE_X11_EXTENSIONS_XF86DGASTR_H)
56 #  define XFreeXDGA
57 # endif
58
59 # if HAVE_X11_EXTENSIONS_XF86MISC_H && HAVE_X11_EXTENSIONS_XF86MSCSTR_H
60 #  define XF86MISC
61 # endif
62
63 # if HAVE_X11_EXTENSIONS_XINPUT_H
64 #  define XINPUT
65 # endif
66
67 # if HAVE_X11_EXTENSIONS_XRENDER_H
68 #  define XRENDER
69 # endif
70
71 # if HAVE_X11_EXTENSIONS_XCOMPOSITE_H
72 #  define COMPOSITE
73 # endif
74
75 # if HAVE_X11_EXTENSIONS_XINERAMA_H
76 #  define PANORAMIX
77 # endif
78
79 # if HAVE_X11_EXTENSIONS_DMXEXT_H
80 #  define DMX
81 # endif
82
83 #endif
84
85 #include <X11/Xlib.h>
86 #include <X11/Xutil.h>
87 #ifdef MULTIBUFFER
88 #include <X11/extensions/multibuf.h>
89 #endif
90 #include <X11/extensions/XTest.h>
91 #include <X11/extensions/sync.h>
92 #include <X11/Xproto.h>
93 #include <X11/extensions/Xdbe.h>
94 #include <X11/extensions/record.h>
95 #include <X11/extensions/shape.h>
96 #ifdef MITSHM
97 #include <X11/extensions/XShm.h>
98 #endif
99 #ifdef XKB
100 #include <X11/extensions/XKB.h>
101 #include <X11/XKBlib.h>
102 #endif
103 #ifdef XF86VIDMODE
104 #include <X11/extensions/xf86vmode.h>
105 # if HAVE_X11_EXTENSIONS_XF86VMPROTO_H /* xf86vidmodeproto 2.2.99.1 & later */
106 #  include <X11/extensions/xf86vmproto.h>
107 # else
108 #  include <X11/extensions/xf86vmstr.h>
109 # endif
110 #endif
111 #ifdef XFreeXDGA
112 # if HAVE_X11_EXTENSIONS_XXF86DGA_H && HAVE_X11_EXTENSIONS_XF86DGAPROTO_H
113 #  include <X11/extensions/Xxf86dga.h>
114 #  include <X11/extensions/xf86dgaproto.h>
115 # else
116 #  include <X11/extensions/xf86dga.h>
117 #  include <X11/extensions/xf86dgastr.h>
118 # endif
119 #endif
120 #ifdef XF86MISC
121 #include <X11/extensions/xf86misc.h>
122 #include <X11/extensions/xf86mscstr.h>
123 #endif
124 #ifdef XINPUT
125 #include <X11/extensions/XInput.h>
126 #endif
127 #ifdef XRENDER
128 #include <X11/extensions/Xrender.h>
129 #endif
130 #ifdef COMPOSITE
131 #include <X11/extensions/Xcomposite.h>
132 #endif
133 #ifdef PANORAMIX
134 #include <X11/extensions/Xinerama.h>
135 #endif
136 #ifdef DMX
137 #include <X11/extensions/dmxext.h>
138 #endif
139 #include <X11/Xos.h>
140 #include <stdio.h>
141 #include <stdlib.h>
142
143 /* Turn a NULL pointer string into an empty string */
144 #define NULLSTR(x) (((x)!=NULL)?(x):(""))
145
146 static char *ProgramName;
147 static Bool queryExtensions = False;
148
149 static int
150 silent_errors(Display *dpy, XErrorEvent *ev)
151 {
152     return 0;
153 }
154
155 static int (*old_handler)(Display *, XErrorEvent *) = NULL;
156
157 static int print_event_mask(char *buf, int lastcol, int indent, long mask);
158
159 static int StrCmp(const void *a, const  void *b)
160 {
161     return strcmp(*(char **)a, *(char **)b);
162 }
163
164 static void
165 print_extension_info(Display *dpy)
166 {
167     int n = 0;
168     char **extlist = XListExtensions (dpy, &n);
169
170     printf ("number of extensions:    %d\n", n);
171
172     if (extlist) {
173         register int i;
174         int opcode, event, error;
175
176         qsort(extlist, n, sizeof(char *), StrCmp);
177         for (i = 0; i < n; i++) {
178             if (!queryExtensions) {
179                 printf ("    %s\n", extlist[i]);
180                 continue;
181             }
182             XQueryExtension(dpy, extlist[i], &opcode, &event, &error);
183             printf ("    %s  (opcode: %d", extlist[i], opcode);
184             if (event)
185                 printf (", base event: %d", event);
186             if (error)
187                 printf (", base error: %d", error);
188             printf(")\n");
189         }
190         /* do not free, Xlib can depend on contents being unaltered */
191         /* XFreeExtensionList (extlist); */
192     }
193 }
194
195 static void
196 print_display_info(Display *dpy)
197 {
198     char dummybuf[40];
199     char *cp;
200     int minkeycode, maxkeycode;
201     int i, n;
202     long req_size;
203     XPixmapFormatValues *pmf;
204     Window focuswin;
205     int focusrevert;
206
207     printf ("name of display:    %s\n", DisplayString (dpy));
208     printf ("version number:    %d.%d\n",
209             ProtocolVersion (dpy), ProtocolRevision (dpy));
210     printf ("vendor string:    %s\n", ServerVendor (dpy));
211     printf ("vendor release number:    %d\n", VendorRelease (dpy));
212
213     if (strstr(ServerVendor (dpy), "XFree86")) {
214         int vendrel = VendorRelease(dpy);
215
216         printf("XFree86 version: ");
217         if (vendrel < 336) {
218             /*
219              * vendrel was set incorrectly for 3.3.4 and 3.3.5, so handle
220              * those cases here.
221              */
222             printf("%d.%d.%d", vendrel / 100,
223                               (vendrel / 10) % 10,
224                                vendrel       % 10);
225         } else if (vendrel < 3900) {
226             /* 3.3.x versions, other than the exceptions handled above */
227             printf("%d.%d", vendrel / 1000,
228                            (vendrel /  100) % 10);
229             if (((vendrel / 10) % 10) || (vendrel % 10)) {
230                 printf(".%d", (vendrel / 10) % 10);
231                 if (vendrel % 10) {
232                     printf(".%d", vendrel % 10);
233                 }
234             }
235         } else if (vendrel < 40000000) {
236             /* 4.0.x versions */
237             printf("%d.%d", vendrel / 1000,
238                            (vendrel /   10) % 10);
239             if (vendrel % 10) {
240                 printf(".%d", vendrel % 10);
241             }
242         } else {
243             /* post-4.0.x */
244             printf("%d.%d.%d", vendrel / 10000000,
245                               (vendrel /   100000) % 100,
246                               (vendrel /     1000) % 100);
247             if (vendrel % 1000) {
248                 printf(".%d", vendrel % 1000);
249             }
250         }
251         printf("\n");
252     }
253
254     if (strstr(ServerVendor (dpy), "X.Org")) {
255         int vendrel = VendorRelease(dpy);
256
257         printf("X.Org version: ");
258         printf("%d.%d.%d", vendrel / 10000000,
259                (vendrel /   100000) % 100,
260                (vendrel /     1000) % 100);
261         if (vendrel % 1000)
262             printf(".%d", vendrel % 1000);
263         printf("\n");
264     }
265
266     if (strstr(ServerVendor (dpy), "DMX")) {
267         int vendrel = VendorRelease(dpy);
268         int major, minor, year, month, day;
269
270         major    = vendrel / 100000000;
271         vendrel -= major   * 100000000;
272         minor    = vendrel /   1000000;
273         vendrel -= minor   *   1000000;
274         year     = vendrel /     10000;
275         vendrel -= year    *     10000;
276         month    = vendrel /       100;
277         vendrel -= month   *       100;
278         day      = vendrel;
279
280                                 /* Add other epoch tests here */
281         if (major > 0 && minor > 0) year += 2000;
282
283                                 /* Do some sanity tests in case there is
284                                  * another server with the same vendor
285                                  * string.  That server could easily use
286                                  * values < 100000000, which would have
287                                  * the effect of keeping our major
288                                  * number 0. */
289         if (major > 0 && major <= 20
290             && minor >= 0 && minor <= 99
291             && year >= 2000
292             && month >= 1 && month <= 12
293             && day >= 1 && day <= 31)
294             printf("DMX version: %d.%d.%04d%02d%02d\n",
295                    major, minor, year, month, day);
296     }
297
298     req_size = XExtendedMaxRequestSize (dpy);
299     if (!req_size) req_size = XMaxRequestSize (dpy);
300     printf ("maximum request size:  %ld bytes\n", req_size * 4);
301     printf ("motion buffer size:  %ld\n", XDisplayMotionBufferSize (dpy));
302
303     switch (BitmapBitOrder (dpy)) {
304       case LSBFirst:    cp = "LSBFirst"; break;
305       case MSBFirst:    cp = "MSBFirst"; break;
306       default:    
307         sprintf (dummybuf, "unknown order %d", BitmapBitOrder (dpy));
308         cp = dummybuf;
309         break;
310     }
311     printf ("bitmap unit, bit order, padding:    %d, %s, %d\n",
312             BitmapUnit (dpy), cp, BitmapPad (dpy));
313
314     switch (ImageByteOrder (dpy)) {
315       case LSBFirst:    cp = "LSBFirst"; break;
316       case MSBFirst:    cp = "MSBFirst"; break;
317       default:    
318         sprintf (dummybuf, "unknown order %d", ImageByteOrder (dpy));
319         cp = dummybuf;
320         break;
321     }
322     printf ("image byte order:    %s\n", cp);
323
324     pmf = XListPixmapFormats (dpy, &n);
325     printf ("number of supported pixmap formats:    %d\n", n);
326     if (pmf) {
327         printf ("supported pixmap formats:\n");
328         for (i = 0; i < n; i++) {
329             printf ("    depth %d, bits_per_pixel %d, scanline_pad %d\n",
330                     pmf[i].depth, pmf[i].bits_per_pixel, pmf[i].scanline_pad);
331         }
332         XFree ((char *) pmf);
333     }
334
335
336     /*
337      * when we get interfaces to the PixmapFormat stuff, insert code here
338      */
339
340     XDisplayKeycodes (dpy, &minkeycode, &maxkeycode);
341     printf ("keycode range:    minimum %d, maximum %d\n",
342             minkeycode, maxkeycode);
343
344     XGetInputFocus (dpy, &focuswin, &focusrevert);
345     printf ("focus:  ");
346     switch (focuswin) {
347       case PointerRoot:
348         printf ("PointerRoot\n");
349         break;
350       case None:
351         printf ("None\n");
352         break;
353       default:
354         printf("window 0x%lx, revert to ", focuswin);
355         switch (focusrevert) {
356           case RevertToParent:
357             printf ("Parent\n");
358             break;
359           case RevertToNone:
360             printf ("None\n");
361             break;
362           case RevertToPointerRoot:
363             printf ("PointerRoot\n");
364             break;
365           default:                      /* should not happen */
366             printf ("%d\n", focusrevert);
367             break;
368         }
369         break;
370     }
371
372     print_extension_info (dpy);
373
374     printf ("default screen number:    %d\n", DefaultScreen (dpy));
375     printf ("number of screens:    %d\n", ScreenCount (dpy));
376 }
377
378 static void
379 print_visual_info(XVisualInfo *vip)
380 {
381     char errorbuf[40];                  /* for sprintfing into */
382     char *class = NULL;                 /* for printing */
383
384     switch (vip->class) {
385       case StaticGray:    class = "StaticGray"; break;
386       case GrayScale:    class = "GrayScale"; break;
387       case StaticColor:    class = "StaticColor"; break;
388       case PseudoColor:    class = "PseudoColor"; break;
389       case TrueColor:    class = "TrueColor"; break;
390       case DirectColor:    class = "DirectColor"; break;
391       default:    
392         sprintf (errorbuf, "unknown class %d", vip->class);
393         class = errorbuf;
394         break;
395     }
396
397     printf ("  visual:\n");
398     printf ("    visual id:    0x%lx\n", vip->visualid);
399     printf ("    class:    %s\n", class);
400     printf ("    depth:    %d plane%s\n", vip->depth, 
401             vip->depth == 1 ? "" : "s");
402     if (vip->class == TrueColor || vip->class == DirectColor)
403         printf ("    available colormap entries:    %d per subfield\n",
404                 vip->colormap_size);
405     else
406         printf ("    available colormap entries:    %d\n",
407                 vip->colormap_size);
408     printf ("    red, green, blue masks:    0x%lx, 0x%lx, 0x%lx\n",
409             vip->red_mask, vip->green_mask, vip->blue_mask);
410     printf ("    significant bits in color specification:    %d bits\n",
411             vip->bits_per_rgb);
412 }
413
414 /* xc/programs/twm/twm.c has a copy of |hasExtension()|, please
415  * keep both versions in sync... */
416 static
417 Bool hasExtension(Display *dpy, char *extname)
418 {
419   int    num_extensions,
420          i;
421   char **extensions;
422   extensions = XListExtensions(dpy, &num_extensions);
423   for (i = 0; i < num_extensions &&
424          (strcmp(extensions[i], extname) != 0); i++);
425   XFreeExtensionList(extensions);
426   return i != num_extensions;
427 }
428
429 static void
430 print_screen_info(Display *dpy, int scr)
431 {
432     Screen *s = ScreenOfDisplay (dpy, scr);  /* opaque structure */
433     XVisualInfo viproto;                /* fill in for getting info */
434     XVisualInfo *vip;                   /* returned info */
435     int nvi;                            /* number of elements returned */
436     int i;                              /* temp variable: iterator */
437     char eventbuf[80];                  /* want 79 chars per line + nul */
438     static char *yes = "YES", *no = "NO", *when = "WHEN MAPPED";
439     double xres, yres;
440     int ndepths = 0, *depths = NULL;
441     unsigned int width, height;
442
443     /*
444      * there are 2.54 centimeters to an inch; so there are 25.4 millimeters.
445      *
446      *     dpi = N pixels / (M millimeters / (25.4 millimeters / 1 inch))
447      *         = N pixels / (M inch / 25.4)
448      *         = N * 25.4 pixels / M inch
449      */
450
451     xres = ((((double) DisplayWidth(dpy,scr)) * 25.4) / 
452             ((double) DisplayWidthMM(dpy,scr)));
453     yres = ((((double) DisplayHeight(dpy,scr)) * 25.4) / 
454             ((double) DisplayHeightMM(dpy,scr)));
455
456     printf ("\n");
457     printf ("screen #%d:\n", scr);
458     printf ("  dimensions:    %dx%d pixels (%dx%d millimeters)\n",
459             XDisplayWidth (dpy, scr),  XDisplayHeight (dpy, scr),
460             XDisplayWidthMM(dpy, scr), XDisplayHeightMM (dpy, scr));
461     printf ("  resolution:    %dx%d dots per inch\n", 
462             (int) (xres + 0.5), (int) (yres + 0.5));
463     depths = XListDepths (dpy, scr, &ndepths);
464     if (!depths) ndepths = 0;
465     printf ("  depths (%d):    ", ndepths);
466     for (i = 0; i < ndepths; i++) {
467         printf ("%d", depths[i]);
468         if (i < ndepths - 1) { 
469             putchar (',');
470             putchar (' ');
471         }
472     }
473     putchar ('\n');
474     if (depths) XFree ((char *) depths);
475     printf ("  root window id:    0x%lx\n", RootWindow (dpy, scr));
476     printf ("  depth of root window:    %d plane%s\n",
477             DisplayPlanes (dpy, scr),
478             DisplayPlanes (dpy, scr) == 1 ? "" : "s");
479     printf ("  number of colormaps:    minimum %d, maximum %d\n",
480             MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
481     printf ("  default colormap:    0x%lx\n", DefaultColormap (dpy, scr));
482     printf ("  default number of colormap cells:    %d\n",
483             DisplayCells (dpy, scr));
484     printf ("  preallocated pixels:    black %ld, white %ld\n",
485             BlackPixel (dpy, scr), WhitePixel (dpy, scr));
486     printf ("  options:    backing-store %s, save-unders %s\n",
487             (DoesBackingStore (s) == NotUseful) ? no :
488             ((DoesBackingStore (s) == Always) ? yes : when),
489             DoesSaveUnders (s) ? yes : no);
490     XQueryBestSize (dpy, CursorShape, RootWindow (dpy, scr), 65535, 65535,
491                     &width, &height);
492     if (width == 65535 && height == 65535)
493         printf ("  largest cursor:    unlimited\n");
494     else
495         printf ("  largest cursor:    %dx%d\n", width, height);
496     printf ("  current input event mask:    0x%lx\n", EventMaskOfScreen (s));
497     (void) print_event_mask (eventbuf, 79, 4, EventMaskOfScreen (s));
498
499     nvi = 0;
500     viproto.screen = scr;
501     vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi);
502     printf ("  number of visuals:    %d\n", nvi);
503     printf ("  default visual id:  0x%lx\n", 
504             XVisualIDFromVisual (DefaultVisual (dpy, scr)));
505     for (i = 0; i < nvi; i++) {
506         print_visual_info (vip+i);
507     }
508     if (vip) XFree ((char *) vip);
509 }
510
511 /*
512  * The following routine prints out an event mask, wrapping events at nice
513  * boundaries.
514  */
515
516 #define MASK_NAME_WIDTH 25
517
518 static struct _event_table {
519     char *name;
520     long value;
521 } event_table[] = {
522     { "KeyPressMask             ", KeyPressMask },
523     { "KeyReleaseMask           ", KeyReleaseMask },
524     { "ButtonPressMask          ", ButtonPressMask },
525     { "ButtonReleaseMask        ", ButtonReleaseMask },
526     { "EnterWindowMask          ", EnterWindowMask },
527     { "LeaveWindowMask          ", LeaveWindowMask },
528     { "PointerMotionMask        ", PointerMotionMask },
529     { "PointerMotionHintMask    ", PointerMotionHintMask },
530     { "Button1MotionMask        ", Button1MotionMask },
531     { "Button2MotionMask        ", Button2MotionMask },
532     { "Button3MotionMask        ", Button3MotionMask },
533     { "Button4MotionMask        ", Button4MotionMask },
534     { "Button5MotionMask        ", Button5MotionMask },
535     { "ButtonMotionMask         ", ButtonMotionMask },
536     { "KeymapStateMask          ", KeymapStateMask },
537     { "ExposureMask             ", ExposureMask },
538     { "VisibilityChangeMask     ", VisibilityChangeMask },
539     { "StructureNotifyMask      ", StructureNotifyMask },
540     { "ResizeRedirectMask       ", ResizeRedirectMask },
541     { "SubstructureNotifyMask   ", SubstructureNotifyMask },
542     { "SubstructureRedirectMask ", SubstructureRedirectMask },
543     { "FocusChangeMask          ", FocusChangeMask },
544     { "PropertyChangeMask       ", PropertyChangeMask },
545     { "ColormapChangeMask       ", ColormapChangeMask },
546     { "OwnerGrabButtonMask      ", OwnerGrabButtonMask },
547     { NULL, 0 }};
548
549 static int                      
550 print_event_mask(char *buf,     /* string to write into */
551                  int lastcol,   /* strlen(buf)+1 */
552                  int indent,    /* amount by which to indent */
553                  long mask)     /* event mask */
554 {
555     struct _event_table *etp;
556     int len;
557     int bitsfound = 0;
558
559     buf[0] = buf[lastcol] = '\0';       /* just in case */
560
561 #define INDENT() { register int i; len = indent; \
562                    for (i = 0; i < indent; i++) buf[i] = ' '; }
563
564     INDENT ();
565
566     for (etp = event_table; etp->name; etp++) {
567         if (mask & etp->value) {
568             if (len + MASK_NAME_WIDTH > lastcol) {
569                 puts (buf);
570                 INDENT ();
571             }
572             strcpy (buf+len, etp->name);
573             len += MASK_NAME_WIDTH;
574             bitsfound++;
575         }
576     }
577
578     if (bitsfound) puts (buf);
579
580 #undef INDENT
581
582     return (bitsfound);
583 }
584
585 static void
586 print_standard_extension_info(Display *dpy, char *extname, 
587                               int majorrev, int minorrev)
588 {
589     int opcode, event, error;
590
591     printf("%s version %d.%d ", extname, majorrev, minorrev);
592
593     XQueryExtension(dpy, extname, &opcode, &event, &error);
594     printf ("opcode: %d", opcode);
595     if (event)
596         printf (", base event: %d", event);
597     if (error)
598         printf (", base error: %d", error);
599     printf("\n");
600 }
601
602 #ifdef MULTIBUFFER
603 static int
604 print_multibuf_info(Display *dpy, char *extname)
605 {
606     int i, j;                   /* temp variable: iterator */
607     int nmono, nstereo;         /* count */
608     XmbufBufferInfo *mono_info = NULL, *stereo_info = NULL; /* arrays */
609     static char *fmt = 
610         "    visual id, max buffers, depth:    0x%lx, %d, %d\n";
611     int scr = 0;
612     int majorrev, minorrev;
613
614     if (!XmbufGetVersion(dpy, &majorrev, &minorrev))
615         return 0;
616
617     print_standard_extension_info(dpy, extname, majorrev, minorrev);
618
619     for (i = 0; i < ScreenCount (dpy); i++)
620     {
621         if (!XmbufGetScreenInfo (dpy, RootWindow(dpy, scr), &nmono, &mono_info,
622                                  &nstereo, &stereo_info)) {
623             fprintf (stderr,
624                      "%s:  unable to get multibuffer info for screen %d\n",
625                      ProgramName, scr);
626         } else {
627             printf ("  screen %d number of mono multibuffer types:    %d\n", i, nmono);
628             for (j = 0; j < nmono; j++) {
629                 printf (fmt, mono_info[j].visualid, mono_info[j].max_buffers,
630                         mono_info[j].depth);
631             }
632             printf ("  number of stereo multibuffer types:    %d\n", nstereo);
633             for (j = 0; j < nstereo; j++) {
634                 printf (fmt, stereo_info[j].visualid,
635                         stereo_info[j].max_buffers, stereo_info[j].depth);
636             }
637             if (mono_info) XFree ((char *) mono_info);
638             if (stereo_info) XFree ((char *) stereo_info);
639         }
640     }
641     return 1;
642 } /* end print_multibuf_info */
643 #endif
644
645 static int
646 print_xtest_info(Display *dpy, char *extname)
647 {
648     int majorrev, minorrev, foo;
649
650     if (!XTestQueryExtension(dpy, &foo, &foo, &majorrev, &minorrev))
651         return 0;
652     print_standard_extension_info(dpy, extname, majorrev, minorrev);
653     return 1;
654 }
655
656 static int
657 print_sync_info(Display *dpy, char *extname)
658 {
659     int majorrev, minorrev;
660     XSyncSystemCounter *syscounters;
661     int ncounters, i;
662
663     if (!XSyncInitialize(dpy, &majorrev, &minorrev))
664         return 0;
665     print_standard_extension_info(dpy, extname, majorrev, minorrev);
666
667     syscounters = XSyncListSystemCounters(dpy, &ncounters);
668     printf("  system counters: %d\n", ncounters);
669     for (i = 0; i < ncounters; i++)
670     {
671         printf("    %s  id: 0x%08x  resolution_lo: %d  resolution_hi: %d\n",
672                syscounters[i].name, (unsigned int)syscounters[i].counter,
673                XSyncValueLow32(syscounters[i].resolution),
674                XSyncValueHigh32(syscounters[i].resolution));
675     }
676     XSyncFreeSystemCounterList(syscounters);
677     return 1;
678 }
679
680 static int
681 print_shape_info(Display *dpy, char *extname)
682 {
683     int majorrev, minorrev;
684
685     if (!XShapeQueryVersion(dpy, &majorrev, &minorrev))
686         return 0;
687     print_standard_extension_info(dpy, extname, majorrev, minorrev);
688     return 1;
689 }
690
691 #ifdef XFreeXDGA
692 static int
693 print_dga_info(Display *dpy, char *extname)
694 {
695     unsigned int offset;
696     int majorrev, minorrev, width, bank, ram, flags;
697
698     if (!XF86DGAQueryVersion(dpy, &majorrev, &minorrev))
699         return 0;
700     print_standard_extension_info(dpy, extname, majorrev, minorrev);
701
702     if (!XF86DGAQueryDirectVideo(dpy, DefaultScreen(dpy), &flags) 
703         || ! (flags & XF86DGADirectPresent) )
704     {
705         printf("  DGA not available on screen %d.\n", DefaultScreen(dpy));
706         return 1;
707     }
708
709     old_handler = XSetErrorHandler(silent_errors);
710
711     if (!XF86DGAGetVideoLL(dpy, DefaultScreen(dpy), &offset,
712                             &width, &bank, &ram))
713         return 0;
714     printf("  Base address = 0x%X, Width = %d, Bank size = %d,"
715            " RAM size = %dk\n", offset, width, bank, ram);
716
717     XSetErrorHandler(old_handler);
718
719     return 1;
720 }
721 #endif
722
723 #ifdef XF86VIDMODE
724 #define V_PHSYNC        0x001 
725 #define V_NHSYNC        0x002
726 #define V_PVSYNC        0x004
727 #define V_NVSYNC        0x008
728 #define V_INTERLACE     0x010 
729 #define V_DBLSCAN       0x020
730 #define V_CSYNC         0x040
731 #define V_PCSYNC        0x080
732 #define V_NCSYNC        0x100
733
734 static void
735 print_XF86VidMode_modeline(
736     unsigned int        dotclock,
737     unsigned short      hdisplay,
738     unsigned short      hsyncstart,
739     unsigned short      hsyncend,
740     unsigned short      htotal,
741     unsigned short      vdisplay,
742     unsigned short      vsyncstart,
743     unsigned short      vsyncend,
744     unsigned short      vtotal,
745     unsigned int        flags)
746 {
747     printf("    %6.2f   %4d %4d %4d %4d   %4d %4d %4d %4d ",
748            (float)dotclock/1000.0,
749            hdisplay, hsyncstart, hsyncend, htotal,
750            vdisplay, vsyncstart, vsyncend, vtotal);
751     if (flags & V_PHSYNC)    printf(" +hsync");
752     if (flags & V_NHSYNC)    printf(" -hsync");
753     if (flags & V_PVSYNC)    printf(" +vsync");
754     if (flags & V_NVSYNC)    printf(" -vsync");
755     if (flags & V_INTERLACE) printf(" interlace");
756     if (flags & V_CSYNC)     printf(" composite");
757     if (flags & V_PCSYNC)    printf(" +csync");
758     if (flags & V_NCSYNC)    printf(" -csync");
759     if (flags & V_DBLSCAN)   printf(" doublescan");
760     printf("\n");
761 }
762
763 static int
764 print_XF86VidMode_info(Display *dpy, char *extname)
765 {
766     int majorrev, minorrev, modecount, dotclock, i;
767     XF86VidModeMonitor monitor;
768     XF86VidModeModeLine modeline;
769     XF86VidModeModeInfo **modelines;
770
771     if (!XF86VidModeQueryVersion(dpy, &majorrev, &minorrev))
772         return 0;
773     print_standard_extension_info(dpy, extname, majorrev, minorrev);
774
775     if (XF86VidModeGetMonitor(dpy, DefaultScreen(dpy), &monitor)) {
776         printf("  Monitor Information:\n");
777         printf("    Vendor: %s, Model: %s\n",
778                monitor.vendor == NULL ? "" : monitor.vendor,
779                monitor.model == NULL ? "" : monitor.model);
780         printf("    Num hsync: %d, Num vsync: %d\n",
781                monitor.nhsync, monitor.nvsync);
782         for (i = 0; i < monitor.nhsync; i++) {
783             printf("    hsync range %d: %6.2f - %6.2f\n", i,
784                    monitor.hsync[i].lo, monitor.hsync[i].hi);
785         }
786         for (i = 0; i < monitor.nvsync; i++) {
787             printf("    vsync range %d: %6.2f - %6.2f\n", i,
788                    monitor.vsync[i].lo, monitor.vsync[i].hi);
789         }
790         XFree(monitor.vendor);
791         XFree(monitor.model);
792         XFree(monitor.hsync);
793         XFree(monitor.vsync);
794     } else {
795         printf("  Monitor Information not available\n");
796     }
797
798     if ((majorrev > 0) || (majorrev == 0 && minorrev > 5)) {
799       if (XF86VidModeGetAllModeLines(dpy, DefaultScreen(dpy), &modecount,
800                                      &modelines)) {
801           printf("  Available Video Mode Settings:\n");
802           printf("     Clock   Hdsp Hbeg Hend Httl   Vdsp Vbeg Vend Vttl  Flags\n");
803           for (i = 0; i < modecount; i++) {
804               print_XF86VidMode_modeline
805                   (modelines[i]->dotclock, modelines[i]->hdisplay,
806                    modelines[i]->hsyncstart, modelines[i]->hsyncend,
807                    modelines[i]->htotal, modelines[i]->vdisplay,
808                    modelines[i]->vsyncstart, modelines[i]->vsyncend,
809                    modelines[i]->vtotal, modelines[i]->flags);
810           }
811           XFree(modelines);
812       } else {
813           printf("  Available Video Mode Settings not available\n");
814       }
815
816       if (XF86VidModeGetModeLine(dpy, DefaultScreen(dpy),
817                                  &dotclock, &modeline)) {
818           printf("  Current Video Mode Setting:\n");
819           print_XF86VidMode_modeline(dotclock,
820                                      modeline.hdisplay, modeline.hsyncstart,
821                                      modeline.hsyncend, modeline.htotal,
822                                      modeline.vdisplay, modeline.vsyncstart,
823                                      modeline.vsyncend, modeline.vtotal,
824                                      modeline.flags);
825       } else {
826           printf("  Current Video Mode Setting not available\n");
827       }
828     }
829
830     return 1;
831 }
832 #endif
833
834 #ifdef XF86MISC
835
836 static char *kbdtable[] = { "Unknown", "84-key", "101-key", "Other", "Xqueue" };
837 static char *msetable[] = { "None", "Microsoft", "MouseSystems", "MMSeries",
838                      "Logitech", "BusMouse", "Mouseman", "PS/2", "MMHitTab",
839                      "GlidePoint", "IntelliMouse", "ThinkingMouse",
840                      "IMPS/2", "ThinkingMousePS/2", "MouseManPlusPS/2",
841                      "GlidePointPS/2", "NetMousePS/2", "NetScrollPS/2",
842                      "SysMouse", "Auto" };
843 static char *flgtable[] = { "None", "ClearDTR", "ClearRTS",
844                      "ClearDTR and ClearRTS" };
845
846 static int
847 print_XF86Misc_info(Display *dpy, char *extname)
848 {
849     int majorrev, minorrev;
850     XF86MiscMouseSettings mouseinfo;
851     XF86MiscKbdSettings kbdinfo;
852
853     if (!XF86MiscQueryVersion(dpy, &majorrev, &minorrev))
854         return 0;
855     print_standard_extension_info(dpy, extname, majorrev, minorrev);
856
857     old_handler = XSetErrorHandler(silent_errors);
858
859     if ((majorrev > 0) || (majorrev == 0 && minorrev > 0)) {
860       if (!XF86MiscGetKbdSettings(dpy, &kbdinfo))
861         return 0;
862       printf("  Keyboard Settings-    Type: %s, Rate: %d, Delay: %d, ServerNumLock: %s\n",
863         kbdtable[kbdinfo.type], kbdinfo.rate, kbdinfo.delay,
864         (kbdinfo.servnumlock? "yes": "no"));
865
866       if (!XF86MiscGetMouseSettings(dpy, &mouseinfo))
867         return 0;
868       printf("  Mouse Settings-       Device: %s, Type: ",
869         strlen(mouseinfo.device) == 0 ? "None": mouseinfo.device);
870       XFree(mouseinfo.device);
871       if (mouseinfo.type == MTYPE_XQUEUE)
872         printf("Xqueue\n");
873       else if (mouseinfo.type == MTYPE_OSMOUSE)
874         printf("OSMouse\n");
875       else if (mouseinfo.type <= MTYPE_AUTOMOUSE)
876         printf("%s\n", msetable[mouseinfo.type+1]);
877       else
878         printf("Unknown\n");
879       printf("                        BaudRate: %d, SampleRate: %d, Resolution: %d\n",
880         mouseinfo.baudrate, mouseinfo.samplerate, mouseinfo.resolution);
881       printf("                        Emulate3Buttons: %s, Emulate3Timeout: %d ms\n",
882         mouseinfo.emulate3buttons? "yes": "no", mouseinfo.emulate3timeout);
883       printf("                        ChordMiddle: %s, Flags: %s\n",
884         mouseinfo.chordmiddle? "yes": "no",
885         flgtable[(mouseinfo.flags & MF_CLEAR_DTR? 1: 0)
886                 +(mouseinfo.flags & MF_CLEAR_RTS? 1: 0)] );
887       printf("                        Buttons: %d\n", mouseinfo.buttons);
888     }
889
890     XSetErrorHandler(old_handler);
891
892     return 1;
893 }
894 #endif
895
896 #ifdef MITSHM
897 static int
898 print_mitshm_info(Display *dpy, char *extname)
899 {
900     int majorrev, minorrev;
901     Bool sharedPixmaps;
902
903     if (!XShmQueryVersion(dpy, &majorrev, &minorrev, &sharedPixmaps))
904         return 0;
905     print_standard_extension_info(dpy, extname, majorrev, minorrev);
906     printf("  shared pixmaps: ");
907     if (sharedPixmaps)
908     {
909         int format = XShmPixmapFormat(dpy);
910         printf("yes, format: %d\n", format);
911     }
912     else
913     {
914         printf("no\n");
915     }
916     return 1;
917 }
918 #endif /* MITSHM */
919
920 #ifdef XKB
921 static int
922 print_xkb_info(Display *dpy, char *extname)
923 {
924     int opcode, eventbase, errorbase, majorrev, minorrev;
925
926     if (!XkbQueryExtension(dpy, &opcode, &eventbase, &errorbase,
927                            &majorrev, &minorrev)) {
928         return 0;
929     }
930     printf("%s version %d.%d ", extname, majorrev, minorrev);
931
932     printf ("opcode: %d", opcode);
933     if (eventbase)
934         printf (", base event: %d", eventbase);
935     if (errorbase)
936         printf (", base error: %d", errorbase);
937     printf("\n");
938
939     return 1;
940 }
941 #endif
942
943 static int
944 print_dbe_info(Display *dpy, char *extname)
945 {
946     int majorrev, minorrev;
947     XdbeScreenVisualInfo *svi;
948     int numscreens = 0;
949     int iscrn, ivis;
950
951     if (!XdbeQueryExtension(dpy, &majorrev, &minorrev))
952         return 0;
953
954     print_standard_extension_info(dpy, extname, majorrev, minorrev);
955     svi = XdbeGetVisualInfo(dpy, (Drawable *)NULL, &numscreens);
956     for (iscrn = 0; iscrn < numscreens; iscrn++)
957     {
958         printf("  Double-buffered visuals on screen %d\n", iscrn);
959         for (ivis = 0; ivis < svi[iscrn].count; ivis++)
960         {
961             printf("    visual id 0x%lx  depth %d  perflevel %d\n",
962                    svi[iscrn].visinfo[ivis].visual,
963                    svi[iscrn].visinfo[ivis].depth,
964                    svi[iscrn].visinfo[ivis].perflevel);
965         }
966     }
967     XdbeFreeVisualInfo(svi);
968     return 1;
969 }
970
971 static int
972 print_record_info(Display *dpy, char *extname)
973 {
974     int majorrev, minorrev;
975
976     if (!XRecordQueryVersion(dpy, &majorrev, &minorrev))
977         return 0;
978     print_standard_extension_info(dpy, extname, majorrev, minorrev);
979     return 1;
980 }
981
982 #ifdef XINPUT
983 static int
984 print_xinput_info(Display *dpy, char *extname)
985 {
986   int           loop, num_extensions, num_devices;
987   char          **extensions;
988   XDeviceInfo   *devices;
989   XExtensionVersion *ext;
990
991   ext = XGetExtensionVersion(dpy, extname);
992   
993   if (!ext || (ext == (XExtensionVersion*) NoSuchExtension))
994       return 0;
995
996   print_standard_extension_info(dpy, extname, ext->major_version,
997                                 ext->minor_version);
998   XFree(ext);
999
1000   extensions = XListExtensions(dpy, &num_extensions);
1001   for (loop = 0; loop < num_extensions &&
1002          (strcmp(extensions[loop], extname) != 0); loop++);
1003   XFreeExtensionList(extensions);
1004   if (loop != num_extensions) {
1005       printf("  Extended devices :\n");
1006       devices = XListInputDevices(dpy, &num_devices);
1007       for(loop=0; loop<num_devices; loop++) {
1008           printf("      \"%s\"  [", devices[loop].name ? devices[loop].name : "<noname>");
1009           switch(devices[loop].use) {
1010           case IsXPointer:
1011               printf("XPointer]\n");
1012               break;
1013           case IsXKeyboard:
1014               printf("XKeyboard]\n");
1015               break;
1016           case IsXExtensionDevice:
1017               printf("XExtensionDevice]\n");
1018               break;
1019 #ifdef IsXExtensionKeyboard
1020           case IsXExtensionKeyboard:
1021               printf("XExtensionKeyboard]\n");
1022               break;
1023 #endif
1024 #ifdef IsXExtensionPointer
1025           case IsXExtensionPointer:
1026               printf("XExtensionPointer]\n");
1027               break;
1028 #endif
1029           default:
1030               printf("invalid value]\n");
1031               break;
1032           }
1033         }
1034       XFreeDeviceList(devices);
1035       return 1;
1036     }
1037   else
1038       return 0;
1039 }
1040 #endif
1041
1042 #ifdef XRENDER
1043 static int
1044 print_xrender_info(Display *dpy, char *extname)
1045 {
1046   int               loop, num_extensions;
1047   char              **extensions;
1048   XRenderPictFormat *pictform;
1049   int               count;
1050   int               major, minor;
1051   int               i, j;
1052   XVisualInfo       viproto;            /* fill in for getting info */
1053   XVisualInfo       *vip;               /* retured info */
1054   int               nvi;                /* number of elements returned */
1055   int               ndepths = 0, *depths = NULL;
1056 #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
1057   XFilters          *filters;
1058   int               f;
1059 #endif
1060
1061   if (!XRenderQueryVersion (dpy, &major, &minor))
1062     return 0;
1063   
1064   print_standard_extension_info(dpy, extname, major, minor);
1065
1066   extensions = XListExtensions(dpy, &num_extensions);
1067   for (loop = 0; loop < num_extensions &&
1068          (strcmp(extensions[loop], extname) != 0); loop++);
1069   XFreeExtensionList(extensions);
1070   if (loop != num_extensions) {
1071     printf ("  Render formats :\n");
1072     for (count = 0; (pictform = XRenderFindFormat (dpy, 0, NULL, count)); count++)
1073     {
1074       printf  ("  pict format:\n");
1075       printf  ("\tformat id:    0x%lx\n", pictform->id);
1076       printf  ("\ttype:         %s\n",
1077              pictform->type == PictTypeIndexed ? "Indexed" : "Direct");
1078       printf  ("\tdepth:        %d\n", pictform->depth);
1079       if (pictform->type == PictTypeDirect) {
1080         printf("\talpha:        %2d mask 0x%x\n", pictform->direct.alpha, pictform->direct.alphaMask);
1081         printf("\tred:          %2d mask 0x%x\n", pictform->direct.red, pictform->direct.redMask);
1082         printf("\tgreen:        %2d mask 0x%x\n", pictform->direct.green, pictform->direct.greenMask);
1083         printf("\tblue:         %2d mask 0x%x\n", pictform->direct.blue, pictform->direct.blueMask);
1084       }
1085       else
1086         printf("\tcolormap      0x%lx\n", pictform->colormap);
1087     }
1088     printf ("  Screen formats :\n");
1089     for (i = 0; i < ScreenCount (dpy); i++) {
1090       nvi = 0;
1091       viproto.screen = i;
1092       vip = XGetVisualInfo (dpy, VisualScreenMask, &viproto, &nvi);
1093       printf ("    Screen %d", i);
1094 #if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
1095       switch (XRenderQuerySubpixelOrder (dpy, i)) {
1096       case SubPixelUnknown: printf (" (sub-pixel order Unknown)"); break;
1097       case SubPixelHorizontalRGB: printf (" (sub-pixel order Horizontal RGB)"); break;
1098       case SubPixelHorizontalBGR: printf (" (sub-pixel order Horizontal BGR)"); break;
1099       case SubPixelVerticalRGB: printf (" (sub-pixel order Vertical RGB)"); break;
1100       case SubPixelVerticalBGR: printf (" (sub-pixel order Vertical BGR)"); break;
1101       case SubPixelNone: printf (" (sub-pixel order None)"); break;
1102       }
1103       printf ("\n");
1104       filters = XRenderQueryFilters (dpy, RootWindow (dpy, i));
1105       if (filters)
1106       {
1107         printf ("      filters: ");
1108         for (f = 0; f < filters->nfilter; f++)
1109         {
1110           printf ("%s", filters->filter[f]);
1111           if (f < filters->nalias && filters->alias[f] != FilterAliasNone)
1112             printf ("(%s)", filters->filter[filters->alias[f]]);
1113           if (f < filters->nfilter - 1)
1114             printf (", ");
1115         }
1116         XFree (filters);
1117       }
1118 #endif
1119       printf ("\n");
1120       for (j = 0; j < nvi; j++)
1121       {
1122         printf  ("      visual format:\n");
1123         printf  ("        visual id:      0x%lx\n", vip[j].visualid);
1124         pictform = XRenderFindVisualFormat (dpy, vip[j].visual);
1125         if (pictform)
1126           printf("        pict format id: 0x%lx\n", pictform->id);
1127         else
1128           printf("        pict format id: None\n");
1129       }
1130       if (vip) XFree ((char *) vip);
1131       depths = XListDepths (dpy, i, &ndepths);
1132       if (!depths) ndepths = 0;
1133       for (j = 0; j < ndepths; j++)
1134       {
1135         XRenderPictFormat templ;
1136
1137         templ.depth = depths[j];
1138         printf  ("     depth formats:\n");
1139         printf  ("       depth           %d\n", depths[j]);
1140         for (count = 0; (pictform = XRenderFindFormat (dpy, PictFormatDepth, &templ, count)); count++)
1141           printf("       pict format id: 0x%lx\n", pictform->id);
1142       }
1143       if (depths) XFree (depths);
1144     }
1145     return 1;
1146   }
1147   else
1148     return 0;
1149 }
1150 #endif /* XRENDER */
1151
1152 #ifdef COMPOSITE
1153 static int
1154 print_composite_info(Display *dpy, char *extname)
1155 {
1156     int majorrev, minorrev, foo;
1157
1158     if (!XCompositeQueryExtension(dpy, &foo, &foo))
1159         return 0;
1160     if (!XCompositeQueryVersion(dpy, &majorrev, &minorrev))
1161         return 0;
1162     print_standard_extension_info(dpy, extname, majorrev, minorrev);
1163     return 1;
1164 }
1165 #endif
1166
1167 #ifdef PANORAMIX
1168
1169 static int
1170 print_xinerama_info(Display *dpy, char *extname)
1171 {
1172   int              majorrev, minorrev;
1173
1174   if (!XineramaQueryVersion (dpy, &majorrev, &minorrev))
1175     return 0;
1176   
1177   print_standard_extension_info(dpy, extname, majorrev, minorrev);
1178
1179   if (!XineramaIsActive(dpy)) {
1180     printf("  Xinerama is inactive.\n");
1181   } else {
1182     int i, count = 0; 
1183     XineramaScreenInfo *xineramaScreens = XineramaQueryScreens(dpy, &count);
1184     
1185     for (i = 0; i < count; i++) {
1186       XineramaScreenInfo *xs = &xineramaScreens[i];
1187       printf("  head #%d: %dx%d @ %d,%d\n", xs->screen_number, 
1188              xs->width, xs->height, xs->x_org, xs->y_org);
1189     }
1190     
1191     XFree(xineramaScreens);
1192   }
1193   
1194   return 1;
1195 }
1196
1197 #endif /* PANORAMIX */
1198
1199 #ifdef DMX
1200 static const char *core(DMXInputAttributes *iinfo)
1201 {
1202     if (iinfo->isCore)         return "core";
1203     else if (iinfo->sendsCore) return "extension (sends core)";
1204     else                       return "extension";
1205 }
1206
1207 static int print_dmx_info(Display *dpy, char *extname)
1208 {
1209     int                  event_base, error_base;
1210     int                  major_version, minor_version, patch_version;
1211     DMXScreenAttributes  sinfo;
1212     DMXInputAttributes   iinfo;
1213     int                  count;
1214     int                  i;
1215
1216     if (!DMXQueryExtension(dpy, &event_base, &error_base)
1217         || !DMXQueryVersion(dpy, &major_version, &minor_version,
1218                             &patch_version)) return 0;
1219     print_standard_extension_info(dpy, extname, major_version, minor_version);
1220     printf("  Version stamp: %d\n", patch_version);
1221
1222     if (!DMXGetScreenCount(dpy, &count)) return 1;
1223     printf("  Screen count: %d\n", count);
1224     for (i = 0; i < count; i++) {
1225         if (DMXGetScreenAttributes(dpy, i, &sinfo)) {
1226             printf("    %2d %s %ux%u+%d+%d %d @%dx%d\n",
1227                    i, sinfo.displayName,
1228                    sinfo.screenWindowWidth, sinfo.screenWindowHeight,
1229                    sinfo.screenWindowXoffset, sinfo.screenWindowYoffset,
1230                    sinfo.logicalScreen,
1231                    sinfo.rootWindowXorigin, sinfo.rootWindowYorigin);
1232         }
1233     }
1234
1235     if (major_version != 1
1236         || minor_version < 1
1237         || !DMXGetInputCount(dpy, &count))
1238         return 1;
1239
1240     printf("  Input count = %d\n", count);
1241     for (i = 0; i < count; i++) {
1242 #ifdef XINPUT
1243         Display *backend;
1244         char    *backendname = NULL;
1245 #endif
1246         if (DMXGetInputAttributes(dpy, i, &iinfo)) {
1247             switch (iinfo.inputType) {
1248             case DMXLocalInputType:
1249                 printf("    %2d local %s", i, core(&iinfo));
1250                 break;
1251             case DMXConsoleInputType:
1252                 printf("    %2d console %s %s", i, core(&iinfo),
1253                        iinfo.name);
1254                 break;
1255             case DMXBackendInputType:
1256 #ifdef XINPUT
1257                 if (iinfo.physicalId >= 0) {
1258                     if ((backend = XOpenDisplay(iinfo.name))) {
1259                         XExtensionVersion *ext
1260                             = XGetExtensionVersion(backend, INAME);
1261                         if (ext
1262                             && ext != (XExtensionVersion *)NoSuchExtension) {
1263                             
1264                             int         count, i;
1265                             XDeviceInfo *devInfo = XListInputDevices(backend,
1266                                                                      &count);
1267                             if (devInfo) {
1268                                 for (i = 0; i < count; i++) {
1269                                     if ((unsigned)iinfo.physicalId
1270                                         == devInfo[i].id
1271                                         && devInfo[i].name) {
1272                                         backendname = strdup(devInfo[i].name);
1273                                         break;
1274                                     }
1275                                 }
1276                                 XFreeDeviceList(devInfo);
1277                             }
1278                         }
1279                         XCloseDisplay(backend);
1280                     }
1281                 }
1282 #endif
1283                 printf("    %2d backend %s o%d/%s",i, core(&iinfo),
1284                        iinfo.physicalScreen, iinfo.name);
1285                 if (iinfo.physicalId >= 0) printf("/id%d", iinfo.physicalId);
1286 #ifdef XINPUT
1287                 if (backendname) {
1288                     printf("=%s", backendname);
1289                     free(backendname);
1290                 }
1291 #endif
1292                 break;
1293             }
1294         }
1295         printf("\n");
1296     }
1297     return 1;
1298 }
1299
1300 #endif /* DMX */
1301
1302 /* utilities to manage the list of recognized extensions */
1303
1304
1305 typedef int (*ExtensionPrintFunc)(
1306     Display *, char *
1307 );
1308
1309 typedef struct {
1310     char *extname;
1311     ExtensionPrintFunc printfunc;
1312     Bool printit;
1313 } ExtensionPrintInfo;
1314
1315 static ExtensionPrintInfo known_extensions[] =
1316 {
1317 #ifdef MITSHM
1318     {"MIT-SHM", print_mitshm_info, False},
1319 #endif /* MITSHM */
1320 #ifdef XKB
1321     {XkbName, print_xkb_info, False},
1322 #endif /* XKB */
1323 #ifdef MULTIBUFFER
1324     {MULTIBUFFER_PROTOCOL_NAME, print_multibuf_info, False},
1325 #endif
1326     {"SHAPE", print_shape_info, False},
1327     {SYNC_NAME, print_sync_info, False},
1328 #ifdef XFreeXDGA
1329     {XF86DGANAME, print_dga_info, False},
1330 #endif /* XFreeXDGA */
1331 #ifdef XF86VIDMODE
1332     {XF86VIDMODENAME, print_XF86VidMode_info, False},
1333 #endif /* XF86VIDMODE */
1334 #ifdef XF86MISC
1335     {XF86MISCNAME, print_XF86Misc_info, False},
1336 #endif /* XF86MISC */
1337     {XTestExtensionName, print_xtest_info, False},
1338     {"DOUBLE-BUFFER", print_dbe_info, False},
1339     {"RECORD", print_record_info, False},
1340 #ifdef XINPUT
1341     {INAME, print_xinput_info, False},
1342 #endif
1343 #ifdef XRENDER
1344     {RENDER_NAME, print_xrender_info, False},
1345 #endif
1346 #ifdef COMPOSITE
1347     {COMPOSITE_NAME, print_composite_info, False},
1348 #endif
1349 #ifdef PANORAMIX
1350     {"XINERAMA", print_xinerama_info, False},
1351 #endif
1352 #ifdef DMX
1353     {"DMX", print_dmx_info, False},
1354 #endif
1355     /* add new extensions here */
1356 };
1357
1358 static int num_known_extensions = sizeof known_extensions / sizeof known_extensions[0];
1359
1360 static void
1361 print_known_extensions(FILE *f)
1362 {
1363     int i, col;
1364     for (i = 0, col = 6; i < num_known_extensions; i++)
1365     {
1366         int extlen = strlen(known_extensions[i].extname) + 1;
1367         
1368         if ((col + extlen) > 79)
1369         {
1370                 col = 6;
1371                 fprintf(f, "\n     ");
1372         }
1373         fprintf(f, "%s ", known_extensions[i].extname);
1374         col += extlen;
1375     }
1376 }
1377
1378 static void
1379 mark_extension_for_printing(char *extname)
1380 {
1381     int i;
1382
1383     if (strcmp(extname, "all") == 0)
1384     {
1385         for (i = 0; i < num_known_extensions; i++)
1386             known_extensions[i].printit = True;
1387     }
1388     else
1389     {
1390         for (i = 0; i < num_known_extensions; i++)
1391         {
1392             if (strcmp(extname, known_extensions[i].extname) == 0)
1393             {
1394                 known_extensions[i].printit = True;
1395                 return;
1396             }
1397         }
1398         printf("%s extension not supported by %s\n", extname, ProgramName);
1399     }
1400 }
1401
1402 static void
1403 print_marked_extensions(Display *dpy)
1404 {
1405     int i;
1406     for (i = 0; i < num_known_extensions; i++)
1407     {
1408         if (known_extensions[i].printit)
1409         {
1410             printf("\n");
1411             if (! (*known_extensions[i].printfunc)(dpy,
1412                                         known_extensions[i].extname))
1413             {
1414                 printf("%s extension not supported by server\n",
1415                        known_extensions[i].extname);
1416             }
1417         }
1418     }
1419 }
1420
1421 static void 
1422 usage(void)
1423 {
1424     fprintf (stderr, "usage:  %s [options]\n", ProgramName);
1425     fprintf (stderr, "-display displayname\tserver to query\n");
1426     fprintf (stderr, "-queryExtensions\tprint info returned by XQueryExtension\n");
1427     fprintf (stderr, "-ext all\t\tprint detailed info for all supported extensions\n");
1428     fprintf (stderr, "-ext extension-name\tprint detailed info for extension-name if one of:\n     ");
1429     print_known_extensions(stderr);
1430     fprintf (stderr, "\n");
1431     exit (1);
1432 }
1433
1434 int 
1435 main(int argc, char *argv[])
1436 {
1437     Display *dpy;                       /* X connection */
1438     char *displayname = NULL;           /* server to contact */
1439     int i;                              /* temp variable:  iterator */
1440
1441     ProgramName = argv[0];
1442
1443     for (i = 1; i < argc; i++) {
1444         char *arg = argv[i];
1445         int len = strlen(arg);
1446         
1447         if (!strncmp("-display", arg, len)) {
1448             if (++i >= argc) usage ();
1449             displayname = argv[i];
1450         } else if (!strncmp("-queryExtensions", arg, len)) {
1451             queryExtensions = True;
1452         } else if (!strncmp("-ext", arg, len)) {
1453             if (++i >= argc) usage ();
1454             mark_extension_for_printing(argv[i]);
1455         } else
1456             usage ();
1457     }
1458
1459     dpy = XOpenDisplay (displayname);
1460     if (!dpy) {
1461         fprintf (stderr, "%s:  unable to open display \"%s\".\n",
1462                  ProgramName, XDisplayName (displayname));
1463         exit (1);
1464     }
1465
1466     print_display_info (dpy);
1467     for (i = 0; i < ScreenCount (dpy); i++) {
1468         print_screen_info (dpy, i);
1469     }
1470
1471     print_marked_extensions(dpy);
1472
1473     XCloseDisplay (dpy);
1474     exit (0);
1475 }