luajitos

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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 }