|
@@ -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);
|
|
|
+ }
|
|
|
+}
|