keyboard.c (4245B)
1 #include "keyboard.h" 2 #include <stdint.h> 3 4 /* External terminal function */ 5 extern void terminal_writestring(const char* str); 6 extern void terminal_writechar(char c); 7 8 /* External function to call Lua callback */ 9 extern void keyboard_input_callback(const char* key, uint8_t scancode); 10 11 /* Keyboard state */ 12 keyboard_state_t keyboard_state = {0}; 13 14 /* US QWERTY keyboard scancode to ASCII mapping */ 15 static const char scancode_to_ascii[128] = { 16 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', 17 '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 18 0, /* Ctrl */ 19 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 20 0, /* Left shift */ 21 '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 22 0, /* Right shift */ 23 '*', 24 0, /* Alt */ 25 ' ', /* Space */ 26 0, /* Caps lock */ 27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F1-F10 */ 28 0, /* Num lock */ 29 0, /* Scroll lock */ 30 0, /* Home */ 31 0, /* Up arrow */ 32 0, /* Page up */ 33 '-', 34 0, /* Left arrow */ 35 0, 36 0, /* Right arrow */ 37 '+', 38 0, /* End */ 39 0, /* Down arrow */ 40 0, /* Page down */ 41 0, /* Insert */ 42 0, /* Delete */ 43 0, 0, 0, 44 0, 0, /* F11, F12 */ 45 0, /* All other keys undefined */ 46 }; 47 48 /* Shifted characters */ 49 static const char scancode_to_ascii_shift[128] = { 50 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', 51 '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 52 0, /* Ctrl */ 53 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 54 0, /* Left shift */ 55 '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 56 0, /* Right shift */ 57 '*', 58 0, /* Alt */ 59 ' ', /* Space */ 60 }; 61 62 /* Scancode definitions */ 63 #define SC_LSHIFT_PRESS 0x2A 64 #define SC_LSHIFT_RELEASE 0xAA 65 #define SC_RSHIFT_PRESS 0x36 66 #define SC_RSHIFT_RELEASE 0xB6 67 #define SC_CTRL_PRESS 0x1D 68 #define SC_CTRL_RELEASE 0x9D 69 #define SC_ALT_PRESS 0x38 70 #define SC_ALT_RELEASE 0xB8 71 #define SC_CAPS_PRESS 0x3A 72 #define SC_LMETA_PRESS 0x5B /* Left Windows/Meta key */ 73 #define SC_LMETA_RELEASE 0xDB 74 #define SC_RMETA_PRESS 0x5C /* Right Windows/Meta key */ 75 #define SC_RMETA_RELEASE 0xDC 76 77 /* Helper: Read from port */ 78 static inline uint8_t inb(uint16_t port) { 79 uint8_t ret; 80 __asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); 81 return ret; 82 } 83 84 /* Initialize keyboard */ 85 void keyboard_init(void) { 86 keyboard_state.shift_pressed = 0; 87 keyboard_state.ctrl_pressed = 0; 88 keyboard_state.alt_pressed = 0; 89 keyboard_state.caps_lock = 0; 90 keyboard_state.initialized = 1; 91 92 terminal_writestring("Keyboard initialized!\n"); 93 } 94 95 /* Keyboard interrupt handler */ 96 void keyboard_handler(void) { 97 uint8_t scancode = inb(KB_DATA_PORT); 98 99 /* Handle modifier keys (update state but don't return - send to Lua) */ 100 if (scancode == SC_LSHIFT_PRESS || scancode == SC_RSHIFT_PRESS) { 101 keyboard_state.shift_pressed = 1; 102 } 103 if (scancode == SC_LSHIFT_RELEASE || scancode == SC_RSHIFT_RELEASE) { 104 keyboard_state.shift_pressed = 0; 105 } 106 if (scancode == SC_CTRL_PRESS) { 107 keyboard_state.ctrl_pressed = 1; 108 } 109 if (scancode == SC_CTRL_RELEASE) { 110 keyboard_state.ctrl_pressed = 0; 111 } 112 if (scancode == SC_ALT_PRESS) { 113 keyboard_state.alt_pressed = 1; 114 } 115 if (scancode == SC_ALT_RELEASE) { 116 keyboard_state.alt_pressed = 0; 117 } 118 if (scancode == SC_CAPS_PRESS) { 119 keyboard_state.caps_lock = !keyboard_state.caps_lock; 120 } 121 122 /* Convert scancode to ASCII */ 123 char ascii = 0; 124 if (keyboard_state.shift_pressed) { 125 ascii = scancode_to_ascii_shift[scancode]; 126 } else { 127 ascii = scancode_to_ascii[scancode]; 128 /* Handle caps lock for letters */ 129 if (keyboard_state.caps_lock && ascii >= 'a' && ascii <= 'z') { 130 ascii = ascii - 'a' + 'A'; 131 } 132 } 133 134 /* Send ALL key events to Lua (including modifiers and releases) */ 135 /* For keys without ASCII, send empty string */ 136 char key_str[2] = {ascii, '\0'}; 137 keyboard_input_callback(key_str, scancode); 138 } 139 140 /* Get keyboard state */ 141 keyboard_state_t keyboard_get_state(void) { 142 return keyboard_state; 143 }