diff --git a/include/grub/term.h b/include/grub/term.h index 009258f6e..9956398da 100644 --- a/include/grub/term.h +++ b/include/grub/term.h @@ -490,6 +490,9 @@ grub_print_spaces (struct grub_term_output *term, int number_spaces) extern void (*EXPORT_VAR (grub_term_poll_usb)) (void); +#define GRUB_TERM_REPEAT_PRE_INTERVAL 100 +#define GRUB_TERM_REPEAT_INTERVAL 50 + #endif /* ! ASM_FILE */ #endif /* ! GRUB_TERM_HEADER */ diff --git a/term/usb_keyboard.c b/term/usb_keyboard.c index 759b3eb7d..c3af1694b 100644 --- a/term/usb_keyboard.c +++ b/term/usb_keyboard.c @@ -144,6 +144,8 @@ struct grub_usb_keyboard_data grub_usb_transfer_t transfer; grub_uint8_t report[8]; int dead; + int last_key; + grub_uint64_t repeat_time; }; static struct grub_term_input grub_usb_keyboards[16]; @@ -368,7 +370,16 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) err = grub_usb_check_transfer (termdata->transfer, &actual); if (err == GRUB_USB_ERR_WAIT) - return -1; + { + if (termdata->last_key != -1 + && grub_get_time_ms () > termdata->repeat_time) + { + termdata->key = termdata->last_key; + termdata->repeat_time = grub_get_time_ms () + + GRUB_TERM_REPEAT_INTERVAL; + } + return termdata->key; + } grub_memcpy (data, termdata->report, sizeof (data)); @@ -382,6 +393,7 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) termdata->dead = 1; } + termdata->last_key = -1; grub_dprintf ("usb_keyboard", "err = %d, actual = %d report: 0x%02x 0x%02x 0x%02x 0x%02x" @@ -419,9 +431,13 @@ grub_usb_keyboard_checkkey (struct grub_term_input *term) if (data[2] > ARRAY_SIZE (usb_to_at_map) || usb_to_at_map[data[2]] == 0) grub_printf ("Unknown key 0x%02x detected\n", data[2]); else - termdata->key = grub_term_map_key (usb_to_at_map[data[2]], - interpret_status (data[0]) - | termdata->mods); + { + termdata->last_key = termdata->key + = grub_term_map_key (usb_to_at_map[data[2]], + interpret_status (data[0]) | termdata->mods); + termdata->repeat_time = grub_get_time_ms () + + GRUB_TERM_REPEAT_PRE_INTERVAL; + } grub_errno = GRUB_ERR_NONE;