Use XCBFlush not XCBSync
[free-sw/xcb/demo] / xcbxvinfo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <X11/XCB/xcb.h>
6 #include <X11/XCB/xv.h>
7
8 static void PrintUsage()
9 {
10     fprintf(stderr, "Usage:  xvinfo [-display host:dpy]\n");
11     exit(0);
12 }
13
14 XCBSCREEN *ScreenOfDisplay (XCBConnection *c, int screen)
15 {
16     XCBSCREENIter iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
17     for (; iter.rem; --screen, XCBSCREENNext (&iter))
18         if (screen == 0)
19             return iter.data;
20     return NULL;
21 }
22
23 static int nstrcmp(char *b, int n, char *s) {
24     while (n > 0) {
25         if (*s == '\0')
26             return 1;
27         if (*b - *s != 0)
28             return *b - *s;
29         b++, s++, --n;
30     }
31     return -(*s != '\0');
32 }
33
34 /* 
35  * Copies a string s of size n and returns it with a NULL appended.
36  * String returned is allocated with malloc and should be freed later.
37  */
38 static char *ExtractString(char *s, int n) {
39     char *str;
40     str = (char *)malloc(sizeof(char) * (n+1));
41     strncpy(str, s, n); 
42     str[n] = '\0';
43     return str;
44 }
45
46 int main(int argc, char *argv[])
47 {
48     XCBConnection *c;
49     int scrn;
50     char *display_name = NULL;
51     char *name = NULL;
52     XCBWINDOW root_window = {0};
53     XCBSCREEN *screen;
54     XCBXvQueryExtensionRep *query_ext;
55     XCBXvQueryAdaptorsRep *adaptors_rep;
56     XCBXvAdaptorInfoIter adaptors_iter;
57     XCBXvAdaptorInfo *ainfo;
58     XCBXvFormat *format;
59     XCBXvQueryPortAttributesRep *attr_rep;
60     XCBXvAttributeInfoIter attr_iter;
61     XCBXvAttributeInfo *attribute;
62
63     int nscreens, nattr, i, j, k;
64
65     if ((argc != 1) && (argc != 3))
66         PrintUsage();
67
68     if (argc != 1) {
69         if (strcmp(argv[1], "-display"))
70             PrintUsage();
71         display_name = argv[2];
72     }
73
74     if (!display_name) display_name = getenv("DISPLAY");
75     if (!(c = XCBConnect(display_name, &scrn)))
76     {
77         fprintf(stderr, "xcbxvinfo: Unable to open display %s\n", display_name);
78         exit(1);
79     }
80
81     if (!(query_ext = XCBXvQueryExtensionReply(c, XCBXvQueryExtension(c), NULL)))
82     {
83         fprintf(stderr, "xvinfo: No X-Video extension on %s\n", display_name);
84         exit(0);
85     }
86     else
87     {
88         fprintf(stdout, "X-Video Extension version %i.%i\n", query_ext->major, query_ext->minor);
89     }
90
91     free(query_ext);
92
93     nscreens = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(c)).rem;
94
95     for (i = 0; i < nscreens; i++)
96     {
97         fprintf(stdout, "screen #%i\n", i);
98
99         screen = ScreenOfDisplay(c, scrn);
100         if (screen) root_window = screen->root;
101
102         adaptors_rep = XCBXvQueryAdaptorsReply(c, XCBXvQueryAdaptors(c, root_window), NULL);
103         if (!adaptors_rep->num_adaptors) {
104             fprintf(stdout, " no adaptors present.\n");
105             continue;
106         }
107
108         adaptors_iter = XCBXvQueryAdaptorsInfoIter(adaptors_rep);
109
110         for (j = 0; j < adaptors_rep->num_adaptors; j++)
111         {
112             ainfo = adaptors_iter.data;
113             name = ExtractString(XCBXvAdaptorInfoName(ainfo), XCBXvAdaptorInfoNameLength(ainfo));
114             fprintf(stdout, "  Adaptor #%i: \"%s\"\n", j, name);
115             fprintf(stdout, "    number of ports: %i\n", ainfo->num_ports);
116             fprintf(stdout, "    port base: %li\n", ainfo->base_id.xid);
117             fprintf(stdout, "    operations supported: ");
118             free(name);
119
120             switch(ainfo->type & (XCBXvTypeInputMask | XCBXvTypeOutputMask)) {
121                 case XCBXvTypeInputMask:
122                     if (ainfo->type & XCBXvTypeVideoMask)
123                         fprintf(stdout, "PutVideo ");
124                     if (ainfo->type & XCBXvTypeStillMask)
125                         fprintf(stdout, "PutStill ");
126                     if (ainfo->type & XCBXvTypeImageMask)
127                         fprintf(stdout, "PutImage ");
128                     break;
129                 case XCBXvTypeOutputMask:
130                     if (ainfo->type & XCBXvTypeVideoMask)
131                         fprintf(stdout, "GetVideo ");
132                     if (ainfo->type & XCBXvTypeStillMask)
133                         fprintf(stdout, "GetStill ");
134                     break;
135                 default:
136                     fprintf(stdout, "none ");
137                     break;
138             }
139             fprintf(stdout, "\n");
140
141             format = XCBXvAdaptorInfoFormats(ainfo);
142
143             fprintf(stdout, "    supported visuals:\n");
144             for (k=0; k < ainfo->num_formats; k++, format++)
145                 fprintf(stdout, "      depth %i, visualID 0x%2lx\n",
146                         format->depth, format->visual.id);
147
148             attr_rep = XCBXvQueryPortAttributesReply(c,
149                     XCBXvQueryPortAttributes(c, ainfo->base_id), NULL);
150             nattr = attr_rep->num_attributes;
151             attr_iter = XCBXvQueryPortAttributesAttributesIter(attr_rep);
152
153             if (nattr) {            
154                 fprintf(stdout, "    number of attributes: %i\n", nattr);
155
156                 for (k = 0; k < nattr; k++) {
157                     attribute = attr_iter.data;
158                     fprintf(stdout, "      \"%s\" (range %li to %li)\n",
159                             XCBXvAttributeInfoName(attribute),
160                             attribute->min,
161                             attribute->max);
162
163                     if (attribute->flags & XCBXvAttributeFlagSettable)
164                         fprintf(stdout, "              client settable attribute\n");
165
166                     if (attribute->flags & XCBXvAttributeFlagGettable) {
167                         XCBATOM the_atom;
168                         XCBInternAtomRep *atom_rep;
169
170                         fprintf(stdout, "              client gettable attribute");
171
172                         atom_rep = XCBInternAtomReply(c,
173                                 XCBInternAtom(c,
174                                     1, 
175                                     /*XCBXvAttributeInfoNameLength(attribute),*/
176                                     strlen(XCBXvAttributeInfoName(attribute)),
177                                     XCBXvAttributeInfoName(attribute)),
178                                 NULL);
179                         the_atom = atom_rep->atom;
180
181                         if (the_atom.xid != 0) {
182                             XCBXvGetPortAttributeRep *pattr_rep =
183                                 XCBXvGetPortAttributeReply(c,
184                                         XCBXvGetPortAttribute(c, ainfo->base_id, the_atom),
185                                         NULL);
186                             if (pattr_rep) fprintf(stdout, " (current value is %li)", pattr_rep->value);
187                             free(pattr_rep);
188                         }
189                         fprintf(stdout, "\n");
190                         free(atom_rep);
191                     }
192                     XCBXvAttributeInfoNext(&attr_iter);
193                 }
194             }
195             else {
196                 fprintf(stdout, "    no port attributes defined\n");
197             }
198
199             XCBXvQueryEncodingsRep *qencodings_rep;
200             qencodings_rep = XCBXvQueryEncodingsReply(c, XCBXvQueryEncodings(c, ainfo->base_id), NULL);
201             int nencode = qencodings_rep->num_encodings;
202             XCBXvEncodingInfoIter encoding_iter = XCBXvQueryEncodingsInfoIter(qencodings_rep);
203             XCBXvEncodingInfo *encoding;
204
205             int ImageEncodings = 0;
206             if (nencode) {
207                 int n;
208                 for (n = 0; n < nencode; n++) {
209                     encoding = encoding_iter.data;
210                     name = ExtractString(XCBXvEncodingInfoName(encoding), XCBXvEncodingInfoNameLength(encoding));
211                     if (!nstrcmp(name, strlen(name), "XV_IMAGE"))
212                         ImageEncodings++;
213                     XCBXvEncodingInfoNext(&encoding_iter);
214                     free(name);
215                 }
216
217                 if(nencode - ImageEncodings) {
218                     fprintf(stdout, "    number of encodings: %i\n", nencode - ImageEncodings);
219
220                     /* Reset the iter. */
221                     encoding_iter = XCBXvQueryEncodingsInfoIter(qencodings_rep);
222                     for(n = 0; n < nencode; n++) {
223                         encoding = encoding_iter.data;
224                         name = ExtractString(XCBXvEncodingInfoName(encoding), XCBXvEncodingInfoNameLength(encoding));
225                         if(nstrcmp(name, strlen(name), "XV_IMAGE")) {
226                             fprintf(stdout,
227                                     "      encoding ID #%li: \"%*s\"\n",
228                                     encoding->encoding.xid,
229                                     strlen(name),
230                                     name);
231                             fprintf(stdout, "        size: %i x %i\n",
232                                     encoding->width,
233                                     encoding->height);
234                             fprintf(stdout, "        rate: %f\n",
235                                     (float)encoding->rate.numerator/
236                                     (float)encoding->rate.denominator);
237                             free(name);
238                         }
239                         XCBXvEncodingInfoNext(&encoding_iter);
240                     }
241                 }
242
243                 if(ImageEncodings && (ainfo->type & XCBXvTypeImageMask)) {
244                     char imageName[5] = {0, 0, 0, 0, 0};
245                     encoding_iter = XCBXvQueryEncodingsInfoIter(qencodings_rep);
246                     for(n = 0; n < nencode; n++) {
247                         encoding = encoding_iter.data;
248                         name = ExtractString(XCBXvEncodingInfoName(encoding), XCBXvEncodingInfoNameLength(encoding));
249                         if(!nstrcmp(name, strlen(name), "XV_IMAGE")) {
250                             fprintf(stdout, 
251                                     "    maximum XvImage size: %i x %i\n",      
252                                     encoding->width, encoding->height);
253                             break;
254                         }
255                         free(name);
256                     }
257                     XCBXvListImageFormatsRep *formats_rep;
258                     formats_rep = XCBXvListImageFormatsReply(c,
259                             XCBXvListImageFormats(c, ainfo->base_id),
260                             NULL);
261
262                     int numImages = formats_rep->num_formats;
263                     XCBXvImageFormatInfo *format;
264                     XCBXvImageFormatInfoIter formats_iter = XCBXvListImageFormatsFormatIter(formats_rep);
265                     fprintf(stdout, "    Number of image formats: %i\n",
266                             numImages);
267
268                     for(n = 0; n < numImages; n++) {
269                         format = formats_iter.data;
270                         memcpy(imageName, &(format->id), 4);
271                         fprintf(stdout, "      id: 0x%lx", format->id);
272                         if(isprint(imageName[0]) && isprint(imageName[1]) &&
273                                 isprint(imageName[2]) && isprint(imageName[3])) 
274                         {
275                             fprintf(stdout, " (%s)\n", imageName);
276                         } else {
277                             fprintf(stdout, "\n");
278                         }
279                         fprintf(stdout, "        guid: ");
280                         fprintf(stdout, "%02x", (unsigned char) 
281                                 format->guid[0]);
282                         fprintf(stdout, "%02x", (unsigned char) 
283                                 format->guid[1]);
284                         fprintf(stdout, "%02x", (unsigned char) 
285                                 format->guid[2]);
286                         fprintf(stdout, "%02x-", (unsigned char) 
287                                 format->guid[3]);
288                         fprintf(stdout, "%02x", (unsigned char) 
289                                 format->guid[4]);
290                         fprintf(stdout, "%02x-", (unsigned char) 
291                                 format->guid[5]);
292                         fprintf(stdout, "%02x", (unsigned char) 
293                                 format->guid[6]);
294                         fprintf(stdout, "%02x-", (unsigned char) 
295                                 format->guid[7]);
296                         fprintf(stdout, "%02x", (unsigned char) 
297                                 format->guid[8]);
298                         fprintf(stdout, "%02x-", (unsigned char) 
299                                 format->guid[9]);
300                         fprintf(stdout, "%02x", (unsigned char) 
301                                 format->guid[10]);
302                         fprintf(stdout, "%02x", (unsigned char) 
303                                 format->guid[11]);
304                         fprintf(stdout, "%02x", (unsigned char) 
305                                 format->guid[12]);
306                         fprintf(stdout, "%02x", (unsigned char) 
307                                 format->guid[13]);
308                         fprintf(stdout, "%02x", (unsigned char) 
309                                 format->guid[14]);
310                         fprintf(stdout, "%02x\n", (unsigned char) 
311                                 format->guid[15]);
312
313                         fprintf(stdout, "        bits per pixel: %i\n",
314                                 format->bpp);
315                         fprintf(stdout, "        number of planes: %i\n",
316                                 format->num_planes);
317                         fprintf(stdout, "        type: %s (%s)\n", 
318                                 (format->type == XCBXvImageFormatInfoTypeRGB) ? "RGB" : "YUV",
319                                 (format->format == XCBXvImageFormatInfoFormatPacked) ? "packed" : "planar");
320
321                         if(format->type == XCBXvImageFormatInfoTypeRGB) {
322                             fprintf(stdout, "        depth: %i\n", 
323                                     format->depth);
324
325                             fprintf(stdout, "        red, green, blue masks: " 
326                                     "0x%lx, 0x%lx, 0x%lx\n", 
327                                     format->red_mask,
328                                     format->green_mask,
329                                     format->blue_mask);
330                         } else {
331
332                         }
333                         XCBXvImageFormatInfoNext(&formats_iter);
334                     }
335                     free(formats_rep);
336                 }
337             }
338             free(qencodings_rep);
339             XCBXvAdaptorInfoNext(&adaptors_iter);
340         }
341     }
342
343     free(adaptors_rep);
344     adaptors_rep = NULL;
345
346     return 1;
347 }