|
|
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: Sclose(&((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: Sclose(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: exit(1);
204: break;
205: }
206: }
207: setlock(){
208: lock++;
209: cursswitch(cursor= &lockarrow);
210: }
211: clrlock(){
212: lock=0;
213: cursswitch(cursor=(Cursor *)0);
214: }
215: startfile(t)
216: Text *t;
217: {
218: outTsl(Tstartfile, t->tag, (long)t);
219: outTs(Tunlockfile, t->tag);
220: t->lock++;
221: }
222: startnewfile(type, t)
223: Text *t;
224: {
225: t->tag=Untagged;
226: outTl(type, (long)t);
227: }
228: inshort(n)
229: {
230: return indata[n]|(indata[n+1]<<8);
231: }
232: long
233: inlong(n)
234: {
235: return indata[n]|(indata[n+1]<<8)|
236: ((long)indata[n+2]<<16)|((long)indata[n+3]<<24);
237: }
238: outT0(type)
239: Tmesg type;
240: {
241: outstart(type);
242: outsend();
243: }
244: outTl(type, l)
245: Tmesg type;
246: long l;
247: {
248: outstart(type);
249: outlong(l);
250: outsend();
251: }
252: outTs(type, s)
253: Tmesg type;
254: {
255: outstart(type);
256: outshort(s);
257: outsend();
258: }
259: outTss(type, s1, s2)
260: Tmesg type;
261: {
262: outstart(type);
263: outshort(s1);
264: outshort(s2);
265: outsend();
266: }
267: outTsll(type, s1, l1, l2)
268: Tmesg type;
269: long l1, l2;
270: {
271: outstart(type);
272: outshort(s1);
273: outlong(l1);
274: outlong(l2);
275: outsend();
276: }
277: outTsl(type, s1, l1)
278: Tmesg type;
279: long l1;
280: {
281: outstart(type);
282: outshort(s1);
283: outlong(l1);
284: outsend();
285: }
286: outTslS(type, s1, l1, s)
287: Tmesg type;
288: long l1;
289: uchar *s;
290: {
291: outstart(type);
292: outshort(s1);
293: outlong(l1);
294: outcopy(strlen(s)+1, s);
295: outsend();
296: }
297: outTsls(type, s1, l1, s2)
298: Tmesg type;
299: long l1;
300: {
301: outstart(type);
302: outshort(s1);
303: outlong(l1);
304: outshort(s2);
305: outsend();
306: }
307: outstart(type)
308: Tmesg type;
309: {
310: outdata[0]=type;
311: outcount=0;
312: }
313: outcopy(count, data)
314: register uchar *data;
315: {
316: while(count--)
317: outdata[HSIZE+outcount++]= *data++;
318: }
319: outshort(s)
320: {
321: uchar buf[2];
322: buf[0]=s;
323: buf[1]=s>>8;
324: outcopy(2, buf);
325: }
326: outlong(l)
327: long l;
328: {
329: uchar buf[4];
330: buf[0]=l;
331: buf[1]=l>>8;
332: buf[2]=l>>16;
333: buf[3]=l>>24;
334: outcopy(4, buf);
335: }
336: outsend()
337: {
338: if(outcount>sizeof outdata-HSIZE)
339: panic("outcount>sizeof outdata");
340: outdata[1]=outcount;
341: outdata[2]=outcount>>8;
342: sendnchars(outcount+HSIZE, (char *)outdata);
343: }
344: hsetdot(m, p0, p1)
345: register long p0, p1;
346: {
347: register Text *t=whichtext(m);
348: register Flayer *l= &t->l[t->front];
349: flsetselect(l, p0, p1);
350: }
351: horigin(m, p0)
352: register long p0;
353: {
354: register Text *t=whichtext(m);
355: register Flayer *l= &t->l[t->front];
356: register long a;
357: if(!flprepare(l)){
358: l->origin=p0;
359: return;
360: }
361: a=p0-l->origin;
362: if(a>=0 && a<l->f.nchars)
363: frdelete(&l->f, (Posn)0, (Posn)a);
364: else if(a<0 && -a<l->f.nchars)
365: frinsert(&l->f, rload(&t->rasp, p0, l->origin), 0);
366: else
367: frdelete(&l->f, (Posn)0, l->f.nchars);
368: l->origin=p0;
369: scrdraw(l, t->rasp.nbytes);
370: if(l->visible==Some)
371: flrefresh(l, l->entire, 0);
372: hcheck(m);
373: }
374: hmoveto(m, p0)
375: register long p0;
376: {
377: register Text *t=whichtext(m);
378: register Flayer *l= &t->l[t->front];
379: if(p0<l->origin || p0-l->origin>muldiv(l->f.nchars, 9, 10))
380: outTsll(Torigin, m, p0, 2L);
381: }
382: hcheck(m)
383: {
384: register Flayer *l;
385: register Text *t;
386: register reqd=0, i;
387: register long n, a;
388: register Point p; /* SUN fix */
389: if(m==Untagged)
390: return;
391: t=whichtext(m);
392: for(l= &t->l[0], i=0; i<NL; i++, l++){
393: if(l->textfn==0 || !flprepare(l)) /* BUG: don't
394: need this if BUG below
395: is fixed */
396: continue;
397: a=t->l[i].origin;
398: n=rcontig(&t->rasp, a, a+l->f.nchars, 1);
399: if(n<l->f.nchars) /* text missing in middle of screen */
400: a+=n;
401: else{ /* text missing at end of screen? */
402: Again:
403: if(l->f.nlines==l->f.maxlines && /* BUG: lastlinefull!! */
404: (p=ptofchar(&l->f, l->f.nchars),p.y)>=
405: l->f.r.origin.y+l->f.maxlines*fheight(l->f.font))
406: goto Checksel; /* all's well */
407: a=t->l[i].origin+l->f.nchars;
408: n=t->rasp.nbytes-a;
409: if(n==0)
410: goto Checksel;
411: if(n>TBLOCKSIZE)
412: n=TBLOCKSIZE;
413: n=rcontig(&t->rasp, a, a+n, 1);
414: if(n>0){
415: rload(&t->rasp, a, a+n);
416: n=l->f.nchars;
417: flinsert(l, &scratch, l->origin+n);
418: if(n==l->f.nchars) /* made no progress */
419: goto Checksel;
420: goto Again;
421: }
422: }
423: if(!reqd){
424: n=rcontig(&t->rasp, a, a+TBLOCKSIZE, 0);
425: if(n<=0)
426: panic("hcheck request==0");
427: outTsls(Trequest, m, a, (int)n);
428: outTs(Tcheck, m);
429: t->lock++;
430: reqd++;
431: }
432: Checksel:
433: flsetselect(l, l->p0, l->p1);
434: }
435: }
436: flnewlyvisible(l)
437: register Flayer *l;
438: {
439: hcheck(((Text *)l->user1)->tag);
440: }
441: hsetsnarf(m){
442: struct{
443: uchar *s;
444: short n;
445: short size;
446: }s1, s2;
447: register c, i;
448: cursswitch(&deadmouse);
449: s1.s=0;
450: s1.n=s1.size=0;
451: getmuxbuf(&s1);
452: s2.n=s2.size=m;
453: GCALLOC(m, &s2.s);
454: for(i=0; i<m; i++){
455: while((c=rcvchar())<0)
456: wait(RCV);
457: s2.s[i]=c;
458: }
459: setmuxbuf(&s2);
460: gcfree(s2.s);
461: snarflen=s1.n;
462: outTs(Tsetsnarf, s1.n);
463: sendnchars(s1.n, s1.s);
464: gcfree(s1.s);
465: cursswitch(cursor);
466: }
467: hgrow(m, a, new, req)
468: register long a, new;
469: {
470: register i;
471: register Flayer *l;
472: register Text *t=whichtext(m);
473: register long o, b;
474: if(new<=0)
475: panic("hgrow");
476: rresize(&t->rasp, a, 0L, new);
477: for(l= &t->l[0], i=0; i<NL; i++, l++){
478: if(l->textfn==0)
479: continue;
480: o=l->origin;
481: b=a-o-rmissing(&t->rasp, o, a);
482: if(a<o)
483: l->origin+=new;
484: if(a<l->p0)
485: l->p0+=new;
486: if(a<l->p1)
487: l->p1+=new;
488: if(!req || a<o || b>(long)l->f.nchars ||
489: (l->f.nchars==0 && a-o>0))
490: continue;
491: if(new>TBLOCKSIZE)
492: new=TBLOCKSIZE;
493: outTsls(Trequest, m, a, (int)new);
494: t->lock++;
495: req=0;
496: }
497: }
498: hdata(m, a, s, len)
499: register long a;
500: uchar *s;
501: {
502: register i;
503: register Flayer *l;
504: register Text *t=whichtext(m);
505: register long o, b;
506: if(t->lock)
507: --t->lock;
508: for(l= &t->l[0], i=0; i<NL; i++, l++){
509: if(l->textfn==0)
510: continue;
511: o=l->origin;
512: b=a-o-rmissing(&t->rasp, o, a);
513: if(a<o || b>(long)l->f.nchars)
514: continue;
515: flinsert(l, &s, o+b);
516: }
517: rdata(&t->rasp, a, a+len, s);
518: rclean(&t->rasp);
519: }
520: #define a A /* need this line or get 'redeclaration of a' error! */
521: hcut(m, a, old)
522: register long a, old;
523: {
524: register Flayer *l;
525: register Text *t=whichtext(m);
526: register i;
527: register long o, b;
528: if(t->lock)
529: --t->lock;
530: for(l= &t->l[0], i=0; i<NL; i++, l++){
531: if(l->textfn==0)
532: continue;
533: o=l->origin;
534: b=a-o-rmissing(&t->rasp, o, a);
535: if(b<(long)l->f.nchars && a+old>=o)
536: fldelete(l, b<0? o : o+b,
537: a+old-rmissing(&t->rasp, o, a+old));
538: if(a+old<o)
539: l->origin-=old;
540: else if(a<=o)
541: l->origin=a;
542: if(a+old<l->p0)
543: l->p0-=old;
544: else if(a<=l->p0)
545: l->p0=a;
546: if(a+old<l->p1)
547: l->p1-=old;
548: else if(a<=l->p1)
549: l->p1=a;
550: }
551: rresize(&t->rasp, a, old, 0L);
552: rclean(&t->rasp);
553: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.