#include <debug.h>
#include <stdio.h>
#include <string.h>
-#include "devices/intq.h"
+#include "devices/input.h"
+#include "devices/shutdown.h"
#include "threads/interrupt.h"
#include "threads/io.h"
/* Keyboard data register port. */
#define DATA_REG 0x60
-/* Shift state bits. */
-#define LSHIFT 0x01 /* Left Shift. */
-#define RSHIFT 0x02 /* Right Shift. */
-#define LALT 0x04 /* Left Alt. */
-#define RALT 0x08 /* Right Alt. */
-#define LCTRL 0x10 /* Left Ctrl. */
-#define RCTRL 0x20 /* Right Ctrl. */
-#define CAPS 0x40 /* Caps Lock. */
+/* Current state of shift keys.
+ True if depressed, false otherwise. */
+static bool left_shift, right_shift; /* Left and right Shift keys. */
+static bool left_alt, right_alt; /* Left and right Alt keys. */
+static bool left_ctrl, right_ctrl; /* Left and right Ctl keys. */
-/* Current shift state. */
-static unsigned shift_state;
-
-/* Keyboard buffer. */
-static struct intq buffer;
+/* Status of Caps Lock.
+ True when on, false when off. */
+static bool caps_lock;
/* Number of keys pressed. */
static int64_t key_cnt;
void
kbd_init (void)
{
- intq_init (&buffer);
intr_register_ext (0x21, keyboard_interrupt, "8042 Keyboard");
}
-/* Retrieves a key from the keyboard buffer.
- If the buffer is empty, waits for a key to be pressed. */
-uint8_t
-kbd_getc (void)
-{
- enum intr_level old_level;
- uint8_t key;
-
- old_level = intr_disable ();
- key = intq_getc (&buffer);
- intr_set_level (old_level);
-
- return key;
-}
-
/* Prints keyboard statistics. */
void
kbd_print_stats (void)
that we handle elsewhere. */
static const struct keymap invariant_keymap[] =
{
- {0x01, "\033"},
+ {0x01, "\033"}, /* Escape. */
{0x0e, "\b"},
{0x0f, "\tQWERTYUIOP"},
- {0x1c, "\n"},
+ {0x1c, "\r"},
{0x1e, "ASDFGHJKL"},
{0x2c, "ZXCVBNM"},
{0x37, "*"},
{0x39, " "},
+ {0x53, "\177"}, /* Delete. */
{0, NULL},
};
keyboard_interrupt (struct intr_frame *args UNUSED)
{
/* Status of shift keys. */
- bool shift = (shift_state & (LSHIFT | RSHIFT)) != 0;
- bool alt = (shift_state & (LALT | RALT)) != 0;
- bool ctrl = (shift_state & (LCTRL | RCTRL)) != 0;
- bool caps = (shift_state & CAPS) != 0;
+ bool shift = left_shift || right_shift;
+ bool alt = left_alt || right_alt;
+ bool ctrl = left_ctrl || right_ctrl;
/* Keyboard scancode. */
unsigned code;
{
/* Caps Lock. */
if (!release)
- shift_state ^= CAPS;
+ caps_lock = !caps_lock;
}
else if (map_key (invariant_keymap, code, &c)
|| (!shift && map_key (unshifted_keymap, code, &c))
/* Ordinary character. */
if (!release)
{
+ /* Reboot if Ctrl+Alt+Del pressed. */
+ if (c == 0177 && ctrl && alt)
+ shutdown_reboot ();
+
/* Handle Ctrl, Shift.
Note that Ctrl overrides Shift. */
if (ctrl && c >= 0x40 && c < 0x60)
/* A is 0x41, Ctrl+A is 0x01, etc. */
c -= 0x40;
}
- else if (shift == caps)
+ else if (shift == caps_lock)
c = tolower (c);
/* Handle Alt by setting the high bit.
c += 0x80;
/* Append to keyboard buffer. */
- if (!intq_full (&buffer))
+ if (!input_full ())
{
key_cnt++;
- intq_putc (&buffer, c);
+ input_putc (c);
}
}
}
else
{
- /* Table of shift keys.
- Maps a keycode into a shift_state bit. */
- static const unsigned shift_keys[][2] =
+ /* Maps a keycode into a shift state variable. */
+ struct shift_key
+ {
+ unsigned scancode;
+ bool *state_var;
+ };
+
+ /* Table of shift keys. */
+ static const struct shift_key shift_keys[] =
{
- { 0x2a, LSHIFT},
- { 0x36, RSHIFT},
- { 0x38, LALT},
- {0xe038, RALT},
- { 0x1d, LCTRL},
- {0xe01d, RCTRL},
- {0, 0},
+ { 0x2a, &left_shift},
+ { 0x36, &right_shift},
+ { 0x38, &left_alt},
+ {0xe038, &right_alt},
+ { 0x1d, &left_ctrl},
+ {0xe01d, &right_ctrl},
+ {0, NULL},
};
- const unsigned (*key)[2];
+ const struct shift_key *key;
/* Scan the table. */
- for (key = shift_keys; (*key)[0] != 0; key++)
- if ((*key)[0] == code)
+ for (key = shift_keys; key->scancode != 0; key++)
+ if (key->scancode == code)
{
- if (release)
- shift_state &= ~(*key)[1];
- else
- shift_state |= (*key)[1];
+ *key->state_var = !release;
break;
}
}