1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:27:35 +00:00

Port WSClientConnection to CIPCServerSideClient

This commit is contained in:
Robin Burchell 2019-07-17 10:31:52 +02:00 committed by Andreas Kling
parent edcbba9e98
commit 6eaa6826fa
6 changed files with 65 additions and 191 deletions

View file

@ -174,7 +174,7 @@ protected:
CObject::event(event); CObject::event(event);
} }
virtual bool handle_message(const ClientMessage&, const ByteBuffer& = {}) = 0; virtual bool handle_message(const ClientMessage&, const ByteBuffer&& = {}) = 0;
private: private:
// TODO: A way to create some kind of CIODevice with an open FD would be nice. // TODO: A way to create some kind of CIODevice with an open FD would be nice.

View file

@ -11,7 +11,7 @@ public:
explicit ASClientConnection(int fd, int client_id, ASMixer& mixer); explicit ASClientConnection(int fd, int client_id, ASMixer& mixer);
~ASClientConnection() override; ~ASClientConnection() override;
void send_greeting() override; void send_greeting() override;
bool handle_message(const ASAPI_ClientMessage&, const ByteBuffer& = {}) override; bool handle_message(const ASAPI_ClientMessage&, const ByteBuffer&& = {}) override;
const char* class_name() const override { return "ASClientConnection"; } const char* class_name() const override { return "ASClientConnection"; }
private: private:

View file

@ -39,34 +39,32 @@ WSClientConnection* WSClientConnection::from_client_id(int client_id)
return (*it).value; return (*it).value;
} }
WSClientConnection::WSClientConnection(int fd) WSClientConnection::WSClientConnection(int fd, int client_id)
: m_fd(fd) : CIPCServerSideClient(fd, client_id)
{ {
static int s_next_client_id = 0;
m_client_id = ++s_next_client_id;
if (!s_connections) if (!s_connections)
s_connections = new HashMap<int, WSClientConnection*>; s_connections = new HashMap<int, WSClientConnection*>;
s_connections->set(m_client_id, this); s_connections->set(client_id, this);
WSAPI_ServerMessage message;
message.type = WSAPI_ServerMessage::Type::Greeting;
message.greeting.server_pid = getpid();
message.greeting.your_client_id = m_client_id;
message.greeting.screen_rect = WSScreen::the().rect();
post_message(message);
} }
WSClientConnection::~WSClientConnection() WSClientConnection::~WSClientConnection()
{ {
s_connections->remove(m_client_id); s_connections->remove(client_id());
int rc = close(m_fd); }
ASSERT(rc == 0);
void WSClientConnection::send_greeting()
{
WSAPI_ServerMessage message;
message.type = WSAPI_ServerMessage::Type::Greeting;
message.greeting.server_pid = getpid();
message.greeting.your_client_id = client_id();
message.greeting.screen_rect = WSScreen::the().rect();
post_message(message);
} }
void WSClientConnection::post_error(const String& error_message) void WSClientConnection::post_error(const String& error_message)
{ {
dbgprintf("WSClientConnection::post_error: client_id=%d: %s\n", m_client_id, error_message.characters()); dbgprintf("WSClientConnection::post_error: client_id=%d: %s\n", client_id(), error_message.characters());
WSAPI_ServerMessage message; WSAPI_ServerMessage message;
message.type = WSAPI_ServerMessage::Type::Error; message.type = WSAPI_ServerMessage::Type::Error;
ASSERT(error_message.length() < (ssize_t)sizeof(message.text)); ASSERT(error_message.length() < (ssize_t)sizeof(message.text));
@ -75,45 +73,6 @@ void WSClientConnection::post_error(const String& error_message)
post_message(message); post_message(message);
} }
void WSClientConnection::post_message(const WSAPI_ServerMessage& message, const ByteBuffer& extra_data)
{
if (!extra_data.is_empty())
const_cast<WSAPI_ServerMessage&>(message).extra_size = extra_data.size();
struct iovec iov[2];
int iov_count = 1;
iov[0].iov_base = const_cast<WSAPI_ServerMessage*>(&message);
iov[0].iov_len = sizeof(message);
if (!extra_data.is_empty()) {
iov[1].iov_base = const_cast<u8*>(extra_data.data());
iov[1].iov_len = extra_data.size();
++iov_count;
}
int nwritten = writev(m_fd, iov, iov_count);
if (nwritten < 0) {
switch (errno) {
case EPIPE:
dbgprintf("WSClientConnection::post_message: Disconnected from peer.\n");
delete_later();
return;
break;
case EAGAIN:
dbgprintf("WSClientConnection::post_message: Client buffer overflowed.\n");
did_misbehave();
return;
break;
default:
perror("WSClientConnection::post_message writev");
ASSERT_NOT_REACHED();
}
}
ASSERT(nwritten == (int)(sizeof(message) + extra_data.size()));
}
void WSClientConnection::notify_about_new_screen_rect(const Rect& rect) void WSClientConnection::notify_about_new_screen_rect(const Rect& rect)
{ {
WSAPI_ServerMessage message; WSAPI_ServerMessage message;
@ -129,21 +88,7 @@ void WSClientConnection::event(CEvent& event)
return; return;
} }
if (event.type() == WSEvent::WM_ClientDisconnected) { CIPCServerSideClient::event(event);
int client_id = static_cast<const WSClientDisconnectedNotification&>(event).client_id();
dbgprintf("WSClientConnection: Client disconnected: %d\n", client_id);
delete this;
return;
}
CObject::event(event);
}
void WSClientConnection::did_misbehave()
{
dbgprintf("WSClientConnection{%p} (id=%d, pid=%d) misbehaved, disconnecting.\n", this, m_client_id, m_pid);
// FIXME: We should make sure we avoid processing any further messages from this client.
delete_later();
} }
static Vector<Rect, 32> get_rects(const WSAPI_ClientMessage& message, const ByteBuffer& extra_data) static Vector<Rect, 32> get_rects(const WSAPI_ClientMessage& message, const ByteBuffer& extra_data)
@ -162,84 +107,46 @@ static Vector<Rect, 32> get_rects(const WSAPI_ClientMessage& message, const Byte
return rects; return rects;
} }
void WSClientConnection::on_ready_read() bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, const ByteBuffer&& extra_data)
{
unsigned messages_received = 0;
for (;;) {
WSAPI_ClientMessage message;
// FIXME: Don't go one message at a time, that's so much context switching, oof.
ssize_t nread = recv(fd(), &message, sizeof(WSAPI_ClientMessage), MSG_DONTWAIT);
if (nread == 0 || (nread == -1 && errno == EAGAIN)) {
if (!messages_received)
CEventLoop::current().post_event(*this, make<WSClientDisconnectedNotification>(client_id()));
break;
}
if (nread < 0) {
perror("recv");
ASSERT_NOT_REACHED();
}
ByteBuffer extra_data;
if (message.extra_size) {
if (message.extra_size >= 32768) {
dbgprintf("message.extra_size is way too large\n");
return did_misbehave();
}
extra_data = ByteBuffer::create_uninitialized(message.extra_size);
// FIXME: We should allow this to time out. Maybe use a socket timeout?
int extra_nread = read(fd(), extra_data.data(), extra_data.size());
if (extra_nread != (int)message.extra_size) {
dbgprintf("extra_nread(%d) != extra_size(%d)\n", extra_nread, extra_data.size());
if (extra_nread < 0)
perror("read");
return did_misbehave();
}
}
if (!handle_message(message, move(extra_data)))
return;
++messages_received;
}
}
bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, ByteBuffer&& extra_data)
{ {
switch (message.type) { switch (message.type) {
case WSAPI_ClientMessage::Type::Greeting: case WSAPI_ClientMessage::Type::Greeting:
set_client_pid(message.greeting.client_pid); set_client_pid(message.greeting.client_pid);
break; break;
case WSAPI_ClientMessage::Type::CreateMenubar: case WSAPI_ClientMessage::Type::CreateMenubar:
CEventLoop::current().post_event(*this, make<WSAPICreateMenubarRequest>(m_client_id)); CEventLoop::current().post_event(*this, make<WSAPICreateMenubarRequest>(client_id()));
break; break;
case WSAPI_ClientMessage::Type::DestroyMenubar: case WSAPI_ClientMessage::Type::DestroyMenubar:
CEventLoop::current().post_event(*this, make<WSAPIDestroyMenubarRequest>(m_client_id, message.menu.menubar_id)); CEventLoop::current().post_event(*this, make<WSAPIDestroyMenubarRequest>(client_id(), message.menu.menubar_id));
break; break;
case WSAPI_ClientMessage::Type::SetApplicationMenubar: case WSAPI_ClientMessage::Type::SetApplicationMenubar:
CEventLoop::current().post_event(*this, make<WSAPISetApplicationMenubarRequest>(m_client_id, message.menu.menubar_id)); CEventLoop::current().post_event(*this, make<WSAPISetApplicationMenubarRequest>(client_id(), message.menu.menubar_id));
break; break;
case WSAPI_ClientMessage::Type::AddMenuToMenubar: case WSAPI_ClientMessage::Type::AddMenuToMenubar:
CEventLoop::current().post_event(*this, make<WSAPIAddMenuToMenubarRequest>(m_client_id, message.menu.menubar_id, message.menu.menu_id)); CEventLoop::current().post_event(*this, make<WSAPIAddMenuToMenubarRequest>(client_id(), message.menu.menubar_id, message.menu.menu_id));
break; break;
case WSAPI_ClientMessage::Type::CreateMenu: case WSAPI_ClientMessage::Type::CreateMenu:
if (message.text_length > (int)sizeof(message.text)) { if (message.text_length > (int)sizeof(message.text)) {
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPICreateMenuRequest>(m_client_id, String(message.text, message.text_length))); CEventLoop::current().post_event(*this, make<WSAPICreateMenuRequest>(client_id(), String(message.text, message.text_length)));
break; break;
case WSAPI_ClientMessage::Type::PopupMenu: case WSAPI_ClientMessage::Type::PopupMenu:
CEventLoop::current().post_event(*this, make<WSAPIPopupMenuRequest>(m_client_id, message.menu.menu_id, message.menu.position)); CEventLoop::current().post_event(*this, make<WSAPIPopupMenuRequest>(client_id(), message.menu.menu_id, message.menu.position));
break; break;
case WSAPI_ClientMessage::Type::DismissMenu: case WSAPI_ClientMessage::Type::DismissMenu:
CEventLoop::current().post_event(*this, make<WSAPIDismissMenuRequest>(m_client_id, message.menu.menu_id)); CEventLoop::current().post_event(*this, make<WSAPIDismissMenuRequest>(client_id(), message.menu.menu_id));
break; break;
case WSAPI_ClientMessage::Type::SetWindowIcon: case WSAPI_ClientMessage::Type::SetWindowIcon:
if (message.text_length > (int)sizeof(message.text)) { if (message.text_length > (int)sizeof(message.text)) {
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPISetWindowIconRequest>(m_client_id, message.window_id, String(message.text, message.text_length))); CEventLoop::current().post_event(*this, make<WSAPISetWindowIconRequest>(client_id(), message.window_id, String(message.text, message.text_length)));
break; break;
case WSAPI_ClientMessage::Type::DestroyMenu: case WSAPI_ClientMessage::Type::DestroyMenu:
CEventLoop::current().post_event(*this, make<WSAPIDestroyMenuRequest>(m_client_id, message.menu.menu_id)); CEventLoop::current().post_event(*this, make<WSAPIDestroyMenuRequest>(client_id(), message.menu.menu_id));
break; break;
case WSAPI_ClientMessage::Type::AddMenuItem: case WSAPI_ClientMessage::Type::AddMenuItem:
if (message.text_length > (int)sizeof(message.text)) { if (message.text_length > (int)sizeof(message.text)) {
@ -250,7 +157,7 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, Byte
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPIAddMenuItemRequest>(m_client_id, message.menu.menu_id, message.menu.identifier, String(message.text, message.text_length), String(message.menu.shortcut_text, message.menu.shortcut_text_length), message.menu.enabled, message.menu.checkable, message.menu.checked)); CEventLoop::current().post_event(*this, make<WSAPIAddMenuItemRequest>(client_id(), message.menu.menu_id, message.menu.identifier, String(message.text, message.text_length), String(message.menu.shortcut_text, message.menu.shortcut_text_length), message.menu.enabled, message.menu.checkable, message.menu.checked));
break; break;
case WSAPI_ClientMessage::Type::UpdateMenuItem: case WSAPI_ClientMessage::Type::UpdateMenuItem:
if (message.text_length > (int)sizeof(message.text)) { if (message.text_length > (int)sizeof(message.text)) {
@ -261,10 +168,10 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, Byte
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPIUpdateMenuItemRequest>(m_client_id, message.menu.menu_id, message.menu.identifier, String(message.text, message.text_length), String(message.menu.shortcut_text, message.menu.shortcut_text_length), message.menu.enabled, message.menu.checkable, message.menu.checked)); CEventLoop::current().post_event(*this, make<WSAPIUpdateMenuItemRequest>(client_id(), message.menu.menu_id, message.menu.identifier, String(message.text, message.text_length), String(message.menu.shortcut_text, message.menu.shortcut_text_length), message.menu.enabled, message.menu.checkable, message.menu.checked));
break; break;
case WSAPI_ClientMessage::Type::AddMenuSeparator: case WSAPI_ClientMessage::Type::AddMenuSeparator:
CEventLoop::current().post_event(*this, make<WSAPIAddMenuSeparatorRequest>(m_client_id, message.menu.menu_id)); CEventLoop::current().post_event(*this, make<WSAPIAddMenuSeparatorRequest>(client_id(), message.menu.menu_id));
break; break;
case WSAPI_ClientMessage::Type::CreateWindow: { case WSAPI_ClientMessage::Type::CreateWindow: {
if (message.text_length > (int)sizeof(message.text)) { if (message.text_length > (int)sizeof(message.text)) {
@ -303,7 +210,7 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, Byte
} }
CEventLoop::current().post_event(*this, CEventLoop::current().post_event(*this,
make<WSAPICreateWindowRequest>(m_client_id, make<WSAPICreateWindowRequest>(client_id(),
message.window.rect, message.window.rect,
String(message.text, message.text_length), String(message.text, message.text_length),
message.window.has_alpha_channel, message.window.has_alpha_channel,
@ -319,29 +226,29 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, Byte
break; break;
} }
case WSAPI_ClientMessage::Type::DestroyWindow: case WSAPI_ClientMessage::Type::DestroyWindow:
CEventLoop::current().post_event(*this, make<WSAPIDestroyWindowRequest>(m_client_id, message.window_id)); CEventLoop::current().post_event(*this, make<WSAPIDestroyWindowRequest>(client_id(), message.window_id));
break; break;
case WSAPI_ClientMessage::Type::SetWindowTitle: case WSAPI_ClientMessage::Type::SetWindowTitle:
if (message.text_length > (int)sizeof(message.text)) { if (message.text_length > (int)sizeof(message.text)) {
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPISetWindowTitleRequest>(m_client_id, message.window_id, String(message.text, message.text_length))); CEventLoop::current().post_event(*this, make<WSAPISetWindowTitleRequest>(client_id(), message.window_id, String(message.text, message.text_length)));
break; break;
case WSAPI_ClientMessage::Type::GetWindowTitle: case WSAPI_ClientMessage::Type::GetWindowTitle:
CEventLoop::current().post_event(*this, make<WSAPIGetWindowTitleRequest>(m_client_id, message.window_id)); CEventLoop::current().post_event(*this, make<WSAPIGetWindowTitleRequest>(client_id(), message.window_id));
break; break;
case WSAPI_ClientMessage::Type::SetWindowRect: case WSAPI_ClientMessage::Type::SetWindowRect:
CEventLoop::current().post_event(*this, make<WSAPISetWindowRectRequest>(m_client_id, message.window_id, message.window.rect)); CEventLoop::current().post_event(*this, make<WSAPISetWindowRectRequest>(client_id(), message.window_id, message.window.rect));
break; break;
case WSAPI_ClientMessage::Type::GetWindowRect: case WSAPI_ClientMessage::Type::GetWindowRect:
CEventLoop::current().post_event(*this, make<WSAPIGetWindowRectRequest>(m_client_id, message.window_id)); CEventLoop::current().post_event(*this, make<WSAPIGetWindowRectRequest>(client_id(), message.window_id));
break; break;
case WSAPI_ClientMessage::Type::SetClipboardContents: case WSAPI_ClientMessage::Type::SetClipboardContents:
CEventLoop::current().post_event(*this, make<WSAPISetClipboardContentsRequest>(m_client_id, message.clipboard.shared_buffer_id, message.clipboard.contents_size)); CEventLoop::current().post_event(*this, make<WSAPISetClipboardContentsRequest>(client_id(), message.clipboard.shared_buffer_id, message.clipboard.contents_size));
break; break;
case WSAPI_ClientMessage::Type::GetClipboardContents: case WSAPI_ClientMessage::Type::GetClipboardContents:
CEventLoop::current().post_event(*this, make<WSAPIGetClipboardContentsRequest>(m_client_id)); CEventLoop::current().post_event(*this, make<WSAPIGetClipboardContentsRequest>(client_id()));
break; break;
case WSAPI_ClientMessage::Type::InvalidateRect: { case WSAPI_ClientMessage::Type::InvalidateRect: {
auto rects = get_rects(message, extra_data); auto rects = get_rects(message, extra_data);
@ -349,7 +256,7 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, Byte
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPIInvalidateRectRequest>(m_client_id, message.window_id, rects)); CEventLoop::current().post_event(*this, make<WSAPIInvalidateRectRequest>(client_id(), message.window_id, rects));
break; break;
} }
case WSAPI_ClientMessage::Type::DidFinishPainting: { case WSAPI_ClientMessage::Type::DidFinishPainting: {
@ -358,48 +265,48 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, Byte
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPIDidFinishPaintingNotification>(m_client_id, message.window_id, rects)); CEventLoop::current().post_event(*this, make<WSAPIDidFinishPaintingNotification>(client_id(), message.window_id, rects));
break; break;
} }
case WSAPI_ClientMessage::Type::GetWindowBackingStore: case WSAPI_ClientMessage::Type::GetWindowBackingStore:
CEventLoop::current().post_event(*this, make<WSAPIGetWindowBackingStoreRequest>(m_client_id, message.window_id)); CEventLoop::current().post_event(*this, make<WSAPIGetWindowBackingStoreRequest>(client_id(), message.window_id));
break; break;
case WSAPI_ClientMessage::Type::SetWindowBackingStore: case WSAPI_ClientMessage::Type::SetWindowBackingStore:
CEventLoop::current().post_event(*this, make<WSAPISetWindowBackingStoreRequest>(m_client_id, message.window_id, message.backing.shared_buffer_id, message.backing.size, message.backing.bpp, message.backing.pitch, message.backing.has_alpha_channel, message.backing.flush_immediately)); CEventLoop::current().post_event(*this, make<WSAPISetWindowBackingStoreRequest>(client_id(), message.window_id, message.backing.shared_buffer_id, message.backing.size, message.backing.bpp, message.backing.pitch, message.backing.has_alpha_channel, message.backing.flush_immediately));
break; break;
case WSAPI_ClientMessage::Type::SetGlobalCursorTracking: case WSAPI_ClientMessage::Type::SetGlobalCursorTracking:
CEventLoop::current().post_event(*this, make<WSAPISetGlobalCursorTrackingRequest>(m_client_id, message.window_id, message.value)); CEventLoop::current().post_event(*this, make<WSAPISetGlobalCursorTrackingRequest>(client_id(), message.window_id, message.value));
break; break;
case WSAPI_ClientMessage::Type::SetWallpaper: case WSAPI_ClientMessage::Type::SetWallpaper:
if (message.text_length > (int)sizeof(message.text)) { if (message.text_length > (int)sizeof(message.text)) {
did_misbehave(); did_misbehave();
return false; return false;
} }
CEventLoop::current().post_event(*this, make<WSAPISetWallpaperRequest>(m_client_id, String(message.text, message.text_length))); CEventLoop::current().post_event(*this, make<WSAPISetWallpaperRequest>(client_id(), String(message.text, message.text_length)));
break; break;
case WSAPI_ClientMessage::Type::GetWallpaper: case WSAPI_ClientMessage::Type::GetWallpaper:
CEventLoop::current().post_event(*this, make<WSAPIGetWallpaperRequest>(m_client_id)); CEventLoop::current().post_event(*this, make<WSAPIGetWallpaperRequest>(client_id()));
break; break;
case WSAPI_ClientMessage::Type::SetWindowOverrideCursor: case WSAPI_ClientMessage::Type::SetWindowOverrideCursor:
CEventLoop::current().post_event(*this, make<WSAPISetWindowOverrideCursorRequest>(m_client_id, message.window_id, (WSStandardCursor)message.cursor.cursor)); CEventLoop::current().post_event(*this, make<WSAPISetWindowOverrideCursorRequest>(client_id(), message.window_id, (WSStandardCursor)message.cursor.cursor));
break; break;
case WSAPI_ClientMessage::SetWindowHasAlphaChannel: case WSAPI_ClientMessage::SetWindowHasAlphaChannel:
CEventLoop::current().post_event(*this, make<WSAPISetWindowHasAlphaChannelRequest>(m_client_id, message.window_id, message.value)); CEventLoop::current().post_event(*this, make<WSAPISetWindowHasAlphaChannelRequest>(client_id(), message.window_id, message.value));
break; break;
case WSAPI_ClientMessage::Type::WM_SetActiveWindow: case WSAPI_ClientMessage::Type::WM_SetActiveWindow:
CEventLoop::current().post_event(*this, make<WSWMAPISetActiveWindowRequest>(m_client_id, message.wm.client_id, message.wm.window_id)); CEventLoop::current().post_event(*this, make<WSWMAPISetActiveWindowRequest>(client_id(), message.wm.client_id, message.wm.window_id));
break; break;
case WSAPI_ClientMessage::Type::WM_SetWindowMinimized: case WSAPI_ClientMessage::Type::WM_SetWindowMinimized:
CEventLoop::current().post_event(*this, make<WSWMAPISetWindowMinimizedRequest>(m_client_id, message.wm.client_id, message.wm.window_id, message.wm.minimized)); CEventLoop::current().post_event(*this, make<WSWMAPISetWindowMinimizedRequest>(client_id(), message.wm.client_id, message.wm.window_id, message.wm.minimized));
break; break;
case WSAPI_ClientMessage::Type::WM_StartWindowResize: case WSAPI_ClientMessage::Type::WM_StartWindowResize:
CEventLoop::current().post_event(*this, make<WSWMAPIStartWindowResizeRequest>(m_client_id, message.wm.client_id, message.wm.window_id)); CEventLoop::current().post_event(*this, make<WSWMAPIStartWindowResizeRequest>(client_id(), message.wm.client_id, message.wm.window_id));
break; break;
case WSAPI_ClientMessage::Type::WM_PopupWindowMenu: case WSAPI_ClientMessage::Type::WM_PopupWindowMenu:
CEventLoop::current().post_event(*this, make<WSWMAPIPopupWindowMenuRequest>(m_client_id, message.wm.client_id, message.wm.window_id, message.wm.position)); CEventLoop::current().post_event(*this, make<WSWMAPIPopupWindowMenuRequest>(client_id(), message.wm.client_id, message.wm.window_id, message.wm.position));
break; break;
case WSAPI_ClientMessage::Type::MoveWindowToFront: case WSAPI_ClientMessage::Type::MoveWindowToFront:
CEventLoop::current().post_event(*this, make<WSAPIMoveWindowToFrontRequest>(m_client_id, message.window_id)); CEventLoop::current().post_event(*this, make<WSAPIMoveWindowToFrontRequest>(client_id(), message.window_id));
break; break;
default: default:
break; break;
@ -745,7 +652,7 @@ void WSClientConnection::handle_request(const WSAPIGetClipboardContentsRequest&)
// FIXME: Optimize case where an app is copy/pasting within itself. // FIXME: Optimize case where an app is copy/pasting within itself.
// We can just reuse the SharedBuffer then, since it will have the same peer PID. // We can just reuse the SharedBuffer then, since it will have the same peer PID.
// It would be even nicer if a SharedBuffer could have an arbitrary number of clients.. // It would be even nicer if a SharedBuffer could have an arbitrary number of clients..
RefPtr<SharedBuffer> shared_buffer = SharedBuffer::create(m_pid, WSClipboard::the().size()); RefPtr<SharedBuffer> shared_buffer = SharedBuffer::create(client_pid(), WSClipboard::the().size());
ASSERT(shared_buffer); ASSERT(shared_buffer);
memcpy(shared_buffer->data(), WSClipboard::the().data(), WSClipboard::the().size()); memcpy(shared_buffer->data(), WSClipboard::the().data(), WSClipboard::the().size());
shared_buffer->seal(); shared_buffer->seal();

View file

@ -5,34 +5,28 @@
#include <AK/OwnPtr.h> #include <AK/OwnPtr.h>
#include <AK/WeakPtr.h> #include <AK/WeakPtr.h>
#include <LibCore/CObject.h> #include <LibCore/CObject.h>
#include <LibCore/CIPCServerSideClient.h>
#include <SharedGraphics/GraphicsBitmap.h> #include <SharedGraphics/GraphicsBitmap.h>
#include <WindowServer/WSEvent.h> #include <WindowServer/WSEvent.h>
class WSWindow; class WSWindow;
class WSMenu; class WSMenu;
class WSMenuBar; class WSMenuBar;
struct WSAPI_ServerMessage;
class WSClientConnection final : public CObject { class WSClientConnection final : public CIPCServerSideClient<WSAPI_ServerMessage, WSAPI_ClientMessage> {
public: public:
explicit WSClientConnection(int fd); explicit WSClientConnection(int fd, int client_id);
virtual ~WSClientConnection() override; ~WSClientConnection() override;
void send_greeting() override;
bool handle_message(const WSAPI_ClientMessage&, const ByteBuffer&& = {}) override;
static WSClientConnection* from_client_id(int client_id); static WSClientConnection* from_client_id(int client_id);
static void for_each_client(Function<void(WSClientConnection&)>); static void for_each_client(Function<void(WSClientConnection&)>);
void post_message(const WSAPI_ServerMessage&, const ByteBuffer& = {});
int client_id() const { return m_client_id; }
WSMenuBar* app_menubar() { return m_app_menubar.ptr(); } WSMenuBar* app_menubar() { return m_app_menubar.ptr(); }
int fd() const { return m_fd; }
pid_t pid() const { return m_pid; }
bool is_showing_modal_window() const; bool is_showing_modal_window() const;
void set_client_pid(pid_t pid) { m_pid = pid; }
template<typename Matching, typename Callback> template<typename Matching, typename Callback>
void for_each_window_matching(Matching, Callback); void for_each_window_matching(Matching, Callback);
template<typename Callback> template<typename Callback>
@ -41,14 +35,10 @@ public:
void notify_about_new_screen_rect(const Rect&); void notify_about_new_screen_rect(const Rect&);
void post_paint_message(WSWindow&); void post_paint_message(WSWindow&);
void did_misbehave();
void on_ready_read();
private: private:
virtual void event(CEvent&) override; virtual void event(CEvent&) override;
bool handle_message(const WSAPI_ClientMessage& message, ByteBuffer&& extra_data);
void on_request(const WSAPIClientRequest&); void on_request(const WSAPIClientRequest&);
void handle_request(const WSAPICreateMenubarRequest&); void handle_request(const WSAPICreateMenubarRequest&);
void handle_request(const WSAPIDestroyMenubarRequest&); void handle_request(const WSAPIDestroyMenubarRequest&);
@ -88,10 +78,6 @@ private:
void post_error(const String&); void post_error(const String&);
int m_client_id { 0 };
int m_fd { -1 };
pid_t m_pid { -1 };
HashMap<int, OwnPtr<WSWindow>> m_windows; HashMap<int, OwnPtr<WSWindow>> m_windows;
HashMap<int, OwnPtr<WSMenuBar>> m_menubars; HashMap<int, OwnPtr<WSMenuBar>> m_menubars;
HashMap<int, OwnPtr<WSMenu>> m_menus; HashMap<int, OwnPtr<WSMenu>> m_menus;

View file

@ -12,9 +12,8 @@
class WSEvent : public CEvent { class WSEvent : public CEvent {
public: public:
enum Type { enum Type {
Invalid = 2000, Invalid = 3000,
WM_DeferredCompose, WM_DeferredCompose,
WM_ClientDisconnected,
MouseMove, MouseMove,
MouseDown, MouseDown,
MouseDoubleClick, MouseDoubleClick,
@ -85,20 +84,6 @@ public:
bool is_key_event() const { return type() == KeyUp || type() == KeyDown; } bool is_key_event() const { return type() == KeyUp || type() == KeyDown; }
}; };
class WSClientDisconnectedNotification : public WSEvent {
public:
explicit WSClientDisconnectedNotification(int client_id)
: WSEvent(WM_ClientDisconnected)
, m_client_id(client_id)
{
}
int client_id() const { return m_client_id; }
private:
int m_client_id { 0 };
};
class WSAPIClientRequest : public WSEvent { class WSAPIClientRequest : public WSEvent {
public: public:
WSAPIClientRequest(Type type, int client_id) WSAPIClientRequest(Type type, int client_id)

View file

@ -54,7 +54,10 @@ void WSEventLoop::drain_server()
if (client_fd < 0) { if (client_fd < 0) {
dbgprintf("WindowServer: accept() failed: %s\n", strerror(errno)); dbgprintf("WindowServer: accept() failed: %s\n", strerror(errno));
} else { } else {
new WSClientConnection(client_fd); static int s_next_client_id = 0;
int client_id = ++s_next_client_id;
new WSClientConnection(client_fd, client_id);
} }
} }
@ -111,9 +114,6 @@ void WSEventLoop::add_file_descriptors_for_select(fd_set& fds, int& max_fd_added
}; };
add_fd_to_set(m_keyboard_fd, fds); add_fd_to_set(m_keyboard_fd, fds);
add_fd_to_set(m_mouse_fd, fds); add_fd_to_set(m_mouse_fd, fds);
WSClientConnection::for_each_client([&](WSClientConnection& client) {
add_fd_to_set(client.fd(), fds);
});
} }
void WSEventLoop::process_file_descriptors_after_select(const fd_set& fds) void WSEventLoop::process_file_descriptors_after_select(const fd_set& fds)
@ -122,9 +122,5 @@ void WSEventLoop::process_file_descriptors_after_select(const fd_set& fds)
drain_keyboard(); drain_keyboard();
if (FD_ISSET(m_mouse_fd, &fds)) if (FD_ISSET(m_mouse_fd, &fds))
drain_mouse(); drain_mouse();
WSClientConnection::for_each_client([&](WSClientConnection& client) {
if (FD_ISSET(client.fd(), &fds))
client.on_ready_read();
});
} }