tests: update for xcb-util >= 0.3.0
[free-sw/xcb/demo] / xcbxvinfo.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <ctype.h>
5 #include <xcb/xcb.h>
6 #include <xcb/xv.h>
7
8 static void PrintUsage()
9 {
10     fprintf(stderr, "Usage:  xvinfo [-display host:dpy]\n");
11     exit(0);
12 }
13
14 xcb_screen_t *ScreenOfDisplay (xcb_connection_t *c, int screen)
15 {
16     xcb_screen_iterator_t iter = xcb_setup_roots_iterator (xcb_get_setup (c));
17     for (; iter.rem; --screen, xcb_screen_next (&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     xcb_connection_t *c;
49     int scrn;
50     char *display_name = NULL;
51     char *name = NULL;
52     xcb_window_t root_window = {0};
53     xcb_screen_t *screen;
54     xcb_xv_query_extension_reply_t *query_ext;
55     xcb_xv_query_adaptors_reply_t *adaptors_rep;
56     xcb_xv_adaptor_info_iterator_t adaptors_iter;
57     xcb_xv_adaptor_info_t *ainfo;
58     xcb_xv_format_t *format;
59     xcb_xv_query_port_attributes_reply_t *attr_rep;
60     xcb_xv_attribute_info_iterator_t attr_iter;
61     xcb_xv_attribute_info_t *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     c = xcb_connect(display_name, &scrn);
76     if (xcb_connection_has_error(c))
77     {
78         fprintf(stderr, "xcbxvinfo: Unable to open display %s\n", display_name);
79         exit(1);
80     }
81
82     if (!(query_ext = xcb_xv_query_extension_reply(c, xcb_xv_query_extension(c), NULL)))
83     {
84         fprintf(stderr, "xvinfo: No X-Video extension on %s\n", display_name);
85         exit(0);
86     }
87     else
88     {
89         fprintf(stdout, "X-Video Extension version %i.%i\n", query_ext->major, query_ext->minor);
90     }
91
92     free(query_ext);
93
94     nscreens = xcb_setup_roots_length(xcb_get_setup(c));
95
96     for (i = 0; i < nscreens; i++)
97     {
98         fprintf(stdout, "screen #%i\n", i);
99
100         screen = ScreenOfDisplay(c, scrn);
101         if (screen) root_window = screen->root;
102
103         adaptors_rep = xcb_xv_query_adaptors_reply(c, xcb_xv_query_adaptors(c, root_window), NULL);
104         if (!adaptors_rep->num_adaptors) {
105             fprintf(stdout, " no adaptors present.\n");
106             free(adaptors_rep);
107             continue;
108         }
109
110         adaptors_iter = xcb_xv_query_adaptors_info_iterator(adaptors_rep);
111
112         for (j = 0; j < adaptors_rep->num_adaptors; j++)
113         {
114             ainfo = adaptors_iter.data;
115             name = ExtractString(xcb_xv_adaptor_info_name(ainfo), xcb_xv_adaptor_info_name_length(ainfo));
116             fprintf(stdout, "  Adaptor #%i: \"%s\"\n", j, name);
117             fprintf(stdout, "    number of ports: %i\n", ainfo->num_ports);
118             fprintf(stdout, "    port base: %i\n", ainfo->base_id);
119             fprintf(stdout, "    operations supported: ");
120             free(name);
121
122             switch(ainfo->type & (XCB_XV_TYPE_INPUT_MASK | XCB_XV_TYPE_OUTPUT_MASK)) {
123                 case XCB_XV_TYPE_INPUT_MASK:
124                     if (ainfo->type & XCB_XV_TYPE_VIDEO_MASK)
125                         fprintf(stdout, "PutVideo ");
126                     if (ainfo->type & XCB_XV_TYPE_STILL_MASK)
127                         fprintf(stdout, "PutStill ");
128                     if (ainfo->type & XCB_XV_TYPE_IMAGE_MASK)
129                         fprintf(stdout, "PutImage ");
130                     break;
131                 case XCB_XV_TYPE_OUTPUT_MASK:
132                     if (ainfo->type & XCB_XV_TYPE_VIDEO_MASK)
133                         fprintf(stdout, "GetVideo ");
134                     if (ainfo->type & XCB_XV_TYPE_STILL_MASK)
135                         fprintf(stdout, "GetStill ");
136                     break;
137                 default:
138                     fprintf(stdout, "none ");
139                     break;
140             }
141             fprintf(stdout, "\n");
142
143             format = xcb_xv_adaptor_info_formats(ainfo);
144
145             fprintf(stdout, "    supported visuals:\n");
146             for (k=0; k < ainfo->num_formats; k++, format++)
147                 fprintf(stdout, "      depth %i, visualID 0x%2x\n",
148                         format->depth, format->visual);
149
150             attr_rep = xcb_xv_query_port_attributes_reply(c,
151                     xcb_xv_query_port_attributes(c, ainfo->base_id), NULL);
152             nattr = attr_rep->num_attributes;
153             attr_iter = xcb_xv_query_port_attributes_attributes_iterator(attr_rep);
154
155             if (nattr) {            
156                 fprintf(stdout, "    number of attributes: %i\n", nattr);
157
158                 for (k = 0; k < nattr; k++) {
159                     attribute = attr_iter.data;
160                     fprintf(stdout, "      \"%s\" (range %i to %i)\n",
161                             xcb_xv_attribute_info_name(attribute),
162                             attribute->min,
163                             attribute->max);
164
165                     if (attribute->flags & XCB_XV_ATTRIBUTE_FLAG_SETTABLE)
166                         fprintf(stdout, "              client settable attribute\n");
167
168                     if (attribute->flags & XCB_XV_ATTRIBUTE_FLAG_GETTABLE) {
169                         xcb_atom_t the_atom;
170                         xcb_intern_atom_reply_t *atom_rep;
171
172                         fprintf(stdout, "              client gettable attribute");
173
174                         atom_rep = xcb_intern_atom_reply(c,
175                                 xcb_intern_atom(c,
176                                     1, 
177                                     /*xcb_xv_attribute_info_name_length(attribute),*/
178                                     strlen(xcb_xv_attribute_info_name(attribute)),
179                                     xcb_xv_attribute_info_name(attribute)),
180                                 NULL);
181                         the_atom = atom_rep->atom;
182
183                         if (the_atom != 0) {
184                             xcb_xv_get_port_attribute_reply_t *pattr_rep =
185                                 xcb_xv_get_port_attribute_reply(c,
186                                         xcb_xv_get_port_attribute(c, ainfo->base_id, the_atom),
187                                         NULL);
188                             if (pattr_rep) fprintf(stdout, " (current value is %i)", pattr_rep->value);
189                             free(pattr_rep);
190                         }
191                         fprintf(stdout, "\n");
192                         free(atom_rep);
193                     }
194                     xcb_xv_attribute_info_next(&attr_iter);
195                 }
196             }
197             else {
198                 fprintf(stdout, "    no port attributes defined\n");
199             }
200
201             xcb_xv_query_encodings_reply_t *qencodings_rep;
202             qencodings_rep = xcb_xv_query_encodings_reply(c, xcb_xv_query_encodings(c, ainfo->base_id), NULL);
203             int nencode = qencodings_rep->num_encodings;
204             xcb_xv_encoding_info_iterator_t encoding_iter = xcb_xv_query_encodings_info_iterator(qencodings_rep);
205             xcb_xv_encoding_info_t *encoding;
206
207             int ImageEncodings = 0;
208             if (nencode) {
209                 int n;
210                 for (n = 0; n < nencode; n++) {
211                     encoding = encoding_iter.data;
212                     name = ExtractString(xcb_xv_encoding_info_name(encoding), xcb_xv_encoding_info_name_length(encoding));
213                     if (!nstrcmp(name, strlen(name), "XV_IMAGE"))
214                         ImageEncodings++;
215                     xcb_xv_encoding_info_next(&encoding_iter);
216                     free(name);
217                 }
218
219                 if(nencode - ImageEncodings) {
220                     fprintf(stdout, "    number of encodings: %i\n", nencode - ImageEncodings);
221
222                     /* Reset the iter. */
223                     encoding_iter = xcb_xv_query_encodings_info_iterator(qencodings_rep);
224                     for(n = 0; n < nencode; n++) {
225                         encoding = encoding_iter.data;
226                         name = ExtractString(xcb_xv_encoding_info_name(encoding), xcb_xv_encoding_info_name_length(encoding));
227                         if(nstrcmp(name, strlen(name), "XV_IMAGE")) {
228                             fprintf(stdout,
229                                     "      encoding ID #%i: \"%*s\"\n",
230                                     encoding->encoding,
231                                     strlen(name),
232                                     name);
233                             fprintf(stdout, "        size: %i x %i\n",
234                                     encoding->width,
235                                     encoding->height);
236                             fprintf(stdout, "        rate: %f\n",
237                                     (float)encoding->rate.numerator/
238                                     (float)encoding->rate.denominator);
239                             free(name);
240                         }
241                         xcb_xv_encoding_info_next(&encoding_iter);
242                     }
243                 }
244
245                 if(ImageEncodings && (ainfo->type & XCB_XV_TYPE_IMAGE_MASK)) {
246                     char imageName[5] = {0, 0, 0, 0, 0};
247                     encoding_iter = xcb_xv_query_encodings_info_iterator(qencodings_rep);
248                     for(n = 0; n < nencode; n++) {
249                         encoding = encoding_iter.data;
250                         name = ExtractString(xcb_xv_encoding_info_name(encoding), xcb_xv_encoding_info_name_length(encoding));
251                         if(!nstrcmp(name, strlen(name), "XV_IMAGE")) {
252                             fprintf(stdout, 
253                                     "    maximum XvImage size: %i x %i\n",      
254                                     encoding->width, encoding->height);
255                             break;
256                         }
257                         free(name);
258                     }
259                     xcb_xv_list_image_formats_reply_t *formats_rep;
260                     formats_rep = xcb_xv_list_image_formats_reply(c,
261                             xcb_xv_list_image_formats(c, ainfo->base_id),
262                             NULL);
263
264                     int numImages = formats_rep->num_formats;
265                     xcb_xv_image_format_info_t *format;
266                     xcb_xv_image_format_info_iterator_t formats_iter = xcb_xv_list_image_formats_format_iterator(formats_rep);
267                     fprintf(stdout, "    Number of image formats: %i\n",
268                             numImages);
269
270                     for(n = 0; n < numImages; n++) {
271                         format = formats_iter.data;
272                         memcpy(imageName, &(format->id), 4);
273                         fprintf(stdout, "      id: 0x%x", format->id);
274                         if(isprint(imageName[0]) && isprint(imageName[1]) &&
275                                 isprint(imageName[2]) && isprint(imageName[3])) 
276                         {
277                             fprintf(stdout, " (%s)\n", imageName);
278                         } else {
279                             fprintf(stdout, "\n");
280                         }
281                         fprintf(stdout, "        guid: ");
282                         fprintf(stdout, "%02x", (unsigned char) 
283                                 format->guid[0]);
284                         fprintf(stdout, "%02x", (unsigned char) 
285                                 format->guid[1]);
286                         fprintf(stdout, "%02x", (unsigned char) 
287                                 format->guid[2]);
288                         fprintf(stdout, "%02x-", (unsigned char) 
289                                 format->guid[3]);
290                         fprintf(stdout, "%02x", (unsigned char) 
291                                 format->guid[4]);
292                         fprintf(stdout, "%02x-", (unsigned char) 
293                                 format->guid[5]);
294                         fprintf(stdout, "%02x", (unsigned char) 
295                                 format->guid[6]);
296                         fprintf(stdout, "%02x-", (unsigned char) 
297                                 format->guid[7]);
298                         fprintf(stdout, "%02x", (unsigned char) 
299                                 format->guid[8]);
300                         fprintf(stdout, "%02x-", (unsigned char) 
301                                 format->guid[9]);
302                         fprintf(stdout, "%02x", (unsigned char) 
303                                 format->guid[10]);
304                         fprintf(stdout, "%02x", (unsigned char) 
305                                 format->guid[11]);
306                         fprintf(stdout, "%02x", (unsigned char) 
307                                 format->guid[12]);
308                         fprintf(stdout, "%02x", (unsigned char) 
309                                 format->guid[13]);
310                         fprintf(stdout, "%02x", (unsigned char) 
311                                 format->guid[14]);
312                         fprintf(stdout, "%02x\n", (unsigned char) 
313                                 format->guid[15]);
314
315                         fprintf(stdout, "        bits per pixel: %i\n",
316                                 format->bpp);
317                         fprintf(stdout, "        number of planes: %i\n",
318                                 format->num_planes);
319                         fprintf(stdout, "        type: %s (%s)\n", 
320                                 (format->type == XCB_XV_IMAGE_FORMAT_INFO_TYPE_RGB) ? "RGB" : "YUV",
321                                 (format->format == XCB_XV_IMAGE_FORMAT_INFO_FORMAT_PACKED) ? "packed" : "planar");
322
323                         if(format->type == XCB_XV_IMAGE_FORMAT_INFO_TYPE_RGB) {
324                             fprintf(stdout, "        depth: %i\n", 
325                                     format->depth);
326
327                             fprintf(stdout, "        red, green, blue masks: " 
328                                     "0x%x, 0x%x, 0x%x\n", 
329                                     format->red_mask,
330                                     format->green_mask,
331                                     format->blue_mask);
332                         } else {
333
334                         }
335                         xcb_xv_image_format_info_next(&formats_iter);
336                     }
337                     free(formats_rep);
338                 }
339             }
340             free(qencodings_rep);
341             xcb_xv_adaptor_info_next(&adaptors_iter);
342         }
343         free(adaptors_rep);
344     }
345
346     return 0;
347 }