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