]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2009-12-25 Robert Millan <rmh.grub@aybabtu.com>
authorRobert Millan <rmh@aybabtu.com>
Fri, 25 Dec 2009 20:33:41 +0000 (20:33 +0000)
committerRobert Millan <rmh@aybabtu.com>
Fri, 25 Dec 2009 20:33:41 +0000 (20:33 +0000)
* include/grub/i386/at_keyboard.h (NUM_LOCK, SCROLL_LOCK): New macros.
* term/i386/pc/at_keyboard.c (KEYBOARD_STATUS_NUM_LOCK)
(KEYBOARD_LED_SCROLL, KEYBOARD_LED_NUM, KEYBOARD_LED_CAPS): New macros.
(led_status): New variable.
(keyboard_controller_led): New function.
(grub_at_keyboard_getkey_noblock): Handle num lock and scroll lock,
update led status for caps lock, num lock and scroll lock.

ChangeLog
include/grub/i386/at_keyboard.h
term/i386/pc/at_keyboard.c

index 84c5e39565c5b09ebfd9ef8476c5a31a9fb00fed..9c34faa9f556fab05ea8dc0a938b1a2315ef333c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-12-25  Robert Millan  <rmh.grub@aybabtu.com>
+
+       * include/grub/i386/at_keyboard.h (NUM_LOCK, SCROLL_LOCK): New macros.
+       * term/i386/pc/at_keyboard.c (KEYBOARD_STATUS_NUM_LOCK)
+       (KEYBOARD_LED_SCROLL, KEYBOARD_LED_NUM, KEYBOARD_LED_CAPS): New macros.
+       (led_status): New variable.
+       (keyboard_controller_led): New function.
+       (grub_at_keyboard_getkey_noblock): Handle num lock and scroll lock,
+       update led status for caps lock, num lock and scroll lock.
+
 2009-12-25  Felix Zielcke <fzielcke@z-51.de>
 
        * util/hostdisk.c (open_device): Fix a comment.
index 12d61608e1516a1842cadfc780a4e856821a2108..017b58a62def1dc692e3d72414d98c557695a08e 100644 (file)
@@ -25,6 +25,8 @@
 #define CTRL           0x1d
 #define ALT            0x38
 #define CAPS_LOCK      0x3a
+#define NUM_LOCK       0x45
+#define SCROLL_LOCK    0x46
 
 #define KEYBOARD_REG_DATA      0x60
 #define KEYBOARD_REG_STATUS    0x64
index cf30e72427cf7515acbf417f05eb8ee77aae79a3..dfa06ab4e27a07ced4120ad89e7aa56e1ee41557 100644 (file)
@@ -32,6 +32,13 @@ static short at_keyboard_status = 0;
 #define KEYBOARD_STATUS_CTRL_L         (1 << 4)
 #define KEYBOARD_STATUS_CTRL_R         (1 << 5)
 #define KEYBOARD_STATUS_CAPS_LOCK      (1 << 6)
+#define KEYBOARD_STATUS_NUM_LOCK       (1 << 7)
+
+static grub_uint8_t led_status;
+
+#define KEYBOARD_LED_SCROLL            (1 << 0)
+#define KEYBOARD_LED_NUM               (1 << 1)
+#define KEYBOARD_LED_CAPS              (1 << 2)
 
 static char keyboard_map[128] =
 {
@@ -80,6 +87,15 @@ grub_keyboard_controller_read (void)
   return grub_inb (KEYBOARD_REG_DATA);
 }
 
+static void
+keyboard_controller_led (grub_uint8_t led_status)
+{
+  while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
+  grub_outb (0xed, KEYBOARD_REG_DATA);
+  while (! KEYBOARD_COMMAND_ISREADY (grub_inb (KEYBOARD_REG_STATUS)));
+  grub_outb (led_status & 0x7, KEYBOARD_REG_DATA);
+}
+
 /* FIXME: This should become an interrupt service routine.  For now
    it's just used to catch events from control keys.  */
 static void
@@ -158,14 +174,37 @@ grub_at_keyboard_getkey_noblock (void)
   switch (code)
     {
       case CAPS_LOCK:
-       at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK;
        /* Caps lock sends scan code twice.  Get the second one and discard it.  */
        while (grub_keyboard_getkey () == -1);
+
+       at_keyboard_status ^= KEYBOARD_STATUS_CAPS_LOCK;
+       led_status ^= KEYBOARD_LED_CAPS;
+       keyboard_controller_led (led_status);
+
 #ifdef DEBUG_AT_KEYBOARD
        grub_dprintf ("atkeyb", "caps_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_CAPS_LOCK));
 #endif
        key = -1;
        break;
+      case NUM_LOCK:
+       /* Num lock sends scan code twice.  Get the second one and discard it.  */
+       while (grub_keyboard_getkey () == -1);
+
+       at_keyboard_status ^= KEYBOARD_STATUS_NUM_LOCK;
+       led_status ^= KEYBOARD_LED_NUM;
+       keyboard_controller_led (led_status);
+
+#ifdef DEBUG_AT_KEYBOARD
+       grub_dprintf ("atkeyb", "num_lock = %d\n", !!(at_keyboard_status & KEYBOARD_STATUS_NUM_LOCK));
+#endif
+       key = -1;
+       break;
+      case SCROLL_LOCK:
+       /* For scroll lock we don't keep track of status.  Only update its led.  */
+       led_status ^= KEYBOARD_LED_SCROLL;
+       keyboard_controller_led (led_status);
+       key = -1;
+       break;
       default:
        if (at_keyboard_status & (KEYBOARD_STATUS_CTRL_L | KEYBOARD_STATUS_CTRL_R))
          key = keyboard_map[code] - 'a' + 1;