22 long modified = 0; /* strange lookahead for menus */
29 threadmain(int argc, char *argv[])
31 int i, got, scr, chord;
36 getscreen(argc, argv);
39 scratch = alloc(100*RUNESIZE);
42 r.max.y = r.min.y+Dy(r)/5;
43 flstart(screen->clipr);
45 flnew(&cmd.l[0], gettext, 1, &cmd);
46 flinit(&cmd.l[0], r, font, cmdcols);
50 outTs(Tversion, VERSION);
51 startnewfile(Tstartcmdfile, &cmd);
55 for(;;got = waitforio()){
56 if(hasunlocked && RESIZED())
61 for(i=0; cmd.l[i].textfn==0; i++)
64 flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);
67 if(got&(1<<RKeyboard))
69 type(which, RKeyboard);
73 if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){
77 nwhich = flwhich(mousep->xy);
78 scr = which && (ptinrect(mousep->xy, which->scroll) ||
79 mousep->buttons&(8|16));
82 if((mousep->buttons&1)==0)
84 if(chord && which && which==nwhich){
85 chord |= mousep->buttons;
86 t = (Text *)which->user1;
98 }else if(mousep->buttons&(1|8)){
103 scroll(which, (mousep->buttons&8) ? 4 : 1);
105 t=(Text *)which->user1;
107 outTsl(Tdclick, t->tag, which->p0);
111 if(mousep->buttons&1)
112 chord = mousep->buttons;
115 }else if((mousep->buttons&2) && which){
120 }else if(mousep->buttons&(4|16)){
122 scroll(which, (mousep->buttons&16) ? 5 : 3);
137 flresize(screen->clipr);
138 for(i = 0; i<nname; i++)
140 hcheck(text[i]->tag);
155 t = (Text *)nw->user1;
156 t->front = nw-&t->l[0];
166 Text *t=(Text *)l->user1;
169 m = whichmenu(t->tag);
175 current(flwhich(Pt(0, 0)));
183 }else if(l == &t->l[t->front]){
184 for(m=0; m<NL; m++) /* find one; any one will do */
197 for(i = 0; i<NL; i++)
198 if(t->l[i].textfn==0)
204 duplicate(Flayer *l, Rectangle r, Font *f, int close)
206 Text *t=(Text *)l->user1;
207 Flayer *nl = findl(t);
212 flnew(nl, gettext, l->user0, (char *)t);
213 flinit(nl, r, f, l->f.cols);
214 nl->origin = l->origin;
215 rp = (*l->textfn)(l, l->f.nchars, &n);
216 flinsert(nl, rp, rp+n, l->origin);
217 flsetselect(nl, l->p0, l->p1);
227 setcursor(mousectl, cursor);
233 while(((mousep->buttons&7)!=0) != updown)
243 *rp = getrect(3, mousectl);
244 if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){
246 r = cmd.l[cmd.front].entire;
251 else if (p.y >= r.max.y)
255 else if (p.x >= r.max.x)
259 return rectclip(rp, screen->r) &&
260 rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40;
264 snarf(Text *t, int w)
266 Flayer *l = &t->l[w];
269 snarflen = l->p1-l->p0;
270 outTsll(Tsnarf, t->tag, l->p0, l->p1);
275 cut(Text *t, int w, int save, int check)
289 outTsll(Tcut, t->tag, p0, p1);
290 flsetselect(l, p0, p0);
292 hcut(t->tag, p0, p1-p0);
298 paste(Text *t, int w)
303 outTsl(Tpaste, t->tag, t->l[w].p0);
308 scrorigin(Flayer *l, int but, long p0)
310 Text *t=(Text *)l->user1;
314 outTsll(Torigin, t->tag, l->origin, p0);
317 outTsll(Torigin, t->tag, p0, 1L);
328 * Hard to get absolutely right. Use what we know about ASCII
329 * and assume anything above the Latin control characters is
330 * potentially an alphanumeric.
334 if(0x7F<=c && c<=0xA0)
336 if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
342 raspc(Rasp *r, long p)
345 rload(r, p, p+1, &n);
352 ctlw(Rasp *r, long o, long p)
358 if(raspc(r, p)=='\n')
360 for(; p>=o && !alnum(c=raspc(r, p)); --p)
363 for(; p>o && alnum(raspc(r, p-1)); --p)
369 ctlu(Rasp *r, long o, long p)
373 if(raspc(r, p)=='\n')
375 for(; p-1>=o && raspc(r, p-1)!='\n'; --p)
381 center(Flayer *l, long a)
386 if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
387 if(a > t->rasp.nrunes)
389 outTsll(Torigin, t->tag, a, 2L);
396 onethird(Flayer *l, long a)
403 if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
404 if(a > t->rasp.nrunes)
406 s = insetrect(l->scroll, 1);
407 lines = ((s.max.y-s.min.y)/l->f.font->height+1)/3;
410 outTsll(Torigin, t->tag, a, lines);
417 flushtyping(int clearesc)
424 if(typestart == typeend) {
431 rload(&t->rasp, typestart, typeend, &n);
433 if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){
437 outTslS(Ttype, t->tag, typestart, scratch);
442 #define BACKSCROLLKEY Kup
445 #define HOMEKEY Khome
446 #define LEFTARROW Kleft
448 #define LINESTART 0x01
449 #define PAGEDOWN Kpgdown
451 #define RIGHTARROW Kright
452 #define SCROLLKEY Kdown
475 type(Flayer *l, int res) /* what a bloody mess this is */
477 Text *t = (Text *)l->user1;
486 scrollkey = nontypingkey(qpeekc()); /* ICK */
488 if(hostlock || t->lock){
493 if(a!=l->p1 && !scrollkey){
495 cut(t, t->front, 1, 1);
496 return; /* it may now be locked */
499 while((c = kbdchar())>0){
500 if(res == RKeyboard){
501 if(nontypingkey(c) || c==ESC)
503 /* backspace, ctrl-u, ctrl-w, del */
504 if(c=='\b' || c==0x15 || c==0x17 || c==0x7F){
514 cursor = ctlu(&t->rasp, 0, a+(p-buf)-1);
515 while(p < buf+nelem(buf)){
516 ch = raspc(&t->rasp, cursor++);
517 if(ch == ' ' || ch == '\t')
523 if(c == '\n' || p >= buf+sizeof(buf)/sizeof(buf[0]))
531 hgrow(t->tag, a, p-buf, 0);
532 t->lock++; /* pretend we Trequest'ed for hdatarune*/
533 hdatarune(t->tag, a, buf, p-buf);
538 if(c=='\n' || typeend-typestart>100)
542 if(c==SCROLLKEY || c==PAGEDOWN){
544 center(l, l->origin+l->f.nchars+1);
545 /* backspacing immediately after outcmd(): sorry */
546 }else if(c==BACKSCROLLKEY || c==PAGEUP){
548 a0 = l->origin-l->f.nchars;
552 }else if(c == RIGHTARROW){
555 if(a0 < t->rasp.nrunes)
557 flsetselect(l, a0, a0);
559 }else if(c == LEFTARROW){
564 flsetselect(l, a0, a0);
566 }else if(c == HOMEKEY){
569 }else if(c == ENDKEY){
571 center(l, t->rasp.nrunes);
572 }else if(c == LINESTART || c == LINEEND){
575 while(a > 0 && raspc(&t->rasp, a-1)!='\n')
578 while(a < t->rasp.nrunes && raspc(&t->rasp, a)!='\n')
581 for(l=t->l; l<&t->l[NL]; l++)
583 flsetselect(l, l->p0, l->p1);
584 }else if(backspacing && !hostlock){
585 /* backspacing immediately after outcmd(): sorry */
586 if(l->f.p0>0 && a>0){
592 case 0x15: /* ctrl-u */
593 l->p0 = ctlu(&t->rasp, l->origin, a);
595 case 0x17: /* ctrl-w */
596 l->p0 = ctlw(&t->rasp, l->origin, a);
601 /* cut locally if possible */
602 if(typestart<=l->p0 && l->p1<=typeend){
603 t->lock++; /* to call hcut */
604 hcut(t->tag, l->p0, l->p1-l->p0);
605 /* hcheck is local because we know rasp is contiguous */
609 cut(t, t->front, 0, 1);
615 if(typestart >= l->p0)
618 if(typestart == typeend){
626 if(c==ESC && typeesc>=0){
631 for(l=t->l; l<&t->l[NL]; l++)
633 flsetselect(l, l->p0, l->p1);
641 outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
651 panic1(Display*, char *s)
653 fprint(2, "samterm:panic: ");
659 gettext(Flayer *l, long n, ulong *np)
664 rload(&t->rasp, l->origin, l->origin+n, np);
671 return ((Text *)l->user1)->rasp.nrunes;