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 | 
