commit 61ec78051d6f8ef2171219ee1033708d0fc5cf0c
parent 569c4f884d4b3e5af1a6a33ccba698f1c14cfa4f
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Wed, 18 Aug 2021 19:15:10 +0000
working on switching to single text buffer, still not done yet
Diffstat:
M | array.c | | | 3 | +++ |
M | devfs.c | | | 14 | +++++++------- |
M | fs.c | | | 105 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------- |
M | richterm.c | | | 134 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------- |
M | richterm.h | | | 18 | +++++++++++------- |
5 files changed, 208 insertions(+), 66 deletions(-)
diff --git a/array.c b/array.c
@@ -38,6 +38,7 @@ arrayfree(Array *ap)
void *
arraygrow(Array *ap, long n)
{
+ if (n < 0) return nil;
qlock(ap->l);
ap->count += n;
if (ap->count > ap->n) {
@@ -53,6 +54,7 @@ void
arraydel(Array *ap, long n)
{
char *v;
+ if ((n < 0) || (n > ap->count)) return;
qlock(ap->l);
v = ap->p + ap->size * n;
if (ap->free != nil) ap->free(v);
@@ -64,5 +66,6 @@ arraydel(Array *ap, long n)
void *
arrayget(Array *ap, long n)
{
+ if ((n < 0) || (n > ap->count)) return nil;
return (void *)(ap->p + ap->size * n);
}
diff --git a/devfs.c b/devfs.c
@@ -8,7 +8,7 @@
#include "array.h"
#include "richterm.h"
-File *cons, *consctl;
+File *cons, *consctl, *text;
void
devfs_read(Req *r)
@@ -27,8 +27,10 @@ devfs_read(Req *r)
respond(r, nil);
} else if (f == consctl) {
respond(r, "not implemented");
- }
- else respond(r, "what");
+ }else if (f == text) {
+ arrayread(r, rich.text);
+ respond(r, nil);
+ } else respond(r, "what");
}
void
@@ -37,10 +39,7 @@ devfs_write(Req *r)
File *f;
f = r->fid->file;
if (f == cons){
- char *buf;
- buf = mallocz(r->ifcall.count + 1, 1);
- memcpy(buf, r->ifcall.data, r->ifcall.count);
- mkobjectftree(newobject(&rich, buf), fsctl->tree->root);
+ mkobjectftree(newobject(&rich, r->ifcall.data, r->ifcall.count), fsctl->tree->root);
redraw(1);
r->ofcall.count = r->ifcall.count;
respond(r, nil);
@@ -67,6 +66,7 @@ initdevfs(void)
if (cons == nil) return nil;
consctl = createfile(srv.tree->root, "consctl", "richterm", 0666, dctl);
if (consctl == nil) return nil;
+ text = createfile(srv.tree->root, "text", "richterm", 0444, dctl);
threadpostmountsrv(&srv, nil, "/dev", MBEFORE);
return dctl;
}
diff --git a/fs.c b/fs.c
@@ -66,7 +66,7 @@ fs_open(Req *r)
{
Fsctl *fsctl;
fsctl = new->aux;
- newobj = mkobjectftree(newobject(&rich, nil), fsctl->tree->root);
+ newobj = mkobjectftree(newobject(&rich, nil, 0), fsctl->tree->root);
respond(r, nil);
}
@@ -84,7 +84,7 @@ fs_read(Req *r)
readstr(r, newobj->id);
respond(r, nil);
} else if (aux != nil) {
- aux->read(r);
+ aux->read(r, aux->data);
respond(r, nil);
} else respond(r, "fs_read: f->aux is nil");
}
@@ -106,23 +106,7 @@ fs_write(Req *r)
} else if (f == new) {
respond(r, "not allowed");
} else if (aux != nil) {
- qlock(rich.l);
- /* TODO: this is not exactly finished */
-
- aux->data->count = 0;
- arraygrow(aux->data, r->ifcall.offset + r->ifcall.count + 1);
- memcpy(arrayget(aux->data, r->ifcall.offset),
- r->ifcall.data, r->ifcall.count);
-
- r->ofcall.count = r->ifcall.count;
-
- if (aux->type == FT_FONT) {
- char *path;
- tokenize(aux->data->p, &path, 1);
- aux->obj->font = getfont(fonts, path);
- }
-
- qunlock(rich.l);
+ aux->read(r, aux->data);
respond(r, nil);
redraw(1);
} else respond(r, "fs_write: f->aux is nil");
@@ -152,21 +136,91 @@ initfs(void)
}
void
-arrayread(Req *r)
+arrayread(Req *r, void *v)
{
- Faux *aux;
Array *data;
+ data = v;
qlock(rich.l);
- aux = r->fid->file->aux;
- data = aux->data;
qlock(data->l);
- readbuf(r, data->p, data->n);
+ readbuf(r, data->p, data->count);
qunlock(data->l);
qunlock(rich.l);
}
void
-arraywrite(Req *)
+arraywrite(Req *, void *)
{
/* stub */
}
+
+void
+textread(Req *r, void *)
+{
+ Faux *aux;
+ Object *obj, *oe;
+ char *s;
+ usize n;
+
+ qlock(rich.l);
+ aux = r->fid->file->aux;
+ obj = aux->obj;
+ oe = obj->next;
+
+ if (oe == nil)
+ n = rich.text->count;
+
+ else n = oe->offset;
+
+ s = arrayget(rich.text, obj->offset);
+
+ print("tr: %ulld %ulld\n", n, obj->offset);
+
+ qlock(rich.text->l);
+
+ readbuf(r, s, n - obj->offset);
+
+ qunlock(rich.text->l);
+ qunlock(rich.l);
+}
+
+void
+textwrite(Req *r, void *)
+{
+ /* TODO: this is not exactly finished */
+ /* in particular TRUNK/APPEND handling is needed */
+
+ char *p, *pe;
+ Faux *aux;
+ Object *obj;
+ long n, m, dn;
+
+ print("textwrite\n");
+
+ qlock(rich.objects->l);
+
+ aux = r->fid->file->aux;
+ obj = aux->obj;
+ p = arrayget(rich.text, obj->offset);
+ pe = arrayget(rich.text, rich.text->count);
+ if (obj->next == nil) n = rich.text->count;
+ else n = obj->next->offset - obj->offset;
+ m = r->ifcall.count + r->ifcall.offset;
+ dn = m - n;
+
+ qlock(rich.text->l);
+
+ if (dn > 0) arraygrow(rich.text, dn);
+ else rich.text->count += dn;
+ memcpy(p + m, p + n, pe - p);
+ memcpy(p + r->ifcall.offset, r->ifcall.data,
+ r->ifcall.count);
+
+ qunlock(rich.text->l);
+
+ for (; obj != nil; obj = obj->next) {
+ obj->offset += dn;
+ }
+
+ qunlock(rich.objects->l);
+
+}
+\ No newline at end of file
diff --git a/richterm.c b/richterm.c
@@ -25,6 +25,8 @@ void msnarf(Rich *);
void mplumb(Rich *);
void msend(Rich *);
+void newdraw(void);
+
Rich rich;
int hostpid = -1;
Channel *pidchan;
@@ -33,7 +35,7 @@ Keyboardctl *kctl;
Devfsctl *dctl;
Fsctl *fsctl;
Array *fonts;
-Image *Iscrollbar, *Ilink, *Inormbg, *Iselbg;
+Image *Iscrollbar, *Ilink, *Inormbg, *Iselbg, *Itext;
char *mitems[] = {"paste", "snarf", "plumb", nil};
void (*mfunc[])(Rich *) = {mpaste, msnarf, mplumb, nil};
@@ -96,6 +98,8 @@ threadmain(int argc, char **argv)
Ilink = allocimage(
display, Rect(0,0,1,1), screen->chan, 1, DBlue);
+ Itext = display->black;
+
fonts = arraycreate(sizeof(Font *), 2, nil);
fp = arraygrow(fonts, 1);
*fp = font;
@@ -112,7 +116,7 @@ threadmain(int argc, char **argv)
qunlock(rich.l);
- olast = newobject(&rich, nil);
+ olast = newobject(&rich, nil, 0);
resize();
redraw(1);
@@ -144,6 +148,12 @@ threadmain(int argc, char **argv)
redraw(1);
break;
case KBD:
+ if (kv == 0xf001) {
+ draw(screen, rich.page.r, display->white, nil, ZP);
+ newdraw();
+ flushimage(display, 1);
+ break;
+ }
if (kv == 0x7f) shutdown(); /* delete */
if (kv == 0xf00e) { /* d-pad up */
scroll(
@@ -190,22 +200,20 @@ threadmain(int argc, char **argv)
redraw(1);
}
if (kv == '\n') {
- Object *obj;
-
- obj = mkobjectftree(newobject(&rich, nil), fsctl->tree->root);
-
qlock(rich.l);
dv = arraycreate(sizeof(char), olast->dtext->n, nil);
arraygrow(dv, olast->dtext->count);
memcpy(dv->p, olast->dtext->p, dv->count);
- arraygrow(obj->dtext, olast->dtext->n);
- memcpy(obj->dtext->p, olast->dtext->p, olast->dtext->count);
- olast->dtext->count = 0;
-
qunlock(rich.l);
+ mkobjectftree(
+ newobject(&rich, olast->dtext->p, olast->dtext->count),
+ fsctl->tree->root);
+
+ olast->dtext->count = 0;
+
nbsend(dctl->rc, &dv);
redraw(1);
@@ -610,50 +618,56 @@ fauxalloc(Object *obj, Array *data, int type)
}
Object *
-newobject(Rich *rich, char *text)
+newobject(Rich *rich, char *p, long n)
{
- Object *obj, **op;
+ Object *obj, **op, **old;
qlock(rich->l);
+ old = arrayget(rich->objects, rich->objects->count - 1);
+
op = arraygrow(rich->objects, 1);
if (rich->objects->count > 1) {
Object **o1;
o1 = arrayget(rich->objects, rich->objects->count - 2);
+
*op = *o1;
op = o1;
}
+ if (rich->objects->count > 2) {
+ (*(op - 2))->next = *op;
+ }
+
obj = mallocz(sizeof(Object), 1);
*op = obj;
+ obj->offset = rich->text->count;
+
+ print("offset %ulld\n", obj->offset);
+
+ obj->id = smprint("%ulld", rich->idcount++);
+ obj->font = font;
+ obj->text = rich->text;
+
obj->dtext = arraycreate(sizeof(char), 4096, nil);
obj->dfont = arraycreate(sizeof(char), 4096, nil);
obj->dlink = arraycreate(sizeof(char), 4096, nil);
obj->dimage = arraycreate(sizeof(char), 4096, nil);
- if (text != nil) {
- char *p;
- p = arraygrow(obj->dtext, strlen(text));
- memcpy(p, text, strlen(text));
+ if (p != nil) {
+ char *pp;
+ pp = arraygrow(obj->dtext, n);
+ memcpy(pp, p, n);
- p = arraygrow(rich->text, strlen(text));
- memcpy(p, text, strlen(text));
+ pp = arraygrow(rich->text, n);
+ memcpy(pp, p, n);
};
arraygrow(obj->dfont, strlen(font->name));
memcpy(obj->dfont->p, font->name, strlen(font->name));
- obj->id = smprint("%ulld", rich->idcount);
-
- obj->font = font;
-
- obj->text = rich->text;
- obj->offset = rich->text->count;
-
- rich->idcount++;
-
qunlock(rich->l);
return obj;
}
@@ -672,6 +686,9 @@ mkobjectftree(Object *obj, File *root)
auxlink = fauxalloc(obj, obj->dlink, FT_LINK);
auximage = fauxalloc(obj, obj->dimage, FT_IMAGE);
+ auxtext->read = textread;
+ auxtext->write = textwrite;
+
obj->ftext = createfile(obj->dir, "text", "richterm", 0666, auxtext);
obj->ffont = createfile(obj->dir, "font", "richterm", 0666, auxfont);
obj->flink = createfile(obj->dir, "link", "richterm", 0666, auxlink);
@@ -895,3 +912,65 @@ mplumb(Rich *)
{
}
+void
+_drawchar(char *p, Point pt, Font *font, Image *fg, Image *bg)
+{
+ Point ptact, ptnew;
+ ptact = subpt(addpt(pt, rich.page.r.min), rich.page.scroll);
+ ptnew = stringnbg(screen, ptact, fg, ZP, font, p, 1, bg, ZP);
+}
+
+void
+drawchar(Object *obj, long n, Point *cur)
+{
+ int tab, cw;
+ char *p;
+ p = arrayget(rich.text, n);
+ cw = stringnwidth(obj->font, p, 1);
+
+ if (cur->x + cw > Dx(rich.page.r)) {
+ cur->x = 0;
+ cur->y += obj->font->height;
+ }
+
+ switch (*p) {
+ case '\n':
+ cur->x = 0;
+ cur->y += obj->font->height;
+// obj->nextlinept.y = cur->y + obj->font->height;
+ break;
+ case '\t':
+ tab = stringwidth(font, "0") * 4;
+ cur->x = (cur->x / tab + 1) * tab;
+ break;
+ default:
+ _drawchar(p, *cur, obj->font, Itext, Inormbg);
+ cur->x += cw;
+ }
+}
+
+void
+drawobject(Object *obj, Point *cur)
+{
+ long i, n;
+ if (obj->next == nil) n = rich.text->count;
+ else n = obj->next->offset;
+ for (i = obj->offset; i < n; i++) {
+ drawchar(obj, i, cur);
+ }
+}
+
+void
+newdraw(void)
+{
+ Point cur, nextlinept;
+ Object **op;
+ long i;
+
+ cur = ZP;
+ nextlinept = cur;
+ for (i = 0; i < rich.objects->count; i++) {
+ op = arrayget(rich.objects, i);
+ drawobject(*op, &cur);
+ }
+}
+\ No newline at end of file
diff --git a/richterm.h b/richterm.h
@@ -19,6 +19,10 @@ struct Object {
Array *text;
usize offset;
+ Object *next;
+ Point startpt;
+ Point endpt;
+ Point nextlinept;
};
extern Object *olast;
@@ -72,7 +76,7 @@ extern Rich rich;
void drawpage(Image *, Rich *);
void generatepage(Rich *, long);
-Object * newobject(Rich *, char *);
+Object * newobject(Rich *, char *, long);
typedef struct Devfsctl Devfsctl;
@@ -100,8 +104,8 @@ struct Faux {
int type;
Object *obj;
Array *data;
- void (*read)(Req *);
- void (*write)(Req *);
+ void (*read)(Req *, void *);
+ void (*write)(Req *, void *);
};
enum {
@@ -113,7 +117,7 @@ enum {
Faux * fauxalloc(Object *, Array *, int);
-void textread(Req *);
-void textwrite(Req *);
-void arrayread(Req *);
-void arraywrite(Req *);
+void textread(Req *, void *);
+void textwrite(Req *, void *);
+void arrayread(Req *, void *);
+void arraywrite(Req *, void *);