|
|
1.1 root 1: #include "samterm.h"
2:
3: Text cmd;
4: uchar *scratch;
5: long nscralloc;
6: long typeaddr= -1;
7: Cursor *cursor;
8: Flayer *which=0;
9: Flayer *work=0;
10: long snarflen;
11: char lock=1; /* goes to 2 soon */
12: main(argc, argv)
13: int argc;
14: char **argv;
15: {
16: register got, scr;
17: register Text *t;
18: Rectangle r;
19: register Flayer *nwhich;
20:
21: request(MOUSE|KBD|RCV);
22: initdisplay(argc, argv);
23: initcursors();
24: GCALLOC(100, &scratch);
25: nscralloc=100;
26: cursswitch(&sweep);
27: do {
28: while(!button3())
29: wait(MOUSE);
30: } while(!getr(&r, 0));
31: cursswitch((Cursor *)0);
32: setlock();
33: flstart(Drect);
34: rinit(&cmd.rasp);
35: flnew(&cmd.l[0], gettext, 1, (char *)&cmd);
36: flinit(&cmd.l[0], r, &defont);
37: cmd.nwin=1;
38: which= &cmd.l[0];
39: cmd.tag=Untagged;
40: startnewfile(Tstartcmdfile, &cmd);
41: for(;;){
42: if ((P->state&KBD) && which && (lock || ((Text *)which->user1)->lock))
43: wait(MOUSE|RCV);
44: else
45: wait(MOUSE|KBD|RCV);
46: if (P->state&RCV) {
47: rcv();
48: continue;
49: }
50: if(lock<2 && (P->state&RESHAPED)) {
51: P->state &= ~RESHAPED;
52: reshape();
53: }
54: if(which && (P->state&KBD))
55: type(which);
56: if(lock<2){
57: if(!button123() || !ptinrect(mouse.xy, Drect))
58: continue;
59: nwhich=flwhich(mouse.xy);
60: scr=which && ptinrect(mouse.xy, which->scroll);
61: if(button1()){
62: typeaddr= -1;
63: if(nwhich){
64: if(nwhich!=which)
65: current(nwhich);
66: else if(scr)
67: scroll(which, 1);
68: else{
69: t=(Text *)which->user1;
70: if(flselect(which)){
71: outTsl(Tdclick, t->tag, which->p0);
72: t->lock++;
73: }else if(t!=&cmd)
74: outcmd();
75: }
76: }
77: }else if(button2() && which){
78: typeaddr= -1;
79: if(scr)
80: scroll(which, 2);
81: else
82: menu2hit();
83: }else if(button3()){
84: typeaddr= -1;
85: if(scr)
86: scroll(which, 3);
87: else
88: menu3hit();
89: }
90: }
91: }
92: }
93: reshape(){
94: register i;
95: flreshape(Drect);
96: for(i=0; i<nname; i++)
97: if(text[i]){
98: hcheck(text[i]->tag);
99: }
100: }
101: current(nw)
102: register Flayer *nw;
103: {
104: register Text *t;
105: if(which)
106: flborder(which, 0);
107: if(nw){
108: typeaddr= -1;
109: cursswitch(&deadmouse);
110: flupfront(nw);
111: flborder(nw, 1);
112: (Up);
113: cursswitch(cursor);
114: t=(Text *)nw->user1;
115: t->front=nw-&t->l[0];
116: if(t!=&cmd)
117: work=nw;
118: }
119: which=nw;
120: }
121: Sclose(l)
122: register Flayer *l;
123: {
124: register Text *t=(Text *)l->user1;
125: register m;
126: m=whichmenu(t->tag);
127: if(m<0)
128: return;
129: cursswitch(&deadmouse);
130: flclose(l);
131: cursswitch(cursor);
132: if(l==which){
133: which=0;
134: current(flwhich(Pt(0, 0)));
135: }
136: if(l==work)
137: work=0;
138: if(--t->nwin==0){
139: rclear(&t->rasp);
140: free((char *)t);
141: text[m]=0;
142: }else if(l==&t->l[t->front]){
143: for(m=0; m<NL; m++) /* find one; any one will do */
144: if(t->l[m].textfn){
145: t->front=m;
146: return;
147: }
148: panic("Sclose");
149: }
150: }
151: Flayer *
152: findl(t)
153: register Text *t;
154: {
155: register i;
156: for(i=0; i<NL; i++)
157: if(t->l[i].textfn==0)
158: return &t->l[i];
159: return 0;
160: }
161: duplicate(l, r, f, close)
162: register Flayer *l;
163: Rectangle r;
164: Font *f;
165: {
166: register Text *t=(Text *)l->user1;
167: register Flayer *nl=findl(t);
168: if(nl){
169: cursswitch(&deadmouse);
170: flnew(nl, gettext, l->user0, (char *)t);
171: flinit(nl, r, f);
172: nl->origin=l->origin;
173: flinsert(nl, (*l->textfn)(l, l->f.nchars), l->origin);
174: flsetselect(nl, l->p0, l->p1);
175: if(close){
176: flclose(l);
177: if(l==which)
178: which=0;
179: }else
180: t->nwin++;
181: current(nl);
182: hcheck(t->tag);
183: }
184: cursswitch(cursor);
185: }
186: getr(rp, block)
187: Rectangle *rp;
188: {
189: Point p;
190: Rectangle r;
191: *rp=getrectb(1,block);
192: if(rp->corner.x && rp->corner.x-rp->origin.x<=5 && rp->corner.y-rp->origin.y<=5){
193: p=rp->origin;
194: r=cmd.l[cmd.front].entire;
195: *rp=Drect;
196: if(cmd.nwin==1){
197: if (p.y <= r.origin.y)
198: rp->corner.y = r.origin.y;
199: else if (p.y >= r.corner.y)
200: rp->origin.y = r.corner.y;
201: else if (p.x <= r.origin.x)
202: rp->corner.x = r.origin.x;
203: else if (p.x >= r.corner.x)
204: rp->origin.x = r.corner.x;
205: }
206: }
207: return rectclip(rp, Drect) &&
208: rp->corner.x-rp->origin.x>100 && rp->corner.y-rp->origin.y>40;
209: }
210: snarf(t, w)
211: register Text *t;
212: {
213: register Flayer *l= &t->l[w];
214: if(l->p1>l->p0){
215: snarflen=l->p1-l->p0;
216: outTsll(Tsnarf, t->tag, l->p0, l->p1);
217: }
218: }
219: cut(t, w, save)
220: Text *t;
221: {
222: register long p0, p1;
223: if((p0=t->l[w].p0)==(p1=t->l[w].p1))
224: return;
225: if(save)
226: snarf(t, w);
227: outTsll(Tcut, t->tag, p0, p1);
228: t->lock++;
229: flsetselect(&t->l[w], p0, p0);
230: hcut(t->tag, p0, p1-p0);
231: hcheck(t->tag);
232: }
233: paste(t, w)
234: Text *t;
235: {
236: long p0=t->l[w].p0;
237: if(snarflen){
238: cut(t, w, 0);
239: t->lock++;
240: outTsl(Tpaste, t->tag, p0);
241: }
242: }
243: strlen(s)
244: register uchar *s;
245: {
246: register n=0;
247: while(*s++)
248: n++;
249: return n;
250: }
251: alnum(c)
252: register c;
253: {
254: return ('0'<=c && c<='9') || (c=='_') ||
255: ('a'<=c && c<='z') || ('A'<=c && c<='Z');
256: }
257: raspc(r, p)
258: register Rasp *r;
259: register long p;
260: {
261: rload(r, p, p+1);
262: return scratch[0]; /* will be 0 if p is in a hole */
263: }
264: long
265: ctlw(r, o, p)
266: register Rasp *r;
267: register long o, p;
268: {
269: register c;
270: if(--p<o)
271: return o;
272: if(raspc(r, p)=='\n')
273: return p;
274: for(; p>=o && !alnum(c=raspc(r, p)); --p)
275: if(c=='\n')
276: return p+1;
277: for(; p>o && alnum(raspc(r, p-1)); --p)
278: ;
279: return p>=o? p : o;
280: }
281: #define ESC 0x1B
282: type(l) /* what a bloody mess this is */
283: register Flayer *l;
284: {
285: Text *t=(Text *)l->user1;
286: uchar buf[100];
287: register uchar *p=buf;
288: register c, backspacing=0;
289: register long a;
290: if(lock || t->lock)
291: return;
292: if((a=l->p0)!=l->p1){
293: cut(t, t->front, 1);
294: return; /* it may now be locked */
295: }
296: while(!backspacing && (c=kbdchar())>0 && c!=ESC)
297: switch(c&=0x7F){
298: case '\027':
299: case '\b':
300: backspacing=1;
301: break;
302: case '\r':
303: c='\n';
304: default:
305: *p++=c;
306: break;
307: }
308: if(p>buf){
309: if(typeaddr<0)
310: typeaddr=a;
311: *p=0;
312: hgrow(t->tag, a, (long)(p-buf), 0);
313: t->lock++; /* pretend we Trequest'ed */
314: hdata(t->tag, a, buf, (int)(p-buf));
315: if(t==&cmd && a+(p-buf)==t->rasp.nbytes && p[-1]=='\n'){
316: setlock();
317: outcmd();
318: outTslS(Ttype, t->tag, a, buf);
319: typeaddr= -1;
320: }else
321: outTslS(Ttype, t->tag, a, buf);
322: l->p0=l->p1=(a+=p-buf);
323: center(l, a);
324: }
325: if(!lock && backspacing && l->f.p0>0){
326: l->p1=a;
327: l->p0=c=='\b'? a-1 : ctlw(&t->rasp, l->origin, a);
328: cut(t, t->front, 0);
329: if(typeaddr>=l->p0)
330: typeaddr=l->p0;
331: }else{
332: if(c==ESC && typeaddr>=0){
333: l->p0=typeaddr, l->p1=a;
334: typeaddr= -1;
335: }
336: for(l=t->l; l<&t->l[NL]; l++)
337: if(l->textfn)
338: flsetselect(l, l->p0, l->p1);
339: }
340: }
341: center(l, a)
342: register Flayer *l;
343: register long a;
344: {
345: register Text *t=(Text *)l->user1;
346: if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
347: if(a>t->rasp.nbytes)
348: a=t->rasp.nbytes;
349: outTsll(Torigin, t->tag, a, 2L);
350: outTs(Tunlockfile, t->tag);
351: t->lock++;
352: return 1;
353: }
354: return 0;
355: }
356: outcmd(){
357: if(work)
358: outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
359: }
360: panic(s)
361: char *s;
362: {
363: rectf(D, Drect, F_XOR);
364: string(&defont, s, D, add(Drect.origin, Pt(4, 4)), F_STORE);
365: sleep(30);
366: exit(1);
367: }
368:
369: strgrow(s, n, want) /* can always toss the old data when called */
370: uchar **s;
371: long *n;
372: {
373: if(*n>=want)
374: return;
375: gcfree(*s);
376: GCALLOC(want, s);
377: *n=want;
378: }
379: uchar **
380: gettext(l, n)
381: register Flayer *l;
382: long n;
383: {
384: register Text *t=(Text *)l->user1;
385: rload(&t->rasp, l->origin, l->origin+n);
386: return &scratch;
387: }
388: long
389: scrtotal(l)
390: Flayer *l;
391: {
392: return ((Text *)l->user1)->rasp.nbytes;
393: }
394: uchar *
395: ALLOC(n)
396: {
397: register uchar *p=(uchar *)alloc(n);
398: if(p==0)
399: panic("ALLOC");
400: return p;
401: }
402: GCALLOC(n, w)
403: uchar **w;
404: {
405: register i, j;
406: register Text *t;
407: register Flayer *l;
408: if(gcalloc((unsigned long)n, (char **)w)==0){
409: for(i=0; i<nname; i++)
410: if(t=text[i]){
411: /*raspcleanup(t); - uncache worthless stuff*/
412: /*rclean(&t->rasp); (Can we do this if !t->lock?) */
413: for(j=0,l= &t->l[0]; j<NL; j++,l++)
414: if(l->textfn && l->visible==Some && l->f.b){
415: bfree(l->f.b);
416: l->f.b=0;
417: }
418: }
419: if(gcalloc((unsigned long)n, w)==0)
420: panic("GCALLOC");
421: }
422: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.