Compare commits
No commits in common. "4efaf65d3f2e89c139363be7421be6313f382549" and "d941e6d70b9ddf0a794d9358b9f3eb3d2fce93ff" have entirely different histories.
4efaf65d3f
...
d941e6d70b
|
@ -28,7 +28,7 @@ namespace Kernel
|
|||
// 1x singly indirect
|
||||
// 1x doubly indirect
|
||||
// 1x triply indirect
|
||||
BAN::Array<size_t, 5> block;
|
||||
BAN::Array<paddr_t, 5> block;
|
||||
static constexpr size_t direct_block_count = 2;
|
||||
#elif ARCH(i686)
|
||||
uint32_t __padding;
|
||||
|
@ -36,8 +36,8 @@ namespace Kernel
|
|||
// 1x singly indirect
|
||||
// 1x doubly indirect
|
||||
// 1x triply indirect
|
||||
BAN::Array<size_t, 16> block;
|
||||
static constexpr size_t direct_block_count = 13;
|
||||
BAN::Array<paddr_t, 8> block;
|
||||
static constexpr size_t direct_block_count = 5;
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
|
|
@ -58,9 +58,8 @@ namespace Kernel
|
|||
virtual void start_report() = 0;
|
||||
virtual void stop_report() = 0;
|
||||
|
||||
virtual void handle_array(uint16_t usage_page, uint16_t usage) = 0;
|
||||
virtual void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) = 0;
|
||||
virtual void handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max) = 0;
|
||||
virtual void handle_array(uint16_t usage_page, uint16_t usage) = 0;
|
||||
};
|
||||
|
||||
class USBHIDDriver final : public USBClassDriver
|
||||
|
|
|
@ -14,9 +14,8 @@ namespace Kernel
|
|||
void start_report() override;
|
||||
void stop_report() override;
|
||||
|
||||
void handle_array(uint16_t usage_page, uint16_t usage) override;
|
||||
void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) override;
|
||||
void handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max) override;
|
||||
void handle_array(uint16_t usage_page, uint16_t usage) override;
|
||||
|
||||
void update() override;
|
||||
|
||||
|
|
|
@ -14,9 +14,8 @@ namespace Kernel
|
|||
void start_report() override;
|
||||
void stop_report() override;
|
||||
|
||||
void handle_array(uint16_t usage_page, uint16_t usage) override;
|
||||
void handle_variable(uint16_t usage_page, uint16_t usage, int64_t state) override;
|
||||
void handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max) override;
|
||||
void handle_array(uint16_t usage_page, uint16_t usage) override;
|
||||
|
||||
private:
|
||||
USBMouse()
|
||||
|
@ -24,25 +23,13 @@ namespace Kernel
|
|||
{}
|
||||
~USBMouse() = default;
|
||||
|
||||
private:
|
||||
struct AbsInfo
|
||||
{
|
||||
int64_t val { -1 };
|
||||
int64_t min { 0 };
|
||||
int64_t max { 0 };
|
||||
bool valid() const { return min <= val && val <= max; }
|
||||
};
|
||||
|
||||
private:
|
||||
BAN::Array<bool, 5> m_button_state { false };
|
||||
BAN::Array<bool, 5> m_button_state_temp { false };
|
||||
int64_t m_rel_x { 0 };
|
||||
int64_t m_rel_y { 0 };
|
||||
int64_t m_pointer_x { 0 };
|
||||
int64_t m_pointer_y { 0 };
|
||||
int64_t m_wheel { 0 };
|
||||
|
||||
AbsInfo m_abs_x;
|
||||
AbsInfo m_abs_y;
|
||||
|
||||
friend class BAN::RefPtr<USBMouse>;
|
||||
};
|
||||
|
||||
|
|
|
@ -470,7 +470,7 @@ namespace Kernel
|
|||
IOAPIC* ioapic = nullptr;
|
||||
for (IOAPIC& io : m_io_apics)
|
||||
{
|
||||
if (io.gsi_base <= gsi && gsi < io.gsi_base + io.max_redirs)
|
||||
if (io.gsi_base <= gsi && gsi <= io.gsi_base + io.max_redirs)
|
||||
{
|
||||
ioapic = &io;
|
||||
break;
|
||||
|
@ -512,7 +512,7 @@ namespace Kernel
|
|||
bool found_ioapic = false;
|
||||
for (const auto& io : m_io_apics)
|
||||
{
|
||||
if (io.gsi_base <= gsi && gsi < io.gsi_base + io.max_redirs)
|
||||
if (io.gsi_base <= gsi && gsi <= io.gsi_base + io.max_redirs)
|
||||
{
|
||||
found_ioapic = true;
|
||||
break;
|
||||
|
@ -529,7 +529,7 @@ namespace Kernel
|
|||
int bit = gsi % 8;
|
||||
if (m_reserved_gsis[byte] & (1 << bit))
|
||||
{
|
||||
dwarnln("GSI {} is already reserved (IRQ {})", gsi, irq);
|
||||
dwarnln("GSI {} is already reserved", gsi);
|
||||
return BAN::Error::from_errno(EFAULT);
|
||||
}
|
||||
m_reserved_gsis[byte] |= 1 << bit;
|
||||
|
@ -566,7 +566,7 @@ namespace Kernel
|
|||
IOAPIC* ioapic = nullptr;
|
||||
for (IOAPIC& io : m_io_apics)
|
||||
{
|
||||
if (io.gsi_base <= gsi && gsi < io.gsi_base + io.max_redirs)
|
||||
if (io.gsi_base <= gsi && gsi <= io.gsi_base + io.max_redirs)
|
||||
{
|
||||
ioapic = &io;
|
||||
break;
|
||||
|
|
|
@ -284,9 +284,7 @@ namespace Kernel
|
|||
|
||||
paddr_t page_to_free;
|
||||
PageTable::with_fast_page(layer1_page.paddr(), [&] {
|
||||
static_assert(sizeof(size_t) <= sizeof(PageInfo));
|
||||
|
||||
auto& allocated_pages = PageTable::fast_page_as<size_t>(PAGE_SIZE - sizeof(size_t));
|
||||
auto& allocated_pages = PageTable::fast_page_as_sized<size_t>(page_infos_per_page - 1);
|
||||
ASSERT(allocated_pages > 0);
|
||||
allocated_pages--;
|
||||
|
||||
|
@ -407,9 +405,8 @@ namespace Kernel
|
|||
|
||||
PageTable::with_fast_page(layer1_page.paddr(), [&] {
|
||||
constexpr size_t pages_per_block = page_infos_per_page - 1;
|
||||
static_assert(sizeof(size_t) <= sizeof(PageInfo));
|
||||
|
||||
auto& allocated_pages = PageTable::fast_page_as<size_t>(PAGE_SIZE - sizeof(size_t));
|
||||
auto& allocated_pages = PageTable::fast_page_as_sized<size_t>(pages_per_block);
|
||||
if (allocated_pages == pages_per_block)
|
||||
return;
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace Kernel
|
|||
if (filesystem_or_error.is_error())
|
||||
panic("Failed to create fallback filesystem: {}", filesystem_or_error.error());
|
||||
|
||||
dprintln("Loading fallback filesystem from {} modules", g_boot_info.modules.size());
|
||||
dwarnln("Attempting to load fallback filesystem from {} modules", g_boot_info.modules.size());
|
||||
|
||||
auto filesystem = BAN::RefPtr<FileSystem>::adopt(filesystem_or_error.release_value());
|
||||
|
||||
|
@ -78,9 +78,6 @@ namespace Kernel
|
|||
|
||||
static BAN::RefPtr<FileSystem> load_root_filesystem(BAN::StringView root_path)
|
||||
{
|
||||
if (root_path.empty())
|
||||
return load_fallback_root_filesystem();
|
||||
|
||||
enum class RootType
|
||||
{
|
||||
PartitionUUID,
|
||||
|
|
|
@ -65,9 +65,7 @@ namespace Kernel
|
|||
{
|
||||
memset(&m_tss, 0x00, sizeof(TaskStateSegment));
|
||||
m_tss.iopb = sizeof(TaskStateSegment);
|
||||
#if ARCH(x86_64)
|
||||
m_tss.ist1 = reinterpret_cast<vaddr_t>(g_boot_stack_top);
|
||||
#endif
|
||||
|
||||
uintptr_t base = reinterpret_cast<uintptr_t>(&m_tss);
|
||||
|
||||
|
|
|
@ -410,11 +410,9 @@ namespace Kernel
|
|||
desc.offset1 = (uint16_t)((uintptr_t)handler >> 16);
|
||||
#if ARCH(x86_64)
|
||||
desc.offset2 = (uint32_t)((uintptr_t)handler >> 32);
|
||||
desc.IST = ist;
|
||||
#else
|
||||
(void)ist;
|
||||
#endif
|
||||
|
||||
desc.IST = ist;
|
||||
desc.selector = 0x08;
|
||||
desc.flags = 0x8E;
|
||||
}
|
||||
|
@ -456,10 +454,8 @@ namespace Kernel
|
|||
ISR_LIST_X
|
||||
#undef X
|
||||
|
||||
#if ARCH(x86_64)
|
||||
idt->register_interrupt_handler(DoubleFault, isr8, 1);
|
||||
static_assert(DoubleFault == 8);
|
||||
#endif
|
||||
|
||||
#define X(num) idt->register_interrupt_handler(IRQ_VECTOR_BASE + num, irq ## num);
|
||||
IRQ_LIST_X
|
||||
|
|
|
@ -1420,11 +1420,9 @@ namespace Kernel
|
|||
address_region2->unpin();
|
||||
});
|
||||
|
||||
if (address_len)
|
||||
{
|
||||
address_region1 = TRY(validate_and_pin_pointer_access(address_len, sizeof(address_len), true));
|
||||
address_region2 = TRY(validate_and_pin_pointer_access(address, *address_len, true));
|
||||
}
|
||||
address_region1 = TRY(validate_and_pin_pointer_access(address_len, sizeof(address_len), true));
|
||||
const socklen_t address_len_safe = address_len ? *address_len : 0;
|
||||
address_region2 = TRY(validate_and_pin_pointer_access(address, address_len_safe, true));
|
||||
|
||||
auto inode = TRY(m_open_file_descriptors.inode_of(socket));
|
||||
if (!inode->mode().ifsock())
|
||||
|
@ -1500,8 +1498,7 @@ namespace Kernel
|
|||
});
|
||||
|
||||
message_region = TRY(validate_and_pin_pointer_access(arguments.message, arguments.length, false));
|
||||
if (arguments.dest_addr)
|
||||
address_region = TRY(validate_and_pin_pointer_access(arguments.dest_addr, arguments.dest_len, false));
|
||||
address_region = TRY(validate_and_pin_pointer_access(arguments.dest_addr, arguments.dest_len, false));
|
||||
|
||||
auto message = BAN::ConstByteSpan(static_cast<const uint8_t*>(arguments.message), arguments.length);
|
||||
return TRY(m_open_file_descriptors.sendto(arguments.socket, message, arguments.dest_addr, arguments.dest_len));
|
||||
|
@ -1535,12 +1532,9 @@ namespace Kernel
|
|||
});
|
||||
|
||||
buffer_region = TRY(validate_and_pin_pointer_access(arguments.buffer, arguments.length, true));
|
||||
|
||||
if (arguments.address_len)
|
||||
{
|
||||
address_region1 = TRY(validate_and_pin_pointer_access(arguments.address_len, sizeof(*arguments.address_len), true));
|
||||
address_region2 = TRY(validate_and_pin_pointer_access(arguments.address, *arguments.address_len, true));
|
||||
}
|
||||
address_region1 = TRY(validate_and_pin_pointer_access(arguments.address_len, sizeof(*arguments.address_len), true));
|
||||
const socklen_t address_len_safe = arguments.address_len ? *arguments.address_len : 0;
|
||||
address_region2 = TRY(validate_and_pin_pointer_access(arguments.address, address_len_safe, true));
|
||||
|
||||
auto message = BAN::ByteSpan(static_cast<uint8_t*>(arguments.buffer), arguments.length);
|
||||
return TRY(m_open_file_descriptors.recvfrom(arguments.socket, message, arguments.address, arguments.address_len));
|
||||
|
@ -1576,12 +1570,9 @@ namespace Kernel
|
|||
errorfd_region->unpin();
|
||||
});
|
||||
|
||||
if (arguments.readfds)
|
||||
readfd_region = TRY(validate_and_pin_pointer_access(arguments.readfds, sizeof(fd_set), true));
|
||||
if (arguments.writefds)
|
||||
writefd_region = TRY(validate_and_pin_pointer_access(arguments.writefds, sizeof(fd_set), true));
|
||||
if (arguments.errorfds)
|
||||
errorfd_region = TRY(validate_and_pin_pointer_access(arguments.errorfds, sizeof(fd_set), true));
|
||||
readfd_region = TRY(validate_and_pin_pointer_access(arguments.readfds, sizeof(fd_set), true));
|
||||
writefd_region = TRY(validate_and_pin_pointer_access(arguments.writefds, sizeof(fd_set), true));
|
||||
errorfd_region = TRY(validate_and_pin_pointer_access(arguments.errorfds, sizeof(fd_set), true));
|
||||
|
||||
const auto old_sigmask = Thread::current().m_signal_block_mask;
|
||||
if (arguments.sigmask)
|
||||
|
|
|
@ -21,14 +21,13 @@ namespace Kernel
|
|||
if (ecx & CPUID::ECX_RDRND)
|
||||
{
|
||||
#if ARCH(x86_64)
|
||||
asm volatile("rdrand %0" : "=r"(s_rand_seed) :: "flags");
|
||||
asm volatile("rdrand %0" : "=r"(s_rand_seed));
|
||||
#elif ARCH(i686)
|
||||
uint32_t lo, hi;
|
||||
asm volatile(
|
||||
"rdrand %[lo];"
|
||||
"rdrand %[hi];"
|
||||
: [lo]"=r"(lo), [hi]"=r"(hi)
|
||||
:: "flags"
|
||||
);
|
||||
s_rand_seed = ((uint64_t)hi << 32) | lo;
|
||||
#else
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
#define SELECT_CHANNEL1 0x40
|
||||
#define SELECT_CHANNEL2 0x80
|
||||
|
||||
#define ACCESS_LO 0x10
|
||||
#define ACCESS_HI 0x20
|
||||
#define ACCESS_HI 0x10
|
||||
#define ACCESS_LO 0x20
|
||||
|
||||
#define MODE_RATE_GENERATOR 0x04
|
||||
#define MODE_RATE_GENERATOR 0x05
|
||||
|
||||
#define BASE_FREQUENCY 1193182
|
||||
|
||||
|
@ -116,7 +116,10 @@ namespace Kernel
|
|||
while (elapsed_ticks < target_ticks)
|
||||
{
|
||||
const uint8_t current_ticks = IO::inb(TIMER0_CTL);
|
||||
elapsed_ticks += static_cast<uint8_t>(last_ticks - current_ticks);
|
||||
if (last_ticks <= current_ticks)
|
||||
elapsed_ticks += current_ticks - last_ticks;
|
||||
else
|
||||
elapsed_ticks += 0xFF + current_ticks - last_ticks;
|
||||
last_ticks = current_ticks;
|
||||
}
|
||||
|
||||
|
|
|
@ -376,26 +376,17 @@ namespace Kernel
|
|||
continue;
|
||||
}
|
||||
|
||||
const int64_t physical =
|
||||
(input.physical_maximum - input.physical_minimum) *
|
||||
(logical - input.logical_minimum) /
|
||||
(input.logical_maximum - input.logical_minimum) +
|
||||
input.physical_minimum;
|
||||
|
||||
const uint32_t usage_base = input.usage_id ? input.usage_id : input.usage_minimum;
|
||||
|
||||
const bool relative = !!(input.flags & 0x04);
|
||||
const bool variable = !!(input.flags & 0x02);
|
||||
|
||||
if (!variable)
|
||||
device_input.device->handle_array(input.usage_page, usage_base + logical);
|
||||
if (input.flags & 0x02)
|
||||
device_input.device->handle_variable(input.usage_page, usage_base + i, physical);
|
||||
else
|
||||
{
|
||||
const int64_t physical =
|
||||
(input.physical_maximum - input.physical_minimum) *
|
||||
(logical - input.logical_minimum) /
|
||||
(input.logical_maximum - input.logical_minimum) +
|
||||
input.physical_minimum;
|
||||
|
||||
if (relative)
|
||||
device_input.device->handle_variable(input.usage_page, usage_base + i, physical);
|
||||
else
|
||||
device_input.device->handle_variable_absolute(input.usage_page, usage_base + i, physical, input.physical_minimum, input.physical_maximum);
|
||||
}
|
||||
device_input.device->handle_array(input.usage_page, usage_base + physical);
|
||||
|
||||
bit_offset += input.report_size;
|
||||
}
|
||||
|
@ -567,8 +558,6 @@ namespace Kernel
|
|||
{
|
||||
switch (item_tag)
|
||||
{
|
||||
case 0b0000:
|
||||
break;
|
||||
case 0b1000: // input
|
||||
if (collection_stack.empty())
|
||||
{
|
||||
|
|
|
@ -102,31 +102,8 @@ namespace Kernel
|
|||
m_keyboard_lock.unlock(m_lock_state);
|
||||
}
|
||||
|
||||
void USBKeyboard::handle_array(uint16_t usage_page, uint16_t usage)
|
||||
{
|
||||
ASSERT(m_keyboard_lock.current_processor_has_lock());
|
||||
|
||||
if (usage_page != 0x07)
|
||||
{
|
||||
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
||||
return;
|
||||
}
|
||||
if (usage >= 4 && usage < m_keyboard_state_temp.size())
|
||||
m_keyboard_state_temp[usage] = true;
|
||||
}
|
||||
|
||||
void USBKeyboard::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state)
|
||||
{
|
||||
(void)usage_page;
|
||||
(void)usage;
|
||||
(void)state;
|
||||
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard relative usage page {2H}", usage_page);
|
||||
}
|
||||
|
||||
void USBKeyboard::handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max)
|
||||
{
|
||||
(void)min; (void)max;
|
||||
|
||||
ASSERT(m_keyboard_lock.current_processor_has_lock());
|
||||
|
||||
if (usage_page != 0x07)
|
||||
|
@ -140,6 +117,19 @@ namespace Kernel
|
|||
m_keyboard_state_temp[usage] = state;
|
||||
}
|
||||
|
||||
void USBKeyboard::handle_array(uint16_t usage_page, uint16_t usage)
|
||||
{
|
||||
ASSERT(m_keyboard_lock.current_processor_has_lock());
|
||||
|
||||
if (usage_page != 0x07)
|
||||
{
|
||||
dprintln_if(DEBUG_USB_KEYBOARD, "Unsupported keyboard usage page {2H}", usage_page);
|
||||
return;
|
||||
}
|
||||
if (usage >= 4 && usage < m_keyboard_state_temp.size())
|
||||
m_keyboard_state_temp[usage] = true;
|
||||
}
|
||||
|
||||
void USBKeyboard::update()
|
||||
{
|
||||
using KeyModifier = LibInput::KeyEvent::Modifier;
|
||||
|
|
|
@ -6,43 +6,24 @@ namespace Kernel
|
|||
|
||||
void USBMouse::start_report()
|
||||
{
|
||||
m_wheel = 0;
|
||||
m_rel_x = 0;
|
||||
m_rel_y = 0;
|
||||
|
||||
m_abs_x = {};
|
||||
m_abs_y = {};
|
||||
|
||||
for (auto& val : m_button_state_temp)
|
||||
val = false;
|
||||
}
|
||||
|
||||
void USBMouse::stop_report()
|
||||
{
|
||||
if (m_abs_x.valid() && m_abs_y.valid())
|
||||
if (m_pointer_x || m_pointer_y)
|
||||
{
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Mouse move absolute event {}, {}", m_abs_x.val, m_abs_y.val);
|
||||
|
||||
LibInput::MouseEvent event;
|
||||
event.type = LibInput::MouseEventType::MouseMoveAbsEvent;
|
||||
event.move_abs_event.abs_x = m_abs_x.val;
|
||||
event.move_abs_event.min_x = m_abs_x.min;
|
||||
event.move_abs_event.max_x = m_abs_x.max;
|
||||
event.move_abs_event.abs_y = m_abs_y.val;
|
||||
event.move_abs_event.min_y = m_abs_y.min;
|
||||
event.move_abs_event.max_y = m_abs_y.max;
|
||||
add_event(BAN::ConstByteSpan::from(event));
|
||||
}
|
||||
|
||||
if (m_rel_x || m_rel_y)
|
||||
{
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Mouse move event {}, {}", m_rel_x, m_rel_y);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Mouse move event {}, {}", m_pointer_x, m_pointer_y);
|
||||
|
||||
LibInput::MouseEvent event;
|
||||
event.type = LibInput::MouseEventType::MouseMoveEvent;
|
||||
event.move_event.rel_x = m_rel_x;
|
||||
event.move_event.rel_y = -m_rel_y;
|
||||
event.move_event.rel_x = m_pointer_x;
|
||||
event.move_event.rel_y = -m_pointer_y;
|
||||
add_event(BAN::ConstByteSpan::from(event));
|
||||
|
||||
m_pointer_x = 0;
|
||||
m_pointer_y = 0;
|
||||
}
|
||||
|
||||
if (m_wheel)
|
||||
|
@ -53,6 +34,8 @@ namespace Kernel
|
|||
event.type = LibInput::MouseEventType::MouseScrollEvent;
|
||||
event.scroll_event.scroll = m_wheel;
|
||||
add_event(BAN::ConstByteSpan::from(event));
|
||||
|
||||
m_wheel = 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < m_button_state.size(); i++)
|
||||
|
@ -74,11 +57,6 @@ namespace Kernel
|
|||
}
|
||||
}
|
||||
|
||||
void USBMouse::handle_array(uint16_t usage_page, uint16_t usage)
|
||||
{
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unhandled array report {2H}:{2H}", usage_page, usage);
|
||||
}
|
||||
|
||||
void USBMouse::handle_variable(uint16_t usage_page, uint16_t usage, int64_t state)
|
||||
{
|
||||
switch (usage_page)
|
||||
|
@ -87,50 +65,16 @@ namespace Kernel
|
|||
switch (usage)
|
||||
{
|
||||
case 0x30:
|
||||
m_rel_x = state;
|
||||
m_pointer_x = state;
|
||||
break;
|
||||
case 0x31:
|
||||
m_rel_y = state;
|
||||
m_pointer_y = state;
|
||||
break;
|
||||
case 0x38:
|
||||
m_wheel = state;
|
||||
break;
|
||||
default:
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported relative mouse usage {2H} on page {2H}", usage, usage_page);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported relative mouse usage page {2H}", usage_page);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void USBMouse::handle_variable_absolute(uint16_t usage_page, uint16_t usage, int64_t state, int64_t min, int64_t max)
|
||||
{
|
||||
(void)min; (void)max;
|
||||
|
||||
switch (usage_page)
|
||||
{
|
||||
case 0x01: // pointer
|
||||
switch (usage)
|
||||
{
|
||||
case 0x30:
|
||||
m_abs_x = {
|
||||
.val = state,
|
||||
.min = min,
|
||||
.max = max,
|
||||
};
|
||||
break;
|
||||
case 0x31:
|
||||
m_abs_y = {
|
||||
.val = state,
|
||||
.min = min,
|
||||
.max = max,
|
||||
};
|
||||
break;
|
||||
default:
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported absolute mouse usage {2H} on page {2H}", usage, usage_page);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported mouse usage {2H} on page {2H}", usage, usage_page);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -140,9 +84,14 @@ namespace Kernel
|
|||
m_button_state_temp[usage - 1] = state;
|
||||
break;
|
||||
default:
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported absolute mouse usage page {2H}", usage_page);
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unsupported mouse usage page {2H}", usage_page);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void USBMouse::handle_array(uint16_t usage_page, uint16_t usage)
|
||||
{
|
||||
dprintln_if(DEBUG_USB_MOUSE, "Unhandled array report {2H}:{2H}", usage_page, usage);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ fi
|
|||
NET_ARGS='-netdev user,id=net'
|
||||
NET_ARGS="-device e1000e,netdev=net $NET_ARGS"
|
||||
|
||||
USB_ARGS='-device qemu-xhci -device usb-kbd,port=1 -device usb-hub,port=2 -device usb-tablet,port=2.1'
|
||||
USB_ARGS='-device qemu-xhci -device usb-kbd,port=1 -device usb-hub,port=2 -device usb-mouse,port=2.1'
|
||||
|
||||
SOUND_ARGS='-device ac97'
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ foreach(library ${USERSPACE_LIBRARIES})
|
|||
# This is to allow cmake to link when libc updates
|
||||
target_link_options(${library_lower} PRIVATE -nolibc)
|
||||
# Default compile options
|
||||
target_compile_options(${library_lower} PRIVATE -g -O2 -Wall -Wextra -Werror -msse -msse2)
|
||||
target_compile_options(${library_lower} PRIVATE -g -O2 -Wall -Wextra -Werror)
|
||||
|
||||
# set SONAME as cmake doesn't set it for some reason??
|
||||
set_target_properties(${library_lower} PROPERTIES LINK_FLAGS "-Wl,-soname,${library_lower}.so")
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <immintrin.h>
|
||||
|
||||
namespace LibImage
|
||||
{
|
||||
|
||||
|
@ -64,41 +62,33 @@ namespace LibImage
|
|||
return BAN::Error::from_errno(ENOTSUP);
|
||||
}
|
||||
|
||||
|
||||
struct FloatingColor
|
||||
{
|
||||
__m128 vals;
|
||||
double r, g, b, a;
|
||||
|
||||
FloatingColor() {}
|
||||
FloatingColor(float b, float g, float r, float a)
|
||||
: vals { b, g, r, a }
|
||||
constexpr FloatingColor() {}
|
||||
constexpr FloatingColor(double r, double g, double b, double a)
|
||||
: r(r), g(g), b(b), a(a)
|
||||
{}
|
||||
FloatingColor(Image::Color c)
|
||||
: FloatingColor(c.b, c.g, c.r, c.a)
|
||||
constexpr FloatingColor(Image::Color c)
|
||||
: r(c.r), g(c.g), b(c.b), a(c.a)
|
||||
{}
|
||||
FloatingColor operator*(float value) const
|
||||
constexpr FloatingColor operator*(double value) const
|
||||
{
|
||||
FloatingColor color;
|
||||
color.vals = _mm_mul_ps(vals, _mm_set1_ps(value));
|
||||
return color;
|
||||
return FloatingColor(r * value, g * value, b * value, a * value);
|
||||
}
|
||||
FloatingColor operator+(FloatingColor other) const
|
||||
constexpr FloatingColor operator+(FloatingColor other) const
|
||||
{
|
||||
FloatingColor color;
|
||||
color.vals = _mm_add_ps(this->vals, other.vals);
|
||||
return color;
|
||||
return FloatingColor(r + other.r, g + other.g, b + other.b, a + other.a);
|
||||
}
|
||||
Image::Color as_color() const
|
||||
constexpr Image::Color as_color() const
|
||||
{
|
||||
__m128i int32 = _mm_cvttps_epi32(this->vals);
|
||||
__m128i int16 = _mm_packs_epi32(int32, _mm_setzero_si128());
|
||||
__m128i int8 = _mm_packus_epi16(int16, _mm_setzero_si128());
|
||||
|
||||
const uint32_t temp = _mm_cvtsi128_si32(int8);
|
||||
return Image::Color {
|
||||
.b = reinterpret_cast<const uint8_t*>(&temp)[0],
|
||||
.g = reinterpret_cast<const uint8_t*>(&temp)[1],
|
||||
.r = reinterpret_cast<const uint8_t*>(&temp)[2],
|
||||
.a = reinterpret_cast<const uint8_t*>(&temp)[3],
|
||||
.b = static_cast<uint8_t>(b < 0.0 ? 0.0 : b > 255.0 ? 255.0 : b),
|
||||
.g = static_cast<uint8_t>(g < 0.0 ? 0.0 : g > 255.0 ? 255.0 : g),
|
||||
.r = static_cast<uint8_t>(r < 0.0 ? 0.0 : r > 255.0 ? 255.0 : r),
|
||||
.a = static_cast<uint8_t>(a < 0.0 ? 0.0 : a > 255.0 ? 255.0 : a),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -108,8 +98,8 @@ namespace LibImage
|
|||
if (!validate_size(new_width, new_height))
|
||||
return BAN::Error::from_errno(EOVERFLOW);
|
||||
|
||||
const float ratio_x = static_cast<float>(width()) / new_width;
|
||||
const float ratio_y = static_cast<float>(height()) / new_height;
|
||||
const double ratio_x = (double)width() / new_width;
|
||||
const double ratio_y = (double)height() / new_height;
|
||||
|
||||
const auto get_clamped_color =
|
||||
[this](int64_t x, int64_t y)
|
||||
|
@ -135,38 +125,26 @@ namespace LibImage
|
|||
BAN::Vector<Color> bilinear_bitmap;
|
||||
TRY(bilinear_bitmap.resize(new_width * new_height));
|
||||
|
||||
const uint64_t temp_w = width() + 1;
|
||||
const uint64_t temp_h = height() + 1;
|
||||
|
||||
BAN::Vector<FloatingColor> floating_bitmap;
|
||||
TRY(floating_bitmap.resize(temp_w * temp_h));
|
||||
for (uint64_t y = 0; y < temp_h; y++)
|
||||
for (uint64_t x = 0; x < temp_w; x++)
|
||||
floating_bitmap[y * temp_w + x] = get_clamped_color(x, y);
|
||||
|
||||
for (uint64_t y = 0; y < new_height; y++)
|
||||
{
|
||||
for (uint64_t x = 0; x < new_width; x++)
|
||||
{
|
||||
const float src_x = x * ratio_x;
|
||||
const float src_y = y * ratio_y;
|
||||
const double src_x = x * ratio_x;
|
||||
const double src_y = y * ratio_y;
|
||||
const double weight_x = src_x - BAN::Math::floor(src_x);
|
||||
const double weight_y = src_y - BAN::Math::floor(src_y);
|
||||
|
||||
const float weight_x = BAN::Math::fmod(src_x, 1.0f);
|
||||
const float weight_y = BAN::Math::fmod(src_y, 1.0f);
|
||||
|
||||
const uint64_t src_x_u64 = BAN::Math::clamp<uint64_t>(src_x, 0, width() - 1);
|
||||
const uint64_t src_y_u64 = BAN::Math::clamp<uint64_t>(src_y, 0, height() - 1);
|
||||
|
||||
const auto tl = floating_bitmap[(src_y_u64 + 0) * temp_w + (src_x_u64 + 0)];
|
||||
const auto tr = floating_bitmap[(src_y_u64 + 0) * temp_w + (src_x_u64 + 1)];
|
||||
const auto bl = floating_bitmap[(src_y_u64 + 1) * temp_w + (src_x_u64 + 0)];
|
||||
const auto br = floating_bitmap[(src_y_u64 + 1) * temp_w + (src_x_u64 + 1)];
|
||||
|
||||
const auto avg_t = tl * (1.0f - weight_x) + tr * weight_x;
|
||||
const auto avg_b = bl * (1.0f - weight_x) + br * weight_x;
|
||||
const auto avg = avg_t * (1.0f - weight_y) + avg_b * weight_y;
|
||||
|
||||
bilinear_bitmap[y * new_width + x] = avg.as_color();
|
||||
const Color avg_t = Color::average(
|
||||
get_clamped_color(src_x + 0.0, src_y),
|
||||
get_clamped_color(src_x + 1.0, src_y),
|
||||
weight_x
|
||||
);
|
||||
const Color avg_b = Color::average(
|
||||
get_clamped_color(src_x + 0.0, src_y + 1.0),
|
||||
get_clamped_color(src_x + 0.0, src_y + 1.0),
|
||||
weight_x
|
||||
);
|
||||
bilinear_bitmap[y * new_width + x] = Color::average(avg_t, avg_b, weight_y);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,52 +153,35 @@ namespace LibImage
|
|||
case ResizeAlgorithm::Cubic:
|
||||
{
|
||||
BAN::Vector<Color> bicubic_bitmap;
|
||||
TRY(bicubic_bitmap.resize(new_width * new_height, {}));
|
||||
TRY(bicubic_bitmap.resize(new_width * new_height));
|
||||
|
||||
constexpr auto cubic_interpolate =
|
||||
[](const FloatingColor p[4], float weight) -> FloatingColor
|
||||
[](FloatingColor p[4], double x)
|
||||
{
|
||||
const auto a = (p[0] * -0.5) + (p[1] * 1.5) + (p[2] * -1.5) + (p[3] * 0.5);
|
||||
const auto b = p[0] + (p[1] * -2.5) + (p[2] * 2.0) + (p[3] * -0.5);
|
||||
const auto c = (p[0] * -0.5) + (p[2] * 0.5);
|
||||
const auto d = p[1];
|
||||
return ((a * weight + b) * weight + c) * weight + d;
|
||||
return ((a * x + b) * x + c) * x + d;
|
||||
};
|
||||
|
||||
const uint64_t temp_w = width() + 3;
|
||||
const uint64_t temp_h = height() + 3;
|
||||
|
||||
BAN::Vector<FloatingColor> floating_bitmap;
|
||||
TRY(floating_bitmap.resize(temp_w * temp_h, {}));
|
||||
for (uint64_t y = 0; y < temp_h; y++)
|
||||
for (uint64_t x = 0; x < temp_w; x++)
|
||||
floating_bitmap[y * temp_w + x] = get_clamped_color(
|
||||
static_cast<int64_t>(x) - 1,
|
||||
static_cast<int64_t>(y) - 1
|
||||
);
|
||||
|
||||
for (uint64_t y = 0; y < new_height; y++)
|
||||
{
|
||||
for (uint64_t x = 0; x < new_width; x++)
|
||||
{
|
||||
const float src_x = x * ratio_x;
|
||||
const float src_y = y * ratio_y;
|
||||
|
||||
const float weight_x = BAN::Math::fmod(src_x, 1.0f);
|
||||
const float weight_y = BAN::Math::fmod(src_y, 1.0f);
|
||||
|
||||
const uint64_t src_x_u64 = BAN::Math::clamp<uint64_t>(src_x, 0, width() - 1) + 1;
|
||||
const uint64_t src_y_u64 = BAN::Math::clamp<uint64_t>(src_y, 0, height() - 1) + 1;
|
||||
const double src_x = x * ratio_x;
|
||||
const double src_y = y * ratio_y;
|
||||
const double weight_x = src_x - BAN::Math::floor(src_x);
|
||||
const double weight_y = src_y - BAN::Math::floor(src_y);
|
||||
|
||||
FloatingColor values[4];
|
||||
for (int64_t m = -1; m <= 2; m++)
|
||||
{
|
||||
const FloatingColor p[4] {
|
||||
floating_bitmap[(src_y_u64 + m) * temp_w + (src_x_u64 - 1)],
|
||||
floating_bitmap[(src_y_u64 + m) * temp_w + (src_x_u64 + 0)],
|
||||
floating_bitmap[(src_y_u64 + m) * temp_w + (src_x_u64 + 1)],
|
||||
floating_bitmap[(src_y_u64 + m) * temp_w + (src_x_u64 + 2)],
|
||||
};
|
||||
FloatingColor p[4];
|
||||
p[0] = get_clamped_color(src_x - 1.0, src_y + m);
|
||||
p[1] = get_clamped_color(src_x + 0.0, src_y + m);
|
||||
p[2] = get_clamped_color(src_x + 1.0, src_y + m);
|
||||
p[3] = get_clamped_color(src_x + 2.0, src_y + m);
|
||||
values[m + 1] = cubic_interpolate(p, weight_x);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,16 +22,6 @@ namespace LibInput
|
|||
int32_t rel_y;
|
||||
};
|
||||
|
||||
struct MouseMoveAbsEvent
|
||||
{
|
||||
int32_t abs_x;
|
||||
int32_t abs_y;
|
||||
int32_t min_x;
|
||||
int32_t min_y;
|
||||
int32_t max_x;
|
||||
int32_t max_y;
|
||||
};
|
||||
|
||||
struct MouseScrollEvent
|
||||
{
|
||||
int32_t scroll;
|
||||
|
@ -41,7 +31,6 @@ namespace LibInput
|
|||
{
|
||||
MouseButtonEvent,
|
||||
MouseMoveEvent,
|
||||
MouseMoveAbsEvent,
|
||||
MouseScrollEvent,
|
||||
};
|
||||
|
||||
|
@ -52,7 +41,6 @@ namespace LibInput
|
|||
{
|
||||
MouseButtonEvent button_event;
|
||||
MouseMoveEvent move_event;
|
||||
MouseMoveAbsEvent move_abs_event;
|
||||
MouseScrollEvent scroll_event;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -57,5 +57,5 @@ foreach(project ${USERSPACE_PROGRAMS})
|
|||
# This is to allow cmake to link when libc updates
|
||||
target_link_options(${project} PRIVATE -nolibc)
|
||||
# Default compile options
|
||||
target_compile_options(${project} PRIVATE -g -O2 -Wall -Wextra -Werror -msse -msse2)
|
||||
target_compile_options(${project} PRIVATE -g -O2 -Wall -Wextra -Werror)
|
||||
endforeach()
|
||||
|
|
|
@ -613,9 +613,36 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
|
|||
}
|
||||
}
|
||||
|
||||
void WindowServer::on_mouse_move_impl(int32_t new_x, int32_t new_y)
|
||||
void WindowServer::on_mouse_move(LibInput::MouseMoveEvent event)
|
||||
{
|
||||
LibInput::MouseMoveEvent event;
|
||||
if (m_is_mouse_captured)
|
||||
{
|
||||
ASSERT(m_focused_window);
|
||||
|
||||
LibGUI::EventPacket::MouseMoveEvent packet;
|
||||
packet.event.x = event.rel_x;
|
||||
packet.event.y = -event.rel_y;
|
||||
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
|
||||
dwarnln("could not send mouse move event: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto [new_x, new_y] =
|
||||
[&]() -> Position
|
||||
{
|
||||
const int32_t new_x = m_cursor.x + event.rel_x;
|
||||
const int32_t new_y = m_cursor.y - event.rel_y;
|
||||
return (m_state == State::Fullscreen)
|
||||
? Position {
|
||||
.x = BAN::Math::clamp(new_x, m_focused_window->client_x(), m_focused_window->client_x() + m_focused_window->client_width()),
|
||||
.y = BAN::Math::clamp(new_y, m_focused_window->client_y(), m_focused_window->client_y() + m_focused_window->client_height())
|
||||
}
|
||||
: Position {
|
||||
.x = BAN::Math::clamp(new_x, 0, m_framebuffer.width),
|
||||
.y = BAN::Math::clamp(new_y, 0, m_framebuffer.height)
|
||||
};
|
||||
}();
|
||||
|
||||
event.rel_x = new_x - m_cursor.x;
|
||||
event.rel_y = new_y - m_cursor.y;
|
||||
if (event.rel_x == 0 && event.rel_y == 0)
|
||||
|
@ -679,74 +706,6 @@ void WindowServer::on_mouse_move_impl(int32_t new_x, int32_t new_y)
|
|||
}
|
||||
}
|
||||
|
||||
void WindowServer::on_mouse_move(LibInput::MouseMoveEvent event)
|
||||
{
|
||||
if (m_is_mouse_captured)
|
||||
{
|
||||
ASSERT(m_focused_window);
|
||||
|
||||
LibGUI::EventPacket::MouseMoveEvent packet;
|
||||
packet.event.x = event.rel_x;
|
||||
packet.event.y = -event.rel_y;
|
||||
if (auto ret = packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
|
||||
dwarnln("could not send mouse move event: {}", ret.error());
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t min_x, max_x;
|
||||
int32_t min_y, max_y;
|
||||
|
||||
if (m_state == State::Fullscreen)
|
||||
{
|
||||
min_x = m_focused_window->client_x();
|
||||
min_y = m_focused_window->client_y();
|
||||
max_x = m_focused_window->client_x() + m_focused_window->client_width();
|
||||
max_y = m_focused_window->client_y() + m_focused_window->client_height();
|
||||
}
|
||||
else
|
||||
{
|
||||
min_x = 0;
|
||||
min_y = 0;
|
||||
max_x = m_framebuffer.width;
|
||||
max_y = m_framebuffer.height;
|
||||
}
|
||||
|
||||
const int32_t new_x = BAN::Math::clamp(m_cursor.x + event.rel_x, min_x, max_x);
|
||||
const int32_t new_y = BAN::Math::clamp(m_cursor.y + event.rel_y, min_y, max_y);
|
||||
return on_mouse_move_impl(new_x, new_y);
|
||||
}
|
||||
|
||||
void WindowServer::on_mouse_move_abs(LibInput::MouseMoveAbsEvent event)
|
||||
{
|
||||
constexpr auto map =
|
||||
[](int32_t val, int32_t in_min, int32_t in_max, int32_t out_min, int32_t out_max) -> int32_t
|
||||
{
|
||||
return (val - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
};
|
||||
|
||||
int32_t out_min_x, out_max_x;
|
||||
int32_t out_min_y, out_max_y;
|
||||
|
||||
if (m_state == State::Fullscreen)
|
||||
{
|
||||
out_min_x = m_focused_window->client_x();
|
||||
out_min_y = m_focused_window->client_y();
|
||||
out_max_x = m_focused_window->client_x() + m_focused_window->client_width();
|
||||
out_max_y = m_focused_window->client_y() + m_focused_window->client_height();
|
||||
}
|
||||
else
|
||||
{
|
||||
out_min_x = 0;
|
||||
out_min_y = 0;
|
||||
out_max_x = m_framebuffer.width;
|
||||
out_max_y = m_framebuffer.height;
|
||||
}
|
||||
|
||||
const int32_t new_x = map(event.abs_x, event.min_x, event.max_x, out_min_x, out_max_x);
|
||||
const int32_t new_y = map(event.abs_y, event.min_y, event.max_y, out_min_y, out_max_y);
|
||||
return on_mouse_move_impl(new_x, new_y);
|
||||
}
|
||||
|
||||
void WindowServer::on_mouse_scroll(LibInput::MouseScrollEvent event)
|
||||
{
|
||||
if (m_focused_window)
|
||||
|
|
|
@ -46,7 +46,6 @@ public:
|
|||
void on_key_event(LibInput::KeyEvent event);
|
||||
void on_mouse_button(LibInput::MouseButtonEvent event);
|
||||
void on_mouse_move(LibInput::MouseMoveEvent event);
|
||||
void on_mouse_move_abs(LibInput::MouseMoveAbsEvent event);
|
||||
void on_mouse_scroll(LibInput::MouseScrollEvent event);
|
||||
|
||||
void set_focused_window(BAN::RefPtr<Window> window);
|
||||
|
@ -64,8 +63,6 @@ public:
|
|||
bool is_stopped() const { return m_is_stopped; }
|
||||
|
||||
private:
|
||||
void on_mouse_move_impl(int32_t new_x, int32_t new_y);
|
||||
|
||||
void mark_pending_sync(Rectangle area);
|
||||
|
||||
bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height) const;
|
||||
|
|
|
@ -290,9 +290,6 @@ int main()
|
|||
case LibInput::MouseEventType::MouseMoveEvent:
|
||||
window_server.on_mouse_move(event.move_event);
|
||||
break;
|
||||
case LibInput::MouseEventType::MouseMoveAbsEvent:
|
||||
window_server.on_mouse_move_abs(event.move_abs_event);
|
||||
break;
|
||||
case LibInput::MouseEventType::MouseScrollEvent:
|
||||
window_server.on_mouse_scroll(event.scroll_event);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue