1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*
* Copyright (c) 2021, Kyle Pereira <kyle@xylepereira.me>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "ConnectionToClipboardServer.h"
#include <AK/ByteBuffer.h>
#include <AK/Vector.h>
#include <LibCore/Notifier.h>
#pragma once
class SpiceAgent {
public:
SpiceAgent(int fd, ConnectionToClipboardServer&);
static constexpr u32 AGENT_PROTOCOL = 1;
enum class Port {
Client = 1,
Server
};
struct [[gnu::packed]] ChunkHeader {
u32 port {};
u32 size {};
};
struct [[gnu::packed]] Message {
u32 protocol;
u32 type;
u64 opaque;
u32 size;
u8 data[];
};
enum class MessageType {
MouseState = 1, // server -> client
MonitorsConfig, // client -> agent|server
Reply, // agent -> client
Clipboard, // both directions
DisplayConfig, // client -> agent
AnnounceCapabilities, // both directions
ClipboardGrab, // both directions
ClipboardRequest, // both directions
ClipboardRelease, // both directions
FileTransferStart,
FileTransferStatus,
FileTransferData,
Disconnected,
MaxClipboard,
VolumeSync,
GraphicsDeviceInfo,
};
enum class Capability {
MouseState = 0,
MonitorsConfig,
Reply,
Clipboard,
DisplayConfig,
ClipboardByDemand,
ClipboardSelection,
SparseMonitorsConfig,
GuestLineEndLF,
GuestLineEndCRLF,
MaxClipboard,
AudioVolumeSync,
MonitorsConfigPosition,
FileTransferDisabled,
FileTransferDetailedErrors,
GraphicsCardInfo,
ClipboardNoReleaseOnRegrab,
ClipboardGrabSerial,
__End,
};
enum class ClipboardType {
None = 0,
Text,
PNG,
BMP,
TIFF,
JPG,
FileList,
__Count
};
constexpr static size_t CAPABILITIES_SIZE = ((size_t)Capability::__End + 31) / 32;
struct [[gnu::packed]] AnnounceCapabilities {
u32 request;
u32 caps[CAPABILITIES_SIZE];
static ByteBuffer make_buffer(bool request, Vector<Capability> const& capabilities);
};
struct [[gnu::packed]] ClipboardGrab {
u32 types[0];
static ByteBuffer make_buffer(Vector<ClipboardType> const&);
};
struct [[gnu::packed]] Clipboard {
u32 type;
u8 data[];
static ByteBuffer make_buffer(ClipboardType, ReadonlyBytes);
};
struct [[gnu::packed]] ClipboardRequest {
u32 type;
static ByteBuffer make_buffer(ClipboardType);
};
private:
int m_fd { -1 };
RefPtr<Core::Notifier> m_notifier;
ConnectionToClipboardServer& m_clipboard_connection;
void on_message_received();
void send_message(ByteBuffer const& buffer);
bool m_just_set_clip { false };
void read_n(void* dest, size_t n);
static Message* initialize_headers(u8* data, size_t additional_data_size, MessageType type);
static Optional<ClipboardType> mime_type_to_clipboard_type(String const& mime);
};
|