1#ifdef HAVE_CONFIG_H 2# include "config.h" 3#endif 4 5#include <X11/X.h> 6#include <X11/Xlib.h> 7#include <X11/extensions/Xvlib.h> 8#include <stdio.h> 9#include <stdlib.h> 10#include <string.h> 11#include <ctype.h> 12 13static char *progname; 14 15static void _X_NORETURN _X_COLD 16PrintUsage(void) 17{ 18 fprintf(stderr, "Usage: %s [-display host:dpy] [-short] [-version]\n", 19 progname); 20 exit(0); 21} 22 23int 24main(int argc, char *argv[]) 25{ 26 Display *dpy; 27 unsigned int ver, rev, eventB, reqB, errorB; 28 int nscreens; 29 char *disname = NULL; 30 char shortmode = 0; 31 32 progname = argv[0]; 33 34 if ((argc > 4)) 35 PrintUsage(); 36 37 if (argc != 1) { 38 for (int i = 1; i < argc; i++) { 39 if (!strcmp(argv[i], "-display")) { 40 if (++i >= argc) { 41 fprintf (stderr, "%s: missing argument to -display\n", 42 progname); 43 PrintUsage(); 44 } 45 disname = argv[i]; 46 } 47 else if (!strcmp(argv[i], "-short")) 48 shortmode = 1; 49 else if (!strcmp(argv[i], "-version")) { 50 printf("%s\n", PACKAGE_STRING); 51 exit(0); 52 } 53 else { 54 fprintf (stderr, "%s: unrecognized argument '%s'\n", 55 progname, argv[i]); 56 PrintUsage(); 57 } 58 } 59 } 60 61 if (!(dpy = XOpenDisplay(disname))) { 62 fprintf(stderr, "%s: Unable to open display %s\n", progname, 63 (disname != NULL) ? disname : XDisplayName(NULL)); 64 exit(-1); 65 } 66 67 if (Success != XvQueryExtension(dpy, &ver, &rev, &reqB, &eventB, &errorB)) { 68 fprintf(stderr, "%s: No X-Video Extension on %s\n", progname, 69 (disname != NULL) ? disname : XDisplayName(NULL)); 70 exit(0); 71 } 72 else { 73 fprintf(stdout, "X-Video Extension version %i.%i\n", ver, rev); 74 } 75 76 nscreens = ScreenCount(dpy); 77 78 for (int i = 0; i < nscreens; i++) { 79 unsigned int nadaptors; 80 XvAdaptorInfo *ainfo; 81 82 fprintf(stdout, "screen #%i\n", i); 83 if (Success != XvQueryAdaptors(dpy, RootWindow(dpy, i), &nadaptors, 84 &ainfo)) { 85 fprintf(stderr, "%s: Failed to query adaptors on display %s\n", 86 progname, (disname != NULL) ? disname : XDisplayName(NULL)); 87 exit(-1); 88 } 89 90 if (!nadaptors) { 91 fprintf(stdout, " no adaptors present\n"); 92 continue; 93 } 94 95 for (unsigned int j = 0; j < nadaptors; j++) { 96 XvFormat *format; 97 int nattr; 98 XvAttribute *attributes; 99 unsigned int nencode; 100 XvEncodingInfo *encodings; 101 102 fprintf(stdout, " Adaptor #%i: \"%s\"\n", j, ainfo[j].name); 103 fprintf(stdout, " number of ports: %li\n", ainfo[j].num_ports); 104 fprintf(stdout, " port base: %li\n", ainfo[j].base_id); 105 fprintf(stdout, " operations supported: "); 106 switch (ainfo[j].type & (XvInputMask | XvOutputMask)) { 107 case XvInputMask: 108 if (ainfo[j].type & XvVideoMask) 109 fprintf(stdout, "PutVideo "); 110 if (ainfo[j].type & XvStillMask) 111 fprintf(stdout, "PutStill "); 112 if (ainfo[j].type & XvImageMask) 113 fprintf(stdout, "PutImage "); 114 break; 115 case XvOutputMask: 116 if (ainfo[j].type & XvVideoMask) 117 fprintf(stdout, "GetVideo "); 118 if (ainfo[j].type & XvStillMask) 119 fprintf(stdout, "GetStill "); 120 break; 121 default: 122 fprintf(stdout, "none "); 123 break; 124 } 125 fprintf(stdout, "\n"); 126 127 format = ainfo[j].formats; 128 129 if (!shortmode) { 130 fprintf(stdout, " supported visuals:\n"); 131 for (unsigned long k = 0; k < ainfo[j].num_formats; k++, format++) { 132 fprintf(stdout, " depth %i, visualID 0x%2lx\n", 133 format->depth, format->visual_id); 134 } 135 } 136 137 attributes = XvQueryPortAttributes(dpy, ainfo[j].base_id, &nattr); 138 139 if (attributes && nattr) { 140 fprintf(stdout, " number of attributes: %i\n", nattr); 141 142 for (int k = 0; k < nattr; k++) { 143 fprintf(stdout, " \"%s\" (range %i to %i)\n", 144 attributes[k].name, 145 attributes[k].min_value, attributes[k].max_value); 146 147 if (attributes[k].flags & XvSettable) { 148 if (!shortmode) 149 fprintf(stdout, 150 " client settable attribute\n"); 151 else 152 fprintf(stdout, " settable"); 153 } 154 155 if (attributes[k].flags & XvGettable) { 156 Atom the_atom; 157 158 int value; 159 160 if (!shortmode) 161 fprintf(stdout, 162 " client gettable attribute"); 163 else 164 fprintf(stdout, ", gettable"); 165 166 the_atom = XInternAtom(dpy, attributes[k].name, True); 167 168 if (the_atom != None) { 169 if ((Success == XvGetPortAttribute(dpy, 170 ainfo[j].base_id, 171 the_atom, 172 &value))) 173 fprintf(stdout, " (current value is %i)", 174 value); 175 } 176 fprintf(stdout, "\n"); 177 } 178 else if (shortmode) 179 fprintf(stdout, "\n"); 180 181 } 182 XFree(attributes); 183 } 184 else { 185 fprintf(stdout, " no port attributes defined\n"); 186 } 187 188 if (Success != XvQueryEncodings(dpy, ainfo[j].base_id, &nencode, 189 &encodings)) { 190 fprintf(stderr, 191 "%s: Failed to query encodings on display %s\n", 192 progname, 193 (disname != NULL) ? disname : XDisplayName(NULL)); 194 exit(-1); 195 } 196 197 if (encodings && nencode) { 198 unsigned int ImageEncodings = 0; 199 200 for (unsigned int n = 0; n < nencode; n++) { 201 if (!strcmp(encodings[n].name, "XV_IMAGE")) 202 ImageEncodings++; 203 } 204 205 if (nencode - ImageEncodings) { 206 fprintf(stdout, " number of encodings: %i\n", 207 nencode - ImageEncodings); 208 209 for (unsigned int n = 0; n < nencode; n++) { 210 if (strcmp(encodings[n].name, "XV_IMAGE")) { 211 fprintf(stdout, " encoding ID #%li: \"%s\"\n", 212 encodings[n].encoding_id, 213 encodings[n].name); 214 fprintf(stdout, " size: %li x %li\n", 215 encodings[n].width, encodings[n].height); 216 fprintf(stdout, " rate: %f\n", 217 (double) encodings[n].rate.numerator / 218 (double) encodings[n].rate.denominator); 219 } 220 } 221 } 222 223 if (ImageEncodings && (ainfo[j].type & XvImageMask)) { 224 int numImages; 225 XvImageFormatValues *formats; 226 227 for (unsigned int n = 0; n < nencode; n++) { 228 if (!strcmp(encodings[n].name, "XV_IMAGE")) { 229 fprintf(stdout, 230 " maximum XvImage size: %li x %li\n", 231 encodings[n].width, encodings[n].height); 232 break; 233 } 234 } 235 236 formats = 237 XvListImageFormats(dpy, ainfo[j].base_id, &numImages); 238 239 fprintf(stdout, " Number of image formats: %i\n", 240 numImages); 241 242 for (int n = 0; n < numImages; n++) { 243 char imageName[5]; 244 245 snprintf(imageName, sizeof(imageName), "%c%c%c%c", 246 formats[n].id & 0xff, 247 (formats[n].id >> 8) & 0xff, 248 (formats[n].id >> 16) & 0xff, 249 (formats[n].id >> 24) & 0xff); 250 fprintf(stdout, " id: 0x%x", formats[n].id); 251 if (isprint(imageName[0]) && isprint(imageName[1]) && 252 isprint(imageName[2]) && isprint(imageName[3])) { 253 fprintf(stdout, " (%s)\n", imageName); 254 } 255 else { 256 fprintf(stdout, "\n"); 257 } 258 if (!shortmode) { 259 fprintf(stdout, " guid: "); 260 fprintf(stdout, "%02x", (unsigned char) 261 formats[n].guid[0]); 262 fprintf(stdout, "%02x", (unsigned char) 263 formats[n].guid[1]); 264 fprintf(stdout, "%02x", (unsigned char) 265 formats[n].guid[2]); 266 fprintf(stdout, "%02x-", (unsigned char) 267 formats[n].guid[3]); 268 fprintf(stdout, "%02x", (unsigned char) 269 formats[n].guid[4]); 270 fprintf(stdout, "%02x-", (unsigned char) 271 formats[n].guid[5]); 272 fprintf(stdout, "%02x", (unsigned char) 273 formats[n].guid[6]); 274 fprintf(stdout, "%02x-", (unsigned char) 275 formats[n].guid[7]); 276 fprintf(stdout, "%02x", (unsigned char) 277 formats[n].guid[8]); 278 fprintf(stdout, "%02x-", (unsigned char) 279 formats[n].guid[9]); 280 fprintf(stdout, "%02x", (unsigned char) 281 formats[n].guid[10]); 282 fprintf(stdout, "%02x", (unsigned char) 283 formats[n].guid[11]); 284 fprintf(stdout, "%02x", (unsigned char) 285 formats[n].guid[12]); 286 fprintf(stdout, "%02x", (unsigned char) 287 formats[n].guid[13]); 288 fprintf(stdout, "%02x", (unsigned char) 289 formats[n].guid[14]); 290 fprintf(stdout, "%02x\n", (unsigned char) 291 formats[n].guid[15]); 292 293 fprintf(stdout, " bits per pixel: %i\n", 294 formats[n].bits_per_pixel); 295 fprintf(stdout, " number of planes: %i\n", 296 formats[n].num_planes); 297 fprintf(stdout, " type: %s (%s)\n", 298 (formats[n].type == XvRGB) ? "RGB" : "YUV", 299 (formats[n].format == 300 XvPacked) ? "packed" : "planar"); 301 302 if (formats[n].type == XvRGB) { 303 fprintf(stdout, " depth: %i\n", 304 formats[n].depth); 305 306 fprintf(stdout, 307 " red, green, blue masks: " 308 "0x%x, 0x%x, 0x%x\n", 309 formats[n].red_mask, 310 formats[n].green_mask, 311 formats[n].blue_mask); 312 } 313 else { 314 315 } 316 } 317 318 } 319 if (formats) 320 XFree(formats); 321 } 322 323 XvFreeEncodingInfo(encodings); 324 } 325 326 } 327 328 XvFreeAdaptorInfo(ainfo); 329 } 330 return 0; 331} 332