diff options
Diffstat (limited to 'Servers')
-rw-r--r-- | Servers/WindowServer/WSAPITypes.h | 9 | ||||
-rw-r--r-- | Servers/WindowServer/WSClientConnection.cpp | 32 | ||||
-rw-r--r-- | Servers/WindowServer/WSClientConnection.h | 1 | ||||
-rw-r--r-- | Servers/WindowServer/WSEvent.h | 39 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.cpp | 17 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindow.h | 2 | ||||
-rw-r--r-- | Servers/WindowServer/WSWindowManager.cpp | 5 |
7 files changed, 102 insertions, 3 deletions
diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 28fe734d6e..526aecadd0 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -111,10 +111,14 @@ struct WSAPI_ServerMessage { DidGetWallpaper, DidSetWindowHasAlphaChannel, ScreenRectChanged, + + __Begin_WM_Events__, WM_WindowRemoved, WM_WindowStateChanged, WM_WindowRectChanged, WM_WindowIconChanged, + WM_WindowIconBitmapChanged, + __End_WM_Events__, }; Type type { Invalid }; int window_id { -1 }; @@ -145,6 +149,8 @@ struct WSAPI_ServerMessage { bool is_active; bool is_minimized; WSAPI_WindowType window_type; + int icon_buffer_id; + WSAPI_Size icon_size; } wm; struct { WSAPI_Rect rect; @@ -229,6 +235,7 @@ struct WSAPI_ClientMessage { SetWindowIcon, SetWindowHasAlphaChannel, MoveWindowToFront, + SetWindowIconBitmap, }; Type type { Invalid }; int window_id { -1 }; @@ -278,6 +285,8 @@ struct WSAPI_ClientMessage { 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; diff --git a/Servers/WindowServer/WSClientConnection.cpp b/Servers/WindowServer/WSClientConnection.cpp index 08bce8656a..325cc311c4 100644 --- a/Servers/WindowServer/WSClientConnection.cpp +++ b/Servers/WindowServer/WSClientConnection.cpp @@ -1,3 +1,4 @@ +#include <LibC/SharedBuffer.h> #include <SharedBuffer.h> #include <WindowServer/WSAPITypes.h> #include <WindowServer/WSClientConnection.h> @@ -13,8 +14,8 @@ #include <WindowServer/WSWindowSwitcher.h> #include <errno.h> #include <stdio.h> -#include <sys/socket.h> #include <sys/ioctl.h> +#include <sys/socket.h> #include <sys/uio.h> #include <unistd.h> @@ -145,6 +146,9 @@ bool WSClientConnection::handle_message(const WSAPI_ClientMessage& message, cons } CEventLoop::current().post_event(*this, make<WSAPISetWindowIconRequest>(client_id(), message.window_id, String(message.text, message.text_length))); break; + case WSAPI_ClientMessage::Type::SetWindowIconBitmap: + CEventLoop::current().post_event(*this, make<WSAPISetWindowIconBitmapRequest>(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<WSAPIDestroyMenuRequest>(client_id(), message.menu.menu_id)); break; @@ -538,7 +542,7 @@ void WSClientConnection::handle_request(const WSAPIGetWallpaperRequest&) WSAPI_ServerMessage response; response.type = WSAPI_ServerMessage::Type::DidGetWallpaper; ASSERT(path.length() < (int)sizeof(response.text)); - strncpy(response.text, path.characters(), path.length()); + memcpy(response.text, path.characters(), path.length() + 1); response.text_length = path.length(); post_message(response); } @@ -595,6 +599,28 @@ void WSClientConnection::handle_request(const WSAPISetWindowIconRequest& request WSWindowManager::the().tell_wm_listeners_window_icon_changed(window); } +void WSClientConnection::handle_request(const WSAPISetWindowIconBitmapRequest& request) +{ + int window_id = request.window_id(); + auto it = m_windows.find(window_id); + if (it == m_windows.end()) { + post_error("WSAPISetWindowIconBitmapRequest: Bad window ID"); + return; + } + auto& window = *(*it).value; + + auto icon_buffer = SharedBuffer::create_from_shared_buffer_id(request.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.frame().invalidate_title_bar(); + WSWindowManager::the().tell_wm_listeners_window_icon_changed(window); +} + void WSClientConnection::handle_request(const WSAPISetWindowRectRequest& request) { int window_id = request.window_id(); @@ -946,6 +972,8 @@ void WSClientConnection::on_request(const WSAPIClientRequest& request) return handle_request(static_cast<const WSAPIGetWindowRectRequest&>(request)); case WSEvent::APISetWindowIconRequest: return handle_request(static_cast<const WSAPISetWindowIconRequest&>(request)); + case WSEvent::APISetWindowIconBitmapRequest: + return handle_request(static_cast<const WSAPISetWindowIconBitmapRequest&>(request)); case WSEvent::APISetClipboardContentsRequest: return handle_request(static_cast<const WSAPISetClipboardContentsRequest&>(request)); case WSEvent::APIGetClipboardContentsRequest: diff --git a/Servers/WindowServer/WSClientConnection.h b/Servers/WindowServer/WSClientConnection.h index 8038ffe2e4..bf883f7c39 100644 --- a/Servers/WindowServer/WSClientConnection.h +++ b/Servers/WindowServer/WSClientConnection.h @@ -55,6 +55,7 @@ private: void handle_request(const WSAPISetWindowRectRequest&); void handle_request(const WSAPIGetWindowRectRequest&); void handle_request(const WSAPISetWindowIconRequest&); + void handle_request(const WSAPISetWindowIconBitmapRequest&); void handle_request(const WSAPISetClipboardContentsRequest&); void handle_request(const WSAPIGetClipboardContentsRequest&); void handle_request(const WSAPICreateWindowRequest&); diff --git a/Servers/WindowServer/WSEvent.h b/Servers/WindowServer/WSEvent.h index 4339be917b..6e4a7c1cd2 100644 --- a/Servers/WindowServer/WSEvent.h +++ b/Servers/WindowServer/WSEvent.h @@ -32,6 +32,7 @@ public: WM_WindowStateChanged, WM_WindowRectChanged, WM_WindowIconChanged, + WM_WindowIconBitmapChanged, __Begin_API_Client_Requests, APICreateMenubarRequest, @@ -50,6 +51,7 @@ public: APISetWindowRectRequest, APIGetWindowRectRequest, APISetWindowIconRequest, + APISetWindowIconBitmapRequest, APIInvalidateRectRequest, APIDidFinishPaintingNotification, APIGetWindowBackingStoreRequest, @@ -588,6 +590,26 @@ private: String m_icon_path; }; +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) @@ -856,6 +878,23 @@ private: String m_icon_path; }; +class WSWMWindowIconBitmapChangedEvent : public WSWMEvent { +public: + WSWMWindowIconBitmapChangedEvent(int client_id, int window_id, int icon_buffer_id, const Size& icon_size) + : WSWMEvent(WSEvent::WM_WindowIconBitmapChanged, client_id, window_id) + , m_icon_buffer_id(icon_buffer_id) + , m_icon_size(icon_size) + { + } + + int icon_buffer_id() const { return m_icon_buffer_id; } + const Size icon_size() const { return m_icon_size; } + +private: + int m_icon_buffer_id; + Size m_icon_size; +}; + class WSWMWindowRectChangedEvent : public WSWMEvent { public: WSWMWindowRectChangedEvent(int client_id, int window_id, const Rect& rect) diff --git a/Servers/WindowServer/WSWindow.cpp b/Servers/WindowServer/WSWindow.cpp index 13b4b49b64..50599820b7 100644 --- a/Servers/WindowServer/WSWindow.cpp +++ b/Servers/WindowServer/WSWindow.cpp @@ -254,6 +254,23 @@ void WSWindow::event(CEvent& event) break; } + case WSEvent::WM_WindowIconBitmapChanged: { + auto& changed_event = static_cast<const WSWMWindowIconBitmapChangedEvent&>(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) { + ASSERT_NOT_REACHED(); + } + break; + } + case WSEvent::WM_WindowRectChanged: { auto& changed_event = static_cast<const WSWMWindowRectChangedEvent&>(event); server_message.type = WSAPI_ServerMessage::Type::WM_WindowRectChanged; diff --git a/Servers/WindowServer/WSWindow.h b/Servers/WindowServer/WSWindow.h index b8c29aa573..e9ed0c82b9 100644 --- a/Servers/WindowServer/WSWindow.h +++ b/Servers/WindowServer/WSWindow.h @@ -129,6 +129,8 @@ public: void set_base_size(const Size& size) { m_base_size = size; } const GraphicsBitmap& icon() const { return *m_icon; } + void set_icon(NonnullRefPtr<GraphicsBitmap>&& icon) { m_icon = move(icon); } + String icon_path() const { return m_icon_path; } void set_icon(const String& path, NonnullRefPtr<GraphicsBitmap>&& icon) { diff --git a/Servers/WindowServer/WSWindowManager.cpp b/Servers/WindowServer/WSWindowManager.cpp index a9abf88c87..b64721da8d 100644 --- a/Servers/WindowServer/WSWindowManager.cpp +++ b/Servers/WindowServer/WSWindowManager.cpp @@ -319,8 +319,11 @@ void WSWindowManager::tell_wm_listener_about_window_icon(WSWindow& listener, WSW { if (!(listener.wm_event_mask() & WSAPI_WMEventMask::WindowIconChanges)) return; - if (window.client()) + if (window.client()) { CEventLoop::current().post_event(listener, make<WSWMWindowIconChangedEvent>(window.client()->client_id(), window.window_id(), window.icon_path())); + if (window.icon().shared_buffer_id() != -1) + CEventLoop::current().post_event(listener, make<WSWMWindowIconBitmapChangedEvent>(window.client()->client_id(), window.window_id(), window.icon().shared_buffer_id(), window.icon().size())); + } } void WSWindowManager::tell_wm_listeners_window_state_changed(WSWindow& window) |