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