diff --git a/kernel-src/arch/x86-64/ps2.c b/kernel-src/arch/x86-64/ps2.c index 62ccbded..1c605279 100644 --- a/kernel-src/arch/x86-64/ps2.c +++ b/kernel-src/arch/x86-64/ps2.c @@ -277,4 +277,4 @@ void arch_ps2_init() { ps2_write_data(control); } -INIT_ROUTINE_DEFINE(ps2, INIT_ROUTINE_FLAGS_NONE, arch_ps2_init, acpi, keyboard); +INIT_ROUTINE_DEFINE(ps2, INIT_ROUTINE_FLAGS_NONE, arch_ps2_init, acpi, input); diff --git a/kernel-src/arch/x86-64/ps2kbd.c b/kernel-src/arch/x86-64/ps2kbd.c index f6b0c133..ed2090bd 100644 --- a/kernel-src/arch/x86-64/ps2kbd.c +++ b/kernel-src/arch/x86-64/ps2kbd.c @@ -1,123 +1,124 @@ -#include -#include -#include -#include -#include #include -#include +#include +#include #include +#include +#include +#include #include +#include -static char codes[128] = { - KEYCODE_RESERVED, - KEYCODE_ESCAPE, - KEYCODE_1, - KEYCODE_2, - KEYCODE_3, - KEYCODE_4, - KEYCODE_5, - KEYCODE_6, - KEYCODE_7, - KEYCODE_8, - KEYCODE_9, - KEYCODE_0, - KEYCODE_MINUS, - KEYCODE_EQUAL, - KEYCODE_BACKSPACE, - KEYCODE_TAB, - KEYCODE_Q, - KEYCODE_W, - KEYCODE_E, - KEYCODE_R, - KEYCODE_T, - KEYCODE_Y, - KEYCODE_U, - KEYCODE_I, - KEYCODE_O, - KEYCODE_P, - KEYCODE_LEFTBRACE, - KEYCODE_RIGHTBRACE, - KEYCODE_ENTER, - KEYCODE_LEFTCTRL, - KEYCODE_A, - KEYCODE_S, - KEYCODE_D, - KEYCODE_F, - KEYCODE_G, - KEYCODE_H, - KEYCODE_J, - KEYCODE_K, - KEYCODE_L, - KEYCODE_SEMICOLON, - KEYCODE_APOSTROPHE, - KEYCODE_GRAVE, - KEYCODE_LEFTSHIFT, - KEYCODE_BACKSLASH, - KEYCODE_Z, - KEYCODE_X, - KEYCODE_C, - KEYCODE_V, - KEYCODE_B, - KEYCODE_N, - KEYCODE_M, - KEYCODE_COMMA, - KEYCODE_DOT, - KEYCODE_SLASH, - KEYCODE_RIGHTSHIFT, - KEYCODE_KEYPADASTERISK, - KEYCODE_LEFTALT, - KEYCODE_SPACE, - KEYCODE_CAPSLOCK, - KEYCODE_F1, - KEYCODE_F2, - KEYCODE_F3, - KEYCODE_F4, - KEYCODE_F5, - KEYCODE_F6, - KEYCODE_F7, - KEYCODE_F8, - KEYCODE_F9, - KEYCODE_F10, - KEYCODE_NUMLOCK, - KEYCODE_SCROLLLOCK, - KEYCODE_KEYPAD7, - KEYCODE_KEYPAD8, - KEYCODE_KEYPAD9, - KEYCODE_KEYPADMINUS, - KEYCODE_KEYPAD4, - KEYCODE_KEYPAD5, - KEYCODE_KEYPAD6, - KEYCODE_KEYPADPLUS, - KEYCODE_KEYPAD1, - KEYCODE_KEYPAD2, - KEYCODE_KEYPAD3, - KEYCODE_KEYPAD0, - KEYCODE_KEYPADDOT, +static uint8_t codes[128] = { + INPUT_KEY_RESERVED, + INPUT_KEY_ESC, + INPUT_KEY_1, + INPUT_KEY_2, + INPUT_KEY_3, + INPUT_KEY_4, + INPUT_KEY_5, + INPUT_KEY_6, + INPUT_KEY_7, + INPUT_KEY_8, + INPUT_KEY_9, + INPUT_KEY_0, + INPUT_KEY_MINUS, + INPUT_KEY_EQUAL, + INPUT_KEY_BACKSPACE, + INPUT_KEY_TAB, + INPUT_KEY_Q, + INPUT_KEY_W, + INPUT_KEY_E, + INPUT_KEY_R, + INPUT_KEY_T, + INPUT_KEY_Y, + INPUT_KEY_U, + INPUT_KEY_I, + INPUT_KEY_O, + INPUT_KEY_P, + INPUT_KEY_LEFTBRACE, + INPUT_KEY_RIGHTBRACE, + INPUT_KEY_ENTER, + INPUT_KEY_LEFTCTRL, + INPUT_KEY_A, + INPUT_KEY_S, + INPUT_KEY_D, + INPUT_KEY_F, + INPUT_KEY_G, + INPUT_KEY_H, + INPUT_KEY_J, + INPUT_KEY_K, + INPUT_KEY_L, + INPUT_KEY_SEMICOLON, + INPUT_KEY_APOSTROPHE, + INPUT_KEY_GRAVE, + INPUT_KEY_LEFTSHIFT, + INPUT_KEY_BACKSLASH, + INPUT_KEY_Z, + INPUT_KEY_X, + INPUT_KEY_C, + INPUT_KEY_V, + INPUT_KEY_B, + INPUT_KEY_N, + INPUT_KEY_M, + INPUT_KEY_COMMA, + INPUT_KEY_DOT, + INPUT_KEY_SLASH, + INPUT_KEY_RIGHTSHIFT, + INPUT_KEY_KPASTERISK, + INPUT_KEY_LEFTALT, + INPUT_KEY_SPACE, + INPUT_KEY_CAPSLOCK, + INPUT_KEY_F1, + INPUT_KEY_F2, + INPUT_KEY_F3, + INPUT_KEY_F4, + INPUT_KEY_F5, + INPUT_KEY_F6, + INPUT_KEY_F7, + INPUT_KEY_F8, + INPUT_KEY_F9, + INPUT_KEY_F10, + INPUT_KEY_NUMLOCK, + INPUT_KEY_SCROLLLOCK, + INPUT_KEY_KP7, + INPUT_KEY_KP8, + INPUT_KEY_KP9, + INPUT_KEY_KPMINUS, + INPUT_KEY_KP4, + INPUT_KEY_KP5, + INPUT_KEY_KP6, + INPUT_KEY_KPPLUS, + INPUT_KEY_KP1, + INPUT_KEY_KP2, + INPUT_KEY_KP3, + INPUT_KEY_KP0, + INPUT_KEY_KPDOT, 0, 0, 0, - KEYCODE_F11, - KEYCODE_F12 + INPUT_KEY_F11, + INPUT_KEY_F12 }; -static char extendedcodes[128] = { - [0x1C] = KEYCODE_KEYPADENTER, - [0x1D] = KEYCODE_RIGHTCTRL, - [0x35] = KEYCODE_KEYPADSLASH, // k/ - [0x38] = KEYCODE_RIGHTALT, // altgr - [0x47] = KEYCODE_HOME, // home - [0x48] = KEYCODE_UP, // up - [0x49] = KEYCODE_PAGEUP, // page up - [0x4B] = KEYCODE_LEFT, // left - [0x4D] = KEYCODE_RIGHT, // right - [0x4F] = KEYCODE_END, // end - [0x50] = KEYCODE_DOWN, // down - [0x51] = KEYCODE_PAGEDOWN, // page down - [0x52] = KEYCODE_INSERT, // insert - [0x53] = KEYCODE_DELETE // delete +static uint8_t extendedcodes[128] = { + [0x1C] = INPUT_KEY_KPENTER, + [0x1D] = INPUT_KEY_RIGHTCTRL, + [0x35] = INPUT_KEY_KPSLASH, // k/ + [0x38] = INPUT_KEY_RIGHTALT, // altgr + [0x47] = INPUT_KEY_HOME, // home + [0x48] = INPUT_KEY_UP, // up + [0x49] = INPUT_KEY_PAGEUP, // page up + [0x4B] = INPUT_KEY_LEFT, // left + [0x4D] = INPUT_KEY_RIGHT, // right + [0x4F] = INPUT_KEY_END, // end + [0x50] = INPUT_KEY_DOWN, // down + [0x51] = INPUT_KEY_PAGEDOWN, // page down + [0x52] = INPUT_KEY_INSERT, // insert + [0x53] = INPUT_KEY_DELETE // delete }; #define KEYBOARDIRQ 1 -keyboard_t *kb; +static input_device_t *input_dev; + static bool extended = false; static void kbdisr(isr_t *isr, context_t *ctx) { @@ -127,35 +128,46 @@ static void kbdisr(isr_t *isr, context_t *ctx) { return; } - kbpacket_t packet; - - packet.flags = 0; - - if (scancode & 0x80) { - packet.flags = KBPACKET_FLAGS_RELEASED; - scancode &= 0x7F; - } - - char *tab = codes; - + uint8_t *table = codes; if (extended) { - tab = extendedcodes; + table = extendedcodes; extended = false; } - packet.keycode = tab[scancode]; + bool released = (scancode & 0x80) != 0; + scancode &= 0x7f; - if (!packet.keycode) + input_event_t event; + event.type = INPUT_EV_KEY; + event.code = table[scancode]; + if (event.code == INPUT_KEY_RESERVED) return; - keyboard_sendpacket(kb, &packet); + event.value = released ? 0 : 1; + input_queue_packet(input_dev, &event, 1); } void ps2kbd_init() { - isr_t *isr = interrupt_allocate(kbdisr, arch_apic_eoi, IPL_KEYBOARD); + isr_t *isr = interrupt_allocate(kbdisr, arch_apic_eoi, IPL_INPUT); __assert(isr); arch_ioapic_setirq(KEYBOARDIRQ, isr->id & 0xff, current_cpu_id(), false); - kb = keyboard_new(); - __assert(kb); + + input_dev = input_new(); + __assert(input_dev); + input_dev->id_bus = INPUT_DEVICE_BUS_I8042; + snprintf(input_dev->name, sizeof(input_dev->name), "PS/2 Keyboard"); + input_dev->id_version = 1; + input_dev->ver_major = 1; + input_dev->ver_minor = 0; + input_dev->ver_patch = 0; + + bitmap_set(&input_dev->ev_bits, INPUT_EV_KEY, 1); + for (int i = 0; i < 128; ++i) { + if (codes[i] != INPUT_KEY_RESERVED) + bitmap_set(&input_dev->key_bits, codes[i], 1); + if (extendedcodes[i] != INPUT_KEY_RESERVED) + bitmap_set(&input_dev->key_bits, extendedcodes[i], 1); + } + printf("ps2kbd: irq enabled with vector %u\n", isr->id & 0xff); } diff --git a/kernel-src/arch/x86-64/ps2mouse.c b/kernel-src/arch/x86-64/ps2mouse.c index 17777ba4..57b34394 100644 --- a/kernel-src/arch/x86-64/ps2mouse.c +++ b/kernel-src/arch/x86-64/ps2mouse.c @@ -1,6 +1,6 @@ #include #include -#include +#include #define PS2_MOUSE_CMD_SAMPLERATE 0xF3 @@ -21,7 +21,7 @@ static void ps2_mouse_setrate(int port, uint8_t rate) { } } -static int datac; +static int datac; static uint8_t data[4]; @@ -32,7 +32,13 @@ static inline bool enoughdata() { return true; } -static mouse_t *mouse; +static input_device_t *input_dev; + +static bool last_left = false; +static bool last_right = false; +static bool last_middle = false; +static bool last_side = false; +static bool last_extra = false; static void mouseisr() { data[datac] = inb(PS2_PORT_DATA); @@ -48,25 +54,67 @@ static void mouseisr() { if (!enoughdata()) return; - mousepacket_t packet = {0}; - datac = 0; - bool left = data[0] & 1; - bool right = data[0] & 2; - bool middle = data[0] & 4; - bool b4 = data[3] & 0x10; - bool b5 = data[3] & 0x20; - packet.x = data[1] - (data[0] & 0x10 ? 0x100 : 0); - packet.y = data[2] - (data[0] & 0x20 ? 0x100 : 0); - packet.z = (data[3] & 0x7) * (data[3] & 0x8 ? -1 : 1); + int x = data[1] - (data[0] & 0x10 ? 0x100 : 0); + int y = data[2] - (data[0] & 0x20 ? 0x100 : 0); + int z = 0; - packet.flags |= left ? MOUSE_FLAG_LB : 0; - packet.flags |= middle ? MOUSE_FLAG_MB : 0; - packet.flags |= right ? MOUSE_FLAG_RB : 0; - packet.flags |= b4 ? MOUSE_FLAG_B4 : 0; - packet.flags |= b5 ? MOUSE_FLAG_B5 : 0; - mouse_packet(mouse, &packet); + if (haswheel) { + if (fivebuttons) + z = (data[3] & 0x7) * (data[3] & 0x8 ? -1 : 1); + else + z = (int8_t)data[3]; + } + + bool left = (data[0] & 1) != 0; + bool right = (data[0] & 2) != 0; + bool middle = (data[0] & 4) != 0; + bool side = false, extra = false; + + if (fivebuttons) { + side = (data[3] & 16) != 0; + extra = (data[3] & 32) != 0; + } + + input_event_t events[8]; + int eventcount = 0; + +#define EMIT_EVENT(TYPE, CODE, VALUE) \ + do { \ + events[eventcount].type = (TYPE); \ + events[eventcount].code = (CODE); \ + events[eventcount].value = (VALUE); \ + eventcount++; \ + } while (0) + + if (x != 0) + EMIT_EVENT(INPUT_EV_REL, INPUT_REL_X, x); + if (y != 0) + EMIT_EVENT(INPUT_EV_REL, INPUT_REL_Y, -y); + if (z != 0) + EMIT_EVENT(INPUT_EV_REL, INPUT_REL_WHEEL, z); + + if (left != last_left) + EMIT_EVENT(INPUT_EV_KEY, INPUT_KEY_BTN_LEFT, left ? 1 : 0); + if (right != last_right) + EMIT_EVENT(INPUT_EV_KEY, INPUT_KEY_BTN_RIGHT, right ? 1 : 0); + if (middle != last_middle) + EMIT_EVENT(INPUT_EV_KEY, INPUT_KEY_BTN_MIDDLE, middle ? 1 : 0); + if (side != last_side) + EMIT_EVENT(INPUT_EV_KEY, INPUT_KEY_BTN_SIDE, side ? 1 : 0); + if (extra != last_extra) + EMIT_EVENT(INPUT_EV_KEY, INPUT_KEY_BTN_EXTRA, extra ? 1 : 0); + + last_left = left; + last_right = right; + last_middle = middle; + last_side = side; + last_extra = extra; + +#undef EMIT_EVENT + + input_queue_packet(input_dev, events, eventcount); } #define DO_IDENTIFY_CHECK(step) \ @@ -92,7 +140,7 @@ void ps2mouse_init() { ps2_mouse_setrate(2, 80); DO_IDENTIFY_CHECK("has scroll"); - + if (identity[0] == PS2_MOUSE_Z) { haswheel = true; @@ -109,11 +157,36 @@ void ps2mouse_init() { ps2_mouse_setrate(2, 60); - isr_t *isr = interrupt_allocate(mouseisr, arch_apic_eoi, IPL_MOUSE); + isr_t *isr = interrupt_allocate(mouseisr, arch_apic_eoi, IPL_INPUT); __assert(isr); arch_ioapic_setirq(PS2_MOUSEIRQ, isr->id & 0xff, current_cpu_id(), false); - mouse = mouse_new(); - __assert(mouse); + + input_dev = input_new(); + __assert(input_dev); + input_dev->id_bus = INPUT_DEVICE_BUS_I8042; + snprintf(input_dev->name, sizeof(input_dev->name), "PS/2 Mouse"); + input_dev->id_version = 1; + input_dev->ver_major = 1; + input_dev->ver_minor = 0; + input_dev->ver_patch = 0; + + bitmap_set(&input_dev->ev_bits, INPUT_EV_KEY, 1); + bitmap_set(&input_dev->key_bits, INPUT_KEY_BTN_LEFT, 1); + bitmap_set(&input_dev->key_bits, INPUT_KEY_BTN_RIGHT, 1); + bitmap_set(&input_dev->key_bits, INPUT_KEY_BTN_MIDDLE, 1); + + if (fivebuttons) { + bitmap_set(&input_dev->key_bits, INPUT_KEY_BTN_SIDE, 1); + bitmap_set(&input_dev->key_bits, INPUT_KEY_BTN_EXTRA, 1); + } + + bitmap_set(&input_dev->ev_bits, INPUT_EV_REL, 1); + bitmap_set(&input_dev->rel_bits, INPUT_REL_X, 1); + bitmap_set(&input_dev->rel_bits, INPUT_REL_Y, 1); + + if (haswheel) + bitmap_set(&input_dev->rel_bits, INPUT_REL_WHEEL, 1); + printf("ps2mouse: irq enabled with vector %u\n", isr->id & 0xff); printf("ps2mouse: wheel: %d five buttons: %d\n", haswheel, fivebuttons); }