|
|
1.1 root 1: #include "samterm.h"
2:
3: #define HSIZE 3 /* Type + short count */
4: Header h;
5: uchar indata[DATASIZE];
6: uchar outdata[DATASIZE];
7: short outcount;
8: long inlong();
9: Text *sweeptext();
10: rcv(){
11: register c;
12: static state=0;
13: static count=0;
14: static i=0;
15: while((c=rcvchar())!=-1)
16: switch(state){
17: case 0:
18: h.type=c;
19: state++;
20: break;
21: case 1:
22: h.count0=c;
23: state++;
24: break;
25: case 2:
26: h.count1=c;
27: count=h.count0|(h.count1<<8);
28: i=0;
29: if(count>DATASIZE)
30: panic("count>DATASIZE");
31: if(count==0)
32: goto zerocount;
33: state++;
34: break;
35: case 3:
36: indata[i++]=c;
37: if(i==count){
38: zerocount:
39: inmesg(h.type, count);
40: state=count=0;
41: continue;
42: }
43: break;
44: }
45: }
46: Text *
47: whichtext(tg)
48: register tg;
49: {
50: register i;
51: for(i=0; i<nname; i++)
52: if(tag[i]==tg)
53: return text[i];
54: panic("whichtext");
55: return 0;
56: }
57: inmesg(type, count)
58: Hmesg type;
59: {
60: register Text *t;
61: register i, m;
62: register long l;
63: register Flayer *lp;
64: m=inshort(0);
65: l=inlong(2);
66: switch(type){
67: case -1:
68: panic("rcv error");
69: default:
70: panic("rcv unknown");
71: case Hnewname:
72: menuins(0, (uchar *)"", (Text *)0, ' ', m);
73: break;
74: case Hdelname:
75: if((m=whichmenu(m))>=0)
76: menudel(m);
77: break;
78: case Hmovname:
79: if((m=whichmenu(m))<0)
80: break;
81: t=text[m];
82: l=tag[m];
83: i=name[m][0];
84: text[m]=0; /* suppress panic in menudel */
85: menudel(m);
86: if(t==&cmd)
87: m=0;
88: else{
89: for(m=nname>0 && text[0]==&cmd; m<nname; m++)
90: if(strcmp(indata+2, name[m]+1)<0)
91: break;
92: }
93: menuins(m, indata+2, t, i, (int)l);
94: break;
95: case Hbindname:
96: if((i=whichmenu(m))<0)
97: break;
98: /* in case of a race, a bindname may already have occurred */
99: if((t=whichtext(m))==0)
100: t=(Text *)l;
101: else /* let the old one win; clean up the new one */
102: while(((Text *)l)->nwin>0)
103: close(&((Text *)l)->l[((Text *)l)->front]);
104: text[i]=t;
105: text[i]->tag=m;
106: break;
107: case Hcurrent:
108: if(whichmenu(m)<0)
109: break;
110: t=whichtext(m);
111: i=which && ((Text *)which->user1)==&cmd && m!=cmd.tag;
112: if(t==0 && (t=sweeptext(0, m))==0)
113: break;
114: if(t->l[t->front].textfn==0)
115: panic("Hcurrent");
116: lp=&t->l[t->front];
117: if(i){
118: flupfront(lp);
119: flborder(lp, 0);
120: work=lp;
121: }else
122: current(lp);
123: break;
124: case Hgrow:
125: if(whichmenu(m)>=0)
126: hgrow(m, l, inlong(6), 1);
127: break;
128: case Hdata:
129: if(whichmenu(m)>=0)
130: hdata(m, l, indata+6, count-7);
131: Checkscroll:
132: if(m==cmd.tag)
133: for(i=0; i<NL; i++){
134: lp=&cmd.l[i];
135: if(lp->textfn && lp->user0)
136: center(lp, l+1);
137: }
138: break;
139: case Hgrowdata:
140: if(whichmenu(m)<0)
141: break;
142: hgrow(m, l, inlong(6), 0);
143: whichtext(m)->lock++; /* fake the request */
144: hdata(m, l, indata+10, count-11);
145: goto Checkscroll;
146: case Hcut:
147: if(whichmenu(m)>=0)
148: hcut(m, l, inlong(6));
149: break;
150: case Hclean:
151: if((m=whichmenu(m))>=0)
152: name[m][0]=' ';
153: break;
154: case Hdirty:
155: if((m=whichmenu(m))>=0)
156: name[m][0]='\'';
157: break;
158: case Hcheck0:
159: if(whichmenu(m)>=0)
160: outTs(Tcheck, m);
161: break;
162: case Hcheck:
163: if(whichmenu(m)>=0)
164: hcheck(m);
165: break;
166: case Hmoveto:
167: if(whichmenu(m)>=0)
168: hmoveto(m, l);
169: break;
170: case Hsetdot:
171: if(whichmenu(m)>=0)
172: hsetdot(m, l, inlong(6));
173: break;
174: case Horigin:
175: if(whichmenu(m)>=0)
176: horigin(m, l);
177: break;
178: case Hclose:
179: if(whichmenu(m)<0 || (t=whichtext(m))==0)
180: break;
181: for(i=0,lp=t->l; i<NL; i++,lp++)
182: if(lp->textfn)
183: close(lp);
184: break;
185: case Hunlock:
186: clrlock();
187: break;
188: case Hsetpat:
189: setpat((char *)indata);
190: break;
191: case Hunlockfile:
192: if(whichmenu(m)>=0 && (t=whichtext(m))->lock)
193: --t->lock;
194: break;
195: case Hsetsnarf:
196: hsetsnarf(m);
197: break;
198: case Hsnarflen:
199: snarflen=inlong(0);
200: break;
201: case Hexit:
202: outT0(Texit);
203: break;
204: }
205: }
206: setlock(){
207: lock++;
208: cursswitch(cursor=&lockarrow);
209: }
210: clrlock(){
211: lock=0;
212: cursswitch(cursor=(Texture *)0);
213: }
214: startfile(t)
215: Text *t;
216: {
217: outTsl(Tstartfile, t->tag, (long)t);
218: outTs(Tunlockfile, t->tag);
219: t->lock++;
220: }
221: startnewfile(type, t)
222: Text *t;
223: {
224: t->tag=Untagged;
225: outTl(type, (long)t);
226: }
227: inshort(n)
228: {
229: return indata[n]|(indata[n+1]<<8);
230: }
231: long
232: inlong(n)
233: {
234: return indata[n]|(indata[n+1]<<8)|
235: ((long)indata[n+2]<<16)|((long)indata[n+3]<<24);
236: }
237: outT0(type)
238: Tmesg type;
239: {
240: outstart(type);
241: outsend();
242: }
243: outTl(type, l)
244: Tmesg type;
245: long l;
246: {
247: outstart(type);
248: outlong(l);
249: outsend();
250: }
251: outTs(type, s)
252: Tmesg type;
253: {
254: outstart(type);
255: outshort(s);
256: outsend();
257: }
258: outTss(type, s1, s2)
259: Tmesg type;
260: {
261: outstart(type);
262: outshort(s1);
263: outshort(s2);
264: outsend();
265: }
266: outTsll(type, s1, l1, l2)
267: Tmesg type;
268: long l1, l2;
269: {
270: outstart(type);
271: outshort(s1);
272: outlong(l1);
273: outlong(l2);
274: outsend();
275: }
276: outTsl(type, s1, l1)
277: Tmesg type;
278: long l1;
279: {
280: outstart(type);
281: outshort(s1);
282: outlong(l1);
283: outsend();
284: }
285: outTslS(type, s1, l1, s)
286: Tmesg type;
287: long l1;
288: uchar *s;
289: {
290: outstart(type);
291: outshort(s1);
292: outlong(l1);
293: outcopy(strlen(s)+1, s);
294: outsend();
295: }
296: outTsls(type, s1, l1, s2)
297: Tmesg type;
298: long l1;
299: {
300: outstart(type);
301: outshort(s1);
302: outlong(l1);
303: outshort(s2);
304: outsend();
305: }
306: outstart(type)
307: Tmesg type;
308: {
309: outdata[0]=type;
310: outcount=0;
311: }
312: outcopy(count, data)
313: register uchar *data;
314: {
315: while(count--)
316: outdata[HSIZE+outcount++]=*data++;
317: }
318: outshort(s)
319: {
320: uchar buf[2];
321: buf[0]=s;
322: buf[1]=s>>8;
323: outcopy(2, buf);
324: }
325: outlong(l)
326: long l;
327: {
328: uchar buf[4];
329: buf[0]=l;
330: buf[1]=l>>8;
331: buf[2]=l>>16;
332: buf[3]=l>>24;
333: outcopy(4, buf);
334: }
335: outsend()
336: {
337: if(outcount>sizeof outdata-HSIZE)
338: panic("outcount>sizeof outdata");
339: outdata[1]=outcount;
340: outdata[2]=outcount>>8;
341: sendnchars(outcount+HSIZE, (char *)outdata);
342: }
343: hsetdot(m, p0, p1)
344: register long p0, p1;
345: {
346: register Text *t=whichtext(m);
347: register Flayer *l=&t->l[t->front];
348: flsetselect(l, p0, p1);
349: }
350: horigin(m, p0)
351: register long p0;
352: {
353: register Text *t=whichtext(m);
354: register Flayer *l=&t->l[t->front];
355: register long a;
356: if(!flprepare(l)){
357: l->origin=p0;
358: return;
359: }
360: a=p0-l->origin;
361: if(a>=0 && a<l->f.nchars)
362: frdelete(&l->f, (Posn)0, (Posn)a);
363: else if(a<0 && -a<l->f.nchars)
364: frinsert(&l->f, rload(&t->rasp, p0, l->origin), 0);
365: else
366: frdelete(&l->f, (Posn)0, l->f.nchars);
367: l->origin=p0;
368: scrdraw(l, t->rasp.nbytes);
369: if(l->visible==Some)
370: flrefresh(l, l->entire, 0);
371: hcheck(m);
372: }
373: hmoveto(m, p0)
374: register long p0;
375: {
376: register Text *t=whichtext(m);
377: register Flayer *l=&t->l[t->front];
378: if(p0<l->origin || p0-l->origin>muldiv(l->f.nchars, 9, 10))
379: outTsll(Torigin, m, p0, 2L);
380: }
381: hcheck(m)
382: {
383: register Flayer *l;
384: register Text *t;
385: register reqd=0, i;
386: register long n, a;
387: if(m==Untagged)
388: return;
389: t=whichtext(m);
390: for(l=&t->l[0], i=0; i<NL; i++, l++){
391: if(l->textfn==0 || !flprepare(l)) /* BUG: don't
392: need this if BUG below
393: is fixed */
394: continue;
395: a=t->l[i].origin;
396: n=rcontig(&t->rasp, a, a+l->f.nchars, 1);
397: if(n<l->f.nchars) /* text missing in middle of screen */
398: a+=n;
399: else{ /* text missing at end of screen? */
400: Again:
401: if(l->f.nlines==l->f.maxlines && /* BUG: lastlinefull!! */
402: ptofchar(&l->f, l->f.nchars).y>=
403: l->f.r.origin.y+l->f.maxlines*l->f.font->height)
404: goto Checksel; /* all's well */
405: a=t->l[i].origin+l->f.nchars;
406: n=t->rasp.nbytes-a;
407: if(n==0)
408: goto Checksel;
409: if(n>TBLOCKSIZE)
410: n=TBLOCKSIZE;
411: n=rcontig(&t->rasp, a, a+n, 1);
412: if(n>0){
413: rload(&t->rasp, a, a+n);
414: n=l->f.nchars;
415: flinsert(l, &scratch, l->origin+n);
416: if(n==l->f.nchars) /* made no progress */
417: goto Checksel;
418: goto Again;
419: }
420: }
421: if(!reqd){
422: n=rcontig(&t->rasp, a, a+TBLOCKSIZE, 0);
423: if(n<=0)
424: panic("hcheck request==0");
425: outTsls(Trequest, m, a, (int)n);
426: outTs(Tcheck, m);
427: t->lock++;
428: reqd++;
429: }
430: Checksel:
431: flsetselect(l, l->p0, l->p1);
432: }
433: }
434: flnewlyvisible(l)
435: register Flayer *l;
436: {
437: hcheck(((Text *)l->user1)->tag);
438: }
439: hsetsnarf(m){
440: struct{
441: uchar *s;
442: short n;
443: short size;
444: }s1, s2;
445: register c, i;
446: cursswitch(&deadmouse);
447: s1.s=0;
448: s1.n=s1.size=0;
449: getmuxbuf(&s1);
450: s2.n=s2.size=m;
451: GCALLOC(m, &s2.s);
452: for(i=0; i<m; i++){
453: while((c=rcvchar())<0)
454: wait(RCV);
455: s2.s[i]=c;
456: }
457: setmuxbuf(&s2);
458: gcfree(s2.s);
459: snarflen=s1.n;
460: outTs(Tsetsnarf, s1.n);
461: sendnchars(s1.n, s1.s);
462: gcfree(s1.s);
463: cursswitch(cursor);
464: }
465: hgrow(m, a, new, req)
466: register long a, new;
467: {
468: register i;
469: register Flayer *l;
470: register Text *t=whichtext(m);
471: register long o, b;
472: if(new<=0)
473: panic("hgrow");
474: rresize(&t->rasp, a, 0L, new);
475: for(l=&t->l[0], i=0; i<NL; i++, l++){
476: if(l->textfn==0)
477: continue;
478: o=l->origin;
479: b=a-o-rmissing(&t->rasp, o, a);
480: if(a<o)
481: l->origin+=new;
482: if(a<l->p0)
483: l->p0+=new;
484: if(a<l->p1)
485: l->p1+=new;
486: if(!req || a<o || b>(long)l->f.nchars ||
487: (l->f.nchars==0 && a-o>0))
488: continue;
489: if(new>TBLOCKSIZE)
490: new=TBLOCKSIZE;
491: outTsls(Trequest, m, a, (int)new);
492: t->lock++;
493: req=0;
494: }
495: }
496: hdata(m, a, s, len)
497: register long a;
498: uchar *s;
499: {
500: register i;
501: register Flayer *l;
502: register Text *t=whichtext(m);
503: register long o, b;
504: if(t->lock)
505: --t->lock;
506: for(l=&t->l[0], i=0; i<NL; i++, l++){
507: if(l->textfn==0)
508: continue;
509: o=l->origin;
510: b=a-o-rmissing(&t->rasp, o, a);
511: if(a<o || b>(long)l->f.nchars)
512: continue;
513: flinsert(l, &s, o+b);
514: }
515: rdata(&t->rasp, a, a+len, s);
516: rclean(&t->rasp);
517: }
518: #define a A /* need this line or get 'redeclaration of a' error! */
519: hcut(m, a, old)
520: register long a, old;
521: {
522: register Flayer *l;
523: register Text *t=whichtext(m);
524: register i;
525: register long o, b;
526: if(t->lock)
527: --t->lock;
528: for(l=&t->l[0], i=0; i<NL; i++, l++){
529: if(l->textfn==0)
530: continue;
531: o=l->origin;
532: b=a-o-rmissing(&t->rasp, o, a);
533: if(b<(long)l->f.nchars && a+old>=o)
534: fldelete(l, b<0? o : o+b,
535: a+old-rmissing(&t->rasp, o, a+old));
536: if(a+old<o)
537: l->origin-=old;
538: else if(a<=o)
539: l->origin=a;
540: if(a+old<l->p0)
541: l->p0-=old;
542: else if(a<=l->p0)
543: l->p0=a;
544: if(a+old<l->p1)
545: l->p1-=old;
546: else if(a<=l->p1)
547: l->p1=a;
548: }
549: rresize(&t->rasp, a, old, 0L);
550: rclean(&t->rasp);
551: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.