mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:07:34 +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 {
|
||||
|
||||
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)
|
||||
{
|
||||
// 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>();
|
||||
while (!stream.is_eof()) {
|
||||
auto value = TRY(stream.read_value<u32>());
|
||||
if (value >= to_underlying(ClipboardDataType::__End)) {
|
||||
return Error::from_string_literal("Unsupported clipboard type");
|
||||
}
|
||||
|
||||
types.append(static_cast<ClipboardDataType>(value));
|
||||
types.append(TRY(clipboard_data_type_from_raw_value(value)));
|
||||
}
|
||||
|
||||
return ClipboardGrabMessage(types);
|
||||
|
@ -88,11 +116,7 @@ ErrorOr<String> ClipboardGrabMessage::debug_description()
|
|||
ErrorOr<ClipboardRequestMessage> ClipboardRequestMessage::read_from_stream(AK::Stream& stream)
|
||||
{
|
||||
auto value = TRY(stream.read_value<u32>());
|
||||
if (value >= to_underlying(ClipboardDataType::__End)) {
|
||||
return Error::from_string_literal("Unsupported clipboard type");
|
||||
}
|
||||
|
||||
auto type = static_cast<ClipboardDataType>(value);
|
||||
auto type = TRY(clipboard_data_type_from_raw_value(value));
|
||||
return ClipboardRequestMessage(type);
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/Format.h>
|
||||
#include <AK/Forward.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
namespace SpiceAgent {
|
||||
|
@ -50,6 +51,9 @@ enum class ClipboardDataType : u32 {
|
|||
__End
|
||||
};
|
||||
|
||||
ErrorOr<String> clipboard_data_type_to_mime_type(ClipboardDataType type);
|
||||
ErrorOr<ClipboardDataType> clipboard_data_type_from_raw_value(u32 value);
|
||||
|
||||
class Message {
|
||||
public:
|
||||
// The spice protocol headers contain a bit of documentation about these, but nothing major:
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "SpiceAgent.h"
|
||||
#include <AK/Debug.h>
|
||||
#include <LibGUI/Clipboard.h>
|
||||
#include <LibGfx/ImageFormats/ImageDecoder.h>
|
||||
|
||||
namespace SpiceAgent {
|
||||
|
||||
|
@ -111,11 +112,33 @@ ErrorOr<void> SpiceAgent::did_receive_clipboard_message(ClipboardMessage& messag
|
|||
case ClipboardDataType::Text: {
|
||||
// The default mime_type for set_data is `text/plain`.
|
||||
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:
|
||||
return Error::from_string_literal("Unsupported clipboard data type!");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<ByteBuffer> SpiceAgent::read_message_buffer()
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "Message.h"
|
||||
#include "MessageHeader.h"
|
||||
#include <AK/MemoryStream.h>
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibCore/File.h>
|
||||
#include <LibCore/Notifier.h>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue