summaryrefslogtreecommitdiff
path: root/common/rawaccel-userspace.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/rawaccel-userspace.hpp')
-rw-r--r--common/rawaccel-userspace.hpp113
1 files changed, 113 insertions, 0 deletions
diff --git a/common/rawaccel-userspace.hpp b/common/rawaccel-userspace.hpp
new file mode 100644
index 0000000..80fcecc
--- /dev/null
+++ b/common/rawaccel-userspace.hpp
@@ -0,0 +1,113 @@
+#pragma once
+
+#include <iostream>
+
+#include "external/clipp.h"
+
+#include "rawaccel.hpp"
+
+namespace rawaccel {
+
+inline constexpr int SYSTEM_ERROR = -1;
+inline constexpr int PARSE_ERROR = 1;
+inline constexpr int INVALID_ARGUMENT = 2;
+
+void error(const char* s) {
+ throw std::domain_error(s);
+}
+
+variables parse(int argc, char** argv) {
+ double degrees = 0;
+ vec2d sens = { 1, 1 };
+ accel_function::args_t accel_args{};
+
+ // default options
+ auto opt_sens = "sensitivity, <y> defaults to <x> (default = 1)" % (
+ clipp::option("sens") &
+ clipp::number("x", sens.x, sens.y) &
+ clipp::opt_number("y", sens.y)
+ );
+ auto opt_rot = "counter-clockwise rotation (default = 0)" % (
+ clipp::option("rotate") &
+ clipp::number("degrees", degrees)
+ );
+
+ // mode-independent accel options
+ auto opt_weight = "accel multiplier, <y> defaults to <x> (default = 1)" % (
+ clipp::option("weight") &
+ clipp::number("x", accel_args.weight.x, accel_args.weight.y) &
+ clipp::opt_number("y", accel_args.weight.y)
+ );
+ auto opt_offset = "speed (dots/ms) where accel kicks in (default = 0)" % (
+ clipp::option("offset") & clipp::number("speed", accel_args.offset)
+ );
+ auto opt_cap = "accel scale cap, <y> defaults to <x> (default = 9)" % (
+ clipp::option("cap") &
+ clipp::number("x", accel_args.cap.x, accel_args.cap.y) &
+ clipp::opt_number("y", accel_args.cap.y)
+ );
+ auto opt_tmin = "minimum time between polls (default = 0.4)" % (
+ clipp::option("tmin") &
+ clipp::number("ms", accel_args.time_min)
+ );
+
+ auto accel_var = (clipp::required("accel") & clipp::number("num", accel_args.accel)) % "ramp rate";
+ auto limit_var = (clipp::required("limit") & clipp::number("scale", accel_args.lim_exp)) % "limit";
+
+ // modes
+ auto noaccel_mode = "no-accel mode" % (
+ clipp::command("off", "noaccel").set(accel_args.accel_mode, mode::noaccel)
+ );
+ auto lin_mode = "linear accel mode:" % (
+ clipp::command("linear").set(accel_args.accel_mode, mode::linear),
+ accel_var
+ );
+ auto classic_mode = "classic accel mode:" % (
+ clipp::command("classic").set(accel_args.accel_mode, mode::classic),
+ accel_var,
+ (clipp::required("exponent") & clipp::number("num", accel_args.lim_exp)) % "exponent"
+ );
+ auto nat_mode = "natural accel mode:" % (
+ clipp::command("natural").set(accel_args.accel_mode, mode::natural),
+ accel_var,
+ limit_var
+ );
+ auto log_mode = "logarithmic accel mode:" % (
+ clipp::command("logarithmic").set(accel_args.accel_mode, mode::logarithmic),
+ accel_var
+ );
+ auto sig_mode = "sigmoid accel mode:" % (
+ clipp::command("sigmoid").set(accel_args.accel_mode, mode::sigmoid),
+ accel_var,
+ limit_var,
+ (clipp::required("midpoint") & clipp::number("speed", accel_args.midpoint)) % "midpoint"
+ );
+
+ auto accel_mode_exclusive = (lin_mode | classic_mode | nat_mode | log_mode | sig_mode);
+ auto accel_opts = "mode-independent accel options:" % (opt_offset, opt_cap, opt_weight, opt_tmin);
+
+ bool help = false;
+
+ auto cli = clipp::group(clipp::command("help").set(help)) | (
+ noaccel_mode | (accel_mode_exclusive, accel_opts),
+ opt_sens,
+ opt_rot
+ );
+
+ if (!clipp::parse(argc, argv, cli)) {
+ std::cout << clipp::usage_lines(cli, "rawaccel");
+ std::exit(PARSE_ERROR);
+ }
+
+ if (help) {
+ auto fmt = clipp::doc_formatting{}.first_column(4)
+ .doc_column(28)
+ .last_column(80);
+ std::cout << clipp::make_man_page(cli, "rawaccel", fmt);
+ std::exit(0);
+ }
+
+ return variables(-degrees, sens, accel_args);
+}
+
+} // rawaccel