diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2012-08-10 15:39:38 -0400 |
---|---|---|
committer | Henrik Rydberg <rydberg@euromail.se> | 2012-09-19 13:50:17 -0400 |
commit | 0672120a2ee7c533dfec6db7c3e43450f439e5ff (patch) | |
tree | 5391ff51230e52c22ed4d5d8c1a6026cf87b1206 | |
parent | 7c75bf99271139ca7cb2d0cca3be11f1f7c59efd (diff) |
Input: Make sure we follow all EV_KEY events
For some EV_KEY types, sending a larger-than-one value causes the
input state to oscillate. This patch makes sure this cannot happen,
clearing up the autorepeat bypass logic in the process.
Tested-by: Benjamin Tissoires <benjamin.tissoires@enac.fr>
Tested-by: Ping Cheng <pingc@wacom.com>
Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
-rw-r--r-- | drivers/input/input.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index fb3a2c112deb..f075fbbfb1e7 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -240,24 +240,30 @@ static void input_handle_event(struct input_dev *dev, | |||
240 | break; | 240 | break; |
241 | 241 | ||
242 | case EV_KEY: | 242 | case EV_KEY: |
243 | if (is_event_supported(code, dev->keybit, KEY_MAX) && | 243 | if (is_event_supported(code, dev->keybit, KEY_MAX)) { |
244 | !!test_bit(code, dev->key) != value) { | 244 | |
245 | /* auto-repeat bypasses state updates */ | ||
246 | if (value == 2) { | ||
247 | disposition = INPUT_PASS_TO_HANDLERS; | ||
248 | break; | ||
249 | } | ||
250 | |||
251 | if (!!test_bit(code, dev->key) != !!value) { | ||
245 | 252 | ||
246 | if (value != 2) { | ||
247 | __change_bit(code, dev->key); | 253 | __change_bit(code, dev->key); |
254 | disposition = INPUT_PASS_TO_HANDLERS; | ||
255 | |||
248 | if (value) | 256 | if (value) |
249 | input_start_autorepeat(dev, code); | 257 | input_start_autorepeat(dev, code); |
250 | else | 258 | else |
251 | input_stop_autorepeat(dev); | 259 | input_stop_autorepeat(dev); |
252 | } | 260 | } |
253 | |||
254 | disposition = INPUT_PASS_TO_HANDLERS; | ||
255 | } | 261 | } |
256 | break; | 262 | break; |
257 | 263 | ||
258 | case EV_SW: | 264 | case EV_SW: |
259 | if (is_event_supported(code, dev->swbit, SW_MAX) && | 265 | if (is_event_supported(code, dev->swbit, SW_MAX) && |
260 | !!test_bit(code, dev->sw) != value) { | 266 | !!test_bit(code, dev->sw) != !!value) { |
261 | 267 | ||
262 | __change_bit(code, dev->sw); | 268 | __change_bit(code, dev->sw); |
263 | disposition = INPUT_PASS_TO_HANDLERS; | 269 | disposition = INPUT_PASS_TO_HANDLERS; |
@@ -284,7 +290,7 @@ static void input_handle_event(struct input_dev *dev, | |||
284 | 290 | ||
285 | case EV_LED: | 291 | case EV_LED: |
286 | if (is_event_supported(code, dev->ledbit, LED_MAX) && | 292 | if (is_event_supported(code, dev->ledbit, LED_MAX) && |
287 | !!test_bit(code, dev->led) != value) { | 293 | !!test_bit(code, dev->led) != !!value) { |
288 | 294 | ||
289 | __change_bit(code, dev->led); | 295 | __change_bit(code, dev->led); |
290 | disposition = INPUT_PASS_TO_ALL; | 296 | disposition = INPUT_PASS_TO_ALL; |