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