22 long modified = 0; /* strange lookahead for menus */
28 threadmain(int argc, char *argv[])
36 * sam is talking to us on fd 0 and 1.
37 * move these elsewhere so that if we accidentally
38 * use 0 and 1 in other code, nothing bad happens.
46 open("/dev/null", OREAD);
49 getscreen(argc, argv);
52 scratch = alloc(100*RUNESIZE);
55 r.max.y = r.min.y+Dy(r)/5;
56 flstart(screen->clipr);
58 flnew(&cmd.l[0], gettext, 1, &cmd);
59 flinit(&cmd.l[0], r, font, cmdcols);
63 outTs(Tversion, VERSION);
64 startnewfile(Tstartcmdfile, &cmd);
67 for(;;got = waitforio()){
68 if(hasunlocked && RESIZED())
73 for(i=0; cmd.l[i].textfn==0; i++)
76 flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);
79 if(got&(1<<RKeyboard))
81 type(which, RKeyboard);
85 if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){
89 nwhich = flwhich(mousep->xy);
90 scr = which && ptinrect(mousep->xy, which->scroll);
93 if(mousep->buttons&1){
100 t=(Text *)which->user1;
102 outTsl(Tdclick, t->tag, which->p0);
108 }else if((mousep->buttons&2) && which){
113 }else if((mousep->buttons&4)){
130 flresize(screen->clipr);
131 for(i = 0; i<nname; i++)
133 hcheck(text[i]->tag);
148 t = (Text *)nw->user1;
149 t->front = nw-&t->l[0];
159 Text *t=(Text *)l->user1;
162 m = whichmenu(t->tag);
168 current(flwhich(Pt(0, 0)));
176 }else if(l == &t->l[t->front]){
177 for(m=0; m<NL; m++) /* find one; any one will do */
190 for(i = 0; i<NL; i++)
191 if(t->l[i].textfn==0)
197 duplicate(Flayer *l, Rectangle r, Font *f, int close)
199 Text *t=(Text *)l->user1;
200 Flayer *nl = findl(t);
205 flnew(nl, gettext, l->user0, (char *)t);
206 flinit(nl, r, f, l->f.cols);
207 nl->origin = l->origin;
208 rp = (*l->textfn)(l, l->f.nchars, &n);
209 flinsert(nl, rp, rp+n, l->origin);
210 flsetselect(nl, l->p0, l->p1);
220 setcursor(mousectl, cursor);
226 while(((mousep->buttons&7)!=0) != updown)
236 *rp = getrect(3, mousectl);
237 if(rp->max.x && rp->max.x-rp->min.x<=5 && rp->max.y-rp->min.y<=5){
239 r = cmd.l[cmd.front].entire;
244 else if (p.y >= r.max.y)
248 else if (p.x >= r.max.x)
252 return rectclip(rp, screen->r) &&
253 rp->max.x-rp->min.x>100 && rp->max.y-rp->min.y>40;
257 snarf(Text *t, int w)
259 Flayer *l = &t->l[w];
262 snarflen = l->p1-l->p0;
263 outTsll(Tsnarf, t->tag, l->p0, l->p1);
268 cut(Text *t, int w, int save, int check)
282 outTsll(Tcut, t->tag, p0, p1);
283 flsetselect(l, p0, p0);
285 hcut(t->tag, p0, p1-p0);
291 paste(Text *t, int w)
296 outTsl(Tpaste, t->tag, t->l[w].p0);
301 scrorigin(Flayer *l, int but, long p0)
303 Text *t=(Text *)l->user1;
307 outTsll(Torigin, t->tag, l->origin, p0);
310 outTsll(Torigin, t->tag, p0, 1L);
321 * Hard to get absolutely right. Use what we know about ASCII
322 * and assume anything above the Latin control characters is
323 * potentially an alphanumeric.
327 if(0x7F<=c && c<=0xA0)
329 if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
335 raspc(Rasp *r, long p)
338 rload(r, p, p+1, &n);
345 ctlw(Rasp *r, long o, long p)
351 if(raspc(r, p)=='\n')
353 for(; p>=o && !alnum(c=raspc(r, p)); --p)
356 for(; p>o && alnum(raspc(r, p-1)); --p)
362 ctlu(Rasp *r, long o, long p)
366 if(raspc(r, p)=='\n')
368 for(; p-1>=o && raspc(r, p-1)!='\n'; --p)
374 center(Flayer *l, long a)
379 if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
380 if(a > t->rasp.nrunes)
382 outTsll(Torigin, t->tag, a, 2L);
389 onethird(Flayer *l, long a)
396 if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
397 if(a > t->rasp.nrunes)
399 s = insetrect(l->scroll, 1);
400 lines = ((s.max.y-s.min.y)/l->f.font->height+1)/3;
403 outTsll(Torigin, t->tag, a, lines);
410 flushtyping(int clearesc)
417 if(typestart == typeend) {
424 rload(&t->rasp, typestart, typeend, &n);
426 if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){
430 outTslS(Ttype, t->tag, typestart, scratch);
435 #define SCROLLKEY Kdown
436 #define BACKSCROLLKEY Kup
438 #define HOMEKEY Khome
441 #define PAGEDOWN Kpgdown
442 #define LEFTARROW Kleft
443 #define RIGHTARROW Kright
448 return c==SCROLLKEY || c==BACKSCROLLKEY
449 || c==LEFTARROW || c==RIGHTARROW
450 || c==HOMEKEY || c==ENDKEY
451 || c==PAGEUP || c==PAGEDOWN;
455 type(Flayer *l, int res) /* what a bloody mess this is */
457 Text *t = (Text *)l->user1;
466 scrollkey = nontypingkey(qpeekc()); /* ICK */
468 if(hostlock || t->lock){
473 if(a!=l->p1 && !scrollkey){
475 cut(t, t->front, 1, 1);
476 return; /* it may now be locked */
479 while((c = kbdchar())>0){
480 if(res == RKeyboard){
481 if(nontypingkey(c) || c==ESC)
483 /* backspace, ctrl-u, ctrl-w, del */
484 if(c=='\b' || c==0x15 || c==0x17 || c==0x7F){
490 if(c == '\n' || p >= buf+sizeof(buf)/sizeof(buf[0]))
498 hgrow(t->tag, a, p-buf, 0);
499 t->lock++; /* pretend we Trequest'ed for hdatarune*/
500 hdatarune(t->tag, a, buf, p-buf);
505 if(c=='\n' || typeend-typestart>100)
509 if(c==SCROLLKEY || c==PAGEDOWN){
511 center(l, l->origin+l->f.nchars+1);
512 }else if(c==BACKSCROLLKEY || c==PAGEUP){
514 a0 = l->origin-l->f.nchars;
518 }else if(c == RIGHTARROW){
521 if(a0 < t->rasp.nrunes)
523 flsetselect(l, a0, a0);
525 }else if(c == LEFTARROW){
530 flsetselect(l, a0, a0);
532 }else if(c == HOMEKEY){
535 }else if(c == ENDKEY){
537 center(l, t->rasp.nrunes);
538 }else if(backspacing && !hostlock){
539 /* backspacing immediately after outcmd(): sorry */
540 if(l->f.p0>0 && a>0){
546 case 0x15: /* ctrl-u */
547 l->p0 = ctlu(&t->rasp, l->origin, a);
549 case 0x17: /* ctrl-w */
550 l->p0 = ctlw(&t->rasp, l->origin, a);
555 /* cut locally if possible */
556 if(typestart<=l->p0 && l->p1<=typeend){
557 t->lock++; /* to call hcut */
558 hcut(t->tag, l->p0, l->p1-l->p0);
559 /* hcheck is local because we know rasp is contiguous */
563 cut(t, t->front, 0, 1);
569 if(typestart >= l->p0)
572 if(typestart == typeend){
580 if(c==ESC && typeesc>=0){
585 for(l=t->l; l<&t->l[NL]; l++)
587 flsetselect(l, l->p0, l->p1);
595 outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
605 panic1(Display *d, char *s)
607 fprint(2, "samterm:panic: ");
613 gettext(Flayer *l, long n, ulong *np)
618 rload(&t->rasp, l->origin, l->origin+n, np);
625 return ((Text *)l->user1)->rasp.nrunes;