ref: e35c28fbc9d40494cbda9a2687924090231181ce
parent: 5e14b38c8f501895068c5ee37ebf235e9c8e2351
author: Aidan K. Wiggins <akw@oneiri.one>
date: Tue Jan 21 17:15:25 EST 2025
Implement scroll-select; up/down-arrow go by line now, as are pg-up/down by line now. Also attempts to not scroll past the end of the file. Refactors and stylistic changes. Will cleanup further later.
--- a/samterm/flayer.c
+++ b/samterm/flayer.c
@@ -78,7 +78,9 @@
l->visible = All;
l->origin = l->p0 = l->p1 = 0;
frinit(&l->f, insetrect(flrect(l, r), FLMARGIN), ft, screen, cols);
+ l->f.scroll = frscroll;
l->f.maxtab = maxtab*stringwidth(ft, "0");
+ l->width = (l->f.r.max.x - l->f.r.min.x)/l->f.font->width;
newvisibilities(1);
draw(screen, l->entire, l->f.cols[BACK], nil, ZP);
scrdraw(l, 0L);
@@ -225,7 +227,8 @@
flinsert(Flayer *l, Rune *sp, Rune *ep, long p0)
{
if(flprepare(l)){
- frinsert(&l->f, sp, ep, p0-l->origin);
+ p0 -= l->origin;
+ frinsert(&l->f, sp, ep, p0 < 0? 0: p0);
scrdraw(l, scrtotal(l));
if(l->visible==Some)
flrefresh(l, l->entire, 0);
@@ -249,6 +252,42 @@
}
}
+static int sel;
+static int scrled;
+
+/*
+ * XXX: This is a functional fiasco, we must carefully poll for new i/o.
+ * Operates in conjunction with request().
+ */
+void
+flscroll(Flayer *l, int n)
+{
+ Frame *f = &l->f;
+
+ scrled = 1;
+ if(waitforio(0))
+ rcv();
+ if(nbrecv(mousectl->c, &mousectl->Mouse) < 0)
+ panic("mouse");
+
+ if(n < 0){
+ if(sel > l->origin+f->p0)
+ flsetselect(l, l->origin+f->p0, sel);
+ else
+ flsetselect(l, sel, l->origin+f->p0);
+ }else if(n == 0){
+ sleep(25);
+ return;
+ }else{
+ if(sel >= l->origin+f->p1)
+ flsetselect(l, l->origin+f->p1, sel);
+ else
+ flsetselect(l, sel, l->origin+f->p1);
+ }
+ inscroll = 1;
+ center(l, l->origin, n);
+}
+
int
flselect(Flayer *l, ulong *p)
{
@@ -262,6 +301,7 @@
dx = abs(mousep->xy.x - clickpt.x);
dy = abs(mousep->xy.y - clickpt.y);
*p = frcharofpt(&l->f, mousep->xy) + l->origin;
+ sel = *p;
l->click = mousep->msec;
clickpt = mousep->xy;
@@ -270,9 +310,19 @@
return ++clickcount;
clickcount = 0;
+ scrled = 0;
frselect(&l->f, mousectl);
- l->p0 = l->f.p0+l->origin;
- l->p1 = l->f.p1+l->origin;
+ if(scrled){
+ /* location of mouse release */
+ int rel = frcharofpt(&l->f, mousep->xy) + l->origin;
+ if(rel < sel)
+ l->p0 = rel;
+ else
+ l->p1 = rel;
+ }else{
+ l->p0 = l->origin + l->f.p0;
+ l->p1 = l->origin + l->f.p1;
+ }
return 0;
}
@@ -279,6 +329,10 @@
void
flsetselect(Flayer *l, long p0, long p1)
{
+ int fd = open("/usr/glenda/samlog", OWRITE);
+ fprint(fd, "p0 == %ld p1 == %ld\n", p0, p1);
+ close(fd);
+
ulong fp0, fp1;
if(l->visible==None || !flprepare(l)){
@@ -315,7 +369,7 @@
Refresh:
l->f.p0 = fp0;
l->f.p1 = fp1;
- if(l->visible==Some)
+ if(l->visible == Some)
flrefresh(l, l->entire, 0);
}
@@ -380,6 +434,7 @@
f->b = 0;
if(l->visible!=None)
frclear(f, 0);
+ l->width = (f->r.max.x - f->r.min.x)/f->font->width;
}
if(!rectclip(&r, dr))
panic("flresize");
@@ -454,7 +509,7 @@
Rectangle s;
Top:
- if((t=llist[i++]) == l){
+ if((t = llist[i++]) == l){
if(!justvis)
draw(screen, r, l->f.b, nil, r.min);
somevis = 1;
@@ -461,25 +516,25 @@
}else{
if(!rectXrect(t->entire, r))
goto Top; /* avoid stacking unnecessarily */
- if(t->entire.min.x>r.min.x){
+ if(t->entire.min.x > r.min.x){
s = r;
s.max.x = t->entire.min.x;
flrefresh(l, s, i);
r.min.x = t->entire.min.x;
}
- if(t->entire.min.y>r.min.y){
+ if(t->entire.min.y > r.min.y){
s = r;
s.max.y = t->entire.min.y;
flrefresh(l, s, i);
r.min.y = t->entire.min.y;
}
- if(t->entire.max.x<r.max.x){
+ if(t->entire.max.x < r.max.x){
s = r;
s.min.x = t->entire.max.x;
flrefresh(l, s, i);
r.max.x = t->entire.max.x;
}
- if(t->entire.max.y<r.max.y){
+ if(t->entire.max.y < r.max.y){
s = r;
s.min.y = t->entire.max.y;
flrefresh(l, s, i);
--- a/samterm/flayer.h
+++ b/samterm/flayer.h
@@ -23,6 +23,7 @@
Rectangle scroll;
Rectangle lastsr; /* geometry of scrollbar when last drawn */
Vis visible;
+ ulong width; /* # of chars on a line */
};
void flborder(Flayer*, int);
@@ -36,6 +37,7 @@
Rectangle flrect(Flayer*, Rectangle);
void flrefresh(Flayer*, Rectangle, int);
void flresize(Rectangle);
+void flscroll(Flayer*, int);
int flselect(Flayer*, ulong*);
void flsetselect(Flayer*, long, long);
void flstart(Rectangle);
--- a/samterm/io.c
+++ b/samterm/io.c
@@ -31,45 +31,42 @@
initio(void)
{
threadsetname("main");
+
mousectl = initmouse(nil, display->image);
- if(mousectl == nil){
+ if(!mousectl){
fprint(2, "samterm: mouse init failed: %r\n");
threadexitsall("mouse");
}
mousep = mousectl;
+
keyboardctl = initkeyboard(nil);
- if(keyboardctl == nil){
+ if(!keyboardctl){
fprint(2, "samterm: keyboard init failed: %r\n");
threadexitsall("kbd");
}
+
hoststart();
plumbstart();
}
void
-getmouse(void)
-{
- if(readmouse(mousectl) < 0)
- panic("mouse");
-}
-
-void
mouseunblock(void)
{
- got &= ~(1<<RMouse);
+ got &= ~(1 << RMouse);
}
void
kbdblock(void)
{ /* ca suffit */
- block = (1<<RKeyboard)|(1<<RPlumb);
+ block = (1 << RKeyboard) | (1 << RPlumb);
}
int
button(int but)
{
- getmouse();
- return mousep->buttons&(1<<(but-1));
+ if(readmouse(mousectl) < 0)
+ panic("mouse");
+ return mousep->buttons & (1 << (but - 1));
}
void
@@ -76,16 +73,16 @@
externload(int i)
{
plumbbase = malloc(plumbbuf[i].n);
- if(plumbbase == 0)
+ if(!plumbbase)
return;
memmove(plumbbase, plumbbuf[i].data, plumbbuf[i].n);
plumbp = plumbbase;
plumbstop = plumbbase + plumbbuf[i].n;
- got |= 1<<RPlumb;
+ got |= 1 << RPlumb;
}
int
-waitforio(void)
+waitforio(int blk)
{
Alt alts[NRes+1];
Rune r;
@@ -93,38 +90,37 @@
ulong type;
again:
-
alts[RPlumb].c = plumbc;
alts[RPlumb].v = &i;
alts[RPlumb].op = CHANRCV;
- if((block & (1<<RPlumb)) || plumbc == nil)
+ if((block & (1 << RPlumb)) || plumbc == nil)
alts[RPlumb].op = CHANNOP;
alts[RHost].c = hostc;
alts[RHost].v = &i;
alts[RHost].op = CHANRCV;
- if(block & (1<<RHost))
+ if(block & (1 << RHost))
alts[RHost].op = CHANNOP;
alts[RKeyboard].c = keyboardctl->c;
alts[RKeyboard].v = &r;
alts[RKeyboard].op = CHANRCV;
- if(block & (1<<RKeyboard))
+ if(block & (1 << RKeyboard))
alts[RKeyboard].op = CHANNOP;
alts[RMouse].c = mousectl->c;
alts[RMouse].v = &mousectl->Mouse;
alts[RMouse].op = CHANRCV;
- if(block & (1<<RMouse))
+ if(block & (1 << RMouse))
alts[RMouse].op = CHANNOP;
alts[RResize].c = mousectl->resizec;
alts[RResize].v = nil;
alts[RResize].op = CHANRCV;
- if(block & (1<<RResize))
+ if(block & (1 << RResize))
alts[RResize].op = CHANNOP;
- alts[NRes].op = CHANEND;
+ alts[NRes].op = blk? CHANEND : CHANNOBLK;
if(got & ~block)
return got & ~block;
@@ -135,7 +131,8 @@
case RHost:
hostp = hostbuf[i].data;
hoststop = hostbuf[i].data + hostbuf[i].n;
- block = 0;
+ if(blk)
+ block = 0;
break;
case RPlumb:
externload(i);
@@ -148,24 +145,43 @@
case RResize:
resized = 1;
/* do the resize in line if we've finished initializing and we're not in a blocking state */
- if(hasunlocked && block==0 && RESIZED())
+ if(hasunlocked && block == 0 && RESIZED())
resize();
goto again;
}
- got |= 1<<type;
- return got;
+ return got |= 1 << type;
}
+void
+frscroll(Frame *, int n)
+{
+ int b;
+
+ b = block;
+ block = ~(1 << RHost);
+ got = 0;
+ flscroll(which, n);
+ block = b;
+ got = 0;
+}
+
+void
+setblock0(void)
+{
+ block = ~(1 << RHost);
+}
+
int
rcvchar(void)
{
int c;
- if(!(got & (1<<RHost)))
- return -1;
- c = *hostp++;
- if(hostp == hoststop)
- got &= ~(1<<RHost);
+ c = -1;
+ if(got & (1 << RHost)){
+ c = *hostp++;
+ if(hostp == hoststop)
+ got &= ~(1 << RHost);
+ }
return c;
}
@@ -173,7 +189,7 @@
rcvstring(void)
{
*hoststop = 0;
- got &= ~(1<<RHost);
+ got &= ~(1 << RHost);
return (char*)hostp;
}
@@ -183,9 +199,8 @@
int c;
while((c = rcvchar()) == -1){
- block = ~(1<<RHost);
- waitforio();
- block = 0;
+ block = ~(1 << RHost);
+ waitforio(1);
}
return c;
}
@@ -195,11 +210,11 @@
{
Rune r;
- loop:
- if(got & ((1<<RPlumb) & ~block)){
+loop:
+ if(got & ((1 << RPlumb) & ~block)){
plumbp += chartorune(&r, (char*)plumbp);
if(plumbp >= plumbstop){
- got &= ~(1<<RPlumb);
+ got &= ~(1 << RPlumb);
free(plumbbase);
}
if(r == 0)
@@ -210,6 +225,7 @@
}
int kpeekc = -1;
+
int
ecankbd(void)
{
@@ -250,13 +266,13 @@
c = externchar();
if(c > 0)
return c;
- if(got & (1<<RKeyboard)){
+ if(got & (1 << RKeyboard)){
c = kbdc;
kbdc = -1;
got &= ~(1<<RKeyboard);
return c;
}
- while(plumbc!=nil && nbrecv(plumbc, &i)>0){
+ while(plumbc && nbrecv(plumbc, &i) > 0){
externload(i);
c = externchar();
if(c > 0)
--- a/samterm/main.c
+++ b/samterm/main.c
@@ -28,6 +28,8 @@
int autoindent;
int spacesindent;
+void setblock0(void);
+
void
threadmain(int argc, char *argv[])
{
@@ -43,7 +45,7 @@
scratch = alloc(100*RUNESIZE);
nscralloc = 100;
r = screen->r;
- r.max.y = r.min.y+Dy(r)/5;
+ r.max.y = r.min.y + Dy(r)/5;
flstart(screen->clipr);
rinit(&cmd.rasp);
flnew(&cmd.l[0], gettext, 1, &cmd);
@@ -56,56 +58,57 @@
got = 0;
chord = 0;
- for(;;got = waitforio()){
+ for(;;got = waitforio(1)){
if(hasunlocked && RESIZED())
resize();
- if(got&(1<<RHost))
+ if(got & (1 << RHost))
rcv();
- if(got&(1<<RPlumb)){
- for(i=0; cmd.l[i].textfn==0; i++)
+ if(got & (1 << RPlumb)){
+ for(i = 0; cmd.l[i].textfn == 0; i++)
;
current(&cmd.l[i]);
flsetselect(which, cmd.rasp.nrunes, cmd.rasp.nrunes);
type(which, RPlumb);
}
- if(got&(1<<RKeyboard))
+ if(got & (1 << RKeyboard)){
if(which)
type(which, RKeyboard);
else
kbdblock();
- if(got&(1<<RMouse)){
- if(hostlock==2 || !ptinrect(mousep->xy, screen->r)){
+ }
+ if(got & (1 << RMouse)){
+ if(hostlock == 2 || !ptinrect(mousep->xy, screen->r)){
mouseunblock();
continue;
}
nwhich = flwhich(mousep->xy);
scr = which && (ptinrect(mousep->xy, which->scroll) ||
- mousep->buttons&(8|16));
+ mousep->buttons & (8|16));
if(mousep->buttons)
flushtyping(1);
- if((mousep->buttons&1)==0)
+ if((mousep->buttons & 1) == 0)
chord = 0;
- if(chord && which && which==nwhich){
+ if(chord && which && which == nwhich){
chord |= mousep->buttons;
- t = (Text *)which->user1;
+ t = which->user1;
if(!t->lock){
int w = which-t->l;
- if(chord&2){
+ if(chord & 2){
cut(t, w, 1, 1);
chord &= ~2;
}
- if(chord&4){
+ if(chord & 4){
paste(t, w);
chord &= ~4;
}
}
- }else if(mousep->buttons&(1|8)){
+ }else if(mousep->buttons & (1|8)){
if(scr)
- scroll(which, (mousep->buttons&8) ? 4 : 1);
- else if(nwhich && nwhich!=which)
+ scroll(which, (mousep->buttons & 8) ? 4 : 1);
+ else if(nwhich && nwhich != which)
current(nwhich);
- else{
- t=(Text *)which->user1;
+ else if(ptinrect(mousep->xy, which->f.r)){
+ t = which->user1;
nclick = flselect(which, &p);
if(nclick > 0){
if(nclick > 1)
@@ -113,19 +116,19 @@
else
outTsl(Tdclick, t->tag, p);
t->lock++;
- }else if(t!=&cmd)
+ }else if(t != &cmd)
outcmd();
- if(mousep->buttons&1)
+ if(mousep->buttons & 1)
chord = mousep->buttons;
}
- }else if((mousep->buttons&2) && which){
+ }else if((mousep->buttons & 2) && which){
if(scr)
scroll(which, 2);
else
menu2hit();
- }else if(mousep->buttons&(4|16)){
+ }else if(mousep->buttons & (4|16)){
if(scr)
- scroll(which, (mousep->buttons&16) ? 5 : 3);
+ scroll(which, (mousep->buttons & 16)? 5 : 3);
else
menu3hit();
}
@@ -134,7 +137,6 @@
}
}
-
void
resize(void)
{
@@ -141,7 +143,7 @@
int i;
flresize(screen->clipr);
- for(i = 0; i<nname; i++)
+ for(i = 0; i < nname; i++)
if(text[i])
hcheck(text[i]->tag);
}
@@ -158,8 +160,8 @@
flupfront(nw);
flborder(nw, 1);
buttons(Up);
- t = (Text *)nw->user1;
- t->front = nw-&t->l[0];
+ t = nw->user1;
+ t->front = nw - t->l;
if(t != &cmd)
work = nw;
}
@@ -169,7 +171,7 @@
void
closeup(Flayer *l)
{
- Text *t=(Text *)l->user1;
+ Text *t = l->user1;
int m;
m = whichmenu(t->tag);
@@ -187,7 +189,7 @@
free((uchar *)t);
text[m] = 0;
}else if(l == &t->l[t->front]){
- for(m=0; m<NL; m++) /* find one; any one will do */
+ for(m=0; m < NL; m++) /* find one; any one will do */
if(t->l[m].textfn){
t->front = m;
return;
@@ -196,12 +198,13 @@
}
}
-Flayer *
+Flayer*
findl(Text *t)
{
int i;
- for(i = 0; i<NL; i++)
- if(t->l[i].textfn==0)
+
+ for(i = 0; i < NL; i++)
+ if(!t->l[i].textfn)
return &t->l[i];
return 0;
}
@@ -209,7 +212,7 @@
void
duplicate(Flayer *l, Rectangle r, Font *f, int close)
{
- Text *t=(Text *)l->user1;
+ Text *t = l->user1;
Flayer *nl = findl(t);
Rune *rp;
ulong n;
@@ -236,8 +239,9 @@
void
buttons(int updown)
{
- while(((mousep->buttons&7)!=0) != updown)
- getmouse();
+ while(((mousep->buttons & 7) != 0) != updown)
+ if(readmouse(mousectl) < 0)
+ panic("mouse");
}
int
@@ -271,8 +275,8 @@
{
Flayer *l = &t->l[w];
- if(l->p1>l->p0){
- snarflen = l->p1-l->p0;
+ if(l->p1 > l->p0){
+ snarflen = l->p1 - l->p0;
outTsll(Tsnarf, t->tag, l->p0, l->p1);
}
}
@@ -282,8 +286,8 @@
{
long p0, p1;
Flayer *l;
-
l = &t->l[w];
+
p0 = l->p0;
p1 = l->p1;
if(p0 == p1)
@@ -295,7 +299,7 @@
outTsll(Tcut, t->tag, p0, p1);
flsetselect(l, p0, p0);
t->lock++;
- hcut(t->tag, p0, p1-p0);
+ hcut(t->tag, p0, p1 - p0);
if(check)
hcheck(t->tag);
}
@@ -310,47 +314,11 @@
}
}
-void
-scrorigin(Flayer *l, int but, long p0)
-{
- Text *t=(Text *)l->user1;
-
- if(t->tag == Untagged)
- return;
-
- switch(but){
- case 1:
- outTsll(Torigin, t->tag, l->origin, p0);
- break;
- case 2:
- outTsll(Torigin, t->tag, p0, 1L);
- break;
- case 3:
- horigin(t->tag,p0);
- }
-}
-
-int
-alnum(int c)
-{
- /*
- * Hard to get absolutely right. Use what we know about ASCII
- * and assume anything above the Latin control characters is
- * potentially an alphanumeric.
- */
- if(c<=' ')
- return 0;
- if(0x7F<=c && c<=0xA0)
- return 0;
- if(utfrune("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~", c))
- return 0;
- return 1;
-}
-
-int
+Rune
raspc(Rasp *r, long p)
{
ulong n;
+
rload(r, p, p+1, &n);
if(n)
return scratch[0];
@@ -360,11 +328,12 @@
int
getcol(Rasp *r, long p)
{
- int col;
+ int c;
- for(col = 0; p > 0 && raspc(r, p-1)!='\n'; p--, col++)
- ;
- return col;
+ for(c = 0; p > 0; c++)
+ if(raspc(r, --p) == '\n')
+ break;
+ return c;
}
long
@@ -374,10 +343,10 @@
if(--p < o)
return o;
- if(!spacesindent || raspc(r, p)!=' ')
+ if(!spacesindent || raspc(r, p) != ' ')
return p;
- col = getcol(r, p) + 1;
- if((n = col % maxtab) == 0)
+ col = (getcol(r, p) + 1) % maxtab;;
+ if((n = col) == 0)
n = maxtab;
for(i = 0; p-1>=o && raspc(r, p-1)==' ' && i<n-1; --p, i++)
;
@@ -393,10 +362,10 @@
return o;
if(raspc(r, p)=='\n')
return p;
- for(; p>=o && !alnum(c=raspc(r, p)); --p)
+ for(; p>=o && !isalpharune(c=raspc(r, p)); --p)
if(c=='\n')
return p+1;
- for(; p>o && alnum(raspc(r, p-1)); --p)
+ for(; p>o && isalpharune(raspc(r, p-1)); --p)
;
return p>=o? p : o;
}
@@ -406,47 +375,66 @@
{
if(--p < o)
return o;
- if(raspc(r, p)=='\n')
+ if(raspc(r, p) == '\n')
return p;
- for(; p-1>=o && raspc(r, p-1)!='\n'; --p)
+ for(; p-1 >= o && raspc(r, p-1) != '\n'; --p)
;
- return p>=o? p : o;
+ return p >= o? p : o;
}
-int
-center(Flayer *l, long a)
+void
+request(Text *t, int n, int m)
{
- Text *t;
+ int len;
- t = l->user1;
- if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
- if(a > t->rasp.nrunes)
- a = t->rasp.nrunes;
- outTsll(Torigin, t->tag, a, 2L);
- return 1;
+ while(n < m){
+ len = m - n;
+ if(len > TBLOCKSIZE)
+ len = TBLOCKSIZE;
+ outTsls(Trequest, t->tag, n, len);
+ t->lock++;
+ waitforio(1);
+ rcv();
+ n += len;
}
- return 0;
}
-int
-onethird(Flayer *l, long a)
+int inscroll;
+
+void
+center(Flayer *l, long a, long nl)
{
- Text *t;
- Rectangle s;
- long lines;
+ Frame *f = &l->f;
+ Text *t = l->user1;
+ int n;
- t = l->user1;
- if(!t->lock && (a<l->origin || l->origin+l->f.nchars<a)){
- if(a > t->rasp.nrunes)
- a = t->rasp.nrunes;
- s = insetrect(l->scroll, 1);
- lines = ((s.max.y-s.min.y)/l->f.font->height+1)/3;
- if (lines < 2)
- lines = 2;
- outTsll(Torigin, t->tag, a, lines);
- return 1;
+ if(a > t->rasp.nrunes)
+ a = t->rasp.nrunes-1;
+ if(a < 0)
+ a = 0;
+
+ if(nl == 0)
+ n = a + (--nl)*l->width;
+ else
+ n = a + nl*l->width;
+ if(n > t->rasp.nrunes)
+ n = t->rasp.nrunes-1;
+ if(n < 0)
+ n = 0;
+ if(inscroll && n != a){
+ request(t, n < a? n: a, n < a? a: n);
+ inscroll = 0;
}
- return 0;
+
+ if(nl < 0){
+ while(nl++ <= 0 && a > 0)
+ for(n = 0; n < l->width && a > 0; n++)
+ if(raspc(&t->rasp, --a) == '\n')
+ break;
+ a += a != 0;
+ }else if(nl > 0)
+ a += frcharofpt(f, Pt(f->r.min.x, 1+f->r.min.y+nl*f->font->height));
+ horigin(t->tag, a);
}
void
@@ -466,7 +454,7 @@
modified = 1;
rload(&t->rasp, typestart, typeend, &n);
scratch[n] = 0;
- if(t==&cmd && typeend==t->rasp.nrunes && scratch[typeend-typestart-1]=='\n'){
+ if(t == &cmd && typeend == t->rasp.nrunes && scratch[typeend-typestart-1] == '\n'){
setlock();
outcmd();
}
@@ -496,14 +484,13 @@
return 0;
}
-
void
type(Flayer *l, int res) /* what a bloody mess this is */
{
- Text *t = (Text *)l->user1;
+ Text *t = l->user1;
Rune buf[100];
Rune *p = buf;
- int c, backspacing;
+ int c, i;
long a, a0;
int scrollkey;
@@ -516,24 +503,22 @@
return;
}
a = l->p0;
- if(a!=l->p1 && !scrollkey){
+ if(a != l->p1 && !scrollkey){
flushtyping(1);
cut(t, t->front, 1, 1);
return; /* it may now be locked */
}
- backspacing = 0;
- while((c = kbdchar())>0){
+
+ while((c = kbdchar()) > 0){
if(res == RKeyboard){
- if(nontypingkey(c) || c==Kesc)
+ if(nontypingkey(c) || c == Kesc)
break;
/* backspace, ctrl-u, ctrl-w, del */
- if(c==Kbs || c==Knack || c==Ketb || c==Kdel){
- backspacing = 1;
+ if(c == Kbs || c == Knack || c == Ketb || c == Kdel)
break;
- }
}
if(spacesindent && c == '\t'){
- int i, col, n;
+ int col, n;
col = getcol(&t->rasp, a);
n = maxtab - col % maxtab;
for(i = 0; i < n && p < buf+nelem(buf); i++)
@@ -552,9 +537,10 @@
break;
}
}
- if(c == '\n' || p >= buf+sizeof(buf)/sizeof(buf[0]))
+ if(c == '\n' || p >= buf+nelem(buf))
break;
}
+
if(p > buf){
if(typestart < 0)
typestart = a;
@@ -561,8 +547,8 @@
if(typeesc < 0)
typeesc = a;
hgrow(t->tag, a, p-buf, 0);
- t->lock++; /* pretend we Trequest'ed for hdatarune*/
- hdatarune(t->tag, a, buf, p-buf);
+ t->lock++; /* pretend we Trequest'ed for hdata */
+ hdata(t->tag, a, buf, p-buf);
a += p-buf;
l->p0 = a;
l->p1 = a;
@@ -569,43 +555,69 @@
typeend = a;
if(c=='\n' || typeend-typestart>100)
flushtyping(0);
- onethird(l, a);
+ if(a < l->origin || a > l->origin+l->f.nchars)
+ center(l, a, -(l->f.maxlines/3));
}
- if(c==Kdown || c==Kpgdown){
+
+ switch(c){
+ case Kdown:
flushtyping(0);
- center(l, l->origin+l->f.nchars+1);
- /* backspacing immediately after outcmd(): sorry */
- }else if(c==Kup || c==Kpgup){
+ inscroll = 1;
+ center(l, l->origin, 1);
+ break;
+ case Kpgdown:
flushtyping(0);
- a0 = l->origin-l->f.nchars;
- if(a0 < 0)
- a0 = 0;
- center(l, a0);
- }else if(c == Kright){
+ inscroll = 1;
+ center(l, l->origin, l->f.maxlines);
+ break;
+ case Kup:
flushtyping(0);
- a0 = l->p1;
- if(a0 < t->rasp.nrunes)
- a0++;
- flsetselect(l, a0, a0);
- center(l, a0);
- }else if(c == Kleft){
+ inscroll = 1;
+ center(l, l->origin, -1);
+ break;
+ case Kpgup:
flushtyping(0);
+ inscroll = 1;
+ center(l, l->origin, -l->f.maxlines);
+ break;
+ /* these two need a second */
+ case Kleft:
+ flushtyping(0);
a0 = l->p0;
- if(a0 > 0)
- a0--;
+ a0 -= (l->p0 > 0);
flsetselect(l, a0, a0);
- center(l, a0);
- }else if(c == Khome){
+ if(a0-l->origin >= l->f.nchars){
+ inscroll = 1;
+ center(l, a0, -(l->f.maxlines/3));
+ }
+ break;
+ case Kright:
flushtyping(0);
- center(l, 0);
- }else if(c == Kend){
+ a0 = l->p1;
+ a0 += (a < t->rasp.nrunes);
+ flsetselect(l, a0, a0);
+ if(a0-l->origin >= l->f.nchars){
+ inscroll = 1;
+ center(l, a0, -(l->f.maxlines/3));
+ }
+ break;
+ case Khome:
flushtyping(0);
- center(l, t->rasp.nrunes);
- }else if(c == Ksoh || c == Kenq){
+ inscroll = 1;
+ center(l, 0, 0);
+ break;
+ case Kend:
+ flushtyping(0);
+ inscroll = 1;
+ center(l, t->rasp.nrunes, 0);
+ break;
+ case Ksoh:
+ case Kenq:
flushtyping(1);
if(c == Ksoh)
- while(a > 0 && raspc(&t->rasp, a-1)!='\n')
- a--;
+ while(--a > 0)
+ if(raspc(&t->rasp, a) == '\n')
+ break;
else
while(a < t->rasp.nrunes && raspc(&t->rasp, a)!='\n')
a++;
@@ -613,48 +625,55 @@
for(l=t->l; l<&t->l[NL]; l++)
if(l->textfn)
flsetselect(l, l->p0, l->p1);
- }else if(backspacing && !hostlock){
- /* backspacing immediately after outcmd(): sorry */
- if(l->f.p0>0 && a>0){
- switch(c){
- case Kbs:
- case Kdel: /* del */
- l->p0 = del(&t->rasp, l->origin, a);
- break;
- case Knack: /* ctrl-u */
- l->p0 = ctlu(&t->rasp, l->origin, a);
- break;
- case Ketb: /* ctrl-w */
- l->p0 = ctlw(&t->rasp, l->origin, a);
- break;
- }
- l->p1 = a;
- if(l->p1 != l->p0){
- /* cut locally if possible */
- if(typestart<=l->p0 && l->p1<=typeend){
- t->lock++; /* to call hcut */
- hcut(t->tag, l->p0, l->p1-l->p0);
- /* hcheck is local because we know rasp is contiguous */
- hcheck(t->tag);
- }else{
- flushtyping(0);
- cut(t, t->front, 0, 1);
+ break;
+ case Kbs:
+ case Knack:
+ case Ketb:
+ case Kdel:
+ if(!hostlock){
+ /* backspacing immediately after outcmd(): sorry */
+ if(l->f.p0>0 && a>0){
+ switch(c){
+ case Kbs:
+ case Kdel: /* del */
+ l->p0 = del(&t->rasp, l->origin, a);
+ break;
+ case Knack: /* ctrl-u */
+ l->p0 = ctlu(&t->rasp, l->origin, a);
+ break;
+ case Ketb: /* ctrl-w */
+ l->p0 = ctlw(&t->rasp, l->origin, a);
+ break;
}
- }
- if(typeesc >= l->p0)
- typeesc = l->p0;
- if(typestart >= 0){
- if(typestart >= l->p0)
- typestart = l->p0;
- typeend = l->p0;
- if(typestart == typeend){
- typestart = -1;
- typeend = -1;
- modified = 0;
+ l->p1 = a;
+ if(l->p1 != l->p0){
+ /* cut locally if possible */
+ if(typestart<=l->p0 && l->p1<=typeend){
+ t->lock++; /* to call hcut */
+ hcut(t->tag, l->p0, l->p1-l->p0);
+ /* hcheck is local because we know rasp is contiguous */
+ hcheck(t->tag);
+ }else{
+ flushtyping(0);
+ cut(t, t->front, 0, 1);
+ }
}
+ if(typeesc >= l->p0)
+ typeesc = l->p0;
+ if(typestart >= 0){
+ if(typestart >= l->p0)
+ typestart = l->p0;
+ typeend = l->p0;
+ if(typestart == typeend){
+ typestart = -1;
+ typeend = -1;
+ modified = 0;
+ }
+ }
}
}
- }else if(c == Kstx){
+ break;
+ case Kstx:
t = &cmd;
for(l=t->l; l->textfn==0; l++)
;
@@ -662,9 +681,10 @@
flushtyping(0);
a = t->rasp.nrunes;
flsetselect(l, a, a);
- center(l, a);
- }else if(c == Kbel){
- int i;
+ inscroll = 1;
+ center(l, a, 0);
+ break;
+ case Kbel:
if(work == nil)
return;
if(which != work){
@@ -674,17 +694,19 @@
t = (Text*)work->user1;
l = &t->l[t->front];
for(i=t->front; t->nwin>1 && (i = (i+1)%NL) != t->front; )
- if(t->l[i].textfn != 0){
+ if(t->l[i].textfn){
l = &t->l[i];
break;
}
current(l);
- }else{
- if(c==Kesc && typeesc>=0){
+ break;
+ case Kesc:
+ if(typeesc >= 0){
l->p0 = typeesc;
l->p1 = a;
flushtyping(1);
- }
+ } /* wet floor */
+ default:
for(l=t->l; l<&t->l[NL]; l++)
if(l->textfn)
flsetselect(l, l->p0, l->p1);
@@ -693,7 +715,8 @@
void
-outcmd(void){
+outcmd(void)
+{
if(work)
outTsll(Tworkfile, ((Text *)work->user1)->tag, work->p0, work->p1);
}
@@ -707,7 +730,7 @@
void
panic1(Display*, char *s)
{
- fprint(2, "samterm:panic: ");
+ fprint(2, "samterm: panic: ");
perror(s);
abort();
}
@@ -733,9 +756,8 @@
{
void *p;
- p = malloc(n);
- if(p == 0)
+ p = mallocz(n, 1);
+ if(!p)
panic("alloc");
- memset(p, 0, n);
return p;
}
--- a/samterm/menu.c
+++ b/samterm/menu.c
@@ -229,14 +229,13 @@
}
-Text *
+Text*
sweeptext(int new, int tag)
{
Rectangle r;
Text *t;
- if(getr(&r) && (t = malloc(sizeof(Text)))){
- memset((void*)t, 0, sizeof(Text));
+ if(getr(&r) && (t = alloc(sizeof(Text)))){
current((Flayer *)0);
flnew(&t->l[0], gettext, 0, (char *)t);
flinit(&t->l[0], r, font, maincols); /*bnl*/
@@ -259,7 +258,10 @@
{
int i;
- for(i=0; i<nname; i++)
+ if(tg == Untagged)
+ return -1;
+
+ for(i = 0; i < nname; i++)
if(tag[i] == tg)
return i;
return -1;
--- a/samterm/mesg.c
+++ b/samterm/mesg.c
@@ -38,7 +38,7 @@
static i = 0;
static int errs = 0;
- while((c=rcvchar()) != -1)
+ while((c = rcvchar()) != -1)
switch(state){
case 0:
h.type = c;
@@ -81,16 +81,16 @@
}
}
-Text *
-whichtext(int tg)
+Text*
+whichtext(int t)
{
int i;
- for(i=0; i<nname; i++)
- if(tag[i] == tg)
+ for(i = 0; i < nname; i++)
+ if(tag[i] == t)
return text[i];
panic("whichtext");
- return 0;
+ return nil;
}
void
@@ -97,11 +97,15 @@
inmesg(Hmesg type, int count)
{
Text *t;
- int i, m;
+ int i, m, w, menu;
long l;
Flayer *lp;
+ Rune buf[DATASIZE], *r;
+ int offset;
+ offset = 0;
m = inshort(0);
+ menu = whichmenu(m);
l = inlong(2);
switch(type){
case -1:
@@ -116,26 +120,26 @@
case Hbindname:
l = invlong(2); /* for 64-bit pointers */
- if((i=whichmenu(m)) < 0)
+ if(menu < 0)
break;
/* in case of a race, a bindname may already have occurred */
- if((t=whichtext(m)) == 0)
- t=(Text *)l;
+ if(!(t = whichtext(m)))
+ t = (Text*)l;
else /* let the old one win; clean up the new one */
while(((Text *)l)->nwin>0)
closeup(&((Text *)l)->l[((Text *)l)->front]);
- text[i] = t;
- text[i]->tag = m;
+ text[menu] = t;
+ text[menu]->tag = m;
break;
case Hcurrent:
- if(whichmenu(m)<0)
+ if(menu < 0)
break;
t = whichtext(m);
- i = which && ((Text *)which->user1)==&cmd && m!=cmd.tag;
- if(t==0 && (t = sweeptext(0, m))==0)
+ i = which && ((Text *)which->user1) == &cmd && m != cmd.tag;
+ if(!t && (t = sweeptext(0, m)) == 0)
break;
- if(t->l[t->front].textfn==0)
+ if(!t->l[t->front].textfn)
panic("Hcurrent");
lp = &t->l[t->front];
if(i){
@@ -147,39 +151,31 @@
break;
case Hmovname:
- if((m=whichmenu(m)) < 0)
+ if(menu < 0)
break;
- t = text[m];
- l = tag[m];
- i = name[m][0];
- text[m] = 0; /* suppress panic in menudel */
- menudel(m);
+ t = text[menu];
+ l = tag[menu];
+ i = name[menu][0];
+ text[menu] = 0; /* suppress panic in menudel */
+ menudel(menu);
if(t == &cmd)
- m = 0;
+ menu = 0;
else{
- if (nname>0 && text[0]==&cmd)
- m = 1;
- else m = 0;
- for(; m<nname; m++)
- if(strcmp((char*)indata+2, (char*)name[m]+1)<0)
+ menu = nname > 0 && text[0] == &cmd;
+ for(; menu < nname; menu++)
+ if(strcmp((char*)indata+2, (char*)name[menu]+1) < 0)
break;
}
- menuins(m, indata+2, t, i, (int)l);
+ menuins(menu, indata+2, t, i, (int)l);
break;
- case Hgrow:
- if(whichmenu(m) >= 0)
- hgrow(m, l, inlong(6), 1);
- break;
-
case Hnewname:
- menuins(0, (uchar *)"", (Text *)0, ' ', m);
+ menuins(0, (uchar*)"", nil, ' ', m);
break;
case Hcheck0:
- i = whichmenu(m);
- if(i>=0) {
- t = text[i];
+ if(menu >= 0){
+ t = text[menu];
if(t)
t->lock++;
outTs(Tcheck, m);
@@ -187,9 +183,8 @@
break;
case Hcheck:
- i = whichmenu(m);
- if(i>=0) {
- t = text[i];
+ if(menu >= 0){
+ t = text[menu];
if(t && t->lock)
t->lock--;
hcheck(m);
@@ -196,30 +191,46 @@
}
break;
+ case Horigin:
+ if(menu >= 0)
+ horigin(m, l);
+ break;
+
case Hunlock:
clrlock();
break;
+ case Hgrowdata:
+ case Hgrow:
+ if(menu < 0)
+ break;
+ hgrow(m, l, inlong(6), type == Hgrow);
+ if(type == Hgrow)
+ break;
+ whichtext(m)->lock++;
+ offset = 10;
case Hdata:
- if(whichmenu(m) >= 0)
- l += hdata(m, l, indata+6, count-6);
+ if(menu < 0)
+ break;
+ if(!offset)
+ offset = 6;
+ r = buf;
+ for(i = offset; i < count; i += w)
+ w = chartorune(r++, (char*)indata+i);
+ count -= offset;
+ l += hdata(m, l, buf, count);
Checkscroll:
if(m == cmd.tag){
- for(i=0; i<NL; i++){
+ for(i = 0; i < NL; i++){
lp = &cmd.l[i];
if(lp->textfn)
- center(lp, l>=0? l : lp->p1);
+ center(lp, l >= 0? l: lp->p1, 0);
}
}
break;
- case Horigin:
- if(whichmenu(m) >= 0)
- horigin(m, l);
- break;
-
case Hunlockfile:
- if(whichmenu(m)>=0 && (t = whichtext(m))->lock){
+ if(menu >= 0 && (t = whichtext(m))->lock){
--t->lock;
l = -1;
goto Checkscroll;
@@ -227,48 +238,40 @@
break;
case Hsetdot:
- if(whichmenu(m) >= 0)
+ if(menu >= 0)
hsetdot(m, l, inlong(6));
break;
- case Hgrowdata:
- if(whichmenu(m)<0)
- break;
- hgrow(m, l, inlong(6), 0);
- whichtext(m)->lock++; /* fake the request */
- l += hdata(m, l, indata+10, count-10);
- goto Checkscroll;
-
case Hmoveto:
- if(whichmenu(m)>=0)
+ if(menu >= 0)
hmoveto(m, l);
break;
case Hclean:
- if((m = whichmenu(m)) >= 0)
- name[m][0] = ' ';
+ if(menu >= 0)
+ name[menu][0] = ' ';
break;
case Hdirty:
- if((m = whichmenu(m))>=0)
- name[m][0] = '\'';
+ if(menu >= 0)
+ name[menu][0] = '\'';
break;
case Hdelname:
- if((m=whichmenu(m)) >= 0)
- menudel(m);
+ if(menu >= 0)
+ menudel(menu);
break;
case Hcut:
- if(whichmenu(m) >= 0)
+ if(menu >= 0)
hcut(m, l, inlong(6));
break;
case Hclose:
- if(whichmenu(m)<0 || (t = whichtext(m))==0)
+ if(menu < 0 || !(t = whichtext(m)))
break;
l = t->nwin;
- for(i = 0,lp = t->l; l>0 && i<NL; i++,lp++)
+ for(i = 0, lp = t->l; l > 0 && i < NL; i++, lp++)
if(lp->textfn){
closeup(lp);
--l;
@@ -276,7 +279,7 @@
break;
case Hsetpat:
- setpat((char *)indata);
+ setpat((char*)indata);
break;
case Hsetsnarf:
@@ -302,7 +305,7 @@
break;
case Hmenucmd:
- menucmd((char *)indata);
+ menucmd((char*)indata);
break;
}
}
@@ -321,7 +324,7 @@
if(hostlock > 0)
hostlock--;
if(hostlock == 0)
- setcursor(mousectl, cursor=(Cursor *)0);
+ setcursor(mousectl, cursor = nil);
}
void
@@ -486,10 +489,10 @@
{
uchar buf[4];
- buf[0]=l;
- buf[1]=l>>8;
- buf[2]=l>>16;
- buf[3]=l>>24;
+ buf[0] = l;
+ buf[1] = l >> 8;
+ buf[2] = l >> 16;
+ buf[3] = l >> 24;
outcopy(4, buf);
}
@@ -510,11 +513,11 @@
void
outsend(void)
{
- if(outcount>DATASIZE-HSIZE)
- panic("outcount>sizeof outdata");
- outdata[1]=outcount;
- outdata[2]=outcount>>8;
- if(write(1, (char *)outdata, outcount+HSIZE)!=outcount+HSIZE)
+ if(outcount > DATASIZE - HSIZE)
+ panic("outcount > sizeof outdata");
+ outdata[1] = outcount;
+ outdata[2] = outcount >> 8;
+ if(write(1, (char *)outdata, outcount+HSIZE) != outcount+HSIZE)
panic("write error");
}
@@ -522,6 +525,10 @@
void
hsetdot(int m, long p0, long p1)
{
+ int fd = open("/usr/glenda/samlog", OWRITE);
+ fprint(fd, "hsetdot\n");
+ close(fd);
+
Text *t = whichtext(m);
Flayer *l = &t->l[t->front];
@@ -530,33 +537,48 @@
}
void
-horigin(int m, long p0)
+horigin(int m, long p)
{
Text *t = whichtext(m);
Flayer *l = &t->l[t->front];
+ Frame *f = &l->f;
long a;
ulong n;
Rune *r;
+ if(p > t->rasp.nrunes)
+ p = t->rasp.nrunes-1;
+ if(p < 0)
+ p = 0;
+
if(!flprepare(l)){
- l->origin = p0;
+ l->origin = p;
return;
}
- a = p0-l->origin;
- if(a>=0 && a<l->f.nchars)
- frdelete(&l->f, 0, a);
- else if(a<0 && -a<l->f.nchars){
- r = rload(&t->rasp, p0, l->origin, &n);
- frinsert(&l->f, r, r+n, 0);
+
+ a = p - l->origin;
+ if(a > 0 && l->origin+f->nchars == t->rasp.nrunes && f->nlines == f->maxlines/3)
+ return;
+ if(a >= 0 && a < l->f.nchars)
+ frdelete(f, 0, a);
+ else if(a < 0 && -a < l->f.nchars){
+ r = rload(&t->rasp, p, l->origin, &n);
+ frinsert(f, r, r+n, 0);
}else
- frdelete(&l->f, 0, l->f.nchars);
- l->origin = p0;
+ frdelete(f, 0, f->nchars);
+
+ l->origin = p;
scrdraw(l, t->rasp.nrunes);
- if(l->visible==Some)
+ if(l->visible == Some)
flrefresh(l, l->entire, 0);
hcheck(m);
+
+ /* riskyhack: If we have scrolled too far at the end, retrace our steps. */
+ if(p + f->nchars == t->rasp.nrunes && f->nlines < f->maxlines/3 && l->origin > 0)
+ center(l, t->rasp.nrunes, -(f->maxlines/3));
}
+/* todo: investigate, remove Torigin in cmd/sam. */
void
hmoveto(int m, long p0)
{
@@ -563,13 +585,20 @@
Text *t = whichtext(m);
Flayer *l = &t->l[t->front];
- if(p0<l->origin || p0-l->origin>l->f.nchars*9/10)
+ if(p0 < l->origin || p0-l->origin > l->f.nchars*9/10){
+ // inscroll = 1;
+ // center(l, p0, 0);
outTsll(Torigin, m, p0, 2L);
+ }
}
+void request(Text*, int, int);
+
void
hcheck(int m)
{
+ int fd = open("/usr/glenda/samlog", OWRITE);
+
Flayer *l;
Text *t;
int reqd = 0, i;
@@ -588,11 +617,12 @@
continue;
a = t->l[i].origin;
n = rcontig(&t->rasp, a, a+l->f.nchars, 1);
+ fprint(fd, "n == %ld\nl->f.nchars == %ud\n", n, l->f.nchars);
if(n<l->f.nchars) /* text missing in middle of screen */
- a+=n;
+ a += n;
else{ /* text missing at end of screen? */
Again:
- if(l->f.lastlinefull)
+ if(l->f.lastlinefull)
goto Checksel; /* all's well */
a = t->l[i].origin+l->f.nchars;
n = t->rasp.nrunes-a;
@@ -622,8 +652,11 @@
reqd++;
}
Checksel:
+ fprint(fd, "Checksel\n");
flsetselect(l, l->p0, l->p1);
}
+ fprint(fd, "out hcheck()\n");
+ close(fd);
}
void
@@ -672,13 +705,14 @@
Plumbmsg *m;
s = alloc(nc);
- for(i=0; i<nc; i++)
+ for(i = 0; i < nc; i++)
s[i] = getch();
if(plumbfd >= 0){
m = plumbunpack(s, nc);
- if(m != 0)
+ if(m){
plumbsend(plumbfd, m);
- plumbfree(m);
+ plumbfree(m);
+ }
}
free(s);
}
@@ -694,8 +728,8 @@
if(new <= 0)
panic("hgrow");
rresize(&t->rasp, a, 0L, new);
- for(l = &t->l[0], i = 0; i<NL; i++, l++){
- if(l->textfn == 0)
+ for(l = t->l, i = 0; i < NL; i++, l++){
+ if(!l->textfn)
continue;
o = l->origin;
b = a-o-rmissing(&t->rasp, o, a);
@@ -718,19 +752,24 @@
}
int
-hdata1(Text *t, long a, Rune *r, int len)
+hdata(int m, long a, Rune *r, int len)
{
+ Text *t = whichtext(m);
int i;
Flayer *l;
long o, b;
- for(l = &t->l[0], i=0; i<NL; i++, l++){
- if(l->textfn==0)
+ if(t->lock)
+ t->lock--;
+ if(len == 0)
+ return 0;
+ for(l = t->l, i = 0; i < NL; i++, l++){
+ if(!l->textfn)
continue;
o = l->origin;
b = a-o-rmissing(&t->rasp, o, a);
/* must prevent b temporarily becoming unsigned */
- if(a<o || (b>0 && b>l->f.nchars))
+ if(a < o || (b > 0 && b > l->f.nchars))
continue;
flinsert(l, r, r+len, o+b);
}
@@ -739,35 +778,6 @@
return len;
}
-int
-hdata(int m, long a, uchar *s, int len)
-{
- int i, w;
- Text *t = whichtext(m);
- Rune buf[DATASIZE], *r;
-
- if(t->lock)
- --t->lock;
- if(len == 0)
- return 0;
- r = buf;
- for(i=0; i<len; i+=w,s+=w)
- w = chartorune(r++, (char*)s);
- return hdata1(t, a, buf, r-buf);
-}
-
-int
-hdatarune(int m, long a, Rune *r, int len)
-{
- Text *t = whichtext(m);
-
- if(t->lock)
- --t->lock;
- if(len == 0)
- return 0;
- return hdata1(t, a, r, len);
-}
-
void
hcut(int m, long a, long old)
{
@@ -778,7 +788,7 @@
if(t->lock)
--t->lock;
- for(l = &t->l[0], i = 0; i<NL; i++, l++){
+ for(l = t->l, i = 0; i < NL; i++, l++){
if(l->textfn == 0)
continue;
o = l->origin;
--- a/samterm/plan9.c
+++ b/samterm/plan9.c
@@ -64,14 +64,14 @@
if (n != sizeof(buf)-1)
return 0;
buf[n] = 0;
- if (h) {
+ if(h){
*h = atoi(buf+4*12)-atoi(buf+2*12);
- if (*h < 0)
+ if(*h < 0)
return 0;
}
- if (w) {
+ if(w){
*w = atoi(buf+3*12)-atoi(buf+1*12);
- if (*w < 0)
+ if(*w < 0)
return 0;
}
return 1;
@@ -253,7 +253,7 @@
i = 1-i; /* toggle */
n = read(0, hostbuf[i].data, sizeof hostbuf[i].data);
if(n <= 0){
- if(n==0){
+ if(n == 0){
if(exiting)
threadexits(nil);
werrstr("unexpected eof");
--- a/samterm/rasp.c
+++ b/samterm/rasp.c
@@ -11,48 +11,41 @@
void
rinit(Rasp *r)
{
- r->nrunes=0;
- r->sect=0;
+ r->nrunes = 0;
+ r->sect = 0;
}
void
rclear(Rasp *r)
{
- Section *s, *ns;
+ Section *s, *t;
- for(s=r->sect; s; s=ns){
- ns = s->next;
+ for(s = r->sect; s; s = t){
+ t = s->next;
free(s->text);
free(s);
}
- r->sect = 0;
+ r->sect = nil;
}
+/*
+ * Insert a new section t before s
+ */
Section*
-rsinsert(Rasp *r, Section *s) /* insert before s */
+rsinsert(Rasp *r, Section *s)
{
- Section *t;
- Section *u;
+ Section *t, *u;
t = alloc(sizeof(Section));
- if(r->sect == s){ /* includes empty list case: r->sect==s==0 */
+ if(r->sect == s)
r->sect = t;
- t->next = s;
- }else{
- u = r->sect;
- if(u == 0)
- panic("rsinsert 1");
- do{
+ else
+ for(u = r->sect; u; u = u->next)
if(u->next == s){
- t->next = s;
u->next = t;
- goto Return;
+ break;
}
- u=u->next;
- }while(u);
- panic("rsinsert 2");
- }
- Return:
+ t->next = s;
return t;
}
@@ -61,48 +54,49 @@
{
Section *t;
- if(s == 0)
+ if(!s)
panic("rsdelete");
- if(r->sect == s){
+ if(r->sect == s)
r->sect = s->next;
- goto Free;
- }
- for(t=r->sect; t; t=t->next)
- if(t->next == s){
- t->next = s->next;
- Free:
- if(s->text)
- free(s->text);
- free(s);
- return;
- }
- panic("rsdelete 2");
+ else
+ for(t = r->sect; t; t = t->next)
+ if(t->next == s){
+ t->next = s->next;
+ break;
+ }
+ free(s->text);
+ free(s);
}
void
-splitsect(Rasp *r, Section *s, long n0)
+splitsect(Rasp *r, Section *s, long n)
{
- if(s == 0)
+ if(!s)
panic("splitsect");
rsinsert(r, s->next);
- if(s->text == 0)
- s->next->text = 0;
+ if(!s->text)
+ s->next->text = nil;
else{
s->next->text = alloc(RUNESIZE*(TBLOCKSIZE+1));
- Strcpy(s->next->text, s->text+n0);
- s->text[n0] = 0;
+ runestrcpy(s->next->text, s->text+n);
+ s->text[n] = 0;
}
- s->next->nrunes = s->nrunes-n0;
- s->nrunes = n0;
+ s->next->nrunes = s->nrunes - n;
+ s->nrunes = n;
}
-Section *
-findsect(Rasp *r, Section *s, long p, long q) /* find sect containing q and put q on a sect boundary */
+/*
+ * Find the sect containing q and put q on a sect boundary
+ */
+Section*
+findsect(Rasp *r, Section *s, long p, long q)
{
- if(s==0 && p!=q)
+ if(!s && p != q)
panic("findsect");
- for(; s && p+s->nrunes<=q; s=s->next)
+ while(s && p + s->nrunes <= q){
p += s->nrunes;
+ s = s->next;
+ }
if(p != q){
splitsect(r, s, q-p);
s = s->next;
@@ -118,12 +112,12 @@
s = findsect(r, r->sect, 0L, a);
t = findsect(r, s, a, a+old);
for(; s!=t; s=ns){
- ns=s->next;
+ ns = s->next;
rsdelete(r, s);
}
/* now insert the new piece before t */
if(new > 0){
- ns=rsinsert(r, t);
+ ns = rsinsert(r, t);
ns->nrunes=new;
ns->text=0;
}
@@ -137,11 +131,12 @@
s = findsect(r, r->sect, 0L, p0);
t = findsect(r, s, p0, p1);
- for(; s!=t; s=ns){
- ns=s->next;
+ while(s != t){
+ ns = s->next;
if(s->text)
panic("rdata");
rsdelete(r, s);
+ s = ns;
}
p1 -= p0;
s = rsinsert(r, t);
@@ -161,7 +156,7 @@
if(s->text){
if(s->nrunes+s->next->nrunes>TBLOCKSIZE)
break;
- Strcpy(s->text+s->nrunes, s->next->text);
+ runestrcpy(s->text+s->nrunes, s->next->text);
}
s->nrunes += s->next->nrunes;
rsdelete(r, s->next);
@@ -168,12 +163,6 @@
}
}
-void
-Strcpy(Rune *to, Rune *from)
-{
- do; while(*to++ = *from++);
-}
-
Rune*
rload(Rasp *r, ulong p0, ulong p1, ulong *nrp)
{
@@ -215,13 +204,14 @@
{
Section *s;
long p;
- int n, nm=0;
+ int n, nm;
- for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
+ nm = p = 0;
+ for(s = r->sect; s && p+s->nrunes <= p0; s = s->next)
p += s->nrunes;
- while(p<p1 && s){
- if(s->text == 0){
- n = s->nrunes-(p0-p);
+ while(p < p1 && s){
+ if(!s->text){
+ n = s->nrunes - (p0-p);
if(n > p1-p0) /* all in this section */
n = p1-p0;
nm += n;
@@ -238,11 +228,12 @@
{
Section *s;
long p, n;
- int np=0;
+ int np;
- for(p=0,s=r->sect; s && p+s->nrunes<=p0; s=s->next)
+ np = p = 0;
+ for(s = r->sect; s && p+s->nrunes <= p0; s = s->next)
p += s->nrunes;
- while(p<p1 && s && (text? (s->text!=0) : (s->text==0))){
+ while(p < p1 && s && (text? s->text!=0: s->text==0)){
n = s->nrunes-(p0-p);
if(n > p1-p0) /* all in this section */
n = p1-p0;
--- a/samterm/samterm.h
+++ b/samterm/samterm.h
@@ -2,7 +2,7 @@
#define RUNESIZE sizeof(Rune)
#define MAXFILES 256
-#define READBUFSIZE 8192
+#define READBUFSIZE 8192
#define NL 5
enum{
@@ -9,13 +9,13 @@
Up,
Down,
- Kbel=0x7,
+ Kbel = 0x7,
};
typedef struct Text Text;
typedef struct Section Section;
typedef struct Rasp Rasp;
-typedef struct Readbuf Readbuf;
+typedef struct Readbuf Readbuf;
struct Section
{
@@ -36,16 +36,16 @@
{
Rasp rasp;
short nwin;
- short front; /* input window */
+ short front; /* input window */
ushort tag;
char lock;
- Flayer l[NL]; /* screen storage */
+ Flayer l[NL]; /* screen storage */
};
struct Readbuf
{
- short n; /* # bytes in buf */
- uchar data[READBUFSIZE]; /* data bytes */
+ short n; /* # bytes in buf */
+ uchar data[READBUFSIZE]; /* data bytes */
};
enum Resource
@@ -89,6 +89,7 @@
extern int exiting;
extern int autoindent;
extern int spacesindent;
+extern int inscroll;
Rune *gettext(Flayer*, long, ulong*);
void *alloc(ulong n);
@@ -100,7 +101,6 @@
void outcmd(void);
void rinit(Rasp*);
void startnewfile(int, Text*);
-void getmouse(void);
void mouseunblock(void);
void kbdblock(void);
void hoststart(void);
@@ -107,15 +107,17 @@
int plumbstart(void);
int button(int but);
int load(char*, int);
-int waitforio(void);
+int waitforio(int);
+void frscroll(Frame*, int);
int rcvchar(void);
int getch(void);
int kbdchar(void);
int qpeekc(void);
void cut(Text*, int, int, int);
+void center(Flayer*, long, long);
void paste(Text*, int);
void snarf(Text*, int);
-int center(Flayer*, long);
+Rune raspc(Rasp*, long);
int xmenuhit(int, Menu*);
void buttons(int);
int getr(Rectangle*);
@@ -126,8 +128,10 @@
void panic1(Display*, char*);
void closeup(Flayer*);
void Strgrow(Rune**, long*, int);
+void center(Flayer*, long, long);
int RESIZED(void);
void resize(void);
+void rcvhost(void);
void rcv(void);
void type(Flayer*, int);
void menu2hit(void);
@@ -139,8 +143,7 @@
void hcut(int, long, long);
void horigin(int, long);
void hgrow(int, long, long, int);
-int hdata(int, long, uchar*, int);
-int hdatarune(int, long, Rune*, int);
+int hdata(int, long, Rune*, int);
Rune *rload(Rasp*, ulong, ulong, ulong*);
void menuins(int, uchar*, Text*, int, int);
void menudel(int);
@@ -157,23 +160,22 @@
long scrtotal(Flayer*);
void flnewlyvisible(Flayer*);
char *rcvstring(void);
-void Strcpy(Rune*, Rune*);
-void Strncpy(Rune*, Rune*, long);
void flushtyping(int);
void dumperrmsg(int, int, int, int);
int screensize(int*,int*);
-void getmouse(void);
-
+void clrlock(void);
#include "mesg.h"
-void outTs(Tmesg, int);
void outT0(Tmesg);
+void outTs(Tmesg, int);
void outTl(Tmesg, long);
-void outTslS(Tmesg, int, long, Rune*);
-void outTsll(Tmesg, int, long, long);
+void outTv(Tmesg, vlong);
void outTsl(Tmesg, int, long);
void outTsv(Tmesg, int, vlong);
-void outTv(Tmesg, vlong);
+void outTsls(Tmesg, int, long, int);
+void outTsll(Tmesg, int, long, long);
+void outTslS(Tmesg, int, long, Rune*);
+
void outstart(Tmesg);
void outcopy(int, uchar*);
void outshort(int);
--- a/samterm/scroll.c
+++ b/samterm/scroll.c
@@ -55,8 +55,8 @@
scrmark(Flayer *l, Rectangle r)
{
r.max.x--;
- if(rectclip(&r, l->scroll)) {
- if (l->f.b == nil)
+ if(rectclip(&r, l->scroll)){
+ if(l->f.b == nil)
panic("scrmark: nil l->f.b");
draw(l->f.b, r, l->f.cols[HIGH], nil, ZP);
}
@@ -65,8 +65,8 @@
void
scrunmark(Flayer *l, Rectangle r)
{
- if(rectclip(&r, l->scroll)) {
- if (l->f.b == nil)
+ if(rectclip(&r, l->scroll)){
+ if(l->f.b == nil)
panic("scrunmark: nil l->f.b");
draw(l->f.b, r, scrback, nil, Pt(0, r.min.y-l->scroll.min.y));
}
@@ -108,8 +108,8 @@
int in = 0, oin;
long tot = scrtotal(l);
Rectangle scr, r, s, rt;
- int x, y, my, oy, h;
- long p0;
+ int x, y, my, oy;
+ long o, p0;
if(l->visible==None)
return;
@@ -155,23 +155,18 @@
}
}while(but <= 3 && button(but));
if(in){
- h = s.max.y-s.min.y;
scrunmark(l, r);
- p0 = 0;
- if(but == 1 || but == 4){
- but = 1;
- p0 = (long)(my-s.min.y)/l->f.font->height+1;
- }else if(but == 2){
- if(tot > 1024L*1024L)
- p0 = ((tot>>10)*(y-s.min.y)/h)<<10;
- else
- p0 = tot*(y-s.min.y)/h;
- }else if(but == 3 || but == 5){
- but = 3;
- p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
- if(p0 > tot)
- p0 = tot;
+ if(but == 2){
+ p0 = 0;
+ o = (tot / (s.max.y - s.min.y)) * (my - s.min.y);
+ }else{
+ p0 = (but == 1 || but == 4)? -1: 1;
+ p0 *= (my - s.min.y)/l->f.font->height+1;
+ o = l->origin;
+
}
- scrorigin(l, but, p0);
+ mouseunblock();
+ inscroll = 1;
+ center(l, o, p0);
}
}
--
⑨