15 char Ebadwr[] = "bad rectangle in wctl request";
16 char Ewalloc[] = "window allocation failed in wctl request";
18 /* >= Top are disallowed if mouse button is pressed */
35 static char *cmds[] = {
40 [Noscroll] = "noscroll",
44 [Current] = "current",
68 static char *params[] = {
80 [Scrolling] = "-scroll",
81 [Noscrolling] = "-noscroll",
86 * Check that newly created window will be of manageable size
91 if(!eqrect(canonrect(r), r))
93 /* reasonable sizes only please */
94 if(Dx(r) > BIG*Dx(screen->r))
96 if(Dy(r) > BIG*Dy(screen->r))
98 if(Dx(r) < 100 || Dy(r) < 3*font->height)
100 /* window must be on screen */
101 if(!rectXrect(screen->r, r))
103 /* must have some screen and border visible so we can move it out of the way */
104 if(rectinrect(screen->r, insetrect(r, Borderwidth)))
111 word(char **sp, char *tab[])
120 while(*s!='\0' && !isspace(*s))
122 for(i=0; tab[i]!=nil; i++)
123 if(strncmp(tab[i], t, strlen(tab[i])) == 0){
131 set(int sign, int neg, int abs, int pos)
144 int minx, miny, dx, dy;
146 dx = min(600, Dx(screen->r) - 2*Borderwidth);
147 dy = min(400, Dy(screen->r) - 2*Borderwidth);
153 return Rect(minx, miny, minx+dx, miny+dy);
157 shift(int *minp, int *maxp, int min, int max)
172 rectonscreen(Rectangle r)
174 shift(&r.min.x, &r.max.x, screen->r.min.x, screen->r.max.x);
175 shift(&r.min.y, &r.max.y, screen->r.min.y, screen->r.max.y);
179 /* permit square brackets, in the manner of %R */
181 riostrtol(char *s, char **t)
185 while(*s!='\0' && (*s==' ' || *s=='\t' || *s=='['))
189 n = strtol(s, t, 10);
191 while((*t)[0] == ']')
198 parsewctl(char **argp, Rectangle r, Rectangle *rp, int *pidp, int *idp, int *hiddenp, int *scrollingp, char **cdp, char *s, char *err)
200 int cmd, param, xy, sign;
205 *scrollingp = scrolling;
207 cmd = word(&s, cmds);
209 strcpy(err, "unrecognized wctl command");
215 strcpy(err, "missing or bad wctl parameter");
216 while((param = word(&s, params)) >= 0){
217 switch(param){ /* special cases */
228 r.min.x = riostrtol(s, &t);
232 r.min.y = riostrtol(s, &t);
236 r.max.x = riostrtol(s, &t);
240 r.max.y = riostrtol(s, &t);
250 while(*s && !isspace(*s))
266 xy = riostrtol(s, &s);
269 strcpy(err, "unrecognized wctl parameter");
272 r.min.x = set(sign, r.min.x-xy, xy, r.min.x+xy);
275 r.min.y = set(sign, r.min.y-xy, xy, r.min.y+xy);
278 r.max.x = set(sign, r.max.x-xy, xy, r.max.x+xy);
281 r.max.y = set(sign, r.max.y-xy, xy, r.max.y+xy);
284 r.max.x = set(sign, r.max.x-xy, r.min.x+xy, r.max.x+xy);
287 r.max.y = set(sign, r.max.y-xy, r.min.y+xy, r.max.y+xy);
300 *rp = rectonscreen(rectaddpt(r, screen->r.min));
304 if(cmd!=New && *s!='\0'){
305 strcpy(err, "extraneous text in wctl message");
316 wctlnew(Rectangle rect, char *arg, int pid, int hideit, int scrollit, char *dir, char *err)
325 argv = emalloc(4*sizeof(char*));
338 i = allocimage(display, rect, screen->chan, 0, DNofill);
340 i = allocwindow(wscreen, rect, Refbackup, DNofill);
342 strcpy(err, Ewalloc);
346 new(i, hideit, scrollit, pid, dir, "/bin/rc", argv);
348 free(argv); /* when new() returns, argv and args have been copied */
353 wctlcmd(Window *w, Rectangle r, int cmd, char *err)
359 r = Rect(r.min.x, r.min.y, r.min.x+Dx(w->screenr), r.min.y+Dy(w->screenr));
367 if(Dx(w->screenr) > 0){
368 if(eqrect(r, w->screenr))
371 strcpy(err, "window not current");
374 i = allocwindow(wscreen, r, Refbackup, DNofill);
375 } else { /* hidden */
376 if(eqrect(r, w->i->r))
378 i = allocimage(display, r, w->i->chan, 0, DNofill);
382 strcpy(err, Ewalloc);
385 wsendctlmesg(w, Reshaped, r, i);
390 wsendctlmesg(w, Wakeup, ZR, nil);
394 wsendctlmesg(w, Wakeup, ZR, nil);
403 if(Dx(w->screenr)<=0){
404 strcpy(err, "window is hidden");
413 strcpy(err, "window already hidden");
416 strcpy(err, "hide failed");
425 strcpy(err, "window not hidden");
428 strcpy(err, "hide failed");
435 wsendctlmesg(w, Deleted, ZR, nil);
439 strcpy(err, "invalid wctl message");
444 writewctl(Xfid *x, char *err)
446 int cnt, cmd, id, hideit, scrollit, pid;
456 r = rectsubpt(w->screenr, screen->r.min);
457 cmd = parsewctl(&arg, r, &r, &pid, &id, &hideit, &scrollit, &dir, x->data, err);
464 strcpy(err, "no such window id");
471 return wctlnew(r, arg, pid, hideit, scrollit, dir, err);
479 id = wctlcmd(w, r, cmd, err);
488 char *buf, *arg, *dir;
489 int cmd, id, pid, hideit, scrollit;
496 threadsetname("WCTLTHREAD");
500 cmd = parsewctl(&arg, ZR, &rect, &pid, &id, &hideit, &scrollit, &dir, buf, err);
504 wctlnew(rect, arg, pid, hideit, scrollit, dir, err);
517 threadsetname("WCTLPROC");
522 buf = emalloc(messagesize);
523 n = read(wctlfd, buf, messagesize-1); /* room for \0 */