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); }