1 /*
2  * Copyright 2001,2002 Red Hat Inc., Durham, North Carolina.
3  *
4  * All Rights Reserved.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation on the rights to use, copy, modify, merge,
10  * publish, distribute, sublicense, and/or sell copies of the Software,
11  * and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial
16  * portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25  * SOFTWARE.
26  */
27 
28 /*
29  * Authors:
30  *   Rickard E. (Rik) Faith <faith@redhat.com>
31  *
32  */
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <X11/Xlib.h>
37 #include <X11/extensions/dmxext.h>
38 
39 static void
indent(int level)40 indent(int level)
41 {
42     int i;
43 
44     for (i = 0; i < level; i++)
45         printf("    ");
46 }
47 
48 static void
print_window_id(const char * displayName,Display * display,Window window,int level,int child)49 print_window_id(const char *displayName, Display * display,
50                 Window window, int level, int child)
51 {
52     char *name;
53 
54     if (!XFetchName(display, window, &name))
55         name = NULL;
56     indent(level);
57     if (child)
58         printf("(%d) ", child);
59     printf("%s window 0x%08lx: %s%s\n",
60            displayName,
61            (long unsigned) window,
62            name ? name : "", (window == DefaultRootWindow(display))
63            ? " (DMX root window)" : "");
64     if (name)
65         XFree(name);
66 }
67 
68 static void
print_info(Display * display,Window window,int level,int child)69 print_info(Display * display, Window window, int level, int child)
70 {
71     DMXWindowAttributes winfo[128];
72     int count;
73     int i;
74 
75     if (!DMXGetWindowAttributes(display, window, &count, 128, winfo)) {
76         printf("Could not get window information for 0x%08lx\n",
77                (long unsigned) window);
78         exit(-2);
79     }
80     printf("\n");
81     print_window_id("DMX", display, window, level, child);
82     for (i = 0; i < count; i++) {
83         DMXScreenAttributes sinfo;
84         Display *backend;
85 
86         /* This could also be cached -- the information doesn't change. */
87         if (!DMXGetScreenAttributes(display, winfo[i].screen, &sinfo)) {
88             printf("Could not get screen information for screen %d\n", i);
89             exit(-2);
90         }
91         if (!(backend = XOpenDisplay(sinfo.displayName))) {
92             printf("Cannot open backend display %s\n", sinfo.displayName);
93             exit(-2);
94         }
95         XCloseDisplay(backend);
96 
97         indent(level + 1);
98         printf("%s window 0x%08lx: %dx%d%+d%+d",
99                sinfo.displayName,
100                (long unsigned) winfo[i].window,
101                winfo[i].pos.width, winfo[i].pos.height,
102                winfo[i].pos.x, winfo[i].pos.y);
103         if (!winfo[i].vis.width
104             && !winfo[i].vis.height && !winfo[i].vis.x && !winfo[i].vis.y)
105             printf(" not visible\n");
106         else if (winfo[i].vis.width == winfo[i].pos.width
107                  && winfo[i].vis.height == winfo[i].pos.height) {
108             printf(" %+d%+d\n", winfo[i].vis.x, winfo[i].vis.y);
109         }
110         else {
111             printf(" %dx%d%+d%+d\n",
112                    winfo[i].vis.width, winfo[i].vis.height,
113                    winfo[i].vis.x, winfo[i].vis.y);
114         }
115     }
116 }
117 
118 static void
print_tree(Display * display,Window window,int level,int child)119 print_tree(Display * display, Window window, int level, int child)
120 {
121     Window root, parent;
122     Window *list;
123     unsigned int count;
124     unsigned int i;
125 
126     print_info(display, window, level, child);
127 
128     if (!XQueryTree(display, window, &root, &parent, &list, &count)) {
129         printf("Cannot query window tree for 0x%08lx\n",
130                (long unsigned) window);
131         exit(-3);
132     }
133 
134     if (count) {
135         indent(level + 1);
136         printf("%d child%s:\n", count, count > 1 ? "ren" : "");
137         for (i = 0; i < count; i++) {
138             print_tree(display, list[i], level + 1, i + 1);
139         }
140     }
141 }
142 
143 static const char *
core(DMXInputAttributes * iinfo)144 core(DMXInputAttributes * iinfo)
145 {
146     if (iinfo->isCore)
147         return "core";
148     else if (iinfo->sendsCore)
149         return "extension (sends core)";
150     else
151         return "extension";
152 }
153 
154 int
main(int argc,char ** argv)155 main(int argc, char **argv)
156 {
157     Display *display = NULL;
158     Window window = 0;
159     int event_base;
160     int error_base;
161     int major_version, minor_version, patch_version;
162     DMXScreenAttributes sinfo;
163     DMXInputAttributes iinfo;
164     int count;
165     int i;
166 
167     if (argc == 2 || argc == 3) {
168         if (!(display = XOpenDisplay(argv[1]))) {
169             printf("Cannot open display %s\n", argv[1]);
170             return -1;
171         }
172         if (argc == 3)
173             window = strtol(argv[2], NULL, 0);
174     }
175     else {
176         printf("Usage: %s display [windowid]\n", argv[0]);
177         return -1;
178     }
179 
180     if (!display && !(display = XOpenDisplay(NULL))) {
181         printf("Cannot open default display\n");
182         return -1;
183     }
184 
185     if (!DMXQueryExtension(display, &event_base, &error_base)) {
186         printf("DMX extension not present\n");
187         return -1;
188     }
189     printf("DMX extension present: event_base = %d, error_base = %d\n",
190            event_base, error_base);
191 
192     if (!DMXQueryVersion(display,
193                          &major_version, &minor_version, &patch_version)) {
194         printf("Could not get extension version\n");
195         return -1;
196     }
197     printf("Extension version: %d.%d patch %d\n",
198            major_version, minor_version, patch_version);
199 
200     if (!DMXGetScreenCount(display, &count)) {
201         printf("Could not get screen count\n");
202         return -1;
203     }
204     printf("Screen count = %d\n", count);
205 
206     for (i = 0; i < count; i++) {
207         if (!DMXGetScreenAttributes(display, i, &sinfo)) {
208             printf("Could not get screen information for %d\n", i);
209             return -1;
210         }
211         printf("%d: %s %ux%u+%d+%d %d @%dx%d (root: %dx%d%+d%+d)\n",
212                i, sinfo.displayName,
213                sinfo.screenWindowWidth, sinfo.screenWindowHeight,
214                sinfo.screenWindowXoffset, sinfo.screenWindowYoffset,
215                sinfo.logicalScreen,
216                sinfo.rootWindowXorigin, sinfo.rootWindowYorigin,
217                sinfo.rootWindowWidth, sinfo.rootWindowHeight,
218                sinfo.rootWindowXoffset, sinfo.rootWindowYoffset);
219     }
220 
221     if (major_version == 1 && minor_version >= 1) {
222         if (!DMXGetInputCount(display, &count)) {
223             printf("Could not get input count\n");
224             return -1;
225         }
226         printf("Input count = %d\n", count);
227         for (i = 0; i < count; i++) {
228             if (!DMXGetInputAttributes(display, i, &iinfo)) {
229                 printf("Could not get input information for id %d\n", i);
230                 return -1;
231             }
232             switch (iinfo.inputType) {
233             case DMXLocalInputType:
234                 printf("  %2d local   %-20.20s %s\n", i, "", core(&iinfo));
235                 break;
236             case DMXConsoleInputType:
237                 printf("  %2d console %-20.20s %s\n",
238                        i, iinfo.name, core(&iinfo));
239                 break;
240             case DMXBackendInputType:
241                 printf("  %2d backend %-20.20s id=%2d screen=%2d %s\n",
242                        i, iinfo.name, iinfo.physicalId, iinfo.physicalScreen,
243                        core(&iinfo));
244                 break;
245             }
246         }
247     }
248 
249     if (window)
250         print_info(display, window, 0, 0);
251     else
252         print_tree(display, DefaultRootWindow(display), 0, 0);
253 
254     XCloseDisplay(display);
255     return 0;
256 }
257