aboutsummaryrefslogtreecommitdiff
path: root/fastmouse.patch
diff options
context:
space:
mode:
Diffstat (limited to 'fastmouse.patch')
-rw-r--r--fastmouse.patch159
1 files changed, 136 insertions, 23 deletions
diff --git a/fastmouse.patch b/fastmouse.patch
index 6670742..d525668 100644
--- a/fastmouse.patch
+++ b/fastmouse.patch
@@ -1,5 +1,43 @@
+diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
+index 4497b50799db..5a64a10b06da 100644
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1680,6 +1680,8 @@ static void hid_process_report(struct hid_device *hid,
+ unsigned int a;
+ struct hid_field_entry *entry;
+ struct hid_field *field;
++ struct input_dev *fastmouse_dev = NULL;
++
+
+ /* first retrieve all incoming values in data */
+ for (a = 0; a < report->maxfield; a++)
+@@ -1692,6 +1694,10 @@ static void hid_process_report(struct hid_device *hid,
+ list) {
+ field = entry->field;
+
++ if (hid->type == HID_TYPE_USBMOUSE && field->hidinput) {
++ fastmouse_dev = field->hidinput->input;
++ }
++
+ if (field->flags & HID_MAIN_ITEM_VARIABLE)
+ hid_process_event(hid,
+ field,
+@@ -1721,6 +1727,13 @@ static void hid_process_report(struct hid_device *hid,
+ hid_input_array_field(hid, field, interrupt);
+ }
+ }
++
++
++ if (fastmouse_dev) {
++ fastmouse_input_emit(fastmouse_dev);
++ }
++
++
+ }
+
+ /*
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c
-index 9d80635a91eb..8c8a7483261f 100644
+index 9d80635a91eb..56e1bb7b7023 100644
--- a/drivers/hid/hid-input.c
+++ b/drivers/hid/hid-input.c
@@ -14,6 +14,7 @@
@@ -10,21 +48,32 @@ index 9d80635a91eb..8c8a7483261f 100644
#include <linux/slab.h>
#include <linux/kernel.h>
-@@ -1505,6 +1506,87 @@ static void hid_report_set_tool(struct hid_report *report, struct input_dev *inp
+@@ -1505,6 +1506,150 @@ static void hid_report_set_tool(struct hid_report *report, struct input_dev *inp
report->tool = new_tool;
}
+struct fastmouse_state {
+ int division;
-+ long x, y;
++ long frame_x, frame_y;
++ long accum_x, accum_y;
+ int rise, run;
++ /* TODO
++ int polling_rate;
++ long accel;
++ */
+};
+static struct fastmouse_state fastmouse = {
+ .division = 1,
-+ .x = 0,
-+ .y = 0,
++ .frame_x = 0,
++ .frame_y = 0,
++ .accum_x = 0,
++ .accum_y = 0,
+ .rise = 0,
+ .run = INT_MAX,
++ /* TODO
++ .polling_rate = 4000,
++ .accel = 1,
++ */
+};
+
+static int set_division(const char *val, const struct kernel_param *kp) {
@@ -69,42 +118,94 @@ index 9d80635a91eb..8c8a7483261f 100644
+module_param_cb(run, &run_ops, &fastmouse.run, 0664);
+MODULE_PARM_DESC(run, "Mouse movement run amount (default: INT_MAX)");
+
-+static void fastmouse_handle_motion(const long in_x, const long in_y) {
-+ const long rise = fastmouse.rise / fastmouse.division;
-+ const long run = fastmouse.run / fastmouse.division;
-+ fastmouse.x += in_x * run - in_y * rise;
-+ fastmouse.y += in_x * rise + in_y * run;
++/* 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)");
++*/
+
-+static void input_event_fastmouse(struct input_dev *input, const unsigned int type, const unsigned int code, __s32 value) {
-+ const long in_x = (code == REL_X) * value;
-+ const long in_y = (code == REL_Y) * value;
++static void input_event_fastmouse_log(
++ struct input_dev *input,
++ const unsigned int type,
++ const unsigned int code,
++ __s32 value) {
++ fastmouse.frame_x += (code == REL_X) * value;
++ fastmouse.frame_y += (code == REL_Y) * value;
++}
+
-+ fastmouse_handle_motion(in_x, in_y);
++/* 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;
++}
++*/
+
-+ const long emit_x = fastmouse.x / INT_MAX;
++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, type, REL_X, emit_x);
++ input_event(input, EV_REL, REL_X, emit_x);
+ }
-+ const long emit_y = fastmouse.y / INT_MAX;
++ const long emit_y = fastmouse.accum_y / INT_MAX;
+ if (emit_y != 0) {
-+ input_event(input, type, REL_Y, emit_y);
++ input_event(input, EV_REL, REL_Y, emit_y);
+ }
-+
-+ fastmouse.x %= INT_MAX;
-+ fastmouse.y %= INT_MAX;
++ fastmouse.accum_x %= INT_MAX;
++ fastmouse.accum_y %= INT_MAX;
++
++ fastmouse.frame_x = fastmouse.frame_y = 0;
+}
+
void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value)
{
struct input_dev *input;
-@@ -1713,7 +1795,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
+@@ -1713,7 +1858,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
(!test_bit(usage->code, input->key)) == value)
input_event(input, EV_MSC, MSC_SCAN, usage->hid);
- input_event(input, usage->type, usage->code, value);
+ if (hid->type == HID_TYPE_USBMOUSE && usage->type == EV_REL) {
-+ input_event_fastmouse(input, usage->type, usage->code, value);
++ input_event_fastmouse_log(input, usage->type, usage->code, value);
+ } else {
+ input_event(input, usage->type, usage->code, value);
+ }
@@ -112,3 +213,15 @@ index 9d80635a91eb..8c8a7483261f 100644
if ((field->flags & HID_MAIN_ITEM_RELATIVE) &&
usage->type == EV_KEY && value) {
+diff --git a/include/linux/hid.h b/include/linux/hid.h
+index cdc0dc13c87f..8321d637b112 100644
+--- a/include/linux/hid.h
++++ b/include/linux/hid.h
+@@ -940,6 +940,7 @@ extern void hid_unregister_driver(struct hid_driver *);
+ module_driver(__hid_driver, hid_register_driver, \
+ hid_unregister_driver)
+
++extern void fastmouse_input_emit(struct input_dev *input);
+ extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32);
+ extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report);
+ extern int hidinput_connect(struct hid_device *hid, unsigned int force);