summaryrefslogtreecommitdiff
path: root/Userland/Services/SpiceAgent/SpiceAgent.h
blob: 9ef81d7ed1de504c849a7da38dd423802496e30f (plain)
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);
};