mirror of
https://github.com/RGBCube/serenity
synced 2025-05-19 00:55:08 +00:00
Rework WindowServer to use select() in its main event loop.
The system can finally idle without burning CPU. :^) There are some issues with scheduling making the mouse cursor sloppy and unresponsive that need to be dealt with.
This commit is contained in:
parent
f7ca6d254d
commit
4fef895eda
15 changed files with 121 additions and 33 deletions
|
@ -4,7 +4,9 @@
|
|||
#include "WSWindowManager.h"
|
||||
#include "WSScreen.h"
|
||||
#include "PS2MouseDevice.h"
|
||||
#include "Scheduler.h"
|
||||
#include <Kernel/Keyboard.h>
|
||||
#include <AK/Bitmap.h>
|
||||
#include "Process.h"
|
||||
|
||||
//#define WSEVENTLOOP_DEBUG
|
||||
|
||||
|
@ -34,10 +36,19 @@ WSEventLoop& WSEventLoop::the()
|
|||
int WSEventLoop::exec()
|
||||
{
|
||||
m_server_process = current;
|
||||
|
||||
m_keyboard_fd = m_server_process->sys$open("/dev/keyboard", O_RDONLY);
|
||||
m_mouse_fd = m_server_process->sys$open("/dev/psaux", O_RDONLY);
|
||||
|
||||
ASSERT(m_keyboard_fd >= 0);
|
||||
ASSERT(m_mouse_fd >= 0);
|
||||
|
||||
m_running = true;
|
||||
for (;;) {
|
||||
|
||||
if (m_queued_events.is_empty())
|
||||
waitForEvent();
|
||||
wait_for_event();
|
||||
|
||||
Vector<QueuedEvent> events;
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
|
@ -69,20 +80,48 @@ void WSEventLoop::post_event(WSEventReceiver* receiver, OwnPtr<WSEvent>&& event)
|
|||
dbgprintf("WSEventLoop::post_event: {%u} << receiver=%p, event=%p\n", m_queued_events.size(), receiver, event.ptr());
|
||||
#endif
|
||||
m_queued_events.append({ receiver, move(event) });
|
||||
|
||||
if (current != m_server_process)
|
||||
m_server_process->request_wakeup();
|
||||
}
|
||||
|
||||
void WSEventLoop::waitForEvent()
|
||||
void WSEventLoop::wait_for_event()
|
||||
{
|
||||
fd_set rfds;
|
||||
memset(&rfds, 0, sizeof(rfds));
|
||||
auto bitmap = Bitmap::wrap((byte*)&rfds, FD_SETSIZE);
|
||||
bitmap.set(m_keyboard_fd, true);
|
||||
bitmap.set(m_mouse_fd, true);
|
||||
Syscall::SC_select_params params;
|
||||
params.nfds = max(m_keyboard_fd, m_mouse_fd) + 1;
|
||||
params.readfds = &rfds;
|
||||
params.writefds = nullptr;
|
||||
params.exceptfds = nullptr;
|
||||
params.timeout = nullptr;
|
||||
int rc = m_server_process->sys$select(¶ms);
|
||||
memory_barrier();
|
||||
if (rc < 0) {
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
//if (bitmap.get(m_keyboard_fd))
|
||||
drain_keyboard();
|
||||
//if (bitmap.get(m_mouse_fd))
|
||||
drain_mouse();
|
||||
}
|
||||
|
||||
void WSEventLoop::drain_mouse()
|
||||
{
|
||||
auto& mouse = PS2MouseDevice::the();
|
||||
auto& screen = WSScreen::the();
|
||||
auto& mouse = PS2MouseDevice::the();
|
||||
bool prev_left_button = screen.left_mouse_button_pressed();
|
||||
bool prev_right_button = screen.right_mouse_button_pressed();
|
||||
int dx = 0;
|
||||
int dy = 0;
|
||||
while (mouse.can_read(*m_server_process)) {
|
||||
signed_byte data[3];
|
||||
ssize_t nread = mouse.read(*m_server_process, (byte*)data, 3);
|
||||
ASSERT(nread == 3);
|
||||
ssize_t nread = mouse.read(*m_server_process, (byte*)data, sizeof(data));
|
||||
ASSERT(nread == sizeof(data));
|
||||
bool left_button = data[0] & 1;
|
||||
bool right_button = data[0] & 2;
|
||||
dx += data[1];
|
||||
|
@ -96,3 +135,18 @@ void WSEventLoop::waitForEvent()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WSEventLoop::drain_keyboard()
|
||||
{
|
||||
auto& screen = WSScreen::the();
|
||||
auto& keyboard = Keyboard::the();
|
||||
while (keyboard.can_read(*m_server_process)) {
|
||||
byte data[2];
|
||||
ssize_t nread = keyboard.read(*m_server_process, (byte*)data, sizeof(data));
|
||||
ASSERT(nread == sizeof(data));
|
||||
Keyboard::Key key;
|
||||
key.character = data[0];
|
||||
key.modifiers = data[1];
|
||||
screen.on_receive_keyboard_data(key);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue