Compare commits
5 Commits
f8cb6e03df
...
3aaf1c5d84
Author | SHA1 | Date | |
---|---|---|---|
3aaf1c5d84 | |||
4794d0dfef | |||
9c1e275f34 | |||
6593f9241b | |||
df4227eab8 |
@ -44,4 +44,4 @@ luna_app(gol.cpp gol)
|
|||||||
luna_app(buffer-test.cpp buffer-test)
|
luna_app(buffer-test.cpp buffer-test)
|
||||||
luna_app(socket-test.cpp socket-test)
|
luna_app(socket-test.cpp socket-test)
|
||||||
luna_app(socket-client.cpp socket-client)
|
luna_app(socket-client.cpp socket-client)
|
||||||
luna_app(mouse.cpp mouse)
|
luna_app(input.cpp input)
|
||||||
|
69
apps/input.cpp
Normal file
69
apps/input.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <luna/String.h>
|
||||||
|
#include <moon/Keyboard.h>
|
||||||
|
#include <moon/Mouse.h>
|
||||||
|
#include <os/File.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
Result<void> process_mouse_packet(const moon::MousePacket& packet)
|
||||||
|
{
|
||||||
|
bool right = packet.buttons & moon::MouseButton::Right;
|
||||||
|
bool left = packet.buttons & moon::MouseButton::Left;
|
||||||
|
bool middle = packet.buttons & moon::MouseButton::Middle;
|
||||||
|
|
||||||
|
Vector<StringView> buttons;
|
||||||
|
if (right) TRY(buttons.try_append("RIGHT"_sv));
|
||||||
|
if (left) TRY(buttons.try_append("LEFT"_sv));
|
||||||
|
if (middle) TRY(buttons.try_append("MIDDLE"_sv));
|
||||||
|
|
||||||
|
String button_string;
|
||||||
|
if (!buttons.size()) button_string = TRY(String::from_cstring("NONE"));
|
||||||
|
else
|
||||||
|
button_string = TRY(String::join(buttons, " | "_sv));
|
||||||
|
|
||||||
|
os::println("Mouse packet: xdelta=%d, ydelta=%d, buttons=(%s)", packet.xdelta, packet.ydelta,
|
||||||
|
button_string.chars());
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<int> luna_main(int, char**)
|
||||||
|
{
|
||||||
|
auto mouse = TRY(os::File::open("/dev/mouse", os::File::ReadOnly));
|
||||||
|
mouse->set_buffer(os::File::NotBuffered);
|
||||||
|
|
||||||
|
auto keyboard = TRY(os::File::open("/dev/kbd", os::File::ReadOnly));
|
||||||
|
keyboard->set_buffer(os::File::NotBuffered);
|
||||||
|
|
||||||
|
ioctl(STDIN_FILENO, TTYSETGFX, 1);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
struct pollfd fds[] = {
|
||||||
|
{ .fd = mouse->fd(), .events = POLLIN, .revents = 0 },
|
||||||
|
{ .fd = keyboard->fd(), .events = POLLIN, .revents = 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
int rc = poll(fds, 2, 1000);
|
||||||
|
if (!rc) continue;
|
||||||
|
if (rc < 0) { os::println("poll: error: %s", strerror(errno)); }
|
||||||
|
|
||||||
|
if (fds[0].revents & POLLIN)
|
||||||
|
{
|
||||||
|
moon::MousePacket packet;
|
||||||
|
TRY(mouse->read_typed(packet));
|
||||||
|
TRY(process_mouse_packet(packet));
|
||||||
|
}
|
||||||
|
if (fds[1].revents & POLLIN)
|
||||||
|
{
|
||||||
|
moon::KeyboardPacket packet;
|
||||||
|
TRY(keyboard->read_typed(packet));
|
||||||
|
os::println("Keyboard packet: %s key %u", packet.released ? "released" : "pressed", packet.key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -1,32 +0,0 @@
|
|||||||
#include <luna/String.h>
|
|
||||||
#include <moon/Mouse.h>
|
|
||||||
#include <os/File.h>
|
|
||||||
|
|
||||||
Result<int> luna_main(int, char**)
|
|
||||||
{
|
|
||||||
auto mouse = TRY(os::File::open("/dev/mouse", os::File::ReadOnly));
|
|
||||||
mouse->set_buffer(os::File::NotBuffered);
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
moon::MousePacket packet;
|
|
||||||
TRY(mouse->read_typed(packet));
|
|
||||||
|
|
||||||
bool right = packet.buttons & moon::MouseButton::Right;
|
|
||||||
bool left = packet.buttons & moon::MouseButton::Left;
|
|
||||||
bool middle = packet.buttons & moon::MouseButton::Middle;
|
|
||||||
|
|
||||||
Vector<StringView> buttons;
|
|
||||||
if (right) TRY(buttons.try_append("RIGHT"_sv));
|
|
||||||
if (left) TRY(buttons.try_append("LEFT"_sv));
|
|
||||||
if (middle) TRY(buttons.try_append("MIDDLE"_sv));
|
|
||||||
|
|
||||||
String button_string;
|
|
||||||
if (!buttons.size()) button_string = TRY(String::from_cstring("NONE"));
|
|
||||||
else
|
|
||||||
button_string = TRY(String::join(buttons, " | "_sv));
|
|
||||||
|
|
||||||
os::println("Mouse packet: xdelta=%d, ydelta=%d, buttons=(%s)", packet.xdelta, packet.ydelta,
|
|
||||||
button_string.chars());
|
|
||||||
}
|
|
||||||
}
|
|
@ -61,6 +61,7 @@ set(SOURCES
|
|||||||
src/fs/devices/FramebufferDevice.cpp
|
src/fs/devices/FramebufferDevice.cpp
|
||||||
src/fs/devices/UARTDevice.cpp
|
src/fs/devices/UARTDevice.cpp
|
||||||
src/fs/devices/MouseDevice.cpp
|
src/fs/devices/MouseDevice.cpp
|
||||||
|
src/fs/devices/KeyboardDevice.cpp
|
||||||
src/fs/InitRD.cpp
|
src/fs/InitRD.cpp
|
||||||
src/binfmt/ELF.cpp
|
src/binfmt/ELF.cpp
|
||||||
src/binfmt/BinaryFormat.cpp
|
src/binfmt/BinaryFormat.cpp
|
||||||
|
131
kernel/src/api/Keyboard.h
Normal file
131
kernel/src/api/Keyboard.h
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <luna/Types.h>
|
||||||
|
|
||||||
|
namespace moon
|
||||||
|
{
|
||||||
|
enum KeyCode : u8
|
||||||
|
{
|
||||||
|
// Function keys
|
||||||
|
K_F1,
|
||||||
|
K_F2,
|
||||||
|
K_F3,
|
||||||
|
K_F4,
|
||||||
|
K_F5,
|
||||||
|
K_F6,
|
||||||
|
K_F7,
|
||||||
|
K_F8,
|
||||||
|
K_F9,
|
||||||
|
K_F10,
|
||||||
|
K_F11,
|
||||||
|
K_F12,
|
||||||
|
// System keys
|
||||||
|
K_Esc,
|
||||||
|
K_PrtScr,
|
||||||
|
K_Pause,
|
||||||
|
K_Super,
|
||||||
|
K_Menu,
|
||||||
|
// Modifier keys
|
||||||
|
K_LeftShift,
|
||||||
|
K_RightShift,
|
||||||
|
K_LeftAlt,
|
||||||
|
K_RightAlt, // or AltGr on some keyboards
|
||||||
|
K_LeftControl,
|
||||||
|
K_RightControl,
|
||||||
|
// Navigation keys
|
||||||
|
K_Tab,
|
||||||
|
K_Home,
|
||||||
|
K_End,
|
||||||
|
K_PageUp,
|
||||||
|
K_PageDown,
|
||||||
|
K_RightArrow,
|
||||||
|
K_LeftArrow,
|
||||||
|
K_UpArrow,
|
||||||
|
K_DownArrow,
|
||||||
|
// Editing keys
|
||||||
|
K_Backspace,
|
||||||
|
K_Enter,
|
||||||
|
K_Insert,
|
||||||
|
K_Delete,
|
||||||
|
K_KeypadEnter,
|
||||||
|
// Lock keys
|
||||||
|
K_ScrollLock,
|
||||||
|
K_CapsLock,
|
||||||
|
K_NumLock,
|
||||||
|
// Keypad keys
|
||||||
|
K_Keypad0,
|
||||||
|
K_Keypad1,
|
||||||
|
K_Keypad2,
|
||||||
|
K_Keypad3,
|
||||||
|
K_Keypad4,
|
||||||
|
K_Keypad5,
|
||||||
|
K_Keypad6,
|
||||||
|
K_Keypad7,
|
||||||
|
K_Keypad8,
|
||||||
|
K_Keypad9,
|
||||||
|
K_KeypadDot,
|
||||||
|
K_KeypadPlus,
|
||||||
|
K_KeypadMinus,
|
||||||
|
K_KeypadMul,
|
||||||
|
K_KeypadDiv,
|
||||||
|
// Character keys (depending on keyboard layout), examples in US QWERTY
|
||||||
|
K_CH00, // `
|
||||||
|
K_CH01, // 1
|
||||||
|
K_CH02, // 2
|
||||||
|
K_CH03, // 3
|
||||||
|
K_CH04, // 4
|
||||||
|
K_CH05, // 5
|
||||||
|
K_CH06, // 6
|
||||||
|
K_CH07, // 7
|
||||||
|
K_CH08, // 8
|
||||||
|
K_CH09, // 9
|
||||||
|
K_CH10, // 0
|
||||||
|
K_CH11, // -
|
||||||
|
K_CH12, // =
|
||||||
|
K_CH13, // Q
|
||||||
|
K_CH14, // W
|
||||||
|
K_CH15, // E
|
||||||
|
K_CH16, // R
|
||||||
|
K_CH17, // T
|
||||||
|
K_CH18, // Y
|
||||||
|
K_CH19, // U
|
||||||
|
K_CH20, // I
|
||||||
|
K_CH21, // O
|
||||||
|
K_CH22, // P
|
||||||
|
K_CH23, // [
|
||||||
|
K_CH24, // ]
|
||||||
|
K_CH25, // A
|
||||||
|
K_CH26, // S
|
||||||
|
K_CH27, // D
|
||||||
|
K_CH28, // F
|
||||||
|
K_CH29, // G
|
||||||
|
K_CH30, // H
|
||||||
|
K_CH31, // J
|
||||||
|
K_CH32, // K
|
||||||
|
K_CH33, // L
|
||||||
|
K_CH34, // ;
|
||||||
|
K_CH35, // '
|
||||||
|
K_CH36, // #
|
||||||
|
K_CH37, // Backslash
|
||||||
|
K_CH38, // Z
|
||||||
|
K_CH39, // X
|
||||||
|
K_CH40, // C
|
||||||
|
K_CH41, // V
|
||||||
|
K_CH42, // B
|
||||||
|
K_CH43, // N
|
||||||
|
K_CH44, // M
|
||||||
|
K_CH45, // ,
|
||||||
|
K_CH46, // .
|
||||||
|
K_CH47, // /
|
||||||
|
K_CH48, // Space
|
||||||
|
// Unknown key
|
||||||
|
K_Unknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct [[gnu::packed]] KeyboardPacket
|
||||||
|
{
|
||||||
|
u8 key;
|
||||||
|
bool released;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(KeyboardPacket) == 2);
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "api/Keyboard.h"
|
||||||
#include <luna/Option.h>
|
#include <luna/Option.h>
|
||||||
|
|
||||||
namespace Keyboard
|
namespace Keyboard
|
||||||
{
|
{
|
||||||
struct KeyboardState
|
struct TTYKeyboardState
|
||||||
{
|
{
|
||||||
bool ignore_next { false };
|
bool ignore_next { false };
|
||||||
bool left_shift { false };
|
bool left_shift { false };
|
||||||
@ -12,5 +13,12 @@ namespace Keyboard
|
|||||||
bool capslock { false };
|
bool capslock { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
Option<char> decode_scancode_tty(u8 scancode, KeyboardState& state);
|
struct KeyboardState
|
||||||
|
{
|
||||||
|
bool ignore_next { false };
|
||||||
|
};
|
||||||
|
|
||||||
|
Option<char> decode_scancode_tty(u8 scancode, TTYKeyboardState& state);
|
||||||
|
|
||||||
|
Option<moon::KeyboardPacket> decode_scancode(u8 scancode, KeyboardState& state);
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,71 @@ constexpr char shifted_key_table[] = {
|
|||||||
'.', // keypad .
|
'.', // keypad .
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool is_shifted(const Keyboard::KeyboardState& state)
|
using namespace moon;
|
||||||
|
|
||||||
|
constexpr KeyCode keycode_table[] = {
|
||||||
|
K_Unknown, K_Esc,
|
||||||
|
K_CH01, // 1
|
||||||
|
K_CH02, // 2
|
||||||
|
K_CH03, // 3
|
||||||
|
K_CH04, // 4
|
||||||
|
K_CH05, // 5
|
||||||
|
K_CH06, // 6
|
||||||
|
K_CH07, // 7
|
||||||
|
K_CH08, // 8
|
||||||
|
K_CH09, // 9
|
||||||
|
K_CH10, // 0
|
||||||
|
K_CH11, // -
|
||||||
|
K_CH12, // =
|
||||||
|
K_Backspace, K_Tab,
|
||||||
|
K_CH13, // Q
|
||||||
|
K_CH14, // W
|
||||||
|
K_CH15, // E
|
||||||
|
K_CH16, // R
|
||||||
|
K_CH17, // T
|
||||||
|
K_CH18, // Y
|
||||||
|
K_CH19, // U
|
||||||
|
K_CH20, // I
|
||||||
|
K_CH21, // O
|
||||||
|
K_CH22, // P
|
||||||
|
K_CH23, // [
|
||||||
|
K_CH24, // ]
|
||||||
|
K_Enter, K_LeftControl,
|
||||||
|
K_CH25, // A
|
||||||
|
K_CH26, // S
|
||||||
|
K_CH27, // D
|
||||||
|
K_CH28, // F
|
||||||
|
K_CH29, // G
|
||||||
|
K_CH30, // H
|
||||||
|
K_CH31, // J
|
||||||
|
K_CH32, // K
|
||||||
|
K_CH33, // L
|
||||||
|
K_CH34, // ;
|
||||||
|
K_CH35, // '
|
||||||
|
K_CH00, // `
|
||||||
|
K_LeftShift,
|
||||||
|
K_CH36, // #
|
||||||
|
K_CH38, // Z
|
||||||
|
K_CH39, // X
|
||||||
|
K_CH40, // C
|
||||||
|
K_CH41, // V
|
||||||
|
K_CH42, // B
|
||||||
|
K_CH43, // N
|
||||||
|
K_CH44, // M
|
||||||
|
K_CH45, // ,
|
||||||
|
K_CH46, // .
|
||||||
|
K_CH47, // /
|
||||||
|
K_RightShift, K_KeypadMul, K_LeftAlt,
|
||||||
|
K_CH48, // Space
|
||||||
|
K_CapsLock, K_F1, K_F2, K_F3, K_F4, K_F5, K_F6,
|
||||||
|
K_F7, K_F8, K_F9, K_F10, K_NumLock, K_ScrollLock, K_Keypad7,
|
||||||
|
K_Keypad8, K_Keypad9, K_KeypadMinus, K_Keypad4, K_Keypad5, K_Keypad6, K_KeypadPlus,
|
||||||
|
K_Keypad1, K_Keypad2, K_Keypad3, K_Keypad0, K_KeypadDot, K_Unknown, K_Unknown,
|
||||||
|
K_CH37, // Backslash
|
||||||
|
K_F11, K_F12,
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool is_shifted(const Keyboard::TTYKeyboardState& state)
|
||||||
{
|
{
|
||||||
if (state.capslock) return !(state.left_shift || state.right_shift);
|
if (state.capslock) return !(state.left_shift || state.right_shift);
|
||||||
return state.left_shift || state.right_shift;
|
return state.left_shift || state.right_shift;
|
||||||
@ -121,7 +185,7 @@ static bool is_shifted(const Keyboard::KeyboardState& state)
|
|||||||
|
|
||||||
namespace Keyboard
|
namespace Keyboard
|
||||||
{
|
{
|
||||||
Option<char> decode_scancode_tty(u8 scancode, KeyboardState& state)
|
Option<char> decode_scancode_tty(u8 scancode, TTYKeyboardState& state)
|
||||||
{
|
{
|
||||||
if (state.ignore_next)
|
if (state.ignore_next)
|
||||||
{
|
{
|
||||||
@ -184,4 +248,24 @@ namespace Keyboard
|
|||||||
if (is_shifted(state)) return shifted_key_table[scancode];
|
if (is_shifted(state)) return shifted_key_table[scancode];
|
||||||
return key_table[scancode];
|
return key_table[scancode];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Option<KeyboardPacket> decode_scancode(u8 scancode, KeyboardState& state)
|
||||||
|
{
|
||||||
|
if (state.ignore_next)
|
||||||
|
{
|
||||||
|
state.ignore_next = false;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Support extended scancodes.
|
||||||
|
if (scancode == EXTENDED_KEY_CODE)
|
||||||
|
{
|
||||||
|
state.ignore_next = true;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool released = is_key_released(scancode);
|
||||||
|
|
||||||
|
return KeyboardPacket { keycode_table[scancode], released };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "fs/devices/ConsoleDevice.h"
|
#include "fs/devices/ConsoleDevice.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "fs/devices/DeviceRegistry.h"
|
#include "fs/devices/DeviceRegistry.h"
|
||||||
|
#include "fs/devices/KeyboardDevice.h"
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
#include "thread/Scheduler.h"
|
#include "thread/Scheduler.h"
|
||||||
#include "video/TextConsole.h"
|
#include "video/TextConsole.h"
|
||||||
@ -61,7 +62,7 @@ Result<usize> ConsoleDevice::write(const u8* buf, usize, usize length)
|
|||||||
{
|
{
|
||||||
if (m_settings.c_lflag & TOSTOP) TRY(handle_background_process_group(true, SIGTTOU));
|
if (m_settings.c_lflag & TOSTOP) TRY(handle_background_process_group(true, SIGTTOU));
|
||||||
|
|
||||||
if (s_is_in_graphical_mode) return length;
|
// if (s_is_in_graphical_mode) return length;
|
||||||
|
|
||||||
TextConsole::write((const char*)buf, length);
|
TextConsole::write((const char*)buf, length);
|
||||||
return length;
|
return length;
|
||||||
@ -74,7 +75,14 @@ bool ConsoleDevice::will_block_if_read() const
|
|||||||
|
|
||||||
void ConsoleDevice::did_press_or_release_key(u8 scancode)
|
void ConsoleDevice::did_press_or_release_key(u8 scancode)
|
||||||
{
|
{
|
||||||
for (const auto& device : m_console_devices) { device->process_key_event(scancode); }
|
if (!s_is_in_graphical_mode)
|
||||||
|
for (const auto& device : m_console_devices) { device->process_key_event(scancode); }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
static Keyboard::KeyboardState state = {};
|
||||||
|
auto packet = Keyboard::decode_scancode(scancode, state);
|
||||||
|
if (packet.has_value()) KeyboardDevice::add_keyboard_event(packet.release_value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConsoleDevice::process_key_event(u8 scancode)
|
void ConsoleDevice::process_key_event(u8 scancode)
|
||||||
|
@ -37,7 +37,7 @@ class ConsoleDevice : public Device
|
|||||||
mutable Buffer m_input_buffer;
|
mutable Buffer m_input_buffer;
|
||||||
Option<pid_t> m_foreground_process_group {};
|
Option<pid_t> m_foreground_process_group {};
|
||||||
Vector<u8> m_line_buffer;
|
Vector<u8> m_line_buffer;
|
||||||
mutable Keyboard::KeyboardState m_kb_state;
|
mutable Keyboard::TTYKeyboardState m_kb_state;
|
||||||
|
|
||||||
static Vector<SharedPtr<ConsoleDevice>> m_console_devices;
|
static Vector<SharedPtr<ConsoleDevice>> m_console_devices;
|
||||||
static bool s_is_in_graphical_mode;
|
static bool s_is_in_graphical_mode;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "fs/devices/ConsoleDevice.h"
|
#include "fs/devices/ConsoleDevice.h"
|
||||||
#include "fs/devices/FramebufferDevice.h"
|
#include "fs/devices/FramebufferDevice.h"
|
||||||
#include "fs/devices/FullDevice.h"
|
#include "fs/devices/FullDevice.h"
|
||||||
|
#include "fs/devices/KeyboardDevice.h"
|
||||||
#include "fs/devices/MouseDevice.h"
|
#include "fs/devices/MouseDevice.h"
|
||||||
#include "fs/devices/NullDevice.h"
|
#include "fs/devices/NullDevice.h"
|
||||||
#include "fs/devices/UARTDevice.h"
|
#include "fs/devices/UARTDevice.h"
|
||||||
@ -72,6 +73,7 @@ namespace DeviceRegistry
|
|||||||
FramebufferDevice::create();
|
FramebufferDevice::create();
|
||||||
UARTDevice::create();
|
UARTDevice::create();
|
||||||
MouseDevice::create();
|
MouseDevice::create();
|
||||||
|
KeyboardDevice::create();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
34
kernel/src/fs/devices/KeyboardDevice.cpp
Normal file
34
kernel/src/fs/devices/KeyboardDevice.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "fs/devices/KeyboardDevice.h"
|
||||||
|
|
||||||
|
SharedPtr<KeyboardDevice> KeyboardDevice::s_keyboard_device = {};
|
||||||
|
|
||||||
|
Result<void> KeyboardDevice::create()
|
||||||
|
{
|
||||||
|
auto device = TRY(make_shared<KeyboardDevice>());
|
||||||
|
s_keyboard_device = device;
|
||||||
|
return DeviceRegistry::register_special_device(DeviceRegistry::Input, 1, device, 0600);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<usize> KeyboardDevice::read(u8* buf, usize, usize length) const
|
||||||
|
{
|
||||||
|
length = m_packet_buffer.dequeue_data(buf, length);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result<usize> KeyboardDevice::write(const u8* buf, usize, usize length)
|
||||||
|
{
|
||||||
|
TRY(m_packet_buffer.append_data(buf, length));
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KeyboardDevice::add_keyboard_event(const moon::KeyboardPacket& packet)
|
||||||
|
{
|
||||||
|
if (s_keyboard_device) s_keyboard_device->write((const u8*)&packet, 0, sizeof(packet));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool KeyboardDevice::will_block_if_read() const
|
||||||
|
{
|
||||||
|
return !m_packet_buffer.size();
|
||||||
|
}
|
31
kernel/src/fs/devices/KeyboardDevice.h
Normal file
31
kernel/src/fs/devices/KeyboardDevice.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "api/Keyboard.h"
|
||||||
|
#include "fs/devices/DeviceRegistry.h"
|
||||||
|
#include <luna/Buffer.h>
|
||||||
|
|
||||||
|
class KeyboardDevice : public Device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Initializer for DeviceRegistry.
|
||||||
|
static Result<void> create();
|
||||||
|
|
||||||
|
Result<usize> read(u8*, usize, usize) const override;
|
||||||
|
|
||||||
|
Result<usize> write(const u8*, usize, usize) override;
|
||||||
|
|
||||||
|
static void add_keyboard_event(const moon::KeyboardPacket& packet);
|
||||||
|
|
||||||
|
bool will_block_if_read() const override;
|
||||||
|
|
||||||
|
StringView device_path() const override
|
||||||
|
{
|
||||||
|
return "kbd";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~KeyboardDevice() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable Buffer m_packet_buffer;
|
||||||
|
|
||||||
|
static SharedPtr<KeyboardDevice> s_keyboard_device;
|
||||||
|
};
|
@ -6,7 +6,7 @@ Result<void> MouseDevice::create()
|
|||||||
{
|
{
|
||||||
auto device = TRY(make_shared<MouseDevice>());
|
auto device = TRY(make_shared<MouseDevice>());
|
||||||
s_mouse_device = device;
|
s_mouse_device = device;
|
||||||
return DeviceRegistry::register_special_device(DeviceRegistry::Input, 0, device);
|
return DeviceRegistry::register_special_device(DeviceRegistry::Input, 0, device, 0600);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<usize> MouseDevice::read(u8* buf, usize, usize length) const
|
Result<usize> MouseDevice::read(u8* buf, usize, usize length) const
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "Log.h"
|
||||||
#include "fs/VFS.h"
|
#include "fs/VFS.h"
|
||||||
#include "memory/MemoryManager.h"
|
#include "memory/MemoryManager.h"
|
||||||
#include "sys/Syscall.h"
|
#include "sys/Syscall.h"
|
||||||
@ -24,6 +25,7 @@ Result<u64> sys_poll(Registers* regs, SyscallArgs args)
|
|||||||
auto maybe_inode = current->resolve_fd(fd);
|
auto maybe_inode = current->resolve_fd(fd);
|
||||||
if (maybe_inode.has_error())
|
if (maybe_inode.has_error())
|
||||||
{
|
{
|
||||||
|
kwarnln("poll: fd %lu (%d) is not valid, storing POLLNVAL", i, fd);
|
||||||
kfds[i].revents |= POLLNVAL;
|
kfds[i].revents |= POLLNVAL;
|
||||||
TRY(inodes.try_append({}));
|
TRY(inodes.try_append({}));
|
||||||
}
|
}
|
||||||
@ -32,7 +34,7 @@ Result<u64> sys_poll(Registers* regs, SyscallArgs args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool infinite = timeout < 0;
|
bool infinite = timeout < 0;
|
||||||
int fds_with_events;
|
nfds_t fds_with_events;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
fds_with_events = 0;
|
fds_with_events = 0;
|
||||||
@ -51,7 +53,7 @@ Result<u64> sys_poll(Registers* regs, SyscallArgs args)
|
|||||||
if (!fds_with_events && (timeout > 0 || infinite))
|
if (!fds_with_events && (timeout > 0 || infinite))
|
||||||
{
|
{
|
||||||
kernel_sleep(10);
|
kernel_sleep(10);
|
||||||
timeout -= (int)current->sleep_ticks_left;
|
timeout -= (10 - (int)current->sleep_ticks_left);
|
||||||
if (current->interrupted)
|
if (current->interrupted)
|
||||||
{
|
{
|
||||||
guard.deactivate();
|
guard.deactivate();
|
||||||
@ -62,7 +64,9 @@ Result<u64> sys_poll(Registers* regs, SyscallArgs args)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} while (false);
|
|
||||||
|
break;
|
||||||
|
} while (1);
|
||||||
|
|
||||||
MemoryManager::copy_to_user(fds, kfds, nfds * sizeof(pollfd));
|
MemoryManager::copy_to_user(fds, kfds, nfds * sizeof(pollfd));
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ set(SOURCES
|
|||||||
src/sys/pstat.cpp
|
src/sys/pstat.cpp
|
||||||
src/sys/resource.cpp
|
src/sys/resource.cpp
|
||||||
src/sys/socket.cpp
|
src/sys/socket.cpp
|
||||||
|
src/sys/poll.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(${LUNA_ARCH} STREQUAL "x86_64")
|
if(${LUNA_ARCH} STREQUAL "x86_64")
|
||||||
|
@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
#include <bits/fixed-size-types.h>
|
#include <bits/fixed-size-types.h>
|
||||||
|
|
||||||
#define POLLIN 0
|
#define POLLIN (1 << 0)
|
||||||
#define POLLERR 1
|
#define POLLERR (1 << 1)
|
||||||
#define POLLNVAL 2
|
#define POLLNVAL (1 << 2)
|
||||||
|
|
||||||
typedef __u64_t nfds_t;
|
typedef __u64_t nfds_t;
|
||||||
|
|
||||||
|
20
libc/include/sys/poll.h
Normal file
20
libc/include/sys/poll.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/* sys/poll.h: Wait for events on multiple file descriptors. */
|
||||||
|
|
||||||
|
#ifndef _SYS_POLL_H
|
||||||
|
#define _SYS_POLL_H
|
||||||
|
|
||||||
|
#include <bits/poll.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wait for events on multiple file descriptors. */
|
||||||
|
int poll(struct pollfd* fds, nfds_t nfds, int timeout);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
13
libc/src/sys/poll.cpp
Normal file
13
libc/src/sys/poll.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include <bits/errno-return.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
int poll(struct pollfd* fds, nfds_t nfds, int timeout)
|
||||||
|
{
|
||||||
|
long rc = syscall(SYS_poll, fds, nfds, timeout);
|
||||||
|
__errno_return(rc, int);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user