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 8ad51794 2004-03-25 devnull #include "term.h"
14 42c3794c 2004-10-17 devnull
15 42c3794c 2004-10-17 devnull enum
16 42c3794c 2004-10-17 devnull {
17 42c3794c 2004-10-17 devnull STACK = 32768
18 42c3794c 2004-10-17 devnull };
19 b4a659b6 2004-04-19 devnull
20 b4a659b6 2004-04-19 devnull int noecho = 0;
21 42c3794c 2004-10-17 devnull
22 42c3794c 2004-10-17 devnull void servedevtext(void);
23 60535a5f 2004-12-26 devnull void listenproc(void*);
24 42c3794c 2004-10-17 devnull void textthread(void*);
25 ba9ffa53 2004-03-21 devnull
26 ba9ffa53 2004-03-21 devnull typedef struct Text Text;
27 ba9ffa53 2004-03-21 devnull typedef struct Readbuf Readbuf;
28 ba9ffa53 2004-03-21 devnull
29 ba9ffa53 2004-03-21 devnull enum
30 ba9ffa53 2004-03-21 devnull {
31 ba9ffa53 2004-03-21 devnull HiWater = 640000, /* max size of history */
32 8ad51794 2004-03-25 devnull LoWater = 400000, /* min size of history after max'ed */
33 8ad51794 2004-03-25 devnull MinWater = 20000,
34 ba9ffa53 2004-03-21 devnull };
35 ba9ffa53 2004-03-21 devnull
36 ba9ffa53 2004-03-21 devnull /* various geometric paramters */
37 ba9ffa53 2004-03-21 devnull enum
38 ba9ffa53 2004-03-21 devnull {
39 ba9ffa53 2004-03-21 devnull Scrollwid = 12, /* width of scroll bar */
40 ba9ffa53 2004-03-21 devnull Scrollgap = 4, /* gap right of scroll bar */
41 ba9ffa53 2004-03-21 devnull Maxtab = 4,
42 ba9ffa53 2004-03-21 devnull };
43 ba9ffa53 2004-03-21 devnull
44 ba9ffa53 2004-03-21 devnull enum
45 ba9ffa53 2004-03-21 devnull {
46 ba9ffa53 2004-03-21 devnull Cut,
47 ba9ffa53 2004-03-21 devnull Paste,
48 ba9ffa53 2004-03-21 devnull Snarf,
49 ba9ffa53 2004-03-21 devnull Send,
50 ba9ffa53 2004-03-21 devnull Plumb,
51 ba9ffa53 2004-03-21 devnull Scroll,
52 f476c92f 2004-04-18 devnull Cooked,
53 ba9ffa53 2004-03-21 devnull };
54 ba9ffa53 2004-03-21 devnull
55 ba9ffa53 2004-03-21 devnull #define ESC 0x1B
56 8ad51794 2004-03-25 devnull #define CUT 0x18 /* ctrl-x */
57 8ad51794 2004-03-25 devnull #define COPY 0x03 /* crtl-c */
58 8ad51794 2004-03-25 devnull #define PASTE 0x16 /* crtl-v */
59 ba9ffa53 2004-03-21 devnull
60 ba9ffa53 2004-03-21 devnull #define READBUFSIZE 8192
61 8ad51794 2004-03-25 devnull #define TRUE 1
62 8ad51794 2004-03-25 devnull #define FALSE 0
63 ba9ffa53 2004-03-21 devnull
64 8ad51794 2004-03-25 devnull
65 ba9ffa53 2004-03-21 devnull struct Text
66 ba9ffa53 2004-03-21 devnull {
67 ba9ffa53 2004-03-21 devnull Frame *f; /* frame ofr terminal */
68 ba9ffa53 2004-03-21 devnull Mouse m;
69 ba9ffa53 2004-03-21 devnull uint nr; /* num of runes in term */
70 8ad51794 2004-03-25 devnull uint maxr; /* max num of runes in r */
71 ba9ffa53 2004-03-21 devnull Rune *r; /* runes for term */
72 ba9ffa53 2004-03-21 devnull uint nraw; /* num of runes in raw buffer */
73 ba9ffa53 2004-03-21 devnull Rune *raw; /* raw buffer */
74 ba9ffa53 2004-03-21 devnull uint org; /* first rune on the screen */
75 ba9ffa53 2004-03-21 devnull uint q0; /* start of selection region */
76 ba9ffa53 2004-03-21 devnull uint q1; /* end of selection region */
77 ba9ffa53 2004-03-21 devnull uint qh; /* unix point */
78 ba9ffa53 2004-03-21 devnull int npart; /* partial runes read from console */
79 ba9ffa53 2004-03-21 devnull char part[UTFmax];
80 ba9ffa53 2004-03-21 devnull int nsnarf; /* snarf buffer */
81 ba9ffa53 2004-03-21 devnull Rune *snarf;
82 ba9ffa53 2004-03-21 devnull };
83 ba9ffa53 2004-03-21 devnull
84 ba9ffa53 2004-03-21 devnull struct Readbuf
85 ba9ffa53 2004-03-21 devnull {
86 ba9ffa53 2004-03-21 devnull short n; /* # bytes in buf */
87 ba9ffa53 2004-03-21 devnull uchar data[READBUFSIZE]; /* data bytes */
88 ba9ffa53 2004-03-21 devnull };
89 ba9ffa53 2004-03-21 devnull
90 ba9ffa53 2004-03-21 devnull void mouse(void);
91 ba9ffa53 2004-03-21 devnull void domenu2(int);
92 ba9ffa53 2004-03-21 devnull void loop(void);
93 ba9ffa53 2004-03-21 devnull void geom(void);
94 ba9ffa53 2004-03-21 devnull void fill(void);
95 ba9ffa53 2004-03-21 devnull void tcheck(void);
96 ba9ffa53 2004-03-21 devnull void updatesel(void);
97 ba9ffa53 2004-03-21 devnull void doreshape(void);
98 ba9ffa53 2004-03-21 devnull void runewrite(Rune*, int);
99 ba9ffa53 2004-03-21 devnull void consread(void);
100 ba9ffa53 2004-03-21 devnull void conswrite(char*, int);
101 0e25d609 2004-04-20 devnull int bswidth(Rune c, uint start, int eatnl);
102 ba9ffa53 2004-03-21 devnull void cut(void);
103 ba9ffa53 2004-03-21 devnull void paste(Rune*, int, int);
104 ba9ffa53 2004-03-21 devnull void snarfupdate(void);
105 ba9ffa53 2004-03-21 devnull void snarf(void);
106 ba9ffa53 2004-03-21 devnull void show(uint);
107 ba9ffa53 2004-03-21 devnull void key(Rune);
108 ba9ffa53 2004-03-21 devnull void setorigin(uint org, int exact);
109 ba9ffa53 2004-03-21 devnull uint line2q(uint);
110 ba9ffa53 2004-03-21 devnull uint backnl(uint, uint);
111 ba9ffa53 2004-03-21 devnull int cansee(uint);
112 ba9ffa53 2004-03-21 devnull uint backnl(uint, uint);
113 ba9ffa53 2004-03-21 devnull void addraw(Rune*, int);
114 ba9ffa53 2004-03-21 devnull void mselect(void);
115 ba9ffa53 2004-03-21 devnull void doubleclick(uint *q0, uint *q1);
116 ba9ffa53 2004-03-21 devnull int clickmatch(int cl, int cr, int dir, uint *q);
117 ba9ffa53 2004-03-21 devnull Rune *strrune(Rune *s, Rune c);
118 ba9ffa53 2004-03-21 devnull int consready(void);
119 ba9ffa53 2004-03-21 devnull Rectangle scrpos(Rectangle r, ulong p0, ulong p1, ulong tot);
120 ba9ffa53 2004-03-21 devnull void scrdraw(void);
121 ba9ffa53 2004-03-21 devnull void scroll(int);
122 ba9ffa53 2004-03-21 devnull void hostproc(void *arg);
123 ba9ffa53 2004-03-21 devnull void hoststart(void);
124 ba9ffa53 2004-03-21 devnull void plumbstart(void);
125 ba9ffa53 2004-03-21 devnull void plumb(uint, uint);
126 ba9ffa53 2004-03-21 devnull void plumbclick(uint*, uint*);
127 8ad51794 2004-03-25 devnull uint insert(Rune*, int, uint, int);
128 3d991901 2004-06-09 devnull void scrolldown(int);
129 3d991901 2004-06-09 devnull void scrollup(int);
130 cfabc3ed 2003-11-23 devnull
131 ba9ffa53 2004-03-21 devnull #define runemalloc(n) malloc((n)*sizeof(Rune))
132 ba9ffa53 2004-03-21 devnull #define runerealloc(a, n) realloc(a, (n)*sizeof(Rune))
133 ba9ffa53 2004-03-21 devnull #define runemove(a, b, n) memmove(a, b, (n)*sizeof(Rune))
134 cfabc3ed 2003-11-23 devnull Rectangle scrollr; /* scroll bar rectangle */
135 cfabc3ed 2003-11-23 devnull Rectangle lastsr; /* used for scroll bar */
136 cfabc3ed 2003-11-23 devnull int holdon; /* hold mode */
137 f476c92f 2004-04-18 devnull int rawon(void); /* raw mode */
138 f476c92f 2004-04-18 devnull int cooked; /* force cooked */
139 cfabc3ed 2003-11-23 devnull int scrolling; /* window scrolls */
140 cfabc3ed 2003-11-23 devnull int clickmsec; /* time of last click */
141 cfabc3ed 2003-11-23 devnull uint clickq0; /* point of last click */
142 8ad51794 2004-03-25 devnull int rcfd;
143 4dcd9af2 2004-04-15 devnull int sfd; /* slave fd, to get/set terminal mode */
144 cfabc3ed 2003-11-23 devnull int rcpid;
145 cfabc3ed 2003-11-23 devnull int maxtab;
146 ba9ffa53 2004-03-21 devnull int use9wm;
147 cfabc3ed 2003-11-23 devnull Mousectl* mc;
148 cfabc3ed 2003-11-23 devnull Keyboardctl* kc;
149 cfabc3ed 2003-11-23 devnull Channel* hostc;
150 cfabc3ed 2003-11-23 devnull Readbuf rcbuf[2];
151 cfabc3ed 2003-11-23 devnull int mainpid;
152 ba9ffa53 2004-03-21 devnull int acmecolors;
153 cfabc3ed 2003-11-23 devnull int plumbfd;
154 d3acba95 2003-12-04 devnull int button2exec;
155 cfabc3ed 2003-11-23 devnull int label(Rune*, int);
156 cfabc3ed 2003-11-23 devnull char wdir[1024];
157 21a17ff3 2003-11-25 devnull char childwdir[1024];
158 cfabc3ed 2003-11-23 devnull void hangupnote(void*, char*);
159 c3e73c01 2004-10-17 devnull char thesocket[100];
160 cfabc3ed 2003-11-23 devnull
161 cfabc3ed 2003-11-23 devnull char *menu2str[] = {
162 cfabc3ed 2003-11-23 devnull "cut",
163 cfabc3ed 2003-11-23 devnull "paste",
164 cfabc3ed 2003-11-23 devnull "snarf",
165 cfabc3ed 2003-11-23 devnull "send",
166 cfabc3ed 2003-11-23 devnull "plumb",
167 ba9ffa53 2004-03-21 devnull "scroll",
168 f476c92f 2004-04-18 devnull "cooked",
169 cfabc3ed 2003-11-23 devnull 0
170 cfabc3ed 2003-11-23 devnull };
171 cfabc3ed 2003-11-23 devnull
172 cfabc3ed 2003-11-23 devnull Image* cols[NCOL];
173 cfabc3ed 2003-11-23 devnull Image* hcols[NCOL];
174 4f30f3b4 2004-03-30 devnull Image* palegrey;
175 4f30f3b4 2004-03-30 devnull Image* paleblue;
176 4f30f3b4 2004-03-30 devnull Image* blue;
177 cfabc3ed 2003-11-23 devnull Image *plumbcolor;
178 d3acba95 2003-12-04 devnull Image *execcolor;
179 cfabc3ed 2003-11-23 devnull
180 cfabc3ed 2003-11-23 devnull Menu menu2 =
181 cfabc3ed 2003-11-23 devnull {
182 cfabc3ed 2003-11-23 devnull menu2str
183 cfabc3ed 2003-11-23 devnull };
184 cfabc3ed 2003-11-23 devnull
185 cfabc3ed 2003-11-23 devnull Text t;
186 cfabc3ed 2003-11-23 devnull
187 cfabc3ed 2003-11-23 devnull Cursor whitearrow = {
188 cfabc3ed 2003-11-23 devnull {0, 0},
189 cfabc3ed 2003-11-23 devnull {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
190 cfabc3ed 2003-11-23 devnull 0xFF, 0xF0, 0xFF, 0xF0, 0xFF, 0xF8, 0xFF, 0xFC,
191 cfabc3ed 2003-11-23 devnull 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFC,
192 cfabc3ed 2003-11-23 devnull 0xF3, 0xF8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, },
193 cfabc3ed 2003-11-23 devnull {0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x06, 0xC0, 0x1C,
194 cfabc3ed 2003-11-23 devnull 0xC0, 0x30, 0xC0, 0x30, 0xC0, 0x38, 0xC0, 0x1C,
195 cfabc3ed 2003-11-23 devnull 0xC0, 0x0E, 0xC0, 0x07, 0xCE, 0x0E, 0xDF, 0x1C,
196 cfabc3ed 2003-11-23 devnull 0xD3, 0xB8, 0xF1, 0xF0, 0xE0, 0xE0, 0xC0, 0x40, }
197 cfabc3ed 2003-11-23 devnull };
198 cfabc3ed 2003-11-23 devnull
199 acc021b8 2005-01-02 devnull Cursor query = {
200 acc021b8 2005-01-02 devnull {-7,-7},
201 acc021b8 2005-01-02 devnull {0x0f, 0xf0, 0x1f, 0xf8, 0x3f, 0xfc, 0x7f, 0xfe,
202 acc021b8 2005-01-02 devnull 0x7c, 0x7e, 0x78, 0x7e, 0x00, 0xfc, 0x01, 0xf8,
203 acc021b8 2005-01-02 devnull 0x03, 0xf0, 0x07, 0xe0, 0x07, 0xc0, 0x07, 0xc0,
204 acc021b8 2005-01-02 devnull 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xc0, },
205 acc021b8 2005-01-02 devnull {0x00, 0x00, 0x0f, 0xf0, 0x1f, 0xf8, 0x3c, 0x3c,
206 acc021b8 2005-01-02 devnull 0x38, 0x1c, 0x00, 0x3c, 0x00, 0x78, 0x00, 0xf0,
207 acc021b8 2005-01-02 devnull 0x01, 0xe0, 0x03, 0xc0, 0x03, 0x80, 0x03, 0x80,
208 acc021b8 2005-01-02 devnull 0x00, 0x00, 0x03, 0x80, 0x03, 0x80, 0x00, 0x00, }
209 acc021b8 2005-01-02 devnull };
210 acc021b8 2005-01-02 devnull
211 cfabc3ed 2003-11-23 devnull void
212 d3acba95 2003-12-04 devnull usage(void)
213 d3acba95 2003-12-04 devnull {
214 be36ff68 2004-04-29 devnull fprint(2, "usage: 9term [-ars] [-W winsize] [cmd ...]\n");
215 d3acba95 2003-12-04 devnull threadexitsall("usage");
216 d3acba95 2003-12-04 devnull }
217 d3acba95 2003-12-04 devnull
218 d3acba95 2003-12-04 devnull void
219 cfabc3ed 2003-11-23 devnull threadmain(int argc, char *argv[])
220 cfabc3ed 2003-11-23 devnull {
221 aa808685 2004-04-19 devnull char *p, *font;
222 2d930d45 2004-04-25 devnull char buf[32];
223 cfabc3ed 2003-11-23 devnull
224 cfabc3ed 2003-11-23 devnull rfork(RFNOTEG);
225 aa808685 2004-04-19 devnull font = nil;
226 4f30f3b4 2004-03-30 devnull _wantfocuschanges = 1;
227 cfabc3ed 2003-11-23 devnull mainpid = getpid();
228 cfabc3ed 2003-11-23 devnull ARGBEGIN{
229 d3acba95 2003-12-04 devnull default:
230 d3acba95 2003-12-04 devnull usage();
231 d3acba95 2003-12-04 devnull case 'a': /* acme mode */
232 d3acba95 2003-12-04 devnull button2exec++;
233 cfabc3ed 2003-11-23 devnull break;
234 aa808685 2004-04-19 devnull case 'f':
235 aa808685 2004-04-19 devnull font = EARGF(usage());
236 aa808685 2004-04-19 devnull break;
237 cfabc3ed 2003-11-23 devnull case 's':
238 cfabc3ed 2003-11-23 devnull scrolling++;
239 cfabc3ed 2003-11-23 devnull break;
240 ba9ffa53 2004-03-21 devnull case 'w': /* started from "rio" window manager */
241 ba9ffa53 2004-03-21 devnull use9wm = 1;
242 ba9ffa53 2004-03-21 devnull break;
243 be36ff68 2004-04-29 devnull case 'W':
244 be36ff68 2004-04-29 devnull winsize = EARGF(usage());
245 be36ff68 2004-04-29 devnull break;
246 cfabc3ed 2003-11-23 devnull }ARGEND
247 cfabc3ed 2003-11-23 devnull
248 aa808685 2004-04-19 devnull if(font)
249 aa808685 2004-04-19 devnull putenv("font", font);
250 aa808685 2004-04-19 devnull
251 cfabc3ed 2003-11-23 devnull p = getenv("tabstop");
252 cfabc3ed 2003-11-23 devnull if(p == 0)
253 cfabc3ed 2003-11-23 devnull p = getenv("TABSTOP");
254 cfabc3ed 2003-11-23 devnull if(p != 0 && maxtab <= 0)
255 cfabc3ed 2003-11-23 devnull maxtab = strtoul(p, 0, 0);
256 cfabc3ed 2003-11-23 devnull if(maxtab <= 0)
257 2d930d45 2004-04-25 devnull maxtab = 4; /* be like rio */
258 2d930d45 2004-04-25 devnull
259 2d930d45 2004-04-25 devnull snprint(buf, sizeof buf, "%d", maxtab);
260 304b47c1 2004-04-25 devnull putenv("tabstop", buf);
261 cfabc3ed 2003-11-23 devnull
262 be22ae2d 2004-03-26 devnull initdraw(0, nil, "9term");
263 cfabc3ed 2003-11-23 devnull notify(hangupnote);
264 60535a5f 2004-12-26 devnull noteenable("sys: child");
265 42c3794c 2004-10-17 devnull servedevtext();
266 cfabc3ed 2003-11-23 devnull
267 cfabc3ed 2003-11-23 devnull mc = initmouse(nil, screen);
268 cfabc3ed 2003-11-23 devnull kc = initkeyboard(nil);
269 4dcd9af2 2004-04-15 devnull rcpid = rcstart(argc, argv, &rcfd, &sfd);
270 cfabc3ed 2003-11-23 devnull hoststart();
271 cfabc3ed 2003-11-23 devnull plumbstart();
272 cfabc3ed 2003-11-23 devnull
273 cfabc3ed 2003-11-23 devnull t.f = mallocz(sizeof(Frame), 1);
274 cfabc3ed 2003-11-23 devnull
275 ba9ffa53 2004-03-21 devnull if(acmecolors){
276 ba9ffa53 2004-03-21 devnull cols[BACK] = allocimagemix(display, DPaleyellow, DWhite);
277 ba9ffa53 2004-03-21 devnull cols[HIGH] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DDarkyellow);
278 ba9ffa53 2004-03-21 devnull cols[BORD] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DYellowgreen);
279 ba9ffa53 2004-03-21 devnull }else{
280 ba9ffa53 2004-03-21 devnull cols[BACK] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DWhite);
281 ba9ffa53 2004-03-21 devnull cols[HIGH] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0xCCCCCCFF);
282 ba9ffa53 2004-03-21 devnull cols[BORD] = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x999999FF);
283 ba9ffa53 2004-03-21 devnull }
284 cfabc3ed 2003-11-23 devnull cols[TEXT] = display->black;
285 cfabc3ed 2003-11-23 devnull cols[HTEXT] = display->black;
286 4f30f3b4 2004-03-30 devnull palegrey = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, 0x666666FF);
287 cfabc3ed 2003-11-23 devnull
288 cfabc3ed 2003-11-23 devnull hcols[BACK] = cols[BACK];
289 cfabc3ed 2003-11-23 devnull hcols[HIGH] = cols[HIGH];
290 4f30f3b4 2004-03-30 devnull blue = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DMedblue);
291 4f30f3b4 2004-03-30 devnull paleblue = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, DGreyblue);
292 4f30f3b4 2004-03-30 devnull
293 4f30f3b4 2004-03-30 devnull hcols[BORD] = blue;
294 cfabc3ed 2003-11-23 devnull hcols[TEXT] = hcols[BORD];
295 cfabc3ed 2003-11-23 devnull hcols[HTEXT] = hcols[TEXT];
296 cfabc3ed 2003-11-23 devnull
297 cfabc3ed 2003-11-23 devnull plumbcolor = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x006600FF);
298 d3acba95 2003-12-04 devnull execcolor = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xAA0000FF);
299 cfabc3ed 2003-11-23 devnull
300 4f30f3b4 2004-03-30 devnull if(!blue || !palegrey || !paleblue || !plumbcolor || !execcolor)
301 4f30f3b4 2004-03-30 devnull sysfatal("alloc colors: %r");
302 cfabc3ed 2003-11-23 devnull draw(screen, screen->r, cols[BACK], nil, ZP);
303 cfabc3ed 2003-11-23 devnull geom();
304 cfabc3ed 2003-11-23 devnull loop();
305 4999080d 2005-02-11 devnull }
306 4999080d 2005-02-11 devnull
307 4999080d 2005-02-11 devnull int
308 4999080d 2005-02-11 devnull isexpand(Rune r)
309 4999080d 2005-02-11 devnull {
310 040b6da0 2005-05-01 devnull return r=='_' || ('0' <= r && r <= '9') || isalpharune(r);
311 cfabc3ed 2003-11-23 devnull }
312 cfabc3ed 2003-11-23 devnull
313 cfabc3ed 2003-11-23 devnull void
314 cfabc3ed 2003-11-23 devnull hangupnote(void *a, char *msg)
315 cfabc3ed 2003-11-23 devnull {
316 cfabc3ed 2003-11-23 devnull if(getpid() != mainpid)
317 cfabc3ed 2003-11-23 devnull noted(NDFLT);
318 cfabc3ed 2003-11-23 devnull if(strcmp(msg, "hangup") == 0 && rcpid != 0){
319 669250d1 2003-12-03 devnull postnote(PNGROUP, rcpid, "hangup");
320 cfabc3ed 2003-11-23 devnull noted(NDFLT);
321 4dcd9af2 2004-04-15 devnull }
322 4dcd9af2 2004-04-15 devnull if(strstr(msg, "child")){
323 e4508449 2005-01-07 devnull char buf[128];
324 e4508449 2005-01-07 devnull int n;
325 e4508449 2005-01-07 devnull
326 e4508449 2005-01-07 devnull n = awaitnohang(buf, sizeof buf-1);
327 e4508449 2005-01-07 devnull if(n > 0){
328 e4508449 2005-01-07 devnull buf[n] = 0;
329 e4508449 2005-01-07 devnull if(atoi(buf) == rcpid)
330 e4508449 2005-01-07 devnull threadexitsall(0);
331 e4508449 2005-01-07 devnull }
332 e4508449 2005-01-07 devnull noted(NCONT);
333 cfabc3ed 2003-11-23 devnull }
334 cfabc3ed 2003-11-23 devnull noted(NDFLT);
335 cfabc3ed 2003-11-23 devnull }
336 cfabc3ed 2003-11-23 devnull
337 cfabc3ed 2003-11-23 devnull void
338 cfabc3ed 2003-11-23 devnull hostproc(void *arg)
339 cfabc3ed 2003-11-23 devnull {
340 cfabc3ed 2003-11-23 devnull Channel *c;
341 cfabc3ed 2003-11-23 devnull int i, n, which;
342 cfabc3ed 2003-11-23 devnull
343 cfabc3ed 2003-11-23 devnull c = arg;
344 cfabc3ed 2003-11-23 devnull
345 cfabc3ed 2003-11-23 devnull i = 0;
346 cfabc3ed 2003-11-23 devnull for(;;){
347 8ad51794 2004-03-25 devnull /* Let typing have a go -- maybe there's a rubout waiting. */
348 4dcd9af2 2004-04-15 devnull yield();
349 4dcd9af2 2004-04-15 devnull
350 cfabc3ed 2003-11-23 devnull i = 1-i; /* toggle */
351 60535a5f 2004-12-26 devnull n = read(rcfd, rcbuf[i].data, sizeof rcbuf[i].data);
352 cfabc3ed 2003-11-23 devnull if(n <= 0){
353 cfabc3ed 2003-11-23 devnull if(n < 0)
354 cfabc3ed 2003-11-23 devnull fprint(2, "9term: host read error: %r\n");
355 cfabc3ed 2003-11-23 devnull threadexitsall("host");
356 cfabc3ed 2003-11-23 devnull }
357 cfabc3ed 2003-11-23 devnull rcbuf[i].n = n;
358 cfabc3ed 2003-11-23 devnull which = i;
359 cfabc3ed 2003-11-23 devnull send(c, &which);
360 cfabc3ed 2003-11-23 devnull }
361 cfabc3ed 2003-11-23 devnull }
362 cfabc3ed 2003-11-23 devnull
363 cfabc3ed 2003-11-23 devnull void
364 cfabc3ed 2003-11-23 devnull hoststart(void)
365 cfabc3ed 2003-11-23 devnull {
366 cfabc3ed 2003-11-23 devnull hostc = chancreate(sizeof(int), 0);
367 60535a5f 2004-12-26 devnull proccreate(hostproc, hostc, 32*1024);
368 cfabc3ed 2003-11-23 devnull }
369 cfabc3ed 2003-11-23 devnull
370 cfabc3ed 2003-11-23 devnull void
371 cfabc3ed 2003-11-23 devnull loop(void)
372 cfabc3ed 2003-11-23 devnull {
373 cfabc3ed 2003-11-23 devnull Rune r;
374 cfabc3ed 2003-11-23 devnull int i;
375 be22ae2d 2004-03-26 devnull Alt a[5];
376 be22ae2d 2004-03-26 devnull
377 be22ae2d 2004-03-26 devnull a[0].c = mc->c;
378 be22ae2d 2004-03-26 devnull a[0].v = &mc->m;
379 be22ae2d 2004-03-26 devnull a[0].op = CHANRCV;
380 be22ae2d 2004-03-26 devnull
381 be22ae2d 2004-03-26 devnull a[1].c = kc->c;
382 be22ae2d 2004-03-26 devnull a[1].v = &r;
383 be22ae2d 2004-03-26 devnull a[1].op = CHANRCV;
384 cfabc3ed 2003-11-23 devnull
385 be22ae2d 2004-03-26 devnull a[2].c = hostc;
386 be22ae2d 2004-03-26 devnull a[2].v = &i;
387 be22ae2d 2004-03-26 devnull a[2].op = CHANRCV;
388 be22ae2d 2004-03-26 devnull
389 be22ae2d 2004-03-26 devnull a[3].c = mc->resizec;
390 be22ae2d 2004-03-26 devnull a[3].v = nil;
391 be22ae2d 2004-03-26 devnull a[3].op = CHANRCV;
392 be22ae2d 2004-03-26 devnull
393 be22ae2d 2004-03-26 devnull a[4].c = nil;
394 be22ae2d 2004-03-26 devnull a[4].v = nil;
395 be22ae2d 2004-03-26 devnull a[4].op = CHANEND;
396 be22ae2d 2004-03-26 devnull
397 cfabc3ed 2003-11-23 devnull for(;;) {
398 cfabc3ed 2003-11-23 devnull tcheck();
399 cfabc3ed 2003-11-23 devnull
400 cfabc3ed 2003-11-23 devnull scrdraw();
401 cfabc3ed 2003-11-23 devnull flushimage(display, 1);
402 cfabc3ed 2003-11-23 devnull a[2].op = CHANRCV;
403 cfabc3ed 2003-11-23 devnull if(!scrolling && t.qh > t.org+t.f->nchars)
404 cfabc3ed 2003-11-23 devnull a[2].op = CHANNOP;;
405 cfabc3ed 2003-11-23 devnull switch(alt(a)) {
406 cfabc3ed 2003-11-23 devnull default:
407 8ad51794 2004-03-25 devnull sysfatal("impossible");
408 cfabc3ed 2003-11-23 devnull case 0:
409 cfabc3ed 2003-11-23 devnull t.m = mc->m;
410 cfabc3ed 2003-11-23 devnull mouse();
411 cfabc3ed 2003-11-23 devnull break;
412 cfabc3ed 2003-11-23 devnull case 1:
413 cfabc3ed 2003-11-23 devnull key(r);
414 cfabc3ed 2003-11-23 devnull break;
415 cfabc3ed 2003-11-23 devnull case 2:
416 be22ae2d 2004-03-26 devnull conswrite((char*)rcbuf[i].data, rcbuf[i].n);
417 cfabc3ed 2003-11-23 devnull break;
418 cfabc3ed 2003-11-23 devnull case 3:
419 cfabc3ed 2003-11-23 devnull doreshape();
420 cfabc3ed 2003-11-23 devnull break;
421 cfabc3ed 2003-11-23 devnull }
422 cfabc3ed 2003-11-23 devnull }
423 cfabc3ed 2003-11-23 devnull }
424 cfabc3ed 2003-11-23 devnull
425 cfabc3ed 2003-11-23 devnull void
426 cfabc3ed 2003-11-23 devnull doreshape(void)
427 cfabc3ed 2003-11-23 devnull {
428 cfabc3ed 2003-11-23 devnull if(getwindow(display, Refnone) < 0)
429 8ad51794 2004-03-25 devnull sysfatal("can't reattach to window");
430 cfabc3ed 2003-11-23 devnull draw(screen, screen->r, cols[BACK], nil, ZP);
431 cfabc3ed 2003-11-23 devnull geom();
432 cfabc3ed 2003-11-23 devnull scrdraw();
433 cfabc3ed 2003-11-23 devnull }
434 cfabc3ed 2003-11-23 devnull
435 cfabc3ed 2003-11-23 devnull void
436 cfabc3ed 2003-11-23 devnull geom(void)
437 cfabc3ed 2003-11-23 devnull {
438 669250d1 2003-12-03 devnull Point p;
439 cfabc3ed 2003-11-23 devnull Rectangle r;
440 4f30f3b4 2004-03-30 devnull
441 4f30f3b4 2004-03-30 devnull if(!acmecolors){
442 4f30f3b4 2004-03-30 devnull if(_windowhasfocus){
443 4f30f3b4 2004-03-30 devnull cols[TEXT] = cols[HTEXT] = display->black;
444 4f30f3b4 2004-03-30 devnull hcols[TEXT] = hcols[HTEXT] = blue;
445 4f30f3b4 2004-03-30 devnull }else{
446 4f30f3b4 2004-03-30 devnull cols[TEXT] = cols[HTEXT] = palegrey;
447 4f30f3b4 2004-03-30 devnull hcols[TEXT] = hcols[HTEXT] = paleblue;
448 4f30f3b4 2004-03-30 devnull }
449 4f30f3b4 2004-03-30 devnull }
450 cfabc3ed 2003-11-23 devnull
451 cfabc3ed 2003-11-23 devnull r = screen->r;
452 8ad51794 2004-03-25 devnull r.min.y++;
453 8ad51794 2004-03-25 devnull r.max.y--;
454 8ad51794 2004-03-25 devnull
455 8ad51794 2004-03-25 devnull scrollr = r;
456 cfabc3ed 2003-11-23 devnull scrollr.max.x = r.min.x+Scrollwid;
457 cfabc3ed 2003-11-23 devnull lastsr = Rect(0,0,0,0);
458 cfabc3ed 2003-11-23 devnull
459 cfabc3ed 2003-11-23 devnull r.min.x += Scrollwid+Scrollgap;
460 cfabc3ed 2003-11-23 devnull
461 cfabc3ed 2003-11-23 devnull frclear(t.f, 0);
462 cfabc3ed 2003-11-23 devnull frinit(t.f, r, font, screen, holdon ? hcols : cols);
463 cfabc3ed 2003-11-23 devnull t.f->maxtab = maxtab*stringwidth(font, "0");
464 cfabc3ed 2003-11-23 devnull fill();
465 cfabc3ed 2003-11-23 devnull updatesel();
466 669250d1 2003-12-03 devnull
467 669250d1 2003-12-03 devnull p = stringsize(font, "0");
468 669250d1 2003-12-03 devnull if(p.x == 0 || p.y == 0)
469 669250d1 2003-12-03 devnull return;
470 669250d1 2003-12-03 devnull
471 8ad51794 2004-03-25 devnull updatewinsize(Dy(r)/p.y, Dx(r)/p.x, Dx(r), Dy(r));
472 cfabc3ed 2003-11-23 devnull }
473 cfabc3ed 2003-11-23 devnull
474 cfabc3ed 2003-11-23 devnull void
475 cfabc3ed 2003-11-23 devnull drawhold(int holdon)
476 cfabc3ed 2003-11-23 devnull {
477 cfabc3ed 2003-11-23 devnull if(holdon)
478 cfabc3ed 2003-11-23 devnull setcursor(mc, &whitearrow);
479 cfabc3ed 2003-11-23 devnull else
480 cfabc3ed 2003-11-23 devnull setcursor(mc, nil);
481 cfabc3ed 2003-11-23 devnull
482 cfabc3ed 2003-11-23 devnull draw(screen, screen->r, cols[BACK], nil, ZP);
483 cfabc3ed 2003-11-23 devnull geom();
484 cfabc3ed 2003-11-23 devnull scrdraw();
485 cfabc3ed 2003-11-23 devnull }
486 cfabc3ed 2003-11-23 devnull
487 d3acba95 2003-12-04 devnull void
488 d3acba95 2003-12-04 devnull wordclick(uint *q0, uint *q1)
489 d3acba95 2003-12-04 devnull {
490 d3acba95 2003-12-04 devnull while(*q1<t.nr && !isspace(t.r[*q1]))
491 d3acba95 2003-12-04 devnull (*q1)++;
492 d3acba95 2003-12-04 devnull while(*q0>0 && !isspace(t.r[*q0-1]))
493 d3acba95 2003-12-04 devnull (*q0)--;
494 d3acba95 2003-12-04 devnull }
495 cfabc3ed 2003-11-23 devnull
496 d3acba95 2003-12-04 devnull int
497 d3acba95 2003-12-04 devnull aselect(uint *q0, uint *q1, Image *color)
498 d3acba95 2003-12-04 devnull {
499 d3acba95 2003-12-04 devnull int cancel;
500 d3acba95 2003-12-04 devnull uint oldq0, oldq1, newq0, newq1;
501 d3acba95 2003-12-04 devnull
502 d3acba95 2003-12-04 devnull /* save old selection */
503 d3acba95 2003-12-04 devnull oldq0 = t.q0;
504 d3acba95 2003-12-04 devnull oldq1 = t.q1;
505 d3acba95 2003-12-04 devnull
506 d3acba95 2003-12-04 devnull /* sweep out area and record it */
507 d3acba95 2003-12-04 devnull t.f->cols[HIGH] = color;
508 d3acba95 2003-12-04 devnull t.f->cols[HTEXT] = display->white;
509 d3acba95 2003-12-04 devnull mselect();
510 d3acba95 2003-12-04 devnull newq0 = t.q0;
511 d3acba95 2003-12-04 devnull newq1 = t.q1;
512 d3acba95 2003-12-04 devnull
513 d3acba95 2003-12-04 devnull cancel = 0;
514 d3acba95 2003-12-04 devnull if(t.m.buttons != 0){
515 d3acba95 2003-12-04 devnull while(t.m.buttons){
516 d3acba95 2003-12-04 devnull readmouse(mc);
517 d3acba95 2003-12-04 devnull t.m = mc->m;
518 d3acba95 2003-12-04 devnull }
519 d3acba95 2003-12-04 devnull cancel = 1;
520 d3acba95 2003-12-04 devnull }
521 d3acba95 2003-12-04 devnull
522 d3acba95 2003-12-04 devnull /* restore old selection */
523 d3acba95 2003-12-04 devnull t.f->cols[HIGH] = cols[HIGH];
524 d3acba95 2003-12-04 devnull t.f->cols[HTEXT] = cols[HTEXT];
525 d3acba95 2003-12-04 devnull t.q0 = oldq0;
526 d3acba95 2003-12-04 devnull t.q1 = oldq1;
527 d3acba95 2003-12-04 devnull updatesel();
528 d3acba95 2003-12-04 devnull
529 d3acba95 2003-12-04 devnull if(cancel)
530 d3acba95 2003-12-04 devnull return -1;
531 d3acba95 2003-12-04 devnull
532 d3acba95 2003-12-04 devnull /* selected a region */
533 d3acba95 2003-12-04 devnull if(newq0 < newq1){
534 d3acba95 2003-12-04 devnull *q0 = newq0;
535 d3acba95 2003-12-04 devnull *q1 = newq1;
536 d3acba95 2003-12-04 devnull return 0;
537 d3acba95 2003-12-04 devnull }
538 d3acba95 2003-12-04 devnull
539 d3acba95 2003-12-04 devnull /* clicked inside previous selection */
540 e97ceade 2003-12-06 devnull /* the "<=" in newq0 <= oldq1 allows us to click the right edge */
541 e97ceade 2003-12-06 devnull if(oldq0 <= newq0 && newq0 <= oldq1){
542 d3acba95 2003-12-04 devnull *q0 = oldq0;
543 d3acba95 2003-12-04 devnull *q1 = oldq1;
544 d3acba95 2003-12-04 devnull return 0;
545 d3acba95 2003-12-04 devnull }
546 d3acba95 2003-12-04 devnull
547 d3acba95 2003-12-04 devnull /* just a click */
548 d3acba95 2003-12-04 devnull *q0 = newq0;
549 d3acba95 2003-12-04 devnull *q1 = newq1;
550 d3acba95 2003-12-04 devnull return 0;
551 d3acba95 2003-12-04 devnull }
552 d3acba95 2003-12-04 devnull
553 d3acba95 2003-12-04 devnull static Rune Lnl[1] = { '\n' };
554 d3acba95 2003-12-04 devnull
555 cfabc3ed 2003-11-23 devnull void
556 cfabc3ed 2003-11-23 devnull mouse(void)
557 cfabc3ed 2003-11-23 devnull {
558 d3acba95 2003-12-04 devnull int but;
559 d3acba95 2003-12-04 devnull uint q0, q1;
560 cfabc3ed 2003-11-23 devnull
561 cfabc3ed 2003-11-23 devnull but = t.m.buttons;
562 cfabc3ed 2003-11-23 devnull
563 3d991901 2004-06-09 devnull if(but != 1 && but != 2 && but != 4 && but != 8 && but != 16)
564 cfabc3ed 2003-11-23 devnull return;
565 cfabc3ed 2003-11-23 devnull
566 cfabc3ed 2003-11-23 devnull if (ptinrect(t.m.xy, scrollr)) {
567 cfabc3ed 2003-11-23 devnull scroll(but);
568 cfabc3ed 2003-11-23 devnull if(t.qh<=t.org+t.f->nchars)
569 3fd755b7 2003-12-04 devnull consread();
570 cfabc3ed 2003-11-23 devnull return;
571 cfabc3ed 2003-11-23 devnull }
572 cfabc3ed 2003-11-23 devnull
573 cfabc3ed 2003-11-23 devnull switch(but) {
574 cfabc3ed 2003-11-23 devnull case 1:
575 cfabc3ed 2003-11-23 devnull mselect();
576 cfabc3ed 2003-11-23 devnull break;
577 cfabc3ed 2003-11-23 devnull case 2:
578 d3acba95 2003-12-04 devnull if(button2exec){
579 d3acba95 2003-12-04 devnull if(aselect(&q0, &q1, execcolor) >= 0){
580 d3acba95 2003-12-04 devnull if(q0 == q1)
581 d3acba95 2003-12-04 devnull wordclick(&q0, &q1);
582 d3acba95 2003-12-04 devnull if(q0 == q1)
583 d3acba95 2003-12-04 devnull break;
584 dff7e273 2003-12-04 devnull t.q0 = t.q1 = t.nr;
585 dff7e273 2003-12-04 devnull updatesel();
586 d3acba95 2003-12-04 devnull paste(t.r+q0, q1-q0, 1);
587 d3acba95 2003-12-04 devnull if(t.r[q1-1] != '\n')
588 d3acba95 2003-12-04 devnull paste(Lnl, 1, 1);
589 d3acba95 2003-12-04 devnull }
590 d3acba95 2003-12-04 devnull break;
591 d3acba95 2003-12-04 devnull }
592 cfabc3ed 2003-11-23 devnull domenu2(2);
593 cfabc3ed 2003-11-23 devnull break;
594 cfabc3ed 2003-11-23 devnull case 4:
595 78802e69 2004-04-24 devnull bouncemouse(&t.m);
596 78802e69 2004-04-24 devnull break;
597 78802e69 2004-04-24 devnull /*
598 d3acba95 2003-12-04 devnull if(aselect(&q0, &q1, plumbcolor) >= 0)
599 d3acba95 2003-12-04 devnull plumb(q0, q1);
600 cfabc3ed 2003-11-23 devnull break;
601 78802e69 2004-04-24 devnull */
602 3d991901 2004-06-09 devnull case 8:
603 d7037d62 2004-06-11 devnull scrollup(mousescrollsize(t.f->maxlines));
604 3d991901 2004-06-09 devnull break;
605 3d991901 2004-06-09 devnull case 16:
606 d7037d62 2004-06-11 devnull scrolldown(mousescrollsize(t.f->maxlines));
607 3d991901 2004-06-09 devnull break;
608 cfabc3ed 2003-11-23 devnull }
609 cfabc3ed 2003-11-23 devnull }
610 cfabc3ed 2003-11-23 devnull
611 cfabc3ed 2003-11-23 devnull void
612 cfabc3ed 2003-11-23 devnull mselect(void)
613 cfabc3ed 2003-11-23 devnull {
614 cfabc3ed 2003-11-23 devnull int b, x, y;
615 cfabc3ed 2003-11-23 devnull uint q0;
616 cfabc3ed 2003-11-23 devnull
617 cfabc3ed 2003-11-23 devnull b = t.m.buttons;
618 cfabc3ed 2003-11-23 devnull q0 = frcharofpt(t.f, t.m.xy) + t.org;
619 dff7e273 2003-12-04 devnull if(t.m.msec-clickmsec<500 && clickq0==q0 && t.q0==t.q1 && b==1){
620 cfabc3ed 2003-11-23 devnull doubleclick(&t.q0, &t.q1);
621 cfabc3ed 2003-11-23 devnull updatesel();
622 cfabc3ed 2003-11-23 devnull /* t.t.i->flush(); */
623 cfabc3ed 2003-11-23 devnull x = t.m.xy.x;
624 cfabc3ed 2003-11-23 devnull y = t.m.xy.y;
625 cfabc3ed 2003-11-23 devnull /* stay here until something interesting happens */
626 cfabc3ed 2003-11-23 devnull do {
627 cfabc3ed 2003-11-23 devnull readmouse(mc);
628 cfabc3ed 2003-11-23 devnull t.m = mc->m;
629 cfabc3ed 2003-11-23 devnull } while(t.m.buttons==b && abs(t.m.xy.x-x)<4 && abs(t.m.xy.y-y)<4);
630 cfabc3ed 2003-11-23 devnull t.m.xy.x = x; /* in case we're calling frselect */
631 cfabc3ed 2003-11-23 devnull t.m.xy.y = y;
632 cfabc3ed 2003-11-23 devnull clickmsec = 0;
633 cfabc3ed 2003-11-23 devnull }
634 cfabc3ed 2003-11-23 devnull
635 cfabc3ed 2003-11-23 devnull if(t.m.buttons == b) {
636 cfabc3ed 2003-11-23 devnull frselect(t.f, mc);
637 cfabc3ed 2003-11-23 devnull t.m = mc->m;
638 cfabc3ed 2003-11-23 devnull t.q0 = t.f->p0 + t.org;
639 cfabc3ed 2003-11-23 devnull t.q1 = t.f->p1 + t.org;
640 cfabc3ed 2003-11-23 devnull clickmsec = t.m.msec;
641 cfabc3ed 2003-11-23 devnull clickq0 = t.q0;
642 cfabc3ed 2003-11-23 devnull }
643 dff7e273 2003-12-04 devnull if((t.m.buttons != b) &&(b&1)){
644 dff7e273 2003-12-04 devnull enum{Cancut = 1, Canpaste = 2} state = Cancut | Canpaste;
645 cfabc3ed 2003-11-23 devnull while(t.m.buttons){
646 dff7e273 2003-12-04 devnull if(t.m.buttons&2){
647 dff7e273 2003-12-04 devnull if(state&Cancut){
648 cfabc3ed 2003-11-23 devnull snarf();
649 cfabc3ed 2003-11-23 devnull cut();
650 cfabc3ed 2003-11-23 devnull state = Canpaste;
651 cfabc3ed 2003-11-23 devnull }
652 dff7e273 2003-12-04 devnull }else if(t.m.buttons&4){
653 dff7e273 2003-12-04 devnull if(state&Canpaste){
654 cfabc3ed 2003-11-23 devnull snarfupdate();
655 dff7e273 2003-12-04 devnull if(t.nsnarf){
656 cfabc3ed 2003-11-23 devnull paste(t.snarf, t.nsnarf, 0);
657 cfabc3ed 2003-11-23 devnull }
658 23084133 2004-03-26 devnull state = Cancut;
659 cfabc3ed 2003-11-23 devnull }
660 cfabc3ed 2003-11-23 devnull }
661 cfabc3ed 2003-11-23 devnull readmouse(mc);
662 cfabc3ed 2003-11-23 devnull t.m = mc->m;
663 cfabc3ed 2003-11-23 devnull }
664 cfabc3ed 2003-11-23 devnull }
665 cfabc3ed 2003-11-23 devnull }
666 cfabc3ed 2003-11-23 devnull
667 cfabc3ed 2003-11-23 devnull Rune newline[] = { '\n', 0 };
668 cfabc3ed 2003-11-23 devnull
669 cfabc3ed 2003-11-23 devnull void
670 cfabc3ed 2003-11-23 devnull domenu2(int but)
671 cfabc3ed 2003-11-23 devnull {
672 cfabc3ed 2003-11-23 devnull if(scrolling)
673 f80f53a9 2004-04-21 devnull menu2str[Scroll] = "+ scroll";
674 cfabc3ed 2003-11-23 devnull else
675 f80f53a9 2004-04-21 devnull menu2str[Scroll] = "- scroll";
676 f80f53a9 2004-04-21 devnull if(cooked)
677 f80f53a9 2004-04-21 devnull menu2str[Cooked] = "+ mustecho";
678 f476c92f 2004-04-18 devnull else
679 f80f53a9 2004-04-21 devnull menu2str[Cooked] = "- mustecho";
680 cfabc3ed 2003-11-23 devnull
681 cfabc3ed 2003-11-23 devnull switch(menuhit(but, mc, &menu2, nil)){
682 cfabc3ed 2003-11-23 devnull case -1:
683 cfabc3ed 2003-11-23 devnull break;
684 cfabc3ed 2003-11-23 devnull case Cut:
685 cfabc3ed 2003-11-23 devnull snarf();
686 cfabc3ed 2003-11-23 devnull cut();
687 cfabc3ed 2003-11-23 devnull if(scrolling)
688 cfabc3ed 2003-11-23 devnull show(t.q0);
689 cfabc3ed 2003-11-23 devnull break;
690 cfabc3ed 2003-11-23 devnull case Paste:
691 cfabc3ed 2003-11-23 devnull snarfupdate();
692 cfabc3ed 2003-11-23 devnull paste(t.snarf, t.nsnarf, 0);
693 cfabc3ed 2003-11-23 devnull if(scrolling)
694 cfabc3ed 2003-11-23 devnull show(t.q0);
695 cfabc3ed 2003-11-23 devnull break;
696 cfabc3ed 2003-11-23 devnull case Snarf:
697 cfabc3ed 2003-11-23 devnull snarf();
698 cfabc3ed 2003-11-23 devnull if(scrolling)
699 cfabc3ed 2003-11-23 devnull show(t.q0);
700 cfabc3ed 2003-11-23 devnull break;
701 cfabc3ed 2003-11-23 devnull case Send:
702 8ad51794 2004-03-25 devnull if(t.q0 != t.q1)
703 8ad51794 2004-03-25 devnull snarf();
704 8ad51794 2004-03-25 devnull else
705 8ad51794 2004-03-25 devnull snarfupdate();
706 cfabc3ed 2003-11-23 devnull t.q0 = t.q1 = t.nr;
707 cfabc3ed 2003-11-23 devnull updatesel();
708 cfabc3ed 2003-11-23 devnull paste(t.snarf, t.nsnarf, 1);
709 cfabc3ed 2003-11-23 devnull if(t.nsnarf == 0 || t.snarf[t.nsnarf-1] != '\n')
710 cfabc3ed 2003-11-23 devnull paste(newline, 1, 1);
711 cfabc3ed 2003-11-23 devnull show(t.nr);
712 cfabc3ed 2003-11-23 devnull consread();
713 cfabc3ed 2003-11-23 devnull break;
714 cfabc3ed 2003-11-23 devnull case Scroll:
715 cfabc3ed 2003-11-23 devnull scrolling = !scrolling;
716 cfabc3ed 2003-11-23 devnull if (scrolling) {
717 cfabc3ed 2003-11-23 devnull show(t.nr);
718 cfabc3ed 2003-11-23 devnull consread();
719 cfabc3ed 2003-11-23 devnull }
720 cfabc3ed 2003-11-23 devnull break;
721 cfabc3ed 2003-11-23 devnull case Plumb:
722 cfabc3ed 2003-11-23 devnull plumb(t.q0, t.q1);
723 cfabc3ed 2003-11-23 devnull break;
724 f476c92f 2004-04-18 devnull case Cooked:
725 f476c92f 2004-04-18 devnull cooked = !cooked;
726 f476c92f 2004-04-18 devnull break;
727 cfabc3ed 2003-11-23 devnull default:
728 8ad51794 2004-03-25 devnull sysfatal("bad menu item");
729 cfabc3ed 2003-11-23 devnull }
730 8ad51794 2004-03-25 devnull }
731 8ad51794 2004-03-25 devnull
732 8ad51794 2004-03-25 devnull int
733 8ad51794 2004-03-25 devnull windfilewidth(uint q0, int oneelement)
734 8ad51794 2004-03-25 devnull {
735 8ad51794 2004-03-25 devnull uint q;
736 8ad51794 2004-03-25 devnull Rune r;
737 8ad51794 2004-03-25 devnull
738 8ad51794 2004-03-25 devnull q = q0;
739 8ad51794 2004-03-25 devnull while(q > 0){
740 8ad51794 2004-03-25 devnull r = t.r[q-1];
741 8ad51794 2004-03-25 devnull if(r<=' ')
742 8ad51794 2004-03-25 devnull break;
743 8ad51794 2004-03-25 devnull if(oneelement && r=='/')
744 8ad51794 2004-03-25 devnull break;
745 8ad51794 2004-03-25 devnull --q;
746 8ad51794 2004-03-25 devnull }
747 8ad51794 2004-03-25 devnull return q0-q;
748 cfabc3ed 2003-11-23 devnull }
749 cfabc3ed 2003-11-23 devnull
750 cfabc3ed 2003-11-23 devnull void
751 8ad51794 2004-03-25 devnull showcandidates(Completion *c)
752 8ad51794 2004-03-25 devnull {
753 8ad51794 2004-03-25 devnull int i;
754 8ad51794 2004-03-25 devnull Fmt f;
755 8ad51794 2004-03-25 devnull Rune *rp;
756 8ad51794 2004-03-25 devnull uint nr, qline, q0;
757 8ad51794 2004-03-25 devnull char *s;
758 8ad51794 2004-03-25 devnull
759 8ad51794 2004-03-25 devnull runefmtstrinit(&f);
760 8ad51794 2004-03-25 devnull if (c->nmatch == 0)
761 8ad51794 2004-03-25 devnull s = "[no matches in ";
762 8ad51794 2004-03-25 devnull else
763 8ad51794 2004-03-25 devnull s = "[";
764 8ad51794 2004-03-25 devnull if(c->nfile > 32)
765 8ad51794 2004-03-25 devnull fmtprint(&f, "%s%d files]\n", s, c->nfile);
766 8ad51794 2004-03-25 devnull else{
767 8ad51794 2004-03-25 devnull fmtprint(&f, "%s", s);
768 8ad51794 2004-03-25 devnull for(i=0; i<c->nfile; i++){
769 8ad51794 2004-03-25 devnull if(i > 0)
770 8ad51794 2004-03-25 devnull fmtprint(&f, " ");
771 8ad51794 2004-03-25 devnull fmtprint(&f, "%s", c->filename[i]);
772 8ad51794 2004-03-25 devnull }
773 8ad51794 2004-03-25 devnull fmtprint(&f, "]\n");
774 8ad51794 2004-03-25 devnull }
775 8ad51794 2004-03-25 devnull /* place text at beginning of line before host point */
776 8ad51794 2004-03-25 devnull qline = t.qh;
777 8ad51794 2004-03-25 devnull while(qline>0 && t.r[qline-1] != '\n')
778 8ad51794 2004-03-25 devnull qline--;
779 8ad51794 2004-03-25 devnull
780 8ad51794 2004-03-25 devnull rp = runefmtstrflush(&f);
781 8ad51794 2004-03-25 devnull nr = runestrlen(rp);
782 8ad51794 2004-03-25 devnull
783 8ad51794 2004-03-25 devnull q0 = t.q0;
784 8ad51794 2004-03-25 devnull q0 += insert(rp, nr, qline, 0) - qline;
785 8ad51794 2004-03-25 devnull free(rp);
786 8ad51794 2004-03-25 devnull t.q0 = q0+nr;
787 8ad51794 2004-03-25 devnull t.q1 = q0+nr;
788 8ad51794 2004-03-25 devnull updatesel();
789 8ad51794 2004-03-25 devnull }
790 8ad51794 2004-03-25 devnull
791 8ad51794 2004-03-25 devnull Rune*
792 8ad51794 2004-03-25 devnull namecomplete(void)
793 8ad51794 2004-03-25 devnull {
794 8ad51794 2004-03-25 devnull int nstr, npath;
795 8ad51794 2004-03-25 devnull Rune *rp, *path, *str;
796 8ad51794 2004-03-25 devnull Completion *c;
797 8ad51794 2004-03-25 devnull char *s, *dir, *root;
798 8ad51794 2004-03-25 devnull
799 8ad51794 2004-03-25 devnull /* control-f: filename completion; works back to white space or / */
800 8ad51794 2004-03-25 devnull if(t.q0<t.nr && t.r[t.q0]>' ') /* must be at end of word */
801 8ad51794 2004-03-25 devnull return nil;
802 8ad51794 2004-03-25 devnull nstr = windfilewidth(t.q0, TRUE);
803 8ad51794 2004-03-25 devnull str = runemalloc(nstr);
804 8ad51794 2004-03-25 devnull runemove(str, t.r+(t.q0-nstr), nstr);
805 8ad51794 2004-03-25 devnull npath = windfilewidth(t.q0-nstr, FALSE);
806 8ad51794 2004-03-25 devnull path = runemalloc(npath);
807 8ad51794 2004-03-25 devnull runemove(path, t.r+(t.q0-nstr-npath), npath);
808 8ad51794 2004-03-25 devnull rp = nil;
809 8ad51794 2004-03-25 devnull
810 8ad51794 2004-03-25 devnull /* is path rooted? if not, we need to make it relative to window path */
811 8ad51794 2004-03-25 devnull if(npath>0 && path[0]=='/'){
812 8ad51794 2004-03-25 devnull dir = malloc(UTFmax*npath+1);
813 8ad51794 2004-03-25 devnull sprint(dir, "%.*S", npath, path);
814 8ad51794 2004-03-25 devnull }else{
815 8ad51794 2004-03-25 devnull if(strcmp(wdir, "") == 0)
816 8ad51794 2004-03-25 devnull root = ".";
817 8ad51794 2004-03-25 devnull else
818 8ad51794 2004-03-25 devnull root = wdir;
819 8ad51794 2004-03-25 devnull dir = malloc(strlen(root)+1+UTFmax*npath+1);
820 8ad51794 2004-03-25 devnull sprint(dir, "%s/%.*S", root, npath, path);
821 8ad51794 2004-03-25 devnull }
822 8ad51794 2004-03-25 devnull dir = cleanname(dir);
823 8ad51794 2004-03-25 devnull
824 8ad51794 2004-03-25 devnull s = smprint("%.*S", nstr, str);
825 8ad51794 2004-03-25 devnull c = complete(dir, s);
826 8ad51794 2004-03-25 devnull free(s);
827 8ad51794 2004-03-25 devnull if(c == nil)
828 8ad51794 2004-03-25 devnull goto Return;
829 8ad51794 2004-03-25 devnull
830 8ad51794 2004-03-25 devnull if(!c->advance)
831 8ad51794 2004-03-25 devnull showcandidates(c);
832 8ad51794 2004-03-25 devnull
833 8ad51794 2004-03-25 devnull if(c->advance)
834 8ad51794 2004-03-25 devnull rp = runesmprint("%s", c->string);
835 8ad51794 2004-03-25 devnull
836 8ad51794 2004-03-25 devnull Return:
837 8ad51794 2004-03-25 devnull freecompletion(c);
838 8ad51794 2004-03-25 devnull free(dir);
839 8ad51794 2004-03-25 devnull free(path);
840 8ad51794 2004-03-25 devnull free(str);
841 8ad51794 2004-03-25 devnull return rp;
842 3d991901 2004-06-09 devnull }
843 3d991901 2004-06-09 devnull
844 3d991901 2004-06-09 devnull void
845 3d991901 2004-06-09 devnull scrollup(int n)
846 3d991901 2004-06-09 devnull {
847 3d991901 2004-06-09 devnull setorigin(backnl(t.org, n), 1);
848 3d991901 2004-06-09 devnull }
849 3d991901 2004-06-09 devnull
850 3d991901 2004-06-09 devnull void
851 3d991901 2004-06-09 devnull scrolldown(int n)
852 3d991901 2004-06-09 devnull {
853 3d991901 2004-06-09 devnull setorigin(line2q(n), 1);
854 3d991901 2004-06-09 devnull if(t.qh<=t.org+t.f->nchars)
855 3d991901 2004-06-09 devnull consread();
856 8ad51794 2004-03-25 devnull }
857 8ad51794 2004-03-25 devnull
858 8ad51794 2004-03-25 devnull void
859 cfabc3ed 2003-11-23 devnull key(Rune r)
860 cfabc3ed 2003-11-23 devnull {
861 8ad51794 2004-03-25 devnull Rune *rp;
862 8ad51794 2004-03-25 devnull int nr;
863 cfabc3ed 2003-11-23 devnull
864 cfabc3ed 2003-11-23 devnull if(r == 0)
865 cfabc3ed 2003-11-23 devnull return;
866 8ad51794 2004-03-25 devnull switch(r){
867 8ad51794 2004-03-25 devnull case Kpgup:
868 3d991901 2004-06-09 devnull scrollup(t.f->maxlines*2/3);
869 8ad51794 2004-03-25 devnull return;
870 8ad51794 2004-03-25 devnull case Kpgdown:
871 3d991901 2004-06-09 devnull scrolldown(t.f->maxlines*2/3);
872 cfabc3ed 2003-11-23 devnull return;
873 8ad51794 2004-03-25 devnull case Kup:
874 3d991901 2004-06-09 devnull scrollup(t.f->maxlines/3);
875 cfabc3ed 2003-11-23 devnull return;
876 8ad51794 2004-03-25 devnull case Kdown:
877 3d991901 2004-06-09 devnull scrolldown(t.f->maxlines/3);
878 8ad51794 2004-03-25 devnull return;
879 8ad51794 2004-03-25 devnull case Kleft:
880 8ad51794 2004-03-25 devnull if(t.q0 > 0){
881 8ad51794 2004-03-25 devnull t.q0--;
882 8ad51794 2004-03-25 devnull t.q1 = t.q0;
883 8ad51794 2004-03-25 devnull updatesel();
884 8ad51794 2004-03-25 devnull show(t.q0);
885 8ad51794 2004-03-25 devnull }
886 8ad51794 2004-03-25 devnull return;
887 8ad51794 2004-03-25 devnull case Kright:
888 8ad51794 2004-03-25 devnull if(t.q1 < t.nr){
889 8ad51794 2004-03-25 devnull t.q1++;
890 8ad51794 2004-03-25 devnull t.q0 = t.q1;
891 8ad51794 2004-03-25 devnull updatesel();
892 8ad51794 2004-03-25 devnull show(t.q1);
893 8ad51794 2004-03-25 devnull }
894 8ad51794 2004-03-25 devnull return;
895 8ad51794 2004-03-25 devnull case Khome:
896 8ad51794 2004-03-25 devnull show(0);
897 8ad51794 2004-03-25 devnull return;
898 8ad51794 2004-03-25 devnull case Kend:
899 8ad51794 2004-03-25 devnull case 0x05:
900 8ad51794 2004-03-25 devnull show(t.nr);
901 8ad51794 2004-03-25 devnull return;
902 42c3794c 2004-10-17 devnull
903 42c3794c 2004-10-17 devnull /*
904 42c3794c 2004-10-17 devnull * Non-standard extensions.
905 42c3794c 2004-10-17 devnull */
906 8ad51794 2004-03-25 devnull case CUT:
907 cfabc3ed 2003-11-23 devnull snarf();
908 cfabc3ed 2003-11-23 devnull cut();
909 cfabc3ed 2003-11-23 devnull if(scrolling)
910 cfabc3ed 2003-11-23 devnull show(t.q0);
911 cfabc3ed 2003-11-23 devnull return;
912 8ad51794 2004-03-25 devnull case COPY:
913 cfabc3ed 2003-11-23 devnull snarf();
914 cfabc3ed 2003-11-23 devnull if(scrolling)
915 cfabc3ed 2003-11-23 devnull show(t.q0);
916 cfabc3ed 2003-11-23 devnull return;
917 8ad51794 2004-03-25 devnull case PASTE:
918 cfabc3ed 2003-11-23 devnull snarfupdate();
919 cfabc3ed 2003-11-23 devnull paste(t.snarf, t.nsnarf, 0);
920 cfabc3ed 2003-11-23 devnull if(scrolling)
921 cfabc3ed 2003-11-23 devnull show(t.q0);
922 e5c26b01 2004-09-20 devnull return;
923 e5c26b01 2004-09-20 devnull }
924 e5c26b01 2004-09-20 devnull
925 55d360f6 2005-07-13 devnull /*
926 55d360f6 2005-07-13 devnull * This if used to be below the if(rawon() && t.q0==t.nr),
927 55d360f6 2005-07-13 devnull * but let's try putting it here. This will allow ESC-processing
928 55d360f6 2005-07-13 devnull * to toggle hold mode even in remote SSH connections.
929 55d360f6 2005-07-13 devnull * The drawback is that vi-style processing gets harder.
930 55d360f6 2005-07-13 devnull * If you find yourself in some weird readline mode, good
931 55d360f6 2005-07-13 devnull * luck getting out without ESC. Let's see who complains.
932 55d360f6 2005-07-13 devnull */
933 55d360f6 2005-07-13 devnull if(r==ESC){ /* toggle hold */
934 55d360f6 2005-07-13 devnull holdon = !holdon;
935 55d360f6 2005-07-13 devnull drawhold(holdon);
936 55d360f6 2005-07-13 devnull /* replaceintegerproperty("_9WM_HOLD_MODE", 1, 32, holdon); */
937 55d360f6 2005-07-13 devnull if(!holdon)
938 55d360f6 2005-07-13 devnull consread();
939 55d360f6 2005-07-13 devnull return;
940 55d360f6 2005-07-13 devnull }
941 55d360f6 2005-07-13 devnull
942 6cc5b304 2005-07-14 devnull if(!holdon && rawon() && t.q0 == t.nr){
943 8d9f61e1 2005-02-08 devnull addraw(&r, 1);
944 8d9f61e1 2005-02-08 devnull consread();
945 cfabc3ed 2003-11-23 devnull return;
946 cfabc3ed 2003-11-23 devnull }
947 cfabc3ed 2003-11-23 devnull
948 8d9f61e1 2005-02-08 devnull if(r == 0x7F){ /* DEL: send interrupt; what a mess */
949 8d9f61e1 2005-02-08 devnull if(holdon){
950 8d9f61e1 2005-02-08 devnull holdon = 0;
951 8d9f61e1 2005-02-08 devnull drawhold(holdon);
952 8d9f61e1 2005-02-08 devnull }
953 8d9f61e1 2005-02-08 devnull t.qh = t.q0 = t.q1 = t.nr;
954 8d9f61e1 2005-02-08 devnull show(t.q0);
955 8d9f61e1 2005-02-08 devnull write(rcfd, "\x7F", 1);
956 cfabc3ed 2003-11-23 devnull return;
957 cfabc3ed 2003-11-23 devnull }
958 cfabc3ed 2003-11-23 devnull
959 cfabc3ed 2003-11-23 devnull snarf();
960 cfabc3ed 2003-11-23 devnull
961 cfabc3ed 2003-11-23 devnull switch(r) {
962 8ad51794 2004-03-25 devnull case 0x06: /* ^F: file name completion */
963 8ad51794 2004-03-25 devnull case Kins: /* Insert: file name completion */
964 8ad51794 2004-03-25 devnull rp = namecomplete();
965 8ad51794 2004-03-25 devnull if(rp == nil)
966 8ad51794 2004-03-25 devnull return;
967 8ad51794 2004-03-25 devnull nr = runestrlen(rp);
968 8ad51794 2004-03-25 devnull paste(rp, nr, 1);
969 8ad51794 2004-03-25 devnull free(rp);
970 8ad51794 2004-03-25 devnull return;
971 cfabc3ed 2003-11-23 devnull case 0x08: /* ^H: erase character */
972 cfabc3ed 2003-11-23 devnull case 0x15: /* ^U: erase line */
973 cfabc3ed 2003-11-23 devnull case 0x17: /* ^W: erase word */
974 cfabc3ed 2003-11-23 devnull if (t.q0 != 0 && t.q0 != t.qh)
975 0e25d609 2004-04-20 devnull t.q0 -= bswidth(r, t.q0, 1);
976 cfabc3ed 2003-11-23 devnull cut();
977 cfabc3ed 2003-11-23 devnull break;
978 cfabc3ed 2003-11-23 devnull default:
979 cfabc3ed 2003-11-23 devnull paste(&r, 1, 1);
980 cfabc3ed 2003-11-23 devnull break;
981 cfabc3ed 2003-11-23 devnull }
982 cfabc3ed 2003-11-23 devnull if(scrolling)
983 cfabc3ed 2003-11-23 devnull show(t.q0);
984 cfabc3ed 2003-11-23 devnull }
985 cfabc3ed 2003-11-23 devnull
986 cfabc3ed 2003-11-23 devnull int
987 0e25d609 2004-04-20 devnull bswidth(Rune c, uint start, int eatnl)
988 cfabc3ed 2003-11-23 devnull {
989 cfabc3ed 2003-11-23 devnull uint q, eq, stop;
990 cfabc3ed 2003-11-23 devnull Rune r;
991 cfabc3ed 2003-11-23 devnull int skipping;
992 cfabc3ed 2003-11-23 devnull
993 cfabc3ed 2003-11-23 devnull /* there is known to be at least one character to erase */
994 cfabc3ed 2003-11-23 devnull if(c == 0x08) /* ^H: erase character */
995 cfabc3ed 2003-11-23 devnull return 1;
996 0e25d609 2004-04-20 devnull q = start;
997 cfabc3ed 2003-11-23 devnull stop = 0;
998 cfabc3ed 2003-11-23 devnull if(q > t.qh)
999 cfabc3ed 2003-11-23 devnull stop = t.qh;
1000 cfabc3ed 2003-11-23 devnull skipping = 1;
1001 cfabc3ed 2003-11-23 devnull while(q > stop){
1002 cfabc3ed 2003-11-23 devnull r = t.r[q-1];
1003 cfabc3ed 2003-11-23 devnull if(r == '\n'){ /* eat at most one more character */
1004 0e25d609 2004-04-20 devnull if(q == start && eatnl) /* eat the newline */
1005 cfabc3ed 2003-11-23 devnull --q;
1006 cfabc3ed 2003-11-23 devnull break;
1007 cfabc3ed 2003-11-23 devnull }
1008 cfabc3ed 2003-11-23 devnull if(c == 0x17){
1009 4999080d 2005-02-11 devnull eq = isexpand(r);
1010 cfabc3ed 2003-11-23 devnull if(eq && skipping) /* found one; stop skipping */
1011 cfabc3ed 2003-11-23 devnull skipping = 0;
1012 cfabc3ed 2003-11-23 devnull else if(!eq && !skipping)
1013 cfabc3ed 2003-11-23 devnull break;
1014 cfabc3ed 2003-11-23 devnull }
1015 cfabc3ed 2003-11-23 devnull --q;
1016 cfabc3ed 2003-11-23 devnull }
1017 0e25d609 2004-04-20 devnull return start-q;
1018 cfabc3ed 2003-11-23 devnull }
1019 cfabc3ed 2003-11-23 devnull
1020 cfabc3ed 2003-11-23 devnull int
1021 cfabc3ed 2003-11-23 devnull consready(void)
1022 cfabc3ed 2003-11-23 devnull {
1023 cfabc3ed 2003-11-23 devnull int i, c;
1024 cfabc3ed 2003-11-23 devnull
1025 cfabc3ed 2003-11-23 devnull if(holdon)
1026 cfabc3ed 2003-11-23 devnull return 0;
1027 cfabc3ed 2003-11-23 devnull
1028 f476c92f 2004-04-18 devnull if(rawon())
1029 6cc5b304 2005-07-14 devnull return t.nraw != 0 || t.qh < t.nr;
1030 cfabc3ed 2003-11-23 devnull
1031 cfabc3ed 2003-11-23 devnull /* look to see if there is a complete line */
1032 cfabc3ed 2003-11-23 devnull for(i=t.qh; i<t.nr; i++){
1033 cfabc3ed 2003-11-23 devnull c = t.r[i];
1034 ba9ffa53 2004-03-21 devnull if(c=='\n' || c=='\004' || c=='\x7F')
1035 cfabc3ed 2003-11-23 devnull return 1;
1036 cfabc3ed 2003-11-23 devnull }
1037 cfabc3ed 2003-11-23 devnull return 0;
1038 cfabc3ed 2003-11-23 devnull }
1039 cfabc3ed 2003-11-23 devnull
1040 cfabc3ed 2003-11-23 devnull
1041 cfabc3ed 2003-11-23 devnull void
1042 cfabc3ed 2003-11-23 devnull consread(void)
1043 cfabc3ed 2003-11-23 devnull {
1044 cfabc3ed 2003-11-23 devnull char buf[8000], *p;
1045 cfabc3ed 2003-11-23 devnull int c, width, n;
1046 f476c92f 2004-04-18 devnull int s, raw;
1047 cfabc3ed 2003-11-23 devnull
1048 f476c92f 2004-04-18 devnull raw = rawon();
1049 cfabc3ed 2003-11-23 devnull for(;;) {
1050 cfabc3ed 2003-11-23 devnull if(!consready())
1051 cfabc3ed 2003-11-23 devnull return;
1052 cfabc3ed 2003-11-23 devnull n = sizeof(buf);
1053 cfabc3ed 2003-11-23 devnull p = buf;
1054 669250d1 2003-12-03 devnull c = 0;
1055 cfabc3ed 2003-11-23 devnull while(n >= UTFmax && (t.qh<t.nr || t.nraw > 0)) {
1056 cfabc3ed 2003-11-23 devnull if(t.qh == t.nr){
1057 cfabc3ed 2003-11-23 devnull width = runetochar(p, &t.raw[0]);
1058 cfabc3ed 2003-11-23 devnull t.nraw--;
1059 cfabc3ed 2003-11-23 devnull runemove(t.raw, t.raw+1, t.nraw);
1060 cfabc3ed 2003-11-23 devnull }else
1061 cfabc3ed 2003-11-23 devnull width = runetochar(p, &t.r[t.qh++]);
1062 cfabc3ed 2003-11-23 devnull c = *p;
1063 cfabc3ed 2003-11-23 devnull p += width;
1064 cfabc3ed 2003-11-23 devnull n -= width;
1065 f476c92f 2004-04-18 devnull if(!raw && (c == '\n' || c == '\004' || c == '\x7F'))
1066 cfabc3ed 2003-11-23 devnull break;
1067 cfabc3ed 2003-11-23 devnull }
1068 669250d1 2003-12-03 devnull n = p-buf;
1069 a2705f20 2004-04-16 devnull
1070 a2705f20 2004-04-16 devnull /*
1071 0fa6e0cf 2004-08-06 devnull * If we've been echoing, make sure the terminal isn't
1072 a2705f20 2004-04-16 devnull * while we do the write. This screws up if someone
1073 0fa6e0cf 2004-08-06 devnull * else tries to turn off echo at the same time we do
1074 0fa6e0cf 2004-08-06 devnull * (we'll turn it on again after the write), but that's not
1075 0fa6e0cf 2004-08-06 devnull * too likely.
1076 a2705f20 2004-04-16 devnull */
1077 a2705f20 2004-04-16 devnull s = setecho(sfd, 0);
1078 8ad51794 2004-03-25 devnull if(write(rcfd, buf, n) < 0)
1079 38c10d1a 2005-01-17 devnull threadexitsall(0);
1080 8773b4b2 2004-08-02 devnull if(s)
1081 8773b4b2 2004-08-02 devnull setecho(sfd, s);
1082 cfabc3ed 2003-11-23 devnull }
1083 cfabc3ed 2003-11-23 devnull }
1084 cfabc3ed 2003-11-23 devnull
1085 cfabc3ed 2003-11-23 devnull void
1086 cfabc3ed 2003-11-23 devnull conswrite(char *p, int n)
1087 cfabc3ed 2003-11-23 devnull {
1088 cfabc3ed 2003-11-23 devnull int n2, i;
1089 cfabc3ed 2003-11-23 devnull Rune buf2[1000], *q;
1090 cfabc3ed 2003-11-23 devnull
1091 cfabc3ed 2003-11-23 devnull /* convert to runes */
1092 cfabc3ed 2003-11-23 devnull i = t.npart;
1093 cfabc3ed 2003-11-23 devnull if(i > 0){
1094 cfabc3ed 2003-11-23 devnull /* handle partial runes */
1095 cfabc3ed 2003-11-23 devnull while(i < UTFmax && n>0) {
1096 cfabc3ed 2003-11-23 devnull t.part[i] = *p;
1097 cfabc3ed 2003-11-23 devnull i++;
1098 cfabc3ed 2003-11-23 devnull p++;
1099 cfabc3ed 2003-11-23 devnull n--;
1100 cfabc3ed 2003-11-23 devnull if(fullrune(t.part, i)) {
1101 cfabc3ed 2003-11-23 devnull t.npart = 0;
1102 cfabc3ed 2003-11-23 devnull chartorune(buf2, t.part);
1103 cfabc3ed 2003-11-23 devnull runewrite(buf2, 1);
1104 cfabc3ed 2003-11-23 devnull break;
1105 cfabc3ed 2003-11-23 devnull }
1106 cfabc3ed 2003-11-23 devnull }
1107 cfabc3ed 2003-11-23 devnull /* there is a little extra room in a message buf */
1108 cfabc3ed 2003-11-23 devnull }
1109 cfabc3ed 2003-11-23 devnull
1110 cfabc3ed 2003-11-23 devnull while(n >= UTFmax || fullrune(p, n)) {
1111 cfabc3ed 2003-11-23 devnull n2 = nelem(buf2);
1112 cfabc3ed 2003-11-23 devnull q = buf2;
1113 cfabc3ed 2003-11-23 devnull
1114 cfabc3ed 2003-11-23 devnull while(n2) {
1115 cfabc3ed 2003-11-23 devnull if(n < UTFmax && !fullrune(p, n))
1116 cfabc3ed 2003-11-23 devnull break;
1117 cfabc3ed 2003-11-23 devnull i = chartorune(q, p);
1118 cfabc3ed 2003-11-23 devnull p += i;
1119 cfabc3ed 2003-11-23 devnull n -= i;
1120 cfabc3ed 2003-11-23 devnull n2--;
1121 cfabc3ed 2003-11-23 devnull q++;
1122 cfabc3ed 2003-11-23 devnull }
1123 cfabc3ed 2003-11-23 devnull runewrite(buf2, q-buf2);
1124 cfabc3ed 2003-11-23 devnull }
1125 cfabc3ed 2003-11-23 devnull
1126 cfabc3ed 2003-11-23 devnull if(n != 0) {
1127 cfabc3ed 2003-11-23 devnull assert(n+t.npart < UTFmax);
1128 cfabc3ed 2003-11-23 devnull memcpy(t.part+t.npart, p, n);
1129 cfabc3ed 2003-11-23 devnull t.npart += n;
1130 cfabc3ed 2003-11-23 devnull }
1131 cfabc3ed 2003-11-23 devnull
1132 cfabc3ed 2003-11-23 devnull if(scrolling)
1133 cfabc3ed 2003-11-23 devnull show(t.qh);
1134 cfabc3ed 2003-11-23 devnull }
1135 cfabc3ed 2003-11-23 devnull
1136 cfabc3ed 2003-11-23 devnull void
1137 cfabc3ed 2003-11-23 devnull runewrite(Rune *r, int n)
1138 cfabc3ed 2003-11-23 devnull {
1139 dcc0b3ca 2005-07-18 devnull static int havecr;
1140 cfabc3ed 2003-11-23 devnull int i;
1141 cfabc3ed 2003-11-23 devnull uint initial;
1142 cfabc3ed 2003-11-23 devnull uint q0, q1;
1143 cfabc3ed 2003-11-23 devnull uint p0, p1;
1144 cfabc3ed 2003-11-23 devnull Rune *p, *q;
1145 cfabc3ed 2003-11-23 devnull
1146 cfabc3ed 2003-11-23 devnull n = label(r, n);
1147 cfabc3ed 2003-11-23 devnull if(n == 0)
1148 cfabc3ed 2003-11-23 devnull return;
1149 cfabc3ed 2003-11-23 devnull
1150 dcc0b3ca 2005-07-18 devnull /* process trailing \r from previous write */
1151 cfabc3ed 2003-11-23 devnull initial = 0;
1152 dcc0b3ca 2005-07-18 devnull if(havecr && *r != '\r' && *r != '\n')
1153 dcc0b3ca 2005-07-18 devnull initial = bswidth(0x15, t.qh, 0);
1154 dcc0b3ca 2005-07-18 devnull havecr = 0;
1155 dcc0b3ca 2005-07-18 devnull
1156 dcc0b3ca 2005-07-18 devnull /* get rid of backspaces */
1157 cfabc3ed 2003-11-23 devnull p = q = r;
1158 cfabc3ed 2003-11-23 devnull for(i=0; i<n; i++) {
1159 cfabc3ed 2003-11-23 devnull if(*p == '\b') {
1160 cfabc3ed 2003-11-23 devnull if(q == r)
1161 cfabc3ed 2003-11-23 devnull initial++;
1162 cfabc3ed 2003-11-23 devnull else
1163 cfabc3ed 2003-11-23 devnull --q;
1164 0e25d609 2004-04-20 devnull } else if(*p == '\r') { /* treat like ^U */
1165 0e25d609 2004-04-20 devnull /* convert CR without NL into erased line */
1166 0e25d609 2004-04-20 devnull /* i feel really sleazy about this but it helps */
1167 304b47c1 2004-04-25 devnull while(i<n-1 && *(p+1) == '\r'){
1168 304b47c1 2004-04-25 devnull i++;
1169 304b47c1 2004-04-25 devnull p++;
1170 304b47c1 2004-04-25 devnull }
1171 0e25d609 2004-04-20 devnull if(i<n-1 && *(p+1) != '\n'){
1172 0e25d609 2004-04-20 devnull while(q > r && *(q-1) != '\n')
1173 0e25d609 2004-04-20 devnull q--;
1174 0e25d609 2004-04-20 devnull if(q==r)
1175 0e25d609 2004-04-20 devnull initial = bswidth(0x15, t.qh, 0);
1176 dcc0b3ca 2005-07-18 devnull }else if(i == n-1)
1177 dcc0b3ca 2005-07-18 devnull havecr = 1;
1178 cfabc3ed 2003-11-23 devnull } else if(*p)
1179 cfabc3ed 2003-11-23 devnull *q++ = *p;
1180 cfabc3ed 2003-11-23 devnull p++;
1181 cfabc3ed 2003-11-23 devnull }
1182 cfabc3ed 2003-11-23 devnull n = q-r;
1183 cfabc3ed 2003-11-23 devnull
1184 cfabc3ed 2003-11-23 devnull if(initial){
1185 cfabc3ed 2003-11-23 devnull /* write turned into a delete */
1186 cfabc3ed 2003-11-23 devnull
1187 cfabc3ed 2003-11-23 devnull if(initial > t.qh)
1188 cfabc3ed 2003-11-23 devnull initial = t.qh;
1189 cfabc3ed 2003-11-23 devnull q0 = t.qh-initial;
1190 cfabc3ed 2003-11-23 devnull q1 = t.qh;
1191 cfabc3ed 2003-11-23 devnull
1192 cfabc3ed 2003-11-23 devnull runemove(t.r+q0, t.r+q1, t.nr-q1);
1193 cfabc3ed 2003-11-23 devnull t.nr -= initial;
1194 cfabc3ed 2003-11-23 devnull t.qh -= initial;
1195 cfabc3ed 2003-11-23 devnull if(t.q0 > q1)
1196 cfabc3ed 2003-11-23 devnull t.q0 -= initial;
1197 cfabc3ed 2003-11-23 devnull else if(t.q0 > q0)
1198 cfabc3ed 2003-11-23 devnull t.q0 = q0;
1199 cfabc3ed 2003-11-23 devnull if(t.q1 > q1)
1200 cfabc3ed 2003-11-23 devnull t.q1 -= initial;
1201 cfabc3ed 2003-11-23 devnull else if(t.q1 > q0)
1202 cfabc3ed 2003-11-23 devnull t.q1 = q0;
1203 cfabc3ed 2003-11-23 devnull if(t.org > q1)
1204 cfabc3ed 2003-11-23 devnull t.org -= initial;
1205 cfabc3ed 2003-11-23 devnull else if(q0 < t.org+t.f->nchars){
1206 cfabc3ed 2003-11-23 devnull if(t.org < q0)
1207 cfabc3ed 2003-11-23 devnull p0 = q0 - t.org;
1208 cfabc3ed 2003-11-23 devnull else {
1209 cfabc3ed 2003-11-23 devnull t.org = q0;
1210 cfabc3ed 2003-11-23 devnull p0 = 0;
1211 cfabc3ed 2003-11-23 devnull }
1212 cfabc3ed 2003-11-23 devnull p1 = q1 - t.org;
1213 cfabc3ed 2003-11-23 devnull if(p1 > t.f->nchars)
1214 cfabc3ed 2003-11-23 devnull p1 = t.f->nchars;
1215 cfabc3ed 2003-11-23 devnull frdelete(t.f, p0, p1);
1216 cfabc3ed 2003-11-23 devnull fill();
1217 cfabc3ed 2003-11-23 devnull }
1218 cfabc3ed 2003-11-23 devnull updatesel();
1219 cfabc3ed 2003-11-23 devnull }
1220 cfabc3ed 2003-11-23 devnull
1221 8ad51794 2004-03-25 devnull insert(r, n, t.qh, 1);
1222 cfabc3ed 2003-11-23 devnull }
1223 cfabc3ed 2003-11-23 devnull
1224 cfabc3ed 2003-11-23 devnull
1225 cfabc3ed 2003-11-23 devnull void
1226 cfabc3ed 2003-11-23 devnull cut(void)
1227 cfabc3ed 2003-11-23 devnull {
1228 cfabc3ed 2003-11-23 devnull uint n, p0, p1;
1229 cfabc3ed 2003-11-23 devnull uint q0, q1;
1230 cfabc3ed 2003-11-23 devnull
1231 cfabc3ed 2003-11-23 devnull q0 = t.q0;
1232 cfabc3ed 2003-11-23 devnull q1 = t.q1;
1233 cfabc3ed 2003-11-23 devnull
1234 cfabc3ed 2003-11-23 devnull if (q0 < t.org && q1 >= t.org)
1235 cfabc3ed 2003-11-23 devnull show(q0);
1236 cfabc3ed 2003-11-23 devnull
1237 cfabc3ed 2003-11-23 devnull n = q1-q0;
1238 cfabc3ed 2003-11-23 devnull if(n == 0)
1239 cfabc3ed 2003-11-23 devnull return;
1240 cfabc3ed 2003-11-23 devnull runemove(t.r+q0, t.r+q1, t.nr-q1);
1241 cfabc3ed 2003-11-23 devnull t.nr -= n;
1242 cfabc3ed 2003-11-23 devnull t.q0 = t.q1 = q0;
1243 cfabc3ed 2003-11-23 devnull if(q1 < t.qh)
1244 cfabc3ed 2003-11-23 devnull t.qh -= n;
1245 cfabc3ed 2003-11-23 devnull else if(q0 < t.qh)
1246 cfabc3ed 2003-11-23 devnull t.qh = q0;
1247 cfabc3ed 2003-11-23 devnull if(q1 < t.org)
1248 cfabc3ed 2003-11-23 devnull t.org -= n;
1249 cfabc3ed 2003-11-23 devnull else if(q0 < t.org+t.f->nchars){
1250 cfabc3ed 2003-11-23 devnull assert(q0 >= t.org);
1251 cfabc3ed 2003-11-23 devnull p0 = q0 - t.org;
1252 cfabc3ed 2003-11-23 devnull p1 = q1 - t.org;
1253 cfabc3ed 2003-11-23 devnull if(p1 > t.f->nchars)
1254 cfabc3ed 2003-11-23 devnull p1 = t.f->nchars;
1255 cfabc3ed 2003-11-23 devnull frdelete(t.f, p0, p1);
1256 cfabc3ed 2003-11-23 devnull fill();
1257 cfabc3ed 2003-11-23 devnull }
1258 cfabc3ed 2003-11-23 devnull updatesel();
1259 cfabc3ed 2003-11-23 devnull }
1260 cfabc3ed 2003-11-23 devnull
1261 cfabc3ed 2003-11-23 devnull void
1262 cfabc3ed 2003-11-23 devnull snarfupdate(void)
1263 cfabc3ed 2003-11-23 devnull {
1264 cfabc3ed 2003-11-23 devnull char *pp;
1265 cfabc3ed 2003-11-23 devnull int n, i;
1266 cfabc3ed 2003-11-23 devnull Rune *p;
1267 cfabc3ed 2003-11-23 devnull
1268 cfabc3ed 2003-11-23 devnull pp = getsnarf();
1269 d3acba95 2003-12-04 devnull if(pp == nil)
1270 d3acba95 2003-12-04 devnull return;
1271 cfabc3ed 2003-11-23 devnull n = strlen(pp);
1272 cfabc3ed 2003-11-23 devnull if(n <= 0) {
1273 cfabc3ed 2003-11-23 devnull /*t.nsnarf = 0;*/
1274 cfabc3ed 2003-11-23 devnull return;
1275 cfabc3ed 2003-11-23 devnull }
1276 cfabc3ed 2003-11-23 devnull t.snarf = runerealloc(t.snarf, n);
1277 cfabc3ed 2003-11-23 devnull for(i=0,p=t.snarf; i<n; p++)
1278 cfabc3ed 2003-11-23 devnull i += chartorune(p, pp+i);
1279 cfabc3ed 2003-11-23 devnull t.nsnarf = p-t.snarf;
1280 cfabc3ed 2003-11-23 devnull
1281 cfabc3ed 2003-11-23 devnull }
1282 cfabc3ed 2003-11-23 devnull
1283 dff7e273 2003-12-04 devnull char sbuf[SnarfSize];
1284 cfabc3ed 2003-11-23 devnull void
1285 cfabc3ed 2003-11-23 devnull snarf(void)
1286 cfabc3ed 2003-11-23 devnull {
1287 dff7e273 2003-12-04 devnull char *p;
1288 cfabc3ed 2003-11-23 devnull int i, n;
1289 cfabc3ed 2003-11-23 devnull Rune *rp;
1290 cfabc3ed 2003-11-23 devnull
1291 cfabc3ed 2003-11-23 devnull if(t.q1 == t.q0)
1292 cfabc3ed 2003-11-23 devnull return;
1293 cfabc3ed 2003-11-23 devnull n = t.q1-t.q0;
1294 dff7e273 2003-12-04 devnull t.snarf = runerealloc(t.snarf, n);
1295 dff7e273 2003-12-04 devnull for(i=0,p=sbuf,rp=t.snarf; i<n && p < sbuf+SnarfSize-UTFmax; i++){
1296 cfabc3ed 2003-11-23 devnull *rp++ = *(t.r+t.q0+i);
1297 cfabc3ed 2003-11-23 devnull p += runetochar(p, t.r+t.q0+i);
1298 cfabc3ed 2003-11-23 devnull }
1299 cfabc3ed 2003-11-23 devnull t.nsnarf = rp-t.snarf;
1300 cfabc3ed 2003-11-23 devnull *p = '\0';
1301 dff7e273 2003-12-04 devnull putsnarf(sbuf);
1302 cfabc3ed 2003-11-23 devnull }
1303 cfabc3ed 2003-11-23 devnull
1304 8ad51794 2004-03-25 devnull uint
1305 8ad51794 2004-03-25 devnull min(uint x, uint y)
1306 8ad51794 2004-03-25 devnull {
1307 8ad51794 2004-03-25 devnull if(x < y)
1308 8ad51794 2004-03-25 devnull return x;
1309 8ad51794 2004-03-25 devnull return y;
1310 8ad51794 2004-03-25 devnull }
1311 8ad51794 2004-03-25 devnull
1312 8ad51794 2004-03-25 devnull uint
1313 8ad51794 2004-03-25 devnull max(uint x, uint y)
1314 8ad51794 2004-03-25 devnull {
1315 8ad51794 2004-03-25 devnull if(x > y)
1316 8ad51794 2004-03-25 devnull return x;
1317 8ad51794 2004-03-25 devnull return y;
1318 8ad51794 2004-03-25 devnull }
1319 8ad51794 2004-03-25 devnull
1320 8ad51794 2004-03-25 devnull uint
1321 8ad51794 2004-03-25 devnull insert(Rune *r, int n, uint q0, int hostwrite)
1322 8ad51794 2004-03-25 devnull {
1323 8ad51794 2004-03-25 devnull uint m;
1324 8ad51794 2004-03-25 devnull
1325 8ad51794 2004-03-25 devnull if(n == 0)
1326 8ad51794 2004-03-25 devnull return q0;
1327 8ad51794 2004-03-25 devnull if(t.nr+n>HiWater && q0>=t.org && q0>=t.qh){
1328 8ad51794 2004-03-25 devnull m = min(HiWater-LoWater, min(t.org, t.qh));
1329 8ad51794 2004-03-25 devnull t.org -= m;
1330 8ad51794 2004-03-25 devnull t.qh -= m;
1331 8ad51794 2004-03-25 devnull if(t.q0 > m)
1332 8ad51794 2004-03-25 devnull t.q0 -= m;
1333 8ad51794 2004-03-25 devnull else
1334 8ad51794 2004-03-25 devnull t.q0 = 0;
1335 8ad51794 2004-03-25 devnull if(t.q1 > m)
1336 8ad51794 2004-03-25 devnull t.q1 -= m;
1337 8ad51794 2004-03-25 devnull else
1338 8ad51794 2004-03-25 devnull t.q1 = 0;
1339 8ad51794 2004-03-25 devnull t.nr -= m;
1340 8ad51794 2004-03-25 devnull runemove(t.r, t.r+m, t.nr);
1341 8ad51794 2004-03-25 devnull q0 -= m;
1342 8ad51794 2004-03-25 devnull }
1343 8ad51794 2004-03-25 devnull if(t.nr+n > t.maxr){
1344 8ad51794 2004-03-25 devnull /*
1345 8ad51794 2004-03-25 devnull * Minimize realloc breakage:
1346 8ad51794 2004-03-25 devnull * Allocate at least MinWater
1347 8ad51794 2004-03-25 devnull * Double allocation size each time
1348 8ad51794 2004-03-25 devnull * But don't go much above HiWater
1349 8ad51794 2004-03-25 devnull */
1350 8ad51794 2004-03-25 devnull m = max(min(2*(t.nr+n), HiWater), t.nr+n)+MinWater;
1351 8ad51794 2004-03-25 devnull if(m > HiWater)
1352 8ad51794 2004-03-25 devnull m = max(HiWater+MinWater, t.nr+n);
1353 8ad51794 2004-03-25 devnull if(m > t.maxr){
1354 8ad51794 2004-03-25 devnull t.r = runerealloc(t.r, m);
1355 8ad51794 2004-03-25 devnull t.maxr = m;
1356 8ad51794 2004-03-25 devnull }
1357 8ad51794 2004-03-25 devnull }
1358 8ad51794 2004-03-25 devnull runemove(t.r+q0+n, t.r+q0, t.nr-q0);
1359 8ad51794 2004-03-25 devnull runemove(t.r+q0, r, n);
1360 8ad51794 2004-03-25 devnull t.nr += n;
1361 8ad51794 2004-03-25 devnull /* if output touches, advance selection, not qh; works best for keyboard and output */
1362 8ad51794 2004-03-25 devnull if(q0 <= t.q1)
1363 8ad51794 2004-03-25 devnull t.q1 += n;
1364 8ad51794 2004-03-25 devnull if(q0 <= t.q0)
1365 8ad51794 2004-03-25 devnull t.q0 += n;
1366 8ad51794 2004-03-25 devnull if(q0 < t.qh || (q0==t.qh && hostwrite))
1367 8ad51794 2004-03-25 devnull t.qh += n;
1368 8ad51794 2004-03-25 devnull else
1369 8ad51794 2004-03-25 devnull consread();
1370 8ad51794 2004-03-25 devnull if(q0 < t.org)
1371 8ad51794 2004-03-25 devnull t.org += n;
1372 8ad51794 2004-03-25 devnull else if(q0 <= t.org+t.f->nchars)
1373 8ad51794 2004-03-25 devnull frinsert(t.f, r, r+n, q0-t.org);
1374 8ad51794 2004-03-25 devnull return q0;
1375 8ad51794 2004-03-25 devnull }
1376 8ad51794 2004-03-25 devnull
1377 cfabc3ed 2003-11-23 devnull void
1378 cfabc3ed 2003-11-23 devnull paste(Rune *r, int n, int advance)
1379 cfabc3ed 2003-11-23 devnull {
1380 dff7e273 2003-12-04 devnull Rune *rbuf;
1381 cfabc3ed 2003-11-23 devnull
1382 6cc5b304 2005-07-14 devnull if(!holdon && rawon() && t.q0==t.nr){
1383 cfabc3ed 2003-11-23 devnull addraw(r, n);
1384 fa467fbe 2005-02-08 devnull consread();
1385 cfabc3ed 2003-11-23 devnull return;
1386 cfabc3ed 2003-11-23 devnull }
1387 cfabc3ed 2003-11-23 devnull
1388 cfabc3ed 2003-11-23 devnull cut();
1389 cfabc3ed 2003-11-23 devnull if(n == 0)
1390 cfabc3ed 2003-11-23 devnull return;
1391 8ad51794 2004-03-25 devnull
1392 ba9ffa53 2004-03-21 devnull /*
1393 ba9ffa53 2004-03-21 devnull * if this is a button2 execute then we might have been passed
1394 ba9ffa53 2004-03-21 devnull * runes inside the buffer. must save them before realloc.
1395 ba9ffa53 2004-03-21 devnull */
1396 ba9ffa53 2004-03-21 devnull rbuf = nil;
1397 ba9ffa53 2004-03-21 devnull if(t.r <= r && r < t.r+n){
1398 ba9ffa53 2004-03-21 devnull rbuf = runemalloc(n);
1399 ba9ffa53 2004-03-21 devnull runemove(rbuf, r, n);
1400 ba9ffa53 2004-03-21 devnull r = rbuf;
1401 dff7e273 2003-12-04 devnull }
1402 dff7e273 2003-12-04 devnull
1403 8ad51794 2004-03-25 devnull insert(r, n, t.q0, 0);
1404 cfabc3ed 2003-11-23 devnull updatesel();
1405 dff7e273 2003-12-04 devnull free(rbuf);
1406 cfabc3ed 2003-11-23 devnull }
1407 cfabc3ed 2003-11-23 devnull
1408 cfabc3ed 2003-11-23 devnull void
1409 cfabc3ed 2003-11-23 devnull fill(void)
1410 cfabc3ed 2003-11-23 devnull {
1411 cfabc3ed 2003-11-23 devnull if (t.f->nlines >= t.f->maxlines)
1412 cfabc3ed 2003-11-23 devnull return;
1413 cfabc3ed 2003-11-23 devnull frinsert(t.f, t.r + t.org + t.f->nchars, t.r + t.nr, t.f->nchars);
1414 cfabc3ed 2003-11-23 devnull }
1415 cfabc3ed 2003-11-23 devnull
1416 cfabc3ed 2003-11-23 devnull void
1417 cfabc3ed 2003-11-23 devnull updatesel(void)
1418 cfabc3ed 2003-11-23 devnull {
1419 cfabc3ed 2003-11-23 devnull Frame *f;
1420 cfabc3ed 2003-11-23 devnull uint n;
1421 cfabc3ed 2003-11-23 devnull
1422 cfabc3ed 2003-11-23 devnull f = t.f;
1423 cfabc3ed 2003-11-23 devnull if(t.org+f->p0 == t.q0 && t.org+f->p1 == t.q1)
1424 cfabc3ed 2003-11-23 devnull return;
1425 cfabc3ed 2003-11-23 devnull
1426 cfabc3ed 2003-11-23 devnull n = t.f->nchars;
1427 cfabc3ed 2003-11-23 devnull
1428 cfabc3ed 2003-11-23 devnull frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 0);
1429 cfabc3ed 2003-11-23 devnull if (t.q0 >= t.org)
1430 cfabc3ed 2003-11-23 devnull f->p0 = t.q0-t.org;
1431 cfabc3ed 2003-11-23 devnull else
1432 cfabc3ed 2003-11-23 devnull f->p0 = 0;
1433 cfabc3ed 2003-11-23 devnull if(f->p0 > n)
1434 cfabc3ed 2003-11-23 devnull f->p0 = n;
1435 cfabc3ed 2003-11-23 devnull if (t.q1 >= t.org)
1436 cfabc3ed 2003-11-23 devnull f->p1 = t.q1-t.org;
1437 cfabc3ed 2003-11-23 devnull else
1438 cfabc3ed 2003-11-23 devnull f->p1 = 0;
1439 cfabc3ed 2003-11-23 devnull if(f->p1 > n)
1440 cfabc3ed 2003-11-23 devnull f->p1 = n;
1441 cfabc3ed 2003-11-23 devnull frdrawsel(f, frptofchar(f, f->p0), f->p0, f->p1, 1);
1442 cfabc3ed 2003-11-23 devnull
1443 cfabc3ed 2003-11-23 devnull /*
1444 cfabc3ed 2003-11-23 devnull if(t.qh<=t.org+t.f.nchars && t.cwqueue != 0)
1445 cfabc3ed 2003-11-23 devnull t.cwqueue->wakeup <-= 0;
1446 cfabc3ed 2003-11-23 devnull */
1447 cfabc3ed 2003-11-23 devnull
1448 cfabc3ed 2003-11-23 devnull tcheck();
1449 cfabc3ed 2003-11-23 devnull }
1450 cfabc3ed 2003-11-23 devnull
1451 cfabc3ed 2003-11-23 devnull void
1452 cfabc3ed 2003-11-23 devnull show(uint q0)
1453 cfabc3ed 2003-11-23 devnull {
1454 cfabc3ed 2003-11-23 devnull int nl;
1455 cfabc3ed 2003-11-23 devnull uint q, oq;
1456 cfabc3ed 2003-11-23 devnull
1457 cfabc3ed 2003-11-23 devnull if(cansee(q0))
1458 cfabc3ed 2003-11-23 devnull return;
1459 cfabc3ed 2003-11-23 devnull
1460 cfabc3ed 2003-11-23 devnull if (q0<t.org)
1461 cfabc3ed 2003-11-23 devnull nl = t.f->maxlines/5;
1462 cfabc3ed 2003-11-23 devnull else
1463 cfabc3ed 2003-11-23 devnull nl = 4*t.f->maxlines/5;
1464 cfabc3ed 2003-11-23 devnull q = backnl(q0, nl);
1465 cfabc3ed 2003-11-23 devnull /* avoid going in the wrong direction */
1466 cfabc3ed 2003-11-23 devnull if (q0>t.org && q<t.org)
1467 cfabc3ed 2003-11-23 devnull q = t.org;
1468 cfabc3ed 2003-11-23 devnull setorigin(q, 0);
1469 cfabc3ed 2003-11-23 devnull /* keep trying until q0 is on the screen */
1470 cfabc3ed 2003-11-23 devnull while(!cansee(q0)) {
1471 cfabc3ed 2003-11-23 devnull assert(q0 >= t.org);
1472 cfabc3ed 2003-11-23 devnull oq = q;
1473 cfabc3ed 2003-11-23 devnull q = line2q(t.f->maxlines-nl);
1474 cfabc3ed 2003-11-23 devnull assert(q > oq);
1475 cfabc3ed 2003-11-23 devnull setorigin(q, 1);
1476 cfabc3ed 2003-11-23 devnull }
1477 cfabc3ed 2003-11-23 devnull }
1478 cfabc3ed 2003-11-23 devnull
1479 cfabc3ed 2003-11-23 devnull int
1480 cfabc3ed 2003-11-23 devnull cansee(uint q0)
1481 cfabc3ed 2003-11-23 devnull {
1482 cfabc3ed 2003-11-23 devnull uint qe;
1483 cfabc3ed 2003-11-23 devnull
1484 cfabc3ed 2003-11-23 devnull qe = t.org+t.f->nchars;
1485 cfabc3ed 2003-11-23 devnull
1486 cfabc3ed 2003-11-23 devnull if(q0>=t.org && q0 < qe)
1487 cfabc3ed 2003-11-23 devnull return 1;
1488 cfabc3ed 2003-11-23 devnull if (q0 != qe)
1489 cfabc3ed 2003-11-23 devnull return 0;
1490 cfabc3ed 2003-11-23 devnull if (t.f->nlines < t.f->maxlines)
1491 cfabc3ed 2003-11-23 devnull return 1;
1492 cfabc3ed 2003-11-23 devnull if (q0 > 0 && t.r[t.nr-1] == '\n')
1493 cfabc3ed 2003-11-23 devnull return 0;
1494 cfabc3ed 2003-11-23 devnull return 1;
1495 cfabc3ed 2003-11-23 devnull }
1496 cfabc3ed 2003-11-23 devnull
1497 cfabc3ed 2003-11-23 devnull
1498 cfabc3ed 2003-11-23 devnull void
1499 cfabc3ed 2003-11-23 devnull setorigin(uint org, int exact)
1500 cfabc3ed 2003-11-23 devnull {
1501 cfabc3ed 2003-11-23 devnull int i, a;
1502 cfabc3ed 2003-11-23 devnull uint n;
1503 cfabc3ed 2003-11-23 devnull
1504 cfabc3ed 2003-11-23 devnull if(org>0 && !exact){
1505 cfabc3ed 2003-11-23 devnull /* try and start after a newline */
1506 cfabc3ed 2003-11-23 devnull /* don't try harder than 256 chars */
1507 cfabc3ed 2003-11-23 devnull for(i=0; i<256 && org<t.nr; i++){
1508 cfabc3ed 2003-11-23 devnull if(t.r[org-1] == '\n')
1509 cfabc3ed 2003-11-23 devnull break;
1510 cfabc3ed 2003-11-23 devnull org++;
1511 cfabc3ed 2003-11-23 devnull }
1512 cfabc3ed 2003-11-23 devnull }
1513 cfabc3ed 2003-11-23 devnull a = org-t.org;
1514 cfabc3ed 2003-11-23 devnull
1515 cfabc3ed 2003-11-23 devnull if(a>=0 && a<t.f->nchars)
1516 cfabc3ed 2003-11-23 devnull frdelete(t.f, 0, a);
1517 cfabc3ed 2003-11-23 devnull else if(a<0 && -a<100*t.f->maxlines){
1518 cfabc3ed 2003-11-23 devnull n = t.org - org;
1519 cfabc3ed 2003-11-23 devnull frinsert(t.f, t.r+org, t.r+org+n, 0);
1520 cfabc3ed 2003-11-23 devnull }else
1521 cfabc3ed 2003-11-23 devnull frdelete(t.f, 0, t.f->nchars);
1522 cfabc3ed 2003-11-23 devnull t.org = org;
1523 cfabc3ed 2003-11-23 devnull fill();
1524 cfabc3ed 2003-11-23 devnull updatesel();
1525 cfabc3ed 2003-11-23 devnull }
1526 cfabc3ed 2003-11-23 devnull
1527 cfabc3ed 2003-11-23 devnull
1528 cfabc3ed 2003-11-23 devnull uint
1529 cfabc3ed 2003-11-23 devnull line2q(uint n)
1530 cfabc3ed 2003-11-23 devnull {
1531 cfabc3ed 2003-11-23 devnull Frame *f;
1532 cfabc3ed 2003-11-23 devnull
1533 cfabc3ed 2003-11-23 devnull f = t.f;
1534 cfabc3ed 2003-11-23 devnull return frcharofpt(f, Pt(f->r.min.x, f->r.min.y + n*font->height))+t.org;
1535 cfabc3ed 2003-11-23 devnull }
1536 cfabc3ed 2003-11-23 devnull
1537 cfabc3ed 2003-11-23 devnull uint
1538 cfabc3ed 2003-11-23 devnull backnl(uint p, uint n)
1539 cfabc3ed 2003-11-23 devnull {
1540 cfabc3ed 2003-11-23 devnull int i, j;
1541 cfabc3ed 2003-11-23 devnull
1542 cfabc3ed 2003-11-23 devnull for (i = n;; i--) {
1543 cfabc3ed 2003-11-23 devnull /* at 256 chars, call it a line anyway */
1544 cfabc3ed 2003-11-23 devnull for(j=256; --j>0 && p>0; p--)
1545 cfabc3ed 2003-11-23 devnull if(t.r[p-1]=='\n')
1546 cfabc3ed 2003-11-23 devnull break;
1547 cfabc3ed 2003-11-23 devnull if (p == 0 || i == 0)
1548 cfabc3ed 2003-11-23 devnull return p;
1549 cfabc3ed 2003-11-23 devnull p--;
1550 cfabc3ed 2003-11-23 devnull }
1551 cfabc3ed 2003-11-23 devnull }
1552 cfabc3ed 2003-11-23 devnull
1553 cfabc3ed 2003-11-23 devnull void
1554 cfabc3ed 2003-11-23 devnull addraw(Rune *r, int nr)
1555 cfabc3ed 2003-11-23 devnull {
1556 cfabc3ed 2003-11-23 devnull t.raw = runerealloc(t.raw, t.nraw+nr);
1557 cfabc3ed 2003-11-23 devnull runemove(t.raw+t.nraw, r, nr);
1558 cfabc3ed 2003-11-23 devnull t.nraw += nr;
1559 cfabc3ed 2003-11-23 devnull /*
1560 cfabc3ed 2003-11-23 devnull if(t.crqueue != nil)
1561 cfabc3ed 2003-11-23 devnull t.crqueue->wakeup <-= 0;
1562 cfabc3ed 2003-11-23 devnull */
1563 cfabc3ed 2003-11-23 devnull }
1564 cfabc3ed 2003-11-23 devnull
1565 cfabc3ed 2003-11-23 devnull
1566 cfabc3ed 2003-11-23 devnull Rune left1[] = { '{', '[', '(', '<', 0xab, 0 };
1567 cfabc3ed 2003-11-23 devnull Rune right1[] = { '}', ']', ')', '>', 0xbb, 0 };
1568 cfabc3ed 2003-11-23 devnull Rune left2[] = { '\n', 0 };
1569 cfabc3ed 2003-11-23 devnull Rune left3[] = { '\'', '"', '`', 0 };
1570 cfabc3ed 2003-11-23 devnull
1571 cfabc3ed 2003-11-23 devnull Rune *left[] = {
1572 cfabc3ed 2003-11-23 devnull left1,
1573 cfabc3ed 2003-11-23 devnull left2,
1574 cfabc3ed 2003-11-23 devnull left3,
1575 cfabc3ed 2003-11-23 devnull 0
1576 cfabc3ed 2003-11-23 devnull };
1577 cfabc3ed 2003-11-23 devnull
1578 cfabc3ed 2003-11-23 devnull Rune *right[] = {
1579 cfabc3ed 2003-11-23 devnull right1,
1580 cfabc3ed 2003-11-23 devnull left2,
1581 cfabc3ed 2003-11-23 devnull left3,
1582 cfabc3ed 2003-11-23 devnull 0
1583 cfabc3ed 2003-11-23 devnull };
1584 cfabc3ed 2003-11-23 devnull
1585 cfabc3ed 2003-11-23 devnull void
1586 cfabc3ed 2003-11-23 devnull doubleclick(uint *q0, uint *q1)
1587 cfabc3ed 2003-11-23 devnull {
1588 cfabc3ed 2003-11-23 devnull int c, i;
1589 cfabc3ed 2003-11-23 devnull Rune *r, *l, *p;
1590 cfabc3ed 2003-11-23 devnull uint q;
1591 cfabc3ed 2003-11-23 devnull
1592 cfabc3ed 2003-11-23 devnull for(i=0; left[i]!=0; i++){
1593 cfabc3ed 2003-11-23 devnull q = *q0;
1594 cfabc3ed 2003-11-23 devnull l = left[i];
1595 cfabc3ed 2003-11-23 devnull r = right[i];
1596 cfabc3ed 2003-11-23 devnull /* try matching character to left, looking right */
1597 cfabc3ed 2003-11-23 devnull if(q == 0)
1598 cfabc3ed 2003-11-23 devnull c = '\n';
1599 cfabc3ed 2003-11-23 devnull else
1600 cfabc3ed 2003-11-23 devnull c = t.r[q-1];
1601 cfabc3ed 2003-11-23 devnull p = strrune(l, c);
1602 cfabc3ed 2003-11-23 devnull if(p != 0){
1603 cfabc3ed 2003-11-23 devnull if(clickmatch(c, r[p-l], 1, &q))
1604 cfabc3ed 2003-11-23 devnull *q1 = q-(c!='\n');
1605 cfabc3ed 2003-11-23 devnull return;
1606 cfabc3ed 2003-11-23 devnull }
1607 cfabc3ed 2003-11-23 devnull /* try matching character to right, looking left */
1608 cfabc3ed 2003-11-23 devnull if(q == t.nr)
1609 cfabc3ed 2003-11-23 devnull c = '\n';
1610 cfabc3ed 2003-11-23 devnull else
1611 cfabc3ed 2003-11-23 devnull c = t.r[q];
1612 cfabc3ed 2003-11-23 devnull p = strrune(r, c);
1613 cfabc3ed 2003-11-23 devnull if(p != 0){
1614 cfabc3ed 2003-11-23 devnull if(clickmatch(c, l[p-r], -1, &q)){
1615 cfabc3ed 2003-11-23 devnull *q1 = *q0+(*q0<t.nr && c=='\n');
1616 cfabc3ed 2003-11-23 devnull *q0 = q;
1617 cfabc3ed 2003-11-23 devnull if(c!='\n' || q!=0 || t.r[0]=='\n')
1618 cfabc3ed 2003-11-23 devnull (*q0)++;
1619 cfabc3ed 2003-11-23 devnull }
1620 cfabc3ed 2003-11-23 devnull return;
1621 cfabc3ed 2003-11-23 devnull }
1622 cfabc3ed 2003-11-23 devnull }
1623 cfabc3ed 2003-11-23 devnull /* try filling out word to right */
1624 4999080d 2005-02-11 devnull while(*q1<t.nr && isexpand(t.r[*q1]))
1625 cfabc3ed 2003-11-23 devnull (*q1)++;
1626 cfabc3ed 2003-11-23 devnull /* try filling out word to left */
1627 4999080d 2005-02-11 devnull while(*q0>0 && isexpand(t.r[*q0-1]))
1628 cfabc3ed 2003-11-23 devnull (*q0)--;
1629 cfabc3ed 2003-11-23 devnull }
1630 cfabc3ed 2003-11-23 devnull
1631 cfabc3ed 2003-11-23 devnull int
1632 cfabc3ed 2003-11-23 devnull clickmatch(int cl, int cr, int dir, uint *q)
1633 cfabc3ed 2003-11-23 devnull {
1634 cfabc3ed 2003-11-23 devnull Rune c;
1635 cfabc3ed 2003-11-23 devnull int nest;
1636 cfabc3ed 2003-11-23 devnull
1637 cfabc3ed 2003-11-23 devnull nest = 1;
1638 cfabc3ed 2003-11-23 devnull for(;;){
1639 cfabc3ed 2003-11-23 devnull if(dir > 0){
1640 cfabc3ed 2003-11-23 devnull if(*q == t.nr)
1641 cfabc3ed 2003-11-23 devnull break;
1642 cfabc3ed 2003-11-23 devnull c = t.r[*q];
1643 cfabc3ed 2003-11-23 devnull (*q)++;
1644 cfabc3ed 2003-11-23 devnull }else{
1645 cfabc3ed 2003-11-23 devnull if(*q == 0)
1646 cfabc3ed 2003-11-23 devnull break;
1647 cfabc3ed 2003-11-23 devnull (*q)--;
1648 cfabc3ed 2003-11-23 devnull c = t.r[*q];
1649 cfabc3ed 2003-11-23 devnull }
1650 cfabc3ed 2003-11-23 devnull if(c == cr){
1651 cfabc3ed 2003-11-23 devnull if(--nest==0)
1652 cfabc3ed 2003-11-23 devnull return 1;
1653 cfabc3ed 2003-11-23 devnull }else if(c == cl)
1654 cfabc3ed 2003-11-23 devnull nest++;
1655 cfabc3ed 2003-11-23 devnull }
1656 cfabc3ed 2003-11-23 devnull return cl=='\n' && nest==1;
1657 cfabc3ed 2003-11-23 devnull }
1658 cfabc3ed 2003-11-23 devnull
1659 cfabc3ed 2003-11-23 devnull void
1660 cfabc3ed 2003-11-23 devnull tcheck(void)
1661 cfabc3ed 2003-11-23 devnull {
1662 cfabc3ed 2003-11-23 devnull Frame *f;
1663 cfabc3ed 2003-11-23 devnull
1664 cfabc3ed 2003-11-23 devnull f = t.f;
1665 cfabc3ed 2003-11-23 devnull
1666 cfabc3ed 2003-11-23 devnull assert(t.q0 <= t.q1 && t.q1 <= t.nr);
1667 cfabc3ed 2003-11-23 devnull assert(t.org <= t.nr && t.qh <= t.nr);
1668 cfabc3ed 2003-11-23 devnull assert(f->p0 <= f->p1 && f->p1 <= f->nchars);
1669 cfabc3ed 2003-11-23 devnull assert(t.org + f->nchars <= t.nr);
1670 cfabc3ed 2003-11-23 devnull assert(t.org+f->nchars==t.nr || (f->nlines >= f->maxlines));
1671 cfabc3ed 2003-11-23 devnull }
1672 cfabc3ed 2003-11-23 devnull
1673 cfabc3ed 2003-11-23 devnull Rune*
1674 cfabc3ed 2003-11-23 devnull strrune(Rune *s, Rune c)
1675 cfabc3ed 2003-11-23 devnull {
1676 cfabc3ed 2003-11-23 devnull Rune c1;
1677 cfabc3ed 2003-11-23 devnull
1678 cfabc3ed 2003-11-23 devnull if(c == 0) {
1679 cfabc3ed 2003-11-23 devnull while(*s++)
1680 cfabc3ed 2003-11-23 devnull ;
1681 cfabc3ed 2003-11-23 devnull return s-1;
1682 cfabc3ed 2003-11-23 devnull }
1683 cfabc3ed 2003-11-23 devnull
1684 cfabc3ed 2003-11-23 devnull while(c1 = *s++)
1685 cfabc3ed 2003-11-23 devnull if(c1 == c)
1686 cfabc3ed 2003-11-23 devnull return s-1;
1687 cfabc3ed 2003-11-23 devnull return 0;
1688 cfabc3ed 2003-11-23 devnull }
1689 cfabc3ed 2003-11-23 devnull
1690 cfabc3ed 2003-11-23 devnull void
1691 cfabc3ed 2003-11-23 devnull scrdraw(void)
1692 cfabc3ed 2003-11-23 devnull {
1693 cfabc3ed 2003-11-23 devnull Rectangle r, r1, r2;
1694 cfabc3ed 2003-11-23 devnull static Image *scrx;
1695 4f30f3b4 2004-03-30 devnull
1696 cfabc3ed 2003-11-23 devnull r = scrollr;
1697 cfabc3ed 2003-11-23 devnull r.min.x += 1; /* border between margin and bar */
1698 cfabc3ed 2003-11-23 devnull r1 = r;
1699 cfabc3ed 2003-11-23 devnull if(scrx==0 || scrx->r.max.y < r.max.y){
1700 cfabc3ed 2003-11-23 devnull if(scrx)
1701 cfabc3ed 2003-11-23 devnull freeimage(scrx);
1702 cfabc3ed 2003-11-23 devnull scrx = allocimage(display, Rect(0, 0, 32, r.max.y), screen->chan, 1, DPaleyellow);
1703 cfabc3ed 2003-11-23 devnull if(scrx == 0)
1704 8ad51794 2004-03-25 devnull sysfatal("scroll balloc");
1705 cfabc3ed 2003-11-23 devnull }
1706 cfabc3ed 2003-11-23 devnull r1.min.x = 0;
1707 cfabc3ed 2003-11-23 devnull r1.max.x = Dx(r);
1708 cfabc3ed 2003-11-23 devnull r2 = scrpos(r1, t.org, t.org+t.f->nchars, t.nr);
1709 cfabc3ed 2003-11-23 devnull if(!eqrect(r2, lastsr)){
1710 cfabc3ed 2003-11-23 devnull lastsr = r2;
1711 cfabc3ed 2003-11-23 devnull draw(scrx, r1, cols[BORD], nil, ZP);
1712 cfabc3ed 2003-11-23 devnull draw(scrx, r2, cols[BACK], nil, r2.min);
1713 cfabc3ed 2003-11-23 devnull // r2 = r1;
1714 cfabc3ed 2003-11-23 devnull // r2.min.x = r2.max.x-1;
1715 cfabc3ed 2003-11-23 devnull // draw(scrx, r2, cols[BORD], nil, ZP);
1716 cfabc3ed 2003-11-23 devnull draw(screen, r, scrx, nil, r1.min);
1717 cfabc3ed 2003-11-23 devnull }
1718 cfabc3ed 2003-11-23 devnull }
1719 cfabc3ed 2003-11-23 devnull
1720 cfabc3ed 2003-11-23 devnull Rectangle
1721 cfabc3ed 2003-11-23 devnull scrpos(Rectangle r, ulong p0, ulong p1, ulong tot)
1722 cfabc3ed 2003-11-23 devnull {
1723 cfabc3ed 2003-11-23 devnull long h;
1724 cfabc3ed 2003-11-23 devnull Rectangle q;
1725 cfabc3ed 2003-11-23 devnull
1726 cfabc3ed 2003-11-23 devnull q = insetrect(r, 1);
1727 cfabc3ed 2003-11-23 devnull h = q.max.y-q.min.y;
1728 cfabc3ed 2003-11-23 devnull if(tot == 0)
1729 cfabc3ed 2003-11-23 devnull return q;
1730 cfabc3ed 2003-11-23 devnull if(tot > 1024L*1024L)
1731 cfabc3ed 2003-11-23 devnull tot >>= 10, p0 >>= 10, p1 >>= 10;
1732 cfabc3ed 2003-11-23 devnull if(p0 > 0)
1733 cfabc3ed 2003-11-23 devnull q.min.y += h*p0/tot;
1734 cfabc3ed 2003-11-23 devnull if(p1 < tot)
1735 cfabc3ed 2003-11-23 devnull q.max.y -= h*(tot-p1)/tot;
1736 cfabc3ed 2003-11-23 devnull if(q.max.y < q.min.y+2){
1737 cfabc3ed 2003-11-23 devnull if(q.min.y+2 <= r.max.y)
1738 cfabc3ed 2003-11-23 devnull q.max.y = q.min.y+2;
1739 cfabc3ed 2003-11-23 devnull else
1740 cfabc3ed 2003-11-23 devnull q.min.y = q.max.y-2;
1741 cfabc3ed 2003-11-23 devnull }
1742 cfabc3ed 2003-11-23 devnull return q;
1743 cfabc3ed 2003-11-23 devnull }
1744 cfabc3ed 2003-11-23 devnull
1745 cfabc3ed 2003-11-23 devnull void
1746 cfabc3ed 2003-11-23 devnull scroll(int but)
1747 cfabc3ed 2003-11-23 devnull {
1748 cfabc3ed 2003-11-23 devnull uint p0, oldp0;
1749 cfabc3ed 2003-11-23 devnull Rectangle s;
1750 cfabc3ed 2003-11-23 devnull int x, y, my, h, first, exact;
1751 cfabc3ed 2003-11-23 devnull
1752 cfabc3ed 2003-11-23 devnull s = insetrect(scrollr, 1);
1753 cfabc3ed 2003-11-23 devnull h = s.max.y-s.min.y;
1754 cfabc3ed 2003-11-23 devnull x = (s.min.x+s.max.x)/2;
1755 cfabc3ed 2003-11-23 devnull oldp0 = ~0;
1756 cfabc3ed 2003-11-23 devnull first = 1;
1757 cfabc3ed 2003-11-23 devnull do{
1758 cfabc3ed 2003-11-23 devnull if(t.m.xy.x<s.min.x || s.max.x<=t.m.xy.x){
1759 cfabc3ed 2003-11-23 devnull readmouse(mc);
1760 cfabc3ed 2003-11-23 devnull t.m = mc->m;
1761 cfabc3ed 2003-11-23 devnull }else{
1762 cfabc3ed 2003-11-23 devnull my = t.m.xy.y;
1763 cfabc3ed 2003-11-23 devnull if(my < s.min.y)
1764 cfabc3ed 2003-11-23 devnull my = s.min.y;
1765 cfabc3ed 2003-11-23 devnull if(my >= s.max.y)
1766 cfabc3ed 2003-11-23 devnull my = s.max.y;
1767 cfabc3ed 2003-11-23 devnull // if(!eqpt(t.m.xy, Pt(x, my)))
1768 cfabc3ed 2003-11-23 devnull // cursorset(Pt(x, my));
1769 cfabc3ed 2003-11-23 devnull exact = 1;
1770 cfabc3ed 2003-11-23 devnull if(but == 2){
1771 cfabc3ed 2003-11-23 devnull y = my;
1772 cfabc3ed 2003-11-23 devnull if(y > s.max.y-2)
1773 cfabc3ed 2003-11-23 devnull y = s.max.y-2;
1774 cfabc3ed 2003-11-23 devnull if(t.nr > 1024*1024)
1775 cfabc3ed 2003-11-23 devnull p0 = ((t.nr>>10)*(y-s.min.y)/h)<<10;
1776 cfabc3ed 2003-11-23 devnull else
1777 cfabc3ed 2003-11-23 devnull p0 = t.nr*(y-s.min.y)/h;
1778 cfabc3ed 2003-11-23 devnull exact = 0;
1779 cfabc3ed 2003-11-23 devnull } else if(but == 1)
1780 cfabc3ed 2003-11-23 devnull p0 = backnl(t.org, (my-s.min.y)/font->height);
1781 cfabc3ed 2003-11-23 devnull else
1782 cfabc3ed 2003-11-23 devnull p0 = t.org+frcharofpt(t.f, Pt(s.max.x, my));
1783 cfabc3ed 2003-11-23 devnull
1784 cfabc3ed 2003-11-23 devnull if(oldp0 != p0)
1785 cfabc3ed 2003-11-23 devnull setorigin(p0, exact);
1786 cfabc3ed 2003-11-23 devnull oldp0 = p0;
1787 cfabc3ed 2003-11-23 devnull scrdraw();
1788 cfabc3ed 2003-11-23 devnull readmouse(mc);
1789 cfabc3ed 2003-11-23 devnull t.m = mc->m;
1790 cfabc3ed 2003-11-23 devnull }
1791 cfabc3ed 2003-11-23 devnull }while(t.m.buttons & (1<<(but-1)));
1792 cfabc3ed 2003-11-23 devnull }
1793 cfabc3ed 2003-11-23 devnull
1794 cfabc3ed 2003-11-23 devnull void
1795 cfabc3ed 2003-11-23 devnull plumbstart(void)
1796 cfabc3ed 2003-11-23 devnull {
1797 32f69c36 2003-12-11 devnull if((plumbfd = plumbopen("send", OWRITE)) < 0)
1798 304278e5 2004-03-21 devnull fprint(2, "9term: plumbopen: %r\n");
1799 cfabc3ed 2003-11-23 devnull }
1800 cfabc3ed 2003-11-23 devnull
1801 cfabc3ed 2003-11-23 devnull void
1802 cfabc3ed 2003-11-23 devnull plumb(uint q0, uint q1)
1803 cfabc3ed 2003-11-23 devnull {
1804 cfabc3ed 2003-11-23 devnull Plumbmsg *pm;
1805 cfabc3ed 2003-11-23 devnull char *p;
1806 cfabc3ed 2003-11-23 devnull int i, p0, n;
1807 cfabc3ed 2003-11-23 devnull char cbuf[100];
1808 cfabc3ed 2003-11-23 devnull
1809 cfabc3ed 2003-11-23 devnull pm = malloc(sizeof(Plumbmsg));
1810 cfabc3ed 2003-11-23 devnull pm->src = strdup("9term");
1811 cfabc3ed 2003-11-23 devnull pm->dst = 0;
1812 8ad51794 2004-03-25 devnull pm->wdir = strdup(wdir);
1813 cfabc3ed 2003-11-23 devnull pm->type = strdup("text");
1814 64044a07 2004-03-21 devnull pm->data = nil;
1815 cfabc3ed 2003-11-23 devnull if(q1 > q0)
1816 cfabc3ed 2003-11-23 devnull pm->attr = nil;
1817 cfabc3ed 2003-11-23 devnull else{
1818 cfabc3ed 2003-11-23 devnull p0 = q0;
1819 d3acba95 2003-12-04 devnull wordclick(&q0, &q1);
1820 cfabc3ed 2003-11-23 devnull sprint(cbuf, "click=%d", p0-q0);
1821 cfabc3ed 2003-11-23 devnull pm->attr = plumbunpackattr(cbuf);
1822 cfabc3ed 2003-11-23 devnull }
1823 cfabc3ed 2003-11-23 devnull if(q0==q1){
1824 cfabc3ed 2003-11-23 devnull plumbfree(pm);
1825 cfabc3ed 2003-11-23 devnull return;
1826 cfabc3ed 2003-11-23 devnull }
1827 cfabc3ed 2003-11-23 devnull pm->data = malloc(SnarfSize);
1828 cfabc3ed 2003-11-23 devnull n = q1 - q0;
1829 cfabc3ed 2003-11-23 devnull for(i=0,p=pm->data; i<n && p < pm->data + SnarfSize-UTFmax; i++)
1830 cfabc3ed 2003-11-23 devnull p += runetochar(p, t.r+q0+i);
1831 cfabc3ed 2003-11-23 devnull *p = '\0';
1832 cfabc3ed 2003-11-23 devnull pm->ndata = strlen(pm->data);
1833 acc021b8 2005-01-02 devnull if(plumbsend(plumbfd, pm) < 0){
1834 acc021b8 2005-01-02 devnull setcursor(mc, &query);
1835 acc021b8 2005-01-02 devnull sleep(500);
1836 acc021b8 2005-01-02 devnull if(holdon)
1837 acc021b8 2005-01-02 devnull setcursor(mc, &whitearrow);
1838 acc021b8 2005-01-02 devnull else
1839 acc021b8 2005-01-02 devnull setcursor(mc, nil);
1840 acc021b8 2005-01-02 devnull }
1841 cfabc3ed 2003-11-23 devnull plumbfree(pm);
1842 cfabc3ed 2003-11-23 devnull }
1843 cfabc3ed 2003-11-23 devnull
1844 cfabc3ed 2003-11-23 devnull /*
1845 cfabc3ed 2003-11-23 devnull * Process in-band messages about window title changes.
1846 cfabc3ed 2003-11-23 devnull * The messages are of the form:
1847 cfabc3ed 2003-11-23 devnull *
1848 cfabc3ed 2003-11-23 devnull * \033];xxx\007
1849 cfabc3ed 2003-11-23 devnull *
1850 cfabc3ed 2003-11-23 devnull * where xxx is the new directory. This format was chosen
1851 cfabc3ed 2003-11-23 devnull * because it changes the label on xterm windows.
1852 cfabc3ed 2003-11-23 devnull */
1853 cfabc3ed 2003-11-23 devnull int
1854 cfabc3ed 2003-11-23 devnull label(Rune *sr, int n)
1855 cfabc3ed 2003-11-23 devnull {
1856 cfabc3ed 2003-11-23 devnull Rune *sl, *el, *er, *r;
1857 efe12411 2005-01-30 devnull char *p;
1858 efe12411 2005-01-30 devnull
1859 cfabc3ed 2003-11-23 devnull er = sr+n;
1860 cfabc3ed 2003-11-23 devnull for(r=er-1; r>=sr; r--)
1861 cfabc3ed 2003-11-23 devnull if(*r == '\007')
1862 cfabc3ed 2003-11-23 devnull break;
1863 cfabc3ed 2003-11-23 devnull if(r < sr)
1864 cfabc3ed 2003-11-23 devnull return n;
1865 cfabc3ed 2003-11-23 devnull
1866 cfabc3ed 2003-11-23 devnull el = r+1;
1867 cfabc3ed 2003-11-23 devnull if(el-sr > sizeof wdir)
1868 cfabc3ed 2003-11-23 devnull sr = el - sizeof wdir;
1869 cfabc3ed 2003-11-23 devnull for(sl=el-3; sl>=sr; sl--)
1870 cfabc3ed 2003-11-23 devnull if(sl[0]=='\033' && sl[1]==']' && sl[2]==';')
1871 cfabc3ed 2003-11-23 devnull break;
1872 cfabc3ed 2003-11-23 devnull if(sl < sr)
1873 cfabc3ed 2003-11-23 devnull return n;
1874 cfabc3ed 2003-11-23 devnull
1875 cfabc3ed 2003-11-23 devnull snprint(wdir, sizeof wdir, "%.*S", (el-1)-(sl+3), sl+3);
1876 100d5668 2005-01-04 devnull drawsetlabel(wdir);
1877 cfabc3ed 2003-11-23 devnull
1878 efe12411 2005-01-30 devnull /* remove trailing /-sysname if present */
1879 efe12411 2005-01-30 devnull p = strrchr(wdir, '/');
1880 efe12411 2005-01-30 devnull if(p && *(p+1) == '-'){
1881 efe12411 2005-01-30 devnull if(p == wdir)
1882 efe12411 2005-01-30 devnull p++;
1883 efe12411 2005-01-30 devnull *p = 0;
1884 efe12411 2005-01-30 devnull }
1885 efe12411 2005-01-30 devnull
1886 cfabc3ed 2003-11-23 devnull runemove(sl, el, er-el);
1887 cfabc3ed 2003-11-23 devnull n -= (el-sl);
1888 cfabc3ed 2003-11-23 devnull return n;
1889 cfabc3ed 2003-11-23 devnull }
1890 cfabc3ed 2003-11-23 devnull
1891 f476c92f 2004-04-18 devnull int
1892 f476c92f 2004-04-18 devnull rawon(void)
1893 f476c92f 2004-04-18 devnull {
1894 f476c92f 2004-04-18 devnull return !cooked && !isecho(sfd);
1895 f476c92f 2004-04-18 devnull }
1896 f476c92f 2004-04-18 devnull
1897 42c3794c 2004-10-17 devnull /*
1898 42c3794c 2004-10-17 devnull * Clumsy hack to make " and "" work.
1899 42c3794c 2004-10-17 devnull * Then again, what's not a clumsy hack here in Unix land?
1900 42c3794c 2004-10-17 devnull */
1901 42c3794c 2004-10-17 devnull
1902 42c3794c 2004-10-17 devnull char adir[100];
1903 42c3794c 2004-10-17 devnull int afd;
1904 42c3794c 2004-10-17 devnull
1905 42c3794c 2004-10-17 devnull void
1906 c3e73c01 2004-10-17 devnull removethesocket(void)
1907 c3e73c01 2004-10-17 devnull {
1908 c3e73c01 2004-10-17 devnull if(thesocket[0])
1909 c3e73c01 2004-10-17 devnull if(remove(thesocket) < 0)
1910 c3e73c01 2004-10-17 devnull fprint(2, "remove %s: %r\n", thesocket);
1911 c3e73c01 2004-10-17 devnull }
1912 c3e73c01 2004-10-17 devnull
1913 c3e73c01 2004-10-17 devnull void
1914 42c3794c 2004-10-17 devnull servedevtext(void)
1915 42c3794c 2004-10-17 devnull {
1916 42c3794c 2004-10-17 devnull char buf[100];
1917 42c3794c 2004-10-17 devnull
1918 42c3794c 2004-10-17 devnull snprint(buf, sizeof buf, "unix!/tmp/9term-text.%d", getpid());
1919 42c3794c 2004-10-17 devnull
1920 42c3794c 2004-10-17 devnull if((afd = announce(buf, adir)) < 0){
1921 42c3794c 2004-10-17 devnull putenv("text9term", "");
1922 42c3794c 2004-10-17 devnull return;
1923 42c3794c 2004-10-17 devnull }
1924 42c3794c 2004-10-17 devnull
1925 42c3794c 2004-10-17 devnull putenv("text9term", buf);
1926 60535a5f 2004-12-26 devnull proccreate(listenproc, nil, STACK);
1927 c3e73c01 2004-10-17 devnull strcpy(thesocket, buf+5);
1928 c3e73c01 2004-10-17 devnull atexit(removethesocket);
1929 42c3794c 2004-10-17 devnull }
1930 42c3794c 2004-10-17 devnull
1931 42c3794c 2004-10-17 devnull void
1932 60535a5f 2004-12-26 devnull listenproc(void *arg)
1933 42c3794c 2004-10-17 devnull {
1934 42c3794c 2004-10-17 devnull int fd;
1935 42c3794c 2004-10-17 devnull char dir[100];
1936 42c3794c 2004-10-17 devnull
1937 42c3794c 2004-10-17 devnull USED(arg);
1938 42c3794c 2004-10-17 devnull for(;;){
1939 60535a5f 2004-12-26 devnull fd = listen(adir, dir);
1940 42c3794c 2004-10-17 devnull if(fd < 0){
1941 42c3794c 2004-10-17 devnull close(afd);
1942 42c3794c 2004-10-17 devnull return;
1943 42c3794c 2004-10-17 devnull }
1944 60535a5f 2004-12-26 devnull proccreate(textthread, (void*)fd, STACK);
1945 42c3794c 2004-10-17 devnull }
1946 42c3794c 2004-10-17 devnull }
1947 42c3794c 2004-10-17 devnull
1948 42c3794c 2004-10-17 devnull void
1949 42c3794c 2004-10-17 devnull textthread(void *arg)
1950 42c3794c 2004-10-17 devnull {
1951 42c3794c 2004-10-17 devnull int fd, i, x, n, end;
1952 42c3794c 2004-10-17 devnull Rune r;
1953 42c3794c 2004-10-17 devnull char buf[4096], *p, *ep;
1954 42c3794c 2004-10-17 devnull
1955 42c3794c 2004-10-17 devnull fd = (int)arg;
1956 42c3794c 2004-10-17 devnull p = buf;
1957 42c3794c 2004-10-17 devnull ep = buf+sizeof buf;
1958 42c3794c 2004-10-17 devnull end = t.org+t.nr; /* avoid possible output loop */
1959 42c3794c 2004-10-17 devnull for(i=t.org;; i++){
1960 42c3794c 2004-10-17 devnull if(i >= end || ep-p < UTFmax){
1961 42c3794c 2004-10-17 devnull for(x=0; x<p-buf; x+=n)
1962 42c3794c 2004-10-17 devnull if((n = write(fd, buf+x, (p-x)-buf)) <= 0)
1963 42c3794c 2004-10-17 devnull goto break2;
1964 42c3794c 2004-10-17 devnull
1965 42c3794c 2004-10-17 devnull if(i >= end)
1966 42c3794c 2004-10-17 devnull break;
1967 42c3794c 2004-10-17 devnull p = buf;
1968 42c3794c 2004-10-17 devnull }
1969 42c3794c 2004-10-17 devnull if(i < t.org)
1970 42c3794c 2004-10-17 devnull i = t.org;
1971 42c3794c 2004-10-17 devnull r = t.r[i-t.org];
1972 42c3794c 2004-10-17 devnull if(r < Runeself)
1973 42c3794c 2004-10-17 devnull *p++ = r;
1974 42c3794c 2004-10-17 devnull else
1975 42c3794c 2004-10-17 devnull p += runetochar(p, &r);
1976 42c3794c 2004-10-17 devnull }
1977 42c3794c 2004-10-17 devnull break2:
1978 42c3794c 2004-10-17 devnull close(fd);
1979 42c3794c 2004-10-17 devnull }