1706f2543Smrg/* 2706f2543Smrg * Copyright 2001,2002 Red Hat Inc., Durham, North Carolina. 3706f2543Smrg * 4706f2543Smrg * All Rights Reserved. 5706f2543Smrg * 6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 7706f2543Smrg * a copy of this software and associated documentation files (the 8706f2543Smrg * "Software"), to deal in the Software without restriction, including 9706f2543Smrg * without limitation on the rights to use, copy, modify, merge, 10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 11706f2543Smrg * and to permit persons to whom the Software is furnished to do so, 12706f2543Smrg * subject to the following conditions: 13706f2543Smrg * 14706f2543Smrg * The above copyright notice and this permission notice (including the 15706f2543Smrg * next paragraph) shall be included in all copies or substantial 16706f2543Smrg * portions of the Software. 17706f2543Smrg * 18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21706f2543Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25706f2543Smrg * SOFTWARE. 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg/* 29706f2543Smrg * Authors: 30706f2543Smrg * Rickard E. (Rik) Faith <faith@redhat.com> 31706f2543Smrg * 32706f2543Smrg */ 33706f2543Smrg 34706f2543Smrg#include <stdio.h> 35706f2543Smrg#include <stdlib.h> 36706f2543Smrg#include <X11/Xlib.h> 37706f2543Smrg#include <X11/extensions/dmxext.h> 38706f2543Smrg 39706f2543Smrgstatic void indent(int level) 40706f2543Smrg{ 41706f2543Smrg int i; 42706f2543Smrg for (i = 0; i < level; i++) printf(" "); 43706f2543Smrg} 44706f2543Smrg 45706f2543Smrgstatic void print_window_id(const char *displayName, Display *display, 46706f2543Smrg Window window, int level, int child) 47706f2543Smrg{ 48706f2543Smrg char *name; 49706f2543Smrg 50706f2543Smrg if (!XFetchName(display, window, &name)) name = NULL; 51706f2543Smrg indent(level); 52706f2543Smrg if (child) printf("(%d) ", child); 53706f2543Smrg printf("%s window 0x%08lx: %s%s\n", 54706f2543Smrg displayName, 55706f2543Smrg (long unsigned)window, 56706f2543Smrg name ? name : "", 57706f2543Smrg (window == DefaultRootWindow(display)) 58706f2543Smrg ? " (DMX root window)" : ""); 59706f2543Smrg if (name) XFree(name); 60706f2543Smrg} 61706f2543Smrg 62706f2543Smrgstatic void print_info(Display *display, Window window, int level, int child) 63706f2543Smrg{ 64706f2543Smrg DMXWindowAttributes winfo[128]; 65706f2543Smrg int count; 66706f2543Smrg int i; 67706f2543Smrg 68706f2543Smrg if (!DMXGetWindowAttributes(display, window, &count, 128, winfo)) { 69706f2543Smrg printf("Could not get window information for 0x%08lx\n", 70706f2543Smrg (long unsigned)window); 71706f2543Smrg exit(-2); 72706f2543Smrg } 73706f2543Smrg printf("\n"); 74706f2543Smrg print_window_id("DMX", display, window, level, child); 75706f2543Smrg for (i = 0; i < count; i++) { 76706f2543Smrg DMXScreenAttributes sinfo; 77706f2543Smrg Display *backend; 78706f2543Smrg 79706f2543Smrg /* This could also be cached -- the information doesn't change. */ 80706f2543Smrg if (!DMXGetScreenAttributes(display, winfo[i].screen, &sinfo)) { 81706f2543Smrg printf("Could not get screen information for screen %d\n", i); 82706f2543Smrg exit(-2); 83706f2543Smrg } 84706f2543Smrg if (!(backend = XOpenDisplay(sinfo.displayName))) { 85706f2543Smrg printf("Cannot open backend display %s\n", sinfo.displayName); 86706f2543Smrg exit(-2); 87706f2543Smrg } 88706f2543Smrg XCloseDisplay(backend); 89706f2543Smrg 90706f2543Smrg indent(level+1); 91706f2543Smrg printf("%s window 0x%08lx: %dx%d%+d%+d", 92706f2543Smrg sinfo.displayName, 93706f2543Smrg (long unsigned)winfo[i].window, 94706f2543Smrg winfo[i].pos.width, winfo[i].pos.height, 95706f2543Smrg winfo[i].pos.x, winfo[i].pos.y); 96706f2543Smrg if (!winfo[i].vis.width 97706f2543Smrg && !winfo[i].vis.height 98706f2543Smrg && !winfo[i].vis.x 99706f2543Smrg && !winfo[i].vis.y) printf(" not visible\n"); 100706f2543Smrg else if (winfo[i].vis.width == winfo[i].pos.width 101706f2543Smrg && winfo[i].vis.height == winfo[i].pos.height) { 102706f2543Smrg printf( " %+d%+d\n", winfo[i].vis.x, winfo[i].vis.y); 103706f2543Smrg } else { 104706f2543Smrg printf( " %dx%d%+d%+d\n", 105706f2543Smrg winfo[i].vis.width, winfo[i].vis.height, 106706f2543Smrg winfo[i].vis.x, winfo[i].vis.y); 107706f2543Smrg } 108706f2543Smrg } 109706f2543Smrg} 110706f2543Smrg 111706f2543Smrgstatic void print_tree(Display *display, Window window, int level, int child) 112706f2543Smrg{ 113706f2543Smrg Window root, parent; 114706f2543Smrg Window *list; 115706f2543Smrg unsigned int count; 116706f2543Smrg unsigned int i; 117706f2543Smrg 118706f2543Smrg print_info(display, window, level, child); 119706f2543Smrg 120706f2543Smrg if (!XQueryTree(display, window, &root, &parent, &list, &count)) { 121706f2543Smrg printf("Cannot query window tree for 0x%08lx\n", 122706f2543Smrg (long unsigned)window); 123706f2543Smrg exit(-3); 124706f2543Smrg } 125706f2543Smrg 126706f2543Smrg if (count) { 127706f2543Smrg indent(level+1); 128706f2543Smrg printf("%d child%s:\n", count, count > 1 ? "ren" : ""); 129706f2543Smrg for (i = 0; i < count; i++) { 130706f2543Smrg print_tree(display, list[i], level+1, i+1); 131706f2543Smrg } 132706f2543Smrg } 133706f2543Smrg} 134706f2543Smrg 135706f2543Smrgstatic const char *core(DMXInputAttributes *iinfo) 136706f2543Smrg{ 137706f2543Smrg if (iinfo->isCore) return "core"; 138706f2543Smrg else if (iinfo->sendsCore) return "extension (sends core)"; 139706f2543Smrg else return "extension"; 140706f2543Smrg} 141706f2543Smrg 142706f2543Smrgint main(int argc, char **argv) 143706f2543Smrg{ 144706f2543Smrg Display *display = NULL; 145706f2543Smrg Window window = 0; 146706f2543Smrg int event_base; 147706f2543Smrg int error_base; 148706f2543Smrg int major_version, minor_version, patch_version; 149706f2543Smrg DMXScreenAttributes sinfo; 150706f2543Smrg DMXInputAttributes iinfo; 151706f2543Smrg int count; 152706f2543Smrg int i; 153706f2543Smrg 154706f2543Smrg if (argc == 2 || argc == 3) { 155706f2543Smrg if (!(display = XOpenDisplay(argv[1]))) { 156706f2543Smrg printf("Cannot open display %s\n", argv[1]); 157706f2543Smrg return -1; 158706f2543Smrg } 159706f2543Smrg if (argc == 3) window = strtol(argv[2], NULL, 0); 160706f2543Smrg } else { 161706f2543Smrg printf("Usage: %s display [windowid]\n", argv[0]); 162706f2543Smrg return -1; 163706f2543Smrg } 164706f2543Smrg 165706f2543Smrg if (!display && !(display = XOpenDisplay(NULL))) { 166706f2543Smrg printf("Cannot open default display\n"); 167706f2543Smrg return -1; 168706f2543Smrg } 169706f2543Smrg 170706f2543Smrg if (!DMXQueryExtension(display, &event_base, &error_base)) { 171706f2543Smrg printf("DMX extension not present\n"); 172706f2543Smrg return -1; 173706f2543Smrg } 174706f2543Smrg printf("DMX extension present: event_base = %d, error_base = %d\n", 175706f2543Smrg event_base, error_base); 176706f2543Smrg 177706f2543Smrg if (!DMXQueryVersion(display, 178706f2543Smrg &major_version, &minor_version, &patch_version)) { 179706f2543Smrg printf("Could not get extension version\n"); 180706f2543Smrg return -1; 181706f2543Smrg } 182706f2543Smrg printf("Extension version: %d.%d patch %d\n", 183706f2543Smrg major_version, minor_version, patch_version); 184706f2543Smrg 185706f2543Smrg if (!DMXGetScreenCount(display, &count)) { 186706f2543Smrg printf("Could not get screen count\n"); 187706f2543Smrg return -1; 188706f2543Smrg } 189706f2543Smrg printf("Screen count = %d\n", count); 190706f2543Smrg 191706f2543Smrg for (i = 0; i < count; i++) { 192706f2543Smrg if (!DMXGetScreenAttributes(display, i, &sinfo)) { 193706f2543Smrg printf("Could not get screen information for %d\n", i); 194706f2543Smrg return -1; 195706f2543Smrg } 196706f2543Smrg printf("%d: %s %ux%u+%d+%d %d @%dx%d (root: %dx%d%+d%+d)\n", 197706f2543Smrg i, sinfo.displayName, 198706f2543Smrg sinfo.screenWindowWidth, sinfo.screenWindowHeight, 199706f2543Smrg sinfo.screenWindowXoffset, sinfo.screenWindowYoffset, 200706f2543Smrg sinfo.logicalScreen, 201706f2543Smrg sinfo.rootWindowXorigin, sinfo.rootWindowYorigin, 202706f2543Smrg sinfo.rootWindowWidth, sinfo.rootWindowHeight, 203706f2543Smrg sinfo.rootWindowXoffset, sinfo.rootWindowYoffset); 204706f2543Smrg } 205706f2543Smrg 206706f2543Smrg if (major_version == 1 && minor_version >= 1) { 207706f2543Smrg if (!DMXGetInputCount(display, &count)) { 208706f2543Smrg printf("Could not get input count\n"); 209706f2543Smrg return -1; 210706f2543Smrg } 211706f2543Smrg printf("Input count = %d\n", count); 212706f2543Smrg for (i = 0; i < count; i++) { 213706f2543Smrg if (!DMXGetInputAttributes(display, i, &iinfo)) { 214706f2543Smrg printf("Could not get input information for id %d\n", i); 215706f2543Smrg return -1; 216706f2543Smrg } 217706f2543Smrg switch (iinfo.inputType) { 218706f2543Smrg case DMXLocalInputType: 219706f2543Smrg printf(" %2d local %-20.20s %s\n", i, "", core(&iinfo)); 220706f2543Smrg break; 221706f2543Smrg case DMXConsoleInputType: 222706f2543Smrg printf(" %2d console %-20.20s %s\n", 223706f2543Smrg i, iinfo.name, core(&iinfo)); 224706f2543Smrg break; 225706f2543Smrg case DMXBackendInputType: 226706f2543Smrg printf(" %2d backend %-20.20s id=%2d screen=%2d %s\n", 227706f2543Smrg i, iinfo.name, iinfo.physicalId, iinfo.physicalScreen, 228706f2543Smrg core(&iinfo)); 229706f2543Smrg break; 230706f2543Smrg } 231706f2543Smrg } 232706f2543Smrg } 233706f2543Smrg 234706f2543Smrg if (window) print_info(display, window, 0, 0); 235706f2543Smrg else print_tree(display, DefaultRootWindow(display), 0, 0); 236706f2543Smrg 237706f2543Smrg XCloseDisplay(display); 238706f2543Smrg return 0; 239706f2543Smrg} 240