[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH] Detect key modifier status in 'sleep --interruptible'
From: |
Colin Watson |
Subject: |
Re: [PATCH] Detect key modifier status in 'sleep --interruptible' |
Date: |
Wed, 26 Aug 2009 21:26:06 +0100 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
On Wed, Aug 26, 2009 at 08:39:00PM +0200, Robert Millan wrote:
> On Wed, Aug 26, 2009 at 04:33:56PM +0100, Colin Watson wrote:
> > Index: commands/sleep.c
> > ===================================================================
> > --- commands/sleep.c (revision 2535)
> > +++ commands/sleep.c (working copy)
> > [...]
> >
> > +static int
> > +grub_check_keyboard (void)
> > +{
> > + int mods = grub_getkeystatus ();
> > + if (mods >= 0 && (mods & GRUB_TERM_STATUS_SHIFT) != 0)
> > + return 1;
> > +
> > + if (grub_checkkey () >= 0 &&
> > + GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
> > + return 1;
> > +
> > + return 0;
> > +}
> > +
> > /* Based on grub_millisleep() from kern/generic/millisleep.c. */
> > static int
> > grub_interruptible_millisleep (grub_uint32_t ms)
> > @@ -52,8 +66,7 @@
> > start = grub_get_time_ms ();
> >
> > while (grub_get_time_ms () - start < ms)
> > - if (grub_checkkey () >= 0 &&
> > - GRUB_TERM_ASCII_CHAR (grub_getkey ()) == GRUB_TERM_ESC)
> > + if (grub_check_keyboard ())
> > return 1;
>
> I'm still not convinced that we want the sleep bits. They seem too ad-hoc,
> and I'd like to hear what others think first.
>
> But if I understood correctly, you plan on using keystatus command only?
If GRUB_HIDDEN_TIMEOUT is set to a non-zero value, I would use sleep
rather than keystatus, I think. (At least, if I decided I wanted to
support that configuration; I'm not quite sure yet.) In that case I'd
want the sleep to be interruptible by pressing Shift for consistency
with the zero-delay case.
However, since this is essentially an artifact of our configuration and
doesn't introduce any new configuration file words, I could keep this
part as an Ubuntu-specific patch with relatively little trouble.
> > +static int
> > +grub_console_getkeystatus (void)
> > +{
> > + grub_uint8_t status = bios_data_area->keyboard_flag_lower;
> > + int mods = 0;
> > +
> > + if (status & 0x03)
> > + mods |= GRUB_TERM_STATUS_SHIFT;
> > + if (status & 0x04)
> > + mods |= GRUB_TERM_STATUS_CTRL;
> > + if (status & 0x08)
> > + mods |= GRUB_TERM_STATUS_ALT;
> > +
> > + return mods;
> > +}
>
> This should be macroified (but for the time being, I have no problem with
> our internal representation matching the one in BIOS Data Area, hence no
> translation would be needed on i386-pc).
Vladimir objected to the inconsistency between distinguishing left and
right Shift but not left and right Control or Alt, which is why our
internal representation does not currently match. I agree it's clearer
to macroify things.
> > + /* Set idle time to the minimum offered by the spec (4 milliseconds) so
> > + that we can find out the current state. */
> > + grub_usb_control_msg (usbdev, 0x21, 0x0A, 1<<8, 0, 0, 0);
> > +
> > + grub_usb_control_msg (usbdev, (1 << 7) | (1 << 5) | 1, 0x02, 0, 0, 1,
> > (char *) data);
> > +
> > [...]
> > + /* Go back to reporting every time an event occurs and not more often
> > than
> > + that. */
> > + grub_usb_control_msg (usbdev, 0x21, 0x0A, 0<<8, 0, 0, 0);
>
> If they represent fixed numbers like registers/ports, these hex values should
> be macros too.
OK, and doing so helped me notice that I'd left a Get_Idle request in
there by mistake from debugging. Updated patch follows. There are a few
changes unrelated to the main body of the patch as a result; do you want
these split out?
2009-08-24 Colin Watson <address@hidden>
2009-08-24 Robert Millan <address@hidden>
Add `getkeystatus' terminal method. Add a new `keystatus' command
to query it.
* include/grub/term.h (GRUB_TERM_STATUS_SHIFT,
GRUB_TERM_STATUS_CTRL, GRUB_TERM_STATUS_ALT): Definitions for
modifier key bitmasks.
(struct grub_term_input): Add `getkeystatus' member.
(grub_getkeystatus): Add prototype.
* kern/term.c (grub_getkeystatus): New function.
* include/grub/i386/pc/memory.h
(GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR): New macro.
(struct grub_machine_bios_data_area): Define necessary parts of BIOS
Data Area layout.
* term/i386/pc/console.c (grub_console_getkeystatus): New function.
(grub_console_term_input): Set `getkeystatus' member.
* term/usb_keyboard.c (grub_usb_hid): Macroify HID protocol
constants.
(grub_usb_keyboard_getreport): Likewise.
(grub_usb_keyboard_checkkey): Likewise.
(grub_usb_keyboard_getkeystatus): New function.
(grub_usb_keyboard_term): Set `getkeystatus' member.
* commands/keystatus.c: New file.
* conf/common.rmk (pkglib_MODULES): Add keystatus.mod.
(keystatus_mod_SOURCES): New variable.
(keystatus_mod_CFLAGS): Likewise.
(keystatus_mod_LDFLAGS): Likewise.
* conf/i386-coreboot.rmk (grub_emu_SOURCES): Add
commands/keystatus.c.
* conf/i386-efi.rmk (grub_emu_SOURCES): Likewise.
* conf/i386-ieee1275.rmk (grub_emu_SOURCES): Likewise.
* conf/i386-pc.rmk (grub_emu_SOURCES): Likewise.
* conf/powerpc-ieee1275.rmk (grub_emu_SOURCES): Likewise.
* conf/sparc64-ieee1275.rmk (grub_emu_SOURCES): Likewise.
* conf/x86_64-efi.rmk (grub_emu_SOURCES): Likewise.
* DISTLIST: Add commands/keystatus.c.
Index: conf/common.rmk
===================================================================
--- conf/common.rmk (revision 2535)
+++ conf/common.rmk (working copy)
@@ -363,7 +363,8 @@
terminfo.mod test.mod blocklist.mod hexdump.mod \
read.mod sleep.mod loadenv.mod crc.mod parttool.mod \
msdospart.mod memrw.mod normal.mod sh.mod lua.mod \
- gptsync.mod true.mod probe.mod password.mod
+ gptsync.mod true.mod probe.mod password.mod \
+ keystatus.mod
# For password.mod.
password_mod_SOURCES = commands/password.c
@@ -510,6 +511,11 @@
probe_mod_CFLAGS = $(COMMON_CFLAGS)
probe_mod_LDFLAGS = $(COMMON_LDFLAGS)
+# For keystatus.mod.
+keystatus_mod_SOURCES = commands/keystatus.c
+keystatus_mod_CFLAGS = $(COMMON_CFLAGS)
+keystatus_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
# For normal.mod.
normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
normal/auth.c normal/autofs.c normal/handler.c \
Index: conf/i386-pc.rmk
===================================================================
--- conf/i386-pc.rmk (revision 2535)
+++ conf/i386-pc.rmk (working copy)
@@ -123,7 +123,7 @@
lib/hexdump.c commands/i386/pc/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
commands/i386/cpuid.c \
- commands/password.c \
+ commands/password.c commands/keystatus.c \
disk/host.c disk/loopback.c disk/scsi.c \
fs/fshelp.c \
\
Index: conf/i386-efi.rmk
===================================================================
--- conf/i386-efi.rmk (revision 2535)
+++ conf/i386-efi.rmk (working copy)
@@ -37,7 +37,7 @@
commands/configfile.c commands/help.c \
commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/hexdump.c lib/hexdump.c \
- commands/halt.c commands/reboot.c \
+ commands/halt.c commands/reboot.c commands/keystatus.c \
commands/i386/cpuid.c \
commands/password.c \
disk/loopback.c \
Index: conf/i386-ieee1275.rmk
===================================================================
--- conf/i386-ieee1275.rmk (revision 2535)
+++ conf/i386-ieee1275.rmk (working copy)
@@ -66,7 +66,7 @@
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
commands/i386/cpuid.c \
- commands/password.c \
+ commands/password.c commands/keystatus.c \
disk/host.c disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
Index: conf/x86_64-efi.rmk
===================================================================
--- conf/x86_64-efi.rmk (revision 2535)
+++ conf/x86_64-efi.rmk (working copy)
@@ -37,7 +37,7 @@
commands/search.c commands/hexdump.c lib/hexdump.c \
commands/halt.c commands/reboot.c \
commands/i386/cpuid.c \
- commands/password.c \
+ commands/password.c commands/keystatus.c \
disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
Index: conf/i386-coreboot.rmk
===================================================================
--- conf/i386-coreboot.rmk (revision 2535)
+++ conf/i386-coreboot.rmk (working copy)
@@ -110,7 +110,7 @@
commands/handler.c commands/ls.c commands/test.c \
commands/search.c commands/blocklist.c commands/hexdump.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
- commands/password.c \
+ commands/password.c commands/keystatus.c \
lib/hexdump.c commands/i386/cpuid.c \
disk/host.c disk/loopback.c \
\
Index: conf/powerpc-ieee1275.rmk
===================================================================
--- conf/powerpc-ieee1275.rmk (revision 2535)
+++ conf/powerpc-ieee1275.rmk (working copy)
@@ -46,7 +46,7 @@
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
- commands/password.c \
+ commands/password.c commands/keystatus.c \
disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
Index: conf/sparc64-ieee1275.rmk
===================================================================
--- conf/sparc64-ieee1275.rmk (revision 2535)
+++ conf/sparc64-ieee1275.rmk (working copy)
@@ -103,7 +103,7 @@
commands/ls.c commands/blocklist.c commands/hexdump.c \
lib/hexdump.c commands/halt.c commands/reboot.c \
commands/gptsync.c commands/probe.c commands/xnu_uuid.c \
- commands/password.c \
+ commands/password.c commands/keystatus.c \
disk/loopback.c \
\
fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \
Index: kern/term.c
===================================================================
--- kern/term.c (revision 2535)
+++ kern/term.c (working copy)
@@ -140,6 +140,15 @@
return (grub_cur_term_input->checkkey) ();
}
+int
+grub_getkeystatus (void)
+{
+ if (grub_cur_term_input->getkeystatus)
+ return (grub_cur_term_input->getkeystatus) ();
+ else
+ return 0;
+}
+
grub_uint16_t
grub_getxy (void)
{
Index: include/grub/term.h
===================================================================
--- include/grub/term.h (revision 2535)
+++ include/grub/term.h (working copy)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2003,2005,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2003,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -72,6 +72,12 @@
#define GRUB_TERM_NEED_INIT (1 << 16)
+/* Bitmasks for modifier keys returned by grub_getkeystatus. */
+#define GRUB_TERM_STATUS_SHIFT (1 << 0)
+#define GRUB_TERM_STATUS_CTRL (1 << 1)
+#define GRUB_TERM_STATUS_ALT (1 << 2)
+
+
/* Unicode characters for fancy graphics. */
#define GRUB_TERM_DISP_LEFT 0x2190
#define GRUB_TERM_DISP_UP 0x2191
@@ -157,6 +163,9 @@
/* Get a character. */
int (*getkey) (void);
+
+ /* Get keyboard modifier status. */
+ int (*getkeystatus) (void);
};
typedef struct grub_term_input *grub_term_input_t;
@@ -275,6 +284,7 @@
grub_ssize_t EXPORT_FUNC(grub_getcharwidth) (grub_uint32_t code);
int EXPORT_FUNC(grub_getkey) (void);
int EXPORT_FUNC(grub_checkkey) (void);
+int EXPORT_FUNC(grub_getkeystatus) (void);
grub_uint16_t EXPORT_FUNC(grub_getwh) (void);
grub_uint16_t EXPORT_FUNC(grub_getxy) (void);
void EXPORT_FUNC(grub_gotoxy) (grub_uint8_t x, grub_uint8_t y);
Index: include/grub/i386/pc/memory.h
===================================================================
--- include/grub/i386/pc/memory.h (revision 2535)
+++ include/grub/i386/pc/memory.h (working copy)
@@ -78,8 +78,19 @@
/* The data segment of the pseudo real mode. */
#define GRUB_MEMORY_MACHINE_PSEUDO_REAL_DSEG 0x20
+#define GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR 0x400
+
#ifndef ASM_FILE
+/* See http://heim.ifi.uio.no/~stanisls/helppc/bios_data_area.html for a
+ description of the BIOS Data Area layout. */
+struct grub_machine_bios_data_area
+{
+ grub_uint8_t unused1[0x17];
+ grub_uint8_t keyboard_flag_lower; /* 0x17 */
+ grub_uint8_t unused2[0xf0 - 0x18];
+};
+
struct grub_machine_mmap_entry
{
grub_uint32_t size;
Index: commands/keystatus.c
===================================================================
--- commands/keystatus.c (revision 0)
+++ commands/keystatus.c (revision 0)
@@ -0,0 +1,81 @@
+/* keystatus.c - Command to check key modifier status. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/misc.h>
+#include <grub/extcmd.h>
+#include <grub/term.h>
+
+static const struct grub_arg_option options[] =
+ {
+ {"shift", 's', 0, "check Shift key", 0, 0},
+ {"ctrl", 'c', 0, "check Control key", 0, 0},
+ {"alt", 'a', 0, "check Alt key", 0, 0},
+ {0, 0, 0, 0, 0, 0}
+ };
+
+#define grub_cur_term_input grub_term_get_current_input ()
+
+static grub_err_t
+grub_cmd_keystatus (grub_extcmd_t cmd,
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ struct grub_arg_list *state = cmd->state;
+ int expect_mods = 0;
+ int mods;
+
+ if (state[0].set)
+ expect_mods |= GRUB_TERM_STATUS_SHIFT;
+ if (state[1].set)
+ expect_mods |= GRUB_TERM_STATUS_CTRL;
+ if (state[2].set)
+ expect_mods |= GRUB_TERM_STATUS_ALT;
+
+ /* Without arguments, just check whether getkeystatus is supported at
+ all. */
+ if (!grub_cur_term_input->getkeystatus)
+ return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+ grub_dprintf ("keystatus", "expect_mods: %d\n", expect_mods);
+ if (!expect_mods)
+ return 0;
+
+ mods = grub_getkeystatus ();
+ grub_dprintf ("keystatus", "mods: %d\n", mods);
+ if (mods >= 0 && (mods & expect_mods) != 0)
+ return 0;
+ else
+ return grub_error (GRUB_ERR_TEST_FAILURE, "false");
+}
+
+static grub_extcmd_t cmd;
+
+GRUB_MOD_INIT(keystatus)
+{
+ cmd = grub_register_extcmd ("keystatus", grub_cmd_keystatus,
+ GRUB_COMMAND_FLAG_BOTH,
+ "keystatus [--shift|--ctrl|--alt]",
+ "Check key modifier status",
+ options);
+}
+
+GRUB_MOD_FINI(keystatus)
+{
+ grub_unregister_extcmd (cmd);
+}
Index: term/i386/pc/console.c
===================================================================
--- term/i386/pc/console.c (revision 2535)
+++ term/i386/pc/console.c (working copy)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2003,2005,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2003,2005,2007,2008,2009 Free Software Foundation, Inc.
*
* GRUB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,15 +16,40 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <grub/machine/memory.h>
#include <grub/machine/console.h>
#include <grub/term.h>
#include <grub/types.h>
+static const struct grub_machine_bios_data_area *bios_data_area =
GRUB_MEMORY_MACHINE_BIOS_DATA_AREA_ADDR;
+
+#define KEYBOARD_LEFT_SHIFT (1 << 0)
+#define KEYBOARD_RIGHT_SHIFT (1 << 1)
+#define KEYBOARD_CTRL (1 << 2)
+#define KEYBOARD_ALT (1 << 3)
+
+static int
+grub_console_getkeystatus (void)
+{
+ grub_uint8_t status = bios_data_area->keyboard_flag_lower;
+ int mods = 0;
+
+ if (status & (KEYBOARD_LEFT_SHIFT | KEYBOARD_RIGHT_SHIFT))
+ mods |= GRUB_TERM_STATUS_SHIFT;
+ if (status & KEYBOARD_CTRL)
+ mods |= GRUB_TERM_STATUS_CTRL;
+ if (status & KEYBOARD_ALT)
+ mods |= GRUB_TERM_STATUS_ALT;
+
+ return mods;
+}
+
static struct grub_term_input grub_console_term_input =
{
.name = "console",
.checkkey = grub_console_checkkey,
.getkey = grub_console_getkey,
+ .getkeystatus = grub_console_getkeystatus,
};
static struct grub_term_output grub_console_term_output =
Index: term/usb_keyboard.c
===================================================================
--- term/usb_keyboard.c (revision 2535)
+++ term/usb_keyboard.c (working copy)
@@ -58,6 +58,19 @@
static grub_usb_device_t usbdev;
+/* Valid values for bmRequestType. See HID definition version 1.11 section
+ 7.2. */
+#define USB_HID_HOST_TO_DEVICE 0x21
+#define USB_HID_DEVICE_TO_HOST 0x61
+
+/* Valid values for bRequest. See HID definition version 1.11 section 7.2. */
+#define USB_HID_GET_REPORT 0x01
+#define USB_HID_GET_IDLE 0x02
+#define USB_HID_GET_PROTOCOL 0x03
+#define USB_HID_SET_REPORT 0x09
+#define USB_HID_SET_IDLE 0x0A
+#define USB_HID_SET_PROTOCOL 0x0B
+
static void
grub_usb_hid (void)
{
@@ -90,17 +103,19 @@
grub_usb_iterate (usb_iterate);
/* Place the device in boot mode. */
- grub_usb_control_msg (usbdev, 0x21, 0x0B, 0, 0, 0, 0);
+ grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_PROTOCOL,
+ 0, 0, 0, 0);
/* Reports every time an event occurs and not more often than that. */
- grub_usb_control_msg (usbdev, 0x21, 0x0A, 0<<8, 0, 0, 0);
+ grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+ 0<<8, 0, 0, 0);
}
static grub_err_t
grub_usb_keyboard_getreport (grub_usb_device_t dev, grub_uint8_t *report)
{
- return grub_usb_control_msg (dev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0,
- 8, (char *) report);
+ return grub_usb_control_msg (dev, USB_HID_DEVICE_TO_HOST, USB_HID_GET_REPORT,
+ 0, 0, 8, (char *) report);
}
@@ -151,7 +166,8 @@
/* Wait until the key is released. */
while (!err && data[2])
{
- err = grub_usb_control_msg (usbdev, (1 << 7) | (1 << 5) | 1, 0x01, 0, 0,
+ err = grub_usb_control_msg (usbdev, USB_HID_DEVICE_TO_HOST,
+ USB_HID_GET_REPORT, 0, 0,
sizeof (data), (char *) data);
grub_dprintf ("usb_keyboard",
"report2: 0x%02x 0x%02x 0x%02x 0x%02x"
@@ -238,11 +254,67 @@
return key;
}
+static int
+grub_usb_keyboard_getkeystatus (void)
+{
+ grub_uint8_t data[8];
+ int mods = 0;
+ grub_err_t err;
+ grub_uint64_t currtime;
+ int timeout = 50;
+
+ /* Set idle time to the minimum offered by the spec (4 milliseconds) so
+ that we can find out the current state. */
+ grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+ 0<<8, 0, 0, 0);
+
+ currtime = grub_get_time_ms ();
+ do
+ {
+ /* Get_Report. */
+ err = grub_usb_keyboard_getreport (usbdev, data);
+
+ /* Implement a timeout. */
+ if (grub_get_time_ms () > currtime + timeout)
+ break;
+ }
+ while (err || !data[0]);
+
+ /* Go back to reporting every time an event occurs and not more often than
+ that. */
+ grub_usb_control_msg (usbdev, USB_HID_HOST_TO_DEVICE, USB_HID_SET_IDLE,
+ 0<<8, 0, 0, 0);
+
+ /* We allowed a while for modifiers to show up in the report, but it is
+ not an error if they never did. */
+ if (err)
+ return -1;
+
+ grub_dprintf ("usb_keyboard",
+ "report: 0x%02x 0x%02x 0x%02x 0x%02x"
+ " 0x%02x 0x%02x 0x%02x 0x%02x\n",
+ data[0], data[1], data[2], data[3],
+ data[4], data[5], data[6], data[7]);
+
+ /* Check Shift, Control, and Alt status. */
+ if (data[0] & 0x02 || data[0] & 0x20)
+ mods |= GRUB_TERM_STATUS_SHIFT;
+ if (data[0] & 0x01 || data[0] & 0x10)
+ mods |= GRUB_TERM_STATUS_CTRL;
+ if (data[0] & 0x04 || data[0] & 0x40)
+ mods |= GRUB_TERM_STATUS_ALT;
+
+ grub_errno = GRUB_ERR_NONE;
+
+ return mods;
+}
+
static struct grub_term_input grub_usb_keyboard_term =
{
.name = "usb_keyboard",
.checkkey = grub_usb_keyboard_checkkey,
.getkey = grub_usb_keyboard_getkey,
+ .getkeystatus = grub_usb_keyboard_getkeystatus,
.next = 0
};
--
Colin Watson address@hidden
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', (continued)
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Colin Watson, 2009/08/24
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Colin Watson, 2009/08/24
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Robert Millan, 2009/08/24
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Colin Watson, 2009/08/24
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Colin Watson, 2009/08/26
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Robert Millan, 2009/08/26
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible',
Colin Watson <=
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Robert Millan, 2009/08/28
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Colin Watson, 2009/08/28
- Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Robert Millan, 2009/08/24
Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Robert Millan, 2009/08/13
Re: [PATCH] Detect key modifier status in 'sleep --interruptible', Robert Millan, 2009/08/23