richterm

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

commit b1172113893fc77e2f8174c6e55bc19583d5272d
parent 5d10869872e8e20d22b0ecf875fb93ed16c587ca
Author: Pavel Renev <an2qzavok@gmail.com>
Date:   Thu, 26 Aug 2021 22:49:00 +0000

add file "menu" in which users can write additional items for right-clink menu

Diffstat:
Mfs.c | 10++++++----
Mrichterm.c | 72+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
Mrichterm.h | 1+
3 files changed, 72 insertions(+), 11 deletions(-)

diff --git a/fs.c b/fs.c @@ -8,11 +8,11 @@ #include "array.h" #include "richterm.h" -File *new, *ctl, *text, *cons, *consctl; +File *new, *ctl, *text, *cons, *consctl, *menu; Object *newobj; File *fsroot; Channel *consc, *ctlc; -Array *consbuf, *ctlbuf; +Array *consbuf, *ctlbuf, *menubuf; void fs_open(Req *); void fs_read(Req *); @@ -40,6 +40,7 @@ initfs(char *srvname) }; newobj = nil; consbuf = nil; + menubuf = arraycreate(sizeof(char), 1024, nil); consc = chancreate(sizeof(Array *), 1024); ctlc = chancreate(sizeof(Array *), 1024); srv.tree = alloctree("richterm", "richterm", DMDIR|0555, nil); @@ -54,6 +55,8 @@ initfs(char *srvname) fauxalloc(nil, nil, consread, conswrite)); consctl = createfile(fsroot, "consctl", "richterm", 0666, fauxalloc(nil, nil, nil, nil)); + menu = createfile(fsroot, "menu", "richterm", 0666, + fauxalloc(nil, menubuf, arrayread, arraywrite)); threadpostmountsrv(&srv, srvname, "/mnt/richterm", MREPL); return 0; } @@ -359,4 +362,4 @@ newread(Req *r) { readstr(r, newobj->id); return nil; -} -\ No newline at end of file +} diff --git a/richterm.c b/richterm.c @@ -53,8 +53,17 @@ void (*rfunc[])(Object *) = {rfollow, rsnarf, rplumb, nil}; char * rgen(int); Menu rmenu = { - .item = ritems, - .gen = nil, + .item = nil, + .gen = rgen, + .lasthit = 0, +}; + +char * rusergen(int); +void ruseract(int); + +Menu rusermenu = { + .item = nil, + .gen = rusergen, .lasthit = 0, }; @@ -103,6 +112,9 @@ threadmain(int argc, char **argv) if ((kctl = initkeyboard(nil)) == nil) sysfatal("%s: %r", argv0); + display->locking = 1; + unlockdisplay(display); + Iscrollbar = allocimage( display, Rect(0,0,1,1), screen->chan, 1, 0x999999FF); Inormbg = allocimage( @@ -175,10 +187,12 @@ threadmain(int argc, char **argv) nbsend(redrawc, nil); break; case REDRAW: + lockdisplay(display); draw(screen, screen->r, Inormbg, nil, ZP); redraw(ov); drawscrollbar(); flushimage(display, 1); + unlockdisplay(display); break; case INSERT: obj = objectcreate(); @@ -333,7 +347,13 @@ mouse(Mousectl *mc, Mouse mv, int *mmode) obj = getobj(mv.xy); if ((obj != nil) && (obj->dlink->count > 0)) { f = menuhit(3, mc, &rmenu, nil); - if (f >= 0) rfunc[f](obj); + if (f >= 0) { + if (f >= sizeof(ritems) - 1) ruseract(f - 2); + else rfunc[f](obj); + } + } else if (menubuf->count > 0) { + f = menuhit(3, mc, &rusermenu, nil); + if (f >= 0) ruseract(f); } *mmode = MM_NONE; } @@ -792,10 +812,8 @@ objsettext(Object *obj, char *data, long count) char * rgen(int n) { - if (n < sizeof (ritems)) return ritems[n]; - /* TODO: - if n>ritems, return items from /menu file (doesn't exist yet) */ - return nil; + if (n < 3) return ritems[n]; + else return rusergen(n - 3); } void @@ -843,3 +861,43 @@ rplumb(Object *obj) close(pd); } } + +void +ruseract(int f) +{ + Array *a; + char *s; + s = rusergen(f); + a = arraycreate(sizeof(char), 2048, nil); + arraygrow(a, 5, "menu "); + arraygrow(a, strlen(s), s); + arraygrow(a, 1, "\n"); + nbsend(ctlc, &a); +} + +char genbuf[1024]; + + +char * +rusergen(int f) +{ + int i, k; + char *ps, *pe; + memset(genbuf, 0, sizeof(genbuf)); + ps = menubuf->p; + for (k = 0, i = 0; (k != f) && (i < menubuf->count); i++) { + if (menubuf->p[i] == '\n') { + ps = menubuf->p + i; + k++; + } + } + if (k != f) return nil; + ps++; i++; + for (pe = ps; i < menubuf->count; i++, pe++) { + if (*pe == '\n') break; + } + if (pe == '\0') return nil; + if (ps == pe) return nil; + memcpy(genbuf, ps, pe - ps - 1); + return genbuf; +} diff --git a/richterm.h b/richterm.h @@ -3,6 +3,7 @@ extern Channel *insertc; extern Channel *consc; extern Channel *ctlc; extern File *fsroot; +extern Array *menubuf; void drawscrollbar(void);