diff options
author | Marvin Raaijmakers <marvin_raaijmakers@linux-box.nl> | 2007-03-14 22:50:42 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2007-03-14 22:50:42 -0400 |
commit | c8e4c77277ca5db0c4ddbfb4bc628b8abad585b0 (patch) | |
tree | 07bebb34767c8c3bd0902d6c2be3f4819b30a7bf /drivers/input/evdev.c | |
parent | 55e3d9224b60df0fd2dc36bff9b538ce40fd9586 (diff) |
Input: add getkeycode and setkeycode methods
Allow drivers to implement their own get and set keycode methods. This
will allow drivers to change their keymaps without allocating huge
tables covering entire range of possible scancodes.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r-- | drivers/input/evdev.c | 29 |
1 files changed, 9 insertions, 20 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 6439f378f6cc..64b47de052bb 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -434,32 +434,21 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd, | |||
434 | case EVIOCGKEYCODE: | 434 | case EVIOCGKEYCODE: |
435 | if (get_user(t, ip)) | 435 | if (get_user(t, ip)) |
436 | return -EFAULT; | 436 | return -EFAULT; |
437 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) | 437 | |
438 | return -EINVAL; | 438 | error = dev->getkeycode(dev, t, &v); |
439 | if (put_user(INPUT_KEYCODE(dev, t), ip + 1)) | 439 | if (error) |
440 | return error; | ||
441 | |||
442 | if (put_user(v, ip + 1)) | ||
440 | return -EFAULT; | 443 | return -EFAULT; |
444 | |||
441 | return 0; | 445 | return 0; |
442 | 446 | ||
443 | case EVIOCSKEYCODE: | 447 | case EVIOCSKEYCODE: |
444 | if (get_user(t, ip)) | 448 | if (get_user(t, ip) || get_user(v, ip + 1)) |
445 | return -EFAULT; | ||
446 | if (t < 0 || t >= dev->keycodemax || !dev->keycodesize) | ||
447 | return -EINVAL; | ||
448 | if (get_user(v, ip + 1)) | ||
449 | return -EFAULT; | 449 | return -EFAULT; |
450 | if (v < 0 || v > KEY_MAX) | ||
451 | return -EINVAL; | ||
452 | if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8))) | ||
453 | return -EINVAL; | ||
454 | |||
455 | u = SET_INPUT_KEYCODE(dev, t, v); | ||
456 | clear_bit(u, dev->keybit); | ||
457 | set_bit(v, dev->keybit); | ||
458 | for (i = 0; i < dev->keycodemax; i++) | ||
459 | if (INPUT_KEYCODE(dev, i) == u) | ||
460 | set_bit(u, dev->keybit); | ||
461 | 450 | ||
462 | return 0; | 451 | return dev->setkeycode(dev, t, v); |
463 | 452 | ||
464 | case EVIOCSFF: | 453 | case EVIOCSFF: |
465 | if (copy_from_user(&effect, p, sizeof(effect))) | 454 | if (copy_from_user(&effect, p, sizeof(effect))) |