aboutsummaryrefslogtreecommitdiff
path: root/src/fastmouse.h
diff options
context:
space:
mode:
authorNicolas James <Eele1Ephe7uZahRie@tutanota.com>2025-04-14 13:32:55 +1000
committerNicolas James <Eele1Ephe7uZahRie@tutanota.com>2025-04-14 13:32:55 +1000
commit1249653b654bca6caaecc407a2128c4f1ccabd52 (patch)
tree444622eb6c90217c54a2beb6044db1a68a38f495 /src/fastmouse.h
parent12ad6ebd615f57b7b1032953ab9ea9b29ca1bc87 (diff)
Move impl to header single file, fix linking etc
Diffstat (limited to 'src/fastmouse.h')
-rw-r--r--src/fastmouse.h184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/fastmouse.h b/src/fastmouse.h
index f1ee96a..2383de8 100644
--- a/src/fastmouse.h
+++ b/src/fastmouse.h
@@ -1,5 +1,189 @@
#ifndef FASTMOUSE_H_
#define FASTMOUSE_H_
+// Mock functionality and structs for user space unit tests.
+#ifndef __KERNEL__
+#include <climits>
+
+typedef int __s32;
+struct input_dev {};
+enum event_type {
+ EV_REL,
+};
+enum movement_type {
+ REL_X,
+ REL_Y,
+};
+struct mouse_movement {
+ int x = 0;
+ int y = 0;
+};
+static struct mouse_movement movement = {
+ .x = 0,
+ .y = 0,
+};
+static void input_event(input_dev*, event_type, movement_type code, int value) {
+ movement.x += (code == REL_X) * value;
+ movement.y += (code == REL_Y) * value;
+}
+#endif
+
+extern void input_event_fastmouse_log(
+ struct input_dev*,
+ const unsigned int,
+ const unsigned int code,
+ __s32 value);
+extern void fastmouse_input_emit(struct input_dev *input);
+
+struct fastmouse_state {
+ int division;
+ long frame_x, frame_y;
+ long accum_x, accum_y;
+ int rise, run;
+ /* TODO
+ int polling_rate;
+ long accel;
+ */
+};
+
+/* TODO (for accel)
+static unsigned __int128 i128_sqrt(const unsigned __int128 v) {
+ unsigned __int128 left = 0;
+ unsigned __int128 right = v;
+ while (left < right) {
+ const unsigned __int128 mid = left + ((right - left) / 2);
+ if (mid >= ~(u64)0 || mid * mid > v) {
+ right = mid;
+ } else if (mid * mid == v) {
+ return mid;
+ } else {
+ left = mid + 1;
+ }
+ }
+ return left != 0 ? left - 1 : 0;
+}
+*/
+
+#ifdef FASTMOUSE_IMPL
+static struct fastmouse_state fastmouse = {
+ .division = 1,
+ .frame_x = 0,
+ .frame_y = 0,
+ .accum_x = 0,
+ .accum_y = 0,
+ .rise = 0,
+ .run = INT_MAX,
+ /* TODO
+ .polling_rate = 4000,
+ .accel = 1,
+ */
+};
+
+void input_event_fastmouse_log(
+ struct input_dev*,
+ const unsigned int,
+ const unsigned int code,
+ __s32 value) {
+ fastmouse.frame_x += (code == REL_X) * value;
+ fastmouse.frame_y += (code == REL_Y) * value;
+}
+
+void fastmouse_input_emit(struct input_dev *input) {
+ const long rise = fastmouse.rise / fastmouse.division;
+ const long run = fastmouse.run / fastmouse.division;
+
+ fastmouse.accum_x += fastmouse.frame_x * run - fastmouse.frame_y * rise;
+ fastmouse.accum_y += fastmouse.frame_x * rise + fastmouse.frame_y * run;
+
+ const long emit_x = fastmouse.accum_x / INT_MAX;
+ if (emit_x != 0) {
+ input_event(input, EV_REL, REL_X, (__s32)emit_x);
+ }
+ const long emit_y = fastmouse.accum_y / INT_MAX;
+ if (emit_y != 0) {
+ input_event(input, EV_REL, REL_Y, (__s32)emit_y);
+ }
+ fastmouse.accum_x %= INT_MAX;
+ fastmouse.accum_y %= INT_MAX;
+
+ fastmouse.frame_x = fastmouse.frame_y = 0;
+}
+
+#ifdef __KERNEL__
+#include <linux/moduleparam.h>
+
+static int set_division(const char *val, const struct kernel_param *kp) {
+ const int ret = kstrtoint(val, 0, &fastmouse.division);
+ if (ret != 0 || fastmouse.division <= 0) {
+ return -EINVAL;
+ }
+ return ret;
+}
+static const struct kernel_param_ops division_ops = {
+ .set = set_division,
+ .get = param_get_int,
+};
+module_param_cb(division, &division_ops, &fastmouse.division, 0664);
+MODULE_PARM_DESC(division, "Mouse movement division amount (default: 1)");
+
+static int set_rise(const char *val, const struct kernel_param *kp) {
+ const int ret = kstrtoint(val, 0, &fastmouse.rise);
+ if (ret != 0) {
+ return -EINVAL;
+ }
+ return ret;
+}
+static const struct kernel_param_ops rise_ops = {
+ .set = set_rise,
+ .get = param_get_int,
+};
+module_param_cb(rise, &rise_ops, &fastmouse.rise, 0664);
+MODULE_PARM_DESC(rise, "Mouse movement rise amount (default: 0)");
+
+static int set_run(const char *val, const struct kernel_param *kp) {
+ const int ret = kstrtoint(val, 0, &fastmouse.run);
+ if (ret != 0) {
+ return -EINVAL;
+ }
+ return ret;
+}
+static const struct kernel_param_ops run_ops = {
+ .set = set_run,
+ .get = param_get_int,
+};
+module_param_cb(run, &run_ops, &fastmouse.run, 0664);
+MODULE_PARM_DESC(run, "Mouse movement run amount (default: INT_MAX)");
+
+/* TODO
+static int set_polling_rate(const char *val, const struct kernel_param *kp) {
+ const int ret = kstrtoint(val, 0, &fastmouse.polling_rate);
+ if (ret != 0) {
+ return -EINVAL;
+ }
+ return ret;
+}
+static const struct kernel_param_ops poll_ops = {
+ .set = set_polling_rate,
+ .get = param_get_int,
+};
+module_param_cb(polling_rate, &poll_ops, &fastmouse.polling_rate, 0664);
+MODULE_PARM_DESC(polling_rate, "Mouse polling rate (default: 4000)");
+
+static int set_accel(const char *val, const struct kernel_param *kp) {
+ const int ret = kstrtol(val, 0, &fastmouse.accel);
+ if (ret != 0) {
+ return -EINVAL;
+ }
+ return ret;
+}
+static const struct kernel_param_ops accel_ops = {
+ .set = set_accel,
+ .get = param_get_int,
+};
+module_param_cb(acceleration, &accel_ops, &fastmouse.accel, 0664);
+MODULE_PARM_DESC(acceleration, "Mouse acceleration (default: 1)");
+*/
+#endif
+#endif
#endif \ No newline at end of file