12 int mainstacksize = 16*1024;
24 long modified = 0; /* strange lookahead for menus */
32 threadmain(int argc, char *argv[])
34 int i, got, nclick, scr, chord;
40 getscreen(argc, argv);
43 scratch = alloc(100*RUNESIZE);
46 r.max.y = r.min.y+Dy(r)/5;
47 flstart(screen->clipr);
49 flnew(&cmd.l[0], gettext, 1, &cmd);
50 flinit(&cmd.l[0], r, font, cmdcols);
54 outTs(Tversion, VERSION);
55 startnewfile(Tstartcmdfile, &cmd);
59 for(;;got = waitforio()){
60 if(hasunlocked && RESIZED())
65 for(i=0; cmd.l[i].textfn==0; i++)
68 flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);
71 if(got&(1<<RKeyboard))
73 type(which, RKeyboard);
77 if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){
81 nwhich = flwhich(mousep->xy);
82 scr = which && (ptinrect(mousep->xy, which->scroll) ||
83 mousep->buttons&(8|16));
86 if((mousep->buttons&1)==0)
88 if(chord && which && which==nwhich){
89 chord |= mousep->buttons;
90 t = (Text *)which->user1;
102 }else if(mousep->buttons&(1|8)){
104 scroll(which, (mousep->buttons&8) ? 4 : 1);
105 else if(nwhich && nwhich!=which)
108 t=(Text *)which->user1;
109 nclick = flselect(which, &p);
112 outTsl(Ttclick, t->tag, p);
114 outTsl(Tdclick, t->tag, p);
118 if(mousep->buttons&1)
119 chord = mousep->buttons;
121 }else if((mousep->buttons&2) && which){
126 }else if(mousep->buttons&(4|16)){
128 scroll(which, (mousep->buttons&16) ? 5 : 3);
143 flresize(screen->clipr);
144 for(i = 0; i<nname; i++)
146 hcheck(text[i]->tag);
161 t = (Text *)nw->user1;
162 t->front = nw-&t->l[0];
172 Text *t=(Text *)l->user1;
175 m = whichmenu(t->tag);
181 current(flwhich(Pt(0, 0)));
189 }else if(l == &t->l[t->front]){
190 for(m=0; m<NL; m++) /* find one; any one will do */
203 for(i = 0; i<NL; i++)
204 if(t->l[i].textfn==0)
210 duplicate(Flayer *l, Rectangle r, Font *f, int close)
212 Text *t=(Text *)l->user1;
213 Flayer *nl = findl(t);
218 flnew(nl, gettext, l->user0, (char *)t);
219 flinit(nl, r, f, l->f.cols);
220 nl->origin = l->origin;
221 rp = (*l->textfn)(l, l->f.nchars, &n);
222 flinsert(nl, rp, rp+n, l->origin);
223 flsetselect(nl, l->p0, l->p1);
233 setcursor(mousectl, cursor);
239 while(((mousep->buttons&7)!=0) != updown)
249 *rp = getrect(3, mousectl);
250 if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){
252 r = cmd.l[cmd.front].entire;
257 else if (p.y >= r.max.y)
261 else if (p.x >= r.max.x)
265 return rectclip(rp, screen->r) &&
266 rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40;
270 snarf(Text *t, int w)
272 Flayer *l = &t->l[w];
275 snarflen = l->p1-l->p0;
276 outTsll(Tsnarf, t->tag, l->p0, l->p1);
281 cut(Text *t, int w, int save, int check)
295 outTsll(Tcut, t->tag, p0, p1);
296 flsetselect(l, p0, p0);
298 hcut(t->tag, p0, p1-p0);
304 paste(Text *t, int w)
309 outTsl(Tpaste, t->tag, t->l[w].p0);
314 scrorigin(Flayer *l, int but, long p0)
316 Text *t=(Text *)l->user1;
318 if(t->tag == Untagged)
323 outTsll(Torigin, t->tag, l->origin, p0);
326 outTsll(Torigin, t->tag, p0, 1L);
337 * Hard to get absolutely right. Use what we know about ASCII
338 * and assume anything above the Latin control characters is
339 * potentially an alphanumeric.
343 if(0x7F<=c && c<=0xA0)
345 if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
351 raspc(Rasp *r, long p)
354 rload(r, p, p+1, &n);
361 getcol(Rasp *r, long p)
365 for(col = 0; p > 0 && raspc(r, p-1)!='\n'; p--, col++)
371 del(Rasp *r, long o, long p)
377 if(!spacesindent || raspc(r, p)!=' ')
379 col = getcol(r, p) + 1;
380 if((n = col % maxtab) == 0)
382 for(i = 0; p-1>=o && raspc(r, p-1)==' ' && i<n-1; --p, i++)
388 ctlw(Rasp *r, long o, long p)
394 if(raspc(r, p)=='\n')
396 for(; p>=o && !alnum(c=raspc(r, p)); --p)
399 for(; p>o && alnum(raspc(r, p-1)); --p)
405 ctlu(Rasp *r, long o, long p)
409 if(raspc(r, p)=='\n')
411 for(; p-1>=o && raspc(r, p-1)!='\n'; --p)
417 center(Flayer *l, long a)
422 if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
423 if(a > t->rasp.nrunes)
425 outTsll(Torigin, t->tag, a, 2L);
432 onethird(Flayer *l, long a)
439 if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
440 if(a > t->rasp.nrunes)
442 s = insetrect(l->scroll, 1);
443 lines = ((s.max.y-s.min.y)/l->f.font->height+1)/3;
446 outTsll(Torigin, t->tag, a, lines);
453 flushtyping(int clearesc)
460 if(typestart == typeend) {
467 rload(&t->rasp, typestart, typeend, &n);
469 if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){
473 outTslS(Ttype, t->tag, typestart, scratch);
501 type(Flayer *l, int res) /* what a bloody mess this is */
503 Text *t = (Text *)l->user1;
512 scrollkey = nontypingkey(qpeekc()); /* ICK */
514 if(hostlock || t->lock){
519 if(a!=l->p1 && !scrollkey){
521 cut(t, t->front, 1, 1);
522 return; /* it may now be locked */
525 while((c = kbdchar())>0){
526 if(res == RKeyboard){
527 if(nontypingkey(c) || c==Kesc)
529 /* backspace, ctrl-u, ctrl-w, del */
530 if(c==Kbs || c==Knack || c==Ketb || c==Kdel){
535 if(spacesindent && c == '\t'){
537 col = getcol(&t->rasp, a);
538 n = maxtab - col % maxtab;
539 for(i = 0; i < n && p < buf+nelem(buf); i++)
547 cursor = ctlu(&t->rasp, 0, a+(p-buf)-1);
548 while(p < buf+nelem(buf)){
549 ch = raspc(&t->rasp, cursor++);
550 if(ch == ' ' || ch == '\t')
556 if(c == '\n' || p >= buf+sizeof(buf)/sizeof(buf[0]))
564 hgrow(t->tag, a, p-buf, 0);
565 t->lock++; /* pretend we Trequest'ed for hdatarune*/
566 hdatarune(t->tag, a, buf, p-buf);
571 if(c=='\n' || typeend-typestart>100)
575 if(c==Kdown || c==Kpgdown){
577 center(l, l->origin+l->f.nchars+1);
578 /* backspacing immediately after outcmd(): sorry */
579 }else if(c==Kup || c==Kpgup){
581 a0 = l->origin-l->f.nchars;
585 }else if(c == Kright){
588 if(a0 < t->rasp.nrunes)
590 flsetselect(l, a0, a0);
592 }else if(c == Kleft){
597 flsetselect(l, a0, a0);
599 }else if(c == Khome){
604 center(l, t->rasp.nrunes);
605 }else if(c == Ksoh || c == Kenq){
608 while(a > 0 && raspc(&t->rasp, a-1)!='\n')
611 while(a < t->rasp.nrunes && raspc(&t->rasp, a)!='\n')
614 for(l=t->l; l<&t->l[NL]; l++)
616 flsetselect(l, l->p0, l->p1);
617 }else if(backspacing && !hostlock){
618 /* backspacing immediately after outcmd(): sorry */
619 if(l->f.p0>0 && a>0){
623 l->p0 = del(&t->rasp, l->origin, a);
625 case Knack: /* ctrl-u */
626 l->p0 = ctlu(&t->rasp, l->origin, a);
628 case Ketb: /* ctrl-w */
629 l->p0 = ctlw(&t->rasp, l->origin, a);
634 /* cut locally if possible */
635 if(typestart<=l->p0 && l->p1<=typeend){
636 t->lock++; /* to call hcut */
637 hcut(t->tag, l->p0, l->p1-l->p0);
638 /* hcheck is local because we know rasp is contiguous */
642 cut(t, t->front, 0, 1);
648 if(typestart >= l->p0)
651 if(typestart == typeend){
660 for(l=t->l; l->textfn==0; l++)
665 flsetselect(l, a, a);
675 t = (Text*)work->user1;
677 for(i=t->front; t->nwin>1 && (i = (i+1)%NL) != t->front; )
678 if(t->l[i].textfn != 0){
684 if(c==Kesc && typeesc>=0){
689 for(l=t->l; l<&t->l[NL]; l++)
691 flsetselect(l, l->p0, l->p1);
699 outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
709 panic1(Display*, char *s)
711 fprint(2, "samterm:panic: ");
717 gettext(Flayer *l, long n, ulong *np)
722 rload(&t->rasp, l->origin, l->origin+n, np);
729 return ((Text *)l->user1)->rasp.nrunes;