richterm

"terminal emulator" with support for text fonts and images for plan9
git clone git://nsmpr.xyz/richterm.git
Log | Files | Refs | README

commit 11753aab5287d0541bd0f12b2df4355b037284fa
parent 89c7fbdfc23a5914e9b4a04b7584ddf9c3d403a3
Author: glenda <glenda@9front.local>
Date:   Fri, 13 Aug 2021 00:00:14 +0000

move objects to Array, it somehow works

Diffstat:
Marray.c | 21++++++++++++++++-----
Marray.h | 1+
Mfs.c | 39+++++++++++++++++++++------------------
Mmkfile | 2+-
Mrichterm.c | 147+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Mrichterm.h | 10+++-------
6 files changed, 118 insertions(+), 102 deletions(-)

diff --git a/array.c b/array.c @@ -22,24 +22,35 @@ arrayfree(Array *ap) int i; if (ap->free != nil) { for (i = 0; i < ap->count; i ++) { - void *v; + void **v; v = arrayget(ap, i); - ap->free(v); + ap->free(*v); } } free(ap); - /* stub */ } void * arrayadd(Array *ap) { ap->count++; - if (ap->count > ap->n) ap->n += ap->n; - ap->mem = realloc(ap->mem, ap->size * ap->n); + if (ap->count > ap->n) { + ap->n += ap->n; + ap->mem = realloc(ap->mem, ap->size * ap->n); + } return memset(arrayget(ap, ap->count - 1), 0, ap->size); } +void +arraydel(Array *ap, long n) +{ + char *v; + v = ap->mem + ap->size * n; + if (ap->free != nil) ap->free(v); + memcpy(v, v + ap->size, (ap->count - n) * ap->size); + ap->count--; +} + void * arrayget(Array *ap, long n) { diff --git a/array.h b/array.h @@ -11,4 +11,5 @@ struct Array { Array * arraycreate(usize, long, void (*free)(void *)); void arrayfree(Array *); void * arrayadd(Array *); +void arraydel(Array *, long); void * arrayget(Array *, long); diff --git a/fs.c b/fs.c @@ -14,36 +14,39 @@ Object *newobj; char * ctlcmd(char *buf) { + Object **op; int n, i, j; char *args[256]; n = tokenize(buf, args, 256); if (n <= 0) return "expected a command"; + qlock(rich.l); if (strcmp(args[0], "remove") == 0) { - for (i = 0; i < n; i++) { + for (i = 1; i < n; i++) { for (j = 0; j < rich.objects->count; j++) { - if (rich.obj[j] == olast) continue; - if (strcmp(rich.obj[j]->id, args[i]) == 0) { - Object **sp, **tp; - rmobjectftree(rich.obj[j]); - free(rich.obj[j]); - sp = &rich.obj[j]; - tp = &rich.obj[j+1]; - memcpy(sp, tp, (rich.count - j - 1) * sizeof(Object *)); - rich.count--; + op = arrayget(rich.objects, j); + if (*op == olast) continue; + if (strcmp((*op)->id, args[i]) == 0) { + objectfree(*op); + arraydel(rich.objects, j); break; } } } } else if (strcmp(args[0], "clear") == 0) { - for (i = 0; i < rich.count; i++) { - if (rich.obj[i] == olast) continue; - rmobjectftree(rich.obj[i]); - free(rich.obj[i]); + int k; + k = rich.objects->count; + for (i = 0; i < k; i++) { + op = arrayget(rich.objects, 0); + if (*op != olast) { + objectfree(*op); + arraydel(rich.objects, 0); + } } - rich.count = 1; - rich.obj = realloc(rich.obj, 1 * sizeof(Object *)); - rich.obj[0] = olast; - } else return "unknown command"; + } else { + qunlock(rich.l); + return "unknown command"; + } + qunlock(rich.l); return nil; } diff --git a/mkfile b/mkfile @@ -2,6 +2,6 @@ TARG=richterm OFILES=richterm.$O devfs.$O fs.$O array.$O -HFILES=richterm.h +HFILES=richterm.h array.h </sys/src/cmd/mkone diff --git a/richterm.c b/richterm.c @@ -62,20 +62,36 @@ threadmain(int argc, char **argv) usage(); } ARGEND + dv = (Data) {nil, 0}; + mmode = MM_NONE; + + if (initdraw(0, 0, "richterm") < 0) + sysfatal("%s: %r", argv0); + if ((mctl = initmouse(nil, screen)) == nil) + sysfatal("%s: %r", argv0); + if ((kctl = initkeyboard(nil)) == nil) + sysfatal("%s: %r", argv0); + + Iscrollbar = allocimage( + display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF); + Inormbg = allocimage( + display, Rect(0,0,1,1), screen->chan, 1, 0xDDDDDDFF); + Iselbg = allocimage( + display, Rect(0,0,1,1), screen->chan, 1, 0xBBBBBBFF); + Ilink = allocimage( + display, Rect(0,0,1,1), screen->chan, 1, DBlue); + + fonts = arraycreate(sizeof(Font *), 2, nil); + fp = arrayadd(fonts); + *fp = font; + rich.l = mallocz(sizeof(QLock), 1); qlock(rich.l); rich.objects = arraycreate(sizeof(Object *), 8, nil); - /* TODO add objectfree() func above */ - rich.page.views = arraycreate(sizeof(View), 8, nil); - rich.obj = nil; - rich.count = 0; - dv.p = nil; - dv.n = 0; - rich.page.scroll = ZP; rich.page.selstart = 0; @@ -83,29 +99,8 @@ threadmain(int argc, char **argv) qunlock(rich.l); - if (initdraw(0, 0, "richterm") < 0) - sysfatal("%s: %r", argv0); - - fonts = arraycreate(sizeof(Font *), 2, nil); - fp = arrayadd(fonts); - *fp = font; - olast = newobject(&rich, nil); - mmode = MM_NONE; - - Iscrollbar = allocimage( - display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF); - - Inormbg = allocimage( - display, Rect(0,0,1,1), screen->chan, 1, 0xDDDDDDFF); - - Iselbg = allocimage( - display, Rect(0,0,1,1), screen->chan, 1, 0xBBBBBBFF); - - Ilink = allocimage( - display, Rect(0,0,1,1), screen->chan, 1, DBlue); - resize(); redraw(1); @@ -117,11 +112,6 @@ threadmain(int argc, char **argv) proccreate(runcmd, argv, 16 * 1024); hostpid = recvul(pidchan); - if ((mctl = initmouse(nil, screen)) == nil) - sysfatal("%s: %r", argv0); - if ((kctl = initkeyboard(nil)) == nil) - sysfatal("%s: %r", argv0); - enum {MOUSE, RESIZE, KBD, DEVFSWRITE, NONE}; Alt alts[5] = { {mctl->c, &mv, CHANRCV}, @@ -171,7 +161,7 @@ threadmain(int argc, char **argv) redraw(1); break; } - if (rich.obj != nil) { + if (rich.objects->count > 0) { int n; n = runelen(kv); @@ -198,15 +188,16 @@ threadmain(int argc, char **argv) obj->dtext->p = realloc(obj->dtext->p, obj->dtext->n); memcpy(obj->dtext->p, olast->dtext->p, olast->dtext->n); + olast->dtext->n = 0; + + dv.p = mallocz(obj->dtext->n, 1); + dv.n = obj->dtext->n; + memcpy(dv.p, obj->dtext->p, dv.n); + qunlock(rich.l); - dv.p = mallocz(olast->dtext->n, 1); - memcpy(dv.p, olast->dtext->p, olast->dtext->n); - dv.n = olast->dtext->n; nbsend(dctl->rc, &dv); - olast->dtext->n = 0; - redraw(1); break; } @@ -380,7 +371,7 @@ generatepage(Rich *rich) Rectangle r; char *sp; usize cc; - Object *obj; + Object *obj, **op; int sel, ymax, i; usize selmin, selmax; Point pt; @@ -392,17 +383,13 @@ generatepage(Rich *rich) SEL_AFTER }; - sel = SEL_BEFORE; cc = 0; + if (rich->objects->count == 0) return; + qlock(rich->l); - if (rich->obj == nil) { - qunlock(rich->l); - return; - } - page = &rich->page; page->views->count = 0; @@ -420,10 +407,11 @@ generatepage(Rich *rich) pt = r.min; ymax = 0; - obj = *rich->obj; + op = arrayget(rich->objects, 0); + obj = *op; sp = obj->dtext->p; i = 0; - while (i < rich->count) { + while (i < rich->objects->count) { int newline, tab; View *v; char *brkp; @@ -515,8 +503,9 @@ generatepage(Rich *rich) if (v->length >= obj->dtext->n - 1) { i++; - obj = rich->obj[i]; - if (i < rich->count) { + op = arrayget(rich->objects, i); + obj = *op; + if (i < rich->objects->count) { sp = obj->dtext->p; } } @@ -524,8 +513,8 @@ generatepage(Rich *rich) cc += v->length; } - rich->page.max.y = ymax - r.min.y; - rich->page.max.x = 0; + page->max.y = ymax - r.min.y; + page->max.x = r.max.x - r.min.x; qunlock(rich->l); } @@ -568,8 +557,8 @@ fauxalloc(Object *obj, Data *data, int type) Faux *aux; aux = mallocz(sizeof(Faux), 1); aux->obj = obj; - aux->type = type; aux->data = data; + aux->type = type; return aux; } @@ -578,11 +567,18 @@ newobject(Rich *rich, char *text) { Object *obj, **op; qlock(rich->l); - rich->count++; - rich->obj = realloc(rich->obj, rich->count * sizeof(Object *)); - obj = mallocz(sizeof(Object), 1); op = arrayadd(rich->objects); + + if (rich->objects->count > 1) { + Object **o1; + o1 = arrayget(rich->objects, rich->objects->count - 2); + *op = *o1; + op = o1; + } + + obj = mallocz(sizeof(Object), 1); + *op = obj; obj->dtext = mallocz(sizeof(Data), 1); @@ -605,11 +601,6 @@ newobject(Rich *rich, char *text) obj->font = font; - if (rich->count > 1) { - rich->obj[rich->count - 1] = rich->obj[rich->count - 2]; - rich->obj[rich->count - 2] = obj; - } else rich->obj[rich->count - 1] = obj; - rich->idcount++; qunlock(rich->l); @@ -635,20 +626,10 @@ mkobjectftree(Object *obj, File *root) obj->flink = createfile(obj->dir, "link", "richterm", 0666, auxlink); obj->fimage = createfile(obj->dir, "image", "richterm", 0666, auximage); - obj->font = font; qunlock(rich.l); return obj; } -void -rmobjectftree(Object *obj) -{ - removefile(obj->ftext); - removefile(obj->ffont); - removefile(obj->flink); - removefile(obj->fimage); - removefile(obj->dir); -} void redraw(int regen) @@ -735,3 +716,26 @@ resize(void) subpt(screen->r.max, Pt(1,1)) ); } + +void +objectfree(void *v) +{ + Object *op; + op = v; + + removefile(op->ftext); + removefile(op->ffont); + removefile(op->flink); + removefile(op->fimage); + removefile(op->dir); + + /* TODO: why is this not working? */ + free(op->id); + +// free(op->dtext->p); +// free(op->dfont->p); +// free(op->dlink->p); +// free(op->dimage->p); + + free(op); +} +\ No newline at end of file diff --git a/richterm.h b/richterm.h @@ -28,6 +28,7 @@ extern Object *olast; Object * mkobjectftree(Object *, File *); void rmobjectftree(Object *); +void objectfree(void *); extern Array *fonts; @@ -66,15 +67,10 @@ typedef struct Rich Rich; struct Rich { QLock *l; - - Object **obj; - usize count; - - usize idcount; + Array *objects; + u64int idcount; Page page; - - Array *objects; }; extern Rich rich;