2019-09-14 04:19:05 -03:00
|
|
|
#include "WSClipboard.h"
|
2019-06-07 06:47:19 -03:00
|
|
|
#include <Kernel/KeyCode.h>
|
|
|
|
|
#include <Kernel/MousePacket.h>
|
2019-07-27 05:53:50 -03:00
|
|
|
#include <LibCore/CLocalSocket.h>
|
2019-04-14 00:15:22 -03:00
|
|
|
#include <LibCore/CObject.h>
|
2019-02-15 06:14:21 -02:00
|
|
|
#include <WindowServer/WSAPITypes.h>
|
2019-06-07 06:47:19 -03:00
|
|
|
#include <WindowServer/WSClientConnection.h>
|
2019-03-31 18:52:02 -03:00
|
|
|
#include <WindowServer/WSCursor.h>
|
2019-06-07 06:47:19 -03:00
|
|
|
#include <WindowServer/WSEvent.h>
|
|
|
|
|
#include <WindowServer/WSEventLoop.h>
|
|
|
|
|
#include <WindowServer/WSScreen.h>
|
|
|
|
|
#include <WindowServer/WSWindowManager.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <stdio.h>
|
2019-04-14 00:15:22 -03:00
|
|
|
#include <sys/select.h>
|
2019-06-07 06:47:19 -03:00
|
|
|
#include <sys/socket.h>
|
2019-04-14 00:15:22 -03:00
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <unistd.h>
|
2019-01-16 13:03:50 -02:00
|
|
|
|
2019-03-01 06:51:58 -03:00
|
|
|
//#define WSMESSAGELOOP_DEBUG
|
2019-01-16 13:03:50 -02:00
|
|
|
|
2019-04-14 00:23:37 -03:00
|
|
|
WSEventLoop::WSEventLoop()
|
2019-09-21 05:46:55 -03:00
|
|
|
: m_server(CLocalServer::construct())
|
2019-01-16 13:03:50 -02:00
|
|
|
{
|
2019-02-16 21:13:47 -02:00
|
|
|
m_keyboard_fd = open("/dev/keyboard", O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
|
|
|
|
m_mouse_fd = open("/dev/psaux", O_RDONLY | O_NONBLOCK | O_CLOEXEC);
|
2019-01-16 14:20:58 -02:00
|
|
|
|
2019-11-26 13:30:35 -03:00
|
|
|
bool ok = m_server->take_over_from_system_server();
|
|
|
|
|
ASSERT(ok);
|
2019-01-16 14:20:58 -02:00
|
|
|
|
2019-09-21 05:46:55 -03:00
|
|
|
m_server->on_ready_to_accept = [this] {
|
|
|
|
|
auto client_socket = m_server->accept();
|
2019-07-27 05:53:50 -03:00
|
|
|
if (!client_socket) {
|
|
|
|
|
dbg() << "WindowServer: accept failed.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
static int s_next_client_id = 0;
|
|
|
|
|
int client_id = ++s_next_client_id;
|
|
|
|
|
IPC::Server::new_connection_for_client<WSClientConnection>(*client_socket, client_id);
|
|
|
|
|
};
|
2019-02-14 14:18:35 -02:00
|
|
|
|
2019-01-16 14:20:58 -02:00
|
|
|
ASSERT(m_keyboard_fd >= 0);
|
|
|
|
|
ASSERT(m_mouse_fd >= 0);
|
2019-07-13 14:42:03 -03:00
|
|
|
|
2019-09-21 10:18:12 -03:00
|
|
|
m_keyboard_notifier = CNotifier::construct(m_keyboard_fd, CNotifier::Read);
|
2019-07-17 06:09:09 -03:00
|
|
|
m_keyboard_notifier->on_ready_to_read = [this] { drain_keyboard(); };
|
|
|
|
|
|
2019-09-21 10:18:12 -03:00
|
|
|
m_mouse_notifier = CNotifier::construct(m_mouse_fd, CNotifier::Read);
|
2019-07-17 06:09:09 -03:00
|
|
|
m_mouse_notifier->on_ready_to_read = [this] { drain_mouse(); };
|
2019-09-14 04:19:05 -03:00
|
|
|
|
|
|
|
|
WSClipboard::the().on_content_change = [&] {
|
|
|
|
|
WSClientConnection::for_each_client([&](auto& client) {
|
|
|
|
|
client.notify_about_clipboard_contents_changed();
|
|
|
|
|
});
|
|
|
|
|
};
|
2019-02-13 06:10:32 -02:00
|
|
|
}
|
|
|
|
|
|
2019-04-14 00:23:37 -03:00
|
|
|
WSEventLoop::~WSEventLoop()
|
2019-02-13 06:10:32 -02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-14 00:23:37 -03:00
|
|
|
void WSEventLoop::drain_mouse()
|
2019-01-16 13:03:50 -02:00
|
|
|
{
|
|
|
|
|
auto& screen = WSScreen::the();
|
2019-03-05 10:11:46 -03:00
|
|
|
unsigned prev_buttons = screen.mouse_button_state();
|
2019-01-16 13:03:50 -02:00
|
|
|
int dx = 0;
|
|
|
|
|
int dy = 0;
|
2019-05-13 14:52:57 -03:00
|
|
|
int dz = 0;
|
2019-03-05 10:11:46 -03:00
|
|
|
unsigned buttons = prev_buttons;
|
2019-02-16 21:13:47 -02:00
|
|
|
for (;;) {
|
2019-03-05 09:59:44 -03:00
|
|
|
MousePacket packet;
|
|
|
|
|
ssize_t nread = read(m_mouse_fd, &packet, sizeof(MousePacket));
|
2019-02-16 21:13:47 -02:00
|
|
|
if (nread == 0)
|
|
|
|
|
break;
|
2019-03-05 09:59:44 -03:00
|
|
|
ASSERT(nread == sizeof(packet));
|
2019-03-05 10:11:46 -03:00
|
|
|
buttons = packet.buttons;
|
2019-02-07 05:07:37 -02:00
|
|
|
|
2019-03-05 09:59:44 -03:00
|
|
|
dx += packet.dx;
|
|
|
|
|
dy += -packet.dy;
|
2019-05-13 14:52:57 -03:00
|
|
|
dz += packet.dz;
|
2019-03-05 10:11:46 -03:00
|
|
|
if (buttons != prev_buttons) {
|
2019-05-13 14:52:57 -03:00
|
|
|
screen.on_receive_mouse_data(dx, dy, dz, buttons);
|
2019-01-16 13:03:50 -02:00
|
|
|
dx = 0;
|
|
|
|
|
dy = 0;
|
2019-05-13 14:52:57 -03:00
|
|
|
dz = 0;
|
2019-03-05 10:11:46 -03:00
|
|
|
prev_buttons = buttons;
|
2019-01-16 13:03:50 -02:00
|
|
|
}
|
|
|
|
|
}
|
2019-05-13 14:52:57 -03:00
|
|
|
if (dx || dy || dz)
|
|
|
|
|
screen.on_receive_mouse_data(dx, dy, dz, buttons);
|
2019-01-16 13:03:50 -02:00
|
|
|
}
|
2019-01-16 14:20:58 -02:00
|
|
|
|
2019-04-14 00:23:37 -03:00
|
|
|
void WSEventLoop::drain_keyboard()
|
2019-01-16 14:20:58 -02:00
|
|
|
{
|
|
|
|
|
auto& screen = WSScreen::the();
|
2019-02-16 21:13:47 -02:00
|
|
|
for (;;) {
|
|
|
|
|
KeyEvent event;
|
2019-07-03 16:17:35 -03:00
|
|
|
ssize_t nread = read(m_keyboard_fd, (u8*)&event, sizeof(KeyEvent));
|
2019-02-16 21:13:47 -02:00
|
|
|
if (nread == 0)
|
|
|
|
|
break;
|
|
|
|
|
ASSERT(nread == sizeof(KeyEvent));
|
2019-01-21 04:05:31 -02:00
|
|
|
screen.on_receive_keyboard_data(event);
|
2019-01-16 14:20:58 -02:00
|
|
|
}
|
|
|
|
|
}
|