Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 53400
b: refs/heads/master
c: c8e4c77
h: refs/heads/master
v: v3
  • Loading branch information
Marvin Raaijmakers authored and Dmitry Torokhov committed Mar 15, 2007
1 parent 3b46cbc commit 78164f3
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 97 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 55e3d9224b60df0fd2dc36bff9b538ce40fd9586
refs/heads/master: c8e4c77277ca5db0c4ddbfb4bc628b8abad585b0
71 changes: 23 additions & 48 deletions trunk/drivers/char/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,76 +159,51 @@ static int sysrq_alt_use;
static int sysrq_alt;

/*
* Translation of scancodes to keycodes. We set them on only the first attached
* keyboard - for per-keyboard setting, /dev/input/event is more useful.
* Translation of scancodes to keycodes. We set them on only the first
* keyboard in the list that accepts the scancode and keycode.
* Explanation for not choosing the first attached keyboard anymore:
* USB keyboards for example have two event devices: one for all "normal"
* keys and one for extra function keys (like "volume up", "make coffee",
* etc.). So this means that scancodes for the extra function keys won't
* be valid for the first event device, but will be for the second.
*/
int getkeycode(unsigned int scancode)
{
struct list_head *node;
struct input_dev *dev = NULL;
struct input_handle *handle;
int keycode;
int error = -ENODEV;

list_for_each(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
if (handle->dev->keycodesize) {
dev = handle->dev;
break;
}
list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
error = handle->dev->getkeycode(handle->dev, scancode, &keycode);
if (!error)
return keycode;
}

if (!dev)
return -ENODEV;

if (scancode >= dev->keycodemax)
return -EINVAL;

return INPUT_KEYCODE(dev, scancode);
return error;
}

int setkeycode(unsigned int scancode, unsigned int keycode)
{
struct list_head *node;
struct input_dev *dev = NULL;
unsigned int i, oldkey;
struct input_handle *handle;
int error = -ENODEV;

list_for_each(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
if (handle->dev->keycodesize) {
dev = handle->dev;
list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
error = handle->dev->setkeycode(handle->dev, scancode, keycode);
if (!error)
break;
}
}

if (!dev)
return -ENODEV;

if (scancode >= dev->keycodemax)
return -EINVAL;
if (keycode < 0 || keycode > KEY_MAX)
return -EINVAL;
if (dev->keycodesize < sizeof(keycode) && (keycode >> (dev->keycodesize * 8)))
return -EINVAL;

oldkey = SET_INPUT_KEYCODE(dev, scancode, keycode);

clear_bit(oldkey, dev->keybit);
set_bit(keycode, dev->keybit);

for (i = 0; i < dev->keycodemax; i++)
if (INPUT_KEYCODE(dev,i) == oldkey)
set_bit(oldkey, dev->keybit);

return 0;
return error;
}

/*
* Making beeps and bells.
*/
static void kd_nosound(unsigned long ignored)
{
struct list_head *node;
struct input_handle *handle;

list_for_each(node, &kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
list_for_each_entry(handle, &kbd_handler.h_list, h_node) {
if (test_bit(EV_SND, handle->dev->evbit)) {
if (test_bit(SND_TONE, handle->dev->sndbit))
input_inject_event(handle, EV_SND, SND_TONE, 0);
Expand Down
29 changes: 9 additions & 20 deletions trunk/drivers/input/evdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,32 +434,21 @@ static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
case EVIOCGKEYCODE:
if (get_user(t, ip))
return -EFAULT;
if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
return -EINVAL;
if (put_user(INPUT_KEYCODE(dev, t), ip + 1))

error = dev->getkeycode(dev, t, &v);
if (error)
return error;

if (put_user(v, ip + 1))
return -EFAULT;

return 0;

case EVIOCSKEYCODE:
if (get_user(t, ip))
return -EFAULT;
if (t < 0 || t >= dev->keycodemax || !dev->keycodesize)
return -EINVAL;
if (get_user(v, ip + 1))
if (get_user(t, ip) || get_user(v, ip + 1))
return -EFAULT;
if (v < 0 || v > KEY_MAX)
return -EINVAL;
if (dev->keycodesize < sizeof(v) && (v >> (dev->keycodesize * 8)))
return -EINVAL;

u = SET_INPUT_KEYCODE(dev, t, v);
clear_bit(u, dev->keybit);
set_bit(v, dev->keybit);
for (i = 0; i < dev->keycodemax; i++)
if (INPUT_KEYCODE(dev, i) == u)
set_bit(u, dev->keybit);

return 0;
return dev->setkeycode(dev, t, v);

case EVIOCSFF:
if (copy_from_user(&effect, p, sizeof(effect)))
Expand Down
87 changes: 87 additions & 0 deletions trunk/drivers/input/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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),
Expand Down
31 changes: 3 additions & 28 deletions trunk/include/linux/input.h
Original file line number Diff line number Diff line change
Expand Up @@ -913,33 +913,6 @@ struct ff_effect {
#define BIT(x) (1UL<<((x)%BITS_PER_LONG))
#define LONG(x) ((x)/BITS_PER_LONG)

#define INPUT_KEYCODE(dev, scancode) ((dev->keycodesize == 1) ? ((u8*)dev->keycode)[scancode] : \
((dev->keycodesize == 2) ? ((u16*)dev->keycode)[scancode] : (((u32*)dev->keycode)[scancode])))

#define SET_INPUT_KEYCODE(dev, scancode, val) \
({ unsigned __old; \
switch (dev->keycodesize) { \
case 1: { \
u8 *k = (u8 *)dev->keycode; \
__old = k[scancode]; \
k[scancode] = val; \
break; \
} \
case 2: { \
u16 *k = (u16 *)dev->keycode; \
__old = k[scancode]; \
k[scancode] = val; \
break; \
} \
default: { \
u32 *k = (u32 *)dev->keycode; \
__old = k[scancode]; \
k[scancode] = val; \
break; \
} \
} \
__old; })

struct input_dev {

void *private;
Expand All @@ -962,6 +935,8 @@ struct input_dev {
unsigned int keycodemax;
unsigned int keycodesize;
void *keycode;
int (*setkeycode)(struct input_dev *dev, int scancode, int keycode);
int (*getkeycode)(struct input_dev *dev, int scancode, int *keycode);

struct ff_device *ff;

Expand Down Expand Up @@ -1104,7 +1079,7 @@ struct input_handle {
};

#define to_dev(n) container_of(n,struct input_dev,node)
#define to_handler(n) container_of(n,struct input_handler,node);
#define to_handler(n) container_of(n,struct input_handler,node)
#define to_handle(n) container_of(n,struct input_handle,d_node)
#define to_handle_h(n) container_of(n,struct input_handle,h_node)

Expand Down

0 comments on commit 78164f3

Please sign in to comment.