Compare commits
6 Commits
1337758660
...
61f0043cd8
Author | SHA1 | Date |
---|---|---|
Bananymous | 61f0043cd8 | |
Bananymous | dd7bfba8d5 | |
Bananymous | 5b8fdbc82d | |
Bananymous | 6a1c677cbc | |
Bananymous | e30952efee | |
Bananymous | fd8dc03ae9 |
|
@ -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 };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
doomgeneric
|
doomgeneric/
|
||||||
|
doom1.wad
|
||||||
|
|
|
@ -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/
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue