gophra

gopher client for plan9
git clone git://nsmpr.xyz/gophra.git
Log | Files | Refs

commit c232c0ea0c5f046e86ea6ee27597fc168ae70f86
parent 73d9810f8c1ceb9aef46cc5b7fe0dc0f69dbeb8f
Author: glenda <glenda@9front.local>
Date:   Sat, 13 Jun 2020 13:30:25 +0000

fix line length issue, add loading status monitoring

Diffstat:
Mgophra.c | 116+++++++++++++++++++++++++++++++++++++++----------------------------------------
Mload.c | 22+++++++++++++++-------
Mload.h | 3++-
3 files changed, 74 insertions(+), 67 deletions(-)

diff --git a/gophra.c b/gophra.c @@ -13,7 +13,7 @@ enum { DBorder = DBlue, DWBG = DBlack, - DWFG = 0xCCCCCCFF, + DWFG = 0xAAAAAAFF, DWFGL = DWhite, DStatus = DYellow, }; @@ -25,7 +25,7 @@ struct History { History *prev; }; -Channel *lc; +Channel *lc, *sc; History hzero, *hp; Image *Iborder, *Iwbg, *Iwfg, *Iwfgl, *Istatus; Rectangle rstatus, rw; @@ -34,7 +34,7 @@ char status[256], path[256], addr[256], type; const char *tmpfile = "/tmp/gophra.tmp"; long scroll; -char* getline(Text*, long); +char* getlinep(Text*, ulong); int extracturl(char*); int runuri(char*); int save(char*, char*); @@ -55,6 +55,7 @@ threadmain(int argc, char **argv) { Mousectl *mc; Keyboardctl *kc; + char *sv; Mouse mv; Rune kv; int rv[2]; @@ -62,7 +63,7 @@ threadmain(int argc, char **argv) long sline; char *s; - int mpress; + int mpress, flush; ARGBEGIN{ default: @@ -85,10 +86,11 @@ threadmain(int argc, char **argv) RGB24, 1, DStatus); mpress = 0; + flush = 0; scroll = 0; hp = &hzero; lc = chancreate(sizeof(Text), 0); - + sc = chancreate(sizeof(char*), 0); snprint(status, 255, "gophra!"); calcrects(); @@ -113,6 +115,7 @@ threadmain(int argc, char **argv) {mc->c, &mv, CHANRCV}, {mc->resizec, rv, CHANRCV}, {lc, &tv, CHANRCV}, + {sc, &sv, CHANRCV}, {0, 0, CHANEND}, }; @@ -126,7 +129,7 @@ threadmain(int argc, char **argv) if (enter("goto:", buf, 255, mc, kc, 0) >=0) if (runuri(buf) == 0){ drawmenu(); - flushimage(display, 1); + flush = 1; } } break; @@ -138,35 +141,34 @@ threadmain(int argc, char **argv) scroll -= 1 + (mv.xy.y-rw.min.y)/font->height; if (scroll < 0) scroll = 0; drawmenu(); - flushimage(display, 1); + flush = 1; } if (mv.buttons == 16) { mpress = 1; scroll += 1 + (mv.xy.y-rw.min.y)/font->height; drawmenu(); - flushimage(display, 1); + flush = 1; } if (mpress != 0) break; if (mv.buttons == 1) { mpress = 1; sline = (mv.xy.y - rw.min.y) / font->height + scroll; - s = getline(&text, sline); + s = getlinep(&text, sline); if (s == nil) break; extracturl(s); snprint(status, 255, "%s/%c%s", addr, type, path); drawstatus(); - flushimage(display, 1); - if (s != 0) free(s); + flush = 1; } if (mv.buttons == 2) { mpress = 1; sline = (mv.xy.y - rw.min.y) / font->height + scroll; - s = getline(&text, sline); + s = getlinep(&text, sline); + if (s == nil) break; extracturl(s); handlelink(addr, type, path); - if (s != 0) free(s); } if (mv.buttons == 4) { mpress = 1; @@ -179,16 +181,26 @@ threadmain(int argc, char **argv) drawborder(); drawstatus(); drawmenu(); - flushimage(display, 1); + flush = 1; break; case 3: /* loading */ realloc(text.data, 0); text = tv; scroll = 0; drawmenu(); - flushimage(display, 1); + flush = 1; + break; + case 4: /* status */ + snprint(status, 255, "%s", sv); + drawstatus(); + flush = 1; + realloc(sv, 0); break; } + if (flush != 0) { + flush = 0; + flushimage(display, 1); + } } } @@ -280,60 +292,45 @@ drawtext(void) void drawmenu(void) { - char sbuf[1024], *tp, *sp; + char *s, *buf; Image *Ifg; Point dp; - long n, lc; - lc = 0; + ulong n, line; dp = rw.min; - tp = text.data; - sp = sbuf; draw(screen, rw, Iwbg, 0, ZP); - if (sp == nil) return; - while (tp < text.data + text.size) { - *sp = *tp; - sp++; - tp++; - if (*tp == '\n'){ - *sp = 0; - tp++; - lc++; - sp = sbuf; - if (lc-1 < scroll) continue; - n = strchr(sbuf, '\t') - (sbuf + 1); - while (dp.x + stringnwidth(font, sbuf+1, n) > - rw.max.x) n--; - Ifg = Iwfgl; - if (sbuf[0] == 'i') Ifg = Iwfg; - stringn(screen, dp, Ifg, ZP, font, sbuf+1, n); - dp.y += font->height; - if (dp.y + font->height > rw.max.y) break; - } + for(line = scroll;; line++){ + /* + * n in stringn() counts characters, not bytes. + * To prevent unicode from messsing with character count, + * we copy line into new variable buf and draw it, instead of + * drawing s directly. + */ + s = getlinep(&text, line); + if (s == nil) break; + n = strchr(s, '\t') - (s + 1); + while (dp.x + stringnwidth(font, s+1, n) > rw.max.x) n--; + buf = mallocz(sizeof(char) * (n + 1), 1); + memcpy(buf, s + 1, n); + if (*s == 'i') Ifg = Iwfg; + else Ifg = Iwfgl; + string(screen, dp, Ifg, ZP, font, buf); + free(buf); + dp.y += font->height; + if (dp.y + font->height > rw.max.y) break; } - if ((tp >= text.data + text.size) && (scroll > lc)) - scroll = lc; } char* -getline(Text *text, long ln) +getlinep(Text *text, ulong ln) { - char *lbuf; - char *lstart, *lend; - long lcount; - if (text->data == nil) return nil; - lstart = text->data; - for (lcount = 0; lcount < ln; lstart++) { - if (*lstart == '\n') lcount++; - if (lstart > text->data + text->size) return nil; - } - lend = lstart; - while (*lend != '\n') { - lend++; - if (lend > text->data + text->size) return nil; + ulong lcount; + char *lp; + lp = text->data; + for (lcount = 0; lcount < ln; lp++){ + if (*lp == '\n') lcount++; + if (lp > text->data + text->size) return nil; } - lbuf = mallocz(sizeof(char) * (lend - lstart + 1), 1); - memcpy(lbuf, lstart, lend - lstart); - return lbuf; + return lp; } int @@ -393,6 +390,7 @@ loadtext(char *addr, char *path) lctl->addr = strdup(addr); lctl->path = strdup(path); lctl->query = nil; + lctl->sc = sc; threadcreate(threadload, lctl, 64 * 1024); return; } diff --git a/load.c b/load.c @@ -7,19 +7,26 @@ void threadload(void *v) { + char *status; int gfd; Text text; - long n; + ulong n; char buf[1024]; Loadctl *lctl; lctl = v; - // set status to "dialing $addr..." + status = smprint("dialing %s", lctl->addr); + send(lctl->sc, &status); gfd = dial(lctl->addr, 0, 0, 0); if (gfd == -1) { - // set status to "failed to dial $addr" - // send nill + status = smprint("failed to dial %s", lctl->addr); + send(lctl->sc, &status); + send(lctl->c, nil); + + realloc(lctl->path, 0); + realloc(lctl->addr, 0); + realloc(lctl->query, 0); return; } write(gfd, lctl->path, strlen(lctl->path)); @@ -31,14 +38,15 @@ threadload(void *v) text.data = realloc(text.data, text.size + n); memcpy(text.data + text.size, buf, n); text.size += n; - // set status to "loading - $n bytes" + status = smprint("loading - %ld bytes", text.size); + send(lctl->sc, &status); // border animation } - // set status to done + status = smprint("done - %s %s", lctl->addr, lctl->path); + send(lctl->sc, &status); send(lctl->c, &text); realloc(lctl->path, 0); realloc(lctl->addr, 0); realloc(lctl->query, 0); - } diff --git a/load.h b/load.h @@ -1,7 +1,7 @@ typedef struct Text Text; struct Text { - long size; + ulong size; char *data; }; @@ -11,6 +11,7 @@ struct Loadctl { char *path; char *query; Channel *c; + Channel *sc; }; void threadload(void*);