Introduction
Introduction Statistics Contact Development Disclaimer Help
mesg.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
mesg.c (15616B)
---
1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
2 #include <string.h>
3 #include <u.h>
4 #include <libg.h>
5 #include <frame.h>
6 #include "flayer.h"
7 #include "samterm.h"
8
9 extern char *exname;
10 extern Flayer *flast;
11
12 #define HSIZE 3 /* Type + int16_t count */
13 Header h;
14 uint8_t indata[DATASIZE+1]; /* room for NUL */
15 uint8_t outdata[DATASIZE];
16 int16_t outcount;
17 int hversion;
18
19 void inmesg(Hmesg, int);
20 int inshort(int);
21 int64_t inlong(int);
22 void hsetdot(int, int64_t, int64_t);
23 void hmoveto(int, int64_t, Flayer *);
24 void hsetsnarf(int);
25 void clrlock(void);
26 int snarfswap(char*, int, char**);
27
28 void
29 rcv(void)
30 {
31 int c;
32 static int state = 0;
33 static int count = 0;
34 static int i = 0;
35 static int errs = 0;
36
37 while((c=rcvchar()) != -1)
38 switch(state){
39 case 0:
40 h.type = c;
41 state++;
42 break;
43
44 case 1:
45 h.count0 = c;
46 state++;
47 break;
48
49 case 2:
50 h.count1 = c;
51 count = h.count0|(h.count1<<8);
52 i = 0;
53 if(count > DATASIZE){
54 if(++errs < 5){
55 dumperrmsg(count, h.type, h.count0, c);
56 state = 0;
57 continue;
58 }
59 fprintf(stderr, "type %d count %d\n", h.type, count);
60 panic("count>DATASIZE");
61 }
62 if(count == 0)
63 goto zerocount;
64 state++;
65 break;
66
67 case 3:
68 indata[i++] = c;
69 if(i == count){
70 zerocount:
71 indata[i] = 0;
72 inmesg(h.type, count);
73 state = count = 0;
74 continue;
75 }
76 break;
77 }
78 }
79
80 Text *
81 whichtext(int tg)
82 {
83 int i;
84
85 for(i=0; i<nname; i++)
86 if(tag[i] == tg)
87 return text[i];
88 panic("whichtext");
89 return 0;
90 }
91
92 void
93 inmesg(Hmesg type, int count)
94 {
95 Text *t;
96 int i, m;
97 int64_t l, l2;
98 Flayer *lp;
99
100 m = inshort(0);
101 l = inlong(2);
102 switch(type){
103 case Terror:
104 panic("rcv error");
105 default:
106 fprintf(stderr, "type %d\n", type);
107 panic("rcv unknown");
108
109 case Hversion:
110 hversion = m;
111 if (hversion != VERSION)
112 panic("host-terminal version mismatch");
113 break;
114
115 case Hbindname:
116 l = inlong(2); /* for 64-bit pointers */
117 if((i=whichmenu(m)) < 0)
118 break;
119 /* in case of a race, a bindname may already have occurred */
120 if((t=whichtext(m)) == 0)
121 t=(Text *)l;
122 else /* let the old one win; clean up the new one */
123 while(((Text *)l)->nwin>0)
124 closeup(&((Text *)l)->l[((Text *)l)->front]);
125 text[i] = t;
126 text[i]->tag = m;
127 break;
128
129 case Hcurrent:
130 if(whichmenu(m)<0)
131 break;
132 t = whichtext(m);
133 i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag;
134 if(t==0 && (t = sweeptext(0, m))==0)
135 break;
136 if(t->l[t->front].textfn==0)
137 panic("Hcurrent");
138 lp = &t->l[t->front];
139 if(i){
140 flupfront(lp);
141 flborder(lp, 0);
142 work = lp;
143 flast = lp;
144 }else
145 current(lp);
146 break;
147
148 case Hmovname:
149 if((m=whichmenu(m)) < 0)
150 break;
151 t = text[m];
152 l = tag[m];
153 i = name[m][0];
154 text[m] = 0; /* suppress panic in menudel */
155 menudel(m);
156 if(t == &cmd)
157 m = 0;
158 else{
159 if (nname>0 && text[0]==&cmd)
160 m = 1;
161 else m = 0;
162 for(; m<nname; m++)
163 if(strcmp((char*)indata+2, (char*)name[m]+1)<0)
164 break;
165 }
166 menuins(m, indata+2, t, i, (int)l);
167 break;
168
169 case Hgrow:
170 if(whichmenu(m) >= 0)
171 hgrow(m, l, inlong(10), true);
172 break;
173
174 case Hnewname:
175 menuins(0, (uint8_t *)"", (Text *)0, ' ', m);
176 break;
177
178 case Hcheck0:
179 i = whichmenu(m);
180 if(i>=0) {
181 t = text[i];
182 if (t)
183 t->lock++;
184 outTs(Tcheck, m);
185 }
186 break;
187
188 case Hcheck:
189 i = whichmenu(m);
190 if(i>=0) {
191 t = text[i];
192 if (t && t->lock)
193 t->lock--;
194 hcheck(m);
195 }
196 break;
197
198 case Hunlock:
199 clrlock();
200 break;
201
202 case Hdata:
203 if(whichmenu(m) >= 0)
204 l += hdata(m, l, indata+10, count-10);
205 Checkscroll:
206 if(m == cmd.tag){
207 for(i=0; i<NL; i++){
208 lp = &cmd.l[i];
209 if(lp->textfn)
210 center(lp, l>=0? l : lp->p1);
211 }
212 }
213 break;
214
215 case Horigin:
216 if(whichmenu(m) >= 0){
217 Text *t = whichtext(m);
218 l2 = inlong(10);
219 horigin(m, l, &t->l[l2]);
220 }
221 break;
222
223 case Hunlockfile:
224 if(whichmenu(m)>=0 && (t = whichtext(m))->lock){
225 --t->lock;
226 l = -1;
227 goto Checkscroll;
228 }
229 break;
230
231 case Hsetdot:
232 if(whichmenu(m) >= 0)
233 hsetdot(m, l, inlong(10));
234 break;
235
236 case Hgrowdata:
237 if(whichmenu(m)<0)
238 break;
239 hgrow(m, l, inlong(10), false);
240 whichtext(m)->lock++; /* fake the request */
241 l += hdata(m, l, indata+18, count-18);
242 goto Checkscroll;
243
244 case Hmoveto:
245 if(whichmenu(m)>=0)
246 hmoveto(m, l, NULL);
247 break;
248
249 case Hclean:
250 if((m = whichmenu(m)) >= 0)
251 name[m][0] = ' ';
252 break;
253
254 case Hdirty:
255 if((m = whichmenu(m))>=0)
256 name[m][0] = '\'';
257 break;
258
259 case Hdelname:
260 if((m=whichmenu(m)) >= 0)
261 menudel(m);
262 break;
263
264 case Hcut:
265 if(whichmenu(m) >= 0)
266 hcut(m, l, inlong(10));
267 break;
268
269 case Hclose:
270 if(whichmenu(m)<0 || (t = whichtext(m))==0)
271 break;
272 l = t->nwin;
273 for(i = 0,lp = t->l; l>0 && i<NL; i++,lp++)
274 if(lp->textfn){
275 closeup(lp);
276 --l;
277 }
278 break;
279
280 case Hsetpat:
281 setpat((char *)indata);
282 break;
283
284 case Hsetsnarf:
285 hsetsnarf(m);
286 break;
287
288 case Hsnarflen:
289 snarflen = inlong(0);
290 break;
291
292 case Hack:
293 outT0(Tack);
294 break;
295
296 case Hexit:
297 outT0(Texit);
298 mouseexit();
299 break;
300 }
301 }
302
303 void
304 setlock(void)
305 {
306 lock++;
307 cursorswitch(cursor = LockCursor);
308 }
309
310 void
311 clrlock(void)
312 {
313 hasunlocked = true;
314 if(lock > 0)
315 lock--;
316 if(lock == 0)
317 cursorswitch(cursor=DefaultCursor);
318 }
319
320 void
321 startfile(Text *t)
322 {
323 outTsl(Tstartfile, t->tag, (int64_t)t); /* for 64-bit pointers …
324 setlock();
325 }
326
327 void
328 startnewfile(int type, Text *t)
329 {
330 t->tag = Untagged;
331 outTl(type, (int64_t)t); /* for 64-bit pointers */
332 }
333
334 int
335 inshort(int n)
336 {
337 return indata[n]|(indata[n+1]<<8);
338 }
339
340 int64_t
341 inlong(int n)
342 {
343 int64_t l;
344
345 l = (indata[n+7]<<24) | (indata[n+6]<<16) | (indata[n+5]<<8) | indat…
346 l = (l<<16) | (indata[n+3]<<8) | indata[n+2];
347 l = (l<<16) | (indata[n+1]<<8) | indata[n];
348 return l;
349 }
350
351 void
352 outT0(Tmesg type)
353 {
354 outstart(type);
355 outsend();
356 }
357
358 void
359 outTl(Tmesg type, int64_t l)
360 {
361 outstart(type);
362 outlong(l);
363 outsend();
364 }
365
366 void
367 outTs(Tmesg type, int s)
368 {
369 outstart(type);
370 outshort(s);
371 outsend();
372 }
373
374 void
375 outTss(Tmesg type, int s1, int s2)
376 {
377 outstart(type);
378 outshort(s1);
379 outshort(s2);
380 outsend();
381 }
382
383 void
384 outTslll(Tmesg type, int s1, int64_t l1, int64_t l2, int64_t l3)
385 {
386 outstart(type);
387 outshort(s1);
388 outlong(l1);
389 outlong(l2);
390 outlong(l3);
391 outsend();
392 }
393
394 void
395 outTsll(Tmesg type, int s1, int64_t l1, int64_t l2)
396 {
397 outstart(type);
398 outshort(s1);
399 outlong(l1);
400 outlong(l2);
401 outsend();
402 }
403
404 void
405 outTsl(Tmesg type, int s1, int64_t l1)
406 {
407 outstart(type);
408 outshort(s1);
409 outlong(l1);
410 outsend();
411 }
412
413 void
414 outTslS(Tmesg type, int s1, int64_t l1, wchar_t *s)
415 {
416 char buf[DATASIZE*3+1];
417 char *c;
418
419 outstart(type);
420 outshort(s1);
421 outlong(l1);
422 c = buf;
423 while(*s)
424 c += runetochar(c, *s++);
425 *c++ = 0;
426 outcopy(c-buf, (uint8_t *)buf);
427 outsend();
428 }
429
430 void
431 outTsls(Tmesg type, int s1, int64_t l1, int s2)
432 {
433 outstart(type);
434 outshort(s1);
435 outlong(l1);
436 outshort(s2);
437 outsend();
438 }
439
440 void
441 outstart(Tmesg type)
442 {
443 outdata[0] = type;
444 outcount = 0;
445 }
446
447 void
448 outcopy(int count, uint8_t *data)
449 {
450 while(count--)
451 outdata[HSIZE+outcount++] = *data++;
452 }
453
454 void
455 outshort(int s)
456 {
457 uint8_t buf[2];
458
459 buf[0]=s;
460 buf[1]=s>>8;
461 outcopy(2, buf);
462 }
463
464 void
465 outlong(int64_t l)
466 {
467 int i;
468 uint8_t buf[8];
469
470 for(i = 0; i < sizeof(buf); i++, l >>= 8)
471 buf[i] = l;
472
473 outcopy(8, buf);
474 }
475
476 void
477 outsend(void)
478 {
479 if(outcount>DATASIZE-HSIZE)
480 panic("outcount>sizeof outdata");
481 outdata[1]=outcount;
482 outdata[2]=outcount>>8;
483 if(write(1, (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)
484 exit(EXIT_FAILURE);
485 }
486
487
488 void
489 hsetdot(int m, int64_t p0, int64_t p1)
490 {
491 Text *t = whichtext(m);
492 Flayer *l = &t->l[t->front];
493
494 flushtyping(true);
495 flsetselect(l, p0, p1);
496 }
497
498 void
499 horigin(int m, int64_t p0, Flayer *l)
500 {
501 Text *t = whichtext(m);
502 l = l ? l : &t->l[t->front];
503 int64_t a;
504 uint64_t n;
505 wchar_t *r;
506
507 if (getlayer(l, t) < 0)
508 return; /* the user managed to close the layer during the round …
509
510 if(!flprepare(l)){
511 l->origin = p0;
512 return;
513 }
514 a = p0-l->origin;
515 if(a>=0 && a<l->f.nchars)
516 frdelete(&l->f, 0, a);
517 else if(a<0 && -a<l->f.nchars){
518 r = rload(&t->rasp, p0, l->origin, &n);
519 frinsert(&l->f, r, r+n, 0);
520 }else
521 frdelete(&l->f, 0, l->f.nchars);
522 l->origin = p0;
523 scrdraw(l, t->rasp.nrunes);
524 if(l->visible==Some)
525 flrefresh(l, l->entire, 0);
526 hcheck(m);
527 }
528
529 void
530 hmoveto(int m, int64_t p0, Flayer *l)
531 {
532 Text *t = whichtext(m);
533 l = l ? l : &t->l[t->front];
534
535 if (p0 < l->origin || p0 - l->origin > l->f.nchars * 9/10)
536 outTslll(Torigin, m, p0, 2L, getlayer(l, t));
537 }
538
539 void
540 hcheck(int m)
541 {
542 Flayer *l;
543 Text *t;
544 int reqd = 0, i;
545 int64_t n, nl, a;
546 wchar_t *r;
547
548 if(m == Untagged)
549 return;
550 t = whichtext(m);
551 if(t == 0) /* possible in a half-built window */
552 return;
553 for(l = &t->l[0], i = 0; i<NL; i++, l++){
554 if(l->textfn==0 || !flprepare(l)) /* BUG: don't
555 need this if BUG below
556 is fixed */
557 continue;
558 a = t->l[i].origin;
559 n = rcontig(&t->rasp, a, a+l->f.nchars, true);
560 if(n<l->f.nchars) /* text missing in middle of screen */
561 a+=n;
562 else{ /* text missing at end of screen? */
563 Again:
564 if(l->f.lastlinefull)
565 goto Checksel; /* all's well */
566 a = t->l[i].origin+l->f.nchars;
567 n = t->rasp.nrunes-a;
568 if(n==0)
569 goto Checksel;
570 if(n>TBLOCKSIZE)
571 n = TBLOCKSIZE;
572 n = rcontig(&t->rasp, a, a+n, true);
573 if(n>0){
574 rload(&t->rasp, a, a+n, 0);
575 nl = l->f.nchars;
576 r = scratch;
577 flinsert(l, r, r+n, l->origin+nl);
578 if(nl == l->f.nchars) /* made no progress */
579 goto Checksel;
580 goto Again;
581 }
582 }
583 if(!reqd){
584 n = rcontig(&t->rasp, a, a+TBLOCKSIZE, false);
585 if(n <= 0)
586 panic("hcheck request==0");
587 outTsls(Trequest, m, a, (int)n);
588 outTs(Tcheck, m);
589 t->lock++; /* for the Trequest */
590 t->lock++; /* for the Tcheck */
591 reqd++;
592 }
593 Checksel:
594 flsetselect(l, l->p0, l->p1);
595 }
596 }
597
598 void
599 flnewlyvisible(Flayer *l)
600 {
601 hcheck(((Text *)l->user1)->tag);
602 }
603
604 void
605 hsetsnarf(int nc)
606 {
607 char *s2;
608 char *s1;
609 int i;
610 int n;
611
612 cursorswitch(DeadCursor);
613 s2 = alloc(nc+1);
614 for(i=0; i<nc; i++)
615 s2[i] = getch();
616 s2[nc] = 0;
617 n = snarfswap(s2, nc, &s1);
618 if(n >= 0){
619 if(!s1)
620 n = 0;
621 if(n > SNARFSIZE-1)
622 n = SNARFSIZE-1;
623 s1 = realloc(s1, n+1);
624 if (!s1)
625 exit(EXIT_FAILURE);
626 s1[n] = 0;
627 snarflen = n;
628 outTs(Tsetsnarf, n);
629 if(n>0 && write(1, s1, n)!=n)
630 exit(EXIT_FAILURE);
631 free(s1);
632 }else
633 outTs(Tsetsnarf, 0);
634 free(s2);
635 cursorswitch(cursor);
636 }
637
638 void
639 hgrow(int m, int64_t a, int64_t new, bool req)
640 {
641 int i;
642 Flayer *l;
643 Text *t = whichtext(m);
644 int64_t o, b;
645
646 if(new <= 0)
647 panic("hgrow");
648 rresize(&t->rasp, a, 0L, new);
649 for(l = &t->l[0], i = 0; i<NL; i++, l++){
650 if(l->textfn == 0)
651 continue;
652 o = l->origin;
653 b = a-o-rmissing(&t->rasp, o, a);
654 if(a < o)
655 l->origin+=new;
656 if(a < l->p0)
657 l->p0+=new;
658 if(a < l->p1)
659 l->p1+=new;
660 /* must prevent b temporarily becoming unsigned */
661 if(!req || a<o || (b>0 && b>l->f.nchars) ||
662 (l->f.nchars==0 && a-o>0))
663 continue;
664 if(new>TBLOCKSIZE)
665 new = TBLOCKSIZE;
666 outTsls(Trequest, m, a, (int)new);
667 t->lock++;
668 req = false;
669 }
670 }
671
672 int
673 hdata1(Text *t, int64_t a, wchar_t *r, int len)
674 {
675 int i;
676 Flayer *l;
677 int64_t o, b;
678
679 for(l = &t->l[0], i=0; i<NL; i++, l++){
680 if(l->textfn==0)
681 continue;
682 o = l->origin;
683 b = a-o-rmissing(&t->rasp, o, a);
684 /* must prevent b temporarily becoming unsigned */
685 if(a<o || (b>0 && b>l->f.nchars))
686 continue;
687 flinsert(l, r, r+len, o+b);
688 }
689 rdata(&t->rasp, a, a+len, r);
690 rclean(&t->rasp);
691 return len;
692 }
693
694 int
695 hdata(int m, int64_t a, uint8_t *s, int len)
696 {
697 int i, w;
698 Text *t = whichtext(m);
699 wchar_t buf[DATASIZE], *r;
700
701 if(t->lock)
702 --t->lock;
703 if(len == 0)
704 return 0;
705 r = buf;
706 for(i=0; i<len; i+=w,s+=w)
707 w = chartorune(r++, (char*)s);
708 return hdata1(t, a, buf, r-buf);
709 }
710
711 int
712 hdatarune(int m, int64_t a, wchar_t *r, int len)
713 {
714 Text *t = whichtext(m);
715
716 if(t->lock)
717 --t->lock;
718 if(len == 0)
719 return 0;
720 return hdata1(t, a, r, len);
721 }
722
723 void
724 hcut(int m, int64_t a, int64_t old)
725 {
726 Flayer *l;
727 Text *t = whichtext(m);
728 int i;
729 int64_t o, b;
730
731 if(t->lock)
732 --t->lock;
733 for(l = &t->l[0], i = 0; i<NL; i++, l++){
734 if(l->textfn == 0)
735 continue;
736 o = l->origin;
737 b = a-o-rmissing(&t->rasp, o, a);
738 /* must prevent b temporarily becoming unsigned */
739 if((b<0 || b<l->f.nchars) && a+old>=o){
740 fldelete(l, b<0? o : o+b,
741 a+old-rmissing(&t->rasp, o, a+old));
742 }
743 if(a+old<o)
744 l->origin-=old;
745 else if(a<=o)
746 l->origin = a;
747 if(a+old<l->p0)
748 l->p0-=old;
749 else if(a<=l->p0)
750 l->p0 = a;
751 if(a+old<l->p1)
752 l->p1-=old;
753 else if(a<=l->p1)
754 l->p1 = a;
755 }
756 rresize(&t->rasp, a, old, 0L);
757 rclean(&t->rasp);
758 }
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.