diff options
| author | Lena <lena@omega> | 2026-01-01 00:00:00 +0000 |
|---|---|---|
| committer | Lena <lena@omega> | 2026-01-01 00:00:00 +0000 |
| commit | 2fa72ee0dc67d973330aec4ba98260e9f57f7821 (patch) | |
| tree | e6a25c07c8da61d29e4e1f8a72436565e63c5777 /main.c | |
| download | mouseboard-0.1.tar.gz | |
Keyboard-only pointing: a labelled grid over every monitor, type a
label to jump to a cell, bisect it by quadrant until the crosshair is
exact, then one key clicks. The coarse grid keeps labels short and
bisection keeps precision unlimited, so a hotkey and a few keystrokes
replace the mouse.
The core talks only to the backend interface in platform.h; wlroots
Wayland and Win32 backends supply the overlay, keyboard grab and
pointer.
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 131 |
1 files changed, 131 insertions, 0 deletions
@@ -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; +} |