diff --git a/Applications/IRCClient/IRCWindow.cpp b/Applications/IRCClient/IRCWindow.cpp index d1f58ab6db4..8fbca5a57e0 100644 --- a/Applications/IRCClient/IRCWindow.cpp +++ b/Applications/IRCClient/IRCWindow.cpp @@ -116,7 +116,7 @@ void IRCWindow::post_notification_if_needed(const String& name, const String& me notification->set_title(name); } - notification->set_icon_path("/res/icons/32x32/app-irc-client.png"); + notification->set_icon(Gfx::Bitmap::load_from_file("/res/icons/32x32/app-irc-client.png")); notification->set_text(message); notification->show(); } diff --git a/DevTools/IPCCompiler/main.cpp b/DevTools/IPCCompiler/main.cpp index b12e8328fab..252ef7dd4e8 100644 --- a/DevTools/IPCCompiler/main.cpp +++ b/DevTools/IPCCompiler/main.cpp @@ -228,6 +228,7 @@ int main(int argc, char** argv) dbg() << "#include "; dbg() << "#include "; dbg() << "#include "; + dbg() << "#include "; dbg() << "#include "; dbg() << "#include "; dbg() << "#include "; @@ -362,6 +363,10 @@ int main(int argc, char** argv) dbg() << " stream << rect.width();"; dbg() << " stream << rect.height();"; dbg() << " }"; + } else if (parameter.type == "Gfx::ShareableBitmap") { + dbg() << " stream << m_" << parameter.name << ".shbuf_id();"; + dbg() << " stream << m_" << parameter.name << ".width();"; + dbg() << " stream << m_" << parameter.name << ".height();"; } else { dbg() << " stream << m_" << parameter.name << ";"; } diff --git a/Libraries/LibGUI/DragOperation.cpp b/Libraries/LibGUI/DragOperation.cpp index 2f0cb55e2f9..462a9822f70 100644 --- a/Libraries/LibGUI/DragOperation.cpp +++ b/Libraries/LibGUI/DragOperation.cpp @@ -53,7 +53,7 @@ DragOperation::Outcome DragOperation::exec() Gfx::Size bitmap_size; RefPtr shared_bitmap; if (m_bitmap) { - shared_bitmap = m_bitmap->to_shareable_bitmap(); + shared_bitmap = m_bitmap->to_bitmap_backed_by_shared_buffer(); shared_bitmap->shared_buffer()->share_with(WindowServerConnection::the().server_pid()); bitmap_id = shared_bitmap->shbuf_id(); bitmap_size = shared_bitmap->size(); diff --git a/Libraries/LibGUI/Notification.cpp b/Libraries/LibGUI/Notification.cpp index af8d794d83b..4b231c9d2d0 100644 --- a/Libraries/LibGUI/Notification.cpp +++ b/Libraries/LibGUI/Notification.cpp @@ -35,7 +35,7 @@ Notification::~Notification() void Notification::show() { auto connection = NotificationServerConnection::construct(); - connection->post_message(Messages::NotificationServer::ShowNotification(m_text, m_title, m_icon_path)); + connection->send_sync(m_text, m_title, m_icon ? m_icon->to_shareable_bitmap(connection->server_pid()) : Gfx::ShareableBitmap()); } } diff --git a/Libraries/LibGUI/Notification.h b/Libraries/LibGUI/Notification.h index da13ca8be20..6896b963d57 100644 --- a/Libraries/LibGUI/Notification.h +++ b/Libraries/LibGUI/Notification.h @@ -1,6 +1,7 @@ #pragma once #include +#include namespace GUI { @@ -16,8 +17,8 @@ public: const String& title() const { return m_title; } void set_title(const String& title) { m_title = title; } - const String& icon_path() const { return m_icon_path; } - void set_icon_path(const String& icon_path) { m_icon_path = icon_path; } + const Gfx::Bitmap* icon() const { return m_icon; } + void set_icon(const Gfx::Bitmap* icon) { m_icon = icon; } void show(); @@ -26,7 +27,7 @@ private: String m_title; String m_text; - String m_icon_path; + RefPtr m_icon; }; } diff --git a/Libraries/LibGfx/Bitmap.cpp b/Libraries/LibGfx/Bitmap.cpp index cda0ad656b2..962ea59ba9d 100644 --- a/Libraries/LibGfx/Bitmap.cpp +++ b/Libraries/LibGfx/Bitmap.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -97,7 +98,7 @@ Bitmap::Bitmap(BitmapFormat format, NonnullRefPtr&& shared_buffer, ASSERT(format != BitmapFormat::Indexed8); } -NonnullRefPtr Bitmap::to_shareable_bitmap() const +NonnullRefPtr Bitmap::to_bitmap_backed_by_shared_buffer() const { if (m_shared_buffer) return *this; @@ -164,4 +165,12 @@ int Bitmap::shbuf_id() const return m_shared_buffer ? m_shared_buffer->shbuf_id() : -1; } +ShareableBitmap Bitmap::to_shareable_bitmap(pid_t peer_pid) const +{ + auto bitmap = to_bitmap_backed_by_shared_buffer(); + if (peer_pid > 0) + bitmap->shared_buffer()->share_with(peer_pid); + return ShareableBitmap(*bitmap); +} + } diff --git a/Libraries/LibGfx/Bitmap.h b/Libraries/LibGfx/Bitmap.h index be05d08cdb2..7fdec97e65b 100644 --- a/Libraries/LibGfx/Bitmap.h +++ b/Libraries/LibGfx/Bitmap.h @@ -30,6 +30,7 @@ #include #include #include +#include #include namespace Gfx { @@ -49,7 +50,9 @@ public: static RefPtr load_from_file(const StringView& path); static NonnullRefPtr create_with_shared_buffer(BitmapFormat, NonnullRefPtr&&, const Size&); - NonnullRefPtr to_shareable_bitmap() const; + NonnullRefPtr to_bitmap_backed_by_shared_buffer() const; + + ShareableBitmap to_shareable_bitmap(pid_t peer_pid = -1) const; ~Bitmap(); diff --git a/Libraries/LibGfx/Forward.h b/Libraries/LibGfx/Forward.h index c41c7bc21a7..37946b3b43b 100644 --- a/Libraries/LibGfx/Forward.h +++ b/Libraries/LibGfx/Forward.h @@ -44,6 +44,7 @@ class Palette; class PaletteImpl; class Point; class Rect; +class ShareableBitmap; class Size; class StylePainter; struct SystemTheme; diff --git a/Libraries/LibGfx/Makefile b/Libraries/LibGfx/Makefile index e02371bfe98..4c538660c7d 100644 --- a/Libraries/LibGfx/Makefile +++ b/Libraries/LibGfx/Makefile @@ -12,6 +12,7 @@ OBJS = \ Palette.o \ Point.o \ Rect.o \ + ShareableBitmap.o \ Size.o \ StylePainter.o \ SystemTheme.o \ diff --git a/Libraries/LibGfx/ShareableBitmap.cpp b/Libraries/LibGfx/ShareableBitmap.cpp new file mode 100644 index 00000000000..ad5fe8dacde --- /dev/null +++ b/Libraries/LibGfx/ShareableBitmap.cpp @@ -0,0 +1,40 @@ +#include +#include +#include +#include + +namespace Gfx { + +ShareableBitmap::ShareableBitmap(const Bitmap& bitmap) + : m_bitmap(bitmap.to_bitmap_backed_by_shared_buffer()) +{ +} + +} + +namespace IPC { + +bool decode(Decoder& decoder, Gfx::ShareableBitmap& shareable_bitmap) +{ + i32 shbuf_id = 0; + Gfx::Size size; + if (!decoder.decode(shbuf_id)) + return false; + if (!decoder.decode(size)) + return false; + + if (shbuf_id == -1) + return true; + + dbg() << "Decoding a ShareableBitmap with shbuf_id=" << shbuf_id << ", size=" << size; + + auto shared_buffer = SharedBuffer::create_from_shbuf_id(shbuf_id); + if (!shared_buffer) + return false; + + auto bitmap = Gfx::Bitmap::create_with_shared_buffer(Gfx::BitmapFormat::RGBA32, shared_buffer.release_nonnull(), size); + shareable_bitmap = bitmap->to_shareable_bitmap(); + return true; +} + +} diff --git a/Libraries/LibGfx/ShareableBitmap.h b/Libraries/LibGfx/ShareableBitmap.h new file mode 100644 index 00000000000..498ab64c377 --- /dev/null +++ b/Libraries/LibGfx/ShareableBitmap.h @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include + +namespace Gfx { + +class ShareableBitmap { +public: + ShareableBitmap() {} + explicit ShareableBitmap(const Gfx::Bitmap&); + + bool is_valid() const { return m_bitmap; } + + i32 shbuf_id() const { return m_bitmap ? m_bitmap->shbuf_id() : -1; } + + const Bitmap* bitmap() const { return m_bitmap; } + Bitmap* bitmap() { return m_bitmap; } + + Size size() const { return m_bitmap ? m_bitmap->size() : Size(); } + Rect rect() const { return m_bitmap ? m_bitmap->rect() : Rect(); } + + int width() const { return size().width(); } + int height() const { return size().height(); } + +private: + RefPtr m_bitmap; +}; + +} + +namespace IPC { +bool decode(Decoder&, Gfx::ShareableBitmap&); +} diff --git a/Servers/NotificationServer/ClientConnection.cpp b/Servers/NotificationServer/ClientConnection.cpp index c61d1cc028e..9b8064de031 100644 --- a/Servers/NotificationServer/ClientConnection.cpp +++ b/Servers/NotificationServer/ClientConnection.cpp @@ -53,10 +53,11 @@ OwnPtr ClientConnection::handle(con return make(client_id()); } -void ClientConnection::handle(const Messages::NotificationServer::ShowNotification& message) +OwnPtr ClientConnection::handle(const Messages::NotificationServer::ShowNotification& message) { - auto window = NotificationWindow::construct(message.text(), message.title(), message.icon_path()); + auto window = NotificationWindow::construct(message.text(), message.title(), message.icon()); window->show(); + return make(); } } diff --git a/Servers/NotificationServer/ClientConnection.h b/Servers/NotificationServer/ClientConnection.h index 93493679c87..bec07fb127c 100644 --- a/Servers/NotificationServer/ClientConnection.h +++ b/Servers/NotificationServer/ClientConnection.h @@ -43,7 +43,7 @@ private: explicit ClientConnection(Core::LocalSocket&, int client_id); virtual OwnPtr handle(const Messages::NotificationServer::Greet&) override; - virtual void handle(const Messages::NotificationServer::ShowNotification&) override; + virtual OwnPtr handle(const Messages::NotificationServer::ShowNotification&) override; }; } diff --git a/Servers/NotificationServer/NotificationServer.ipc b/Servers/NotificationServer/NotificationServer.ipc index 75bf5e0f89c..f1ac5e13df9 100644 --- a/Servers/NotificationServer/NotificationServer.ipc +++ b/Servers/NotificationServer/NotificationServer.ipc @@ -3,5 +3,5 @@ endpoint NotificationServer = 95 // Basic protocol Greet() => (i32 client_id) - ShowNotification(String text, String title, String icon_path) =| + ShowNotification(String text, String title, Gfx::ShareableBitmap icon) => () } diff --git a/Servers/NotificationServer/NotificationWindow.cpp b/Servers/NotificationServer/NotificationWindow.cpp index 42915f65f94..614075701c3 100644 --- a/Servers/NotificationServer/NotificationWindow.cpp +++ b/Servers/NotificationServer/NotificationWindow.cpp @@ -33,6 +33,7 @@ #include #include #include +#include namespace NotificationServer { @@ -55,7 +56,7 @@ void update_notification_window_locations() } } -NotificationWindow::NotificationWindow(const String& text, const String& title, const String& icon_path) +NotificationWindow::NotificationWindow(const String& text, const String& title, const Gfx::ShareableBitmap& icon) { s_windows.append(this); @@ -86,11 +87,11 @@ NotificationWindow::NotificationWindow(const String& text, const String& title, widget.layout()->set_margins({ 8, 8, 8, 8 }); widget.layout()->set_spacing(6); - if (auto icon = Gfx::Bitmap::load_from_file(icon_path)) { + if (icon.is_valid()) { auto& icon_label = widget.add(); icon_label.set_size_policy(GUI::SizePolicy::Fixed, GUI::SizePolicy::Fixed); icon_label.set_preferred_size(32, 32); - icon_label.set_icon(icon); + icon_label.set_icon(icon.bitmap()); } auto& left_container = widget.add(); diff --git a/Servers/NotificationServer/NotificationWindow.h b/Servers/NotificationServer/NotificationWindow.h index 232588ff609..3519af0752b 100644 --- a/Servers/NotificationServer/NotificationWindow.h +++ b/Servers/NotificationServer/NotificationWindow.h @@ -38,7 +38,7 @@ public: void set_original_rect(Gfx::Rect original_rect) { m_original_rect = original_rect; }; private: - NotificationWindow(const String& text, const String& title, const String& icon_path); + NotificationWindow(const String& text, const String& title, const Gfx::ShareableBitmap&); Gfx::Rect m_original_rect; }; diff --git a/Userland/notify.cpp b/Userland/notify.cpp index 4dded943f55..37431e00ee5 100644 --- a/Userland/notify.cpp +++ b/Userland/notify.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include int main(int argc, char** argv) @@ -45,7 +46,7 @@ int main(int argc, char** argv) auto notification = GUI::Notification::construct(); notification->set_text(message); notification->set_title(title); - notification->set_icon_path(icon_path); + notification->set_icon(Gfx::Bitmap::load_from_file(icon_path)); notification->show(); return 0;