soiffer@tekcrl.TEK.COM (Neil Soiffer) (07/21/87)
The lesson I learned was "never ask people if they want free software."
Below is the modified 'xwininfo' command. To get "toolplaces"-like info,
use the 'xterm' and 'root' flags. The info is written to stdout.
With a minor amount of editing, this output can be used in a start up file.
Here is an example of the output (for a single window):
xterm -n "rlogin tekchips -e" -bw 2 =80x64+588+-3 #188x32+396+-4 -sb -tb
-------------------------------------
#include <X/mit-copyright.h>
/* Copyright 1985, Massachusetts Institute of Technology */
/*
* xwininfo.c - MIT Project Athena, X Window system window
* information utility.
*
* This program will report all relavent information
* about a specific window.
*
* Author: Tony Della Fera, DEC
* 27-Nov-84
* Modifications:
* 'xterm' flag 4/87 -- Neil Soiffer, Tektronix Computer Research Lab
*/
#ifndef lint
static char *rcsid_xhost_c = "$Header: xwininfo.c,v 1.2 87/01/28 11:15:33 toddb Exp $";
#endif
#include <X/Xlib.h>
#include <stdio.h>
#include "../cursors/target.cursor"
#include "../cursors/target_mask.cursor"
#include <strings.h>
typedef enum _bool {FALSE, TRUE} Bool;
#define MAX(a, b) (a) > (b) ? (a) : (b)
#define MIN(a, b) (a) < (b) ? (a) : (b)
#define ABS(a) (a) < 0 ? -(a) : (a)
#define FAILURE 0
char *index();
extern int errno;
main(argc, argv)
int argc;
char **argv;
{
int mse_x, mse_y;
int rel_mse_x, rel_mse_y;
int w0, h0, w_inc, h_inc;
int lr_rel_x, lr_rel_y;
int root_w, root_h;
int num_children;
int status;
char display[256];
char *strind = NULL;
char *win_name = NULL;
char *id = NULL;
char *win_fmt = " 0x%x\n";
Bool children = FALSE;
Bool root_switch = FALSE;
Bool xterm_switch = FALSE;
register int i;
Window target_win;
Window temp_win;
Window parent_win;
Window *child_list;
WindowInfo win_info;
Cursor cursor;
XButtonPressedEvent event;
display[0] = '\0';
for (i = 1; i < argc; i++) {
strind = index(argv[i], ':');
if (strind != NULL) {
(void) strncpy(display, argv[i], sizeof(display));
continue;
}
strind = index (argv [i], '-');
if (strind == NULL) Syntax(argv[0]);
if (strncmp(argv [i], "-children", 9) == 0) {
children = TRUE;
continue;
}
if (strncmp(argv [i], "-help", 5) == 0) {
Syntax(argv[0]);
}
if (strncmp(argv [i], "-id", 3) == 0) {
if (++i >= argc) Syntax(argv[0]);
id = argv[i];
continue;
}
if (strncmp(argv [i], "-int", 4) == 0) {
win_fmt = " %d\n";
continue;
}
if (strncmp(argv [i], "-root", 5) == 0) {
root_switch = TRUE;
continue;
}
if (strncmp(argv [i], "-xterm", 6) == 0) {
xterm_switch = TRUE;
continue;
}
Syntax(argv[0]);
}
if (XOpenDisplay(display) == NULL) {
fprintf(stderr, "%s: Can't open display '%s'\n",
argv[0], XDisplayName(display));
exit(1);
}
/*
* Store the target cursor incase we need it.
*/
cursor = XCreateCursor(
target_width, target_height,
target_bits, target_mask_bits,
8, 8,
BlackPixel, WhitePixel,
GXcopy
);
if (cursor == FAILURE) {
Error("Error occured while trying to store target cursor.");
}
/*
* Depending on the state of the root and id switches, get the
* target window from the user.
*/
if (root_switch) {
/*
* The root window selected on the command line.
*/
target_win = RootWindow;
}
else {
if (id != NULL) {
/*
* A window id was provided on the command line.
*/
(void) sscanf(id, "0x%x", &target_win);
if (target_win == 0) {
/*
* Then the target was entered in decimal.
*/
(void) sscanf(id, "%d", &target_win);
if (target_win == 0) {
Error("Invalid window id format.");
}
}
}
else {
/*
* No selection was provided on the command line.
* Allow the user to select a window with the mouse.
*/
status = XGrabMouse(RootWindow, cursor, ButtonPressed);
if (status == FAILURE) Error("Can't grab the mouse.");
printf("\n");
printf("xwininfo ==> Please select the window you wish\n");
printf(" ==> information on by clicking the\n");
printf(" ==> mouse in that window.\n");
XNextEvent(&event);
target_win = event.subwindow;
XUngrabMouse();
if (target_win == 0) {
/*
* The user must have indicated the root window.
*/
target_win = RootWindow;
}
}
}
status = XQueryMouse(RootWindow, &mse_x, &mse_y, &temp_win);
if (status == FAILURE) Error("Can't query mouse on Root Window.");
if (target_win == RootWindow){
rel_mse_x = mse_x;
rel_mse_y = mse_y;
}
else {
status = XQueryMouse(target_win, &rel_mse_x, &rel_mse_y, &temp_win);
if (status == FAILURE) Error("Can't query mouse on target window.");
}
status = XQueryWindow(RootWindow, &win_info);
if (status == FAILURE) Error("Couldn't query root window.");
root_w = win_info.width;
root_h = win_info.height;
status = XQueryWindow(target_win, &win_info);
if (status == FAILURE) Error("Couldn't query target window.");
lr_rel_x = root_w - (win_info.x + win_info.width +
(win_info.bdrwidth << 1));
lr_rel_y = root_h - (win_info.y + win_info.height +
(win_info.bdrwidth << 1));
status = XFetchName(target_win, &win_name);
if (status == FAILURE) Error("Can't fetch window name.");
status = XQueryTree(target_win, &parent_win, &num_children, &child_list);
if (status == FAILURE) Error("Can't query window tree.");
if (xterm_switch) {
if (root_switch) {
for (i = num_children - 1; i >= 0; i--) {
printAsXTerm(child_list[i]);
}
} else {
printAsXTerm(target_win);
}
exit(0);
}
(void) XGetResizeHint(target_win, &w0, &h0, &w_inc, &h_inc);
printf("\nxwininfo ==> Window name: '%s'\n", win_name);
printf(" ==> Window id:");
printf(win_fmt, target_win);
printf(" ==> Parent window id:");
printf(win_fmt, parent_win);
printf(" ==> Number of children: %d\n", num_children);
if (children) {
for (i = num_children - 1; i >= 0; i--) {
printf(" ==> Child window id:");
printf(win_fmt, child_list[i]);
}
}
printf(" ==> Associated window id:");
printf(win_fmt, win_info.assoc_wind);
printf(" ==> Window type: ");
switch (win_info.type) {
case IsTransparent:
printf("IsTransparent\n");
break;
case IsOpaque:
printf("IsOpaque\n");
break;
case IsIcon:
printf("IsIcon\n");
break;
default:
printf("Unknown %d?\n", win_info.type);
break;
}
printf(" ==> Window state: ");
switch (win_info.mapped) {
case IsMapped:
printf("IsMapped\n");
break;
case IsUnmapped:
printf("IsUnmapped\n");
break;
case IsInvisible:
printf("IsInvisible\n");
break;
default:
printf("Unknown %d?\n", win_info.mapped);
break;
}
printf(" ==> Upper left X: %d\n", win_info.x);
printf(" ==> Upper left Y: %d\n", win_info.y);
printf(" ==> Width: %d\n", win_info.width);
printf(" ==> Height: %d\n", win_info.height);
printf(" ==> Border width: %d\n", win_info.bdrwidth);
printf(" ==> Geometry specification:\n");
printf(" ==> Upper left =%dx%d+%d+%d\n",
win_info.width, win_info.height, win_info.x, win_info.y);
printf(" ==> Lower right =%dx%d-%d-%d\n",
win_info.width, win_info.height, lr_rel_x, lr_rel_y);
printf(" ==> Resize base width: %d\n", w0);
printf(" ==> Resize base height: %d\n", h0);
printf(" ==> Resize width increment: %d\n", w_inc);
printf(" ==> Resize height increment: %d\n", h_inc);
printf(" ==> Root absolute mouse X Position: %d\n", mse_x);
printf(" ==> Root absolute mouse Y Position: %d\n", mse_y);
printf(" ==> Target relative mouse X Position: %d\n", rel_mse_x);
printf(" ==> Target relative mouse Y Position: %d\n", rel_mse_y);
printf("\n");
exit(0);
}
/*
* Print out window info as if the window were an xterm window.
* Information is only printed if the window is mapped -- hence a window
* and its icon can both be passed to this procedure and only one will
* print info.
*
* If an icon does not have an associated window (is this possible?), then
* it can't be an xterm window, and no info is printed.
*/
printAsXTerm(w)
Window w; /* Child window of RootWindow. */
{
WindowInfo info, infoIcon;
Status status;
Status statusIcon = 0;
int isIcon, hasTitle, hasScrollbar, isXterm;
char *name;
int w0, h0, wInc, hInc;
XQueryWindow(w, &info);
if (info.mapped != IsMapped) {
return;
}
isIcon = (info.type == IsIcon);
if (isIcon) {
statusIcon = 1;
infoIcon = info;
w = infoIcon.assoc_wind;
status = XQueryWindow(w, &info);
if (status == NULL) {
return;
}
} else if (info.assoc_wind != NULL) {
statusIcon = XQueryWindow(info.assoc_wind, &infoIcon);
}
isXterm = checkStructure(w, &hasTitle, &hasScrollbar);
isXterm &= statusIcon; /* All xterm's have icons. */
XFetchName(w, &name);
(void) XGetResizeHint(w, &w0, &h0, &wInc, &hInc);
printf("%s -n \"%s\" -bw %d", isXterm ? "xterm":"xxx", name, info.bdrwidth);
if ((wInc > 1) || (hInc > 1)) {
printf(" =%dx%d+%d+%d",
(info.width-w0)/wInc, (info.height-h0)/hInc, info.x, info.y);
} else {
printf(" %s%dx%d+%d+%d",isXterm ? "%" : "=",
info.width, info.height, info.x, info.y);
}
if (statusIcon) {
printf(" #%dx%d+%d+%d",
infoIcon.width, infoIcon.height, infoIcon.x, infoIcon.y);
}
if (isXterm) {
printf(" %ssb %stb", hasScrollbar ? "-":"+", hasTitle ? "+":"-");
}
printf(" %s\n", isIcon ? "-i" : "");
free(name);
}
/* checkStructure -- returns 0/1 if window is an xterm window
* 'hasTitle' and 'hasScrollbar' are set window is an xterm window.
*/
int
checkStructure(w, hasTitle, hasScrollbar)
Window w;
int *hasTitle, *hasScrollbar;
{
Window parentWin;
Window *childList;
int numChildren;
Status status;
WindowInfo info;
int ans = 0;
status = XQueryTree(w, &parentWin, &numChildren, &childList);
if (!status) {
/* Shouldn't happen -- return some "negative" values. */
*hasTitle = *hasScrollbar = 0;
return 0;
}
/* Figure out title, scrollbar status based on number of children.
* We assume that if the child is at 'x > 0' , then it must be a
* scrollbar (as opposed to a title bar).
*/
*hasTitle = *hasScrollbar = 0;
switch (numChildren) {
case 0:
ans = 1;
break;
case 2:
XQueryWindow(childList[1], &info);
if (info.mapped != IsUnmapped) {
if (info.x > 0) {
*hasScrollbar = 1;
} else {
*hasTitle = 1;
}
}
case 1:
XQueryWindow(childList[0], &info);
if (info.mapped != IsUnmapped) {
if (info.x > 0) {
*hasScrollbar = 1;
} else {
*hasTitle = 1;
}
}
ans = 1;
break;
}
if (numChildren > 0) free((char *) childList);
return ans;
}
/*
* Report the syntax for calling xwininfo.
*/
Syntax(call)
char *call;
{
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [-children] [-help] [-id <id>] [-int] ", call);
fprintf(stderr, "[-root] [-xterm] [[host]:vs]\n\n");
exit(0);
}
/*
* Error - Fatal xwininfo error.
*/
Error(string)
char *string; /* Error description string. */
{
fprintf(stderr, "\nxwininfo: %s", string);
fprintf(stderr, "\n\n");
if (errno != 0) {
perror("xwininfo");
fprintf(stderr, "\n");
}
exit(1);
}