ref: a85496cea4c5c62a2038b1b488f541e9030ff379
parent: a6875be771d0b79f59abe6529231d294094b4a23
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Tue Aug 24 09:30:23 EDT 2021
piper: do not keep ctl files open
--- a/cfg/cfg.c
+++ b/cfg/cfg.c
@@ -20,6 +20,7 @@
int index;
uvlong qidpath;
+ int fd;
int ivalue;
double value;
@@ -28,7 +29,6 @@
double max;
double step;
- int ctl;
int flags;
char *group;
@@ -35,6 +35,7 @@
char *name;
char *unit;
+ char *ctlpath;
char *path;
UI **child;
int numchild;
@@ -81,17 +82,31 @@
}
static int
-readctl(UI *ui)
+initctl(UI *ui, char *path)
{
Biobuf b;
char *s, *k;
- int i;
+ int i, fd;
+ Dir *d;
+ if ((fd = open(path, OREAD)) < 0) {
+ fprint(2, "%r\n");
+ return -1;
+ }
+ if ((d = dirfstat(fd)) == nil) {
+ fprint(2, "%r\n");
+ close(fd);
+ return -1;
+ }
+ free(d);
+
+ ui->ctlpath = path;
+ ui->qidpath = d->qid.path;
ui->type = -1;
ui->show = 1; /* show everything by default */
- seek(ui->ctl, 0, 0);
- Binit(&b, ui->ctl, OREAD);
+ Binit(&b, fd, OREAD);
+
if ((s = Brdstr(&b, '\n', 1)) != nil && (k = strtok(s, "\t")) != nil) {
for (i = 0; i < nelem(uitypenames); i++) {
if (strcmp(k, uitypenames[i]) == 0) {
@@ -104,8 +119,6 @@
case UITGroup:
case UIHGroup:
case UIVGroup:
- close(ui->ctl);
- ui->ctl = -1;
break;
case UIButton:
case UICheckBox:
@@ -129,8 +142,9 @@
}
}
free(s);
-
+ close(fd);
Bterm(&b);
+
return 0;
}
@@ -138,7 +152,7 @@
newui(char *path)
{
UI *ui;
- Dir *dirs, *d;
+ Dir *dirs;
char *s, *name, tmp[64];
long i, n;
int f;
@@ -150,7 +164,7 @@
return nil;
ui = calloc(1, sizeof(*ui));
ui->path = strdup(path);
- ui->ctl = -1;
+ ui->fd = -1;
if ((s = strrchr(ui->path, '/')) == nil && fd2path(f, tmp, sizeof(tmp)) == 0) {
if ((s = strrchr(tmp, '/')) == nil)
@@ -171,11 +185,8 @@
} else if (strcmp(name, "clone") == 0) {
ui->flags |= Hasclone;
} else if (strcmp(name, "ctl") == 0) {
- ui->ctl = open(s, ORDWR);
- if (readctl(ui) == 0 && ui->ctl >= 0 && (d = dirfstat(ui->ctl)) != nil) {
- ui->qidpath = d->qid.path;
- free(d);
- }
+ if (initctl(ui, s) == 0)
+ s = nil;
} else if (dirs[i].mode & DMDIR) {
ui->child = realloc(ui->child, (ui->numchild+1) * sizeof(*ui->child));
ui->child[ui->numchild++] = newui(s);
@@ -187,7 +198,29 @@
return ui;
}
+static int
+uiwrite(UI *ui, char *s, int n)
+{
+ if (ui->ctlpath == nil)
+ return -1;
+
+ if (ui->fd < 0 && (ui->fd = open(ui->ctlpath, OWRITE)) < 0) {
+ fprint(2, "%r\n");
+ return -1;
+ }
+
+ return write(ui->fd, s, n);
+}
+
static void
+uidone(UI *ui)
+{
+ if (ui->fd >= 0)
+ close(ui->fd);
+ ui->fd = -1;
+}
+
+static void
process_ui(UI *w)
{
UI *c, *slider;
@@ -217,19 +250,24 @@
break;
case UIButton:
if (mu_button(c->label) & MU_RES_SUBMIT) {
- if (write(c->ctl, "1", 1) > 0)
+ if (uiwrite(c, "1", 1) > 0)
c->value = 1;
+ uidone(c);
} else if (c->value) {
id = mu_get_id(c->label, strlen(c->label));
if (mu_ctx.focus != id || mu_ctx.mouse_down != MU_MOUSE_LEFT) {
- if (write(c->ctl, "0", 1) > 0)
+ if (uiwrite(c, "0", 1) > 0)
c->value = 0;
+ uidone(c);
}
}
break;
case UICheckBox:
- if (mu_checkbox(&c->ivalue, c->label) & MU_RES_CHANGE && write(c->ctl, c->ivalue ? "1" : "0", 1) < 0)
- c->value = c->ivalue;
+ if (mu_checkbox(&c->ivalue, c->label) & MU_RES_CHANGE) {
+ if (uiwrite(c, c->ivalue ? "1" : "0", 1) < 0)
+ c->value = c->ivalue;
+ uidone(c);
+ }
break;
case UIVSlider: /* FIXME no vslider in µui yet */
case UIHSlider:
@@ -254,8 +292,9 @@
snprint(tmp, sizeof(tmp), "%%g%s", c->unit == nil ? "" : c->unit);
if (mu_slider_ex(&v, c->min, c->max, c->step, tmp, MU_OPT_ALIGNCENTER) & MU_RES_CHANGE) {
n = snprint(tmp, sizeof(tmp), "%g", v);
- if (write(c->ctl, tmp, n) > 0)
+ if (uiwrite(c, tmp, n) > 0)
c->value = v;
+ uidone(c);
}
mu_pop_id();
case UINEntry: