Commit 9c99b2b0 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: mousedev - implement tapping for touchpads working in absolute

       mode, such as Synaptics
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent fadb62b6
...@@ -652,6 +652,12 @@ running once the system is up. ...@@ -652,6 +652,12 @@ running once the system is up.
mga= [HW,DRM] mga= [HW,DRM]
mousedev.tap_time=
[MOUSE] Maximum time between finger touching and
leaving touchpad surface for touch to be considered
a tap and be reported as a left button click (for
touchpads working in absolute mode only).
Format: <msecs>
mousedev.xres= [MOUSE] Horizontal screen resolution, used for devices mousedev.xres= [MOUSE] Horizontal screen resolution, used for devices
reporting absolute coordinates, such as tablets reporting absolute coordinates, such as tablets
mousedev.yres= [MOUSE] Vertical screen resolution, used for devices mousedev.yres= [MOUSE] Vertical screen resolution, used for devices
......
...@@ -30,8 +30,6 @@ config MOUSE_PS2 ...@@ -30,8 +30,6 @@ config MOUSE_PS2
and a new verion of GPM at: and a new verion of GPM at:
http://www.geocities.com/dt_or/gpm/gpm.html http://www.geocities.com/dt_or/gpm/gpm.html
to take advantage of the advanced features of the touchpad. to take advantage of the advanced features of the touchpad.
If you do not want install specialized drivers but want tapping
working please use option psmouse.proto=imps.
If unsure, say Y. If unsure, say Y.
......
...@@ -48,6 +48,10 @@ static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y; ...@@ -48,6 +48,10 @@ static int yres = CONFIG_INPUT_MOUSEDEV_SCREEN_Y;
module_param(yres, uint, 0); module_param(yres, uint, 0);
MODULE_PARM_DESC(yres, "Vertical screen resolution"); MODULE_PARM_DESC(yres, "Vertical screen resolution");
static unsigned tap_time = 200;
module_param(tap_time, uint, 0);
MODULE_PARM_DESC(tap_time, "Tap time for touchpads in absolute mode (msecs)");
struct mousedev_motion { struct mousedev_motion {
int dx, dy, dz; int dx, dy, dz;
unsigned long buttons; unsigned long buttons;
...@@ -65,7 +69,7 @@ struct mousedev { ...@@ -65,7 +69,7 @@ struct mousedev {
struct mousedev_motion packet; struct mousedev_motion packet;
unsigned int pkt_count; unsigned int pkt_count;
int old_x[4], old_y[4]; int old_x[4], old_y[4];
unsigned int touch; unsigned long touch;
}; };
enum mousedev_emul { enum mousedev_emul {
...@@ -216,6 +220,30 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_m ...@@ -216,6 +220,30 @@ static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_m
wake_up_interruptible(&mousedev->wait); wake_up_interruptible(&mousedev->wait);
} }
static void mousedev_touchpad_touch(struct mousedev *mousedev, int value)
{
if (!value) {
if (mousedev->touch &&
!time_after(jiffies, mousedev->touch + msecs_to_jiffies(tap_time))) {
/*
* Toggle left button to emulate tap.
* We rely on the fact that mousedev_mix always has 0
* motion packet so we won't mess current position.
*/
set_bit(0, &mousedev->packet.buttons);
set_bit(0, &mousedev_mix.packet.buttons);
mousedev_notify_readers(mousedev, &mousedev_mix.packet);
mousedev_notify_readers(&mousedev_mix, &mousedev_mix.packet);
clear_bit(0, &mousedev->packet.buttons);
clear_bit(0, &mousedev_mix.packet.buttons);
}
mousedev->touch = mousedev->pkt_count = 0;
}
else
if (!mousedev->touch)
mousedev->touch = jiffies;
}
static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
{ {
struct mousedev *mousedev = handle->private; struct mousedev *mousedev = handle->private;
...@@ -239,12 +267,8 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig ...@@ -239,12 +267,8 @@ static void mousedev_event(struct input_handle *handle, unsigned int type, unsig
case EV_KEY: case EV_KEY:
if (value != 2) { if (value != 2) {
if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) { if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
/* Handle touchpad data */ mousedev_touchpad_touch(mousedev, value);
mousedev->touch = value;
if (!mousedev->touch)
mousedev->pkt_count = 0;
}
else else
mousedev_key_event(mousedev, code, value); mousedev_key_event(mousedev, code, value);
} }
......
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