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:
M | fs.c | | | 10 | ++++++---- |
M | richterm.c | | | 72 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- |
M | richterm.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);