mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-08 12:19:37 +03:00
Make PS2MouseDevice behave more like a proper character device.
Get rid of the goofy MouseClient interface and have the GUI event loop just read mouse data from the character device. The previous approach was awful as it was sending us into random GUI code in the mouse interrupt handler.
This commit is contained in:
parent
52e019f9aa
commit
fd4e86460b
Notes:
sideshowbarker
2024-07-19 16:04:30 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/fd4e86460bd
@ -44,8 +44,7 @@ void PS2MouseDevice::handle_irq()
|
||||
(m_data[0] & 2) ? "Right" : ""
|
||||
);
|
||||
#endif
|
||||
if (m_client)
|
||||
m_client->did_receive_mouse_data(m_data[1], -m_data[2], m_data[0] & 1, m_data[0] & 2);
|
||||
m_buffer.write((const byte*)m_data, 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -119,22 +118,15 @@ byte PS2MouseDevice::mouse_read()
|
||||
|
||||
bool PS2MouseDevice::has_data_available_for_reading() const
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
return false;
|
||||
return !m_buffer.is_empty();
|
||||
}
|
||||
|
||||
ssize_t PS2MouseDevice::read(byte* buffer, size_t buffer_size)
|
||||
ssize_t PS2MouseDevice::read(byte* buffer, size_t size)
|
||||
{
|
||||
return m_buffer.read(buffer, size);
|
||||
}
|
||||
|
||||
ssize_t PS2MouseDevice::write(const byte*, size_t)
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t PS2MouseDevice::write(const byte *buffer, size_t buffer_size)
|
||||
{
|
||||
ASSERT_NOT_REACHED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
MouseClient::~MouseClient()
|
||||
{
|
||||
}
|
||||
|
@ -1,10 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <VirtualFileSystem/CharacterDevice.h>
|
||||
#include "DoubleBuffer.h"
|
||||
#include "IRQHandler.h"
|
||||
|
||||
class MouseClient;
|
||||
|
||||
class PS2MouseDevice final : public IRQHandler, public CharacterDevice {
|
||||
public:
|
||||
PS2MouseDevice();
|
||||
@ -12,13 +11,13 @@ public:
|
||||
|
||||
static PS2MouseDevice& the();
|
||||
|
||||
void set_client(MouseClient* client) { m_client = client; }
|
||||
// ^CharacterDevice
|
||||
virtual bool has_data_available_for_reading() const override;
|
||||
virtual ssize_t read(byte* buffer, size_t) override;
|
||||
virtual ssize_t write(const byte* buffer, size_t) override;
|
||||
|
||||
private:
|
||||
virtual bool has_data_available_for_reading() const override;
|
||||
virtual ssize_t read(byte* buffer, size_t buffer_size) override;
|
||||
virtual ssize_t write(const byte* buffer, size_t buffer_size) override;
|
||||
|
||||
// ^IRQHandler
|
||||
virtual void handle_irq() override;
|
||||
|
||||
void initialize();
|
||||
@ -29,13 +28,7 @@ private:
|
||||
void wait_then_write(byte port, byte data);
|
||||
byte wait_then_read(byte port);
|
||||
|
||||
MouseClient* m_client { nullptr };
|
||||
DoubleBuffer m_buffer;
|
||||
byte m_data_state { 0 };
|
||||
signed_byte m_data[3];
|
||||
};
|
||||
|
||||
class MouseClient {
|
||||
public:
|
||||
virtual ~MouseClient();
|
||||
virtual void did_receive_mouse_data(int dx, int dy, bool left_button, bool right_button) = 0;
|
||||
};
|
||||
|
@ -28,7 +28,6 @@ AbstractScreen::AbstractScreen(unsigned width, unsigned height)
|
||||
|
||||
m_cursor_location = rect().center();
|
||||
|
||||
PS2MouseDevice::the().set_client(this);
|
||||
Keyboard::the().set_client(this);
|
||||
}
|
||||
|
||||
@ -36,7 +35,7 @@ AbstractScreen::~AbstractScreen()
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractScreen::did_receive_mouse_data(int dx, int dy, bool left_button, bool right_button)
|
||||
void AbstractScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool right_button)
|
||||
{
|
||||
auto prev_location = m_cursor_location;
|
||||
m_cursor_location.moveBy(dx, dy);
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include "Keyboard.h"
|
||||
#include "PS2MouseDevice.h"
|
||||
|
||||
class AbstractScreen : public Object, public KeyboardClient, public MouseClient {
|
||||
class AbstractScreen : public Object, public KeyboardClient {
|
||||
public:
|
||||
virtual ~AbstractScreen();
|
||||
|
||||
@ -24,13 +24,12 @@ public:
|
||||
bool left_mouse_button_pressed() const { return m_left_mouse_button_pressed; }
|
||||
bool right_mouse_button_pressed() const { return m_right_mouse_button_pressed; }
|
||||
|
||||
void on_receive_mouse_data(int dx, int dy, bool left_button, bool right_button);
|
||||
|
||||
protected:
|
||||
AbstractScreen(unsigned width, unsigned height);
|
||||
|
||||
private:
|
||||
// ^MouseClient
|
||||
virtual void did_receive_mouse_data(int dx, int dy, bool left_button, bool right_button) final;
|
||||
|
||||
// ^KeyboardClient
|
||||
virtual void on_key_pressed(Keyboard::Key) final;
|
||||
|
||||
|
@ -2,6 +2,11 @@
|
||||
#include "Event.h"
|
||||
#include "Object.h"
|
||||
#include "WindowManager.h"
|
||||
#include "AbstractScreen.h"
|
||||
|
||||
#ifdef SERENITY
|
||||
#include "PS2MouseDevice.h"
|
||||
#endif
|
||||
|
||||
static EventLoop* s_mainEventLoop;
|
||||
|
||||
@ -60,6 +65,13 @@ void EventLoop::postEvent(Object* receiver, OwnPtr<Event>&& event)
|
||||
#ifdef SERENITY
|
||||
void EventLoop::waitForEvent()
|
||||
{
|
||||
auto& mouse = PS2MouseDevice::the();
|
||||
while (mouse.has_data_available_for_reading()) {
|
||||
signed_byte data[3];
|
||||
ssize_t nread = mouse.read((byte*)data, 3);
|
||||
ASSERT(nread == 3);
|
||||
AbstractScreen::the().on_receive_mouse_data(data[1], -data[2], data[0] & 1, data[0] & 2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user