Commit 723a2459 authored by Andries E. Brouwer's avatar Andries E. Brouwer Committed by Vojtech Pavlik

Since 2.5.32 the keyboard repeat code was broken.

The reason Vojtech broke it was the stupid name of a field
in struct kbd_repeat, namely "rate".  Every sane person
expects that a rate has dimension [1/sec], but here the
"rate" is a time period measured in msec.

So, the patch below first of all fixes the code,
and secondly changes the name.
Since Vojtech used PERIOD as index, I also used period
as field name in the struct.

Half of the stuff below is actually from Alan Stern.

Andries
parent 0c5daf6e
......@@ -264,23 +264,34 @@ void kd_mksound(unsigned int hz, unsigned int ticks)
/*
* Setting the keyboard rate.
*/
static inline unsigned int ms_to_jiffies(unsigned int ms) {
unsigned int j;
j = (ms * HZ + 500) / 1000;
return (j > 0) ? j : 1;
}
int kbd_rate(struct kbd_repeat *rep)
{
struct list_head * node;
if (rep->rate < 0 || rep->delay < 0)
return -EINVAL;
struct list_head *node;
unsigned int d = 0;
unsigned int p = 0;
list_for_each(node,&kbd_handler.h_list) {
struct input_handle *handle = to_handle_h(node);
if (test_bit(EV_REP, handle->dev->evbit)) {
if (rep->rate > HZ) rep->rate = HZ;
handle->dev->rep[REP_PERIOD] = rep->rate ? (HZ / rep->rate) : 0;
handle->dev->rep[REP_DELAY] = rep->delay * HZ / 1000;
if (handle->dev->rep[REP_DELAY] < handle->dev->rep[REP_PERIOD])
handle->dev->rep[REP_DELAY] = handle->dev->rep[REP_PERIOD];
struct input_dev *dev = handle->dev;
if (test_bit(EV_REP, dev->evbit)) {
if (rep->delay > 0)
dev->rep[REP_DELAY] = ms_to_jiffies(rep->delay);
if (rep->period > 0)
dev->rep[REP_PERIOD] = ms_to_jiffies(rep->period);
d = dev->rep[REP_DELAY] * 1000 / HZ;
p = dev->rep[REP_PERIOD] * 1000 / HZ;
}
}
rep->delay = d;
rep->period = p;
return 0;
}
......
......@@ -430,6 +430,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
case KDKBDREP:
{
struct kbd_repeat kbrep;
int err;
if (!capable(CAP_SYS_TTY_CONFIG))
return -EPERM;
......@@ -437,8 +438,9 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
if (copy_from_user(&kbrep, (void *)arg,
sizeof(struct kbd_repeat)))
return -EFAULT;
if ((i = kbd_rate( &kbrep )))
return i;
err = kbd_rate(&kbrep);
if (err)
return err;
if (copy_to_user((void *)arg, &kbrep,
sizeof(struct kbd_repeat)))
return -EFAULT;
......
......@@ -107,7 +107,7 @@ struct uctrl_status {
u8 speaker_volume; /* 0x23 */
u8 control_tft_brightness; /* 0x24 */
u8 control_kbd_repeat_delay; /* 0x28 */
u8 control_kbd_repeat_rate; /* 0x29 */
u8 control_kbd_repeat_period; /* 0x29 */
u8 control_screen_contrast; /* 0x2F */
};
......
......@@ -134,7 +134,8 @@ struct kbkeycode {
struct kbd_repeat {
int delay; /* in msec; <= 0: don't change */
int rate; /* in msec; <= 0: don't change */
int period; /* in msec; <= 0: don't change */
/* earlier this field was misnamed "rate" */
};
#define KDKBDREP 0x4B52 /* set keyboard delay/repeat rate;
......
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