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