diff options
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/setup.c | 124 | ||||
-rw-r--r-- | src/setup.h | 8 |
3 files changed, 133 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 9ee9d88..acb5c16 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS = modules bin_PROGRAMS = rototiller -rototiller_SOURCES = drmsetup.c drmsetup.h drm_fb.c drm_fb.h fb.c fb.h fps.c fps.h rototiller.c rototiller.h settings.h settings.c threads.c threads.h util.c util.h +rototiller_SOURCES = drmsetup.c drmsetup.h drm_fb.c drm_fb.h fb.c fb.h fps.c fps.h rototiller.c rototiller.h settings.h settings.c setup.h setup.c threads.c threads.h util.c util.h rototiller_LDADD = @ROTOTILLER_LIBS@ -lm modules/julia/libjulia.a modules/plasma/libplasma.a modules/ray/libray.a modules/roto/libroto.a modules/sparkler/libsparkler.a modules/stars/libstars.a rototiller_CPPFLAGS = @ROTOTILLER_CFLAGS@ diff --git a/src/setup.c b/src/setup.c new file mode 100644 index 0000000..6c4a87f --- /dev/null +++ b/src/setup.c @@ -0,0 +1,124 @@ +#include <assert.h> +#include <stdio.h> + +#include "settings.h" +#include "util.h" + +/* add key=value, but if key is NULL, use value as key. */ +static int add_value(settings_t *settings, const char *key, const char *value) +{ + assert(settings); + + if (!key) { + key = value; + value = NULL; + } + + assert(key); + + return settings_add_value(settings, key, value); +} + + +/* returns negative on error, otherwise number of additions made to settings */ +int setup_interactively(settings_t *settings, int (*setup_func)(settings_t *settings, setting_desc_t **next), int defaults) +{ + unsigned additions = 0; + char buf[256] = "\n"; + setting_desc_t *next; + int r; + + assert(settings); + assert(setup_func); + + /* TODO: regex and error handling */ + + while ((r = setup_func(settings, &next)) > 0) { + additions++; + + if (!defaults) + puts(""); + + if (next->values) { + unsigned i, preferred = 0; + int width = 0; + + for (i = 0; next->values[i]; i++) { + int len; + + len = strlen(next->values[i]); + if (len > width) + width = len; + } + + /* multiple choice */ + if (!defaults) + printf("Select %s:\n", next->name); + + for (i = 0; next->values[i]; i++) { + if (!defaults) + printf(" %u: %*s%s%s\n", i, width, next->values[i], + next->annotations ? ": " : "", + next->annotations ? next->annotations[i] : ""); + + if (!strcmp(next->preferred, next->values[i])) + preferred = i; + } + + if (!defaults) + printf("Enter a value 0-%u [%u (%s)]: ", + i - 1, preferred, next->preferred); + } else { + /* arbitrarily typed input */ + if (!defaults) + printf("%s [%s]: ", next->name, next->preferred); + } + + if (!defaults) { + fflush(stdout); + fgets(buf, sizeof(buf), stdin); + } + + if (*buf == '\n') { + /* accept preferred */ + add_value(settings, next->key, next->preferred); + } else { + buf[strlen(buf) - 1] = '\0'; + + if (next->values) { + unsigned i, j, found; + + /* multiple choice, map numeric input to values entry */ + if (sscanf(buf, "%u", &j) < 1) { + printf("Invalid input: \"%s\"\n", buf); + + goto _next; + } + + for (found = i = 0; next->values[i]; i++) { + if (i == j) { + add_value(settings, next->key, next->values[i]); + found = 1; + break; + } + } + + if (!found) { + printf("Invalid option: %u outside of range [0-%u]\n", + j, i - 1); + + goto _next; + } + + } else { + /* use typed input as setting, TODO: apply regex */ + add_value(settings, next->key, buf); + } + } + +_next: + setting_desc_free(next); + } + + return r < 0 ? r : additions; +} diff --git a/src/setup.h b/src/setup.h new file mode 100644 index 0000000..2f190f4 --- /dev/null +++ b/src/setup.h @@ -0,0 +1,8 @@ +#ifndef _SETUP_H +#define _SETUP_H + +#include "settings.h" + +int setup_interactively(settings_t *settings, int (*setup_func)(settings_t *settings, setting_desc_t **next), int defaults); + +#endif |