diff options
Diffstat (limited to 'console-client/pc-kbd.c')
-rw-r--r-- | console-client/pc-kbd.c | 1285 |
1 files changed, 794 insertions, 491 deletions
diff --git a/console-client/pc-kbd.c b/console-client/pc-kbd.c index 81992975..fd7c5a4b 100644 --- a/console-client/pc-kbd.c +++ b/console-client/pc-kbd.c @@ -39,124 +39,145 @@ static device_t kbd_dev; /* The converter. */ static iconv_t cd; +/* The status of various LEDs. */ +struct { + int scroll_lock : 1; + int num_lock : 1; + int caps_lock : 1; +} led_state; + +/* True if we are in the GNU Mach v1 compatibility mode. */ +int gnumach_v1_compat; + /* Forward declaration. */ static struct input_ops pc_kbd_ops; -/* A list of scan codes generated by the keyboard. */ +/* A list of scan codes generated by the keyboard, in the set 2 encoding. */ enum scancode { - SC_ESC = 0x01, - SC_1 = 0x02, - SC_2 = 0x03, - SC_3 = 0x04, - SC_4 = 0x05, - SC_5 = 0x06, - SC_6 = 0x07, - SC_7 = 0x08, - SC_8 = 0x09, - SC_9 = 0x0A, - SC_0 = 0x0B, - SC_MINUS = 0x0C, /* - */ - SC_EQUAL = 0x0D, /* = */ - SC_BACKSPACE = 0x0E, - SC_TAB = 0x0F, - SC_Q = 0x10, - SC_W = 0x11, - SC_E = 0x12, - SC_R = 0x13, - SC_T = 0x14, - SC_Y = 0x15, - SC_U = 0x16, - SC_I = 0x17, - SC_O = 0x18, - SC_P = 0x19, - SC_LEFT_BRACKET = 0x1A, /* [ */ - SC_RIGHT_BRACKET = 0x1B, /* ] */ - SC_ENTER = 0x1C, - SC_LEFT_CTRL = 0x1D, - SC_A = 0x1E, - SC_S = 0x1F, - SC_D = 0x20, - SC_F = 0x21, - SC_G = 0x22, - SC_H = 0x23, - SC_J = 0x24, - SC_K = 0x25, - SC_L = 0x26, - SC_SEMICOLON = 0x27, /* ; */ - SC_APOSTROPHE = 0x28, /* ' */ - SC_BACKQUOTE = 0x29, /* ` */ - SC_LEFT_SHIFT = 0x2A, - SC_BACKSLASH = 0x2B, /* \ */ - SC_Z = 0x2C, - SC_X = 0x2D, - SC_C = 0x2E, - SC_V = 0x2F, - SC_B = 0x30, + SC_F9 = 0x01, + SC_F5 = 0x03, + SC_F3 = 0x04, + SC_F1 = 0x05, + SC_F2 = 0x06, + SC_F12 = 0x07, + SC_F10 = 0x09, + SC_F8 = 0x0A, + SC_F6 = 0x0B, + SC_F4 = 0x0C, + SC_TAB = 0x0D, + SC_BACKQUOTE = 0x0E, /* ` */ + SC_LEFT_ALT = 0x11, + SC_LEFT_SHIFT = 0x12, + SC_LEFT_CTRL = 0x14, + SC_Q = 0x15, + SC_1 = 0x16, + SC_Z = 0x1A, + SC_S = 0x1B, + SC_A = 0x1C, + SC_W = 0x1D, + SC_2 = 0x1E, + SC_C = 0x21, + SC_X = 0x22, + SC_D = 0x23, + SC_E = 0x24, + SC_4 = 0x25, + SC_3 = 0x26, + SC_SPACE = 0x29, + SC_V = 0x2A, + SC_F = 0x2B, + SC_T = 0x2C, + SC_R = 0x2D, + SC_5 = 0x2E, SC_N = 0x31, - SC_M = 0x32, - SC_COMMA = 0x33, /* , */ - SC_PERIOD = 0x34, /* . */ - SC_SLASH = 0x35, /* / */ - SC_RIGHT_SHIFT = 0x36, - SC_PAD_ASTERISK = 0x37, - SC_LEFT_ALT = 0x38, - SC_SPACE = 0x39, - SC_CAPSLOCK = 0x3A, - SC_F1 = 0x3B, - SC_F2 = 0x3C, - SC_F3 = 0x3D, - SC_F4 = 0x3E, - SC_F5 = 0x3F, - SC_F6 = 0x40, - SC_F7 = 0x41, - SC_F8 = 0x42, - SC_F9 = 0x43, - SC_F10 = 0x44, - SC_NUMLOCK = 0x45, - SC_SCROLLLOCK = 0x46, - SC_PAD_7 = 0x47, - SC_PAD_8 = 0x48, - SC_PAD_9 = 0x49, - SC_PAD_MINUS = 0x4A, - SC_PAD_4 = 0x4B, - SC_PAD_5 = 0x4C, - SC_PAD_6 = 0x4D, - SC_PAD_PLUS = 0x4E, - SC_PAD_1 = 0x4F, - SC_PAD_2 = 0x50, - SC_PAD_3 = 0x51, - SC_PAD_0 = 0x52, - SC_PAD_DECIMAL = 0x53, - SC_SYSREQ = 0x54, - SC_F11 = 0x57, - SC_F12 = 0x58, - SC_FLAG_UP = 0x80, /* ORed to basic scancode. */ + SC_B = 0x32, + SC_H = 0x33, + SC_G = 0x34, + SC_Y = 0x35, + SC_6 = 0x36, + SC_M = 0x3A, + SC_J = 0x3B, + SC_U = 0x3C, + SC_7 = 0x3D, + SC_8 = 0x3E, + SC_COMMA = 0x41, /* , */ + SC_K = 0x42, + SC_I = 0x43, + SC_O = 0x44, + SC_0 = 0x45, + SC_9 = 0x46, + SC_PERIOD = 0x49, /* . */ + SC_SLASH = 0x4A, /* / */ + SC_L = 0x4B, + SC_SEMICOLON = 0x4C, /* ; */ + SC_P = 0x4D, + SC_MINUS = 0x4E, /* - */ + SC_APOSTROPHE = 0x52, /* ' */ + SC_LEFT_BRACKET = 0x54, /* [ */ + SC_EQUAL = 0x55, /* = */ + SC_CAPSLOCK = 0x58, + SC_RIGHT_SHIFT = 0x59, + SC_ENTER = 0x5A, + SC_RIGHT_BRACKET = 0x5B, /* ] */ + SC_BACKSLASH = 0x5D, /* \ */ + SC_BACKSPACE = 0x66, + SC_PAD_1 = 0x69, + SC_PAD_4 = 0x6B, + SC_PAD_7 = 0x6C, + SC_PAD_0 = 0x70, + SC_PAD_DECIMAL = 0x71, + SC_PAD_2 = 0x72, + SC_PAD_5 = 0x73, + SC_PAD_6 = 0x74, + SC_PAD_8 = 0x75, + SC_ESC = 0x76, + SC_NUMLOCK = 0x77, + SC_F11 = 0x78, + SC_PAD_PLUS = 0x79, + SC_PAD_3 = 0x7A, + SC_PAD_MINUS = 0x7B, + SC_PAD_ASTERISK = 0x7C, + SC_PAD_9 = 0x7D, + SC_SCROLLLOCK = 0x7E, + SC_F7 = 0x83, SC_EXTENDED1 = 0xE0, /* One code follows. */ SC_EXTENDED2 = 0xE1, /* Two codes follow (only used for Pause). */ - SC_ERROR = 0xFF /* Too many keys held down. */ + SC_ERROR = 0xFF, /* Too many keys held down. */ + SC_FLAG_UP = 0xF000 /* ORed to basic scancode. */ }; /* Codes which can follow SC_EXTENDED1. */ enum scancode_x1 { - SC_X1_PAD_ENTER = 0x1C, - SC_X1_RIGHT_CTRL = 0x1D, - SC_X1_PAD_SLASH = 0x35, - SC_X1_PRTSC = 0x37, - SC_X1_RIGHT_ALT = 0x38, - SC_X1_BREAK = 0x46, - SC_X1_HOME = 0x47, - SC_X1_UP = 0x48, - SC_X1_PGUP = 0x49, - SC_X1_LEFT = 0x4B, - SC_X1_RIGHT = 0x4D, - SC_X1_END = 0x4F, - SC_X1_DOWN = 0x50, - SC_X1_PGDN = 0x51, - SC_X1_INS = 0x52, - SC_X1_DEL = 0x53 + SC_X1_RIGHT_ALT = 0x11, + SC_X1_PRTSC = 0x12, +/* SC_X1_PRTSC = 0x7C, */ + SC_X1_RIGHT_CTRL = 0x14, + SC_X1_LEFT_GUI = 0x1F, + SC_X1_RIGHT_GUI = 0x27, + SC_X1_APPS = 0x2F, + SC_X1_POWER = 0x37, + SC_X1_SLEEP = 0x3F, + SC_X1_PAD_SLASH = 0x4A, + SC_X1_PAD_ENTER = 0x5A, + SC_X1_WAKEUP = 0x5E, + SC_X1_END = 0x69, + SC_X1_LEFT = 0x6B, + SC_X1_HOME = 0x6C, + SC_X1_INS = 0x70, + SC_X1_DEL = 0x71, + SC_X1_DOWN = 0x72, + SC_X1_RIGHT = 0x74, + SC_X1_UP = 0x75, + SC_X1_PGDN = 0x7A, + SC_X1_PGUP = 0x7D + }; + +/* Codes which can follow SC_EXTENDED2. */ +enum scancode_x2 + { + SC_X2_BREAK = 0x1477, }; @@ -166,97 +187,139 @@ char *sc_to_kc[][7] = { /*None, Shift, Ctrl, LAlt, S+LAlt, C+LAlt, RAlt */ { 0, 0, 0, 0, 0, 0, 0 }, - { "\e", "\e", "\e", "\e\e", "\e\e", "\e\e", "\e" }, /* SC_ESC. */ - { "1", "!", 0, "\e1", "\e!", 0, "1" }, /* SC_1. */ - { "2", "@", "", "\e2", "\e@", 0, "2" }, /* SC_2. */ - { "3", "#", "\e", "\e3", "\e#", 0, "3" }, /* SC_3. */ - { "4", "$", "\x1c", "\e4", "\e$", "\e\x1c", "4" }, /* SC_4. */ - { "5", "%", "\x1d", "\e5", "\e%", 0, "5" }, /* SC_5. */ - { "6", "^", "\x1e", "\e6", "\e^", 0, "6" }, /* SC_6. */ - { "7", "&", "\x1f", "\e7", "\e&", "\e\x1f", "7" }, /* SC_7. */ - { "8", "*", "\x7f", "\e8", "\e*", 0, "8" }, /* SC_8. */ - { "9", "(", 0, "\e9", "\e(", 0, "9" }, /* SC_9. */ - { "0", ")", 0, "\e0", "\e)", 0, "0" }, /* SC_0. */ - { "-", "_", "\x1f", "\e-", "\e_", "\e\x1f", "-" }, /* SC_MINUS. */ - { "=", "+", 0, "\e=", "\e+", 0, "=" }, /* SC_EQUAL. */ - { CONS_KEY_BACKSPACE, CONS_KEY_BACKSPACE, CONS_KEY_BACKSPACE, - "\e" CONS_KEY_BACKSPACE, "\e" CONS_KEY_BACKSPACE, - "\e" CONS_KEY_BACKSPACE, CONS_KEY_BACKSPACE }, /* SC_BACKSPACE. */ - /* XXX back tab? */ + { CONS_KEY_F9, 0, 0, 0, 0, 0, 0 }, /* SC_F9. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { CONS_KEY_F5, CONS_KEY_F17, 0, 0, 0, 0, 0 }, /* SC_F5. */ + { CONS_KEY_F3, CONS_KEY_F15, 0, 0, 0, 0, 0 }, /* SC_F3. */ + { CONS_KEY_F1, CONS_KEY_F13, 0, 0, 0, 0, 0 }, /* SC_F1. */ + { CONS_KEY_F2, CONS_KEY_F14, 0, 0, 0, 0, 0 }, /* SC_F2. */ + { CONS_KEY_F12, 0, 0, 0, 0, 0, 0 }, /* SC_F12. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { CONS_KEY_F10, 0, 0, 0, 0, 0, 0 }, /* SC_F10. */ + { CONS_KEY_F8, CONS_KEY_F20, 0, 0, 0, 0, 0 }, /* SC_F8. */ + { CONS_KEY_F6, CONS_KEY_F18, 0, 0, 0, 0, 0 }, /* SC_F6. */ + { CONS_KEY_F4, CONS_KEY_F16, 0, 0, 0, 0, 0 }, /* SC_F4. */ { "\t", "\t", "\t", "\e\t", "\e\t", "\e\t", "\t" }, /* SC_TAB. */ + { "`", "~", 0, "\e`", "\e~", 0, 0 }, /* SC_BACKQUOTE. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_LEFT_ALT. XXX */ + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_LEFT_SHIFT. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_LEFT_CTRL. XXX */ { "q", "Q", "\x11", "\eq", "\eQ", "\e\x11", "q" }, /* SC_Q. */ + { "1", "!", 0, "\e1", "\e!", 0, "1" }, /* SC_1. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { "z", "Z", "\x1a", "\ez", "\eZ", "\e\x1a", "z" }, /* SC_Z. */ + { "s", "S", "\x13", "\es", "\eS", "\e\x13", "s" }, /* SC_S. */ + { "a", "A", "\x01", "\ea", "\eA", "\e\x01", "a" }, /* SC_A. */ { "w", "W", "\x17", "\ew", "\eW", "\e\x17", "w" }, /* SC_W. */ + { "2", "@", "", "\e2", "\e@", 0, "2" }, /* SC_2. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { "c", "C", "\x03", "\ec", "\eC", "\e\x03", "\xc2\xa2" }, /* SC_C. */ + { "x", "X", "\x18", "\ex", "\eX", "\e\x18", "x" }, /* SC_X. */ + { "d", "D", "\x04", "\ed", "\eD", "\e\x04", "d" }, /* SC_D. */ { "e", "E", "\x05", "\ee", "\eE", "\e\x05","\xe2\x82\xac" }, /* SC_E. */ - { "r", "R", "\x12", "\er", "\eR", "\e\x12", "r" }, /* SC_R. */ + { "4", "$", "\x1c", "\e4", "\e$", "\e\x1c", "4" }, /* SC_4. */ + { "3", "#", "\e", "\e3", "\e#", 0, "3" }, /* SC_3. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { " ", " ", "", "\e ", "\e ", /*XXX*/0, " " }, /* SC_SPACE. */ + { "v", "V", "\x16", "\ev", "\eV", "\e\x16", "v" }, /* SC_V. */ + { "f", "F", "\x06", "\ef", "\eF", "\e\x06", "f" }, /* SC_F. */ { "t", "T", "\x14", "\et", "\eT", "\e\x14", "t" }, /* SC_T. */ + { "r", "R", "\x12", "\er", "\eR", "\e\x12", "r" }, /* SC_R. */ + { "5", "%", "\x1d", "\e5", "\e%", 0, "5" }, /* SC_5. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { "n", "N", "\x0e", "\en", "\eN", "\e\x0e", "n" }, /* SC_N. */ + { "b", "B", "\x02", "\eb", "\eB", "\e\x02", "b" }, /* SC_B. */ + { "h", "H", "\x08", "\eh", "\eH", "\e\x08", "h" }, /* SC_H. */ + { "g", "G", "\x07", "\eg", "\eG", "\e\x07", "g" }, /* SC_G. */ { "y", "Y", "\x19", "\ey", "\eY", "\e\x19", "y" }, /* SC_Y. */ + { "6", "^", "\x1e", "\e6", "\e^", 0, "6" }, /* SC_6. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { "m", "M", "\x0d", "\em", "\eM", "\e\x0d", "m" }, /* SC_M. */ + { "j", "J", "\x0a", "\ej", "\eJ", "\e\x0a", "j" }, /* SC_J. */ { "u", "U", "\x15", "\eu", "\eU", "\e\x15", "u" }, /* SC_U. */ + { "7", "&", "\x1f", "\e7", "\e&", "\e\x1f", "7" }, /* SC_7. */ + { "8", "*", "\x7f", "\e8", "\e*", 0, "8" }, /* SC_8. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { ",", "<", 0, "\e,", "\e<", 0, 0 }, /* SC_COMMA. */ + { "k", "K", "\x0b", "\ek", "\eK", "\e\x0b", "k" }, /* SC_K. */ { "i", "I", "\x09", "\ei", "\eI", "\e\x09", "i" }, /* SC_I. */ { "o", "O", "\x0f", "\eo", "\eO", "\e\x0f", "o" }, /* SC_O. */ - { "p", "P", "\x10", "\ep", "\eP", "\e\x10", "p" }, /* SC_P. */ - { "[", "{", "\e", "\e[", "\e{", 0, 0 }, /* SC_LEFT_BRACKET. */ - { "]", "}", "\x1d", "\e]", "\e}", "\e\x1d", "~" }, /* SC_RIGHT_BRACKET. */ - {"\x0d","\x0d", "\x0d","\e\x0d","\e\x0d","\e\x0d","\x0d" }, /* SC_ENTER. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_LEFT_CTRL. XXX */ - { "a", "A", "\x01", "\ea", "\eA", "\e\x01", "a" }, /* SC_A. */ - { "s", "S", "\x13", "\es", "\eS", "\e\x13", "s" }, /* SC_S. */ - { "d", "D", "\x04", "\ed", "\eD", "\e\x04", "d" }, /* SC_D. */ - { "f", "F", "\x06", "\ef", "\eF", "\e\x06", "f" }, /* SC_F. */ - { "g", "G", "\x07", "\eg", "\eG", "\e\x07", "g" }, /* SC_G. */ - { "h", "H", "\x08", "\eh", "\eH", "\e\x08", "h" }, /* SC_H. */ - { "j", "J", "\x0a", "\ej", "\eJ", "\e\x0a", "j" }, /* SC_J. */ - { "k", "K", "\x0b", "\ek", "\eK", "\e\x0b", "k" }, /* SC_K. */ + { "0", ")", 0, "\e0", "\e)", 0, "0" }, /* SC_0. */ + { "9", "(", 0, "\e9", "\e(", 0, "9" }, /* SC_9. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { ".", ">", 0, "\e.", "\e>", 0, 0 }, /* SC_PERIOD. */ + { "/", "?", "\x7f", "\e/", "\e?", 0, 0 }, /* SC_SLASH. */ { "l", "L", "\x0c", "\el", "\eL", "\e\x0c", "l" }, /* SC_L. */ { ";", ":", 0, "\e;", "\e:", 0, 0 }, /* SC_SEMICOLON. */ + { "p", "P", "\x10", "\ep", "\eP", "\e\x10", "p" }, /* SC_P. */ + { "-", "_", "\x1f", "\e-", "\e_", "\e\x1f", "-" }, /* SC_MINUS. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { "'", "\"", "\x07", "\e'", "\e\"", 0, 0 }, /* SC_APOSTROPHE. */ - { "`", "~", 0, "\e`", "\e~", 0, 0 }, /* SC_BACKQUOTE. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_LEFT_SHIFT. */ - { "\\", "|", "\x1c", "\e\\", "\e|", 0, 0 }, /* SC_BACKSLASH. */ - { "z", "Z", "\x1a", "\ez", "\eZ", "\e\x1a", "z" }, /* SC_Z. */ - { "x", "X", "\x18", "\ex", "\eX", "\e\x18", "x" }, /* SC_X. */ - { "c", "C", "\x03", "\ec", "\eC", "\e\x03", "\xc2\xa2" }, /* SC_C. */ - { "v", "V", "\x16", "\ev", "\eV", "\e\x16", "v" }, /* SC_V. */ - { "b", "B", "\x02", "\eb", "\eB", "\e\x02", "b" }, /* SC_B. */ - { "n", "N", "\x0e", "\en", "\eN", "\e\x0e", "n" }, /* SC_N. */ - { "m", "M", "\x0d", "\em", "\eM", "\e\x0d", "m" }, /* SC_M. */ - { ",", "<", 0, "\e,", "\e<", 0, 0 }, /* SC_COMMA. */ - { ".", ">", 0, "\e.", "\e>", 0, 0 }, /* SC_PERIOD. */ - { "/", "?", "\x7f", "\e/", "\e?", 0, 0 }, /* SC_SLASH. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_RIGHT_SHIFT. */ - { "*", "*", "*", "*", "*", "*", "*" }, /* SC_PAD_ASTERISK. XXX */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_LEFT_ALT. XXX */ - { " ", " ", "", "\e ", "\e ", /*XXX*/0, " " }, /* SC_SPACE. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { "[", "{", "\e", "\e[", "\e{", 0, 0 }, /* SC_LEFT_BRACKET. */ + { "=", "+", 0, "\e=", "\e+", 0, "=" }, /* SC_EQUAL. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, /* SC_CAPSLOCK. */ - { CONS_KEY_F1, CONS_KEY_F13, 0, 0, 0, 0, 0 }, /* SC_F1. */ - { CONS_KEY_F2, CONS_KEY_F14, 0, 0, 0, 0, 0 }, /* SC_F2. */ - { CONS_KEY_F3, CONS_KEY_F15, 0, 0, 0, 0, 0 }, /* SC_F3. */ - { CONS_KEY_F4, CONS_KEY_F16, 0, 0, 0, 0, 0 }, /* SC_F4. */ - { CONS_KEY_F5, CONS_KEY_F17, 0, 0, 0, 0, 0 }, /* SC_F5. */ - { CONS_KEY_F6, CONS_KEY_F18, 0, 0, 0, 0, 0 }, /* SC_F6. */ - { CONS_KEY_F7, CONS_KEY_F19, 0, 0, 0, 0, 0 }, /* SC_F7. */ - { CONS_KEY_F8, CONS_KEY_F20, 0, 0, 0, 0, 0 }, /* SC_F8. */ - { CONS_KEY_F9, 0, 0, 0, 0, 0, 0 }, /* SC_F9. */ - { CONS_KEY_F10, 0, 0, 0, 0, 0, 0 }, /* SC_F10. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_NUMLOCK. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_SCROLLLOCK. */ - { CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME, 0, 0, 0, 0 }, /* SC_PAD_7. */ - { CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP, 0, 0, 0, 0 }, /* SC_PAD_8. */ - { CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE,0, 0, 0, 0 }, /* SC_PAD_9. */ - { "-", "-", "-", "-", "-", "-", "-" }, /* SC_PAD_MINUS. */ - { CONS_KEY_LEFT, CONS_KEY_LEFT, CONS_KEY_LEFT, 0, 0, 0, 0 }, /* SC_PAD_4. */ - {/* XXX */ "\e[G", "\e[G", "\e[G", 0, 0, 0, 0 }, /* SC_PAD_5. */ - { CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT,0, 0, 0, 0 }, /* SC_PAD_6. */ - { "+", "+", "+", "+", "+", "+", "+" }, /* SC_PAD_MINUS. */ + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_RIGHT_SHIFT. */ + {"\x0d","\x0d", "\x0d","\e\x0d","\e\x0d","\e\x0d","\x0d" }, /* SC_ENTER. */ + { "]", "}", "\x1d", "\e]", "\e}", "\e\x1d", "~" }, /* SC_RIGHT_BRACKET. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { "\\", "|", "\x1c", "\e\\", "\e|", 0, 0 }, /* SC_BACKSLASH. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { CONS_KEY_BACKSPACE, CONS_KEY_BACKSPACE, CONS_KEY_BACKSPACE, + "\e" CONS_KEY_BACKSPACE, "\e" CONS_KEY_BACKSPACE, + "\e" CONS_KEY_BACKSPACE, CONS_KEY_BACKSPACE }, /* SC_BACKSPACE. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { CONS_KEY_END, CONS_KEY_END, CONS_KEY_END, 0, 0, 0, 0 }, /* SC_PAD_1. */ - { CONS_KEY_DOWN, CONS_KEY_DOWN, CONS_KEY_DOWN, 0, 0, 0, 0 }, /* SC_PAD_2. */ - { CONS_KEY_NPAGE, CONS_KEY_NPAGE, CONS_KEY_NPAGE,0, 0, 0, 0 }, /* SC_PAD_3. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { CONS_KEY_LEFT, CONS_KEY_LEFT, CONS_KEY_LEFT, 0, 0, 0, 0 }, /* SC_PAD_4. */ + { CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME, 0, 0, 0, 0 }, /* SC_PAD_7. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { CONS_KEY_IC, CONS_KEY_IC, CONS_KEY_IC, 0, 0, 0, 0 }, /* SC_PAD_0. */ { CONS_KEY_DC, CONS_KEY_DC, CONS_KEY_DC, 0, 0, 0, 0 }, /* SC_PAD_DECIMAL. */ - { 0, 0, /*XX*/0, 0, 0, 0, 0 }, /* SC_SYSREQ. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* Unused. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* Unused. */ + { CONS_KEY_DOWN, CONS_KEY_DOWN, CONS_KEY_DOWN, 0, 0, 0, 0 }, /* SC_PAD_2. */ + {/* XXX */ "\e[G", "\e[G", "\e[G", 0, 0, 0, 0 }, /* SC_PAD_5. */ + { CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT,0, 0, 0, 0 }, /* SC_PAD_6. */ + { CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP, 0, 0, 0, 0 }, /* SC_PAD_8. */ + { "\e", "\e", "\e", "\e\e", "\e\e", "\e\e", "\e" }, /* SC_ESC. */ + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_NUMLOCK. */ { CONS_KEY_F11, 0, 0, 0, 0, 0, 0 }, /* SC_F11. */ - { CONS_KEY_F12, 0, 0, 0, 0, 0, 0 } /* SC_F12. */ + { "+", "+", "+", "+", "+", "+", "+" }, /* SC_PAD_PLUS. */ + { CONS_KEY_NPAGE, CONS_KEY_NPAGE, CONS_KEY_NPAGE,0, 0, 0, 0 }, /* SC_PAD_3. */ + { "-", "-", "-", "-", "-", "-", "-" }, /* SC_PAD_MINUS. */ + { "*", "*", "*", "*", "*", "*", "*" }, /* SC_PAD_ASTERISK. XXX */ + { CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE,0, 0, 0, 0 }, /* SC_PAD_9. */ + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_SCROLLLOCK. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { CONS_KEY_F7, CONS_KEY_F19, 0, 0, 0, 0, 0 } /* SC_F7. */ }; char *sc_x1_to_kc[][7] = @@ -270,64 +333,225 @@ char *sc_x1_to_kc[][7] = { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_RIGHT_ALT. */ + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_PRTSC. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_RIGHT_CTRL. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_LEFT_GUI. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, - { "\n", "\n", "\n", "\n", "\n", "\n", 0 }, /* SC_X1_PAD_ENTER. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_RIGHT_CTRL. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_RIGHT_GUI. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_APPS. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_POWER. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_SLEEP. */ + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { "/", "/", "/", "/", "/", "/", 0 }, /* SC_X1_PAD_SLASH. */ + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_PRTSC. */ - { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_RIGHT_ALT. */ - { 0, 0, 0, 0, 0, 0, 0 }, + { "\n", "\n", "\n", "\n", "\n", "\n", 0 }, /* SC_X1_PAD_ENTER. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, /* SC_X1_WAKEUP. */ { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, - { "\e[P", "\e[P", "\e[P", "\e[P", "\e[P", "\e[P","\e[P" }, /* SC_X1_BREAK. */ - { CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME, - CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME }, /* SC_X1_HOME. */ - { CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP, - CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP }, /* SC_X1_UP. */ - { CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE, - CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE }, /* SC_X1_PGUP. */ + { CONS_KEY_END, CONS_KEY_END, CONS_KEY_END, CONS_KEY_END, + CONS_KEY_END, CONS_KEY_END, CONS_KEY_END }, /* SC_X1_END. */ { 0, 0, 0, 0, 0, 0, 0 }, { CONS_KEY_LEFT, CONS_KEY_LEFT, CONS_KEY_LEFT, CONS_KEY_LEFT, CONS_KEY_LEFT, CONS_KEY_LEFT, CONS_KEY_LEFT }, /* SC_X1_LEFT. */ + { CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME, + CONS_KEY_HOME, CONS_KEY_HOME, CONS_KEY_HOME }, /* SC_X1_HOME. */ + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, - { CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT, - CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT }, /* SC_X1_RIGHT. */ - { 0, 0, 0, 0, 0, 0, 0 }, - { CONS_KEY_END, CONS_KEY_END, CONS_KEY_END, CONS_KEY_END, - CONS_KEY_END, CONS_KEY_END, CONS_KEY_END }, /* SC_X1_END. */ + { CONS_KEY_IC, CONS_KEY_IC, CONS_KEY_IC, CONS_KEY_IC, + CONS_KEY_IC, CONS_KEY_IC, CONS_KEY_IC }, /* SC_X1_INS. */ + { CONS_KEY_DC, CONS_KEY_DC, CONS_KEY_DC, CONS_KEY_DC, + CONS_KEY_DC, CONS_KEY_DC, CONS_KEY_DC }, /* SC_X1_DEL. */ { CONS_KEY_DOWN, CONS_KEY_DOWN, CONS_KEY_DOWN, CONS_KEY_DOWN, CONS_KEY_DOWN, CONS_KEY_DOWN, CONS_KEY_DOWN }, /* SC_X1_DOWN. */ + { 0, 0, 0, 0, 0, 0, 0 }, + { CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT, + CONS_KEY_RIGHT, CONS_KEY_RIGHT, CONS_KEY_RIGHT }, /* SC_X1_RIGHT. */ + { CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP, + CONS_KEY_UP, CONS_KEY_UP, CONS_KEY_UP }, /* SC_X1_UP. */ + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, { CONS_KEY_NPAGE, CONS_KEY_NPAGE, CONS_KEY_NPAGE, CONS_KEY_NPAGE, CONS_KEY_NPAGE, CONS_KEY_NPAGE, CONS_KEY_NPAGE }, /* SC_X1_PGDN. */ - { CONS_KEY_IC, CONS_KEY_IC, CONS_KEY_IC, CONS_KEY_IC, - CONS_KEY_IC, CONS_KEY_IC, CONS_KEY_IC }, /* SC_X1_INS. */ - { CONS_KEY_DC, CONS_KEY_DC, CONS_KEY_DC, CONS_KEY_DC, - CONS_KEY_DC, CONS_KEY_DC, CONS_KEY_DC } /* SC_X1_DEL. */ + { 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0 }, + { CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE, + CONS_KEY_PPAGE, CONS_KEY_PPAGE, CONS_KEY_PPAGE } /* SC_X1_PGUP. */ + }; + +char *sc_x2_to_kc[][7] = + { + /* We don't add all those zero entries here. It's just one key, + so it's special cased. */ + { "\e[P", "\e[P", "\e[P", "\e[P", "\e[P", "\e[P","\e[P" }, /* SC_X1_BREAK. */ }; +/* GNU Mach v1 compatibility code. */ + +/* This is a conversion table from i8042 scancode set 1 to set 2. */ +enum scancode sc_set1_to_set2[] = + { + 0x00, + SC_ESC, + SC_1, + SC_2, + SC_3, + SC_4, + SC_5, + SC_6, + SC_7, + SC_8, + SC_9, + SC_0, + SC_MINUS, + SC_EQUAL, + SC_BACKSPACE, + SC_TAB, + SC_Q, + SC_W, + SC_E, + SC_R, + SC_T, + SC_Y, + SC_U, + SC_I, + SC_O, + SC_P, + SC_LEFT_BRACKET, + SC_RIGHT_BRACKET, + SC_ENTER, + SC_LEFT_CTRL, + SC_A, + SC_S, + SC_D, + SC_F, + SC_G, + SC_H, + SC_J, + SC_K, + SC_L, + SC_SEMICOLON, + SC_APOSTROPHE, + SC_BACKQUOTE, + SC_LEFT_SHIFT, + SC_BACKSLASH, + SC_Z, + SC_X, + SC_C, + SC_V, + SC_B, + SC_N, + SC_M, + SC_COMMA, + SC_PERIOD, + SC_SLASH, + SC_RIGHT_SHIFT, + SC_PAD_ASTERISK, + SC_LEFT_ALT, + SC_SPACE, + SC_CAPSLOCK, + SC_F1, + SC_F2, + SC_F3, + SC_F4, + SC_F5, + SC_F6, + SC_F7, + SC_F8, + SC_F9, + SC_F10, + SC_NUMLOCK, + SC_SCROLLLOCK, + SC_PAD_7, + SC_PAD_8, + SC_PAD_9, + SC_PAD_MINUS, + SC_PAD_4, + SC_PAD_5, + SC_PAD_6, + SC_PAD_PLUS, + SC_PAD_1, + SC_PAD_2, + SC_PAD_3, + SC_PAD_0, + SC_PAD_DECIMAL, + 0x00, /* XXX SYSREQ */ + SC_F11, + SC_F12, + }; + +/* Conversion table for codes which can follow SC_EXTENDED1. */ +enum scancode sc_set1_to_set2_x1[] = + { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + SC_X1_PAD_ENTER, + SC_X1_RIGHT_CTRL, + 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + SC_X1_PAD_SLASH, + 0x00, + SC_X1_PRTSC, + SC_X1_RIGHT_ALT, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, /* XXX SC_X1_BREAK */ + SC_X1_HOME, + SC_X1_UP, + SC_X1_PGUP, + 0x00, + SC_X1_LEFT, + 0x00, + SC_X1_RIGHT, + 0x00, + SC_X1_END, + SC_X1_DOWN, + SC_X1_PGDN, + SC_X1_INS, + SC_X1_DEL + }; + + /* This gross stuff is cut & pasted from Mach sources, as Mach doesn't export the interface we are using here. */ @@ -405,6 +629,96 @@ typedef struct { /* End of Mach code. */ +static enum scancode +gnumach_v1_input_next () +{ + kd_event data_buf; + int up; + enum scancode sc; + + do + { + /* io_buf_ptr_t is (char *), not (void *). So I have a few + casts to quiet warnings. */ + mach_msg_type_number_t data_cnt = sizeof (data_buf); + error_t err = device_read_inband (kbd_dev, 0, -1, sizeof (kd_event), + (void *) &data_buf, &data_cnt); + + /* XXX The error occured likely because KBD_DEV was closed, so + terminate. */ + if (err) + return 0; + } + while (data_buf.type != KEYBD_EVENT); + + /* Some fixed codes which are the same in set 1 and set 2, and have + the UP flag set. */ + if (data_buf.value.sc == SC_EXTENDED1 + || data_buf.value.sc == SC_EXTENDED2 + || data_buf.value.sc == SC_ERROR) + return data_buf.value.sc; + +#define SC_SET1_FLAG_UP 0x80 + up = data_buf.value.sc & SC_SET1_FLAG_UP; + sc = sc_set1_to_set2[data_buf.value.sc &~ SC_SET1_FLAG_UP]; + + return sc | (up ? SC_FLAG_UP : 0); +} + + +static void +update_leds (void) +{ + char leds[2]; + error_t err; + + /* GNU Mach v1 does not support setting the keyboard LEDs. */ + if (gnumach_v1_compat) + return; + + leds[0] = '\xed'; + leds[1] = (led_state.scroll_lock ? 1 : 0) + | (led_state.num_lock ? 2 : 0) + | (led_state.caps_lock ? 4 : 0); + mach_msg_type_number_t data_cnt = 2; + err = device_write_inband (kbd_dev, 0, -1, (void *) leds, 2, &data_cnt); + if (!err && data_cnt == 1) + err = device_write_inband (kbd_dev, 0, -1, (void *) &leds[1], 1, + &data_cnt); +} + +static enum scancode +input_next () +{ + enum scancode sc = 0; + unsigned char next; + + /* GNU Mach v1 does provide keyboard input in a different format. */ + if (gnumach_v1_compat) + return gnumach_v1_input_next (); + + /* XXX This should read several characters at once. */ + do + { + mach_msg_type_number_t data_cnt = 1; + error_t err = device_read_inband (kbd_dev, 0, -1, 1, + (void *) &next, &data_cnt); + + /* XXX The error occured likely because KBD_DEV was closed, so + terminate. */ + if (err) + return 0; + + if (next == 0xF0) + /* XXX Magic constant. */ + sc |= SC_FLAG_UP; + } + while (next == 0xF0); /* XXX Magic constant. */ + + sc |= next; + return sc; +} + /* The input loop. */ static any_t @@ -412,316 +726,289 @@ input_loop (any_t unused) { while (1) { - kd_event data_buf; + enum scancode fsc = input_next (); + enum scancode sc = fsc & ~SC_FLAG_UP; + int down = !(fsc & SC_FLAG_UP); + char buf[100]; + size_t size = 0; + int modifier = -1; - /* io_buf_ptr_t is (char *), not (void *). So I have a few - casts to quiet warnings. */ - io_buf_ptr_t data_ptr = (void *) &data_buf; - mach_msg_type_number_t data_cnt = sizeof data_buf; - - /* I suppose this could be sped up by reading multiple events - per call. But that isn't important since this is called just - a couple of times per keystroke. Things might be different - if we supported a mouse. */ - error_t err = device_read (kbd_dev, /* device */ - 0, /* mode: could be D_NOWAIT */ - -1, /* recnum: not used by kbdread */ - sizeof (kd_event), /* bytes_wanted */ - &data_ptr, &data_cnt); - if (err) - /* XXX The error occured likely because KBD_DEV was closed, so - terminate. */ - return 0; + static struct { + wchar_t direct; + unsigned int extended : 2; + unsigned int left_shift : 1; + unsigned int right_shift : 1; + unsigned int caps_lock : 1; + unsigned int caps_lock_pressed : 1; + unsigned int left_ctrl : 1; + unsigned int right_ctrl : 1; + unsigned int left_alt : 1; + unsigned int right_alt : 1; + unsigned int num_lock : 1; + unsigned int num_lock_pressed : 1; + } state; - if ((void *) data_ptr != &data_buf) - { - /* Copy the structure to the expected place. */ - data_buf = *(kd_event *) data_ptr; - munmap (data_ptr, data_cnt); - } + if (!state.left_alt && !state.right_alt) + { + if (state.left_ctrl || state.right_ctrl) + modifier = 2; + else if (state.left_shift || state.right_shift) + modifier = 1; + else + modifier = 0; + } + else if (state.left_alt) + { + if (state.left_ctrl || state.right_ctrl) + modifier = 5; + if (state.left_shift || state.right_shift) + modifier = 4; + else + modifier = 3; + } + else if (state.right_alt) + { + if (!state.left_ctrl && !state.right_ctrl + && !state.left_shift && !state.right_shift) + modifier = 6; + } - if (data_buf.type == KEYBD_EVENT) + if (!state.extended) { - enum scancode fsc = data_buf.value.sc; - enum scancode sc = fsc & 0x7f; - int down = !(fsc & SC_FLAG_UP); - char buf[100]; - size_t size = 0; - int modifier = -1; - - static struct { - wchar_t direct; - unsigned int extended : 2; - unsigned int left_shift : 1; - unsigned int right_shift : 1; - unsigned int caps_lock : 1; - unsigned int caps_lock_pressed : 1; - unsigned int left_ctrl : 1; - unsigned int right_ctrl : 1; - unsigned int left_alt : 1; - unsigned int right_alt : 1; - unsigned int num_lock : 1; - unsigned int num_lock_pressed : 1; - } state; - - if (!state.left_alt && !state.right_alt) - { - if (state.left_ctrl || state.right_ctrl) - modifier = 2; - else if (state.left_shift || state.right_shift) - modifier = 1; - else - modifier = 0; - } - else if (state.left_alt) + if (fsc == SC_EXTENDED1) + state.extended = 1; + else if (fsc == SC_EXTENDED2) + state.extended = 2; + else if (sc == SC_LEFT_SHIFT) + state.left_shift = down; + else if (sc == SC_RIGHT_SHIFT) + state.right_shift = down; + else if (sc == SC_CAPSLOCK) { - if (state.left_ctrl || state.right_ctrl) - modifier = 5; - if (state.left_shift || state.right_shift) - modifier = 4; - else - modifier = 3; + if (down && !state.caps_lock_pressed) + { + state.caps_lock = !state.caps_lock; + state.caps_lock_pressed = 1; + led_state.caps_lock = state.caps_lock; + update_leds (); + } + else if (!down) + state.caps_lock_pressed = 0; } - else if (state.right_alt) + else if (sc == SC_LEFT_CTRL) + state.left_ctrl = down; + else if (sc == SC_LEFT_ALT) + state.left_alt = down; + else if (state.left_alt && down && sc >= SC_F1 && sc <= SC_F10) /* XXX */ + console_switch (1 + (sc - SC_F1), 0); + else if (state.left_alt && state.left_ctrl && down && sc == SC_BACKSPACE) + console_exit (); + else if (state.right_alt && down && sc == SC_PAD_0) /* XXX */ + state.direct = (state.direct << 4) | 0x0; + else if (state.right_alt && down && sc == SC_PAD_1) /* XXX */ + state.direct = (state.direct << 4) | 0x1; + else if (state.right_alt && down && sc == SC_PAD_2) /* XXX */ + state.direct = (state.direct << 4) | 0x2; + else if (state.right_alt && down && sc == SC_PAD_3) /* XXX */ + state.direct = (state.direct << 4) | 0x3; + else if (state.right_alt && down && sc == SC_PAD_4) /* XXX */ + state.direct = (state.direct << 4) | 0x4; + else if (state.right_alt && down && sc == SC_PAD_5) /* XXX */ + state.direct = (state.direct << 4) | 0x5; + else if (state.right_alt && down && sc == SC_PAD_6) /* XXX */ + state.direct = (state.direct << 4) | 0x6; + else if (state.right_alt && down && sc == SC_PAD_7) /* XXX */ + state.direct = (state.direct << 4) | 0x7; + else if (state.right_alt && down && sc == SC_PAD_8) /* XXX */ + state.direct = (state.direct << 4) | 0x8; + else if (state.right_alt && down && sc == SC_PAD_9) /* XXX */ + state.direct = (state.direct << 4) | 0x9; + else if (state.right_alt && down && sc == SC_NUMLOCK) /* XXX */ + state.direct = (state.direct << 4) | 0xa; + else if (state.right_alt && down && sc == SC_PAD_ASTERISK) /* XXX */ + state.direct = (state.direct << 4) | 0xc; + else if (state.right_alt && down && sc == SC_PAD_MINUS) /* XXX */ + state.direct = (state.direct << 4) | 0xd; + else if (state.right_alt && down && sc == SC_PAD_PLUS) /* XXX */ + state.direct = (state.direct << 4) | 0xe; + else if (sc == SC_NUMLOCK) { - if (!state.left_ctrl && !state.right_ctrl - && !state.left_shift && !state.right_shift) - modifier = 6; + if (down && !state.num_lock_pressed) + { + state.num_lock = !state.num_lock; + state.num_lock_pressed = 1; + led_state.num_lock = state.num_lock; + update_leds (); + } + else if (!down) + state.num_lock_pressed = 0; } - - if (!state.extended) + else if (down && sc < sizeof (sc_to_kc)/sizeof (sc_to_kc[0])) { - if (fsc == SC_EXTENDED1) - state.extended = 1; - else if (fsc == SC_EXTENDED2) - state.extended = 2; - else if (sc == SC_LEFT_SHIFT) - state.left_shift = down; - else if (sc == SC_RIGHT_SHIFT) - state.right_shift = down; - else if (sc == SC_CAPSLOCK) +#if QUAERENDO_INVENIETIS + if (state.left_alt && state.right_alt + && sc_to_kc[sc][0][0] >= '0' && sc_to_kc[sc][0][0] <= '9' + && sc_to_kc[sc][0][1] == '\0') + console_deprecated (sc_to_kc[sc][0][0] - '0'); + else +#endif { - if (down && !state.caps_lock_pressed) + /* Special rule for caps lock. */ + if (modifier == 0 && state.caps_lock + && sc_to_kc[sc][modifier] + && sc_to_kc[sc][modifier][0] >= 'a' + && sc_to_kc[sc][modifier][0] <= 'z' + && sc_to_kc[sc][modifier][1] == '\0') + modifier = 1; + else if (state.num_lock && sc == SC_PAD_0) { - state.caps_lock = !state.caps_lock; - state.caps_lock_pressed = 1; + modifier = 0; + sc = SC_0; } - else if (!down) - state.caps_lock_pressed = 0; - } - else if (sc == SC_LEFT_CTRL) - state.left_ctrl = down; - else if (sc == SC_LEFT_ALT) - state.left_alt = down; - else if (state.left_alt && down && sc >= SC_F1 && sc <= SC_F10) /* XXX */ - console_switch (1 + (sc - SC_F1), 0); - else if (state.left_alt && state.left_ctrl && down && sc == SC_BACKSPACE) - console_exit (); - else if (state.right_alt && down && sc == SC_PAD_0) /* XXX */ - state.direct = (state.direct << 4) | 0x0; - else if (state.right_alt && down && sc == SC_PAD_1) /* XXX */ - state.direct = (state.direct << 4) | 0x1; - else if (state.right_alt && down && sc == SC_PAD_2) /* XXX */ - state.direct = (state.direct << 4) | 0x2; - else if (state.right_alt && down && sc == SC_PAD_3) /* XXX */ - state.direct = (state.direct << 4) | 0x3; - else if (state.right_alt && down && sc == SC_PAD_4) /* XXX */ - state.direct = (state.direct << 4) | 0x4; - else if (state.right_alt && down && sc == SC_PAD_5) /* XXX */ - state.direct = (state.direct << 4) | 0x5; - else if (state.right_alt && down && sc == SC_PAD_6) /* XXX */ - state.direct = (state.direct << 4) | 0x6; - else if (state.right_alt && down && sc == SC_PAD_7) /* XXX */ - state.direct = (state.direct << 4) | 0x7; - else if (state.right_alt && down && sc == SC_PAD_8) /* XXX */ - state.direct = (state.direct << 4) | 0x8; - else if (state.right_alt && down && sc == SC_PAD_9) /* XXX */ - state.direct = (state.direct << 4) | 0x9; - else if (state.right_alt && down && sc == SC_NUMLOCK) /* XXX */ - state.direct = (state.direct << 4) | 0xa; - else if (state.right_alt && down && sc == SC_PAD_ASTERISK) /* XXX */ - state.direct = (state.direct << 4) | 0xc; - else if (state.right_alt && down && sc == SC_PAD_MINUS) /* XXX */ - state.direct = (state.direct << 4) | 0xd; - else if (state.right_alt && down && sc == SC_PAD_PLUS) /* XXX */ - state.direct = (state.direct << 4) | 0xe; - else if (sc == SC_NUMLOCK) - { - if (down && !state.num_lock_pressed) + else if (state.num_lock && sc == SC_PAD_1) { - state.num_lock = !state.num_lock; - state.num_lock_pressed = 1; + modifier = 0; + sc = SC_1; } - else if (!down) - state.num_lock_pressed = 0; - } - else if (down && sc < sizeof (sc_to_kc)/sizeof (sc_to_kc[0])) - { -#if QUAERENDO_INVENIETIS - if (state.left_alt && state.right_alt - && sc_to_kc[sc][0][0] >= '0' && sc_to_kc[sc][0][0] <= '9' - && sc_to_kc[sc][0][1] == '\0') - console_deprecated (sc_to_kc[sc][0][0] - '0'); - else -#endif + else if (state.num_lock && sc == SC_PAD_2) { - /* Special rule for caps lock. */ - if (modifier == 0 && state.caps_lock - && sc_to_kc[sc][modifier] - && sc_to_kc[sc][modifier][0] >= 'a' - && sc_to_kc[sc][modifier][0] <= 'z' - && sc_to_kc[sc][modifier][1] == '\0') - modifier = 1; - else if (state.num_lock && sc == SC_PAD_0) - { - modifier = 0; - sc = SC_0; - } - else if (state.num_lock && sc == SC_PAD_1) - { - modifier = 0; - sc = SC_1; - } - else if (state.num_lock && sc == SC_PAD_2) - { - modifier = 0; - sc = SC_2; - } - else if (state.num_lock && sc == SC_PAD_3) - { - modifier = 0; - sc = SC_3; - } - else if (state.num_lock && sc == SC_PAD_4) - { - modifier = 0; - sc = SC_4; - } - else if (state.num_lock && sc == SC_PAD_5) - { - modifier = 0; - sc = SC_5; - } - else if (state.num_lock && sc == SC_PAD_6) - { - modifier = 0; - sc = SC_6; - } - else if (state.num_lock && sc == SC_PAD_7) - { - modifier = 0; - sc = SC_7; - } - else if (state.num_lock && sc == SC_PAD_8) - { - modifier = 0; - sc = SC_8; - } - else if (state.num_lock && sc == SC_PAD_9) - { - modifier = 0; - sc = SC_9; - } - else if (state.num_lock && sc == SC_PAD_DECIMAL) + modifier = 0; + sc = SC_2; + } + else if (state.num_lock && sc == SC_PAD_3) + { + modifier = 0; + sc = SC_3; + } + else if (state.num_lock && sc == SC_PAD_4) + { + modifier = 0; + sc = SC_4; + } + else if (state.num_lock && sc == SC_PAD_5) + { + modifier = 0; + sc = SC_5; + } + else if (state.num_lock && sc == SC_PAD_6) + { + modifier = 0; + sc = SC_6; + } + else if (state.num_lock && sc == SC_PAD_7) + { + modifier = 0; + sc = SC_7; + } + else if (state.num_lock && sc == SC_PAD_8) + { + modifier = 0; + sc = SC_8; + } + else if (state.num_lock && sc == SC_PAD_9) + { + modifier = 0; + sc = SC_9; + } + else if (state.num_lock && sc == SC_PAD_DECIMAL) + { + modifier = 0; + sc = SC_PERIOD; + } + + if (modifier >= 0 && sc_to_kc[sc][modifier]) + { + if (!sc_to_kc[sc][modifier][0]) { - modifier = 0; - sc = SC_PERIOD; + /* Special meaning, emit NUL. */ + assert (size < 100); + buf[size++] = '\0'; } - - if (modifier >= 0 && sc_to_kc[sc][modifier]) + else { - if (!sc_to_kc[sc][modifier][0]) - { - /* Special meaning, emit NUL. */ - assert (size < 100); - buf[size++] = '\0'; - } - else - { - assert (size - < 101 - strlen(sc_to_kc[sc][modifier])); - strcpy (&buf[size], sc_to_kc[sc][modifier]); - size += strlen (sc_to_kc[sc][modifier]); - } + assert (size + < 101 - strlen(sc_to_kc[sc][modifier])); + strcpy (&buf[size], sc_to_kc[sc][modifier]); + size += strlen (sc_to_kc[sc][modifier]); } } } } - else if (state.extended == 1) + } + else if (state.extended == 1) + { + state.extended = 0; + if (sc == SC_X1_RIGHT_CTRL) + state.right_ctrl = down; + else if (sc == SC_X1_RIGHT_ALT) { - state.extended = 0; - if (sc == SC_X1_RIGHT_CTRL) - state.right_ctrl = down; - else if (sc == SC_X1_RIGHT_ALT) + state.right_alt = down; + + /* Handle the AltGR+Keypad direct input. */ + if (down) + state.direct = (wchar_t) 0; + else { - state.right_alt = down; - - /* Handle the AltGR+Keypad direct input. */ - if (down) - state.direct = (wchar_t) 0; - else + if (state.direct != (wchar_t) 0) { - if (state.direct != (wchar_t) 0) + char *buffer = &buf[size]; + size_t left = sizeof (buf) - size; + char *inbuf = (char *) &state.direct; + size_t inbufsize = sizeof (wchar_t); + int nr; + + nr = iconv (cd, &inbuf, &inbufsize, &buffer, &left); + if (nr == (size_t) -1) { - char *buffer = &buf[size]; - size_t left = sizeof (buf) - size; - char *inbuf = (char *) &state.direct; - size_t inbufsize = sizeof (wchar_t); - int nr; - - nr = iconv (cd, &inbuf, &inbufsize, &buffer, &left); - if (nr == (size_t) -1) - { - if (errno == E2BIG) - console_error (L"Input buffer overflow"); - else if (errno == EILSEQ) - console_error - (L"Input contained invalid byte sequence"); - else if (errno == EINVAL) - console_error - (L"Input contained incomplete byte sequence"); - else - console_error - (L"Input caused unexpected error"); - } - size = sizeof (buf) - left; + if (errno == E2BIG) + console_error (L"Input buffer overflow"); + else if (errno == EILSEQ) + console_error + (L"Input contained invalid byte sequence"); + else if (errno == EINVAL) + console_error + (L"Input contained incomplete byte sequence"); + else + console_error + (L"Input caused unexpected error"); } + size = sizeof (buf) - left; } } - else if (state.right_alt && down && sc == SC_X1_PAD_SLASH) /* XXX */ - state.direct = (state.direct << 4) | 0xb; - else if (state.right_alt && down && sc == SC_X1_PAD_ENTER) /* XXX */ - state.direct = (state.direct << 4) | 0xf; - else if (state.left_alt && down && sc == SC_X1_RIGHT) /* XXX */ - console_switch (0, 1); - else if (state.left_alt && down && sc == SC_X1_LEFT) /* XXX */ - console_switch (0, -1); - else if (state.left_alt && down && sc == SC_X1_UP) /* XXX */ - console_scrollback (CONS_SCROLL_DELTA_LINES, 1); - else if (state.left_alt && down && sc == SC_X1_DOWN) /* XXX */ - console_scrollback (CONS_SCROLL_DELTA_LINES, -1); - else if (state.right_shift && down && sc == SC_X1_PGUP) /* XXX */ - console_scrollback (CONS_SCROLL_DELTA_SCREENS, 0.5); - else if (state.right_shift && down && sc == SC_X1_PGDN) /* XXX */ - console_scrollback (CONS_SCROLL_DELTA_SCREENS, -0.5); - else if (down && sc < sizeof (sc_x1_to_kc)/sizeof (sc_x1_to_kc[0])) + } + else if (state.right_alt && down && sc == SC_X1_PAD_SLASH) /* XXX */ + state.direct = (state.direct << 4) | 0xb; + else if (state.right_alt && down && sc == SC_X1_PAD_ENTER) /* XXX */ + state.direct = (state.direct << 4) | 0xf; + else if (state.left_alt && down && sc == SC_X1_RIGHT) /* XXX */ + console_switch (0, 1); + else if (state.left_alt && down && sc == SC_X1_LEFT) /* XXX */ + console_switch (0, -1); + else if (state.left_alt && down && sc == SC_X1_UP) /* XXX */ + console_scrollback (CONS_SCROLL_DELTA_LINES, 1); + else if (state.left_alt && down && sc == SC_X1_DOWN) /* XXX */ + console_scrollback (CONS_SCROLL_DELTA_LINES, -1); + else if (state.right_shift && down && sc == SC_X1_PGUP) /* XXX */ + console_scrollback (CONS_SCROLL_DELTA_SCREENS, 0.5); + else if (state.right_shift && down && sc == SC_X1_PGDN) /* XXX */ + console_scrollback (CONS_SCROLL_DELTA_SCREENS, -0.5); + else if (down && sc < sizeof (sc_x1_to_kc)/sizeof (sc_x1_to_kc[0])) + { + if (modifier >= 0 && sc_x1_to_kc[sc][modifier]) { - if (modifier >= 0 && sc_x1_to_kc[sc][modifier]) - { - assert (size < 101 - strlen(sc_x1_to_kc[sc][modifier])); - strcpy (&buf[size], sc_x1_to_kc[sc][modifier]); - size += strlen (sc_x1_to_kc[sc][modifier]); - } + assert (size < 101 - strlen(sc_x1_to_kc[sc][modifier])); + strcpy (&buf[size], sc_x1_to_kc[sc][modifier]); + size += strlen (sc_x1_to_kc[sc][modifier]); } } - else if (state.extended == 2) - state.extended = 3; - else if (state.extended == 3) - state.extended = 0; - - if (size) - console_input (buf, size); } + else if (state.extended == 2) + state.extended = 3; + else if (state.extended == 3) + state.extended = 0; + + if (size) + console_input (buf, size); } return 0; } @@ -742,7 +1029,6 @@ pc_kbd_start (void *handle) { error_t err; device_t device_master; - int data[1]; cd = iconv_open ("UTF-8", "WCHAR_T"); if (cd == (iconv_t) -1) @@ -755,7 +1041,14 @@ pc_kbd_start (void *handle) return err; } - err = device_open (device_master, D_READ, "kbd", &kbd_dev); + err = device_open (device_master, D_READ | D_WRITE, "@>=kbd", &kbd_dev); + if (err == D_NO_SUCH_DEVICE) + { + /* GNU Mach v1 has a different device. */ + gnumach_v1_compat = 1; + err = device_open (device_master, D_READ, "kbd", &kbd_dev); + } + mach_port_deallocate (mach_task_self (), device_master); if (err) { @@ -763,20 +1056,28 @@ pc_kbd_start (void *handle) return err; } - data[0] = KB_EVENT; - err = device_set_status (kbd_dev, KDSKBDMODE, data, 1); - if (err) + if (gnumach_v1_compat) { - device_close (kbd_dev); - mach_port_deallocate (mach_task_self (), kbd_dev); - iconv_close (cd); - return err; + int data = KB_EVENT; + err = device_set_status (kbd_dev, KDSKBDMODE, &data, 1); + if (err) + { + device_close (kbd_dev); + mach_port_deallocate (mach_task_self (), kbd_dev); + iconv_close (cd); + return err; + } } + update_leds (); err = driver_add_input (&pc_kbd_ops, NULL); if (err) { - device_set_status (kbd_dev, KDSKBDMODE, data, 1); + if (gnumach_v1_compat) + { + int data = KB_ASCII; + device_set_status (kbd_dev, KDSKBDMODE, &data, 1); + } device_close (kbd_dev); mach_port_deallocate (mach_task_self (), kbd_dev); iconv_close (cd); @@ -791,11 +1092,12 @@ pc_kbd_start (void *handle) static error_t pc_kbd_fini (void *handle, int force) { - int data[1]; - driver_remove_input (&pc_kbd_ops, NULL); - data[0] = KB_ASCII; - device_set_status (kbd_dev, KDSKBDMODE, data, 1); + if (gnumach_v1_compat) + { + int data = KB_ASCII; + device_set_status (kbd_dev, KDSKBDMODE, &data, 1); + } device_close (kbd_dev); mach_port_deallocate (mach_task_self (), kbd_dev); iconv_close (cd); @@ -808,7 +1110,8 @@ pc_kbd_fini (void *handle, int force) static error_t pc_kbd_set_scroll_lock_status (void *handle, int onoff) { - /* XXX */ + led_state.scroll_lock = onoff; + update_leds (); return 0; } |