From 272d65e3e2ed32981114d89df26d9154e51fb47e Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Mon, 2 Dec 2019 09:33:37 +0100 Subject: [PATCH] WindowServer: Port to the new IPC system This patch introduces code generation for the WindowServer IPC with its clients. The client/server endpoints are defined by the two .ipc files in Servers/WindowServer/: WindowServer.ipc and WindowClient.ipc It now becomes significantly easier to add features and capabilities to WindowServer since you don't have to know nearly as much about all the intricate paths that IPC messages take between LibGUI and WSWindow. The new system also uses significantly less IPC bandwidth since we're now doing packed serialization instead of passing fixed-sized structs of ~600 bytes for each message. Some repaint coalescing optimizations are lost in this conversion and we'll need to look at how to implement those in the new world. The old CoreIPC::Client::Connection and CoreIPC::Server::Connection classes are removed by this patch and replaced by use of ConnectionNG, which will be renamed eventually. Goodbye, old WindowServer IPC. You served us well :^) --- .../DisplayProperties/DisplayProperties.cpp | 6 +- Applications/Taskbar/TaskbarButton.cpp | 8 +- Applications/Taskbar/TaskbarWindow.cpp | 1 - Applications/Taskbar/WindowList.cpp | 13 +- Demos/Fire/Makefile | 2 +- Demos/HelloWorld/Makefile | 2 +- Demos/HelloWorld2/Makefile | 2 +- Demos/WidgetGallery/Makefile | 2 +- DevTools/IPCCompiler/main.cpp | 105 ++- DevTools/Inspector/Makefile | 2 +- DevTools/VisualBuilder/Makefile | 2 +- Games/Minesweeper/Makefile | 2 +- Games/Snake/Makefile | 2 +- Kernel/Process.cpp | 13 +- Kernel/makeall.sh | 4 +- Libraries/LibCore/CoreIPCClient.h | 248 +----- Libraries/LibCore/CoreIPCServer.h | 192 ---- Libraries/LibGUI/GApplication.cpp | 1 - Libraries/LibGUI/GClipboard.cpp | 27 +- Libraries/LibGUI/GDesktop.cpp | 14 +- Libraries/LibGUI/GMenu.cpp | 78 +- Libraries/LibGUI/GMenuBar.cpp | 21 +- Libraries/LibGUI/GMenuItem.cpp | 24 +- Libraries/LibGUI/GResizeCorner.cpp | 1 - Libraries/LibGUI/GWindow.cpp | 153 +--- Libraries/LibGUI/GWindowServerConnection.cpp | 481 +++++----- Libraries/LibGUI/GWindowServerConnection.h | 55 +- Servers/WindowServer/Makefile | 10 +- Servers/WindowServer/WSAPITypes.h | 328 ------- Servers/WindowServer/WSClientConnection.cpp | 824 +++++------------- Servers/WindowServer/WSClientConnection.h | 83 +- Servers/WindowServer/WSEvent.h | 699 --------------- Servers/WindowServer/WSEventLoop.cpp | 3 +- Servers/WindowServer/WSEventLoop.h | 1 - Servers/WindowServer/WSMenu.cpp | 9 +- Servers/WindowServer/WSWindow.cpp | 154 ++-- Servers/WindowServer/WSWindow.h | 9 +- Servers/WindowServer/WSWindowManager.cpp | 9 +- Servers/WindowServer/WSWindowManager.h | 2 - Servers/WindowServer/WindowClient.ipc | 30 + Servers/WindowServer/WindowServer.ipc | 68 ++ Servers/WindowServer/main.cpp | 6 + 42 files changed, 843 insertions(+), 2853 deletions(-) delete mode 100644 Servers/WindowServer/WSAPITypes.h create mode 100644 Servers/WindowServer/WindowClient.ipc create mode 100644 Servers/WindowServer/WindowServer.ipc diff --git a/Applications/DisplayProperties/DisplayProperties.cpp b/Applications/DisplayProperties/DisplayProperties.cpp index 6f3a348a5e9..0594b45be59 100644 --- a/Applications/DisplayProperties/DisplayProperties.cpp +++ b/Applications/DisplayProperties/DisplayProperties.cpp @@ -177,12 +177,8 @@ void DisplayPropertiesWidget::send_settings_to_window_server(int tab_index) builder.append(m_selected_wallpaper); GDesktop::the().set_wallpaper(builder.to_string()); } else if (tab_index == TabIndices::Settings) { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetResolution; dbg() << "Attempting to set resolution " << m_selected_resolution; - request.wm_conf.resolution = { m_selected_resolution.width(), m_selected_resolution.height() }; - auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetResolution); - ASSERT(response.value == 1); + GWindowServerConnection::the().send_sync(m_selected_resolution); } else { dbg() << "Invalid tab index " << tab_index; } diff --git a/Applications/Taskbar/TaskbarButton.cpp b/Applications/Taskbar/TaskbarButton.cpp index 4951e740def..d1c1d6ae943 100644 --- a/Applications/Taskbar/TaskbarButton.cpp +++ b/Applications/Taskbar/TaskbarButton.cpp @@ -1,7 +1,6 @@ #include "TaskbarButton.h" #include #include -#include TaskbarButton::TaskbarButton(const WindowIdentifier& identifier, GWidget* parent) : GButton(parent) @@ -15,10 +14,5 @@ TaskbarButton::~TaskbarButton() void TaskbarButton::context_menu_event(GContextMenuEvent&) { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::WM_PopupWindowMenu; - request.wm.client_id = m_identifier.client_id(); - request.wm.window_id = m_identifier.window_id(); - request.wm.position = screen_relative_rect().location(); - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().post_message(WindowServer::WM_PopupWindowMenu(m_identifier.client_id(), m_identifier.window_id(), screen_relative_rect().location())); } diff --git a/Applications/Taskbar/TaskbarWindow.cpp b/Applications/Taskbar/TaskbarWindow.cpp index b096b78b7d2..8213df66981 100644 --- a/Applications/Taskbar/TaskbarWindow.cpp +++ b/Applications/Taskbar/TaskbarWindow.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include //#define EVENT_DEBUG diff --git a/Applications/Taskbar/WindowList.cpp b/Applications/Taskbar/WindowList.cpp index 5ada8724b3c..f7f8278586b 100644 --- a/Applications/Taskbar/WindowList.cpp +++ b/Applications/Taskbar/WindowList.cpp @@ -1,6 +1,5 @@ #include "WindowList.h" #include -#include WindowList& WindowList::the() { @@ -25,18 +24,12 @@ Window& WindowList::ensure_window(const WindowIdentifier& identifier) return *it->value; auto window = make(identifier); window->set_button(aid_create_button(identifier)); - window->button()->on_click = [window = window.ptr(), identifier](GButton&) { - WSAPI_ClientMessage message; + window->button()->on_click = [window = window.ptr(), identifier](auto&) { if (window->is_minimized() || !window->is_active()) { - message.type = WSAPI_ClientMessage::Type::WM_SetActiveWindow; + GWindowServerConnection::the().post_message(WindowServer::WM_SetActiveWindow(identifier.client_id(), identifier.window_id())); } else { - message.type = WSAPI_ClientMessage::Type::WM_SetWindowMinimized; - message.wm.minimized = true; + GWindowServerConnection::the().post_message(WindowServer::WM_SetWindowMinimized(identifier.client_id(), identifier.window_id(), true)); } - message.wm.client_id = identifier.client_id(); - message.wm.window_id = identifier.window_id(); - bool success = GWindowServerConnection::the().post_message_to_server(message); - ASSERT(success); }; auto& window_ref = *window; m_windows.set(identifier, move(window)); diff --git a/Demos/Fire/Makefile b/Demos/Fire/Makefile index 0d5740cfb7f..5859bb36095 100644 --- a/Demos/Fire/Makefile +++ b/Demos/Fire/Makefile @@ -10,7 +10,7 @@ DEFINES += -DUSERLAND all: $(APP) $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Demos/HelloWorld/Makefile b/Demos/HelloWorld/Makefile index 80eaa7a4f49..d2ca89ebfbb 100644 --- a/Demos/HelloWorld/Makefile +++ b/Demos/HelloWorld/Makefile @@ -10,7 +10,7 @@ DEFINES += -DUSERLAND all: $(APP) $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Demos/HelloWorld2/Makefile b/Demos/HelloWorld2/Makefile index f056a27a1d9..aa09fc27072 100644 --- a/Demos/HelloWorld2/Makefile +++ b/Demos/HelloWorld2/Makefile @@ -15,7 +15,7 @@ UI_HelloWorld2.h: HelloWorld2.frm ../../DevTools/FormCompiler/FormCompiler $< > $@ $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Demos/WidgetGallery/Makefile b/Demos/WidgetGallery/Makefile index 3dea837d1e9..86f73384695 100644 --- a/Demos/WidgetGallery/Makefile +++ b/Demos/WidgetGallery/Makefile @@ -10,7 +10,7 @@ DEFINES += -DUSERLAND all: $(APP) $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/DevTools/IPCCompiler/main.cpp b/DevTools/IPCCompiler/main.cpp index d6f795386a6..af09ff831bf 100644 --- a/DevTools/IPCCompiler/main.cpp +++ b/DevTools/IPCCompiler/main.cpp @@ -5,6 +5,8 @@ #include #include +//#define GENERATE_DEBUG_CODE + struct Parameter { String type; String name; @@ -71,7 +73,7 @@ int main(int argc, char** argv) auto consume_specific = [&](char ch) { if (peek() != ch) { - dbg() << "consume_specific: wanted '" << ch << "', but got '" << peek() << "'"; + dbg() << "consume_specific: wanted '" << ch << "', but got '" << peek() << "' at index " << index; } ASSERT(peek() == ch); ++index; @@ -197,6 +199,8 @@ int main(int argc, char** argv) dbg() << "#pragma once"; dbg() << "#include "; dbg() << "#include "; + dbg() << "#include "; + dbg() << "#include "; dbg() << "#include "; dbg() << "#include "; dbg(); @@ -279,17 +283,66 @@ int main(int argc, char** argv) if (parameter.type == "String") { dbg() << " int " << parameter.name << "_length = 0;"; - dbg() << " char* " << parameter.name << "_buffer = nullptr;"; dbg() << " stream >> " << parameter.name << "_length;"; - dbg() << " auto " << parameter.name << "_impl = StringImpl::create_uninitialized(" << parameter.name << "_length, " << parameter.name << "_buffer);"; - dbg() << " for (int i = 0; i < " << parameter.name << "_length; ++i) {"; - dbg() << " stream >> " << parameter.name << "_buffer[i];"; + dbg() << " if (" << parameter.name << "_length == 0) {"; + dbg() << " " << parameter.name << " = String::empty();"; + dbg() << " } else if (" << parameter.name << "_length == -1) {"; + dbg() << " " << parameter.name << " = String();"; + dbg() << " } else {"; + dbg() << " char* " << parameter.name << "_buffer = nullptr;"; + dbg() << " auto " << parameter.name << "_impl = StringImpl::create_uninitialized(" << parameter.name << "_length, " << parameter.name << "_buffer);"; + dbg() << " for (int i = 0; i < " << parameter.name << "_length; ++i) {"; + dbg() << " stream >> " << parameter.name << "_buffer[i];"; + dbg() << " }"; + dbg() << " " << parameter.name << " = *" << parameter.name << "_impl;"; + dbg() << " }"; + } else if (parameter.type == "Color") { + dbg() << " u32 " << parameter.name << "_rgba = 0;"; + dbg() << " stream >> " << parameter.name << "_rgba;"; + dbg() << " " << parameter.name << " = Color::from_rgba(" << parameter.name << "_rgba);"; + } else if (parameter.type == "Size") { + dbg() << " int " << parameter.name << "_width = 0;"; + dbg() << " stream >> " << parameter.name << "_width;"; + dbg() << " int " << parameter.name << "_height = 0;"; + dbg() << " stream >> " << parameter.name << "_height;"; + dbg() << " " << parameter.name << " = { " << parameter.name << "_width, " << parameter.name << "_height };"; + } else if (parameter.type == "Point") { + dbg() << " int " << parameter.name << "_x = 0;"; + dbg() << " stream >> " << parameter.name << "_x;"; + dbg() << " int " << parameter.name << "_y = 0;"; + dbg() << " stream >> " << parameter.name << "_y;"; + dbg() << " " << parameter.name << " = { " << parameter.name << "_x, " << parameter.name << "_y };"; + } else if (parameter.type == "Rect") { + dbg() << " int " << parameter.name << "_x = 0;"; + dbg() << " stream >> " << parameter.name << "_x;"; + dbg() << " int " << parameter.name << "_y = 0;"; + dbg() << " stream >> " << parameter.name << "_y;"; + dbg() << " int " << parameter.name << "_width = 0;"; + dbg() << " stream >> " << parameter.name << "_width;"; + dbg() << " int " << parameter.name << "_height = 0;"; + dbg() << " stream >> " << parameter.name << "_height;"; + dbg() << " " << parameter.name << " = { " << parameter.name << "_x, " << parameter.name << "_y, " << parameter.name << "_width, " << parameter.name << "_height };"; + } else if (parameter.type == "Vector") { + dbg() << " int " << parameter.name << "_size = 0;"; + dbg() << " stream >> " << parameter.name << "_size;"; + dbg() << " for (int i = 0; i < " << parameter.name << "_size; ++i) {"; + dbg() << " int " << parameter.name << "_x = 0;"; + dbg() << " stream >> " << parameter.name << "_x;"; + dbg() << " int " << parameter.name << "_y = 0;"; + dbg() << " stream >> " << parameter.name << "_y;"; + dbg() << " int " << parameter.name << "_width = 0;"; + dbg() << " stream >> " << parameter.name << "_width;"; + dbg() << " int " << parameter.name << "_height = 0;"; + dbg() << " stream >> " << parameter.name << "_height;"; + dbg() << " " << parameter.name << ".empend(" << parameter.name << "_x, " << parameter.name << "_y, " << parameter.name << "_width, " << parameter.name << "_height);"; dbg() << " }"; - dbg() << " " << parameter.name << " = *" << parameter.name << "_impl;"; } else { dbg() << " stream >> " << parameter.name << ";"; } dbg() << " if (stream.handle_read_failure()) {"; +#ifdef GENERATE_DEBUG_CODE + dbg() << " dbg() << \"Failed to decode " << name << "." << parameter.name << "\";"; +#endif dbg() << " return nullptr;"; dbg() << " }"; } @@ -307,14 +360,39 @@ int main(int argc, char** argv) dbg() << " virtual ByteBuffer encode() const override"; dbg() << " {"; // FIXME: Support longer messages: - dbg() << " auto buffer = ByteBuffer::create_uninitialized(1024);"; + dbg() << " auto buffer = ByteBuffer::create_uninitialized(4096);"; dbg() << " BufferStream stream(buffer);"; dbg() << " stream << endpoint_magic();"; dbg() << " stream << (int)MessageID::" << name << ";"; for (auto& parameter : parameters) { if (parameter.type == "String") { - dbg() << " stream << m_" << parameter.name << ".length();"; - dbg() << " stream << m_" << parameter.name << ";"; + dbg() << " if (m_" << parameter.name << ".is_null()) {"; + dbg() << " stream << (i32)-1;"; + dbg() << " } else {"; + dbg() << " stream << m_" << parameter.name << ".length();"; + dbg() << " stream << m_" << parameter.name << ";"; + dbg() << " }"; + } else if (parameter.type == "Color") { + dbg() << " stream << m_" << parameter.name << ".value();"; + } else if (parameter.type == "Size") { + dbg() << " stream << m_" << parameter.name << ".width();"; + dbg() << " stream << m_" << parameter.name << ".height();"; + } else if (parameter.type == "Point") { + dbg() << " stream << m_" << parameter.name << ".x();"; + dbg() << " stream << m_" << parameter.name << ".y();"; + } else if (parameter.type == "Rect") { + dbg() << " stream << m_" << parameter.name << ".x();"; + dbg() << " stream << m_" << parameter.name << ".y();"; + dbg() << " stream << m_" << parameter.name << ".width();"; + dbg() << " stream << m_" << parameter.name << ".height();"; + } else if (parameter.type == "Vector") { + dbg() << " stream << m_" << parameter.name << ".size();"; + dbg() << " for (auto& rect : m_" << parameter.name << ") {"; + dbg() << " stream << rect.x();"; + dbg() << " stream << rect.y();"; + dbg() << " stream << rect.width();"; + dbg() << " stream << rect.height();"; + dbg() << " }"; } else { dbg() << " stream << m_" << parameter.name << ";"; } @@ -356,8 +434,12 @@ int main(int argc, char** argv) dbg() << " BufferStream stream(const_cast(buffer));"; dbg() << " i32 message_endpoint_magic = 0;"; dbg() << " stream >> message_endpoint_magic;"; - dbg() << " if (message_endpoint_magic != " << endpoint.magic << ")"; + dbg() << " if (message_endpoint_magic != " << endpoint.magic << ") {"; +#ifdef GENERATE_DEBUG_CODE + dbg() << " dbg() << \"endpoint magic \" << message_endpoint_magic << \" != " << endpoint.magic << "\";"; +#endif dbg() << " return nullptr;"; + dbg() << " }"; dbg() << " i32 message_id = 0;"; dbg() << " stream >> message_id;"; dbg() << " switch (message_id) {"; @@ -371,6 +453,9 @@ int main(int argc, char** argv) do_decode_message(message.response_name()); } dbg() << " default:"; +#ifdef GENERATE_DEBUG_CODE + dbg() << " dbg() << \"Failed to decode " << endpoint.name << ".(\" << message_id << \")\";"; +#endif dbg() << " return nullptr;"; dbg() << " }"; diff --git a/DevTools/Inspector/Makefile b/DevTools/Inspector/Makefile index 8c62b3864d2..2430dcb4ddb 100644 --- a/DevTools/Inspector/Makefile +++ b/DevTools/Inspector/Makefile @@ -14,7 +14,7 @@ DEFINES += -DUSERLAND all: $(APP) $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/DevTools/VisualBuilder/Makefile b/DevTools/VisualBuilder/Makefile index 45a7b94c11f..5fbb5492c1f 100644 --- a/DevTools/VisualBuilder/Makefile +++ b/DevTools/VisualBuilder/Makefile @@ -16,7 +16,7 @@ DEFINES += -DUSERLAND all: $(APP) $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Games/Minesweeper/Makefile b/Games/Minesweeper/Makefile index 360d9a8bc3a..396deec731c 100644 --- a/Games/Minesweeper/Makefile +++ b/Games/Minesweeper/Makefile @@ -11,7 +11,7 @@ DEFINES += -DUSERLAND all: $(APP) $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Games/Snake/Makefile b/Games/Snake/Makefile index 3c3e15e437b..fea7faf3324 100644 --- a/Games/Snake/Makefile +++ b/Games/Snake/Makefile @@ -11,7 +11,7 @@ DEFINES += -DUSERLAND all: $(APP) $(APP): $(OBJS) - $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lcore -lc + $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lgui -ldraw -lipc -lcore -lc .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 29597f145d7..fc2946b13e4 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1180,6 +1180,9 @@ ssize_t Process::sys$read(int fd, u8* buffer, ssize_t size) int Process::sys$close(int fd) { auto* description = file_description(fd); +#ifdef DEBUG_IO + dbgprintf("%s(%u) sys$close(%d) %p\n", name().characters(), pid(), fd, description); +#endif if (!description) return -EBADF; int rc = description->close(); @@ -1367,10 +1370,10 @@ int Process::sys$open(const Syscall::SC_open_params* params) return -EINVAL; if (!validate_read(path, path_length)) return -EFAULT; -#ifdef DEBUG_IO - dbgprintf("%s(%u) sys$open(\"%s\")\n", name().characters(), pid(), path); -#endif int fd = alloc_fd(); +#ifdef DEBUG_IO + dbgprintf("%s(%u) sys$open(\"%s\") -> %d\n", name().characters(), pid(), path, fd); +#endif if (fd < 0) return fd; auto result = VFS::the().open(path, options, mode & ~umask(), current_directory()); @@ -2141,8 +2144,10 @@ int Process::sys$select(const Syscall::SC_select_params* params) return 0; for (int fd = 0; fd < params->nfds; ++fd) { if (FD_ISSET(fd, fds)) { - if (!file_description(fd)) + if (!file_description(fd)) { + dbg() << *current << " sys$select: Bad fd number " << fd; return -EBADF; + } vector.append(fd); } } diff --git a/Kernel/makeall.sh b/Kernel/makeall.sh index 95c58f5108e..bf41b174921 100755 --- a/Kernel/makeall.sh +++ b/Kernel/makeall.sh @@ -32,10 +32,11 @@ build_targets="$build_targets ../Libraries/LibPthread" build_targets="$build_targets ../Servers/AudioServer" build_targets="$build_targets ../Servers/LookupServer" build_targets="$build_targets ../Servers/ProtocolServer" +build_targets="$build_targets ../Libraries/LibAudio" +build_targets="$build_targets ../Servers/WindowServer" build_targets="$build_targets ../AK" -build_targets="$build_targets ../Libraries/LibAudio" build_targets="$build_targets ../Libraries/LibDraw" build_targets="$build_targets ../Libraries/LibGUI" build_targets="$build_targets ../Libraries/LibHTML" @@ -81,7 +82,6 @@ build_targets="$build_targets ../Games/Snake" build_targets="$build_targets ../Servers/SystemServer" build_targets="$build_targets ../Servers/TTYServer" build_targets="$build_targets ../Servers/TelnetServer" -build_targets="$build_targets ../Servers/WindowServer" build_targets="$build_targets ../Shell" diff --git a/Libraries/LibCore/CoreIPCClient.h b/Libraries/LibCore/CoreIPCClient.h index 0aea1195aee..f8d4d15d019 100644 --- a/Libraries/LibCore/CoreIPCClient.h +++ b/Libraries/LibCore/CoreIPCClient.h @@ -20,232 +20,6 @@ namespace IPC { namespace Client { - class Event : public CEvent { - public: - enum Type { - Invalid = 2000, - PostProcess, - }; - Event() {} - explicit Event(Type type) - : CEvent(type) - { - } - }; - - class PostProcessEvent : public Event { - public: - explicit PostProcessEvent(int client_id) - : Event(PostProcess) - , m_client_id(client_id) - { - } - - int client_id() const { return m_client_id; } - - private: - int m_client_id { 0 }; - }; - - template - class Connection : public CObject { - public: - Connection(const StringView& address) - : m_connection(CLocalSocket::construct(this)) - , m_notifier(CNotifier::construct(m_connection->fd(), CNotifier::Read, this)) - { - // We want to rate-limit our clients - m_connection->set_blocking(true); - m_notifier->on_ready_to_read = [this] { - drain_messages_from_server(); - CEventLoop::current().post_event(*this, make(m_connection->fd())); - }; - - int retries = 100000; - while (retries) { - if (m_connection->connect(CSocketAddress::local(address))) { - break; - } - - dbgprintf("Client::Connection: connect failed: %d, %s\n", errno, strerror(errno)); - usleep(10000); - --retries; - } - ASSERT(m_connection->is_connected()); - } - - virtual void handshake() = 0; - - virtual void event(CEvent& event) override - { - if (event.type() == Event::PostProcess) { - postprocess_bundles(m_unprocessed_bundles); - } else { - CObject::event(event); - } - } - - void set_server_pid(pid_t pid) { m_server_pid = pid; } - pid_t server_pid() const { return m_server_pid; } - void set_my_client_id(int id) { m_my_client_id = id; } - int my_client_id() const { return m_my_client_id; } - - template - bool wait_for_specific_event(MessageType type, ServerMessage& event) - { - // Double check we don't already have the event waiting for us. - // Otherwise we might end up blocked for a while for no reason. - for (ssize_t i = 0; i < m_unprocessed_bundles.size(); ++i) { - if (m_unprocessed_bundles[i].message.type == type) { - event = move(m_unprocessed_bundles[i].message); - m_unprocessed_bundles.remove(i); - CEventLoop::current().post_event(*this, make(m_connection->fd())); - return true; - } - } - for (;;) { - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(m_connection->fd(), &rfds); - int rc = CSyscallUtils::safe_syscall(select, m_connection->fd() + 1, &rfds, nullptr, nullptr, nullptr); - if (rc < 0) { - perror("select"); - } - ASSERT(rc > 0); - ASSERT(FD_ISSET(m_connection->fd(), &rfds)); - bool success = drain_messages_from_server(); - if (!success) - return false; - for (ssize_t i = 0; i < m_unprocessed_bundles.size(); ++i) { - if (m_unprocessed_bundles[i].message.type == type) { - event = move(m_unprocessed_bundles[i].message); - m_unprocessed_bundles.remove(i); - CEventLoop::current().post_event(*this, make(m_connection->fd())); - return true; - } - } - } - } - - bool post_message_to_server(const ClientMessage& message, const ByteBuffer&& extra_data = {}) - { -#if defined(CIPC_DEBUG) - dbg() << "C: -> S " << int(message.type) << " extra " << extra_data.size(); -#endif - if (!extra_data.is_empty()) - const_cast(message).extra_size = extra_data.size(); - - struct iovec iov[2]; - int iov_count = 1; - iov[0].iov_base = const_cast(&message); - iov[0].iov_len = sizeof(message); - - if (!extra_data.is_empty()) { - iov[1].iov_base = const_cast(extra_data.data()); - iov[1].iov_len = extra_data.size(); - ++iov_count; - } - - int nwritten; - - for (;;) { - nwritten = writev(m_connection->fd(), iov, iov_count); - if (nwritten < 0) { - if (errno == EAGAIN) { - sched_yield(); - continue; - } - perror("writev"); - ASSERT_NOT_REACHED(); - } - break; - } - ASSERT((size_t)nwritten == sizeof(message) + extra_data.size()); - - return true; - } - - template - ServerMessage sync_request(const ClientMessage& request, MessageType response_type) - { - bool success = post_message_to_server(request); - ASSERT(success); - - ServerMessage response; - success = wait_for_specific_event(response_type, response); - ASSERT(success); - return response; - } - - template - typename RequestType::ResponseType send_sync(Args&&... args) - { - bool success = post_message_to_server(RequestType(forward(args)...)); - ASSERT(success); - - ServerMessage response; - success = wait_for_specific_event(RequestType::ResponseType::message_type(), response); - ASSERT(success); - return response; - } - - protected: - struct IncomingMessageBundle { - ServerMessage message; - ByteBuffer extra_data; - }; - - virtual void postprocess_bundles(Vector& new_bundles) - { - dbg() << "Client::Connection: " - << " warning: discarding " << new_bundles.size() << " unprocessed bundles; this may not be what you want"; - new_bundles.clear(); - } - - private: - bool drain_messages_from_server() - { - for (;;) { - ServerMessage message; - ssize_t nread = recv(m_connection->fd(), &message, sizeof(ServerMessage), MSG_DONTWAIT); - if (nread < 0) { - if (errno == EAGAIN) { - return true; - } - perror("read"); - exit(1); - return false; - } - if (nread == 0) { - dbgprintf("EOF on IPC fd\n"); - exit(1); - return false; - } - ASSERT(nread == sizeof(message)); - ByteBuffer extra_data; - if (message.extra_size) { - extra_data = ByteBuffer::create_uninitialized(message.extra_size); - int extra_nread = read(m_connection->fd(), extra_data.data(), extra_data.size()); - if (extra_nread < 0) { - perror("read"); - ASSERT_NOT_REACHED(); - } - ASSERT((size_t)extra_nread == message.extra_size); - } -#if defined(CIPC_DEBUG) - dbg() << "C: <- S " << int(message.type) << " extra " << extra_data.size(); -#endif - m_unprocessed_bundles.append({ move(message), move(extra_data) }); - } - } - - RefPtr m_connection; - RefPtr m_notifier; - Vector m_unprocessed_bundles; - int m_server_pid { -1 }; - int m_my_client_id { -1 }; - }; - template class ConnectionNG : public CObject { public: @@ -258,7 +32,6 @@ namespace Client { m_connection->set_blocking(true); m_notifier->on_ready_to_read = [this] { drain_messages_from_server(); - CEventLoop::current().post_event(*this, make(m_connection->fd())); }; int retries = 100000; @@ -276,15 +49,6 @@ namespace Client { virtual void handshake() = 0; - virtual void event(CEvent& event) override - { - if (event.type() == Event::PostProcess) { - postprocess_messages(m_unprocessed_messages); - } else { - CObject::event(event); - } - } - void set_server_pid(pid_t pid) { m_server_pid = pid; } pid_t server_pid() const { return m_server_pid; } void set_my_client_id(int id) { m_my_client_id = id; } @@ -299,7 +63,6 @@ namespace Client { if (m_unprocessed_messages[i]->id() == MessageType::static_message_id()) { auto message = move(m_unprocessed_messages[i]); m_unprocessed_messages.remove(i); - CEventLoop::current().post_event(*this, make(m_connection->fd())); return message; } } @@ -319,14 +82,13 @@ namespace Client { if (m_unprocessed_messages[i]->id() == MessageType::static_message_id()) { auto message = move(m_unprocessed_messages[i]); m_unprocessed_messages.remove(i); - CEventLoop::current().post_event(*this, make(m_connection->fd())); return message; } } } } - bool post_message_to_server(const IMessage& message) + bool post_message(const IMessage& message) { auto buffer = message.encode(); int nwritten = write(m_connection->fd(), buffer.data(), (size_t)buffer.size()); @@ -342,19 +104,13 @@ namespace Client { template OwnPtr send_sync(Args&&... args) { - bool success = post_message_to_server(RequestType(forward(args)...)); + bool success = post_message(RequestType(forward(args)...)); ASSERT(success); auto response = wait_for_specific_message(); ASSERT(response); return response; } - protected: - virtual void postprocess_messages(Vector>& new_bundles) - { - new_bundles.clear(); - } - private: bool drain_messages_from_server() { diff --git a/Libraries/LibCore/CoreIPCServer.h b/Libraries/LibCore/CoreIPCServer.h index af65613fe49..366518ae113 100644 --- a/Libraries/LibCore/CoreIPCServer.h +++ b/Libraries/LibCore/CoreIPCServer.h @@ -49,204 +49,12 @@ namespace Server { int m_client_id { 0 }; }; - template - NonnullRefPtr new_connection_for_client(Args&&... args) - { - auto conn = T::construct(forward(args)...); - conn->send_greeting(); - return conn; - } - template NonnullRefPtr new_connection_ng_for_client(Args&&... args) { return T::construct(forward(args)...) /* arghs */; } - template - class Connection : public CObject { - protected: - Connection(CLocalSocket& socket, int client_id) - : m_socket(socket) - , m_client_id(client_id) - { - add_child(socket); - m_socket->on_ready_to_read = [this] { - drain_client(); - flush_outgoing_messages(); - }; -#if defined(CIPC_DEBUG) - dbg() << "S: Created new Connection " << fd << client_id << " and said hello"; -#endif - } - - public: - ~Connection() - { -#if defined(CIPC_DEBUG) - dbg() << "S: Destroyed Connection " << m_socket->fd() << client_id(); -#endif - } - - void post_message(const ServerMessage& message, const ByteBuffer& extra_data = {}) - { -#if defined(CIPC_DEBUG) - dbg() << "S: -> C " << int(message.type) << " extra " << extra_data.size(); -#endif - flush_outgoing_messages(); - if (try_send_message(message, extra_data)) - return; - if (m_queue.size() >= max_queued_messages) { - dbg() << "Connection::post_message: Client has too many queued messages already, disconnecting it."; - shutdown(); - return; - } - - QueuedMessage queued_message { message, extra_data }; - if (!extra_data.is_empty()) - queued_message.message.extra_size = extra_data.size(); - m_queue.enqueue(move(queued_message)); - } - - bool try_send_message(const ServerMessage& message, const ByteBuffer& extra_data) - { - struct iovec iov[2]; - int iov_count = 1; - - iov[0].iov_base = const_cast(&message); - iov[0].iov_len = sizeof(message); - - if (!extra_data.is_empty()) { - iov[1].iov_base = const_cast(extra_data.data()); - iov[1].iov_len = extra_data.size(); - ++iov_count; - } - - int nwritten = writev(m_socket->fd(), iov, iov_count); - if (nwritten < 0) { - switch (errno) { - case EPIPE: - dbgprintf("Connection::post_message: Disconnected from peer.\n"); - shutdown(); - return false; - case EAGAIN: -#ifdef CIPC_DEBUG - dbg() << "EAGAIN when trying to send WindowServer message, queue size: " << m_queue.size(); -#endif - return false; - default: - perror("Connection::post_message writev"); - ASSERT_NOT_REACHED(); - } - } - - ASSERT(nwritten == (int)(sizeof(message) + extra_data.size())); - return true; - } - - void flush_outgoing_messages() - { - while (!m_queue.is_empty()) { - auto& queued_message = m_queue.head(); - if (!try_send_message(queued_message.message, queued_message.extra_data)) - break; - m_queue.dequeue(); - } - } - - void drain_client() - { - unsigned messages_received = 0; - for (;;) { - ClientMessage message; - // FIXME: Don't go one message at a time, that's so much context switching, oof. - ssize_t nread = recv(m_socket->fd(), &message, sizeof(ClientMessage), MSG_DONTWAIT); - if (nread == 0 || (nread == -1 && errno == EAGAIN)) { - if (!messages_received) { - CEventLoop::current().post_event(*this, make(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(m_socket->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 defined(CIPC_DEBUG) - dbg() << "S: <- C " << int(message.type) << " extra " << extra_data.size(); -#endif - if (!handle_message(message, move(extra_data))) - return; - ++messages_received; - } - } - - void did_misbehave() - { - dbgprintf("Connection{%p} (id=%d, pid=%d) misbehaved, disconnecting.\n", this, client_id(), m_client_pid); - shutdown(); - } - - void shutdown() - { - m_socket->close(); - die(); - } - - int client_id() const { return m_client_id; } - pid_t client_pid() const { return m_client_pid; } - void set_client_pid(pid_t pid) { m_client_pid = pid; } - - // ### having this public is sad - virtual void send_greeting() = 0; - - virtual void die() = 0; - - protected: - void event(CEvent& event) - { - if (event.type() == Event::Disconnected) { - int client_id = static_cast(event).client_id(); - dbgprintf("Connection: Client disconnected: %d\n", client_id); - die(); - return; - } - - CObject::event(event); - } - - virtual bool handle_message(const ClientMessage&, const ByteBuffer&& = {}) = 0; - - private: - RefPtr m_socket; - - struct QueuedMessage { - ServerMessage message; - ByteBuffer extra_data; - }; - - static const int max_queued_messages = 200; - Queue m_queue; - - int m_client_id { -1 }; - int m_client_pid { -1 }; - }; - template class ConnectionNG : public CObject { public: diff --git a/Libraries/LibGUI/GApplication.cpp b/Libraries/LibGUI/GApplication.cpp index e3f9610c83a..d6f070b4b5b 100644 --- a/Libraries/LibGUI/GApplication.cpp +++ b/Libraries/LibGUI/GApplication.cpp @@ -5,7 +5,6 @@ #include #include #include -#include static GApplication* s_the; diff --git a/Libraries/LibGUI/GClipboard.cpp b/Libraries/LibGUI/GClipboard.cpp index dde06f8aa10..3f4117633ed 100644 --- a/Libraries/LibGUI/GClipboard.cpp +++ b/Libraries/LibGUI/GClipboard.cpp @@ -1,7 +1,6 @@ #include #include #include -#include GClipboard& GClipboard::the() { @@ -17,29 +16,25 @@ GClipboard::GClipboard() GClipboard::DataAndType GClipboard::data_and_type() const { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::GetClipboardContents; - auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidGetClipboardContents); - if (response.clipboard.shared_buffer_id < 0) + auto response = GWindowServerConnection::the().send_sync(); + if (response->shared_buffer_id() < 0) return {}; - auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(response.clipboard.shared_buffer_id); + auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(response->shared_buffer_id()); if (!shared_buffer) { dbgprintf("GClipboard::data() failed to attach to the shared buffer\n"); return {}; } - if (response.clipboard.contents_size > shared_buffer->size()) { + if (response->content_size() > shared_buffer->size()) { dbgprintf("GClipboard::data() clipping contents size is greater than shared buffer size\n"); return {}; } - auto data = String((const char*)shared_buffer->data(), response.clipboard.contents_size); - auto type = String(response.text, response.text_length); + auto data = String((const char*)shared_buffer->data(), response->content_size()); + auto type = response->content_type(); return { data, type }; } void GClipboard::set_data(const StringView& data, const String& type) { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetClipboardContents; auto shared_buffer = SharedBuffer::create_with_size(data.length() + 1); if (!shared_buffer) { dbgprintf("GClipboard::set_data() failed to create a shared buffer\n"); @@ -51,16 +46,8 @@ void GClipboard::set_data(const StringView& data, const String& type) ((u8*)shared_buffer->data())[0] = '\0'; shared_buffer->seal(); shared_buffer->share_with(GWindowServerConnection::the().server_pid()); - request.clipboard.shared_buffer_id = shared_buffer->shared_buffer_id(); - request.clipboard.contents_size = data.length(); - ASSERT(type.length() < (ssize_t)sizeof(request.text)); - if (!type.is_null()) - strcpy(request.text, type.characters()); - request.text_length = type.length(); - - auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetClipboardContents); - ASSERT(response.clipboard.shared_buffer_id == shared_buffer->shared_buffer_id()); + GWindowServerConnection::the().send_sync(shared_buffer->shared_buffer_id(), data.length(), type); } void GClipboard::did_receive_clipboard_contents_changed(Badge, const String& data_type) diff --git a/Libraries/LibGUI/GDesktop.cpp b/Libraries/LibGUI/GDesktop.cpp index d4ae3a93de7..b41329191c3 100644 --- a/Libraries/LibGUI/GDesktop.cpp +++ b/Libraries/LibGUI/GDesktop.cpp @@ -26,19 +26,11 @@ void GDesktop::did_receive_screen_rect(Badge, const Rec bool GDesktop::set_wallpaper(const StringView& path) { - WSAPI_ClientMessage message; - message.type = WSAPI_ClientMessage::Type::SetWallpaper; - ASSERT(path.length() < (int)sizeof(message.text)); - strncpy(message.text, path.characters_without_null_termination(), path.length()); - message.text_length = path.length(); - auto response = GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::Type::DidSetWallpaper); - return response.value; + GWindowServerConnection::the().post_message(WindowServer::AsyncSetWallpaper(path)); + return GWindowServerConnection::the().wait_for_specific_message()->success(); } String GDesktop::wallpaper() const { - WSAPI_ClientMessage message; - message.type = WSAPI_ClientMessage::Type::GetWallpaper; - auto response = GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::Type::DidGetWallpaper); - return String(response.text, response.text_length); + return GWindowServerConnection::the().send_sync()->path(); } diff --git a/Libraries/LibGUI/GMenu.cpp b/Libraries/LibGUI/GMenu.cpp index 6a90a55ddd6..2d5254b9dff 100644 --- a/Libraries/LibGUI/GMenu.cpp +++ b/Libraries/LibGUI/GMenu.cpp @@ -58,32 +58,19 @@ void GMenu::realize_if_needed() void GMenu::popup(const Point& screen_position) { realize_if_needed(); - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::PopupMenu; - request.menu.menu_id = m_menu_id; - request.menu.position = screen_position; - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().post_message(WindowServer::PopupMenu(m_menu_id, screen_position)); } void GMenu::dismiss() { if (m_menu_id == -1) return; - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::DismissMenu; - request.menu.menu_id = m_menu_id; - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().post_message(WindowServer::DismissMenu(m_menu_id)); } int GMenu::realize_menu() { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::CreateMenu; - ASSERT(m_name.length() < (ssize_t)sizeof(request.text)); - strcpy(request.text, m_name.characters()); - request.text_length = m_name.length(); - auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidCreateMenu); - m_menu_id = response.menu.menu_id; + m_menu_id = GWindowServerConnection::the().send_sync(m_name)->menu_id(); #ifdef GMENU_DEBUG dbgprintf("GMenu::realize_menu(): New menu ID: %d\n", m_menu_id); @@ -94,45 +81,18 @@ int GMenu::realize_menu() item.set_menu_id({}, m_menu_id); item.set_identifier({}, i); if (item.type() == GMenuItem::Separator) { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::AddMenuSeparator; - request.menu.menu_id = m_menu_id; - request.menu.submenu_id = -1; - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuSeparator); + GWindowServerConnection::the().send_sync(m_menu_id); continue; } if (item.type() == GMenuItem::Submenu) { auto& submenu = *item.submenu(); submenu.realize_if_needed(); - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::AddMenuItem; - request.menu.menu_id = m_menu_id; - request.menu.submenu_id = submenu.menu_id(); - request.menu.identifier = i; - // FIXME: It should be possible to disable a submenu. - request.menu.enabled = true; - request.menu.checkable = false; - request.menu.checked = false; - - // no shortcut on submenu, make sure this is cleared out - request.menu.shortcut_text_length = 0; - strcpy(request.menu.shortcut_text, "\0"); - - ASSERT(submenu.name().length() < (ssize_t)sizeof(request.text)); - strcpy(request.text, submenu.name().characters()); - request.text_length = submenu.name().length(); - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuItem); + GWindowServerConnection::the().send_sync(m_menu_id, i, submenu.menu_id(), submenu.name(), true, false, false, "", -1); continue; } if (item.type() == GMenuItem::Action) { auto& action = *item.action(); - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::AddMenuItem; - request.menu.menu_id = m_menu_id; - request.menu.submenu_id = -1; - request.menu.identifier = i; - request.menu.enabled = action.is_enabled(); - request.menu.checkable = action.is_checkable(); + int icon_buffer_id = -1; if (action.icon()) { ASSERT(action.icon()->format() == GraphicsBitmap::Format::RGBA32); ASSERT(action.icon()->size() == Size(16, 16)); @@ -145,26 +105,9 @@ int GMenu::realize_menu() shared_buffer->share_with(GWindowServerConnection::the().server_pid()); action.set_icon(shared_icon); } - request.menu.icon_buffer_id = action.icon()->shared_buffer_id(); - } else { - request.menu.icon_buffer_id = -1; + icon_buffer_id = action.icon()->shared_buffer_id(); } - if (action.is_checkable()) - request.menu.checked = action.is_checked(); - ASSERT(action.text().length() < (ssize_t)sizeof(request.text)); - strcpy(request.text, action.text().characters()); - request.text_length = action.text().length(); - - if (action.shortcut().is_valid()) { - auto shortcut_text = action.shortcut().to_string(); - ASSERT(shortcut_text.length() < (ssize_t)sizeof(request.menu.shortcut_text)); - strcpy(request.menu.shortcut_text, shortcut_text.characters()); - request.menu.shortcut_text_length = shortcut_text.length(); - } else { - request.menu.shortcut_text_length = 0; - } - - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuItem); + GWindowServerConnection::the().send_sync(m_menu_id, i, -1, action.text(), action.is_enabled(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, action.shortcut().to_string(), icon_buffer_id); } } all_menus().set(m_menu_id, this); @@ -176,10 +119,7 @@ void GMenu::unrealize_menu() if (m_menu_id == -1) return; all_menus().remove(m_menu_id); - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::DestroyMenu; - request.menu.menu_id = m_menu_id; - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyMenu); + GWindowServerConnection::the().send_sync(m_menu_id); m_menu_id = 0; } diff --git a/Libraries/LibGUI/GMenuBar.cpp b/Libraries/LibGUI/GMenuBar.cpp index a3a37a66a5b..1449b189bde 100644 --- a/Libraries/LibGUI/GMenuBar.cpp +++ b/Libraries/LibGUI/GMenuBar.cpp @@ -17,20 +17,14 @@ void GMenuBar::add_menu(NonnullOwnPtr&& menu) int GMenuBar::realize_menubar() { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::CreateMenubar; - WSAPI_ServerMessage response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidCreateMenubar); - return response.menu.menubar_id; + return GWindowServerConnection::the().send_sync()->menubar_id(); } void GMenuBar::unrealize_menubar() { if (m_menubar_id == -1) return; - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::DestroyMenubar; - request.menu.menubar_id = m_menubar_id; - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyMenubar); + GWindowServerConnection::the().send_sync(m_menubar_id); m_menubar_id = -1; } @@ -42,16 +36,9 @@ void GMenuBar::notify_added_to_application(Badge) for (auto& menu : m_menus) { int menu_id = menu.realize_menu(); ASSERT(menu_id != -1); - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::AddMenuToMenubar; - request.menu.menubar_id = m_menubar_id; - request.menu.menu_id = menu_id; - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidAddMenuToMenubar); + GWindowServerConnection::the().send_sync(m_menubar_id, menu_id); } - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetApplicationMenubar; - request.menu.menubar_id = m_menubar_id; - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetApplicationMenubar); + GWindowServerConnection::the().send_sync(m_menubar_id); } void GMenuBar::notify_removed_from_application(Badge) diff --git a/Libraries/LibGUI/GMenuItem.cpp b/Libraries/LibGUI/GMenuItem.cpp index 970a1b59f85..4c1266f6a7a 100644 --- a/Libraries/LibGUI/GMenuItem.cpp +++ b/Libraries/LibGUI/GMenuItem.cpp @@ -2,7 +2,6 @@ #include #include #include -#include GMenuItem::GMenuItem(unsigned menu_id, Type type) : m_type(type) @@ -57,26 +56,5 @@ void GMenuItem::update_window_server() if (m_menu_id < 0) return; auto& action = *m_action; - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::UpdateMenuItem; - request.menu.menu_id = m_menu_id; - request.menu.identifier = m_identifier; - request.menu.enabled = action.is_enabled(); - request.menu.checkable = action.is_checkable(); - if (action.is_checkable()) - request.menu.checked = action.is_checked(); - ASSERT(action.text().length() < (ssize_t)sizeof(request.text)); - strcpy(request.text, action.text().characters()); - request.text_length = action.text().length(); - - if (action.shortcut().is_valid()) { - auto shortcut_text = action.shortcut().to_string(); - ASSERT(shortcut_text.length() < (ssize_t)sizeof(request.menu.shortcut_text)); - strcpy(request.menu.shortcut_text, shortcut_text.characters()); - request.menu.shortcut_text_length = shortcut_text.length(); - } else { - request.menu.shortcut_text_length = 0; - } - - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidUpdateMenuItem); + GWindowServerConnection::the().send_sync(m_menu_id, m_identifier, -1, action.text(), action.is_enabled(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, action.shortcut().to_string()); } diff --git a/Libraries/LibGUI/GResizeCorner.cpp b/Libraries/LibGUI/GResizeCorner.cpp index 7d4bfc46c6d..da401976a75 100644 --- a/Libraries/LibGUI/GResizeCorner.cpp +++ b/Libraries/LibGUI/GResizeCorner.cpp @@ -2,7 +2,6 @@ #include #include #include -#include GResizeCorner::GResizeCorner(GWidget* parent) : GWidget(parent) diff --git a/Libraries/LibGUI/GWindow.cpp b/Libraries/LibGUI/GWindow.cpp index 3352cbf5453..9386ae607b1 100644 --- a/Libraries/LibGUI/GWindow.cpp +++ b/Libraries/LibGUI/GWindow.cpp @@ -50,36 +50,27 @@ void GWindow::move_to_front() if (!m_window_id) return; - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::MoveWindowToFront; - request.window_id = m_window_id; - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().send_sync(m_window_id); } void GWindow::show() { if (m_window_id) return; - - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::CreateWindow; - request.window_id = m_window_id; - request.window.rect = m_rect_when_windowless; - request.window.has_alpha_channel = m_has_alpha_channel; - request.window.modal = m_modal; - request.window.resizable = m_resizable; - request.window.fullscreen = m_fullscreen; - request.window.show_titlebar = m_show_titlebar; - request.window.opacity = m_opacity_when_windowless; - request.window.background_color = m_background_color.value(); - request.window.size_increment = m_size_increment; - request.window.base_size = m_base_size; - request.window.type = (WSAPI_WindowType)m_window_type; - ASSERT(m_title_when_windowless.length() < (ssize_t)sizeof(request.text)); - strcpy(request.text, m_title_when_windowless.characters()); - request.text_length = m_title_when_windowless.length(); - auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidCreateWindow); - m_window_id = response.window_id; + auto response = GWindowServerConnection::the().send_sync( + m_rect_when_windowless, + m_has_alpha_channel, + m_modal, + m_resizable, + m_fullscreen, + m_show_titlebar, + m_opacity_when_windowless, + m_background_color, + m_base_size, + m_size_increment, + (i32)m_window_type, + m_title_when_windowless); + m_window_id = response->window_id(); apply_icon(); @@ -93,10 +84,7 @@ void GWindow::hide() if (!m_window_id) return; reified_windows.remove(m_window_id); - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::DestroyWindow; - request.window_id = m_window_id; - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidDestroyWindow); + GWindowServerConnection::the().send_sync(m_window_id); m_window_id = 0; m_pending_paint_event_rects.clear(); m_back_bitmap = nullptr; @@ -118,39 +106,21 @@ void GWindow::set_title(const StringView& title) m_title_when_windowless = title; if (!m_window_id) return; - - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetWindowTitle; - request.window_id = m_window_id; - ASSERT(m_title_when_windowless.length() < (ssize_t)sizeof(request.text)); - strcpy(request.text, m_title_when_windowless.characters()); - request.text_length = m_title_when_windowless.length(); - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().send_sync(m_window_id, title); } String GWindow::title() const { if (!m_window_id) return m_title_when_windowless; - - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::GetWindowTitle; - request.window_id = m_window_id; - auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidGetWindowTitle); - return String(response.text, response.text_length); + return GWindowServerConnection::the().send_sync(m_window_id)->title(); } Rect GWindow::rect() const { if (!m_window_id) return m_rect_when_windowless; - - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::GetWindowRect; - request.window_id = m_window_id; - auto response = GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidGetWindowRect); - ASSERT(response.window_id == m_window_id); - return response.window.rect; + return GWindowServerConnection::the().send_sync(m_window_id)->rect(); } void GWindow::set_rect(const Rect& a_rect) @@ -161,11 +131,7 @@ void GWindow::set_rect(const Rect& a_rect) m_main_widget->resize(m_rect_when_windowless.size()); return; } - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetWindowRect; - request.window_id = m_window_id; - request.window.rect = a_rect; - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().send_sync(m_window_id, a_rect); if (m_back_bitmap && m_back_bitmap->size() != a_rect.size()) m_back_bitmap = nullptr; if (m_front_bitmap && m_front_bitmap->size() != a_rect.size()) @@ -183,11 +149,7 @@ void GWindow::set_override_cursor(GStandardCursor cursor) { if (!m_window_id) return; - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetWindowOverrideCursor; - request.window_id = m_window_id; - request.cursor.cursor = (WSAPI_StandardCursor)cursor; - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().send_sync(m_window_id, (u32)cursor); } void GWindow::event(CEvent& event) @@ -258,16 +220,10 @@ void GWindow::event(CEvent& event) set_current_backing_bitmap(*m_back_bitmap, true); if (m_window_id) { - WSAPI_ClientMessage message; - message.type = WSAPI_ClientMessage::Type::DidFinishPainting; - message.window_id = m_window_id; - message.rect_count = rects.size(); - for (int i = 0; i < min(WSAPI_ClientMessage::max_inline_rect_count, rects.size()); ++i) - message.rects[i] = rects[i]; - ByteBuffer extra_data; - if (rects.size() > WSAPI_ClientMessage::max_inline_rect_count) - extra_data = ByteBuffer::wrap(&rects[WSAPI_ClientMessage::max_inline_rect_count], (rects.size() - WSAPI_ClientMessage::max_inline_rect_count) * sizeof(WSAPI_Rect)); - GWindowServerConnection::the().post_message_to_server(message, move(extra_data)); + Vector rects_to_send; + for (auto& r : rects) + rects_to_send.append(r); + GWindowServerConnection::the().post_message(WindowServer::DidFinishPainting(m_window_id, rects_to_send)); } return; } @@ -455,16 +411,10 @@ void GWindow::update(const Rect& a_rect) auto rects = move(m_pending_paint_event_rects); if (rects.is_empty()) return; - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::InvalidateRect; - request.window_id = m_window_id; - for (int i = 0; i < min(WSAPI_ClientMessage::max_inline_rect_count, rects.size()); ++i) - request.rects[i] = rects[i]; - ByteBuffer extra_data; - if (rects.size() > WSAPI_ClientMessage::max_inline_rect_count) - extra_data = ByteBuffer::wrap(&rects[WSAPI_ClientMessage::max_inline_rect_count], (rects.size() - WSAPI_ClientMessage::max_inline_rect_count) * sizeof(WSAPI_Rect)); - request.rect_count = rects.size(); - GWindowServerConnection::the().post_message_to_server(request, move(extra_data)); + Vector rects_to_send; + for (auto& r : rects) + rects_to_send.append(r); + GWindowServerConnection::the().post_message(WindowServer::InvalidateRect(m_window_id, rects_to_send)); }); } m_pending_paint_event_rects.append(a_rect); @@ -534,12 +484,7 @@ void GWindow::set_has_alpha_channel(bool value) m_back_bitmap = nullptr; m_front_bitmap = nullptr; - WSAPI_ClientMessage message; - message.type = WSAPI_ClientMessage::Type::SetWindowHasAlphaChannel; - message.window_id = m_window_id; - message.value = value; - GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::DidSetWindowHasAlphaChannel); - + GWindowServerConnection::the().send_sync(m_window_id, value); update(); } @@ -554,12 +499,7 @@ void GWindow::set_opacity(float opacity) m_opacity_when_windowless = opacity; if (!m_window_id) return; - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetWindowOpacity; - request.window_id = m_window_id; - request.window.opacity = opacity; - m_opacity_when_windowless = opacity; - GWindowServerConnection::the().post_message_to_server(request); + GWindowServerConnection::the().send_sync(m_window_id, opacity); } void GWindow::set_hovered_widget(GWidget* widget) @@ -578,16 +518,7 @@ void GWindow::set_hovered_widget(GWidget* widget) void GWindow::set_current_backing_bitmap(GraphicsBitmap& bitmap, bool flush_immediately) { - WSAPI_ClientMessage message; - message.type = WSAPI_ClientMessage::Type::SetWindowBackingStore; - message.window_id = m_window_id; - message.backing.bpp = 32; - message.backing.pitch = bitmap.pitch(); - message.backing.shared_buffer_id = bitmap.shared_buffer_id(); - message.backing.has_alpha_channel = bitmap.has_alpha_channel(); - message.backing.size = bitmap.size(); - message.backing.flush_immediately = flush_immediately; - GWindowServerConnection::the().sync_request(message, WSAPI_ServerMessage::Type::DidSetWindowBackingStore); + GWindowServerConnection::the().send_sync(m_window_id, 32, bitmap.pitch(), bitmap.shared_buffer_id(), bitmap.has_alpha_channel(), bitmap.size(), flush_immediately); } void GWindow::flip(const Vector& dirty_rects) @@ -668,21 +599,12 @@ void GWindow::apply_icon() if (!has_set_process_icon) set_process_icon(m_icon->shared_buffer_id()); - WSAPI_ClientMessage message; - message.type = WSAPI_ClientMessage::Type::SetWindowIconBitmap; - message.window_id = m_window_id; - message.window.icon_buffer_id = m_icon->shared_buffer_id(); - message.window.icon_size = m_icon->size(); - GWindowServerConnection::the().post_message_to_server(message); + GWindowServerConnection::the().send_sync(m_window_id, m_icon->shared_buffer_id(), m_icon->size()); } void GWindow::start_wm_resize() { - WSAPI_ClientMessage message; - message.type = WSAPI_ClientMessage::Type::WM_StartWindowResize; - message.wm.client_id = GWindowServerConnection::the().my_client_id(); - message.wm.window_id = m_window_id; - GWindowServerConnection::the().post_message_to_server(message); + GWindowServerConnection::the().post_message(WindowServer::WM_StartWindowResize(GWindowServerConnection::the().my_client_id(), m_window_id)); } Vector GWindow::focusable_widgets() const @@ -729,12 +651,7 @@ void GWindow::set_fullscreen(bool fullscreen) m_fullscreen = fullscreen; if (!m_window_id) return; - - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::SetFullscreen; - request.window_id = m_window_id; - request.value = fullscreen; - GWindowServerConnection::the().sync_request(request, WSAPI_ServerMessage::Type::DidSetFullscreen); + GWindowServerConnection::the().send_sync(m_window_id, fullscreen); } void GWindow::schedule_relayout() diff --git a/Libraries/LibGUI/GWindowServerConnection.cpp b/Libraries/LibGUI/GWindowServerConnection.cpp index 7e60155e7ad..fd4d533c869 100644 --- a/Libraries/LibGUI/GWindowServerConnection.cpp +++ b/Libraries/LibGUI/GWindowServerConnection.cpp @@ -1,15 +1,3 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -19,301 +7,258 @@ #include #include #include -#include //#define GEVENTLOOP_DEBUG -//#define COALESCING_DEBUG GWindowServerConnection& GWindowServerConnection::the() { static GWindowServerConnection* s_connection = nullptr; - if (!s_connection) { - s_connection = new GWindowServerConnection(); - s_connection->handshake(); - } + if (!s_connection) + s_connection = new GWindowServerConnection; return *s_connection; } void GWindowServerConnection::handshake() { - WSAPI_ClientMessage request; - request.type = WSAPI_ClientMessage::Type::Greeting; - request.greeting.client_pid = getpid(); - auto response = sync_request(request, WSAPI_ServerMessage::Type::Greeting); - handle_greeting(response); + auto response = send_sync(getpid()); + set_server_pid(response->server_pid()); + set_my_client_id(response->client_id()); + GDesktop::the().did_receive_screen_rect({}, response->screen_rect()); } -void GWindowServerConnection::handle_paint_event(const WSAPI_ServerMessage& event, GWindow& window, const ByteBuffer& extra_data) +void GWindowServerConnection::handle(const WindowClient::Paint& message) { #ifdef GEVENTLOOP_DEBUG - dbgprintf("WID=%x Paint\n", event.window_id); + dbgprintf("WID=%d Paint\n", message.window_id()); #endif - Vector rects; - for (int i = 0; i < min(WSAPI_ServerMessage::max_inline_rect_count, event.rect_count); ++i) - rects.append(event.rects[i]); - if (event.extra_size) { - auto* extra_rects = reinterpret_cast(extra_data.data()); - for (int i = 0; i < event.rect_count - WSAPI_ServerMessage::max_inline_rect_count; ++i) - rects.append(extra_rects[i]); - } - CEventLoop::current().post_event(window, make(rects, event.paint.window_size)); -} - -void GWindowServerConnection::handle_resize_event(const WSAPI_ServerMessage& event, GWindow& window) -{ - CEventLoop::current().post_event(window, make(event.window.old_rect.size, event.window.rect.size)); -} - -void GWindowServerConnection::handle_window_activation_event(const WSAPI_ServerMessage& event, GWindow& window) -{ -#ifdef GEVENTLOOP_DEBUG - dbgprintf("WID=%x WindowActivation\n", event.window_id); -#endif - CEventLoop::current().post_event(window, make(event.type == WSAPI_ServerMessage::Type::WindowActivated ? GEvent::WindowBecameActive : GEvent::WindowBecameInactive)); -} - -void GWindowServerConnection::handle_window_close_request_event(const WSAPI_ServerMessage&, GWindow& window) -{ - CEventLoop::current().post_event(window, make(GEvent::WindowCloseRequest)); -} - -void GWindowServerConnection::handle_window_entered_or_left_event(const WSAPI_ServerMessage& message, GWindow& window) -{ - CEventLoop::current().post_event(window, make(message.type == WSAPI_ServerMessage::Type::WindowEntered ? GEvent::WindowEntered : GEvent::WindowLeft)); -} - -void GWindowServerConnection::handle_key_event(const WSAPI_ServerMessage& event, GWindow& window) -{ -#ifdef GEVENTLOOP_DEBUG - dbgprintf("WID=%x KeyEvent character=0x%b\n", event.window_id, event.key.character); -#endif - auto key_event = make(event.type == WSAPI_ServerMessage::Type::KeyDown ? GEvent::KeyDown : GEvent::KeyUp, event.key.key, event.key.modifiers); - if (event.key.character != '\0') - key_event->m_text = String(&event.key.character, 1); - - if (event.type == WSAPI_ServerMessage::Type::KeyDown) { - if (auto* focused_widget = window.focused_widget()) { - if (auto* action = focused_widget->action_for_key_event(*key_event)) { - if (action->is_enabled()) { - action->activate(); - return; - } - } + if (auto* window = GWindow::from_window_id(message.window_id())) { + Vector rects; + for (auto& r : message.rects()) { + rects.append(r); } + CEventLoop::current().post_event(*window, make(rects, message.window_size())); + } +} - if (auto* action = GApplication::the().action_for_key_event(*key_event)) { +void GWindowServerConnection::handle(const WindowClient::WindowResized& message) +{ + if (auto* window = GWindow::from_window_id(message.window_id())) { + CEventLoop::current().post_event(*window, make(message.old_rect().size(), message.new_rect().size())); + } +} + +void GWindowServerConnection::handle(const WindowClient::WindowActivated& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("(%d) WID=%d WindowActivated\n", getpid(), message.window_id()); +#endif + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::WindowBecameActive)); +} + +void GWindowServerConnection::handle(const WindowClient::WindowDeactivated& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("(%d) WID=%d WindowDeactivated\n", getpid(), message.window_id()); +#endif + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::WindowBecameInactive)); +} + +void GWindowServerConnection::handle(const WindowClient::WindowCloseRequest& message) +{ + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::WindowCloseRequest)); +} + +void GWindowServerConnection::handle(const WindowClient::WindowEntered& message) +{ + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::WindowEntered)); +} + +void GWindowServerConnection::handle(const WindowClient::WindowLeft& message) +{ + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::WindowLeft)); +} + +void GWindowServerConnection::handle(const WindowClient::KeyDown& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("WID=%d KeyDown character=0x%02x\n", message.window_id(), message.character()); +#endif + auto* window = GWindow::from_window_id(message.window_id()); + if (!window) + return; + + auto key_event = make(GEvent::KeyDown, message.key(), message.modifiers()); + if (message.character() != '\0') { + char ch = message.character(); + key_event->m_text = String(&ch, 1); + } + + if (auto* focused_widget = window->focused_widget()) { + if (auto* action = focused_widget->action_for_key_event(*key_event)) { if (action->is_enabled()) { action->activate(); return; } } } - CEventLoop::current().post_event(window, move(key_event)); -} -void GWindowServerConnection::handle_mouse_event(const WSAPI_ServerMessage& event, GWindow& window) -{ -#ifdef GEVENTLOOP_DEBUG - dbgprintf("WID=%x MouseEvent %d,%d,%d\n", event.window_id, event.mouse.position.x, event.mouse.position.y, event.mouse.wheel_delta); -#endif - GMouseEvent::Type type; - switch (event.type) { - case WSAPI_ServerMessage::Type::MouseMove: - type = GEvent::MouseMove; - break; - case WSAPI_ServerMessage::Type::MouseUp: - type = GEvent::MouseUp; - break; - case WSAPI_ServerMessage::Type::MouseDown: - type = GEvent::MouseDown; - break; - case WSAPI_ServerMessage::Type::MouseDoubleClick: - type = GEvent::MouseDoubleClick; - break; - case WSAPI_ServerMessage::Type::MouseWheel: - type = GEvent::MouseWheel; - break; - default: - ASSERT_NOT_REACHED(); - break; - } - GMouseButton button { GMouseButton::None }; - switch (event.mouse.button) { - case WSAPI_MouseButton::NoButton: - button = GMouseButton::None; - break; - case WSAPI_MouseButton::Left: - button = GMouseButton::Left; - break; - case WSAPI_MouseButton::Right: - button = GMouseButton::Right; - break; - case WSAPI_MouseButton::Middle: - button = GMouseButton::Middle; - break; - default: - ASSERT_NOT_REACHED(); - break; - } - CEventLoop::current().post_event(window, make(type, event.mouse.position, event.mouse.buttons, button, event.mouse.modifiers, event.mouse.wheel_delta)); -} - -void GWindowServerConnection::handle_menu_event(const WSAPI_ServerMessage& event) -{ - if (event.type == WSAPI_ServerMessage::Type::MenuItemActivated) { - auto* menu = GMenu::from_menu_id(event.menu.menu_id); - if (!menu) { - dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id); + if (auto* action = GApplication::the().action_for_key_event(*key_event)) { + if (action->is_enabled()) { + action->activate(); return; } - if (auto* action = menu->action_at(event.menu.identifier)) - action->activate(); - return; } - ASSERT_NOT_REACHED(); + CEventLoop::current().post_event(*window, move(key_event)); } -void GWindowServerConnection::handle_wm_event(const WSAPI_ServerMessage& event, GWindow& window) +void GWindowServerConnection::handle(const WindowClient::KeyUp& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("WID=%d KeyUp character=0x%02x\n", message.window_id(), message.character()); +#endif + auto* window = GWindow::from_window_id(message.window_id()); + if (!window) + return; + + auto key_event = make(GEvent::KeyUp, message.key(), message.modifiers()); + if (message.character() != '\0') { + char ch = message.character(); + key_event->m_text = String(&ch, 1); + } + + CEventLoop::current().post_event(*window, move(key_event)); +} + +GMouseButton to_gmousebutton(u32 button) +{ + switch (button) { + case 0: + return GMouseButton::None; + case 1: + return GMouseButton::Left; + case 2: + return GMouseButton::Right; + case 4: + return GMouseButton::Middle; + default: + ASSERT_NOT_REACHED(); + break; + } +} + +void GWindowServerConnection::handle(const WindowClient::MouseDown& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("WID=%d MouseDown %d,%d,%d\n", message.window_id(), message.mouse_position().x(), message.mouse_position().y(), message.wheel_delta(); +#endif + + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::MouseDown, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta())); +} + +void GWindowServerConnection::handle(const WindowClient::MouseUp& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("WID=%d MouseUp %d,%d,%d\n", message.window_id(), message.mouse_position().x(), message.mouse_position().y(), message.wheel_delta(); +#endif + + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::MouseUp, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta())); +} + +void GWindowServerConnection::handle(const WindowClient::MouseMove& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("WID=%d MouseMove %d,%d,%d\n", message.window_id(), message.mouse_position().x(), message.mouse_position().y(), message.wheel_delta(); +#endif + + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::MouseMove, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta())); +} + +void GWindowServerConnection::handle(const WindowClient::MouseDoubleClick& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("WID=%d MouseDoubleClick %d,%d,%d\n", message.window_id(), message.mouse_position().x(), message.mouse_position().y(), message.wheel_delta(); +#endif + + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::MouseDoubleClick, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta())); +} + +void GWindowServerConnection::handle(const WindowClient::MouseWheel& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("WID=%d MouseWheel %d,%d,%d\n", message.window_id(), message.mouse_position().x(), message.mouse_position().y(), message.wheel_delta(); +#endif + + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(GEvent::MouseWheel, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta())); +} + +void GWindowServerConnection::handle(const WindowClient::MenuItemActivated& message) +{ + auto* menu = GMenu::from_menu_id(message.menu_id()); + if (!menu) { + dbgprintf("GEventLoop received event for invalid menu ID %d\n", message.menu_id()); + return; + } + if (auto* action = menu->action_at(message.identifier())) + action->activate(); +} + +void GWindowServerConnection::handle(const WindowClient::WM_WindowStateChanged& message) { #ifdef GEVENTLOOP_DEBUG dbgprintf("GEventLoop: handle_wm_event: %d\n", (int)event.type); #endif - if (event.type == WSAPI_ServerMessage::WM_WindowStateChanged) - CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect, event.wm.is_active, (GWindowType)event.wm.window_type, event.wm.is_minimized)); - else if (event.type == WSAPI_ServerMessage::WM_WindowRectChanged) - CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id, event.wm.rect)); - else if (event.type == WSAPI_ServerMessage::WM_WindowIconBitmapChanged) - CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id, event.wm.icon_buffer_id, event.wm.icon_size)); - else if (event.type == WSAPI_ServerMessage::WM_WindowRemoved) - CEventLoop::current().post_event(window, make(event.wm.client_id, event.wm.window_id)); - else - ASSERT_NOT_REACHED(); + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(message.client_id(), message.window_id(), message.title(), message.rect(), message.is_active(), (GWindowType)message.window_type(), message.is_minimized())); } -void GWindowServerConnection::postprocess_bundles(Vector& bundles) +void GWindowServerConnection::handle(const WindowClient::WM_WindowRectChanged& message) { - int coalesced_paints = 0; - int coalesced_resizes = 0; - auto unprocessed_bundles = move(bundles); - - HashMap latest_size_for_window_id; - for (auto& bundle : unprocessed_bundles) { - auto& event = bundle.message; - if (event.type == WSAPI_ServerMessage::Type::WindowResized) { - latest_size_for_window_id.set(event.window_id, event.window.rect.size); - } - } - - int paint_count = 0; - HashMap latest_paint_size_for_window_id; - for (auto& bundle : unprocessed_bundles) { - auto& event = bundle.message; - if (event.type == WSAPI_ServerMessage::Type::Paint) { - ++paint_count; -#ifdef COALESCING_DEBUG - dbgprintf(" (window: %s)\n", Size(event.paint.window_size).to_string().characters()); -#endif - latest_paint_size_for_window_id.set(event.window_id, event.paint.window_size); - } - } -#ifdef COALESCING_DEBUG - dbgprintf("paint_count: %d\n", paint_count); -#endif - - for (auto& bundle : unprocessed_bundles) { - auto& event = bundle.message; - if (event.type == WSAPI_ServerMessage::Type::Greeting) { - // Shouldn't get a second greeting - dbg() << "Got second Greeting!?"; - ASSERT_NOT_REACHED(); - continue; - } - - if (event.type == WSAPI_ServerMessage::Type::ScreenRectChanged) { - GDesktop::the().did_receive_screen_rect({}, event.screen.rect); - continue; - } - - if (event.type == WSAPI_ServerMessage::Type::ClipboardContentsChanged) { - GClipboard::the().did_receive_clipboard_contents_changed({}, String(event.text, event.text_length)); - continue; - } - - if (event.type == WSAPI_ServerMessage::Error) { - dbgprintf("GEventLoop got error message from server\n"); - dbgprintf(" - error message: %s\n", String(event.text, event.text_length).characters()); - CEventLoop::current().quit(1); - return; - } - - switch (event.type) { - case WSAPI_ServerMessage::MenuItemActivated: - handle_menu_event(event); - continue; - default: - break; - } - - auto* window = GWindow::from_window_id(event.window_id); - if (!window) { - dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id); - continue; - } - switch (event.type) { - case WSAPI_ServerMessage::Type::Paint: - if (Size(event.paint.window_size) != latest_paint_size_for_window_id.get(event.window_id).value_or({})) { - ++coalesced_paints; - break; - } - handle_paint_event(event, *window, bundle.extra_data); - break; - case WSAPI_ServerMessage::Type::MouseDown: - case WSAPI_ServerMessage::Type::MouseDoubleClick: - case WSAPI_ServerMessage::Type::MouseUp: - case WSAPI_ServerMessage::Type::MouseMove: - case WSAPI_ServerMessage::Type::MouseWheel: - handle_mouse_event(event, *window); - break; - case WSAPI_ServerMessage::Type::WindowActivated: - case WSAPI_ServerMessage::Type::WindowDeactivated: - handle_window_activation_event(event, *window); - break; - case WSAPI_ServerMessage::Type::WindowCloseRequest: - handle_window_close_request_event(event, *window); - break; - case WSAPI_ServerMessage::Type::KeyDown: - case WSAPI_ServerMessage::Type::KeyUp: - handle_key_event(event, *window); - break; - case WSAPI_ServerMessage::Type::WindowEntered: - case WSAPI_ServerMessage::Type::WindowLeft: - handle_window_entered_or_left_event(event, *window); - break; - case WSAPI_ServerMessage::Type::WindowResized: - if (Size(event.window.rect.size) != latest_size_for_window_id.get(event.window_id).value_or({})) { - ++coalesced_resizes; - break; - } - handle_resize_event(event, *window); - break; - default: - if (event.type > WSAPI_ServerMessage::__Begin_WM_Events__ && event.type < WSAPI_ServerMessage::Type::__End_WM_Events__) - handle_wm_event(event, *window); - break; - } - } - -#ifdef COALESCING_DEBUG - if (coalesced_paints) - dbgprintf("Coalesced %d paints\n", coalesced_paints); - if (coalesced_resizes) - dbgprintf("Coalesced %d resizes\n", coalesced_resizes); +#ifdef GEVENTLOOP_DEBUG + dbgprintf("GEventLoop: handle_wm_event: %d\n", (int)event.type); #endif + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(message.client_id(), message.window_id(), message.rect())); } -void GWindowServerConnection::handle_greeting(WSAPI_ServerMessage& message) +void GWindowServerConnection::handle(const WindowClient::WM_WindowIconBitmapChanged& message) { - set_server_pid(message.greeting.server_pid); - set_my_client_id(message.greeting.your_client_id); - GDesktop::the().did_receive_screen_rect({}, message.greeting.screen_rect); +#ifdef GEVENTLOOP_DEBUG + dbgprintf("GEventLoop: handle_wm_event: %d\n", (int)event.type); +#endif + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(message.client_id(), message.window_id(), message.icon_buffer_id(), message.icon_size())); +} + +void GWindowServerConnection::handle(const WindowClient::WM_WindowRemoved& message) +{ +#ifdef GEVENTLOOP_DEBUG + dbgprintf("GEventLoop: handle_wm_event: %d\n", (int)event.type); +#endif + if (auto* window = GWindow::from_window_id(message.window_id())) + CEventLoop::current().post_event(*window, make(message.client_id(), message.window_id())); +} + +void GWindowServerConnection::handle(const WindowClient::ScreenRectChanged& message) +{ + GDesktop::the().did_receive_screen_rect({}, message.rect()); +} + +void GWindowServerConnection::handle(const WindowClient::ClipboardContentsChanged& message) +{ + GClipboard::the().did_receive_clipboard_contents_changed({}, message.content_type()); +} + +void GWindowServerConnection::handle(const WindowClient::AsyncSetWallpaperFinished&) +{ + // This is handled manually by GDesktop::set_wallpaper(). } diff --git a/Libraries/LibGUI/GWindowServerConnection.h b/Libraries/LibGUI/GWindowServerConnection.h index 218cc0944a9..39390971faf 100644 --- a/Libraries/LibGUI/GWindowServerConnection.h +++ b/Libraries/LibGUI/GWindowServerConnection.h @@ -1,35 +1,44 @@ #pragma once -#include #include -#include -#include +#include +#include -class GAction; -class CObject; -class CNotifier; -class GWindow; - -class GWindowServerConnection : public IPC::Client::Connection { +class GWindowServerConnection + : public IPC::Client::ConnectionNG + , public WindowClientEndpoint { C_OBJECT(GWindowServerConnection) public: GWindowServerConnection() - : Connection("/tmp/portal/window") - {} + : ConnectionNG(*this, "/tmp/portal/window") + { + handshake(); + } - void handshake() override; + virtual void handshake() override; static GWindowServerConnection& the(); private: - void postprocess_bundles(Vector& m_unprocessed_bundles) override; - void handle_paint_event(const WSAPI_ServerMessage&, GWindow&, const ByteBuffer& extra_data); - void handle_resize_event(const WSAPI_ServerMessage&, GWindow&); - void handle_mouse_event(const WSAPI_ServerMessage&, GWindow&); - void handle_key_event(const WSAPI_ServerMessage&, GWindow&); - void handle_window_activation_event(const WSAPI_ServerMessage&, GWindow&); - void handle_window_close_request_event(const WSAPI_ServerMessage&, GWindow&); - void handle_menu_event(const WSAPI_ServerMessage&); - void handle_window_entered_or_left_event(const WSAPI_ServerMessage&, GWindow&); - void handle_wm_event(const WSAPI_ServerMessage&, GWindow&); - void handle_greeting(WSAPI_ServerMessage&); + virtual void handle(const WindowClient::Paint&) override; + virtual void handle(const WindowClient::MouseMove&) override; + virtual void handle(const WindowClient::MouseDown&) override; + virtual void handle(const WindowClient::MouseDoubleClick&) override; + virtual void handle(const WindowClient::MouseUp&) override; + virtual void handle(const WindowClient::MouseWheel&) override; + virtual void handle(const WindowClient::WindowEntered&) override; + virtual void handle(const WindowClient::WindowLeft&) override; + virtual void handle(const WindowClient::KeyDown&) override; + virtual void handle(const WindowClient::KeyUp&) override; + virtual void handle(const WindowClient::WindowActivated&) override; + virtual void handle(const WindowClient::WindowDeactivated&) override; + virtual void handle(const WindowClient::WindowCloseRequest&) override; + virtual void handle(const WindowClient::WindowResized&) override; + virtual void handle(const WindowClient::MenuItemActivated&) override; + virtual void handle(const WindowClient::ScreenRectChanged&) override; + virtual void handle(const WindowClient::ClipboardContentsChanged&) override; + virtual void handle(const WindowClient::WM_WindowRemoved&) override; + virtual void handle(const WindowClient::WM_WindowStateChanged&) override; + virtual void handle(const WindowClient::WM_WindowIconBitmapChanged&) override; + virtual void handle(const WindowClient::WM_WindowRectChanged&) override; + virtual void handle(const WindowClient::AsyncSetWallpaperFinished&) override; }; diff --git a/Servers/WindowServer/Makefile b/Servers/WindowServer/Makefile index f731caa25be..411ec11953c 100644 --- a/Servers/WindowServer/Makefile +++ b/Servers/WindowServer/Makefile @@ -25,6 +25,14 @@ DEFINES += -DUSERLAND all: $(APP) +*.cpp: WindowServerEndpoint.h WindowClientEndpoint.h + +WindowServerEndpoint.h: WindowServer.ipc + @echo "IPC $<"; $(IPCCOMPILER) $< > $@ + +WindowClientEndpoint.h: WindowClient.ipc + @echo "IPC $<"; $(IPCCOMPILER) $< > $@ + $(APP): $(OBJS) $(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lc -ldraw -lcore -lthread -lpthread -laudio -lipc @@ -34,5 +42,5 @@ $(APP): $(OBJS) -include $(OBJS:%.o=%.d) clean: - @echo "CLEAN"; rm -f $(APP) $(OBJS) *.d + @echo "CLEAN"; rm -f $(APP) $(OBJS) *.d WindowServerEndpoint.h WindowClientEndpoint.h diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h deleted file mode 100644 index 20908401d04..00000000000 --- a/Servers/WindowServer/WSAPITypes.h +++ /dev/null @@ -1,328 +0,0 @@ -#pragma once - -#include -#include - -typedef unsigned WSAPI_Color; - -struct WSAPI_Point { - int x; - int y; -}; - -struct WSAPI_Size { - int width; - int height; -}; - -struct WSAPI_Rect { - WSAPI_Point location; - WSAPI_Size size; -}; - -enum WSAPI_WindowType { - Invalid = 0, - Normal, - Menu, - WindowSwitcher, - Taskbar, - Tooltip, - Menubar, -}; - -struct WSAPI_WindowBackingStoreInfo { - WSAPI_Size size; - size_t bpp; - size_t pitch; - RGBA32* pixels; -}; - -enum class WSAPI_MouseButton : unsigned char { - NoButton = 0, - Left = 1, - Right = 2, - Middle = 4, -}; - -struct WSAPI_KeyModifiers { - enum { - Shift = 1 << 0, - Alt = 1 << 1, - Ctrl = 1 << 2, - }; -}; - -enum class WSAPI_StandardCursor : unsigned char { - None = 0, - Arrow, - IBeam, - ResizeHorizontal, - ResizeVertical, - ResizeDiagonalTLBR, - ResizeDiagonalBLTR, -}; - -enum WSAPI_WMEventMask : unsigned { - WindowRectChanges = 1 << 0, - WindowStateChanges = 1 << 1, - WindowIconChanges = 1 << 2, - WindowRemovals = 1 << 3, -}; - -struct WSAPI_ServerMessage { - enum Type : unsigned { - Invalid, - Error, - Paint, - MouseMove, - MouseDown, - MouseDoubleClick, - MouseUp, - MouseWheel, - WindowEntered, - WindowLeft, - KeyDown, - KeyUp, - WindowActivated, - WindowDeactivated, - WindowResized, - WindowCloseRequest, - MenuItemActivated, - DidCreateMenubar, - DidDestroyMenubar, - DidCreateMenu, - DidDestroyMenu, - DidAddMenuToMenubar, - DidSetApplicationMenubar, - DidAddMenuItem, - DidAddMenuSeparator, - DidUpdateMenuItem, - DidCreateWindow, - DidDestroyWindow, - DidGetWindowTitle, - DidGetWindowRect, - Greeting, - DidGetClipboardContents, - DidSetClipboardContents, - DidSetWindowBackingStore, - DidSetWallpaper, - DidGetWallpaper, - DidSetResolution, - DidSetWindowHasAlphaChannel, - ScreenRectChanged, - ClipboardContentsChanged, - DidSetFullscreen, - - __Begin_WM_Events__, - WM_WindowRemoved, - WM_WindowStateChanged, - WM_WindowRectChanged, - WM_WindowIconBitmapChanged, - __End_WM_Events__, - }; - Type type { Invalid }; - int window_id { -1 }; - unsigned extra_size { 0 }; - - union { - int text_length { 0 }; - int rect_count; - }; - - static const int max_inline_rect_count = 32; - union { - char text[512]; - WSAPI_Rect rects[32]; - }; - int value { 0 }; - - union { - struct { - int server_pid; - int your_client_id; - WSAPI_Rect screen_rect; - } greeting; - struct { - int client_id; - int window_id; - WSAPI_Rect rect; - bool is_active; - bool is_minimized; - WSAPI_WindowType window_type; - int icon_buffer_id; - WSAPI_Size icon_size; - } wm; - struct { - WSAPI_Rect rect; - } screen; - struct { - WSAPI_Rect rect; - WSAPI_Rect old_rect; - } window; - struct { - WSAPI_Size window_size; - } paint; - struct { - WSAPI_Point position; - WSAPI_MouseButton button; - unsigned buttons; - u8 modifiers; - int wheel_delta; - } mouse; - struct { - char character; - u8 key; - u8 modifiers; - bool ctrl : 1; - bool alt : 1; - bool shift : 1; - } key; - struct { - int menubar_id; - int menu_id; - unsigned identifier; - } menu; - struct { - WSAPI_Size size; - size_t bpp; - size_t pitch; - int shared_buffer_id; - bool has_alpha_channel; - } backing; - struct { - int shared_buffer_id; - int contents_size; - } clipboard; - }; -}; - -struct WSAPI_ClientMessage { - enum Type : unsigned { - Invalid, - CreateMenubar, - DestroyMenubar, - CreateMenu, - DestroyMenu, - AddMenuToMenubar, - SetApplicationMenubar, - AddMenuItem, - AddMenuSeparator, - UpdateMenuItem, - CreateWindow, - DestroyWindow, - SetWindowTitle, - GetWindowTitle, - SetWindowRect, - GetWindowRect, - InvalidateRect, - DidFinishPainting, - SetGlobalCursorTracking, - SetWindowOpacity, - SetWindowBackingStore, - GetClipboardContents, - SetClipboardContents, - Greeting, - SetWallpaper, - GetWallpaper, - SetResolution, - SetWindowOverrideCursor, - WM_SetActiveWindow, - WM_SetWindowMinimized, - WM_StartWindowResize, - WM_PopupWindowMenu, - PopupMenu, - DismissMenu, - SetWindowHasAlphaChannel, - MoveWindowToFront, - SetWindowIconBitmap, - SetFullscreen, - }; - Type type { Invalid }; - int window_id { -1 }; - unsigned extra_size { 0 }; - union { - int text_length { 0 }; - int rect_count; - }; - - static const int max_inline_rect_count = 32; - union { - char text[512]; - WSAPI_Rect rects[max_inline_rect_count]; - }; - int value { 0 }; - - union { - struct { - int client_pid; - } greeting; - struct { - int client_id; - int window_id; - bool minimized; - WSAPI_Point position; - } wm; - struct { - WSAPI_Size resolution; - } wm_conf; - struct { - int menubar_id; - int menu_id; - int submenu_id; - int icon_buffer_id; - unsigned identifier; - char shortcut_text[32]; - int shortcut_text_length; - bool enabled; - bool checkable; - bool checked; - WSAPI_Point position; - } menu; - struct { - WSAPI_Rect rect; - bool has_alpha_channel; - bool modal; - bool resizable; - bool fullscreen; - bool show_titlebar; - WSAPI_WindowType type; - float opacity; - WSAPI_Size base_size; - WSAPI_Size size_increment; - WSAPI_Color background_color; - int icon_buffer_id; - WSAPI_Size icon_size; - } window; - struct { - WSAPI_Size size; - size_t bpp; - size_t pitch; - int shared_buffer_id; - bool has_alpha_channel; - bool flush_immediately; - } backing; - struct { - int shared_buffer_id; - int contents_size; - } clipboard; - struct { - WSAPI_StandardCursor cursor; - } cursor; - }; -}; - -inline Rect::Rect(const WSAPI_Rect& r) - : Rect(r.location, r.size) -{ -} -inline Point::Point(const WSAPI_Point& p) - : Point(p.x, p.y) -{ -} -inline Size::Size(const WSAPI_Size& s) - : Size(s.width, s.height) -{ -} -inline Rect::operator WSAPI_Rect() const { return { m_location, m_size }; } -inline Point::operator WSAPI_Point() const { return { m_x, m_y }; } -inline Size::operator WSAPI_Size() const { return { m_width, m_height }; } diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 4ea53cbfeb8..0adb383ca0b 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -13,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -42,7 +42,7 @@ WSClientConnection* WSClientConnection::from_client_id(int client_id) } WSClientConnection::WSClientConnection(CLocalSocket& client_socket, int client_id) - : Connection(client_socket, client_id) + : ConnectionNG(*this, client_socket, client_id) { if (!s_connections) s_connections = new HashMap>; @@ -54,16 +54,6 @@ WSClientConnection::~WSClientConnection() auto windows = move(m_windows); } -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::die() { s_connections->remove(client_id()); @@ -72,642 +62,327 @@ void WSClientConnection::die() void WSClientConnection::post_error(const String& error_message) { dbgprintf("WSClientConnection::post_error: client_id=%d: %s\n", client_id(), error_message.characters()); - WSAPI_ServerMessage message; - message.type = WSAPI_ServerMessage::Type::Error; - ASSERT(error_message.length() < (ssize_t)sizeof(message.text)); - strcpy(message.text, error_message.characters()); - message.text_length = error_message.length(); - post_message(message); + did_misbehave(); } void WSClientConnection::notify_about_new_screen_rect(const Rect& rect) { - WSAPI_ServerMessage message; - message.type = WSAPI_ServerMessage::Type::ScreenRectChanged; - message.screen.rect = rect; - post_message(message); + post_message(WindowClient::ScreenRectChanged(rect)); } void WSClientConnection::notify_about_clipboard_contents_changed() { - auto& clipboard = WSClipboard::the(); - WSAPI_ServerMessage message; - message.type = WSAPI_ServerMessage::Type::ClipboardContentsChanged; - message.clipboard.shared_buffer_id = -1; - message.clipboard.contents_size = -1; - ASSERT(clipboard.data_type().length() < (ssize_t)sizeof(message.text)); - strcpy(message.text, clipboard.data_type().characters()); - message.text_length = clipboard.data_type().length(); - post_message(message); + post_message(WindowClient::ClipboardContentsChanged(WSClipboard::the().data_type())); } -void WSClientConnection::event(CEvent& event) -{ - if (static_cast(event).is_client_request()) { - on_request(static_cast(event)); - return; - } - - Connection::event(event); -} - -static Vector get_rects(const WSAPI_ClientMessage& message, const ByteBuffer& extra_data) -{ - Vector rects; - if (message.rect_count > (int)(WSAPI_ClientMessage::max_inline_rect_count + extra_data.size() / sizeof(WSAPI_Rect))) { - return {}; - } - for (int i = 0; i < min(WSAPI_ClientMessage::max_inline_rect_count, message.rect_count); ++i) - rects.append(message.rects[i]); - if (!extra_data.is_empty()) { - auto* extra_rects = reinterpret_cast(extra_data.data()); - for (int i = 0; i < (int)(extra_data.size() / sizeof(WSAPI_Rect)); ++i) - rects.append(extra_rects[i]); - } - return rects; -} - -bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, const ByteBuffer&& extra_data) -{ - switch (message.type) { - case WSAPI_ClientMessage::Type::Greeting: - set_client_pid(message.greeting.client_pid); - break; - case WSAPI_ClientMessage::Type::CreateMenubar: - CEventLoop::current().post_event(*this, make(client_id())); - break; - case WSAPI_ClientMessage::Type::DestroyMenubar: - CEventLoop::current().post_event(*this, make(client_id(), message.menu.menubar_id)); - break; - case WSAPI_ClientMessage::Type::SetApplicationMenubar: - CEventLoop::current().post_event(*this, make(client_id(), message.menu.menubar_id)); - break; - case WSAPI_ClientMessage::Type::AddMenuToMenubar: - CEventLoop::current().post_event(*this, make(client_id(), message.menu.menubar_id, message.menu.menu_id)); - break; - case WSAPI_ClientMessage::Type::CreateMenu: - if (message.text_length > (int)sizeof(message.text)) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(client_id(), String(message.text, message.text_length))); - break; - case WSAPI_ClientMessage::Type::PopupMenu: - CEventLoop::current().post_event(*this, make(client_id(), message.menu.menu_id, message.menu.position)); - break; - case WSAPI_ClientMessage::Type::DismissMenu: - CEventLoop::current().post_event(*this, make(client_id(), message.menu.menu_id)); - break; - case WSAPI_ClientMessage::Type::SetWindowIconBitmap: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, message.window.icon_buffer_id, message.window.icon_size)); - break; - case WSAPI_ClientMessage::Type::DestroyMenu: - CEventLoop::current().post_event(*this, make(client_id(), message.menu.menu_id)); - break; - case WSAPI_ClientMessage::Type::AddMenuItem: - if (message.text_length > (int)sizeof(message.text)) { - did_misbehave(); - return false; - } - if (message.menu.shortcut_text_length > (int)sizeof(message.menu.shortcut_text)) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(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, message.menu.icon_buffer_id, message.menu.submenu_id)); - break; - case WSAPI_ClientMessage::Type::UpdateMenuItem: - if (message.text_length > (int)sizeof(message.text)) { - did_misbehave(); - return false; - } - if (message.menu.shortcut_text_length > (int)sizeof(message.menu.shortcut_text)) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(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; - case WSAPI_ClientMessage::Type::AddMenuSeparator: - CEventLoop::current().post_event(*this, make(client_id(), message.menu.menu_id)); - break; - case WSAPI_ClientMessage::Type::CreateWindow: { - if (message.text_length > (int)sizeof(message.text)) { - did_misbehave(); - return false; - } - - auto ws_window_type = WSWindowType::Invalid; - switch (message.window.type) { - case WSAPI_WindowType::Normal: - ws_window_type = WSWindowType::Normal; - break; - case WSAPI_WindowType::Menu: - ws_window_type = WSWindowType::Menu; - break; - case WSAPI_WindowType::WindowSwitcher: - ws_window_type = WSWindowType::WindowSwitcher; - break; - case WSAPI_WindowType::Taskbar: - ws_window_type = WSWindowType::Taskbar; - break; - case WSAPI_WindowType::Tooltip: - ws_window_type = WSWindowType::Tooltip; - break; - case WSAPI_WindowType::Menubar: - ws_window_type = WSWindowType::Menubar; - break; - case WSAPI_WindowType::Invalid: - default: - dbgprintf("Unknown WSAPI_WindowType: %d\n", message.window.type); - did_misbehave(); - return false; - } - - CEventLoop::current().post_event(*this, - make(client_id(), - message.window.rect, - String(message.text, message.text_length), - message.window.has_alpha_channel, - message.window.modal, - message.window.resizable, - message.window.fullscreen, - message.window.show_titlebar, - message.window.opacity, - message.window.base_size, - message.window.size_increment, - ws_window_type, - Color::from_rgba(message.window.background_color))); - break; - } - case WSAPI_ClientMessage::Type::DestroyWindow: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id)); - break; - case WSAPI_ClientMessage::Type::SetWindowTitle: - if (message.text_length > (int)sizeof(message.text)) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, String(message.text, message.text_length))); - break; - case WSAPI_ClientMessage::Type::GetWindowTitle: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id)); - break; - case WSAPI_ClientMessage::Type::SetWindowRect: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, message.window.rect)); - break; - case WSAPI_ClientMessage::Type::GetWindowRect: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id)); - break; - case WSAPI_ClientMessage::Type::SetClipboardContents: - if (message.text_length > (int)sizeof(message.text)) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(client_id(), message.clipboard.shared_buffer_id, message.clipboard.contents_size, String(message.text, message.text_length))); - break; - case WSAPI_ClientMessage::Type::GetClipboardContents: - CEventLoop::current().post_event(*this, make(client_id())); - break; - case WSAPI_ClientMessage::Type::InvalidateRect: { - auto rects = get_rects(message, extra_data); - if (rects.is_empty()) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, rects)); - break; - } - case WSAPI_ClientMessage::Type::DidFinishPainting: { - auto rects = get_rects(message, extra_data); - if (rects.is_empty()) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, rects)); - break; - } - case WSAPI_ClientMessage::Type::SetWindowBackingStore: - CEventLoop::current().post_event(*this, make(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; - case WSAPI_ClientMessage::Type::SetGlobalCursorTracking: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, message.value)); - break; - case WSAPI_ClientMessage::Type::SetWallpaper: - if (message.text_length > (int)sizeof(message.text)) { - did_misbehave(); - return false; - } - CEventLoop::current().post_event(*this, make(client_id(), String(message.text, message.text_length))); - break; - case WSAPI_ClientMessage::Type::GetWallpaper: - CEventLoop::current().post_event(*this, make(client_id())); - break; - case WSAPI_ClientMessage::Type::SetResolution: - CEventLoop::current().post_event(*this, make(client_id(), message.wm_conf.resolution.width, message.wm_conf.resolution.height)); - break; - case WSAPI_ClientMessage::Type::SetWindowOverrideCursor: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, (WSStandardCursor)message.cursor.cursor)); - break; - case WSAPI_ClientMessage::SetWindowHasAlphaChannel: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, message.value)); - break; - case WSAPI_ClientMessage::Type::WM_SetActiveWindow: - CEventLoop::current().post_event(*this, make(client_id(), message.wm.client_id, message.wm.window_id)); - break; - case WSAPI_ClientMessage::Type::WM_SetWindowMinimized: - CEventLoop::current().post_event(*this, make(client_id(), message.wm.client_id, message.wm.window_id, message.wm.minimized)); - break; - case WSAPI_ClientMessage::Type::WM_StartWindowResize: - CEventLoop::current().post_event(*this, make(client_id(), message.wm.client_id, message.wm.window_id)); - break; - case WSAPI_ClientMessage::Type::WM_PopupWindowMenu: - CEventLoop::current().post_event(*this, make(client_id(), message.wm.client_id, message.wm.window_id, message.wm.position)); - break; - case WSAPI_ClientMessage::Type::MoveWindowToFront: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id)); - break; - case WSAPI_ClientMessage::Type::SetFullscreen: - CEventLoop::current().post_event(*this, make(client_id(), message.window_id, message.value)); - break; - default: - break; - } - return true; -} - -void WSClientConnection::handle_request(const WSAPICreateMenubarRequest&) +OwnPtr WSClientConnection::handle(const WindowServer::CreateMenubar&) { int menubar_id = m_next_menubar_id++; auto menubar = make(*this, menubar_id); m_menubars.set(menubar_id, move(menubar)); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidCreateMenubar; - response.menu.menubar_id = menubar_id; - post_message(response); + return make(menubar_id); } -void WSClientConnection::handle_request(const WSAPIDestroyMenubarRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::DestroyMenubar& message) { - int menubar_id = request.menubar_id(); + int menubar_id = message.menubar_id(); auto it = m_menubars.find(menubar_id); if (it == m_menubars.end()) { post_error("WSAPIDestroyMenubarRequest: Bad menubar ID"); - return; + return make(); } auto& menubar = *(*it).value; WSWindowManager::the().close_menubar(menubar); m_menubars.remove(it); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidDestroyMenubar; - response.menu.menubar_id = menubar_id; - post_message(response); + return make(); } -void WSClientConnection::handle_request(const WSAPICreateMenuRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::CreateMenu& message) { int menu_id = m_next_menu_id++; - auto menu = WSMenu::construct(this, menu_id, request.text()); + auto menu = WSMenu::construct(this, menu_id, message.menu_title()); m_menus.set(menu_id, move(menu)); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidCreateMenu; - response.menu.menu_id = menu_id; - post_message(response); + dbg() << "Created menu ID " << menu_id << " (" << message.menu_title() << ")"; + return make(menu_id); } -void WSClientConnection::handle_request(const WSAPIDestroyMenuRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::DestroyMenu& message) { - int menu_id = static_cast(request).menu_id(); + int menu_id = message.menu_id(); auto it = m_menus.find(menu_id); if (it == m_menus.end()) { post_error("WSAPIDestroyMenuRequest: Bad menu ID"); - return; + return make(); } auto& menu = *(*it).value; menu.close(); m_menus.remove(it); remove_child(menu); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidDestroyMenu; - response.menu.menu_id = menu_id; - post_message(response); + return make(); } -void WSClientConnection::handle_request(const WSAPISetApplicationMenubarRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetApplicationMenubar& message) { - int menubar_id = request.menubar_id(); + int menubar_id = message.menubar_id(); auto it = m_menubars.find(menubar_id); if (it == m_menubars.end()) { post_error("WSAPISetApplicationMenubarRequest: Bad menubar ID"); - return; + return make(); } auto& menubar = *(*it).value; m_app_menubar = menubar.make_weak_ptr(); WSWindowManager::the().notify_client_changed_app_menubar(*this); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetApplicationMenubar; - response.menu.menubar_id = menubar_id; - post_message(response); + return make(); } -void WSClientConnection::handle_request(const WSAPIAddMenuToMenubarRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::AddMenuToMenubar& message) { - int menubar_id = request.menubar_id(); - int menu_id = request.menu_id(); + int menubar_id = message.menubar_id(); + int menu_id = message.menu_id(); auto it = m_menubars.find(menubar_id); auto jt = m_menus.find(menu_id); if (it == m_menubars.end()) { post_error("WSAPIAddMenuToMenubarRequest: Bad menubar ID"); - return; + return make(); } if (jt == m_menus.end()) { post_error("WSAPIAddMenuToMenubarRequest: Bad menu ID"); - return; + return make(); } auto& menubar = *(*it).value; auto& menu = *(*jt).value; menubar.add_menu(menu); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidAddMenuToMenubar; - response.menu.menubar_id = menubar_id; - response.menu.menu_id = menu_id; - post_message(response); + return make(); } -void WSClientConnection::handle_request(const WSAPIAddMenuItemRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::AddMenuItem& message) { - int menu_id = request.menu_id(); - unsigned identifier = request.identifier(); + int menu_id = message.menu_id(); + unsigned identifier = message.identifier(); auto it = m_menus.find(menu_id); if (it == m_menus.end()) { - post_error("WSAPIAddMenuItemRequest: Bad menu ID"); - return; + dbg() << "WSAPIAddMenuItemRequest: Bad menu ID: " << menu_id; + return make(); } auto& menu = *(*it).value; - auto menu_item = make(menu, identifier, request.text(), request.shortcut_text(), request.is_enabled(), request.is_checkable(), request.is_checked()); - if (request.icon_buffer_id() != -1) { - auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(request.icon_buffer_id()); + auto menu_item = make(menu, identifier, message.text(), message.shortcut(), message.enabled(), message.checkable(), message.checked()); + if (message.icon_buffer_id() != -1) { + auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(message.icon_buffer_id()); if (!icon_buffer) { did_misbehave(); - return; + return make(); } // FIXME: Verify that the icon buffer can accomodate a 16x16 bitmap view. auto shared_icon = GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, icon_buffer.release_nonnull(), { 16, 16 }); menu_item->set_icon(shared_icon); } - menu_item->set_submenu_id(request.submenu_id()); + menu_item->set_submenu_id(message.submenu_id()); menu.add_item(move(menu_item)); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidAddMenuItem; - response.menu.menu_id = menu_id; - response.menu.identifier = identifier; - post_message(response); + return make(); } -void WSClientConnection::handle_request(const WSAPIPopupMenuRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::PopupMenu& message) { - int menu_id = request.menu_id(); - auto position = request.position(); + int menu_id = message.menu_id(); + auto position = message.screen_position(); auto it = m_menus.find(menu_id); if (it == m_menus.end()) { post_error("WSAPIPopupMenuRequest: Bad menu ID"); - return; + return make(); } auto& menu = *(*it).value; menu.popup(position); + return make(); } -void WSClientConnection::handle_request(const WSAPIDismissMenuRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::DismissMenu& message) { - int menu_id = request.menu_id(); + int menu_id = message.menu_id(); auto it = m_menus.find(menu_id); if (it == m_menus.end()) { post_error("WSAPIDismissMenuRequest: Bad menu ID"); - return; + return make(); } auto& menu = *(*it).value; menu.close(); + return make(); } -void WSClientConnection::handle_request(const WSAPIUpdateMenuItemRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::UpdateMenuItem& message) { - int menu_id = request.menu_id(); - unsigned identifier = request.identifier(); + int menu_id = message.menu_id(); auto it = m_menus.find(menu_id); if (it == m_menus.end()) { post_error("WSAPIUpdateMenuItemRequest: Bad menu ID"); - return; + return make(); } auto& menu = *(*it).value; - auto* menu_item = menu.item_with_identifier(request.identifier()); + auto* menu_item = menu.item_with_identifier(message.identifier()); if (!menu_item) { post_error("WSAPIUpdateMenuItemRequest: Bad menu item identifier"); - return; + return make(); } - menu_item->set_text(request.text()); - menu_item->set_shortcut_text(request.shortcut_text()); - menu_item->set_enabled(request.is_enabled()); - menu_item->set_checkable(request.is_checkable()); - if (request.is_checkable()) - menu_item->set_checked(request.is_checked()); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidUpdateMenuItem; - response.menu.menu_id = menu_id; - response.menu.identifier = identifier; - post_message(response); + menu_item->set_text(message.text()); + menu_item->set_shortcut_text(message.shortcut()); + menu_item->set_enabled(message.enabled()); + menu_item->set_checkable(message.checkable()); + if (message.checkable()) + menu_item->set_checked(message.checked()); + return make(); } -void WSClientConnection::handle_request(const WSAPIAddMenuSeparatorRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::AddMenuSeparator& message) { - int menu_id = request.menu_id(); + int menu_id = message.menu_id(); auto it = m_menus.find(menu_id); if (it == m_menus.end()) { post_error("WSAPIAddMenuSeparatorRequest: Bad menu ID"); - return; + return make(); } auto& menu = *(*it).value; menu.add_item(make(menu, WSMenuItem::Separator)); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidAddMenuSeparator; - response.menu.menu_id = menu_id; - post_message(response); + return make(); } -void WSClientConnection::handle_request(const WSAPIMoveWindowToFrontRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::MoveWindowToFront& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPIMoveWindowToFrontRequest: Bad window ID"); - return; + return make(); } - auto& window = *(*it).value; - WSWindowManager::the().move_to_front_and_make_active(window); + WSWindowManager::the().move_to_front_and_make_active(*(*it).value); + return make(); } -void WSClientConnection::handle_request(const WSAPISetFullscreenRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetFullscreen& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPISetFullscreenRequest: Bad window ID"); - return; + return make(); } - auto& window = *(*it).value; - window.set_fullscreen(request.fullscreen()); - - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetFullscreen; - response.window_id = window_id; - post_message(response); + it->value->set_fullscreen(message.fullscreen()); + return make(); } -void WSClientConnection::handle_request(const WSAPISetWindowOpacityRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetWindowOpacity& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPISetWindowOpacityRequest: Bad window ID"); - return; + return make(); } - auto& window = *(*it).value; - window.set_opacity(request.opacity()); + it->value->set_opacity(message.opacity()); + return make(); } -void WSClientConnection::handle_request(const WSAPISetWallpaperRequest& request) +void WSClientConnection::handle(const WindowServer::AsyncSetWallpaper& message) { - WSCompositor::the().set_wallpaper(request.wallpaper(), [&](bool success) { - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetWallpaper; - response.value = success; - post_message(response); + WSCompositor::the().set_wallpaper(message.path(), [&](bool success) { + post_message(WindowClient::AsyncSetWallpaperFinished(success)); }); } -void WSClientConnection::handle_request(const WSAPIGetWallpaperRequest&) +OwnPtr WSClientConnection::handle(const WindowServer::GetWallpaper&) { - auto path = WSCompositor::the().wallpaper_path(); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidGetWallpaper; - ASSERT(path.length() < (int)sizeof(response.text)); - memcpy(response.text, path.characters(), path.length() + 1); - response.text_length = path.length(); - post_message(response); + return make(WSCompositor::the().wallpaper_path()); } -void WSClientConnection::handle_request(const WSAPISetResolutionRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetResolution& message) { - WSWindowManager::the().set_resolution(request.resolution().width(), request.resolution().height()); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetResolution; - response.value = true; - post_message(response); + WSWindowManager::the().set_resolution(message.resolution().width(), message.resolution().height()); + return make(); } -void WSClientConnection::handle_request(const WSAPISetWindowTitleRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetWindowTitle& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPISetWindowTitleRequest: Bad window ID"); - return; + return make(); } - auto& window = *(*it).value; - window.set_title(request.title()); + it->value->set_title(message.title()); + return make(); } -void WSClientConnection::handle_request(const WSAPIGetWindowTitleRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::GetWindowTitle& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPIGetWindowTitleRequest: Bad window ID"); - return; + return make(""); } - auto& window = *(*it).value; - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidGetWindowTitle; - response.window_id = window.window_id(); - ASSERT(window.title().length() < (ssize_t)sizeof(response.text)); - strcpy(response.text, window.title().characters()); - response.text_length = window.title().length(); - post_message(response); + return make(it->value->title()); } -void WSClientConnection::handle_request(const WSAPISetWindowIconBitmapRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetWindowIconBitmap& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPISetWindowIconBitmapRequest: Bad window ID"); - return; + return make(); } auto& window = *(*it).value; - auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(request.icon_buffer_id()); + auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(message.icon_buffer_id()); if (!icon_buffer) { window.set_default_icon(); } else { - window.set_icon(GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *icon_buffer, request.icon_size())); + window.set_icon(GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *icon_buffer, message.icon_size())); } window.frame().invalidate_title_bar(); WSWindowManager::the().tell_wm_listeners_window_icon_changed(window); + return make(); } -void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetWindowRect& message) { - int window_id = request.window_id(); + int window_id = message.window_id(); auto it = m_windows.find(window_id); if (it == m_windows.end()) { post_error("WSAPISetWindowRectRequest: Bad window ID"); - return; + return make(); } auto& window = *(*it).value; if (window.is_fullscreen()) { dbgprintf("WSClientConnection: Ignoring SetWindowRect request for fullscreen window\n"); - return; + return make(); } - window.set_rect(request.rect()); - window.request_update(request.rect()); + window.set_rect(message.rect()); + window.request_update(message.rect()); + return make(); } -void WSClientConnection::handle_request(const WSAPIGetWindowRectRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::GetWindowRect& message) { - int window_id = request.window_id(); + int window_id = message.window_id(); auto it = m_windows.find(window_id); if (it == m_windows.end()) { post_error("WSAPIGetWindowRectRequest: Bad window ID"); - return; + return make(Rect()); } - auto& window = *(*it).value; - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidGetWindowRect; - response.window_id = window.window_id(); - response.window.rect = window.rect(); - post_message(response); + return make(it->value->rect()); } -void WSClientConnection::handle_request(const WSAPISetClipboardContentsRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetClipboardContents& message) { - auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(request.shared_buffer_id()); + auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(message.shared_buffer_id()); if (!shared_buffer) { post_error("WSAPISetClipboardContentsRequest: Bad shared buffer ID"); - return; + return make(); } - WSClipboard::the().set_data(*shared_buffer, request.size(), request.data_type()); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetClipboardContents; - response.clipboard.shared_buffer_id = shared_buffer->shared_buffer_id(); - post_message(response); + WSClipboard::the().set_data(*shared_buffer, message.content_size(), message.content_type()); + return make(); } -void WSClientConnection::handle_request(const WSAPIGetClipboardContentsRequest&) +OwnPtr WSClientConnection::handle(const WindowServer::GetClipboardContents&) { auto& clipboard = WSClipboard::the(); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidGetClipboardContents; - response.clipboard.shared_buffer_id = -1; - response.clipboard.contents_size = 0; + + i32 shared_buffer_id = -1; if (clipboard.size()) { // 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. @@ -717,59 +392,47 @@ void WSClientConnection::handle_request(const WSAPIGetClipboardContentsRequest&) memcpy(shared_buffer->data(), clipboard.data(), clipboard.size()); shared_buffer->seal(); shared_buffer->share_with(client_pid()); - response.clipboard.shared_buffer_id = shared_buffer->shared_buffer_id(); - response.clipboard.contents_size = clipboard.size(); + shared_buffer_id = shared_buffer->shared_buffer_id(); // FIXME: This is a workaround for the fact that SharedBuffers will go away if neither side is retaining them. // After we respond to GetClipboardContents, we have to wait for the client to ref the buffer on his side. m_last_sent_clipboard_content = move(shared_buffer); } - ASSERT(clipboard.data_type().length() < (ssize_t)sizeof(response.text)); - if (!clipboard.data_type().is_null()) - strcpy(response.text, clipboard.data_type().characters()); - response.text_length = clipboard.data_type().length(); - post_message(response); + return make(shared_buffer_id, clipboard.size(), clipboard.data_type()); } -void WSClientConnection::handle_request(const WSAPICreateWindowRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::CreateWindow& message) { int window_id = m_next_window_id++; - auto window = WSWindow::construct(*this, request.window_type(), window_id, request.is_modal(), request.is_resizable(), request.is_fullscreen()); - window->set_background_color(request.background_color()); - window->set_has_alpha_channel(request.has_alpha_channel()); - window->set_title(request.title()); - if (!request.is_fullscreen()) - window->set_rect(request.rect()); - window->set_show_titlebar(request.show_titlebar()); - window->set_opacity(request.opacity()); - window->set_size_increment(request.size_increment()); - window->set_base_size(request.base_size()); + auto window = WSWindow::construct(*this, (WSWindowType)message.type(), window_id, message.modal(), message.resizable(), message.fullscreen()); + window->set_background_color(message.background_color()); + window->set_has_alpha_channel(message.has_alpha_channel()); + window->set_title(message.title()); + if (!message.fullscreen()) + window->set_rect(message.rect()); + window->set_show_titlebar(message.show_titlebar()); + window->set_opacity(message.opacity()); + window->set_size_increment(message.size_increment()); + window->set_base_size(message.base_size()); window->invalidate(); m_windows.set(window_id, move(window)); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidCreateWindow; - response.window_id = window_id; - post_message(response); + return make(window_id); } -void WSClientConnection::handle_request(const WSAPIDestroyWindowRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::DestroyWindow& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPIDestroyWindowRequest: Bad window ID"); - return; + return make(); } auto& window = *(*it).value; WSWindowManager::the().invalidate(window); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidDestroyWindow; - response.window_id = window.window_id(); - post_message(response); - remove_child(window); ASSERT(it->value.ptr() == &window); - m_windows.remove(window_id); + m_windows.remove(message.window_id()); + + return make(); } void WSClientConnection::post_paint_message(WSWindow& window) @@ -777,130 +440,113 @@ void WSClientConnection::post_paint_message(WSWindow& window) auto rect_set = window.take_pending_paint_rects(); if (window.is_minimized()) return; - WSAPI_ServerMessage message; - message.type = WSAPI_ServerMessage::Type::Paint; - message.window_id = window.window_id(); - auto& rects = rect_set.rects(); - message.rect_count = rects.size(); - for (int i = 0; i < min(WSAPI_ServerMessage::max_inline_rect_count, rects.size()); ++i) - message.rects[i] = rects[i]; - message.paint.window_size = window.size(); - ByteBuffer extra_data; - if (rects.size() > WSAPI_ServerMessage::max_inline_rect_count) - extra_data = ByteBuffer::wrap(&rects[WSAPI_ServerMessage::max_inline_rect_count], (rects.size() - WSAPI_ServerMessage::max_inline_rect_count) * sizeof(WSAPI_Rect)); - post_message(message, extra_data); + + Vector rects; + rects.ensure_capacity(rect_set.size()); + for (auto& r : rect_set.rects()) { + rects.append(r); + } + post_message(WindowClient::Paint(window.window_id(), window.size(), rects)); } -void WSClientConnection::handle_request(const WSAPIInvalidateRectRequest& request) +void WSClientConnection::handle(const WindowServer::InvalidateRect& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPIInvalidateRectRequest: Bad window ID"); return; } auto& window = *(*it).value; - for (int i = 0; i < request.rects().size(); ++i) - window.request_update(request.rects()[i].intersected({ {}, window.size() })); + for (int i = 0; i < message.rects().size(); ++i) + window.request_update(message.rects()[i].intersected({ {}, window.size() })); } -void WSClientConnection::handle_request(const WSAPIDidFinishPaintingNotification& request) +void WSClientConnection::handle(const WindowServer::DidFinishPainting& message) { - int window_id = request.window_id(); + int window_id = message.window_id(); auto it = m_windows.find(window_id); if (it == m_windows.end()) { post_error("WSAPIDidFinishPaintingNotification: Bad window ID"); return; } auto& window = *(*it).value; - for (auto& rect : request.rects()) + for (auto& rect : message.rects()) WSWindowManager::the().invalidate(window, rect); WSWindowSwitcher::the().refresh_if_needed(); } -void WSClientConnection::handle_request(const WSAPISetWindowBackingStoreRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetWindowBackingStore& message) { - int window_id = request.window_id(); + int window_id = message.window_id(); auto it = m_windows.find(window_id); if (it == m_windows.end()) { post_error("WSAPISetWindowBackingStoreRequest: Bad window ID"); - return; + return make(); } auto& window = *(*it).value; - if (window.last_backing_store() && window.last_backing_store()->shared_buffer_id() == request.shared_buffer_id()) { + if (window.last_backing_store() && window.last_backing_store()->shared_buffer_id() == message.shared_buffer_id()) { window.swap_backing_stores(); } else { - auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(request.shared_buffer_id()); + auto shared_buffer = SharedBuffer::create_from_shared_buffer_id(message.shared_buffer_id()); if (!shared_buffer) - return; + return make(); auto backing_store = GraphicsBitmap::create_with_shared_buffer( - request.has_alpha_channel() ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32, + message.has_alpha_channel() ? GraphicsBitmap::Format::RGBA32 : GraphicsBitmap::Format::RGB32, *shared_buffer, - request.size()); + message.size()); window.set_backing_store(move(backing_store)); } - if (request.flush_immediately()) + if (message.flush_immediately()) window.invalidate(); - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetWindowBackingStore; - response.window_id = window_id; - response.backing.shared_buffer_id = request.shared_buffer_id(); - post_message(response); + return make(); } -void WSClientConnection::handle_request(const WSAPISetGlobalCursorTrackingRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetGlobalCursorTracking& message) { - int window_id = request.window_id(); + int window_id = message.window_id(); auto it = m_windows.find(window_id); if (it == m_windows.end()) { post_error("WSAPISetGlobalCursorTrackingRequest: Bad window ID"); - return; + return make(); } - auto& window = *(*it).value; - window.set_global_cursor_tracking_enabled(request.value()); + it->value->set_global_cursor_tracking_enabled(message.enabled()); + return make(); } -void WSClientConnection::handle_request(const WSAPISetWindowOverrideCursorRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetWindowOverrideCursor& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPISetWindowOverrideCursorRequest: Bad window ID"); - return; + return make(); } auto& window = *(*it).value; - window.set_override_cursor(WSCursor::create(request.cursor())); + window.set_override_cursor(WSCursor::create((WSStandardCursor)message.cursor_type())); + return make(); } -void WSClientConnection::handle_request(const WSAPISetWindowHasAlphaChannelRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::SetWindowHasAlphaChannel& message) { - int window_id = request.window_id(); - auto it = m_windows.find(window_id); + auto it = m_windows.find(message.window_id()); if (it == m_windows.end()) { post_error("WSAPISetWindowHasAlphaChannelRequest: Bad window ID"); - return; + return make(); } - auto& window = *(*it).value; - window.set_has_alpha_channel(request.value()); - - WSAPI_ServerMessage response; - response.type = WSAPI_ServerMessage::Type::DidSetWindowHasAlphaChannel; - response.window_id = window_id; - response.value = request.value(); - post_message(response); + it->value->set_has_alpha_channel(message.has_alpha_channel()); + return make(); } -void WSClientConnection::handle_request(const WSWMAPISetActiveWindowRequest& request) +void WSClientConnection::handle(const WindowServer::WM_SetActiveWindow& message) { - auto* client = WSClientConnection::from_client_id(request.target_client_id()); + auto* client = WSClientConnection::from_client_id(message.client_id()); if (!client) { post_error("WSWMAPISetActiveWindowRequest: Bad client ID"); return; } - auto it = client->m_windows.find(request.target_window_id()); + auto it = client->m_windows.find(message.window_id()); if (it == client->m_windows.end()) { post_error("WSWMAPISetActiveWindowRequest: Bad window ID"); return; @@ -910,30 +556,30 @@ void WSClientConnection::handle_request(const WSWMAPISetActiveWindowRequest& req WSWindowManager::the().move_to_front_and_make_active(window); } -void WSClientConnection::handle_request(const WSWMAPIPopupWindowMenuRequest& request) +void WSClientConnection::handle(const WindowServer::WM_PopupWindowMenu& message) { - auto* client = WSClientConnection::from_client_id(request.target_client_id()); + auto* client = WSClientConnection::from_client_id(message.client_id()); if (!client) { post_error("WSWMAPIPopupWindowMenuRequest: Bad client ID"); return; } - auto it = client->m_windows.find(request.target_window_id()); + auto it = client->m_windows.find(message.window_id()); if (it == client->m_windows.end()) { post_error("WSWMAPIPopupWindowMenuRequest: Bad window ID"); return; } auto& window = *(*it).value; - window.popup_window_menu(request.position()); + window.popup_window_menu(message.screen_position()); } -void WSClientConnection::handle_request(const WSWMAPIStartWindowResizeRequest& request) +void WSClientConnection::handle(const WindowServer::WM_StartWindowResize& request) { - auto* client = WSClientConnection::from_client_id(request.target_client_id()); + auto* client = WSClientConnection::from_client_id(request.client_id()); if (!client) { post_error("WSWMAPIStartWindowResizeRequest: Bad client ID"); return; } - auto it = client->m_windows.find(request.target_window_id()); + auto it = client->m_windows.find(request.window_id()); if (it == client->m_windows.end()) { post_error("WSWMAPIStartWindowResizeRequest: Bad window ID"); return; @@ -944,100 +590,26 @@ void WSClientConnection::handle_request(const WSWMAPIStartWindowResizeRequest& r WSWindowManager::the().start_window_resize(window, WSScreen::the().cursor_location(), MouseButton::Left); } -void WSClientConnection::handle_request(const WSWMAPISetWindowMinimizedRequest& request) +void WSClientConnection::handle(const WindowServer::WM_SetWindowMinimized& message) { - auto* client = WSClientConnection::from_client_id(request.target_client_id()); + auto* client = WSClientConnection::from_client_id(message.client_id()); if (!client) { post_error("WSWMAPISetWindowMinimizedRequest: Bad client ID"); return; } - auto it = client->m_windows.find(request.target_window_id()); + auto it = client->m_windows.find(message.window_id()); if (it == client->m_windows.end()) { post_error("WSWMAPISetWindowMinimizedRequest: Bad window ID"); return; } auto& window = *(*it).value; - window.set_minimized(request.is_minimized()); + window.set_minimized(message.minimized()); } -void WSClientConnection::on_request(const WSAPIClientRequest& request) +OwnPtr WSClientConnection::handle(const WindowServer::Greet& message) { - switch (request.type()) { - case WSEvent::APICreateMenubarRequest: - return handle_request(static_cast(request)); - case WSEvent::APIDestroyMenubarRequest: - return handle_request(static_cast(request)); - case WSEvent::APICreateMenuRequest: - return handle_request(static_cast(request)); - case WSEvent::APIDestroyMenuRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetApplicationMenubarRequest: - return handle_request(static_cast(request)); - case WSEvent::APIAddMenuToMenubarRequest: - return handle_request(static_cast(request)); - case WSEvent::APIAddMenuItemRequest: - return handle_request(static_cast(request)); - case WSEvent::APIAddMenuSeparatorRequest: - return handle_request(static_cast(request)); - case WSEvent::APIUpdateMenuItemRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWindowTitleRequest: - return handle_request(static_cast(request)); - case WSEvent::APIGetWindowTitleRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWindowRectRequest: - return handle_request(static_cast(request)); - case WSEvent::APIGetWindowRectRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWindowIconBitmapRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetClipboardContentsRequest: - return handle_request(static_cast(request)); - case WSEvent::APIGetClipboardContentsRequest: - return handle_request(static_cast(request)); - case WSEvent::APICreateWindowRequest: - return handle_request(static_cast(request)); - case WSEvent::APIDestroyWindowRequest: - return handle_request(static_cast(request)); - case WSEvent::APIInvalidateRectRequest: - return handle_request(static_cast(request)); - case WSEvent::APIDidFinishPaintingNotification: - return handle_request(static_cast(request)); - case WSEvent::APISetGlobalCursorTrackingRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWindowOpacityRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWindowBackingStoreRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWallpaperRequest: - return handle_request(static_cast(request)); - case WSEvent::APIGetWallpaperRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetResolutionRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWindowOverrideCursorRequest: - return handle_request(static_cast(request)); - case WSEvent::WMAPISetActiveWindowRequest: - return handle_request(static_cast(request)); - case WSEvent::WMAPISetWindowMinimizedRequest: - return handle_request(static_cast(request)); - case WSEvent::WMAPIStartWindowResizeRequest: - return handle_request(static_cast(request)); - case WSEvent::WMAPIPopupWindowMenuRequest: - return handle_request(static_cast(request)); - case WSEvent::APIPopupMenuRequest: - return handle_request(static_cast(request)); - case WSEvent::APIDismissMenuRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetWindowHasAlphaChannelRequest: - return handle_request(static_cast(request)); - case WSEvent::APIMoveWindowToFrontRequest: - return handle_request(static_cast(request)); - case WSEvent::APISetFullscreenRequest: - return handle_request(static_cast(request)); - default: - break; - } + set_client_pid(message.client_pid()); + return make(getpid(), client_id(), WSScreen::the().rect()); } bool WSClientConnection::is_showing_modal_window() const diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index 1cef9072b34..adbd64b9018 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -7,20 +7,20 @@ #include #include #include -#include #include +#include class WSWindow; class WSMenu; class WSMenuBar; -class WSClientConnection final : public IPC::Server::Connection { +class WSClientConnection final + : public IPC::Server::ConnectionNG + , public WindowServerEndpoint { C_OBJECT(WSClientConnection) public: ~WSClientConnection() override; - virtual void send_greeting() override; virtual void die() override; - bool handle_message(const WSAPI_ClientMessage&, const ByteBuffer&& = {}) override; static WSClientConnection* from_client_id(int client_id); static void for_each_client(Function); @@ -48,45 +48,44 @@ public: private: explicit WSClientConnection(CLocalSocket&, int client_id); - virtual void event(CEvent&) override; - void on_request(const WSAPIClientRequest&); - void handle_request(const WSAPICreateMenubarRequest&); - void handle_request(const WSAPIDestroyMenubarRequest&); - void handle_request(const WSAPICreateMenuRequest&); - void handle_request(const WSAPIDestroyMenuRequest&); - void handle_request(const WSAPISetApplicationMenubarRequest&); - void handle_request(const WSAPIAddMenuToMenubarRequest&); - void handle_request(const WSAPIAddMenuItemRequest&); - void handle_request(const WSAPIUpdateMenuItemRequest&); - void handle_request(const WSAPIAddMenuSeparatorRequest&); - void handle_request(const WSAPISetWindowTitleRequest&); - void handle_request(const WSAPIGetWindowTitleRequest&); - void handle_request(const WSAPISetWindowRectRequest&); - void handle_request(const WSAPIGetWindowRectRequest&); - void handle_request(const WSAPISetWindowIconBitmapRequest&); - void handle_request(const WSAPISetClipboardContentsRequest&); - void handle_request(const WSAPIGetClipboardContentsRequest&); - void handle_request(const WSAPICreateWindowRequest&); - void handle_request(const WSAPIDestroyWindowRequest&); - void handle_request(const WSAPIInvalidateRectRequest&); - void handle_request(const WSAPIDidFinishPaintingNotification&); - void handle_request(const WSAPISetWindowBackingStoreRequest&); - void handle_request(const WSAPISetGlobalCursorTrackingRequest&); - void handle_request(const WSAPISetWindowOpacityRequest&); - void handle_request(const WSAPISetWallpaperRequest&); - void handle_request(const WSAPIGetWallpaperRequest&); - void handle_request(const WSAPISetResolutionRequest&); - void handle_request(const WSAPISetWindowOverrideCursorRequest&); - void handle_request(const WSWMAPISetActiveWindowRequest&); - void handle_request(const WSWMAPISetWindowMinimizedRequest&); - void handle_request(const WSWMAPIStartWindowResizeRequest&); - void handle_request(const WSWMAPIPopupWindowMenuRequest&); - void handle_request(const WSAPIPopupMenuRequest&); - void handle_request(const WSAPIDismissMenuRequest&); - void handle_request(const WSAPISetWindowHasAlphaChannelRequest&); - void handle_request(const WSAPIMoveWindowToFrontRequest&); - void handle_request(const WSAPISetFullscreenRequest&); + virtual OwnPtr handle(const WindowServer::Greet&) override; + virtual OwnPtr handle(const WindowServer::CreateMenubar&) override; + virtual OwnPtr handle(const WindowServer::DestroyMenubar&) override; + virtual OwnPtr handle(const WindowServer::CreateMenu&) override; + virtual OwnPtr handle(const WindowServer::DestroyMenu&) override; + virtual OwnPtr handle(const WindowServer::AddMenuToMenubar&) override; + virtual OwnPtr handle(const WindowServer::SetApplicationMenubar&) override; + virtual OwnPtr handle(const WindowServer::AddMenuItem&) override; + virtual OwnPtr handle(const WindowServer::AddMenuSeparator&) override; + virtual OwnPtr handle(const WindowServer::UpdateMenuItem&) override; + virtual OwnPtr handle(const WindowServer::CreateWindow&) override; + virtual OwnPtr handle(const WindowServer::DestroyWindow&) override; + virtual OwnPtr handle(const WindowServer::SetWindowTitle&) override; + virtual OwnPtr handle(const WindowServer::GetWindowTitle&) override; + virtual OwnPtr handle(const WindowServer::SetWindowRect&) override; + virtual OwnPtr handle(const WindowServer::GetWindowRect&) override; + virtual void handle(const WindowServer::InvalidateRect&) override; + virtual void handle(const WindowServer::DidFinishPainting&) override; + virtual OwnPtr handle(const WindowServer::SetGlobalCursorTracking&) override; + virtual OwnPtr handle(const WindowServer::SetWindowOpacity&) override; + virtual OwnPtr handle(const WindowServer::SetWindowBackingStore&) override; + virtual OwnPtr handle(const WindowServer::GetClipboardContents&) override; + virtual OwnPtr handle(const WindowServer::SetClipboardContents&) override; + virtual void handle(const WindowServer::WM_SetActiveWindow&) override; + virtual void handle(const WindowServer::WM_SetWindowMinimized&) override; + virtual void handle(const WindowServer::WM_StartWindowResize&) override; + virtual void handle(const WindowServer::WM_PopupWindowMenu&) override; + virtual OwnPtr handle(const WindowServer::SetWindowHasAlphaChannel&) override; + virtual OwnPtr handle(const WindowServer::MoveWindowToFront&) override; + virtual OwnPtr handle(const WindowServer::SetFullscreen&) override; + virtual void handle(const WindowServer::AsyncSetWallpaper&) override; + virtual OwnPtr handle(const WindowServer::GetWallpaper&) override; + virtual OwnPtr handle(const WindowServer::SetResolution&) override; + virtual OwnPtr handle(const WindowServer::SetWindowOverrideCursor&) override; + virtual OwnPtr handle(const WindowServer::PopupMenu&) override; + virtual OwnPtr handle(const WindowServer::DismissMenu&) override; + virtual OwnPtr handle(const WindowServer::SetWindowIconBitmap&) override; void post_error(const String&); diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index 6059c784d17..0ad51bd7d63 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -1,13 +1,10 @@ #pragma once #include -#include #include #include -#include #include #include -#include #include class WSEvent : public CEvent { @@ -33,45 +30,6 @@ public: WM_WindowStateChanged, WM_WindowRectChanged, WM_WindowIconBitmapChanged, - - __Begin_API_Client_Requests, - APICreateMenubarRequest, - APIDestroyMenubarRequest, - APIAddMenuToMenubarRequest, - APISetApplicationMenubarRequest, - APICreateMenuRequest, - APIDestroyMenuRequest, - APIAddMenuItemRequest, - APIAddMenuSeparatorRequest, - APIUpdateMenuItemRequest, - APICreateWindowRequest, - APIDestroyWindowRequest, - APISetWindowTitleRequest, - APIGetWindowTitleRequest, - APISetWindowRectRequest, - APIGetWindowRectRequest, - APISetWindowIconBitmapRequest, - APIInvalidateRectRequest, - APIDidFinishPaintingNotification, - APISetGlobalCursorTrackingRequest, - APISetWindowOpacityRequest, - APISetWindowBackingStoreRequest, - APISetClipboardContentsRequest, - APIGetClipboardContentsRequest, - APISetWallpaperRequest, - APIGetWallpaperRequest, - APISetResolutionRequest, - APISetWindowOverrideCursorRequest, - APISetWindowHasAlphaChannelRequest, - APIMoveWindowToFrontRequest, - APISetFullscreenRequest, - WMAPISetActiveWindowRequest, - WMAPISetWindowMinimizedRequest, - WMAPIStartWindowResizeRequest, - WMAPIPopupWindowMenuRequest, - APIPopupMenuRequest, - APIDismissMenuRequest, - __End_API_Client_Requests, }; WSEvent() {} @@ -81,667 +39,10 @@ public: } virtual ~WSEvent() {} - bool is_client_request() const { return type() > __Begin_API_Client_Requests && type() < __End_API_Client_Requests; } bool is_mouse_event() const { return type() == MouseMove || type() == MouseDown || type() == MouseDoubleClick || type() == MouseUp || type() == MouseWheel; } bool is_key_event() const { return type() == KeyUp || type() == KeyDown; } }; -class WSAPIClientRequest : public WSEvent { -public: - WSAPIClientRequest(Type type, int client_id) - : WSEvent(type) - , m_client_id(client_id) - { - } - - int client_id() const { return m_client_id; } - -private: - int m_client_id { 0 }; -}; - -class WSWMAPIStartWindowResizeRequest : public WSAPIClientRequest { -public: - WSWMAPIStartWindowResizeRequest(int client_id, int target_client_id, int target_window_id) - : WSAPIClientRequest(WSEvent::WMAPIStartWindowResizeRequest, client_id) - , m_target_client_id(target_client_id) - , m_target_window_id(target_window_id) - { - } - - int target_client_id() const { return m_target_client_id; } - int target_window_id() const { return m_target_window_id; } - -private: - int m_target_client_id; - int m_target_window_id; -}; - -class WSWMAPIPopupWindowMenuRequest : public WSAPIClientRequest { -public: - WSWMAPIPopupWindowMenuRequest(int client_id, int target_client_id, int target_window_id, const Point& position) - : WSAPIClientRequest(WSEvent::WMAPIPopupWindowMenuRequest, client_id) - , m_target_client_id(target_client_id) - , m_target_window_id(target_window_id) - , m_position(position) - { - } - - int target_client_id() const { return m_target_client_id; } - int target_window_id() const { return m_target_window_id; } - Point position() const { return m_position; } - -private: - int m_target_client_id; - int m_target_window_id; - Point m_position; -}; - -class WSWMAPISetActiveWindowRequest : public WSAPIClientRequest { -public: - WSWMAPISetActiveWindowRequest(int client_id, int target_client_id, int target_window_id) - : WSAPIClientRequest(WSEvent::WMAPISetActiveWindowRequest, client_id) - , m_target_client_id(target_client_id) - , m_target_window_id(target_window_id) - { - } - - int target_client_id() const { return m_target_client_id; } - int target_window_id() const { return m_target_window_id; } - -private: - int m_target_client_id; - int m_target_window_id; -}; - -class WSWMAPISetWindowMinimizedRequest : public WSAPIClientRequest { -public: - WSWMAPISetWindowMinimizedRequest(int client_id, int target_client_id, int target_window_id, bool minimized) - : WSAPIClientRequest(WSEvent::WMAPISetWindowMinimizedRequest, client_id) - , m_target_client_id(target_client_id) - , m_target_window_id(target_window_id) - , m_minimized(minimized) - { - } - - int target_client_id() const { return m_target_client_id; } - int target_window_id() const { return m_target_window_id; } - bool is_minimized() const { return m_minimized; } - -private: - int m_target_client_id; - int m_target_window_id; - bool m_minimized; -}; - -class WSAPISetGlobalCursorTrackingRequest : public WSAPIClientRequest { -public: - WSAPISetGlobalCursorTrackingRequest(int client_id, int window_id, bool value) - : WSAPIClientRequest(WSEvent::APISetGlobalCursorTrackingRequest, client_id) - , m_window_id(window_id) - , m_value(value) - { - } - - int window_id() const { return m_window_id; } - bool value() const { return m_value; } - -private: - int m_window_id { 0 }; - bool m_value { false }; -}; - -class WSAPICreateMenubarRequest : public WSAPIClientRequest { -public: - WSAPICreateMenubarRequest(int client_id) - : WSAPIClientRequest(WSEvent::APICreateMenubarRequest, client_id) - { - } -}; - -class WSAPIDestroyMenubarRequest : public WSAPIClientRequest { -public: - WSAPIDestroyMenubarRequest(int client_id, int menubar_id) - : WSAPIClientRequest(WSEvent::APIDestroyMenubarRequest, client_id) - , m_menubar_id(menubar_id) - { - } - - int menubar_id() const { return m_menubar_id; } - -private: - int m_menubar_id { 0 }; -}; - -class WSAPISetApplicationMenubarRequest : public WSAPIClientRequest { -public: - WSAPISetApplicationMenubarRequest(int client_id, int menubar_id) - : WSAPIClientRequest(WSEvent::APISetApplicationMenubarRequest, client_id) - , m_menubar_id(menubar_id) - { - } - - int menubar_id() const { return m_menubar_id; } - -private: - int m_menubar_id { 0 }; -}; - -class WSAPIAddMenuToMenubarRequest : public WSAPIClientRequest { -public: - WSAPIAddMenuToMenubarRequest(int client_id, int menubar_id, int menu_id) - : WSAPIClientRequest(WSEvent::APIAddMenuToMenubarRequest, client_id) - , m_menubar_id(menubar_id) - , m_menu_id(menu_id) - { - } - - int menubar_id() const { return m_menubar_id; } - int menu_id() const { return m_menu_id; } - -private: - int m_menubar_id { 0 }; - int m_menu_id { 0 }; -}; - -class WSAPIPopupMenuRequest : public WSAPIClientRequest { -public: - WSAPIPopupMenuRequest(int client_id, int menu_id, const Point& position) - : WSAPIClientRequest(WSEvent::APIPopupMenuRequest, client_id) - , m_menu_id(menu_id) - , m_position(position) - { - } - - int menu_id() const { return m_menu_id; } - Point position() const { return m_position; } - -private: - int m_menu_id; - Point m_position; -}; - -class WSAPIDismissMenuRequest : public WSAPIClientRequest { -public: - WSAPIDismissMenuRequest(int client_id, int menu_id) - : WSAPIClientRequest(WSEvent::APIDismissMenuRequest, client_id) - , m_menu_id(menu_id) - { - } - - int menu_id() const { return m_menu_id; } - -private: - int m_menu_id; -}; - -class WSAPICreateMenuRequest : public WSAPIClientRequest { -public: - WSAPICreateMenuRequest(int client_id, const String& text) - : WSAPIClientRequest(WSEvent::APICreateMenuRequest, client_id) - , m_text(text) - { - } - - String text() const { return m_text; } - -private: - String m_text; -}; - -class WSAPIDestroyMenuRequest : public WSAPIClientRequest { -public: - WSAPIDestroyMenuRequest(int client_id, int menu_id) - : WSAPIClientRequest(WSEvent::APIDestroyMenuRequest, client_id) - , m_menu_id(menu_id) - { - } - - int menu_id() const { return m_menu_id; } - -private: - int m_menu_id { 0 }; -}; - -class WSAPIAddMenuItemRequest : public WSAPIClientRequest { -public: - WSAPIAddMenuItemRequest(int client_id, int menu_id, unsigned identifier, const String& text, const String& shortcut_text, bool enabled, bool checkable, bool checked, int icon_buffer_id, int submenu_id) - : WSAPIClientRequest(WSEvent::APIAddMenuItemRequest, client_id) - , m_menu_id(menu_id) - , m_identifier(identifier) - , m_text(text) - , m_shortcut_text(shortcut_text) - , m_enabled(enabled) - , m_checkable(checkable) - , m_checked(checked) - , m_icon_buffer_id(icon_buffer_id) - , m_submenu_id(submenu_id) - { - } - - int menu_id() const { return m_menu_id; } - unsigned identifier() const { return m_identifier; } - String text() const { return m_text; } - String shortcut_text() const { return m_shortcut_text; } - bool is_enabled() const { return m_enabled; } - bool is_checkable() const { return m_checkable; } - bool is_checked() const { return m_checked; } - int icon_buffer_id() const { return m_icon_buffer_id; } - int submenu_id() const { return m_submenu_id; } - -private: - int m_menu_id { 0 }; - unsigned m_identifier { 0 }; - String m_text; - String m_shortcut_text; - bool m_enabled; - bool m_checkable; - bool m_checked; - int m_icon_buffer_id { 0 }; - int m_submenu_id { 0 }; -}; - -class WSAPIUpdateMenuItemRequest : public WSAPIClientRequest { -public: - WSAPIUpdateMenuItemRequest(int client_id, int menu_id, unsigned identifier, const String& text, const String& shortcut_text, bool enabled, bool checkable, bool checked) - : WSAPIClientRequest(WSEvent::APIUpdateMenuItemRequest, client_id) - , m_menu_id(menu_id) - , m_identifier(identifier) - , m_text(text) - , m_shortcut_text(shortcut_text) - , m_enabled(enabled) - , m_checkable(checkable) - , m_checked(checked) - { - } - - int menu_id() const { return m_menu_id; } - unsigned identifier() const { return m_identifier; } - String text() const { return m_text; } - String shortcut_text() const { return m_shortcut_text; } - bool is_enabled() const { return m_enabled; } - bool is_checkable() const { return m_checkable; } - bool is_checked() const { return m_checked; } - -private: - int m_menu_id { 0 }; - unsigned m_identifier { 0 }; - String m_text; - String m_shortcut_text; - bool m_enabled { true }; - bool m_checkable; - bool m_checked; -}; - -class WSAPIAddMenuSeparatorRequest : public WSAPIClientRequest { -public: - WSAPIAddMenuSeparatorRequest(int client_id, int menu_id) - : WSAPIClientRequest(WSEvent::APIAddMenuSeparatorRequest, client_id) - , m_menu_id(menu_id) - { - } - - int menu_id() const { return m_menu_id; } - -private: - int m_menu_id { 0 }; -}; - -class WSAPISetWindowOverrideCursorRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWindowOverrideCursorRequest(int client_id, int window_id, WSStandardCursor cursor) - : WSAPIClientRequest(WSEvent::APISetWindowOverrideCursorRequest, client_id) - , m_window_id(window_id) - , m_cursor(cursor) - { - } - - int window_id() const { return m_window_id; } - WSStandardCursor cursor() const { return m_cursor; } - -private: - int m_window_id { 0 }; - WSStandardCursor m_cursor { WSStandardCursor::None }; -}; - -class WSAPISetWindowHasAlphaChannelRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWindowHasAlphaChannelRequest(int client_id, int window_id, bool value) - : WSAPIClientRequest(WSEvent::APISetWindowHasAlphaChannelRequest, client_id) - , m_window_id(window_id) - , m_value(value) - { - } - - int window_id() const { return m_window_id; } - bool value() const { return m_value; } - -private: - int m_window_id { 0 }; - bool m_value { 0 }; -}; - -class WSAPISetWallpaperRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWallpaperRequest(int client_id, const String& wallpaper) - : WSAPIClientRequest(WSEvent::APISetWallpaperRequest, client_id) - , m_wallpaper(wallpaper) - { - } - - String wallpaper() const { return m_wallpaper; } - -private: - String m_wallpaper; -}; - -class WSAPIGetWallpaperRequest final : public WSAPIClientRequest { -public: - explicit WSAPIGetWallpaperRequest(int client_id) - : WSAPIClientRequest(WSEvent::APIGetWallpaperRequest, client_id) - { - } -}; - -class WSAPISetResolutionRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetResolutionRequest(int client_id, int width, int height) - : WSAPIClientRequest(WSEvent::APISetResolutionRequest, client_id), - m_resolution(width, height) - { - } - - Size resolution() const { return m_resolution; } - -private: - Size m_resolution; -}; - -class WSAPISetWindowTitleRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWindowTitleRequest(int client_id, int window_id, const String& title) - : WSAPIClientRequest(WSEvent::APISetWindowTitleRequest, client_id) - , m_window_id(window_id) - , m_title(title) - { - } - - int window_id() const { return m_window_id; } - String title() const { return m_title; } - -private: - int m_window_id { 0 }; - String m_title; -}; - -class WSAPIGetWindowTitleRequest final : public WSAPIClientRequest { -public: - explicit WSAPIGetWindowTitleRequest(int client_id, int window_id) - : WSAPIClientRequest(WSEvent::APIGetWindowTitleRequest, client_id) - , m_window_id(window_id) - { - } - - int window_id() const { return m_window_id; } - -private: - int m_window_id { 0 }; -}; - -class WSAPIMoveWindowToFrontRequest final : public WSAPIClientRequest { -public: - explicit WSAPIMoveWindowToFrontRequest(int client_id, int window_id) - : WSAPIClientRequest(WSEvent::APIMoveWindowToFrontRequest, client_id) - , m_window_id(window_id) - { - } - - int window_id() const { return m_window_id; } - -private: - int m_window_id { 0 }; -}; - -class WSAPISetFullscreenRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetFullscreenRequest(int client_id, int window_id, bool fullscreen) - : WSAPIClientRequest(WSEvent::APISetFullscreenRequest, client_id) - , m_window_id(window_id) - , m_fullscreen(fullscreen) - { - } - - int window_id() const { return m_window_id; } - bool fullscreen() const { return m_fullscreen; } - -private: - int m_window_id { 0 }; - bool m_fullscreen; -}; - -class WSAPISetClipboardContentsRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetClipboardContentsRequest(int client_id, int shared_buffer_id, int size, const String& data_type) - : WSAPIClientRequest(WSEvent::APISetClipboardContentsRequest, client_id) - , m_shared_buffer_id(shared_buffer_id) - , m_size(size) - , m_data_type(data_type) - { - } - - int shared_buffer_id() const { return m_shared_buffer_id; } - int size() const { return m_size; } - const String& data_type() const { return m_data_type; } - -private: - int m_shared_buffer_id { 0 }; - int m_size { 0 }; - String m_data_type; -}; - -class WSAPIGetClipboardContentsRequest final : public WSAPIClientRequest { -public: - explicit WSAPIGetClipboardContentsRequest(int client_id) - : WSAPIClientRequest(WSEvent::APIGetClipboardContentsRequest, client_id) - { - } -}; - -class WSAPISetWindowOpacityRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWindowOpacityRequest(int client_id, int window_id, float opacity) - : WSAPIClientRequest(WSEvent::APISetWindowOpacityRequest, client_id) - , m_window_id(window_id) - , m_opacity(opacity) - { - } - - int window_id() const { return m_window_id; } - float opacity() const { return m_opacity; } - -private: - int m_window_id { 0 }; - float m_opacity { 0 }; -}; - -class WSAPISetWindowBackingStoreRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWindowBackingStoreRequest(int client_id, int window_id, int shared_buffer_id, const Size& size, size_t bpp, size_t pitch, bool has_alpha_channel, bool flush_immediately) - : WSAPIClientRequest(WSEvent::APISetWindowBackingStoreRequest, client_id) - , m_window_id(window_id) - , m_shared_buffer_id(shared_buffer_id) - , m_size(size) - , m_bpp(bpp) - , m_pitch(pitch) - , m_has_alpha_channel(has_alpha_channel) - , m_flush_immediately(flush_immediately) - { - } - - int window_id() const { return m_window_id; } - int shared_buffer_id() const { return m_shared_buffer_id; } - Size size() const { return m_size; } - size_t bpp() const { return m_bpp; } - size_t pitch() const { return m_pitch; } - bool has_alpha_channel() const { return m_has_alpha_channel; } - bool flush_immediately() const { return m_flush_immediately; } - -private: - int m_window_id { 0 }; - int m_shared_buffer_id { 0 }; - Size m_size; - size_t m_bpp; - size_t m_pitch; - bool m_has_alpha_channel; - bool m_flush_immediately; -}; - -class WSAPISetWindowRectRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWindowRectRequest(int client_id, int window_id, const Rect& rect) - : WSAPIClientRequest(WSEvent::APISetWindowRectRequest, client_id) - , m_window_id(window_id) - , m_rect(rect) - { - } - - int window_id() const { return m_window_id; } - Rect rect() const { return m_rect; } - -private: - int m_window_id { 0 }; - Rect m_rect; -}; - -class WSAPISetWindowIconBitmapRequest final : public WSAPIClientRequest { -public: - explicit WSAPISetWindowIconBitmapRequest(int client_id, int window_id, int icon_buffer_id, const Size& icon_size) - : WSAPIClientRequest(WSEvent::APISetWindowIconBitmapRequest, client_id) - , m_window_id(window_id) - , m_icon_buffer_id(icon_buffer_id) - , m_icon_size(icon_size) - { - } - - int window_id() const { return m_window_id; } - int icon_buffer_id() const { return m_icon_buffer_id; } - const Size& icon_size() const { return m_icon_size; } - -private: - int m_window_id { 0 }; - int m_icon_buffer_id { 0 }; - Size m_icon_size; -}; - -class WSAPIGetWindowRectRequest final : public WSAPIClientRequest { -public: - explicit WSAPIGetWindowRectRequest(int client_id, int window_id) - : WSAPIClientRequest(WSEvent::APIGetWindowRectRequest, client_id) - , m_window_id(window_id) - { - } - - int window_id() const { return m_window_id; } - -private: - int m_window_id { 0 }; -}; - -class WSAPICreateWindowRequest : public WSAPIClientRequest { -public: - WSAPICreateWindowRequest(int client_id, const Rect& rect, const String& title, bool has_alpha_channel, bool modal, bool resizable, bool fullscreen, bool show_titlebar, float opacity, const Size& base_size, const Size& size_increment, WSWindowType window_type, Color background_color) - : WSAPIClientRequest(WSEvent::APICreateWindowRequest, client_id) - , m_rect(rect) - , m_title(title) - , m_opacity(opacity) - , m_has_alpha_channel(has_alpha_channel) - , m_modal(modal) - , m_resizable(resizable) - , m_fullscreen(fullscreen) - , m_show_titlebar(show_titlebar) - , m_size_increment(size_increment) - , m_base_size(base_size) - , m_window_type(window_type) - , m_background_color(background_color) - { - } - - Rect rect() const { return m_rect; } - String title() const { return m_title; } - bool has_alpha_channel() const { return m_has_alpha_channel; } - bool is_modal() const { return m_modal; } - bool is_resizable() const { return m_resizable; } - bool is_fullscreen() const { return m_fullscreen; } - bool show_titlebar() const { return m_show_titlebar; } - float opacity() const { return m_opacity; } - Size size_increment() const { return m_size_increment; } - Size base_size() const { return m_base_size; } - WSWindowType window_type() const { return m_window_type; } - Color background_color() const { return m_background_color; } - -private: - Rect m_rect; - String m_title; - float m_opacity { 0 }; - bool m_has_alpha_channel { false }; - bool m_modal { false }; - bool m_resizable { false }; - bool m_fullscreen { false }; - bool m_show_titlebar { true }; - Size m_size_increment; - Size m_base_size; - WSWindowType m_window_type; - Color m_background_color; -}; - -class WSAPIDestroyWindowRequest : public WSAPIClientRequest { -public: - WSAPIDestroyWindowRequest(int client_id, int window_id) - : WSAPIClientRequest(WSEvent::APIDestroyWindowRequest, client_id) - , m_window_id(window_id) - { - } - - int window_id() const { return m_window_id; } - -private: - int m_window_id { 0 }; -}; - -class WSAPIInvalidateRectRequest final : public WSAPIClientRequest { -public: - explicit WSAPIInvalidateRectRequest(int client_id, int window_id, const Vector& rects) - : WSAPIClientRequest(WSEvent::APIInvalidateRectRequest, client_id) - , m_window_id(window_id) - , m_rects(rects) - { - } - - int window_id() const { return m_window_id; } - const Vector& rects() const { return m_rects; } - -private: - int m_window_id { 0 }; - Vector m_rects; -}; - -class WSAPIDidFinishPaintingNotification final : public WSAPIClientRequest { -public: - explicit WSAPIDidFinishPaintingNotification(int client_id, int window_id, const Vector& rects) - : WSAPIClientRequest(WSEvent::APIDidFinishPaintingNotification, client_id) - , m_window_id(window_id) - , m_rects(rects) - { - } - - int window_id() const { return m_window_id; } - const Vector& rects() const { return m_rects; } - -private: - int m_window_id { 0 }; - Vector m_rects; -}; - enum class MouseButton : u8 { None = 0, Left = 1, diff --git a/Servers/WindowServer/WSEventLoop.cpp b/Servers/WindowServer/WSEventLoop.cpp index dbcd0e68a24..7909229a3a2 100644 --- a/Servers/WindowServer/WSEventLoop.cpp +++ b/Servers/WindowServer/WSEventLoop.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +37,7 @@ WSEventLoop::WSEventLoop() } static int s_next_client_id = 0; int client_id = ++s_next_client_id; - IPC::Server::new_connection_for_client(*client_socket, client_id); + IPC::Server::new_connection_ng_for_client(*client_socket, client_id); }; ASSERT(m_keyboard_fd >= 0); diff --git a/Servers/WindowServer/WSEventLoop.h b/Servers/WindowServer/WSEventLoop.h index 7d13f455025..84a5558d970 100644 --- a/Servers/WindowServer/WSEventLoop.h +++ b/Servers/WindowServer/WSEventLoop.h @@ -6,7 +6,6 @@ #include class WSClientConnection; -struct WSAPI_ClientMessage; class WSEventLoop { public: diff --git a/Servers/WindowServer/WSMenu.cpp b/Servers/WindowServer/WSMenu.cpp index 1cacfa534e4..71186e4fa91 100644 --- a/Servers/WindowServer/WSMenu.cpp +++ b/Servers/WindowServer/WSMenu.cpp @@ -11,8 +11,8 @@ #include #include #include -#include #include +#include WSMenu::WSMenu(WSClientConnection* client, int menu_id, const String& name) : CObject(client) @@ -247,13 +247,8 @@ void WSMenu::did_activate(WSMenuItem& item) WSWindowManager::the().menu_manager().close_bar(); - WSAPI_ServerMessage message; - message.type = WSAPI_ServerMessage::Type::MenuItemActivated; - message.menu.menu_id = m_menu_id; - message.menu.identifier = item.identifier(); - if (m_client) - m_client->post_message(message); + m_client->post_message(WindowClient::MenuItemActivated(m_menu_id, item.identifier())); } WSMenuItem* WSMenu::item_with_identifier(unsigned identifer) diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index debd983f836..855ece5094f 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -3,8 +3,8 @@ #include "WSEventLoop.h" #include "WSScreen.h" #include "WSWindowManager.h" -#include #include +#include static String default_window_icon_path() { @@ -41,7 +41,7 @@ WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int win { // FIXME: This should not be hard-coded here. if (m_type == WSWindowType::Taskbar) { - m_wm_event_mask = WSAPI_WMEventMask::WindowStateChanges | WSAPI_WMEventMask::WindowRemovals | WSAPI_WMEventMask::WindowIconChanges; + m_wm_event_mask = WSWMEventMask::WindowStateChanges | WSWMEventMask::WindowRemovals | WSWMEventMask::WindowIconChanges; m_listens_to_wm_events = true; } WSWindowManager::the().add_window(*this); @@ -73,76 +73,29 @@ void WSWindow::set_rect(const Rect& rect) m_frame.notify_window_rect_changed(old_rect, rect); } -// FIXME: Just use the same types. -static WSAPI_MouseButton to_api(MouseButton button) -{ - switch (button) { - case MouseButton::None: - return WSAPI_MouseButton::NoButton; - case MouseButton::Left: - return WSAPI_MouseButton::Left; - case MouseButton::Right: - return WSAPI_MouseButton::Right; - case MouseButton::Middle: - return WSAPI_MouseButton::Middle; - } - ASSERT_NOT_REACHED(); -} - void WSWindow::handle_mouse_event(const WSMouseEvent& event) { set_automatic_cursor_tracking_enabled(event.buttons() != 0); - WSAPI_ServerMessage server_message; - server_message.window_id = window_id(); - switch (event.type()) { case WSEvent::MouseMove: - server_message.type = WSAPI_ServerMessage::Type::MouseMove; + m_client->post_message(WindowClient::MouseMove(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta())); break; case WSEvent::MouseDown: - server_message.type = WSAPI_ServerMessage::Type::MouseDown; + m_client->post_message(WindowClient::MouseDown(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta())); break; case WSEvent::MouseDoubleClick: - server_message.type = WSAPI_ServerMessage::Type::MouseDoubleClick; + m_client->post_message(WindowClient::MouseDoubleClick(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta())); break; case WSEvent::MouseUp: - server_message.type = WSAPI_ServerMessage::Type::MouseUp; + m_client->post_message(WindowClient::MouseUp(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta())); break; case WSEvent::MouseWheel: - server_message.type = WSAPI_ServerMessage::Type::MouseWheel; + m_client->post_message(WindowClient::MouseWheel(m_window_id, event.position(), (u32)event.button(), event.buttons(), event.modifiers(), event.wheel_delta())); break; default: ASSERT_NOT_REACHED(); } - - server_message.mouse.position = event.position(); - server_message.mouse.button = to_api(event.button()); - server_message.mouse.buttons = event.buttons(); - server_message.mouse.modifiers = event.modifiers(); - server_message.mouse.wheel_delta = event.wheel_delta(); - - m_client->post_message(server_message); -} - -static WSAPI_WindowType to_api(WSWindowType ws_type) -{ - switch (ws_type) { - case WSWindowType::Normal: - return WSAPI_WindowType::Normal; - case WSWindowType::Menu: - return WSAPI_WindowType::Menu; - case WSWindowType::WindowSwitcher: - return WSAPI_WindowType::WindowSwitcher; - case WSWindowType::Taskbar: - return WSAPI_WindowType::Taskbar; - case WSWindowType::Tooltip: - return WSAPI_WindowType::Tooltip; - case WSWindowType::Menubar: - return WSAPI_WindowType::Menubar; - default: - ASSERT_NOT_REACHED(); - } } void WSWindow::set_minimized(bool minimized) @@ -183,101 +136,96 @@ void WSWindow::event(CEvent& event) if (is_blocked_by_modal_window()) return; - WSAPI_ServerMessage server_message; - server_message.window_id = window_id(); - if (static_cast(event).is_mouse_event()) return handle_mouse_event(static_cast(event)); switch (event.type()) { case WSEvent::WindowEntered: - server_message.type = WSAPI_ServerMessage::Type::WindowEntered; + m_client->post_message(WindowClient::WindowEntered(m_window_id)); break; case WSEvent::WindowLeft: - server_message.type = WSAPI_ServerMessage::Type::WindowLeft; + m_client->post_message(WindowClient::WindowLeft(m_window_id)); break; case WSEvent::KeyDown: - server_message.type = WSAPI_ServerMessage::Type::KeyDown; - server_message.key.character = static_cast(event).character(); - server_message.key.key = static_cast(event).key(); - server_message.key.modifiers = static_cast(event).modifiers(); + m_client->post_message( + WindowClient::KeyDown(m_window_id, + (u8) static_cast(event).character(), + (u32) static_cast(event).key(), + static_cast(event).modifiers())); break; case WSEvent::KeyUp: - server_message.type = WSAPI_ServerMessage::Type::KeyUp; - server_message.key.character = static_cast(event).character(); - server_message.key.key = static_cast(event).key(); - server_message.key.modifiers = static_cast(event).modifiers(); + m_client->post_message( + WindowClient::KeyUp(m_window_id, + (u8) static_cast(event).character(), + (u32) static_cast(event).key(), + static_cast(event).modifiers())); break; case WSEvent::WindowActivated: - server_message.type = WSAPI_ServerMessage::Type::WindowActivated; + m_client->post_message(WindowClient::WindowActivated(m_window_id)); break; case WSEvent::WindowDeactivated: - server_message.type = WSAPI_ServerMessage::Type::WindowDeactivated; + m_client->post_message(WindowClient::WindowDeactivated(m_window_id)); break; case WSEvent::WindowCloseRequest: - server_message.type = WSAPI_ServerMessage::Type::WindowCloseRequest; + m_client->post_message(WindowClient::WindowCloseRequest(m_window_id)); break; case WSEvent::WindowResized: - server_message.type = WSAPI_ServerMessage::Type::WindowResized; - server_message.window.old_rect = static_cast(event).old_rect(); - server_message.window.rect = static_cast(event).rect(); + m_client->post_message( + WindowClient::WindowResized( + m_window_id, + static_cast(event).old_rect(), + static_cast(event).rect())); break; case WSEvent::WM_WindowRemoved: { auto& removed_event = static_cast(event); - server_message.type = WSAPI_ServerMessage::Type::WM_WindowRemoved; - server_message.wm.client_id = removed_event.client_id(); - server_message.wm.window_id = removed_event.window_id(); + m_client->post_message(WindowClient::WM_WindowRemoved( + removed_event.client_id(), + removed_event.window_id())); break; } case WSEvent::WM_WindowStateChanged: { auto& changed_event = static_cast(event); - server_message.type = WSAPI_ServerMessage::Type::WM_WindowStateChanged; - server_message.wm.client_id = changed_event.client_id(); - server_message.wm.window_id = changed_event.window_id(); - server_message.wm.is_active = changed_event.is_active(); - server_message.wm.is_minimized = changed_event.is_minimized(); - server_message.wm.window_type = to_api(changed_event.window_type()); - ASSERT(changed_event.title().length() < (int)sizeof(server_message.text)); - memcpy(server_message.text, changed_event.title().characters(), changed_event.title().length()); - server_message.text_length = changed_event.title().length(); - server_message.wm.rect = changed_event.rect(); + m_client->post_message(WindowClient::WM_WindowStateChanged( + changed_event.client_id(), + changed_event.window_id(), + changed_event.is_active(), + changed_event.is_minimized(), + (i32)(changed_event.window_type()), + changed_event.title(), + changed_event.rect())); break; } case WSEvent::WM_WindowIconBitmapChanged: { auto& changed_event = static_cast(event); - server_message.type = WSAPI_ServerMessage::Type::WM_WindowIconBitmapChanged; - server_message.wm.client_id = changed_event.client_id(); - server_message.wm.window_id = changed_event.window_id(); - server_message.wm.icon_buffer_id = changed_event.icon_buffer_id(); - server_message.wm.icon_size = changed_event.icon_size(); - // FIXME: Perhaps we should update the bitmap sharing list somewhere else instead? - ASSERT(client()); dbg() << "WindowServer: Sharing icon buffer " << changed_event.icon_buffer_id() << " with PID " << client()->client_pid(); - if (share_buffer_with(changed_event.icon_buffer_id(), client()->client_pid()) < 0) { + if (share_buffer_with(changed_event.icon_buffer_id(), m_client->client_pid()) < 0) { ASSERT_NOT_REACHED(); } + m_client->post_message( + WindowClient::WM_WindowIconBitmapChanged( + changed_event.client_id(), + changed_event.window_id(), + changed_event.icon_buffer_id(), + changed_event.icon_size())); + break; } case WSEvent::WM_WindowRectChanged: { auto& changed_event = static_cast(event); - server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged; - server_message.wm.client_id = changed_event.client_id(); - server_message.wm.window_id = changed_event.window_id(); - server_message.wm.rect = changed_event.rect(); + m_client->post_message( + WindowClient::WM_WindowRectChanged( + changed_event.client_id(), + changed_event.window_id(), + changed_event.rect())); break; } default: break; } - - if (server_message.type == WSAPI_ServerMessage::Type::Invalid) - return; - - m_client->post_message(server_message); } void WSWindow::set_global_cursor_tracking_enabled(bool enabled) diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index a77aba5d1ca..0be54481ca2 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -1,7 +1,7 @@ #pragma once -#include #include +#include #include #include #include @@ -14,6 +14,13 @@ class WSCursor; class WSMenu; class WSMouseEvent; +enum WSWMEventMask { + WindowRectChanges = 1 << 0, + WindowStateChanges = 1 << 1, + WindowIconChanges = 1 << 2, + WindowRemovals = 1 << 3, +}; + class WSWindow final : public CObject , public InlineLinkedListNode { C_OBJECT(WSWindow) diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index a9ca19f2f93..c9433ac7796 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -318,7 +317,7 @@ void WSWindowManager::remove_window(WSWindow& window) m_switcher.refresh(); for_each_window_listening_to_wm_events([&window](WSWindow& listener) { - if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowRemovals)) + if (!(listener.wm_event_mask() & WSWMEventMask::WindowRemovals)) return IterationDecision::Continue; if (window.client()) CEventLoop::current().post_event(listener, make(window.client()->client_id(), window.window_id())); @@ -328,7 +327,7 @@ void WSWindowManager::remove_window(WSWindow& window) void WSWindowManager::tell_wm_listener_about_window(WSWindow& listener, WSWindow& window) { - if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowStateChanges)) + if (!(listener.wm_event_mask() & WSWMEventMask::WindowStateChanges)) return; if (window.client()) CEventLoop::current().post_event(listener, make(window.client()->client_id(), window.window_id(), window.title(), window.rect(), window.is_active(), window.type(), window.is_minimized())); @@ -336,7 +335,7 @@ void WSWindowManager::tell_wm_listener_about_window(WSWindow& listener, WSWindow void WSWindowManager::tell_wm_listener_about_window_rect(WSWindow& listener, WSWindow& window) { - if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowRectChanges)) + if (!(listener.wm_event_mask() & WSWMEventMask::WindowRectChanges)) return; if (window.client()) CEventLoop::current().post_event(listener, make(window.client()->client_id(), window.window_id(), window.rect())); @@ -344,7 +343,7 @@ void WSWindowManager::tell_wm_listener_about_window_rect(WSWindow& listener, WSW void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSWindow& window) { - if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges)) + if (!(listener.wm_event_mask() & WSWMEventMask::WindowIconChanges)) return; if (window.client() && window.icon().shared_buffer_id() != -1) CEventLoop::current().post_event(listener, make(window.client()->client_id(), window.window_id(), window.icon().shared_buffer_id(), window.icon().size())); diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 3929adf7df8..b0ef9fcbf8b 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -18,7 +18,6 @@ #include #include -class WSAPIClientRequest; class WSScreen; class WSMenuBar; class WSMouseEvent; @@ -158,7 +157,6 @@ private: bool process_ongoing_window_resize(const WSMouseEvent&, WSWindow*& hovered_window); bool process_ongoing_window_drag(WSMouseEvent&, WSWindow*& hovered_window); void start_window_drag(WSWindow&, const WSMouseEvent&); - void handle_client_request(const WSAPIClientRequest&); void set_hovered_window(WSWindow*); template IterationDecision for_each_visible_window_of_type_from_back_to_front(WSWindowType, Callback, bool ignore_highlight = false); diff --git a/Servers/WindowServer/WindowClient.ipc b/Servers/WindowServer/WindowClient.ipc new file mode 100644 index 00000000000..d4a09179213 --- /dev/null +++ b/Servers/WindowServer/WindowClient.ipc @@ -0,0 +1,30 @@ +endpoint WindowClient = 4 +{ + Paint(i32 window_id, Size window_size, Vector rects) =| + MouseMove(i32 window_id, Point mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| + MouseDown(i32 window_id, Point mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| + MouseDoubleClick(i32 window_id, Point mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| + MouseUp(i32 window_id, Point mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| + MouseWheel(i32 window_id, Point mouse_position, u32 button, u32 buttons, u32 modifiers, i32 wheel_delta) =| + WindowEntered(i32 window_id) =| + WindowLeft(i32 window_id) =| + KeyDown(i32 window_id, u8 character, u32 key, u32 modifiers) =| + KeyUp(i32 window_id, u8 character, u32 key, u32 modifiers) =| + WindowActivated(i32 window_id) =| + WindowDeactivated(i32 window_id) =| + WindowCloseRequest(i32 window_id) =| + WindowResized(i32 window_id, Rect old_rect, Rect new_rect) =| + + MenuItemActivated(i32 menu_id, i32 identifier) =| + + ScreenRectChanged(Rect rect) =| + + ClipboardContentsChanged(String content_type) =| + + WM_WindowRemoved(i32 client_id, i32 window_id) =| + WM_WindowStateChanged(i32 client_id, i32 window_id, bool is_active, bool is_minimized, i32 window_type, String title, Rect rect) =| + WM_WindowIconBitmapChanged(i32 client_id, i32 window_id, i32 icon_buffer_id, Size icon_size) =| + WM_WindowRectChanged(i32 client_id, i32 window_id, Rect rect) =| + + AsyncSetWallpaperFinished(bool success) =| +} diff --git a/Servers/WindowServer/WindowServer.ipc b/Servers/WindowServer/WindowServer.ipc new file mode 100644 index 00000000000..e75ad0daf0e --- /dev/null +++ b/Servers/WindowServer/WindowServer.ipc @@ -0,0 +1,68 @@ +endpoint WindowServer = 2 +{ + Greet(i32 client_pid) => (i32 server_pid, i32 client_id, Rect screen_rect) + + CreateMenubar() => (i32 menubar_id) + DestroyMenubar(i32 menubar_id) => () + + CreateMenu(String menu_title) => (i32 menu_id) + DestroyMenu(i32 menu_id) => () + + AddMenuToMenubar(i32 menubar_id, i32 menu_id) => () + SetApplicationMenubar(i32 menubar_id) => () + + AddMenuItem(i32 menu_id, i32 identifier, i32 submenu_id, String text, bool enabled, bool checkable, bool checked, String shortcut, i32 icon_buffer_id) => () + AddMenuSeparator(i32 menu_id) => () + + UpdateMenuItem(i32 menu_id, i32 identifier, i32 submenu_id, String text, bool enabled, bool checkable, bool checked, String shortcut) => () + + CreateWindow( + Rect rect, + bool has_alpha_channel, + bool modal, + bool resizable, + bool fullscreen, + bool show_titlebar, + float opacity, + Color background_color, + Size base_size, + Size size_increment, + i32 type, + String title) => (i32 window_id) + + DestroyWindow(i32 window_id) => () + + SetWindowTitle(i32 window_id, String title) => () + GetWindowTitle(i32 window_id) => (String title) + + SetWindowRect(i32 window_id, Rect rect) => () + GetWindowRect(i32 window_id) => (Rect rect) + + InvalidateRect(i32 window_id, Vector rects) =| + DidFinishPainting(i32 window_id, Vector rects) =| + + SetGlobalCursorTracking(i32 window_id, bool enabled) => () + SetWindowOpacity(i32 window_id, float opacity) => () + + SetWindowBackingStore(i32 window_id, i32 bpp, i32 pitch, i32 shared_buffer_id, bool has_alpha_channel, Size size, bool flush_immediately) => () + GetClipboardContents() => (i32 shared_buffer_id, i32 content_size, String content_type) + SetClipboardContents(i32 shared_buffer_id, i32 content_size, String content_type) => () + + WM_SetActiveWindow(i32 client_id, i32 window_id) =| + WM_SetWindowMinimized(i32 client_id, i32 window_id, bool minimized) =| + WM_StartWindowResize(i32 client_id, i32 window_id) =| + WM_PopupWindowMenu(i32 client_id, i32 window_id, Point screen_position) =| + + SetWindowHasAlphaChannel(i32 window_id, bool has_alpha_channel) => () + MoveWindowToFront(i32 window_id) => () + SetFullscreen(i32 window_id, bool fullscreen) => () + PopupMenu(i32 menu_id, Point screen_position) => () + DismissMenu(i32 menu_id) => () + + AsyncSetWallpaper(String path) =| + SetResolution(Size resolution) => () + SetWindowIconBitmap(i32 window_id, i32 icon_buffer_id, Size icon_size) => () + + GetWallpaper() => (String path) + SetWindowOverrideCursor(i32 window_id, i32 cursor_type) => () +} diff --git a/Servers/WindowServer/main.cpp b/Servers/WindowServer/main.cpp index 542998a3d0c..cbd38306276 100644 --- a/Servers/WindowServer/main.cpp +++ b/Servers/WindowServer/main.cpp @@ -18,13 +18,19 @@ int main(int, char**) return 1; } + dbg() << "1"; WSEventLoop loop; + dbg() << "2"; auto wm_config = CConfigFile::get_for_app("WindowManager"); + dbg() << "3"; WSScreen screen(wm_config->read_num_entry("Screen", "Width", 1024), wm_config->read_num_entry("Screen", "Height", 768)); + dbg() << "4"; WSCompositor::the(); + dbg() << "5"; auto wm = WSWindowManager::construct(); + dbg() << "6"; dbgprintf("Entering WindowServer main loop.\n"); loop.exec();