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