mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:57:45 +00:00
SpiceAgent: Add support for copying images to the clipboard
This commit is contained in:
parent
50a8db3922
commit
9f92e52464
4 changed files with 63 additions and 11 deletions
|
@ -11,6 +11,38 @@
|
||||||
|
|
||||||
namespace SpiceAgent {
|
namespace SpiceAgent {
|
||||||
|
|
||||||
|
ErrorOr<String> clipboard_data_type_to_mime_type(ClipboardDataType data_type)
|
||||||
|
{
|
||||||
|
switch (data_type) {
|
||||||
|
case ClipboardDataType::Text:
|
||||||
|
return "text/plain"_string;
|
||||||
|
|
||||||
|
case ClipboardDataType::PNG:
|
||||||
|
return "image/png"_string;
|
||||||
|
|
||||||
|
case ClipboardDataType::BMP:
|
||||||
|
return "image/bitmap"_string;
|
||||||
|
|
||||||
|
case ClipboardDataType::JPG:
|
||||||
|
return "image/jpeg"_string;
|
||||||
|
|
||||||
|
case ClipboardDataType::TIFF:
|
||||||
|
return "image/tiff"_string;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return Error::from_string_literal("Unable to determine mime type!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorOr<ClipboardDataType> clipboard_data_type_from_raw_value(u32 value)
|
||||||
|
{
|
||||||
|
if (value >= to_underlying(ClipboardDataType::__End)) {
|
||||||
|
return Error::from_string_literal("Unsupported clipboard type");
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_cast<ClipboardDataType>(value);
|
||||||
|
}
|
||||||
|
|
||||||
ErrorOr<AnnounceCapabilitiesMessage> AnnounceCapabilitiesMessage::read_from_stream(AK::Stream& stream)
|
ErrorOr<AnnounceCapabilitiesMessage> AnnounceCapabilitiesMessage::read_from_stream(AK::Stream& stream)
|
||||||
{
|
{
|
||||||
// If this message is a capabilities request, we don't have to parse anything else.
|
// If this message is a capabilities request, we don't have to parse anything else.
|
||||||
|
@ -57,11 +89,7 @@ ErrorOr<ClipboardGrabMessage> ClipboardGrabMessage::read_from_stream(AK::Stream&
|
||||||
auto types = Vector<ClipboardDataType>();
|
auto types = Vector<ClipboardDataType>();
|
||||||
while (!stream.is_eof()) {
|
while (!stream.is_eof()) {
|
||||||
auto value = TRY(stream.read_value<u32>());
|
auto value = TRY(stream.read_value<u32>());
|
||||||
if (value >= to_underlying(ClipboardDataType::__End)) {
|
types.append(TRY(clipboard_data_type_from_raw_value(value)));
|
||||||
return Error::from_string_literal("Unsupported clipboard type");
|
|
||||||
}
|
|
||||||
|
|
||||||
types.append(static_cast<ClipboardDataType>(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ClipboardGrabMessage(types);
|
return ClipboardGrabMessage(types);
|
||||||
|
@ -88,11 +116,7 @@ ErrorOr<String> ClipboardGrabMessage::debug_description()
|
||||||
ErrorOr<ClipboardRequestMessage> ClipboardRequestMessage::read_from_stream(AK::Stream& stream)
|
ErrorOr<ClipboardRequestMessage> ClipboardRequestMessage::read_from_stream(AK::Stream& stream)
|
||||||
{
|
{
|
||||||
auto value = TRY(stream.read_value<u32>());
|
auto value = TRY(stream.read_value<u32>());
|
||||||
if (value >= to_underlying(ClipboardDataType::__End)) {
|
auto type = TRY(clipboard_data_type_from_raw_value(value));
|
||||||
return Error::from_string_literal("Unsupported clipboard type");
|
|
||||||
}
|
|
||||||
|
|
||||||
auto type = static_cast<ClipboardDataType>(value);
|
|
||||||
return ClipboardRequestMessage(type);
|
return ClipboardRequestMessage(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/ByteBuffer.h>
|
#include <AK/ByteBuffer.h>
|
||||||
#include <AK/Format.h>
|
#include <AK/Format.h>
|
||||||
#include <AK/Forward.h>
|
#include <AK/Forward.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
|
||||||
namespace SpiceAgent {
|
namespace SpiceAgent {
|
||||||
|
@ -50,6 +51,9 @@ enum class ClipboardDataType : u32 {
|
||||||
__End
|
__End
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ErrorOr<String> clipboard_data_type_to_mime_type(ClipboardDataType type);
|
||||||
|
ErrorOr<ClipboardDataType> clipboard_data_type_from_raw_value(u32 value);
|
||||||
|
|
||||||
class Message {
|
class Message {
|
||||||
public:
|
public:
|
||||||
// The spice protocol headers contain a bit of documentation about these, but nothing major:
|
// The spice protocol headers contain a bit of documentation about these, but nothing major:
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "SpiceAgent.h"
|
#include "SpiceAgent.h"
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <LibGUI/Clipboard.h>
|
#include <LibGUI/Clipboard.h>
|
||||||
|
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
||||||
|
|
||||||
namespace SpiceAgent {
|
namespace SpiceAgent {
|
||||||
|
|
||||||
|
@ -111,11 +112,33 @@ ErrorOr<void> SpiceAgent::did_receive_clipboard_message(ClipboardMessage& messag
|
||||||
case ClipboardDataType::Text: {
|
case ClipboardDataType::Text: {
|
||||||
// The default mime_type for set_data is `text/plain`.
|
// The default mime_type for set_data is `text/plain`.
|
||||||
GUI::Clipboard::the().set_data(message.contents());
|
GUI::Clipboard::the().set_data(message.contents());
|
||||||
return {};
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For the image formats, let's try to find a decoder from LibGfx.
|
||||||
|
case ClipboardDataType::PNG:
|
||||||
|
case ClipboardDataType::BMP:
|
||||||
|
case ClipboardDataType::JPG:
|
||||||
|
case ClipboardDataType::TIFF: {
|
||||||
|
auto mime_type = TRY(clipboard_data_type_to_mime_type(message.data_type()));
|
||||||
|
|
||||||
|
// FIXME: It should be trivial to make `try_create_for_raw_bytes` take a `StringView` instead of a direct `DeprecatedString`.
|
||||||
|
auto decoder = Gfx::ImageDecoder::try_create_for_raw_bytes(message.contents(), mime_type.to_deprecated_string());
|
||||||
|
if (!decoder || (decoder->frame_count() == 0)) {
|
||||||
|
return Error::from_string_literal("Failed to find a suitable decoder for a pasted image!");
|
||||||
|
}
|
||||||
|
|
||||||
|
auto frame = TRY(decoder->frame(0));
|
||||||
|
GUI::Clipboard::the().set_bitmap(*frame.image);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Error::from_string_literal("Unsupported clipboard data type!");
|
return Error::from_string_literal("Unsupported clipboard data type!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<ByteBuffer> SpiceAgent::read_message_buffer()
|
ErrorOr<ByteBuffer> SpiceAgent::read_message_buffer()
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "Message.h"
|
#include "Message.h"
|
||||||
#include "MessageHeader.h"
|
#include "MessageHeader.h"
|
||||||
#include <AK/MemoryStream.h>
|
#include <AK/MemoryStream.h>
|
||||||
|
#include <AK/String.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
#include <LibCore/File.h>
|
#include <LibCore/File.h>
|
||||||
#include <LibCore/Notifier.h>
|
#include <LibCore/Notifier.h>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue