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