#include <grub/i386/vga_common.h>
/* These are global to share code between C and asm. */
-int grub_console_checkkey (struct grub_term_input *term);
int grub_console_getkey (struct grub_term_input *term);
grub_uint16_t grub_console_getxy (struct grub_term_output *term);
void grub_console_gotoxy (struct grub_term_output *term,
/* Clean up the terminal. */
grub_err_t (*fini) (struct grub_term_input *term);
- /* Check if any input character is available. */
- int (*checkkey) (struct grub_term_input *term);
-
- /* Get a character. */
+ /* Get a character if any input character is available. Otherwise return -1 */
int (*getkey) (struct grub_term_input *term);
/* Get keyboard modifier status. */
const grub_term_color_state state);
-int EXPORT_FUNC (grub_terminfo_checkkey) (struct grub_term_input *term);
grub_err_t EXPORT_FUNC (grub_terminfo_input_init) (struct grub_term_input *term);
int EXPORT_FUNC (grub_terminfo_getkey) (struct grub_term_input *term);
void EXPORT_FUNC (grub_terminfo_putchar) (struct grub_term_output *term,
}
}
-static int saved_char = ERR;
-
static int
-grub_ncurses_checkkey (struct grub_term_input *term __attribute__ ((unused)))
+grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
{
int c;
- /* Check for SAVED_CHAR. This should not be true, because this
- means checkkey is called twice continuously. */
- if (saved_char != ERR)
- return saved_char;
-
wtimeout (stdscr, 100);
c = getch ();
- /* If C is not ERR, then put it back in the input queue. */
- if (c != ERR)
- {
- saved_char = c;
- return c;
- }
-
- return -1;
-}
-
-static int
-grub_ncurses_getkey (struct grub_term_input *term __attribute__ ((unused)))
-{
- int c;
-
- /* If checkkey has already got a character, then return it. */
- if (saved_char != ERR)
- {
- c = saved_char;
- saved_char = ERR;
- }
- else
- {
- wtimeout (stdscr, -1);
- c = getch ();
- }
switch (c)
{
+ case ERR:
+ return -1;
case KEY_LEFT:
c = GRUB_TERM_LEFT;
break;
static struct grub_term_input grub_ncurses_term_input =
{
.name = "console",
- .checkkey = grub_ncurses_checkkey,
.getkey = grub_ncurses_getkey,
};
/*
* int grub_console_getkey (void)
+ * if there is a character pending, return it; otherwise return -1
+ * BIOS call "INT 16H Function 01H" to check whether a character is pending
+ * Call with %ah = 0x1
+ * Return:
+ * If key waiting to be input:
+ * %ah = keyboard scan code
+ * %al = ASCII character
+ * Zero flag = clear
+ * else
+ * Zero flag = set
* BIOS call "INT 16H Function 00H" to read character from keyboard
* Call with %ah = 0x0
* Return: %ah = keyboard scan code
* INT 16/AH = 1 before calling INT 16/AH = 0.
*/
-1:
movb $1, %ah
int $0x16
- jnz 2f
- hlt
- jmp 1b
-
-2:
+ jz notpending
movb $0, %ah
int $0x16
popl %ebp
ret
-/*
- * int grub_console_checkkey (void)
- * if there is a character pending, return it; otherwise return -1
- * BIOS call "INT 16H Function 01H" to check whether a character is pending
- * Call with %ah = 0x1
- * Return:
- * If key waiting to be input:
- * %ah = keyboard scan code
- * %al = ASCII character
- * Zero flag = clear
- * else
- * Zero flag = set
- */
-FUNCTION(grub_console_checkkey)
- pushl %ebp
- xorl %edx, %edx
-
- call prot_to_real /* enter real mode */
+notpending:
.code16
-
- movb $0x1, %ah
- int $0x16
-
- jz notpending
-
- xorl %edx, %edx
- movw %ax, %dx
- DATA32 jmp pending
-
-notpending:
- xorl %edx, %edx
- decl %edx
-
-pending:
DATA32 call real_to_prot
.code32
-
- movl %edx, %eax
-
- popl %ebp
- ret
+ decl %eax
+ jmp 2b
/*
void (*grub_xputs) (const char *str) = grub_xputs_dumb;
+static int pending_key = -1;
+
int
grub_getkey (void)
{
grub_refresh ();
+ if (pending_key != -1)
+ {
+ pending_key = -1;
+ return pending_key;
+ }
+
while (1)
{
if (grub_term_poll_usb)
FOR_ACTIVE_TERM_INPUTS(term)
{
- int key = term->checkkey (term);
+ int key = term->getkey (term);
if (key != -1)
- return term->getkey (term);
+ return key;
}
grub_cpu_idle ();
{
grub_term_input_t term;
+ if (pending_key != -1)
+ return pending_key;
+
if (grub_term_poll_usb)
grub_term_poll_usb ();
FOR_ACTIVE_TERM_INPUTS(term)
{
- int key = term->checkkey (term);
- if (key != -1)
- return key;
+ pending_key = term->getkey (term);
+ if (pending_key != -1)
+ return pending_key;
}
return -1;
static short at_keyboard_status = 0;
static int e0_received = 0;
static int f0_received = 0;
-static int pending_key = -1;
static grub_uint8_t led_status;
/* If there is a character pending, return it; otherwise return -1. */
static int
-grub_at_keyboard_getkey_noblock (void)
+grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)))
{
int code;
code = grub_keyboard_getkey ();
}
}
-static int
-grub_at_keyboard_checkkey (struct grub_term_input *term __attribute__ ((unused)))
-{
- if (pending_key != -1)
- return 1;
-
- pending_key = grub_at_keyboard_getkey_noblock ();
-
- if (pending_key != -1)
- return 1;
-
- return -1;
-}
-
-static int
-grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused)))
-{
- int key;
- if (pending_key != -1)
- {
- key = pending_key;
- pending_key = -1;
- return key;
- }
- do
- {
- key = grub_at_keyboard_getkey_noblock ();
- } while (key == -1);
- return key;
-}
-
static grub_err_t
grub_keyboard_controller_init (struct grub_term_input *term __attribute__ ((unused)))
{
- pending_key = -1;
at_keyboard_status = 0;
/* Drain input buffer. */
while (1)
.name = "at_keyboard",
.init = grub_keyboard_controller_init,
.fini = grub_keyboard_controller_fini,
- .checkkey = grub_at_keyboard_checkkey,
.getkey = grub_at_keyboard_getkey
};
grub_console_standard_color = GRUB_EFI_TEXT_ATTR (GRUB_EFI_YELLOW,
GRUB_EFI_BACKGROUND_BLACK);
-static int read_key = -1;
-
static grub_uint32_t
map_char (grub_uint32_t c)
{
static int
-grub_console_checkkey (struct grub_term_input *term __attribute__ ((unused)))
+grub_console_getkey (struct grub_term_input *term __attribute__ ((unused)))
{
grub_efi_simple_input_interface_t *i;
grub_efi_input_key_t key;
grub_efi_status_t status;
- if (read_key >= 0)
- return 1;
-
i = grub_efi_system_table->con_in;
status = efi_call_2 (i->read_key_stroke, i, &key);
return -1;
if (key.scan_code == 0)
- read_key = key.unicode_char;
+ return key.unicode_char;
else if (key.scan_code < ARRAY_SIZE (efi_codes))
- read_key = efi_codes[key.scan_code];
-
- return read_key;
-}
-
-static int
-grub_console_getkey (struct grub_term_input *term)
-{
- grub_efi_simple_input_interface_t *i;
- grub_efi_boot_services_t *b;
- grub_efi_uintn_t index;
- grub_efi_status_t status;
- int key;
-
- if (read_key >= 0)
- {
- key = read_key;
- read_key = -1;
- return key;
- }
-
- i = grub_efi_system_table->con_in;
- b = grub_efi_system_table->boot_services;
-
- do
- {
- status = efi_call_3 (b->wait_for_event, 1, &(i->wait_for_key), &index);
- if (status != GRUB_EFI_SUCCESS)
- return -1;
-
- grub_console_checkkey (term);
- }
- while (read_key < 0);
+ return efi_codes[key.scan_code];
- key = read_key;
- read_key = -1;
- return key;
+ return -1;
}
static grub_uint16_t
static struct grub_term_input grub_console_term_input =
{
.name = "console",
- .checkkey = grub_console_checkkey,
.getkey = grub_console_getkey,
};
static struct grub_term_input grub_console_term_input =
{
.name = "console",
- .checkkey = grub_console_checkkey,
.getkey = grub_console_getkey,
.getkeystatus = grub_console_getkeystatus
};
{
.name = "ofconsole",
.init = grub_ofconsole_init_input,
- .checkkey = grub_terminfo_checkkey,
.getkey = grub_terminfo_getkey,
.data = &grub_ofconsole_terminfo_input
};
{
.name = "serial",
.init = grub_terminfo_input_init,
- .checkkey = grub_terminfo_checkkey,
.getkey = grub_terminfo_getkey,
.data = &grub_serial_terminfo_input
};
#undef CONTINUE_READ
}
-/* The terminfo version of checkkey. */
+/* The terminfo version of getkey. */
int
-grub_terminfo_checkkey (struct grub_term_input *termi)
+grub_terminfo_getkey (struct grub_term_input *termi)
{
struct grub_terminfo_input_state *data
= (struct grub_terminfo_input_state *) (termi->data);
if (data->npending)
- return data->input_buf[0];
+ {
+ data->npending--;
+ grub_memmove (data->input_buf, data->input_buf + 1, data->npending);
+ return data->input_buf[0];
+ }
grub_terminfo_readkey (termi, data->input_buf,
&data->npending, data->readkey);
if (data->npending)
- return data->input_buf[0];
+ {
+ data->npending--;
+ grub_memmove (data->input_buf, data->input_buf + 1, data->npending);
+ return data->input_buf[0];
+ }
return -1;
}
-/* The terminfo version of getkey. */
-int
-grub_terminfo_getkey (struct grub_term_input *termi)
-{
- struct grub_terminfo_input_state *data
- = (struct grub_terminfo_input_state *) (termi->data);
- int ret;
- while (! data->npending)
- grub_terminfo_readkey (termi, data->input_buf, &data->npending,
- data->readkey);
-
- ret = data->input_buf[0];
- data->npending--;
- grub_memmove (data->input_buf, data->input_buf + 1, data->npending);
- return ret;
-}
-
grub_err_t
grub_terminfo_input_init (struct grub_term_input *termi)
{
grub_usb_device_t usbdev;
grub_uint8_t status;
grub_uint16_t mods;
- int key;
int interfno;
struct grub_usb_desc_endp *endp;
grub_usb_transfer_t transfer;
grub_uint64_t repeat_time;
};
-static struct grub_term_input grub_usb_keyboards[16];
-
-static int grub_usb_keyboard_checkkey (struct grub_term_input *term);
static int grub_usb_keyboard_getkey (struct grub_term_input *term);
static int grub_usb_keyboard_getkeystatus (struct grub_term_input *term);
static struct grub_term_input grub_usb_keyboard_term =
{
- .checkkey = grub_usb_keyboard_checkkey,
.getkey = grub_usb_keyboard_getkey,
.getkeystatus = grub_usb_keyboard_getkeystatus,
.next = 0
USB_HID_GET_REPORT, 0x0100, interfno,
sizeof (report), (char *) report);
if (err)
- {
- data->status = 0;
- data->key = -1;
- }
+ data->status = 0;
else
- {
- data->status = report[0];
- data->key = report[2] ? : -1;
- }
+ data->status = report[0];
}
#else
data->status = 0;
- data->key = -1;
#endif
data->transfer = grub_usb_bulk_read_background (usbdev,
}
static int
-grub_usb_keyboard_checkkey (struct grub_term_input *term)
+grub_usb_keyboard_getkey (struct grub_term_input *term)
{
grub_usb_err_t err;
struct grub_usb_keyboard_data *termdata = term->data;
grub_uint8_t data[sizeof (termdata->report)];
grub_size_t actual;
- if (termdata->key != -1)
- return termdata->key;
-
if (termdata->dead)
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->last_key;
}
- return termdata->key;
+ return -1;
}
grub_memcpy (data, termdata->report, sizeof (data));
return -1;
}
- termdata->last_key = termdata->key
- = grub_term_map_key (data[2], interpret_status (data[0]) | termdata->mods);
+ termdata->last_key = grub_term_map_key (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;
- return termdata->key;
-}
-
-static int
-grub_usb_keyboard_getkey (struct grub_term_input *term)
-{
- int ret;
- struct grub_usb_keyboard_data *termdata = term->data;
-
- while (termdata->key == -1)
- grub_usb_keyboard_checkkey (term);
-
- ret = termdata->key;
-
- termdata->key = -1;
-
- return ret;
+ return termdata->last_key;
}
static int
{
struct grub_usb_keyboard_data *termdata = term->data;
- grub_usb_keyboard_checkkey (term);
-
return interpret_status (termdata->status) | termdata->mods;
}