aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c131
1 files changed, 131 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..4f2b491
--- /dev/null
+++ b/main.c
@@ -0,0 +1,131 @@
+/* main.c - argument handling and wire-up. */
+#include "config.h"
+#include "core.h"
+#include "platform.h"
+
+#include <stdio.h>
+#include <string.h>
+
+/* Canonical version lives in the Makefile (VERSION), injected via -D; a
+ * release build stamps the git tag in that way. */
+#ifndef MOUSEBOARD_VERSION
+#define MOUSEBOARD_VERSION "0-dev"
+#endif
+
+static const char usage[] =
+ "usage: mouseboard [options]\n"
+ "\n"
+ "Draw a labelled grid, type a label to pick a cell, refine by\n"
+ "bisection (u/i/j/k), then click (m=left , =middle .=right ;=double\n"
+ "v=drag). Esc cancels, Backspace undoes.\n"
+ "\n"
+ " --config PATH config file (default $XDG_CONFIG_HOME/mouseboard/config)\n"
+ " --cell-size N target coarse-cell size in pixels\n"
+ " --cols N --rows N explicit grid instead of cell-size\n"
+ " --alphabet STR label characters\n"
+ " --opacity N backdrop opacity 0..100 (100 = solid)\n"
+ " --opacity-fg N label/grid/crosshair opacity 0..100\n"
+ " --dry-run print 'x y action' instead of clicking\n"
+ " --selftest run offline logic checks and exit\n"
+ " -h, --help this help\n"
+ " -V, --version version\n";
+
+/* Flags taking a value; each one sets a config key. */
+static const struct { const char *flag, *key; } opts[] = {
+ { "--cell-size", "cell_size" },
+ { "--cols", "cols" },
+ { "--rows", "rows" },
+ { "--alphabet", "alphabet" },
+ { "--opacity", "opacity_bg" },
+ { "--opacity-fg", "opacity_fg" },
+};
+
+int main(int argc, char **argv)
+{
+ platform_early_init();
+
+ struct config cfg;
+ config_defaults(&cfg);
+
+ const char *cfgpath = NULL; /* set only by --config */
+ int dry = 0;
+
+ /* Pass 1: handle exit-early flags and locate the config path. */
+ for (int i = 1; i < argc; i++) {
+ const char *a = argv[i];
+ if (!strcmp(a, "-h") || !strcmp(a, "--help")) {
+ fputs(usage, stdout);
+ return 0;
+ }
+ if (!strcmp(a, "-V") || !strcmp(a, "--version")) {
+ printf("mouseboard %s\n", MOUSEBOARD_VERSION);
+ return 0;
+ }
+ if (!strcmp(a, "--selftest"))
+ return core_selftest();
+ if (!strcmp(a, "--config")) {
+ if (++i >= argc) {
+ fprintf(stderr,
+ "mouseboard: %s needs an argument\n", a);
+ return 2;
+ }
+ cfgpath = argv[i];
+ }
+ }
+
+ /* Load the file (CLI flags below override it). */
+ int lr = config_load_file(&cfg,
+ cfgpath ? cfgpath : config_default_path());
+ if (lr == -1 && cfgpath) {
+ fprintf(stderr, "mouseboard: %s: not found\n", cfgpath);
+ return 2;
+ }
+ if (lr == -2)
+ return 2;
+
+ /* Pass 2: apply CLI overrides. */
+ for (int i = 1; i < argc; i++) {
+ const char *a = argv[i];
+ if (!strcmp(a, "--config")) {
+ i++;
+ continue;
+ }
+ if (!strcmp(a, "--dry-run")) {
+ dry = 1;
+ continue;
+ }
+ const char *key = NULL;
+ for (size_t o = 0; o < sizeof opts / sizeof opts[0]; o++)
+ if (!strcmp(a, opts[o].flag))
+ key = opts[o].key;
+ if (!key) {
+ fprintf(stderr, "mouseboard: unknown option %s\n", a);
+ fputs(usage, stderr);
+ return 2;
+ }
+ if (++i >= argc) {
+ fprintf(stderr, "mouseboard: %s needs an argument\n", a);
+ return 2;
+ }
+ if (config_set(&cfg, key, argv[i])) {
+ fprintf(stderr, "mouseboard: %s: bad value '%s'\n", a,
+ argv[i]);
+ return 2;
+ }
+ }
+
+ const char *invalid = config_validate(&cfg);
+ if (invalid) {
+ fprintf(stderr, "mouseboard: invalid configuration: %s\n", invalid);
+ return 2;
+ }
+ config_apply_opacity(&cfg);
+
+ struct platform *p = platform_init();
+ if (!p)
+ return 2;
+
+ int rc = core_run(p, &cfg, dry);
+ p->teardown(p);
+ return rc;
+}