1405c8079Smrg#ifdef HAVE_CONFIG_H 2405c8079Smrg# include "config.h" 3405c8079Smrg#endif 4405c8079Smrg 58ae04fa6Smrg#include <X11/X.h> 68ae04fa6Smrg#include <X11/Xlib.h> 78ae04fa6Smrg#include <X11/extensions/Xvlib.h> 88ae04fa6Smrg#include <stdio.h> 98ae04fa6Smrg#include <stdlib.h> 108ae04fa6Smrg#include <string.h> 118ae04fa6Smrg#include <ctype.h> 128ae04fa6Smrg 1380f56f3aSmrgstatic char *progname; 1480f56f3aSmrg 1580f56f3aSmrgstatic void _X_NORETURN _X_COLD 168ae04fa6SmrgPrintUsage(void) 178ae04fa6Smrg{ 1880f56f3aSmrg fprintf(stderr, "Usage: %s [-display host:dpy] [-short] [-version]\n", 1980f56f3aSmrg progname); 20405c8079Smrg exit(0); 218ae04fa6Smrg} 228ae04fa6Smrg 23405c8079Smrgint 24405c8079Smrgmain(int argc, char *argv[]) 258ae04fa6Smrg{ 268ae04fa6Smrg Display *dpy; 27405c8079Smrg unsigned int ver, rev, eventB, reqB, errorB; 28138a9f8aSmrg int nscreens; 29405c8079Smrg char *disname = NULL; 3044af7230Smrg char shortmode = 0; 318ae04fa6Smrg 3280f56f3aSmrg progname = argv[0]; 3380f56f3aSmrg 34405c8079Smrg if ((argc > 4)) 35405c8079Smrg PrintUsage(); 36405c8079Smrg 37405c8079Smrg if (argc != 1) { 38d71d4977Smrg for (int i = 1; i < argc; i++) { 39405c8079Smrg if (!strcmp(argv[i], "-display")) { 4080f56f3aSmrg if (++i >= argc) { 4180f56f3aSmrg fprintf (stderr, "%s: missing argument to -display\n", 4280f56f3aSmrg progname); 4380f56f3aSmrg PrintUsage(); 4480f56f3aSmrg } 4580f56f3aSmrg disname = argv[i]; 46405c8079Smrg } 47405c8079Smrg else if (!strcmp(argv[i], "-short")) 48405c8079Smrg shortmode = 1; 49405c8079Smrg else if (!strcmp(argv[i], "-version")) { 50405c8079Smrg printf("%s\n", PACKAGE_STRING); 51405c8079Smrg exit(0); 52405c8079Smrg } 53405c8079Smrg else { 5480f56f3aSmrg fprintf (stderr, "%s: unrecognized argument '%s'\n", 5580f56f3aSmrg progname, argv[i]); 56405c8079Smrg PrintUsage(); 57405c8079Smrg } 58405c8079Smrg } 598ae04fa6Smrg } 608ae04fa6Smrg 61405c8079Smrg if (!(dpy = XOpenDisplay(disname))) { 6280f56f3aSmrg fprintf(stderr, "%s: Unable to open display %s\n", progname, 63405c8079Smrg (disname != NULL) ? disname : XDisplayName(NULL)); 64405c8079Smrg exit(-1); 658ae04fa6Smrg } 668ae04fa6Smrg 67d71d4977Smrg if (Success != XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB)) { 6880f56f3aSmrg fprintf(stderr, "%s: No X-Video Extension on %s\n", progname, 69405c8079Smrg (disname != NULL) ? disname : XDisplayName(NULL)); 70405c8079Smrg exit(0); 71405c8079Smrg } 72405c8079Smrg else { 73405c8079Smrg fprintf(stdout, "X-Video Extension version %i.%i\n", ver, rev); 748ae04fa6Smrg } 758ae04fa6Smrg 768ae04fa6Smrg nscreens = ScreenCount(dpy); 778ae04fa6Smrg 78d71d4977Smrg for (int i = 0; i < nscreens; i++) { 79138a9f8aSmrg unsigned int nadaptors; 80138a9f8aSmrg XvAdaptorInfo *ainfo; 81138a9f8aSmrg 82405c8079Smrg fprintf(stdout, "screen #%i\n", i); 83d71d4977Smrg if (Success != XvQueryAdaptors(dpy, RootWindow(dpy, i), &nadaptors, 84d71d4977Smrg &ainfo)) { 85d71d4977Smrg fprintf(stderr, "%s: Failed to query adaptors on display %s\n", 86d71d4977Smrg progname, (disname != NULL) ? disname : XDisplayName(NULL)); 87d71d4977Smrg exit(-1); 88d71d4977Smrg } 89405c8079Smrg 90405c8079Smrg if (!nadaptors) { 91405c8079Smrg fprintf(stdout, " no adaptors present\n"); 92405c8079Smrg continue; 93405c8079Smrg } 94405c8079Smrg 95d71d4977Smrg for (unsigned int j = 0; j < nadaptors; j++) { 96138a9f8aSmrg XvFormat *format; 97138a9f8aSmrg int nattr; 98138a9f8aSmrg XvAttribute *attributes; 99138a9f8aSmrg unsigned int nencode; 100138a9f8aSmrg XvEncodingInfo *encodings; 101138a9f8aSmrg 102405c8079Smrg fprintf(stdout, " Adaptor #%i: \"%s\"\n", j, ainfo[j].name); 103405c8079Smrg fprintf(stdout, " number of ports: %li\n", ainfo[j].num_ports); 104405c8079Smrg fprintf(stdout, " port base: %li\n", ainfo[j].base_id); 105405c8079Smrg fprintf(stdout, " operations supported: "); 106405c8079Smrg switch (ainfo[j].type & (XvInputMask | XvOutputMask)) { 107405c8079Smrg case XvInputMask: 108405c8079Smrg if (ainfo[j].type & XvVideoMask) 109405c8079Smrg fprintf(stdout, "PutVideo "); 110405c8079Smrg if (ainfo[j].type & XvStillMask) 111405c8079Smrg fprintf(stdout, "PutStill "); 112405c8079Smrg if (ainfo[j].type & XvImageMask) 113405c8079Smrg fprintf(stdout, "PutImage "); 114405c8079Smrg break; 115405c8079Smrg case XvOutputMask: 116405c8079Smrg if (ainfo[j].type & XvVideoMask) 117405c8079Smrg fprintf(stdout, "GetVideo "); 118405c8079Smrg if (ainfo[j].type & XvStillMask) 119405c8079Smrg fprintf(stdout, "GetStill "); 120405c8079Smrg break; 121405c8079Smrg default: 122405c8079Smrg fprintf(stdout, "none "); 123405c8079Smrg break; 124405c8079Smrg } 125405c8079Smrg fprintf(stdout, "\n"); 126405c8079Smrg 127405c8079Smrg format = ainfo[j].formats; 128405c8079Smrg 129405c8079Smrg if (!shortmode) { 130405c8079Smrg fprintf(stdout, " supported visuals:\n"); 131d71d4977Smrg for (unsigned long k = 0; k < ainfo[j].num_formats; k++, format++) { 132405c8079Smrg fprintf(stdout, " depth %i, visualID 0x%2lx\n", 133405c8079Smrg format->depth, format->visual_id); 134405c8079Smrg } 135405c8079Smrg } 136405c8079Smrg 137405c8079Smrg attributes = XvQueryPortAttributes(dpy, ainfo[j].base_id, &nattr); 138405c8079Smrg 139405c8079Smrg if (attributes && nattr) { 140405c8079Smrg fprintf(stdout, " number of attributes: %i\n", nattr); 141405c8079Smrg 142d71d4977Smrg for (int k = 0; k < nattr; k++) { 143405c8079Smrg fprintf(stdout, " \"%s\" (range %i to %i)\n", 144405c8079Smrg attributes[k].name, 145405c8079Smrg attributes[k].min_value, attributes[k].max_value); 146405c8079Smrg 147405c8079Smrg if (attributes[k].flags & XvSettable) { 148405c8079Smrg if (!shortmode) 149405c8079Smrg fprintf(stdout, 150405c8079Smrg " client settable attribute\n"); 151405c8079Smrg else 152405c8079Smrg fprintf(stdout, " settable"); 153405c8079Smrg } 154405c8079Smrg 155405c8079Smrg if (attributes[k].flags & XvGettable) { 156405c8079Smrg Atom the_atom; 157405c8079Smrg 158405c8079Smrg int value; 159405c8079Smrg 160405c8079Smrg if (!shortmode) 161405c8079Smrg fprintf(stdout, 162405c8079Smrg " client gettable attribute"); 163405c8079Smrg else 164405c8079Smrg fprintf(stdout, ", gettable"); 165405c8079Smrg 166405c8079Smrg the_atom = XInternAtom(dpy, attributes[k].name, True); 167405c8079Smrg 168405c8079Smrg if (the_atom != None) { 169405c8079Smrg if ((Success == XvGetPortAttribute(dpy, 170405c8079Smrg ainfo[j].base_id, 171405c8079Smrg the_atom, 172405c8079Smrg &value))) 173405c8079Smrg fprintf(stdout, " (current value is %i)", 174405c8079Smrg value); 175405c8079Smrg } 176405c8079Smrg fprintf(stdout, "\n"); 177405c8079Smrg } 178405c8079Smrg else if (shortmode) 179405c8079Smrg fprintf(stdout, "\n"); 180405c8079Smrg 181405c8079Smrg } 182405c8079Smrg XFree(attributes); 183405c8079Smrg } 184405c8079Smrg else { 185405c8079Smrg fprintf(stdout, " no port attributes defined\n"); 186405c8079Smrg } 187405c8079Smrg 188d71d4977Smrg if (Success != XvQueryEncodings(dpy, ainfo[j].base_id, &nencode, 189d71d4977Smrg &encodings)) { 190d71d4977Smrg fprintf(stderr, 191d71d4977Smrg "%s: Failed to query encodings on display %s\n", 192d71d4977Smrg progname, 193d71d4977Smrg (disname != NULL) ? disname : XDisplayName(NULL)); 194d71d4977Smrg exit(-1); 195d71d4977Smrg } 196405c8079Smrg 197405c8079Smrg if (encodings && nencode) { 19880f56f3aSmrg unsigned int ImageEncodings = 0; 199405c8079Smrg 200d71d4977Smrg for (unsigned int n = 0; n < nencode; n++) { 201405c8079Smrg if (!strcmp(encodings[n].name, "XV_IMAGE")) 202405c8079Smrg ImageEncodings++; 203405c8079Smrg } 204405c8079Smrg 205405c8079Smrg if (nencode - ImageEncodings) { 206405c8079Smrg fprintf(stdout, " number of encodings: %i\n", 207405c8079Smrg nencode - ImageEncodings); 208405c8079Smrg 209d71d4977Smrg for (unsigned int n = 0; n < nencode; n++) { 210405c8079Smrg if (strcmp(encodings[n].name, "XV_IMAGE")) { 211405c8079Smrg fprintf(stdout, " encoding ID #%li: \"%s\"\n", 212405c8079Smrg encodings[n].encoding_id, 213405c8079Smrg encodings[n].name); 214405c8079Smrg fprintf(stdout, " size: %li x %li\n", 215405c8079Smrg encodings[n].width, encodings[n].height); 216405c8079Smrg fprintf(stdout, " rate: %f\n", 217138a9f8aSmrg (double) encodings[n].rate.numerator / 218138a9f8aSmrg (double) encodings[n].rate.denominator); 219405c8079Smrg } 220405c8079Smrg } 221405c8079Smrg } 222405c8079Smrg 223405c8079Smrg if (ImageEncodings && (ainfo[j].type & XvImageMask)) { 224138a9f8aSmrg int numImages; 225138a9f8aSmrg XvImageFormatValues *formats; 226138a9f8aSmrg 227d71d4977Smrg for (unsigned int n = 0; n < nencode; n++) { 228405c8079Smrg if (!strcmp(encodings[n].name, "XV_IMAGE")) { 229405c8079Smrg fprintf(stdout, 230405c8079Smrg " maximum XvImage size: %li x %li\n", 231405c8079Smrg encodings[n].width, encodings[n].height); 232405c8079Smrg break; 233405c8079Smrg } 234405c8079Smrg } 235405c8079Smrg 236405c8079Smrg formats = 237405c8079Smrg XvListImageFormats(dpy, ainfo[j].base_id, &numImages); 238405c8079Smrg 239405c8079Smrg fprintf(stdout, " Number of image formats: %i\n", 240405c8079Smrg numImages); 241405c8079Smrg 242d71d4977Smrg for (int n = 0; n < numImages; n++) { 24380f56f3aSmrg char imageName[5]; 24480f56f3aSmrg 24580f56f3aSmrg snprintf(imageName, sizeof(imageName), "%c%c%c%c", 24680f56f3aSmrg formats[n].id & 0xff, 247405c8079Smrg (formats[n].id >> 8) & 0xff, 248405c8079Smrg (formats[n].id >> 16) & 0xff, 249405c8079Smrg (formats[n].id >> 24) & 0xff); 250405c8079Smrg fprintf(stdout, " id: 0x%x", formats[n].id); 251405c8079Smrg if (isprint(imageName[0]) && isprint(imageName[1]) && 252405c8079Smrg isprint(imageName[2]) && isprint(imageName[3])) { 253405c8079Smrg fprintf(stdout, " (%s)\n", imageName); 254405c8079Smrg } 255405c8079Smrg else { 256405c8079Smrg fprintf(stdout, "\n"); 257405c8079Smrg } 258405c8079Smrg if (!shortmode) { 259405c8079Smrg fprintf(stdout, " guid: "); 260405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 261405c8079Smrg formats[n].guid[0]); 262405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 263405c8079Smrg formats[n].guid[1]); 264405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 265405c8079Smrg formats[n].guid[2]); 266405c8079Smrg fprintf(stdout, "%02x-", (unsigned char) 267405c8079Smrg formats[n].guid[3]); 268405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 269405c8079Smrg formats[n].guid[4]); 270405c8079Smrg fprintf(stdout, "%02x-", (unsigned char) 271405c8079Smrg formats[n].guid[5]); 272405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 273405c8079Smrg formats[n].guid[6]); 274405c8079Smrg fprintf(stdout, "%02x-", (unsigned char) 275405c8079Smrg formats[n].guid[7]); 276405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 277405c8079Smrg formats[n].guid[8]); 278405c8079Smrg fprintf(stdout, "%02x-", (unsigned char) 279405c8079Smrg formats[n].guid[9]); 280405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 281405c8079Smrg formats[n].guid[10]); 282405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 283405c8079Smrg formats[n].guid[11]); 284405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 285405c8079Smrg formats[n].guid[12]); 286405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 287405c8079Smrg formats[n].guid[13]); 288405c8079Smrg fprintf(stdout, "%02x", (unsigned char) 289405c8079Smrg formats[n].guid[14]); 290405c8079Smrg fprintf(stdout, "%02x\n", (unsigned char) 291405c8079Smrg formats[n].guid[15]); 292405c8079Smrg 293405c8079Smrg fprintf(stdout, " bits per pixel: %i\n", 294405c8079Smrg formats[n].bits_per_pixel); 295405c8079Smrg fprintf(stdout, " number of planes: %i\n", 296405c8079Smrg formats[n].num_planes); 297405c8079Smrg fprintf(stdout, " type: %s (%s)\n", 298405c8079Smrg (formats[n].type == XvRGB) ? "RGB" : "YUV", 299405c8079Smrg (formats[n].format == 300405c8079Smrg XvPacked) ? "packed" : "planar"); 301405c8079Smrg 302405c8079Smrg if (formats[n].type == XvRGB) { 303405c8079Smrg fprintf(stdout, " depth: %i\n", 3048ae04fa6Smrg formats[n].depth); 3058ae04fa6Smrg 306405c8079Smrg fprintf(stdout, 307405c8079Smrg " red, green, blue masks: " 308405c8079Smrg "0x%x, 0x%x, 0x%x\n", 309405c8079Smrg formats[n].red_mask, 310405c8079Smrg formats[n].green_mask, 311405c8079Smrg formats[n].blue_mask); 312405c8079Smrg } 313405c8079Smrg else { 314405c8079Smrg 315405c8079Smrg } 316405c8079Smrg } 317405c8079Smrg 318405c8079Smrg } 319405c8079Smrg if (formats) 320405c8079Smrg XFree(formats); 321405c8079Smrg } 322405c8079Smrg 323405c8079Smrg XvFreeEncodingInfo(encodings); 324405c8079Smrg } 325405c8079Smrg 326405c8079Smrg } 327405c8079Smrg 328405c8079Smrg XvFreeAdaptorInfo(ainfo); 3298ae04fa6Smrg } 330d71d4977Smrg return 0; 3318ae04fa6Smrg} 332