Blob


1 /* Copyright (c) 1994-1996 David Hogan, see README for licence details */
2 #include <stdio.h>
3 #include <signal.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <sys/wait.h>
7 #include <X11/X.h>
8 #include <X11/Xlib.h>
9 #include <X11/Xutil.h>
10 #include "dat.h"
11 #include "fns.h"
13 Client *hiddenc[MAXHIDDEN];
15 int numhidden;
17 char *b3items[B3FIXED+MAXHIDDEN+1] =
18 {
19 "New",
20 "Reshape",
21 "Move",
22 "Delete",
23 "Hide",
24 0,
25 };
27 Menu b3menu =
28 {
29 b3items,
30 };
32 Menu egg =
33 {
34 version,
35 };
37 void
38 button(XButtonEvent *e)
39 {
40 int n, shift;
41 Client *c;
42 Window dw;
43 ScreenInfo *s;
45 curtime = e->time;
46 s = getscreen(e->root);
47 if (s == 0)
48 return;
49 c = getclient(e->window, 0);
50 if(c){
51 if (debug) fprintf(stderr, "but: e x=%d y=%d c x=%d y=%d dx=%d dy=%d BORDR %d\n",
52 e->x, e->y, c->x, c->y, c->dx, c->dy, BORDER);
53 if(borderorient(c, e->x, e->y) != BorderUnknown){
54 switch (e->button) {
55 case Button1:
56 case Button2:
57 reshape(c, e->button, pull, e);
58 return;
59 case Button3:
60 move(c, Button3);
61 return;
62 default:
63 return;
64 }
65 }
66 e->x += c->x - BORDER;
67 e->y += c->y - BORDER;
68 } else if (e->window != e->root) {
69 if (debug) fprintf(stderr, "but no client: e x=%d y=%d\n",
70 e->x, e->y);
71 XTranslateCoordinates(dpy, e->window, s->root, e->x, e->y,
72 &e->x, &e->y, &dw);
73 }
74 switch (e->button) {
75 case Button1:
76 if (c) {
77 XMapRaised(dpy, c->parent);
78 top(c);
79 active(c);
80 }
81 return;
82 case Button2:
83 if ((e->state&(ShiftMask|ControlMask))==(ShiftMask|ControlMask))
84 menuhit(e, &egg);
85 return;
86 default:
87 return;
88 case Button3:
89 break;
90 }
92 if (current && current->screen == s)
93 cmapnofocus(s);
94 switch (n = menuhit(e, &b3menu)) {
95 case 0: /* New */
96 spawn(s);
97 break;
98 case 1: /* Reshape */
99 reshape(selectwin(1, 0, s), Button3, sweep, 0);
100 break;
101 case 2: /* Move */
102 move(selectwin(0, 0, s), Button3);
103 break;
104 case 3: /* Delete */
105 shift = 0;
106 c = selectwin(1, &shift, s);
107 delete(c, shift);
108 break;
109 case 4: /* Hide */
110 hide(selectwin(1, 0, s));
111 break;
112 default: /* unhide window */
113 unhide(n - B3FIXED, 1);
114 break;
115 case -1: /* nothing */
116 break;
118 if (current && current->screen == s)
119 cmapfocus(current);
122 void
123 spawn(ScreenInfo *s)
125 /*
126 * ugly dance to cause sweeping for terminals.
127 * the very next window created will require sweeping.
128 * hope it's created by the program we're about to
129 * exec!
130 */
131 isNew = 1;
132 /*
133 * ugly dance to avoid leaving zombies. Could use SIGCHLD,
134 * but it's not very portable.
135 */
136 if (fork() == 0) {
137 if (fork() == 0) {
138 close(ConnectionNumber(dpy));
139 if (s->display[0] != '\0')
140 putenv(s->display);
141 if (termprog != NULL) {
142 execl(shell, shell, "-c", termprog, 0);
143 fprintf(stderr, "rio: exec %s", shell);
144 perror(" failed");
146 execlp("9term", "9term", "-w", 0);
147 execlp("xterm", "xterm", "-ut", 0);
148 perror("rio: exec 9term/xterm failed");
149 exit(1);
151 exit(0);
153 wait((int *) 0);
156 void
157 reshape(Client *c, int but, int (*fn)(Client*, int, XButtonEvent *), XButtonEvent *e)
159 int odx, ody;
161 if (c == 0)
162 return;
163 odx = c->dx;
164 ody = c->dy;
165 if (fn(c, but, e) == 0)
166 return;
167 active(c);
168 top(c);
169 XRaiseWindow(dpy, c->parent);
170 XMoveResizeWindow(dpy, c->parent, c->x-BORDER, c->y-BORDER,
171 c->dx+2*BORDER, c->dy+2*BORDER);
172 if (c->dx == odx && c->dy == ody)
173 sendconfig(c);
174 else
175 XMoveResizeWindow(dpy, c->window, BORDER, BORDER, c->dx, c->dy);
178 void
179 move(Client *c, int but)
181 if (c == 0)
182 return;
183 if (drag(c, but) == 0)
184 return;
185 active(c);
186 top(c);
187 XRaiseWindow(dpy, c->parent);
188 XMoveWindow(dpy, c->parent, c->x-BORDER, c->y-BORDER);
189 sendconfig(c);
192 void
193 delete(Client *c, int shift)
195 if (c == 0)
196 return;
197 if ((c->proto & Pdelete) && !shift)
198 sendcmessage(c->window, wm_protocols, wm_delete, 0);
199 else
200 XKillClient(dpy, c->window); /* let event clean up */
203 void
204 hide(Client *c)
206 if (c == 0 || numhidden == MAXHIDDEN)
207 return;
208 if (hidden(c)) {
209 fprintf(stderr, "rio: already hidden: %s\n", c->label);
210 return;
212 XUnmapWindow(dpy, c->parent);
213 XUnmapWindow(dpy, c->window);
214 setstate(c, IconicState);
215 if (c == current)
216 nofocus();
217 hiddenc[numhidden] = c;
218 b3items[B3FIXED+numhidden] = c->label;
219 numhidden++;
220 b3items[B3FIXED+numhidden] = 0;
223 void
224 unhide(int n, int map)
226 Client *c;
227 int i;
229 if (n >= numhidden) {
230 fprintf(stderr, "rio: unhide: n %d numhidden %d\n", n, numhidden);
231 return;
233 c = hiddenc[n];
234 if (!hidden(c)) {
235 fprintf(stderr, "rio: unhide: not hidden: %s(0x%x)\n",
236 c->label, (int)c->window);
237 return;
240 if (map) {
241 XMapWindow(dpy, c->window);
242 XMapRaised(dpy, c->parent);
243 setstate(c, NormalState);
244 active(c);
245 top(c);
248 numhidden--;
249 for (i = n; i < numhidden; i ++) {
250 hiddenc[i] = hiddenc[i+1];
251 b3items[B3FIXED+i] = b3items[B3FIXED+i+1];
253 b3items[B3FIXED+numhidden] = 0;
256 void
257 unhidec(Client *c, int map)
259 int i;
261 for (i = 0; i < numhidden; i++)
262 if (c == hiddenc[i]) {
263 unhide(i, map);
264 return;
266 fprintf(stderr, "rio: unhidec: not hidden: %s(0x%x)\n",
267 c->label, (int)c->window);
270 void
271 renamec(Client *c, char *name)
273 int i;
275 if (name == 0)
276 name = "???";
277 c->label = name;
278 if (!hidden(c))
279 return;
280 for (i = 0; i < numhidden; i++)
281 if (c == hiddenc[i]) {
282 b3items[B3FIXED+i] = name;
283 return;