Blame


1 f73497bb 2008-02-01 rsc #include <u.h>
2 f73497bb 2008-02-01 rsc #include <X11/X.h>
3 f73497bb 2008-02-01 rsc #include <X11/Xatom.h>
4 f73497bb 2008-02-01 rsc #include <X11/Xlib.h>
5 f73497bb 2008-02-01 rsc #include <X11/Xutil.h>
6 f73497bb 2008-02-01 rsc #include <libc.h>
7 f73497bb 2008-02-01 rsc #include <ctype.h>
8 f73497bb 2008-02-01 rsc
9 f73497bb 2008-02-01 rsc AUTOLIB(X11);
10 f73497bb 2008-02-01 rsc
11 f73497bb 2008-02-01 rsc typedef struct Rectangle Rectangle;
12 f73497bb 2008-02-01 rsc struct Rectangle
13 f73497bb 2008-02-01 rsc {
14 f73497bb 2008-02-01 rsc struct {
15 f73497bb 2008-02-01 rsc int x;
16 f73497bb 2008-02-01 rsc int y;
17 f73497bb 2008-02-01 rsc } min, max;
18 f73497bb 2008-02-01 rsc };
19 f73497bb 2008-02-01 rsc #define Dx(r) ((r).max.x - (r).min.x)
20 f73497bb 2008-02-01 rsc #define Dy(r) ((r).max.y - (r).min.y)
21 f73497bb 2008-02-01 rsc
22 f73497bb 2008-02-01 rsc typedef struct Win Win;
23 f73497bb 2008-02-01 rsc struct Win
24 f73497bb 2008-02-01 rsc {
25 f73497bb 2008-02-01 rsc Window xw;
26 f73497bb 2008-02-01 rsc int x;
27 f73497bb 2008-02-01 rsc int y;
28 f73497bb 2008-02-01 rsc int dx;
29 f73497bb 2008-02-01 rsc int dy;
30 4241cae2 2020-01-15 crossd char *idstr;
31 f73497bb 2008-02-01 rsc char *class;
32 f73497bb 2008-02-01 rsc char *instance;
33 f73497bb 2008-02-01 rsc char *name;
34 f73497bb 2008-02-01 rsc char *iconname;
35 f73497bb 2008-02-01 rsc };
36 f73497bb 2008-02-01 rsc
37 f73497bb 2008-02-01 rsc Display *dpy;
38 f73497bb 2008-02-01 rsc Window root;
39 f73497bb 2008-02-01 rsc
40 f73497bb 2008-02-01 rsc Win *w;
41 f73497bb 2008-02-01 rsc int nw;
42 f73497bb 2008-02-01 rsc
43 f73497bb 2008-02-01 rsc void getinfo(void);
44 f73497bb 2008-02-01 rsc void listwindows(void);
45 ad8d5423 2008-02-01 rsc int parsewinsize(char*, Rectangle*, int*, int*, int*);
46 f73497bb 2008-02-01 rsc void shove(char*, char*);
47 f73497bb 2008-02-01 rsc
48 f73497bb 2008-02-01 rsc void
49 f73497bb 2008-02-01 rsc usage(void)
50 f73497bb 2008-02-01 rsc {
51 ad8d5423 2008-02-01 rsc fprint(2, "usage: xshove [window rectangle]\n");
52 f73497bb 2008-02-01 rsc exits("usage");
53 f73497bb 2008-02-01 rsc }
54 f73497bb 2008-02-01 rsc
55 f73497bb 2008-02-01 rsc void
56 f73497bb 2008-02-01 rsc main(int argc, char **argv)
57 f73497bb 2008-02-01 rsc {
58 f73497bb 2008-02-01 rsc int screen;
59 fa325e9b 2020-01-10 cross
60 f73497bb 2008-02-01 rsc screen = 0;
61 f73497bb 2008-02-01 rsc ARGBEGIN{
62 f73497bb 2008-02-01 rsc case 's':
63 f73497bb 2008-02-01 rsc screen = atoi(EARGF(usage()));
64 f73497bb 2008-02-01 rsc break;
65 f73497bb 2008-02-01 rsc default:
66 f73497bb 2008-02-01 rsc usage();
67 f73497bb 2008-02-01 rsc break;
68 f73497bb 2008-02-01 rsc }ARGEND
69 fa325e9b 2020-01-10 cross
70 f73497bb 2008-02-01 rsc dpy = XOpenDisplay("");
71 f73497bb 2008-02-01 rsc if(dpy == nil)
72 f73497bb 2008-02-01 rsc sysfatal("open display: %r");
73 f73497bb 2008-02-01 rsc
74 f73497bb 2008-02-01 rsc root = RootWindow(dpy, screen);
75 f73497bb 2008-02-01 rsc getinfo();
76 f73497bb 2008-02-01 rsc
77 f73497bb 2008-02-01 rsc if(argc == 0){
78 f73497bb 2008-02-01 rsc listwindows();
79 f73497bb 2008-02-01 rsc exits(0);
80 f73497bb 2008-02-01 rsc }
81 f73497bb 2008-02-01 rsc if(argc != 2)
82 f73497bb 2008-02-01 rsc usage();
83 f73497bb 2008-02-01 rsc shove(argv[0], argv[1]);
84 f73497bb 2008-02-01 rsc exits(0);
85 f73497bb 2008-02-01 rsc }
86 f73497bb 2008-02-01 rsc
87 f73497bb 2008-02-01 rsc char*
88 f73497bb 2008-02-01 rsc getproperty(Window w, Atom a)
89 f73497bb 2008-02-01 rsc {
90 f73497bb 2008-02-01 rsc uchar *p;
91 f73497bb 2008-02-01 rsc int fmt;
92 f73497bb 2008-02-01 rsc Atom type;
93 f73497bb 2008-02-01 rsc ulong n, dummy;
94 f73497bb 2008-02-01 rsc
95 f73497bb 2008-02-01 rsc n = 100;
96 f73497bb 2008-02-01 rsc p = nil;
97 fa325e9b 2020-01-10 cross XGetWindowProperty(dpy, w, a, 0, 100L, 0,
98 f73497bb 2008-02-01 rsc AnyPropertyType, &type, &fmt,
99 f73497bb 2008-02-01 rsc &n, &dummy, &p);
100 f73497bb 2008-02-01 rsc if(p == nil || *p == 0)
101 f73497bb 2008-02-01 rsc return nil;
102 f73497bb 2008-02-01 rsc return strdup((char*)p);
103 f73497bb 2008-02-01 rsc }
104 f73497bb 2008-02-01 rsc
105 f73497bb 2008-02-01 rsc Window
106 f73497bb 2008-02-01 rsc findname(Window w)
107 f73497bb 2008-02-01 rsc {
108 f73497bb 2008-02-01 rsc int i;
109 f73497bb 2008-02-01 rsc uint nxwin;
110 f73497bb 2008-02-01 rsc Window dw1, dw2, *xwin;
111 f73497bb 2008-02-01 rsc
112 f73497bb 2008-02-01 rsc if(getproperty(w, XA_WM_NAME))
113 f73497bb 2008-02-01 rsc return w;
114 f73497bb 2008-02-01 rsc if(!XQueryTree(dpy, w, &dw1, &dw2, &xwin, &nxwin))
115 f73497bb 2008-02-01 rsc return 0;
116 f73497bb 2008-02-01 rsc for(i=0; i<nxwin; i++)
117 f73497bb 2008-02-01 rsc if((w = findname(xwin[i])) != 0)
118 f73497bb 2008-02-01 rsc return w;
119 f73497bb 2008-02-01 rsc return 0;
120 f73497bb 2008-02-01 rsc }
121 f73497bb 2008-02-01 rsc
122 f73497bb 2008-02-01 rsc void
123 f73497bb 2008-02-01 rsc getinfo(void)
124 f73497bb 2008-02-01 rsc {
125 f73497bb 2008-02-01 rsc int i;
126 f73497bb 2008-02-01 rsc uint nxwin;
127 f73497bb 2008-02-01 rsc Window dw1, dw2, *xwin;
128 f73497bb 2008-02-01 rsc XClassHint class;
129 f73497bb 2008-02-01 rsc XWindowAttributes attr;
130 f73497bb 2008-02-01 rsc
131 f73497bb 2008-02-01 rsc if(!XQueryTree(dpy, root, &dw1, &dw2, &xwin, &nxwin))
132 f73497bb 2008-02-01 rsc return;
133 f73497bb 2008-02-01 rsc w = mallocz(nxwin*sizeof w[0], 1);
134 f73497bb 2008-02-01 rsc if(w == 0)
135 f73497bb 2008-02-01 rsc sysfatal("malloc: %r");
136 fa325e9b 2020-01-10 cross
137 f73497bb 2008-02-01 rsc Win *ww = w;
138 f73497bb 2008-02-01 rsc for(i=0; i<nxwin; i++){
139 f73497bb 2008-02-01 rsc memset(&attr, 0, sizeof attr);
140 f73497bb 2008-02-01 rsc xwin[i] = findname(xwin[i]);
141 f73497bb 2008-02-01 rsc if(xwin[i] == 0)
142 f73497bb 2008-02-01 rsc continue;
143 f73497bb 2008-02-01 rsc XGetWindowAttributes(dpy, xwin[i], &attr);
144 f73497bb 2008-02-01 rsc if(attr.width <= 0 || attr.override_redirect || attr.map_state != IsViewable)
145 f73497bb 2008-02-01 rsc continue;
146 f73497bb 2008-02-01 rsc ww->xw = xwin[i];
147 4241cae2 2020-01-15 crossd char idstr[9];
148 4241cae2 2020-01-15 crossd snprint(idstr, sizeof(idstr), "%08x", (uint)ww->xw);
149 4241cae2 2020-01-15 crossd ww->idstr = strdup(idstr);
150 f73497bb 2008-02-01 rsc ww->x = attr.x;
151 f73497bb 2008-02-01 rsc ww->y = attr.y;
152 f73497bb 2008-02-01 rsc ww->dx = attr.width;
153 f73497bb 2008-02-01 rsc ww->dy = attr.height;
154 f73497bb 2008-02-01 rsc XTranslateCoordinates(dpy, ww->xw, root, 0, 0, &ww->x, &ww->y, &dw1);
155 f73497bb 2008-02-01 rsc if(XGetClassHint(dpy, ww->xw, &class)){
156 f73497bb 2008-02-01 rsc ww->class = strdup(class.res_class);
157 f73497bb 2008-02-01 rsc ww->instance = strdup(class.res_name);
158 f73497bb 2008-02-01 rsc }
159 f73497bb 2008-02-01 rsc ww->iconname = getproperty(ww->xw, XA_WM_ICON_NAME);
160 f73497bb 2008-02-01 rsc ww->name = getproperty(ww->xw, XA_WM_NAME);
161 f73497bb 2008-02-01 rsc ww++;
162 f73497bb 2008-02-01 rsc }
163 f73497bb 2008-02-01 rsc nw = ww - w;
164 fa325e9b 2020-01-10 cross }
165 f73497bb 2008-02-01 rsc
166 f73497bb 2008-02-01 rsc void
167 f73497bb 2008-02-01 rsc listwindows(void)
168 f73497bb 2008-02-01 rsc {
169 f73497bb 2008-02-01 rsc int i;
170 f73497bb 2008-02-01 rsc
171 f73497bb 2008-02-01 rsc for(i=0; i<nw; i++){
172 f73497bb 2008-02-01 rsc Win *ww = &w[i];
173 f73497bb 2008-02-01 rsc char rect[50];
174 f73497bb 2008-02-01 rsc snprint(rect, sizeof rect, "%d,%d,%d,%d", ww->x, ww->y, ww->x+ww->dx, ww->y+ww->dy);
175 f73497bb 2008-02-01 rsc print("%08x %-20s %-10s %s\n",
176 fa325e9b 2020-01-10 cross (uint)ww->xw,
177 f73497bb 2008-02-01 rsc rect,
178 f73497bb 2008-02-01 rsc ww->instance,
179 f73497bb 2008-02-01 rsc ww->class);
180 f73497bb 2008-02-01 rsc }
181 f73497bb 2008-02-01 rsc }
182 f73497bb 2008-02-01 rsc
183 f73497bb 2008-02-01 rsc void
184 f73497bb 2008-02-01 rsc shove(char *name, char *geom)
185 f73497bb 2008-02-01 rsc {
186 f73497bb 2008-02-01 rsc int i;
187 ad8d5423 2008-02-01 rsc int isdelta, havemin, havesize;
188 ad8d5423 2008-02-01 rsc int old, new;
189 f73497bb 2008-02-01 rsc Rectangle r;
190 f73497bb 2008-02-01 rsc
191 ad8d5423 2008-02-01 rsc if(parsewinsize(geom, &r, &isdelta, &havemin, &havesize) < 0)
192 f73497bb 2008-02-01 rsc sysfatal("bad window spec: %s", name);
193 f73497bb 2008-02-01 rsc
194 ad8d5423 2008-02-01 rsc old = 0;
195 ad8d5423 2008-02-01 rsc new = 1;
196 ad8d5423 2008-02-01 rsc if(isdelta){
197 ad8d5423 2008-02-01 rsc old = 1;
198 ad8d5423 2008-02-01 rsc new = isdelta;
199 ad8d5423 2008-02-01 rsc }
200 f73497bb 2008-02-01 rsc for(i=0; i<nw; i++){
201 f73497bb 2008-02-01 rsc Win *ww = &w[i];
202 f73497bb 2008-02-01 rsc if(ww->instance && strstr(ww->instance, name)
203 4241cae2 2020-01-15 crossd || ww->class && strstr(ww->class, name)
204 4241cae2 2020-01-15 crossd || ww->idstr && strstr(ww->idstr, name)){
205 f73497bb 2008-02-01 rsc int value_mask;
206 f73497bb 2008-02-01 rsc XWindowChanges e;
207 f73497bb 2008-02-01 rsc
208 f73497bb 2008-02-01 rsc memset(&e, 0, sizeof e);
209 f73497bb 2008-02-01 rsc if(havemin){
210 ad8d5423 2008-02-01 rsc e.x = old*ww->x + new*r.min.x;
211 ad8d5423 2008-02-01 rsc e.y = old*ww->y + new*r.min.y;
212 ad8d5423 2008-02-01 rsc }else{
213 ad8d5423 2008-02-01 rsc e.x = ww->x;
214 ad8d5423 2008-02-01 rsc e.y = ww->y;
215 f73497bb 2008-02-01 rsc }
216 ad8d5423 2008-02-01 rsc if(havesize){
217 ad8d5423 2008-02-01 rsc e.width = old*ww->dx + new*Dx(r);
218 ad8d5423 2008-02-01 rsc e.height = old*ww->dy + new*Dy(r);
219 ad8d5423 2008-02-01 rsc }else{
220 ad8d5423 2008-02-01 rsc e.width = ww->dx;
221 ad8d5423 2008-02-01 rsc e.height = ww->dy;
222 ad8d5423 2008-02-01 rsc }
223 ad8d5423 2008-02-01 rsc value_mask = CWX | CWY | CWWidth | CWHeight;
224 f73497bb 2008-02-01 rsc XConfigureWindow(dpy, ww->xw, value_mask, &e);
225 f73497bb 2008-02-01 rsc XFlush(dpy);
226 f73497bb 2008-02-01 rsc }
227 f73497bb 2008-02-01 rsc }
228 f73497bb 2008-02-01 rsc }
229 f73497bb 2008-02-01 rsc
230 f73497bb 2008-02-01 rsc int
231 ad8d5423 2008-02-01 rsc parsewinsize(char *s, Rectangle *r, int *isdelta, int *havemin, int *havesize)
232 f73497bb 2008-02-01 rsc {
233 f73497bb 2008-02-01 rsc char c, *os;
234 f73497bb 2008-02-01 rsc int i, j, k, l;
235 f73497bb 2008-02-01 rsc
236 f73497bb 2008-02-01 rsc os = s;
237 ad8d5423 2008-02-01 rsc if(*s == '-'){
238 ad8d5423 2008-02-01 rsc s++;
239 ad8d5423 2008-02-01 rsc *isdelta = -1;
240 ad8d5423 2008-02-01 rsc }else if(*s == '+'){
241 ad8d5423 2008-02-01 rsc s++;
242 ad8d5423 2008-02-01 rsc *isdelta = 1;
243 ad8d5423 2008-02-01 rsc }else
244 ad8d5423 2008-02-01 rsc *isdelta = 0;
245 f73497bb 2008-02-01 rsc *havemin = 0;
246 ad8d5423 2008-02-01 rsc *havesize = 0;
247 f73497bb 2008-02-01 rsc memset(r, 0, sizeof *r);
248 f73497bb 2008-02-01 rsc if(!isdigit((uchar)*s))
249 f73497bb 2008-02-01 rsc goto oops;
250 f73497bb 2008-02-01 rsc i = strtol(s, &s, 0);
251 f73497bb 2008-02-01 rsc if(*s == 'x'){
252 f73497bb 2008-02-01 rsc s++;
253 f73497bb 2008-02-01 rsc if(!isdigit((uchar)*s))
254 f73497bb 2008-02-01 rsc goto oops;
255 f73497bb 2008-02-01 rsc j = strtol(s, &s, 0);
256 f73497bb 2008-02-01 rsc r->max.x = i;
257 f73497bb 2008-02-01 rsc r->max.y = j;
258 ad8d5423 2008-02-01 rsc *havesize = 1;
259 f73497bb 2008-02-01 rsc if(*s == 0)
260 f73497bb 2008-02-01 rsc return 0;
261 f73497bb 2008-02-01 rsc if(*s != '@')
262 f73497bb 2008-02-01 rsc goto oops;
263 f73497bb 2008-02-01 rsc
264 f73497bb 2008-02-01 rsc s++;
265 f73497bb 2008-02-01 rsc if(!isdigit((uchar)*s))
266 f73497bb 2008-02-01 rsc goto oops;
267 f73497bb 2008-02-01 rsc i = strtol(s, &s, 0);
268 f73497bb 2008-02-01 rsc if(*s != ',' && *s != ' ')
269 f73497bb 2008-02-01 rsc goto oops;
270 f73497bb 2008-02-01 rsc s++;
271 f73497bb 2008-02-01 rsc if(!isdigit((uchar)*s))
272 f73497bb 2008-02-01 rsc goto oops;
273 f73497bb 2008-02-01 rsc j = strtol(s, &s, 0);
274 f73497bb 2008-02-01 rsc if(*s != 0)
275 f73497bb 2008-02-01 rsc goto oops;
276 f73497bb 2008-02-01 rsc r->min.x += i;
277 f73497bb 2008-02-01 rsc r->max.x += i;
278 f73497bb 2008-02-01 rsc r->min.y += j;
279 f73497bb 2008-02-01 rsc r->max.y += j;
280 ad8d5423 2008-02-01 rsc *havesize = 1;
281 f73497bb 2008-02-01 rsc *havemin = 1;
282 f73497bb 2008-02-01 rsc return 0;
283 f73497bb 2008-02-01 rsc }
284 f73497bb 2008-02-01 rsc
285 f73497bb 2008-02-01 rsc c = *s;
286 f73497bb 2008-02-01 rsc if(c != ' ' && c != ',')
287 f73497bb 2008-02-01 rsc goto oops;
288 f73497bb 2008-02-01 rsc s++;
289 f73497bb 2008-02-01 rsc if(!isdigit((uchar)*s))
290 f73497bb 2008-02-01 rsc goto oops;
291 f73497bb 2008-02-01 rsc j = strtol(s, &s, 0);
292 ad8d5423 2008-02-01 rsc if(*s == 0){
293 ad8d5423 2008-02-01 rsc r->min.x = i;
294 ad8d5423 2008-02-01 rsc r->min.y = j;
295 ad8d5423 2008-02-01 rsc *havemin = 1;
296 ad8d5423 2008-02-01 rsc return 0;
297 ad8d5423 2008-02-01 rsc }
298 f73497bb 2008-02-01 rsc if(*s != c)
299 f73497bb 2008-02-01 rsc goto oops;
300 f73497bb 2008-02-01 rsc s++;
301 f73497bb 2008-02-01 rsc if(!isdigit((uchar)*s))
302 f73497bb 2008-02-01 rsc goto oops;
303 f73497bb 2008-02-01 rsc k = strtol(s, &s, 0);
304 f73497bb 2008-02-01 rsc if(*s != c)
305 f73497bb 2008-02-01 rsc goto oops;
306 f73497bb 2008-02-01 rsc s++;
307 f73497bb 2008-02-01 rsc if(!isdigit((uchar)*s))
308 f73497bb 2008-02-01 rsc goto oops;
309 f73497bb 2008-02-01 rsc l = strtol(s, &s, 0);
310 f73497bb 2008-02-01 rsc if(*s != 0)
311 f73497bb 2008-02-01 rsc goto oops;
312 f73497bb 2008-02-01 rsc r->min.x = i;
313 f73497bb 2008-02-01 rsc r->min.y = j;
314 f73497bb 2008-02-01 rsc r->max.x = k;
315 f73497bb 2008-02-01 rsc r->max.y = l;
316 f73497bb 2008-02-01 rsc *havemin = 1;
317 ad8d5423 2008-02-01 rsc *havesize = 1;
318 f73497bb 2008-02-01 rsc return 0;
319 f73497bb 2008-02-01 rsc
320 f73497bb 2008-02-01 rsc oops:
321 f73497bb 2008-02-01 rsc werrstr("bad syntax in window size '%s'", os);
322 f73497bb 2008-02-01 rsc return -1;
323 f73497bb 2008-02-01 rsc }