Compare commits

...

6 Commits

Author SHA1 Message Date
Bananymous 61f0043cd8 resolver: Fix infinite debug printing loop, if client disconnects 2024-07-16 15:05:07 +03:00
Bananymous dd7bfba8d5 ports: Compile with multiple jobs and fix curl install query 2024-07-16 15:04:46 +03:00
Bananymous 5b8fdbc82d LibC: Don't expose math.h in stdlib.h 2024-07-16 12:47:38 +03:00
Bananymous 6a1c677cbc Ports: Update doom port gitignore 2024-07-16 11:54:57 +03:00
Bananymous e30952efee Kernel: Implement key repeating for USB keyboard
USB keyboards don't send repeating keys automatically, so it has to be
emulated in software.
2024-07-16 11:54:57 +03:00
Bananymous fd8dc03ae9 BAN: Default initialize optional storage
This removes maybe uninitialized warning when using default initialized
optionals.
2024-07-16 11:19:16 +03:00
10 changed files with 137 additions and 27 deletions

View File

@ -44,7 +44,7 @@ namespace BAN
constexpr void clear(); constexpr void clear();
private: private:
alignas(T) uint8_t m_storage[sizeof(T)]; alignas(T) uint8_t m_storage[sizeof(T)] {};
bool m_has_value { false }; bool m_has_value { false };
}; };

View File

@ -17,6 +17,8 @@ namespace Kernel
void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) override; void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) override;
void handle_array(uint16_t usage_page, uint16_t usage) override; void handle_array(uint16_t usage_page, uint16_t usage) override;
void update() override;
private: private:
USBKeyboard() USBKeyboard()
: USBHIDDevice(InputDevice::Type::Keyboard) : USBHIDDevice(InputDevice::Type::Keyboard)
@ -24,10 +26,17 @@ namespace Kernel
~USBKeyboard() = default; ~USBKeyboard() = default;
private: private:
SpinLock m_keyboard_lock;
InterruptState m_lock_state;
BAN::Array<bool, 0x100> m_keyboard_state { false }; BAN::Array<bool, 0x100> m_keyboard_state { false };
BAN::Array<bool, 0x100> m_keyboard_state_temp { false }; BAN::Array<bool, 0x100> m_keyboard_state_temp { false };
uint8_t m_toggle_mask { 0 }; uint8_t m_toggle_mask { 0 };
BAN::Optional<uint8_t> m_repeat_scancode;
uint8_t m_repeat_modifier { 0 };
uint64_t m_next_repeat_event_ms { 0 };
friend class BAN::RefPtr<USBKeyboard>; friend class BAN::RefPtr<USBKeyboard>;
}; };

View File

@ -1,3 +1,4 @@
#include <kernel/Timer/Timer.h>
#include <kernel/USB/HID/Keyboard.h> #include <kernel/USB/HID/Keyboard.h>
#include <LibInput/KeyEvent.h> #include <LibInput/KeyEvent.h>
@ -6,13 +7,18 @@
namespace Kernel namespace Kernel
{ {
static constexpr uint64_t s_repeat_initial_ms = 500;
static constexpr uint64_t s_repeat_interval_ms = 50;
static BAN::Optional<uint8_t> s_scancode_to_keycode[0x100] {}; static BAN::Optional<uint8_t> s_scancode_to_keycode[0x100] {};
static bool s_scancode_to_keycode_initialized = false; static bool s_scancode_to_keycode_initialized = false;
static void initialize_scancode_to_keycode(); static void initialize_scancode_to_keycode();
static constexpr bool is_repeatable_scancode(uint8_t scancode);
void USBKeyboard::start_report() void USBKeyboard::start_report()
{ {
m_lock_state = m_keyboard_lock.lock();
for (auto& val : m_keyboard_state_temp) for (auto& val : m_keyboard_state_temp)
val = false; val = false;
} }
@ -28,37 +34,39 @@ namespace Kernel
// Modifier should be determined when converting to KeyEvent. // Modifier should be determined when converting to KeyEvent.
uint8_t modifier = 0; uint8_t modifier = 0;
if (m_keyboard_state_temp[0xE1])
modifier |= KeyModifier::LShift;
if (m_keyboard_state_temp[0xE5])
modifier |= KeyModifier::RShift;
if (m_keyboard_state_temp[0xE0])
modifier |= KeyModifier::LCtrl;
if (m_keyboard_state_temp[0xE4])
modifier |= KeyModifier::RCtrl;
if (m_keyboard_state_temp[0xE2])
modifier |= KeyModifier::LAlt;
if (m_keyboard_state_temp[0xE6])
modifier |= KeyModifier::RAlt;
if (m_keyboard_state_temp[0x39] && !m_keyboard_state[0x39]) #define READ_MODIFIER(scancode, key_modifier) \
m_toggle_mask ^= KeyModifier::CapsLock; if (m_keyboard_state_temp[scancode]) \
if (m_keyboard_state_temp[0x47] && !m_keyboard_state[0x47]) modifier |= key_modifier;
m_toggle_mask ^= KeyModifier::ScrollLock; READ_MODIFIER(0xE1, KeyModifier::LShift);
if (m_keyboard_state_temp[0x53] && !m_keyboard_state[0x53]) READ_MODIFIER(0xE5, KeyModifier::RShift);
m_toggle_mask ^= KeyModifier::NumLock; READ_MODIFIER(0xE0, KeyModifier::LCtrl);
READ_MODIFIER(0xE4, KeyModifier::RCtrl);
READ_MODIFIER(0xE2, KeyModifier::LAlt);
READ_MODIFIER(0xE6, KeyModifier::RAlt);
#undef READ_MODIFIER
#define READ_TOGGLE(scancode, key_modifier) \
if (m_keyboard_state_temp[scancode] && !m_keyboard_state[scancode]) \
m_toggle_mask ^= key_modifier;
READ_TOGGLE(0x39, KeyModifier::CapsLock);
READ_TOGGLE(0x47, KeyModifier::ScrollLock);
READ_TOGGLE(0x53, KeyModifier::NumLock);
#undef READ_TOGGLE
modifier |= m_toggle_mask; modifier |= m_toggle_mask;
BAN::Optional<uint8_t> new_scancode;
for (size_t i = 0; i < m_keyboard_state.size(); i++) for (size_t i = 0; i < m_keyboard_state.size(); i++)
{ {
if (m_keyboard_state[i] == m_keyboard_state_temp[i]) if (m_keyboard_state[i] == m_keyboard_state_temp[i])
continue; continue;
if (m_keyboard_state_temp[i] && is_repeatable_scancode(i))
new_scancode = i;
const bool pressed = m_keyboard_state_temp[i]; const bool pressed = m_keyboard_state_temp[i];
if (pressed) if (pressed)
dprintln_if(DEBUG_KEYBOARD, "{2H}", i); dprintln_if(DEBUG_KEYBOARD, "Pressed {2H}", i);
auto opt_keycode = s_scancode_to_keycode[i]; auto opt_keycode = s_scancode_to_keycode[i];
if (opt_keycode.has_value()) if (opt_keycode.has_value())
@ -71,10 +79,27 @@ namespace Kernel
m_keyboard_state[i] = m_keyboard_state_temp[i]; m_keyboard_state[i] = m_keyboard_state_temp[i];
} }
if (m_repeat_scancode.has_value() && !m_keyboard_state_temp[m_repeat_scancode.value()])
m_repeat_scancode.clear();
m_repeat_modifier = modifier;
if (new_scancode.has_value())
{
if (!m_repeat_scancode.has_value() || m_repeat_scancode.value() != new_scancode.value())
{
m_repeat_scancode = new_scancode;
m_next_repeat_event_ms = SystemTimer::get().ms_since_boot() + s_repeat_initial_ms;
}
}
m_keyboard_lock.unlock(m_lock_state);
} }
void USBKeyboard::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) void USBKeyboard::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state)
{ {
ASSERT(m_keyboard_lock.current_processor_has_lock());
if (usage_page != 0x07) if (usage_page != 0x07)
{ {
dprintln_if(DEBUG_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page); dprintln_if(DEBUG_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
@ -88,6 +113,8 @@ namespace Kernel
void USBKeyboard::handle_array(uint16_t usage_page, uint16_t usage) void USBKeyboard::handle_array(uint16_t usage_page, uint16_t usage)
{ {
ASSERT(m_keyboard_lock.current_processor_has_lock());
if (usage_page != 0x07) if (usage_page != 0x07)
{ {
dprintln_if(DEBUG_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page); dprintln_if(DEBUG_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
@ -97,12 +124,36 @@ namespace Kernel
m_keyboard_state_temp[usage] = true; m_keyboard_state_temp[usage] = true;
} }
void USBKeyboard::update()
{
using KeyModifier = LibInput::KeyEvent::Modifier;
SpinLockGuard _(m_keyboard_lock);
if (!m_repeat_scancode.has_value() || SystemTimer::get().ms_since_boot() < m_next_repeat_event_ms)
return;
auto opt_keycode = s_scancode_to_keycode[m_repeat_scancode.value()];
if (!opt_keycode.has_value())
return;
LibInput::RawKeyEvent event;
event.keycode = opt_keycode.value();
event.modifier = m_repeat_modifier | KeyModifier::Pressed;
add_event(BAN::ConstByteSpan::from(event));
m_next_repeat_event_ms += s_repeat_interval_ms;
}
void initialize_scancode_to_keycode() void initialize_scancode_to_keycode()
{ {
using LibInput::keycode_function; using LibInput::keycode_function;
using LibInput::keycode_normal; using LibInput::keycode_normal;
using LibInput::keycode_numpad; using LibInput::keycode_numpad;
for (auto& mapping : s_scancode_to_keycode)
mapping.clear();
s_scancode_to_keycode[0x35] = keycode_normal(0, 0); s_scancode_to_keycode[0x35] = keycode_normal(0, 0);
s_scancode_to_keycode[0x1E] = keycode_normal(0, 1); s_scancode_to_keycode[0x1E] = keycode_normal(0, 1);
s_scancode_to_keycode[0x1F] = keycode_normal(0, 2); s_scancode_to_keycode[0x1F] = keycode_normal(0, 2);
@ -211,4 +262,42 @@ namespace Kernel
s_scancode_to_keycode_initialized = true; s_scancode_to_keycode_initialized = true;
} }
constexpr bool is_repeatable_scancode(uint8_t scancode)
{
switch (scancode)
{
case 0x00: // reserved
case 0x01: // error roll over
case 0x02: // post fail
case 0x03: // error undefined
case 0x29: // escape
case 0x39: // caps lock
case 0x3A: // f1
case 0x3B: // f2
case 0x3C: // f3
case 0x3D: // f4
case 0x3E: // f5
case 0x3F: // f6
case 0x40: // f7
case 0x41: // f8
case 0x42: // f9
case 0x43: // f10
case 0x44: // f11
case 0x45: // f12
case 0x47: // scroll lock
case 0x53: // num lock
case 0xE0: // left control
case 0xE1: // left shift
case 0xE2: // left alt
case 0xE3: // left super
case 0xE4: // right control
case 0xE5: // right shift
case 0xE6: // right alt
case 0xE7: // right super
return false;
default:
return true;
}
}
} }

View File

@ -31,7 +31,7 @@ if [ ! -d $CURL_VERSION ]; then
patch -ruN -d $CURL_VERSION < "$patch" patch -ruN -d $CURL_VERSION < "$patch"
done done
grep -qxF doom ../installed || echo curl >> ../installed grep -qxF curl ../installed || echo curl >> ../installed
fi fi
cd $CURL_VERSION cd $CURL_VERSION
@ -55,4 +55,4 @@ fi
cd "build-${BANAN_ARCH}" cd "build-${BANAN_ARCH}"
make && make install make -j $(nproc) && make install

View File

@ -1 +1,2 @@
doomgeneric doomgeneric/
doom1.wad

View File

@ -28,6 +28,6 @@ if [ ! -f doom1.wad ]; then
wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad wget https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
fi fi
make --directory doomgeneric/doomgeneric --file Makefile.banan_os make --directory doomgeneric/doomgeneric --file Makefile.banan_os -j $(nproc)
cp "doomgeneric/doomgeneric/build-${BANAN_ARCH}/doomgeneric" "${BANAN_SYSROOT}/bin/doom" cp "doomgeneric/doomgeneric/build-${BANAN_ARCH}/doomgeneric" "${BANAN_SYSROOT}/bin/doom"
cp doom1.wad $BANAN_SYSROOT/home/user/ cp doom1.wad $BANAN_SYSROOT/home/user/

View File

@ -8,7 +8,6 @@
__BEGIN_DECLS __BEGIN_DECLS
#include <limits.h> #include <limits.h>
#include <math.h>
#include <sys/wait.h> #include <sys/wait.h>
#define __need_NULL #define __need_NULL

View File

@ -6,6 +6,7 @@
#include <LibImage/PNG.h> #include <LibImage/PNG.h>
#include <fcntl.h> #include <fcntl.h>
#include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/mman.h> #include <sys/mman.h>

View File

@ -5,6 +5,7 @@
#include <ctype.h> #include <ctype.h>
#include <inttypes.h> #include <inttypes.h>
#include <math.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>

View File

@ -286,13 +286,23 @@ int main(int, char**)
if (!client.query.empty()) if (!client.query.empty())
{ {
dprintln("Client already has a query"); static uint8_t buffer[4096];
ssize_t nrecv = recv(client.socket, buffer, sizeof(buffer), 0);
if (nrecv < 0)
dprintln("{}", strerror(errno));
if (nrecv <= 0)
client.close = true;
else
dprintln("Client already has a query");
continue; continue;
} }
auto query = read_service_query(client.socket); auto query = read_service_query(client.socket);
if (!query.has_value()) if (!query.has_value())
{
client.close = true;
continue; continue;
}
BAN::Optional<DNSEntry> result; BAN::Optional<DNSEntry> result;