You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
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>
This commit is contained in:
committed by
Dmitry Torokhov
parent
55e3d9224b
commit
c8e4c77277
@@ -299,6 +299,87 @@ void input_close_device(struct input_handle *handle)
|
||||
}
|
||||
EXPORT_SYMBOL(input_close_device);
|
||||
|
||||
static int input_fetch_keycode(struct input_dev *dev, int scancode)
|
||||
{
|
||||
switch (dev->keycodesize) {
|
||||
case 1:
|
||||
return ((u8 *)dev->keycode)[scancode];
|
||||
|
||||
case 2:
|
||||
return ((u16 *)dev->keycode)[scancode];
|
||||
|
||||
default:
|
||||
return ((u32 *)dev->keycode)[scancode];
|
||||
}
|
||||
}
|
||||
|
||||
static int input_default_getkeycode(struct input_dev *dev,
|
||||
int scancode, int *keycode)
|
||||
{
|
||||
if (!dev->keycodesize)
|
||||
return -EINVAL;
|
||||
|
||||
if (scancode < 0 || scancode >= dev->keycodemax)
|
||||
return -EINVAL;
|
||||
|
||||
*keycode = input_fetch_keycode(dev, scancode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int input_default_setkeycode(struct input_dev *dev,
|
||||
int scancode, int keycode)
|
||||
{
|
||||
int old_keycode;
|
||||
int i;
|
||||
|
||||
if (scancode < 0 || scancode >= dev->keycodemax)
|
||||
return -EINVAL;
|
||||
|
||||
if (keycode < 0 || keycode > KEY_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (!dev->keycodesize)
|
||||
return -EINVAL;
|
||||
|
||||
if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
|
||||
return -EINVAL;
|
||||
|
||||
switch (dev->keycodesize) {
|
||||
case 1: {
|
||||
u8 *k = (u8 *)dev->keycode;
|
||||
old_keycode = k[scancode];
|
||||
k[scancode] = keycode;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
u16 *k = (u16 *)dev->keycode;
|
||||
old_keycode = k[scancode];
|
||||
k[scancode] = keycode;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
u32 *k = (u32 *)dev->keycode;
|
||||
old_keycode = k[scancode];
|
||||
k[scancode] = keycode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
clear_bit(old_keycode, dev->keybit);
|
||||
set_bit(keycode, dev->keybit);
|
||||
|
||||
for (i = 0; i < dev->keycodemax; i++) {
|
||||
if (input_fetch_keycode(dev, i) == old_keycode) {
|
||||
set_bit(old_keycode, dev->keybit);
|
||||
break; /* Setting the bit twice is useless, so break */
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void input_link_handle(struct input_handle *handle)
|
||||
{
|
||||
list_add_tail(&handle->d_node, &handle->dev->h_list);
|
||||
@@ -978,6 +1059,12 @@ int input_register_device(struct input_dev *dev)
|
||||
dev->rep[REP_PERIOD] = 33;
|
||||
}
|
||||
|
||||
if (!dev->getkeycode)
|
||||
dev->getkeycode = input_default_getkeycode;
|
||||
|
||||
if (!dev->setkeycode)
|
||||
dev->setkeycode = input_default_setkeycode;
|
||||
|
||||
list_add_tail(&dev->node, &input_dev_list);
|
||||
|
||||
snprintf(dev->cdev.class_id, sizeof(dev->cdev.class_id),
|
||||
|
||||
Reference in New Issue
Block a user