Commit c5b7a7d2 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Input: smooth out mouse jitter

From: Dmitry Torokhov <dtor_core@ameritech.net>

When calculating deltas for touchpads that generate absolute events use
average over the last 3 packets to remove jitter
parent a15092bd
...@@ -553,16 +553,19 @@ static void synaptics_process_packet(struct psmouse *psmouse) ...@@ -553,16 +553,19 @@ static void synaptics_process_packet(struct psmouse *psmouse)
finger_width = 0; finger_width = 0;
} }
/* Post events */ /* Post events
* BTN_TOUCH has to be first as mousedev relies on it when doing
* absolute -> relative conversion
*/
if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
if (hw.z > 0) { if (hw.z > 0) {
input_report_abs(dev, ABS_X, hw.x); input_report_abs(dev, ABS_X, hw.x);
input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y); input_report_abs(dev, ABS_Y, YMAX_NOMINAL + YMIN_NOMINAL - hw.y);
} }
input_report_abs(dev, ABS_PRESSURE, hw.z); input_report_abs(dev, ABS_PRESSURE, hw.z);
if (hw.z > 30) input_report_key(dev, BTN_TOUCH, 1);
if (hw.z < 25) input_report_key(dev, BTN_TOUCH, 0);
input_report_abs(dev, ABS_TOOL_WIDTH, finger_width); input_report_abs(dev, ABS_TOOL_WIDTH, finger_width);
input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1); input_report_key(dev, BTN_TOOL_FINGER, num_fingers == 1);
input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); input_report_key(dev, BTN_TOOL_DOUBLETAP, num_fingers == 2);
......
...@@ -53,12 +53,14 @@ struct mousedev_list { ...@@ -53,12 +53,14 @@ struct mousedev_list {
struct fasync_struct *fasync; struct fasync_struct *fasync;
struct mousedev *mousedev; struct mousedev *mousedev;
struct list_head node; struct list_head node;
int dx, dy, dz, oldx, oldy; int dx, dy, dz;
signed char ps2[6]; int old_x[4], old_y[4];
unsigned long buttons; unsigned long buttons;
signed char ps2[6];
unsigned char ready, buffer, bufsiz; unsigned char ready, buffer, bufsiz;
unsigned char mode, imexseq, impsseq; unsigned char mode, imexseq, impsseq;
int finger; unsigned int pkt_count;
unsigned char touch;
}; };
#define MOUSEDEV_SEQ_LEN 6 #define MOUSEDEV_SEQ_LEN 6
...@@ -74,49 +76,49 @@ static struct mousedev mousedev_mix; ...@@ -74,49 +76,49 @@ static struct mousedev mousedev_mix;
static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X; static int xres = CONFIG_INPUT_MOUSEDEV_SCREEN_X;
static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
#define fx(i) (list->old_x[(list->pkt_count - (i)) & 03])
#define fy(i) (list->old_y[(list->pkt_count - (i)) & 03])
static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value) static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value)
{ {
int size; int size;
int touchpad;
/* Ignore joysticks */ /* Ignore joysticks */
if (test_bit(BTN_TRIGGER, handle->dev->keybit)) if (test_bit(BTN_TRIGGER, handle->dev->keybit))
return; return;
/* Handle touchpad data */ touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit);
if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
if (list->finger && list->finger < 3)
list->finger++;
switch (code) {
case ABS_X:
if (list->finger == 3)
list->dx += (value - list->oldx) / 8;
list->oldx = value;
return;
case ABS_Y:
if (list->finger == 3)
list->dy -= (value - list->oldy) / 8;
list->oldy = value;
return;
}
return;
}
/* Handle tablet data */
switch (code) { switch (code) {
case ABS_X: case ABS_X:
size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X]; if (touchpad) {
if (size == 0) size = xres; if (list->touch) {
list->dx += (value * xres - list->oldx) / size; fx(0) = value;
list->oldx += list->dx * size; if (list->pkt_count >= 2)
return; list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
}
} else {
size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
if (size == 0) size = xres;
list->dx += (value * xres - list->old_x[0]) / size;
list->old_x[0] += list->dx * size;
}
break;
case ABS_Y: case ABS_Y:
size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y]; if (touchpad) {
if (size == 0) size = yres; if (list->touch) {
list->dy -= (value * yres - list->oldy) / size; fy(0) = value;
list->oldy -= list->dy * size; if (list->pkt_count >= 2)
return; list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
}
} else {
size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
if (size == 0) size = yres;
list->dy -= (value * yres - list->old_y[0]) / size;
list->old_y[0] -= list->dy * size;
}
break;
} }
} }
...@@ -149,7 +151,9 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig ...@@ -149,7 +151,9 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
switch (code) { switch (code) {
case BTN_TOUCH: /* Handle touchpad data */ case BTN_TOUCH: /* Handle touchpad data */
if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) { if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
list->finger = value; list->touch = value;
if (!list->touch)
list->pkt_count = 0;
return; return;
} }
case BTN_0: case BTN_0:
...@@ -178,6 +182,16 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig ...@@ -178,6 +182,16 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
case EV_SYN: case EV_SYN:
switch (code) { switch (code) {
case SYN_REPORT: case SYN_REPORT:
if (list->touch) {
list->pkt_count++;
/* Input system eats duplicate events,
* but we need all of them to do correct
* averaging so apply present one forward
*/
fx(0) = fx(1);
fy(0) = fy(1);
}
list->ready = 1; list->ready = 1;
kill_fasync(&list->fasync, SIGIO, POLL_IN); kill_fasync(&list->fasync, SIGIO, POLL_IN);
wake = 1; wake = 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment