1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
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);
}
|