diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-07-08 20:46:52 -0400 |
commit | fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch) | |
tree | bdda434976bc09c864f2e4fa6f16ba1952b1e555 /vendor/x11iraf/obm/geom.c | |
download | iraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz |
Initial commit
Diffstat (limited to 'vendor/x11iraf/obm/geom.c')
-rw-r--r-- | vendor/x11iraf/obm/geom.c | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/vendor/x11iraf/obm/geom.c b/vendor/x11iraf/obm/geom.c new file mode 100644 index 00000000..ac5db512 --- /dev/null +++ b/vendor/x11iraf/obm/geom.c @@ -0,0 +1,179 @@ +/* Copyright(c) 1993 Association of Universities for Research in Astronomy Inc. + */ +/* Copyright 1987, Massachusetts Institute of Technology */ + +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <stdio.h> + +/* + * GEOM.C -- Code to get geometry information for a window. This code was + * extracted from the xwininfo sources and hacked into the form of a library + * routine. + */ + +#define SZ_GEOMETRY 64 +static char geometry[SZ_GEOMETRY]; +static Display *dpy; + + +/* get_geometry -- Return the absolute size and position of a window. The + * geometry specification coresponding to the window size and position is + * returned as the function value. + */ +char * +get_geometry (display, screen, window, origin) + Display *display; + Screen *screen; + Window window; + int origin; /* return only origin-relative coords */ +{ + register char *op; + int screen_number = XScreenNumberOfScreen (screen); + XWindowAttributes win_attributes; + XVisualInfo vistemplate, *vinfo; + XSizeHints hints; + + int dw = DisplayWidth (display, screen_number); + int dh = DisplayHeight (display, screen_number); + int showright = 0, showbelow = 0; + int rx, ry, xright, ybelow; + Status status; + Window wmframe; + long longjunk; + Window junkwin; + int junk; + + if (!XGetWindowAttributes (dpy = display, window, &win_attributes)) + return (NULL); + vistemplate.visualid = XVisualIDFromVisual(win_attributes.visual); + /* MF036 + vinfo = XGetVisualInfo (dpy, VisualIDMask, &vistemplate, &junk); + */ + + (void) XTranslateCoordinates (dpy, window, win_attributes.root, + -win_attributes.border_width, + -win_attributes.border_width, + &rx, &ry, &junkwin); + + xright = (dw - rx - win_attributes.border_width * 2 - + win_attributes.width); + ybelow = (dh - ry - win_attributes.border_width * 2 - + win_attributes.height); + + /* compute size in appropriate units */ + status = XGetWMNormalHints (dpy, window, &hints, &longjunk); + op = geometry; + + if (status && (hints.flags & PResizeInc) && + hints.width_inc != 0 && hints.height_inc != 0) { + + if (hints.flags & (PBaseSize|PMinSize)) { + if (hints.flags & PBaseSize) { + win_attributes.width -= hints.base_width; + win_attributes.height -= hints.base_height; + } else { + /* ICCCM says MinSize is default for BaseSize */ + win_attributes.width -= hints.min_width; + win_attributes.height -= hints.min_height; + } + } + sprintf (op, "%dx%d", + win_attributes.width / hints.width_inc, + win_attributes.height / hints.height_inc); + } else + sprintf (op, "%dx%d", win_attributes.width, win_attributes.height); + + while (*op) + op++; + + if (!(hints.flags&PWinGravity)) + hints.win_gravity = NorthWestGravity; /* per ICCCM */ + + /* Find our window manager frame, if any. */ + wmframe = window; + while (True) { + Window root, parent; + Window *childlist; + unsigned int ujunk; + + status = XQueryTree (dpy, wmframe, &root, &parent, &childlist, &ujunk); + if (parent == root || !parent || !status) + break; + wmframe = parent; + if (status && childlist) + XFree ((char *)childlist); + } + + if (wmframe != window) { + /* WM reparented, so find edges of the frame. This only works for + * ICCCM-compliant WMs, and then only if the window has corner gravity. + * We would need to know the original width of the window to correctly + * handle the other gravities. + */ + XWindowAttributes frame_attr; + if (!XGetWindowAttributes (dpy, wmframe, &frame_attr)) + return (NULL); + + switch (hints.win_gravity) { + case NorthWestGravity: + case SouthWestGravity: + case NorthEastGravity: + case SouthEastGravity: + case WestGravity: + rx = frame_attr.x; + } + switch (hints.win_gravity) { + case NorthWestGravity: + case SouthWestGravity: + case NorthEastGravity: + case SouthEastGravity: + case EastGravity: + xright = dw - frame_attr.x - frame_attr.width - + 2 * frame_attr.border_width; + } + switch (hints.win_gravity) { + case NorthWestGravity: case SouthWestGravity: + case NorthEastGravity: case SouthEastGravity: + case NorthGravity: + ry = frame_attr.y; + } + switch (hints.win_gravity) { + case NorthWestGravity: case SouthWestGravity: + case NorthEastGravity: case SouthEastGravity: + case SouthGravity: + ybelow = dh - frame_attr.y - frame_attr.height - + 2 * frame_attr.border_width; + } + } + + /* If edge gravity, offer a corner on that edge (because the application + * programmer cares about that edge), otherwise offer upper left unless + * some other corner is close to an edge of the screen. (For corner + * gravity, assume gravity was set by XWMGeometry. For CenterGravity, + * it doesn't matter.) + */ + if (hints.win_gravity == EastGravity || + (abs(xright) <= 100 && abs(xright) < abs(rx) && + hints.win_gravity != WestGravity)) + showright = 1; + + if (hints.win_gravity == SouthGravity || + (abs(ybelow) <= 100 && abs(ybelow) < abs(ry) && + hints.win_gravity != NorthGravity)) + showbelow = 1; + + if (showright && !origin) + sprintf (op, "-%d", xright); + else + sprintf (op, "+%d", rx); + while (*op) + op++; + + if (showbelow && !origin) + sprintf (op, "-%d", ybelow); + else + sprintf (op, "+%d", ry); + + return (geometry); +} |