Blame


1 8ad51794 2004-03-25 devnull #include <u.h>
2 42c3794c 2004-10-17 devnull #include <signal.h>
3 8ad51794 2004-03-25 devnull #include <libc.h>
4 8ad51794 2004-03-25 devnull #include <ctype.h>
5 8ad51794 2004-03-25 devnull #include <draw.h>
6 8ad51794 2004-03-25 devnull #include <thread.h>
7 8ad51794 2004-03-25 devnull #include <mouse.h>
8 8ad51794 2004-03-25 devnull #include <cursor.h>
9 8ad51794 2004-03-25 devnull #include <keyboard.h>
10 8ad51794 2004-03-25 devnull #include <frame.h>
11 8ad51794 2004-03-25 devnull #include <plumb.h>
12 8ad51794 2004-03-25 devnull #include <complete.h>
13 e830a908 2005-11-06 devnull #define Extern
14 e830a908 2005-11-06 devnull #include "dat.h"
15 e830a908 2005-11-06 devnull #include "fns.h"
16 e830a908 2005-11-06 devnull #include "term.h"
17 e830a908 2005-11-06 devnull
18 bf63f986 2013-08-06 rsc const char *termprog = "9term";
19 e830a908 2005-11-06 devnull int use9wm;
20 e830a908 2005-11-06 devnull int mainpid;
21 93921c48 2006-06-28 devnull int mousepid;
22 e830a908 2005-11-06 devnull int plumbfd;
23 e830a908 2005-11-06 devnull int rcpid;
24 e830a908 2005-11-06 devnull int rcfd;
25 e830a908 2005-11-06 devnull int sfd;
26 e830a908 2005-11-06 devnull Window *w;
27 e830a908 2005-11-06 devnull char *fontname;
28 e830a908 2005-11-06 devnull
29 e830a908 2005-11-06 devnull void derror(Display*, char*);
30 e830a908 2005-11-06 devnull void mousethread(void*);
31 e830a908 2005-11-06 devnull void keyboardthread(void*);
32 e830a908 2005-11-06 devnull void winclosethread(void*);
33 e830a908 2005-11-06 devnull void deletethread(void*);
34 e830a908 2005-11-06 devnull void rcoutputproc(void*);
35 e830a908 2005-11-06 devnull void rcinputproc(void*);
36 e830a908 2005-11-06 devnull void hangupnote(void*, char*);
37 e830a908 2005-11-06 devnull void resizethread(void*);
38 c935adc6 2005-11-10 devnull void servedevtext(void);
39 e830a908 2005-11-06 devnull
40 e830a908 2005-11-06 devnull int errorshouldabort = 0;
41 670f7301 2010-05-20 rsc int cooked;
42 e830a908 2005-11-06 devnull
43 e830a908 2005-11-06 devnull void
44 e830a908 2005-11-06 devnull usage(void)
45 e830a908 2005-11-06 devnull {
46 e830a908 2005-11-06 devnull fprint(2, "usage: 9term [-s] [-f font] [-W winsize] [cmd ...]\n");
47 e830a908 2005-11-06 devnull threadexitsall("usage");
48 dbc153f5 2020-12-30 rsc }
49 dbc153f5 2020-12-30 rsc
50 dbc153f5 2020-12-30 rsc int
51 dbc153f5 2020-12-30 rsc threadmaybackground(void)
52 dbc153f5 2020-12-30 rsc {
53 dbc153f5 2020-12-30 rsc return 1;
54 e830a908 2005-11-06 devnull }
55 e830a908 2005-11-06 devnull
56 e830a908 2005-11-06 devnull void
57 e830a908 2005-11-06 devnull threadmain(int argc, char *argv[])
58 e830a908 2005-11-06 devnull {
59 21d0dda6 2005-11-11 devnull char *p;
60 fa325e9b 2020-01-10 cross
61 e830a908 2005-11-06 devnull rfork(RFNOTEG);
62 e830a908 2005-11-06 devnull font = nil;
63 e830a908 2005-11-06 devnull _wantfocuschanges = 1;
64 e830a908 2005-11-06 devnull mainpid = getpid();
65 e830a908 2005-11-06 devnull messagesize = 8192;
66 fa325e9b 2020-01-10 cross
67 e830a908 2005-11-06 devnull ARGBEGIN{
68 e830a908 2005-11-06 devnull default:
69 e830a908 2005-11-06 devnull usage();
70 5bd21066 2006-01-18 devnull case 'l':
71 5bd21066 2006-01-18 devnull loginshell = TRUE;
72 5bd21066 2006-01-18 devnull break;
73 e830a908 2005-11-06 devnull case 'f':
74 21d0dda6 2005-11-11 devnull fontname = EARGF(usage());
75 e830a908 2005-11-06 devnull break;
76 e830a908 2005-11-06 devnull case 's':
77 210d461c 2011-10-12 rsc scrolling = TRUE;
78 e830a908 2005-11-06 devnull break;
79 670f7301 2010-05-20 rsc case 'c':
80 670f7301 2010-05-20 rsc cooked = TRUE;
81 670f7301 2010-05-20 rsc break;
82 e830a908 2005-11-06 devnull case 'w': /* started from rio or 9wm */
83 e830a908 2005-11-06 devnull use9wm = TRUE;
84 e830a908 2005-11-06 devnull break;
85 e830a908 2005-11-06 devnull case 'W':
86 e830a908 2005-11-06 devnull winsize = EARGF(usage());
87 e830a908 2005-11-06 devnull break;
88 e830a908 2005-11-06 devnull }ARGEND
89 fa325e9b 2020-01-10 cross
90 21d0dda6 2005-11-11 devnull if(fontname)
91 21d0dda6 2005-11-11 devnull putenv("font", fontname);
92 21d0dda6 2005-11-11 devnull
93 e830a908 2005-11-06 devnull p = getenv("tabstop");
94 e830a908 2005-11-06 devnull if(p == 0)
95 e830a908 2005-11-06 devnull p = getenv("TABSTOP");
96 e830a908 2005-11-06 devnull if(p && maxtab <= 0)
97 e830a908 2005-11-06 devnull maxtab = strtoul(p, 0, 0);
98 e830a908 2005-11-06 devnull if(maxtab <= 0)
99 e830a908 2005-11-06 devnull maxtab = 4;
100 e830a908 2005-11-06 devnull free(p);
101 fa325e9b 2020-01-10 cross
102 e830a908 2005-11-06 devnull startdir = ".";
103 21d0dda6 2005-11-11 devnull
104 98df7c80 2006-06-25 devnull if(initdraw(derror, fontname, "9term") < 0)
105 98df7c80 2006-06-25 devnull sysfatal("initdraw: %r");
106 98df7c80 2006-06-25 devnull
107 e830a908 2005-11-06 devnull notify(hangupnote);
108 e830a908 2005-11-06 devnull noteenable("sys: child");
109 fa325e9b 2020-01-10 cross
110 e830a908 2005-11-06 devnull mousectl = initmouse(nil, screen);
111 e830a908 2005-11-06 devnull if(mousectl == nil)
112 e830a908 2005-11-06 devnull error("cannot find mouse");
113 e830a908 2005-11-06 devnull keyboardctl = initkeyboard(nil);
114 e830a908 2005-11-06 devnull if(keyboardctl == nil)
115 e830a908 2005-11-06 devnull error("cannot find keyboard");
116 e830a908 2005-11-06 devnull mouse = &mousectl->m;
117 e830a908 2005-11-06 devnull
118 e830a908 2005-11-06 devnull winclosechan = chancreate(sizeof(Window*), 0);
119 e830a908 2005-11-06 devnull deletechan = chancreate(sizeof(char*), 0);
120 e830a908 2005-11-06 devnull
121 e830a908 2005-11-06 devnull timerinit();
122 c21d0ab4 2005-11-11 devnull servedevtext();
123 e830a908 2005-11-06 devnull rcpid = rcstart(argc, argv, &rcfd, &sfd);
124 210d461c 2011-10-12 rsc w = new(screen, FALSE, scrolling, rcpid, ".", nil, nil);
125 e830a908 2005-11-06 devnull
126 e830a908 2005-11-06 devnull threadcreate(keyboardthread, nil, STACK);
127 e830a908 2005-11-06 devnull threadcreate(mousethread, nil, STACK);
128 e830a908 2005-11-06 devnull threadcreate(resizethread, nil, STACK);
129 c935adc6 2005-11-10 devnull
130 e830a908 2005-11-06 devnull proccreate(rcoutputproc, nil, STACK);
131 e830a908 2005-11-06 devnull proccreate(rcinputproc, nil, STACK);
132 e830a908 2005-11-06 devnull }
133 e830a908 2005-11-06 devnull
134 e830a908 2005-11-06 devnull void
135 e830a908 2005-11-06 devnull derror(Display *d, char *errorstr)
136 e830a908 2005-11-06 devnull {
137 e830a908 2005-11-06 devnull USED(d);
138 e830a908 2005-11-06 devnull error(errorstr);
139 e830a908 2005-11-06 devnull }
140 e830a908 2005-11-06 devnull
141 e830a908 2005-11-06 devnull void
142 e830a908 2005-11-06 devnull hangupnote(void *a, char *msg)
143 e830a908 2005-11-06 devnull {
144 e830a908 2005-11-06 devnull if(getpid() != mainpid)
145 e830a908 2005-11-06 devnull noted(NDFLT);
146 93921c48 2006-06-28 devnull if(strcmp(msg, "hangup") == 0){
147 93921c48 2006-06-28 devnull postnote(PNPROC, rcpid, "hangup");
148 93921c48 2006-06-28 devnull noted(NDFLT);
149 93921c48 2006-06-28 devnull }
150 e830a908 2005-11-06 devnull if(strstr(msg, "child")){
151 e830a908 2005-11-06 devnull char buf[128];
152 e830a908 2005-11-06 devnull int n;
153 e830a908 2005-11-06 devnull
154 e830a908 2005-11-06 devnull n = awaitnohang(buf, sizeof buf-1);
155 e830a908 2005-11-06 devnull if(n > 0){
156 e830a908 2005-11-06 devnull buf[n] = 0;
157 e830a908 2005-11-06 devnull if(atoi(buf) == rcpid)
158 e830a908 2005-11-06 devnull threadexitsall(0);
159 e830a908 2005-11-06 devnull }
160 e830a908 2005-11-06 devnull noted(NCONT);
161 e830a908 2005-11-06 devnull }
162 e830a908 2005-11-06 devnull noted(NDFLT);
163 e830a908 2005-11-06 devnull }
164 e830a908 2005-11-06 devnull
165 e830a908 2005-11-06 devnull void
166 e830a908 2005-11-06 devnull keyboardthread(void *v)
167 e830a908 2005-11-06 devnull {
168 e830a908 2005-11-06 devnull Rune buf[2][20], *rp;
169 e830a908 2005-11-06 devnull int i, n;
170 e830a908 2005-11-06 devnull
171 e830a908 2005-11-06 devnull USED(v);
172 e830a908 2005-11-06 devnull threadsetname("keyboardthread");
173 e830a908 2005-11-06 devnull n = 0;
174 e830a908 2005-11-06 devnull for(;;){
175 e830a908 2005-11-06 devnull rp = buf[n];
176 e830a908 2005-11-06 devnull n = 1-n;
177 e830a908 2005-11-06 devnull recv(keyboardctl->c, rp);
178 e830a908 2005-11-06 devnull for(i=1; i<nelem(buf[0])-1; i++)
179 e830a908 2005-11-06 devnull if(nbrecv(keyboardctl->c, rp+i) <= 0)
180 e830a908 2005-11-06 devnull break;
181 e830a908 2005-11-06 devnull rp[i] = L'\0';
182 e830a908 2005-11-06 devnull sendp(w->ck, rp);
183 e830a908 2005-11-06 devnull }
184 e830a908 2005-11-06 devnull }
185 e830a908 2005-11-06 devnull
186 e830a908 2005-11-06 devnull void
187 e830a908 2005-11-06 devnull resizethread(void *v)
188 e830a908 2005-11-06 devnull {
189 c935adc6 2005-11-10 devnull Point p;
190 fa325e9b 2020-01-10 cross
191 e830a908 2005-11-06 devnull USED(v);
192 fa325e9b 2020-01-10 cross
193 baa6e34b 2005-11-30 devnull for(;;){
194 c935adc6 2005-11-10 devnull p = stringsize(display->defaultfont, "0");
195 c935adc6 2005-11-10 devnull if(p.x && p.y)
196 fa325e9b 2020-01-10 cross updatewinsize(Dy(screen->r)/p.y, (Dx(screen->r)-Scrollwid-2)/p.x,
197 c935adc6 2005-11-10 devnull Dx(screen->r), Dy(screen->r));
198 bcc96c1d 2005-11-11 devnull wresize(w, screen, 0);
199 bcc96c1d 2005-11-11 devnull flushimage(display, 1);
200 baa6e34b 2005-11-30 devnull if(recv(mousectl->resizec, nil) != 1)
201 baa6e34b 2005-11-30 devnull break;
202 baa6e34b 2005-11-30 devnull if(getwindow(display, Refnone) < 0)
203 baa6e34b 2005-11-30 devnull sysfatal("can't reattach to window");
204 e830a908 2005-11-06 devnull }
205 e830a908 2005-11-06 devnull }
206 fa325e9b 2020-01-10 cross
207 e830a908 2005-11-06 devnull void
208 e830a908 2005-11-06 devnull mousethread(void *v)
209 e830a908 2005-11-06 devnull {
210 e830a908 2005-11-06 devnull int sending;
211 e830a908 2005-11-06 devnull Mouse tmp;
212 e830a908 2005-11-06 devnull
213 e830a908 2005-11-06 devnull USED(v);
214 e830a908 2005-11-06 devnull
215 e830a908 2005-11-06 devnull sending = FALSE;
216 e830a908 2005-11-06 devnull threadsetname("mousethread");
217 e830a908 2005-11-06 devnull while(readmouse(mousectl) >= 0){
218 e830a908 2005-11-06 devnull if(sending){
219 e830a908 2005-11-06 devnull Send:
220 e830a908 2005-11-06 devnull /* send to window */
221 e830a908 2005-11-06 devnull if(mouse->buttons == 0)
222 e830a908 2005-11-06 devnull sending = FALSE;
223 e830a908 2005-11-06 devnull else
224 e830a908 2005-11-06 devnull wsetcursor(w, 0);
225 e830a908 2005-11-06 devnull tmp = mousectl->m;
226 e830a908 2005-11-06 devnull send(w->mc.c, &tmp);
227 e830a908 2005-11-06 devnull continue;
228 e830a908 2005-11-06 devnull }
229 3b7ca01f 2009-08-11 t.lainson if((mouse->buttons&(1|8|16)) || ptinrect(mouse->xy, w->scrollr)){
230 e830a908 2005-11-06 devnull sending = TRUE;
231 e830a908 2005-11-06 devnull goto Send;
232 e830a908 2005-11-06 devnull }else if(mouse->buttons&2)
233 e830a908 2005-11-06 devnull button2menu(w);
234 e830a908 2005-11-06 devnull else
235 d879e173 2005-11-26 devnull bouncemouse(mouse);
236 e830a908 2005-11-06 devnull }
237 e830a908 2005-11-06 devnull }
238 fa325e9b 2020-01-10 cross
239 e830a908 2005-11-06 devnull void
240 e830a908 2005-11-06 devnull wborder(Window *w, int type)
241 e830a908 2005-11-06 devnull {
242 e830a908 2005-11-06 devnull }
243 e830a908 2005-11-06 devnull
244 e830a908 2005-11-06 devnull Window*
245 e830a908 2005-11-06 devnull wpointto(Point pt)
246 e830a908 2005-11-06 devnull {
247 e830a908 2005-11-06 devnull return w;
248 e830a908 2005-11-06 devnull }
249 e830a908 2005-11-06 devnull
250 e830a908 2005-11-06 devnull Window*
251 210d461c 2011-10-12 rsc new(Image *i, int hideit, int scrollit, int pid, char *dir, char *cmd, char **argv)
252 e830a908 2005-11-06 devnull {
253 e830a908 2005-11-06 devnull Window *w;
254 e830a908 2005-11-06 devnull Mousectl *mc;
255 e830a908 2005-11-06 devnull Channel *cm, *ck, *cctl;
256 e830a908 2005-11-06 devnull
257 e830a908 2005-11-06 devnull if(i == nil)
258 e830a908 2005-11-06 devnull return nil;
259 e830a908 2005-11-06 devnull cm = chancreate(sizeof(Mouse), 0);
260 e830a908 2005-11-06 devnull ck = chancreate(sizeof(Rune*), 0);
261 e830a908 2005-11-06 devnull cctl = chancreate(sizeof(Wctlmesg), 4);
262 e830a908 2005-11-06 devnull if(cm==nil || ck==nil || cctl==nil)
263 e830a908 2005-11-06 devnull error("new: channel alloc failed");
264 e830a908 2005-11-06 devnull mc = emalloc(sizeof(Mousectl));
265 e830a908 2005-11-06 devnull *mc = *mousectl;
266 cbeb0b26 2006-04-01 devnull /* mc->image = i; */
267 e830a908 2005-11-06 devnull mc->c = cm;
268 210d461c 2011-10-12 rsc w = wmk(i, mc, ck, cctl, scrollit);
269 e830a908 2005-11-06 devnull free(mc); /* wmk copies *mc */
270 e830a908 2005-11-06 devnull window = erealloc(window, ++nwindow*sizeof(Window*));
271 e830a908 2005-11-06 devnull window[nwindow-1] = w;
272 e830a908 2005-11-06 devnull if(hideit){
273 e830a908 2005-11-06 devnull hidden[nhidden++] = w;
274 e830a908 2005-11-06 devnull w->screenr = ZR;
275 e830a908 2005-11-06 devnull }
276 7fe619f7 2005-12-29 devnull threadcreate(winctl, w, STACK);
277 e830a908 2005-11-06 devnull if(!hideit)
278 e830a908 2005-11-06 devnull wcurrent(w);
279 e830a908 2005-11-06 devnull flushimage(display, 1);
280 e830a908 2005-11-06 devnull wsetpid(w, pid, 1);
281 e830a908 2005-11-06 devnull wsetname(w);
282 e830a908 2005-11-06 devnull if(dir)
283 e830a908 2005-11-06 devnull w->dir = estrdup(dir);
284 e830a908 2005-11-06 devnull return w;
285 e830a908 2005-11-06 devnull }
286 e830a908 2005-11-06 devnull
287 e830a908 2005-11-06 devnull /*
288 e830a908 2005-11-06 devnull * Button 2 menu. Extra entry for always cook
289 e830a908 2005-11-06 devnull */
290 e830a908 2005-11-06 devnull
291 e830a908 2005-11-06 devnull enum
292 e830a908 2005-11-06 devnull {
293 e830a908 2005-11-06 devnull Cut,
294 e830a908 2005-11-06 devnull Paste,
295 e830a908 2005-11-06 devnull Snarf,
296 e830a908 2005-11-06 devnull Plumb,
297 a4e59b37 2020-01-07 crossd Look,
298 e830a908 2005-11-06 devnull Send,
299 210d461c 2011-10-12 rsc Scroll,
300 cbeb0b26 2006-04-01 devnull Cook
301 e830a908 2005-11-06 devnull };
302 e830a908 2005-11-06 devnull
303 e830a908 2005-11-06 devnull char *menu2str[] = {
304 e830a908 2005-11-06 devnull "cut",
305 e830a908 2005-11-06 devnull "paste",
306 e830a908 2005-11-06 devnull "snarf",
307 e830a908 2005-11-06 devnull "plumb",
308 a4e59b37 2020-01-07 crossd "look",
309 e830a908 2005-11-06 devnull "send",
310 e830a908 2005-11-06 devnull "cook",
311 210d461c 2011-10-12 rsc "scroll",
312 e830a908 2005-11-06 devnull nil
313 e830a908 2005-11-06 devnull };
314 e830a908 2005-11-06 devnull
315 e830a908 2005-11-06 devnull
316 e830a908 2005-11-06 devnull Menu menu2 =
317 e830a908 2005-11-06 devnull {
318 e830a908 2005-11-06 devnull menu2str
319 e830a908 2005-11-06 devnull };
320 e830a908 2005-11-06 devnull
321 e830a908 2005-11-06 devnull Rune newline[] = { '\n' };
322 e830a908 2005-11-06 devnull
323 e830a908 2005-11-06 devnull void
324 e830a908 2005-11-06 devnull button2menu(Window *w)
325 e830a908 2005-11-06 devnull {
326 e830a908 2005-11-06 devnull if(w->deleted)
327 e830a908 2005-11-06 devnull return;
328 e830a908 2005-11-06 devnull incref(&w->ref);
329 210d461c 2011-10-12 rsc if(w->scrolling)
330 210d461c 2011-10-12 rsc menu2str[Scroll] = "noscroll";
331 210d461c 2011-10-12 rsc else
332 210d461c 2011-10-12 rsc menu2str[Scroll] = "scroll";
333 e830a908 2005-11-06 devnull if(cooked)
334 e830a908 2005-11-06 devnull menu2str[Cook] = "nocook";
335 e830a908 2005-11-06 devnull else
336 e830a908 2005-11-06 devnull menu2str[Cook] = "cook";
337 e830a908 2005-11-06 devnull
338 e830a908 2005-11-06 devnull switch(menuhit(2, mousectl, &menu2, wscreen)){
339 e830a908 2005-11-06 devnull case Cut:
340 e830a908 2005-11-06 devnull wsnarf(w);
341 e830a908 2005-11-06 devnull wcut(w);
342 e830a908 2005-11-06 devnull wscrdraw(w);
343 e830a908 2005-11-06 devnull break;
344 e830a908 2005-11-06 devnull
345 e830a908 2005-11-06 devnull case Snarf:
346 e830a908 2005-11-06 devnull wsnarf(w);
347 e830a908 2005-11-06 devnull break;
348 e830a908 2005-11-06 devnull
349 e830a908 2005-11-06 devnull case Paste:
350 3fd51250 2005-11-07 devnull riogetsnarf();
351 e830a908 2005-11-06 devnull wpaste(w);
352 e830a908 2005-11-06 devnull wscrdraw(w);
353 e830a908 2005-11-06 devnull break;
354 e830a908 2005-11-06 devnull
355 e830a908 2005-11-06 devnull case Plumb:
356 e830a908 2005-11-06 devnull wplumb(w);
357 a4e59b37 2020-01-07 crossd break;
358 a4e59b37 2020-01-07 crossd
359 a4e59b37 2020-01-07 crossd case Look:
360 a4e59b37 2020-01-07 crossd wlook(w);
361 e830a908 2005-11-06 devnull break;
362 e830a908 2005-11-06 devnull
363 e830a908 2005-11-06 devnull case Send:
364 3fd51250 2005-11-07 devnull riogetsnarf();
365 e830a908 2005-11-06 devnull wsnarf(w);
366 e830a908 2005-11-06 devnull if(nsnarf == 0)
367 e830a908 2005-11-06 devnull break;
368 e830a908 2005-11-06 devnull if(w->rawing){
369 e830a908 2005-11-06 devnull waddraw(w, snarf, nsnarf);
370 e830a908 2005-11-06 devnull if(snarf[nsnarf-1]!='\n' && snarf[nsnarf-1]!='\004')
371 e830a908 2005-11-06 devnull waddraw(w, newline, 1);
372 e830a908 2005-11-06 devnull }else{
373 e830a908 2005-11-06 devnull winsert(w, snarf, nsnarf, w->nr);
374 e830a908 2005-11-06 devnull if(snarf[nsnarf-1]!='\n' && snarf[nsnarf-1]!='\004')
375 e830a908 2005-11-06 devnull winsert(w, newline, 1, w->nr);
376 e830a908 2005-11-06 devnull }
377 e830a908 2005-11-06 devnull wsetselect(w, w->nr, w->nr);
378 e830a908 2005-11-06 devnull wshow(w, w->nr);
379 e830a908 2005-11-06 devnull break;
380 210d461c 2011-10-12 rsc
381 210d461c 2011-10-12 rsc case Scroll:
382 210d461c 2011-10-12 rsc if(w->scrolling ^= 1)
383 210d461c 2011-10-12 rsc wshow(w, w->nr);
384 210d461c 2011-10-12 rsc break;
385 e830a908 2005-11-06 devnull case Cook:
386 e830a908 2005-11-06 devnull cooked ^= 1;
387 e830a908 2005-11-06 devnull break;
388 e830a908 2005-11-06 devnull }
389 e830a908 2005-11-06 devnull wclose(w);
390 e830a908 2005-11-06 devnull wsendctlmesg(w, Wakeup, ZR, nil);
391 e830a908 2005-11-06 devnull flushimage(display, 1);
392 e830a908 2005-11-06 devnull }
393 e830a908 2005-11-06 devnull
394 e830a908 2005-11-06 devnull int
395 e830a908 2005-11-06 devnull rawon(void)
396 e830a908 2005-11-06 devnull {
397 e830a908 2005-11-06 devnull return !cooked && !isecho(sfd);
398 e830a908 2005-11-06 devnull }
399 e830a908 2005-11-06 devnull
400 e830a908 2005-11-06 devnull /*
401 e830a908 2005-11-06 devnull * I/O with child rc.
402 e830a908 2005-11-06 devnull */
403 e830a908 2005-11-06 devnull
404 e830a908 2005-11-06 devnull int label(Rune*, int);
405 e830a908 2005-11-06 devnull
406 e830a908 2005-11-06 devnull void
407 e830a908 2005-11-06 devnull rcoutputproc(void *arg)
408 e830a908 2005-11-06 devnull {
409 e830a908 2005-11-06 devnull int i, cnt, n, nb, nr;
410 e830a908 2005-11-06 devnull static char data[9000];
411 e830a908 2005-11-06 devnull Conswritemesg cwm;
412 e830a908 2005-11-06 devnull Rune *r;
413 e830a908 2005-11-06 devnull Stringpair pair;
414 fa325e9b 2020-01-10 cross
415 e830a908 2005-11-06 devnull i = 0;
416 e830a908 2005-11-06 devnull cnt = 0;
417 e830a908 2005-11-06 devnull for(;;){
418 e830a908 2005-11-06 devnull /* XXX Let typing have a go -- maybe there's a rubout waiting. */
419 e830a908 2005-11-06 devnull i = 1-i;
420 e830a908 2005-11-06 devnull n = read(rcfd, data+cnt, sizeof data-cnt);
421 e830a908 2005-11-06 devnull if(n <= 0){
422 e830a908 2005-11-06 devnull if(n < 0)
423 e830a908 2005-11-06 devnull fprint(2, "9term: rc read error: %r\n");
424 e830a908 2005-11-06 devnull threadexitsall("eof on rc output");
425 e830a908 2005-11-06 devnull }
426 ef5c6a6e 2010-09-03 rsc n = echocancel(data+cnt, n);
427 ef5c6a6e 2010-09-03 rsc if(n == 0)
428 ef5c6a6e 2010-09-03 rsc continue;
429 e830a908 2005-11-06 devnull cnt += n;
430 e830a908 2005-11-06 devnull r = runemalloc(cnt);
431 e830a908 2005-11-06 devnull cvttorunes(data, cnt-UTFmax, r, &nb, &nr, nil);
432 e830a908 2005-11-06 devnull /* approach end of buffer */
433 e830a908 2005-11-06 devnull while(fullrune(data+nb, cnt-nb)){
434 e830a908 2005-11-06 devnull nb += chartorune(&r[nr], data+nb);
435 e830a908 2005-11-06 devnull if(r[nr])
436 e830a908 2005-11-06 devnull nr++;
437 e830a908 2005-11-06 devnull }
438 e830a908 2005-11-06 devnull if(nb < cnt)
439 e830a908 2005-11-06 devnull memmove(data, data+nb, cnt-nb);
440 e830a908 2005-11-06 devnull cnt -= nb;
441 fa325e9b 2020-01-10 cross
442 e830a908 2005-11-06 devnull nr = label(r, nr);
443 e830a908 2005-11-06 devnull if(nr == 0)
444 e830a908 2005-11-06 devnull continue;
445 fa325e9b 2020-01-10 cross
446 e830a908 2005-11-06 devnull recv(w->conswrite, &cwm);
447 e830a908 2005-11-06 devnull pair.s = r;
448 e830a908 2005-11-06 devnull pair.ns = nr;
449 e830a908 2005-11-06 devnull send(cwm.cw, &pair);
450 e830a908 2005-11-06 devnull }
451 10ab06a7 2005-11-06 devnull }
452 10ab06a7 2005-11-06 devnull
453 10ab06a7 2005-11-06 devnull void
454 10ab06a7 2005-11-06 devnull winterrupt(Window *w)
455 10ab06a7 2005-11-06 devnull {
456 10ab06a7 2005-11-06 devnull char rubout[1];
457 fa325e9b 2020-01-10 cross
458 10ab06a7 2005-11-06 devnull USED(w);
459 10ab06a7 2005-11-06 devnull rubout[0] = getintr(sfd);
460 10ab06a7 2005-11-06 devnull write(rcfd, rubout, 1);
461 e830a908 2005-11-06 devnull }
462 e830a908 2005-11-06 devnull
463 be7485e1 2017-01-09 rsc int
464 c819ee64 2017-01-09 rsc intrc(void)
465 c819ee64 2017-01-09 rsc {
466 be7485e1 2017-01-09 rsc return getintr(sfd);
467 be7485e1 2017-01-09 rsc }
468 be7485e1 2017-01-09 rsc
469 e830a908 2005-11-06 devnull /*
470 e830a908 2005-11-06 devnull * Process in-band messages about window title changes.
471 e830a908 2005-11-06 devnull * The messages are of the form:
472 e830a908 2005-11-06 devnull *
473 e830a908 2005-11-06 devnull * \033];xxx\007
474 e830a908 2005-11-06 devnull *
475 e830a908 2005-11-06 devnull * where xxx is the new directory. This format was chosen
476 e830a908 2005-11-06 devnull * because it changes the label on xterm windows.
477 e830a908 2005-11-06 devnull */
478 e830a908 2005-11-06 devnull int
479 e830a908 2005-11-06 devnull label(Rune *sr, int n)
480 e830a908 2005-11-06 devnull {
481 e830a908 2005-11-06 devnull Rune *sl, *el, *er, *r;
482 e830a908 2005-11-06 devnull char *p, *dir;
483 fa325e9b 2020-01-10 cross
484 e830a908 2005-11-06 devnull er = sr+n;
485 e830a908 2005-11-06 devnull for(r=er-1; r>=sr; r--)
486 e830a908 2005-11-06 devnull if(*r == '\007')
487 e830a908 2005-11-06 devnull break;
488 e830a908 2005-11-06 devnull if(r < sr)
489 e830a908 2005-11-06 devnull return n;
490 e830a908 2005-11-06 devnull
491 e830a908 2005-11-06 devnull el = r+1;
492 e830a908 2005-11-06 devnull for(sl=el-3; sl>=sr; sl--)
493 e830a908 2005-11-06 devnull if(sl[0]=='\033' && sl[1]==']' && sl[2]==';')
494 e830a908 2005-11-06 devnull break;
495 e830a908 2005-11-06 devnull if(sl < sr)
496 e830a908 2005-11-06 devnull return n;
497 e830a908 2005-11-06 devnull
498 e830a908 2005-11-06 devnull dir = smprint("%.*S", (el-1)-(sl+3), sl+3);
499 e830a908 2005-11-06 devnull if(dir){
500 0e881c05 2011-10-11 rsc if(strcmp(dir, "*9term-hold+") == 0) {
501 0e881c05 2011-10-11 rsc w->holding = 1;
502 0e881c05 2011-10-11 rsc wrepaint(w);
503 f1825251 2011-10-13 rsc flushimage(display, 1);
504 0e881c05 2011-10-11 rsc } else {
505 0e881c05 2011-10-11 rsc drawsetlabel(dir);
506 0e881c05 2011-10-11 rsc free(w->dir);
507 0e881c05 2011-10-11 rsc w->dir = dir;
508 0e881c05 2011-10-11 rsc }
509 e830a908 2005-11-06 devnull }
510 e830a908 2005-11-06 devnull
511 e830a908 2005-11-06 devnull /* remove trailing /-sysname if present */
512 e830a908 2005-11-06 devnull p = strrchr(dir, '/');
513 e830a908 2005-11-06 devnull if(p && *(p+1) == '-'){
514 e830a908 2005-11-06 devnull if(p == dir)
515 e830a908 2005-11-06 devnull p++;
516 e830a908 2005-11-06 devnull *p = 0;
517 e830a908 2005-11-06 devnull }
518 e830a908 2005-11-06 devnull
519 e830a908 2005-11-06 devnull runemove(sl, el, er-el);
520 e830a908 2005-11-06 devnull n -= (el-sl);
521 e830a908 2005-11-06 devnull return n;
522 e830a908 2005-11-06 devnull }
523 e830a908 2005-11-06 devnull
524 e830a908 2005-11-06 devnull void
525 e830a908 2005-11-06 devnull rcinputproc(void *arg)
526 e830a908 2005-11-06 devnull {
527 e830a908 2005-11-06 devnull static char data[9000];
528 e830a908 2005-11-06 devnull Consreadmesg crm;
529 e830a908 2005-11-06 devnull Channel *c1, *c2;
530 e830a908 2005-11-06 devnull Stringpair pair;
531 e830a908 2005-11-06 devnull
532 e830a908 2005-11-06 devnull for(;;){
533 e830a908 2005-11-06 devnull recv(w->consread, &crm);
534 e830a908 2005-11-06 devnull c1 = crm.c1;
535 e830a908 2005-11-06 devnull c2 = crm.c2;
536 fa325e9b 2020-01-10 cross
537 e830a908 2005-11-06 devnull pair.s = data;
538 e830a908 2005-11-06 devnull pair.ns = sizeof data;
539 e830a908 2005-11-06 devnull send(c1, &pair);
540 e830a908 2005-11-06 devnull recv(c2, &pair);
541 ef5c6a6e 2010-09-03 rsc
542 ef5c6a6e 2010-09-03 rsc if(isecho(sfd))
543 ef5c6a6e 2010-09-03 rsc echoed(pair.s, pair.ns);
544 e830a908 2005-11-06 devnull if(write(rcfd, pair.s, pair.ns) < 0)
545 e830a908 2005-11-06 devnull threadexitsall(nil);
546 3fd51250 2005-11-07 devnull }
547 3fd51250 2005-11-07 devnull }
548 3fd51250 2005-11-07 devnull
549 c935adc6 2005-11-10 devnull /*
550 c935adc6 2005-11-10 devnull * Snarf buffer - rio uses runes internally
551 c935adc6 2005-11-10 devnull */
552 3fd51250 2005-11-07 devnull void
553 3fd51250 2005-11-07 devnull rioputsnarf(void)
554 3fd51250 2005-11-07 devnull {
555 3fd51250 2005-11-07 devnull char *s;
556 fa325e9b 2020-01-10 cross
557 3fd51250 2005-11-07 devnull s = smprint("%.*S", nsnarf, snarf);
558 3fd51250 2005-11-07 devnull if(s){
559 3fd51250 2005-11-07 devnull putsnarf(s);
560 3fd51250 2005-11-07 devnull free(s);
561 e830a908 2005-11-06 devnull }
562 e830a908 2005-11-06 devnull }
563 e830a908 2005-11-06 devnull
564 3fd51250 2005-11-07 devnull void
565 3fd51250 2005-11-07 devnull riogetsnarf(void)
566 3fd51250 2005-11-07 devnull {
567 3fd51250 2005-11-07 devnull char *s;
568 3fd51250 2005-11-07 devnull int n, nb, nulls;
569 3fd51250 2005-11-07 devnull
570 3fd51250 2005-11-07 devnull s = getsnarf();
571 3fd51250 2005-11-07 devnull if(s == nil)
572 3fd51250 2005-11-07 devnull return;
573 3fd51250 2005-11-07 devnull n = strlen(s)+1;
574 3fd51250 2005-11-07 devnull free(snarf);
575 3fd51250 2005-11-07 devnull snarf = runemalloc(n);
576 3fd51250 2005-11-07 devnull cvttorunes(s, n, snarf, &nb, &nsnarf, &nulls);
577 3fd51250 2005-11-07 devnull free(s);
578 3fd51250 2005-11-07 devnull }
579 c935adc6 2005-11-10 devnull
580 c935adc6 2005-11-10 devnull /*
581 c935adc6 2005-11-10 devnull * Clumsy hack to make " and "" work.
582 c935adc6 2005-11-10 devnull * Then again, what's not a clumsy hack here in Unix land?
583 c935adc6 2005-11-10 devnull */
584 c935adc6 2005-11-10 devnull
585 c935adc6 2005-11-10 devnull char adir[100];
586 c935adc6 2005-11-10 devnull char thesocket[100];
587 c935adc6 2005-11-10 devnull int afd;
588 c935adc6 2005-11-10 devnull
589 c935adc6 2005-11-10 devnull void listenproc(void*);
590 c935adc6 2005-11-10 devnull void textproc(void*);
591 c935adc6 2005-11-10 devnull
592 c935adc6 2005-11-10 devnull void
593 c935adc6 2005-11-10 devnull removethesocket(void)
594 c935adc6 2005-11-10 devnull {
595 c935adc6 2005-11-10 devnull if(thesocket[0])
596 c935adc6 2005-11-10 devnull if(remove(thesocket) < 0)
597 c935adc6 2005-11-10 devnull fprint(2, "remove %s: %r\n", thesocket);
598 c935adc6 2005-11-10 devnull }
599 c935adc6 2005-11-10 devnull
600 c935adc6 2005-11-10 devnull void
601 c935adc6 2005-11-10 devnull servedevtext(void)
602 c935adc6 2005-11-10 devnull {
603 c935adc6 2005-11-10 devnull char buf[100];
604 c935adc6 2005-11-10 devnull
605 c935adc6 2005-11-10 devnull snprint(buf, sizeof buf, "unix!/tmp/9term-text.%d", getpid());
606 c935adc6 2005-11-10 devnull
607 c935adc6 2005-11-10 devnull if((afd = announce(buf, adir)) < 0){
608 c935adc6 2005-11-10 devnull putenv("text9term", "");
609 c935adc6 2005-11-10 devnull return;
610 c935adc6 2005-11-10 devnull }
611 c935adc6 2005-11-10 devnull
612 c935adc6 2005-11-10 devnull putenv("text9term", buf);
613 c935adc6 2005-11-10 devnull proccreate(listenproc, nil, STACK);
614 c935adc6 2005-11-10 devnull strcpy(thesocket, buf+5);
615 c935adc6 2005-11-10 devnull atexit(removethesocket);
616 c935adc6 2005-11-10 devnull }
617 c935adc6 2005-11-10 devnull
618 c935adc6 2005-11-10 devnull void
619 c935adc6 2005-11-10 devnull listenproc(void *arg)
620 c935adc6 2005-11-10 devnull {
621 c935adc6 2005-11-10 devnull int fd;
622 c935adc6 2005-11-10 devnull char dir[100];
623 c935adc6 2005-11-10 devnull
624 bcc96c1d 2005-11-11 devnull threadsetname("listen %s", thesocket);
625 c935adc6 2005-11-10 devnull USED(arg);
626 c935adc6 2005-11-10 devnull for(;;){
627 c935adc6 2005-11-10 devnull fd = listen(adir, dir);
628 c935adc6 2005-11-10 devnull if(fd < 0){
629 c935adc6 2005-11-10 devnull close(afd);
630 c935adc6 2005-11-10 devnull return;
631 c935adc6 2005-11-10 devnull }
632 e58459c7 2005-12-29 devnull proccreate(textproc, (void*)(uintptr)fd, STACK);
633 c935adc6 2005-11-10 devnull }
634 c935adc6 2005-11-10 devnull }
635 c935adc6 2005-11-10 devnull
636 c935adc6 2005-11-10 devnull void
637 c935adc6 2005-11-10 devnull textproc(void *arg)
638 c935adc6 2005-11-10 devnull {
639 c935adc6 2005-11-10 devnull int fd, i, x, n, end;
640 c935adc6 2005-11-10 devnull Rune r;
641 c935adc6 2005-11-10 devnull char buf[4096], *p, *ep;
642 c935adc6 2005-11-10 devnull
643 bcc96c1d 2005-11-11 devnull threadsetname("textproc");
644 e58459c7 2005-12-29 devnull fd = (uintptr)arg;
645 c935adc6 2005-11-10 devnull p = buf;
646 c935adc6 2005-11-10 devnull ep = buf+sizeof buf;
647 c21d0ab4 2005-11-11 devnull if(w == nil){
648 c21d0ab4 2005-11-11 devnull close(fd);
649 c21d0ab4 2005-11-11 devnull return;
650 c21d0ab4 2005-11-11 devnull }
651 c935adc6 2005-11-10 devnull end = w->org+w->nr; /* avoid possible output loop */
652 c935adc6 2005-11-10 devnull for(i=w->org;; i++){
653 c935adc6 2005-11-10 devnull if(i >= end || ep-p < UTFmax){
654 c935adc6 2005-11-10 devnull for(x=0; x<p-buf; x+=n)
655 c935adc6 2005-11-10 devnull if((n = write(fd, buf+x, (p-x)-buf)) <= 0)
656 c935adc6 2005-11-10 devnull goto break2;
657 fa325e9b 2020-01-10 cross
658 c935adc6 2005-11-10 devnull if(i >= end)
659 c935adc6 2005-11-10 devnull break;
660 c935adc6 2005-11-10 devnull p = buf;
661 c935adc6 2005-11-10 devnull }
662 c935adc6 2005-11-10 devnull if(i < w->org)
663 c935adc6 2005-11-10 devnull i = w->org;
664 c935adc6 2005-11-10 devnull r = w->r[i-w->org];
665 c935adc6 2005-11-10 devnull if(r < Runeself)
666 c935adc6 2005-11-10 devnull *p++ = r;
667 c935adc6 2005-11-10 devnull else
668 c935adc6 2005-11-10 devnull p += runetochar(p, &r);
669 c935adc6 2005-11-10 devnull }
670 c935adc6 2005-11-10 devnull break2:
671 c935adc6 2005-11-10 devnull close(fd);
672 c935adc6 2005-11-10 devnull }