FreeRDP
Loading...
Searching...
No Matches
sdl_clip.hpp
1
21#pragma once
22
23#include <utility>
24#include <vector>
25#include <atomic>
26#include <queue>
27#include <deque>
28#include <map>
29
30#include <winpr/wtypes.h>
31#include <freerdp/freerdp.h>
32#include <freerdp/client/client_cliprdr_file.h>
33#include <SDL3/SDL.h>
34
35#include "sdl_types.hpp"
36#include "sdl_utils.hpp"
37
40{
41 public:
42 ClipRequest(UINT32 format, const std::string& mime);
43 ClipRequest(const ClipRequest& other) = default;
44 ClipRequest(ClipRequest&& other) = default;
45 ~ClipRequest() = default;
46
47 ClipRequest& operator=(const ClipRequest& other) = delete;
48 ClipRequest& operator=(ClipRequest&& other) = delete;
49
50 [[nodiscard]] uint32_t format() const;
51 [[nodiscard]] std::string formatstr() const;
52 [[nodiscard]] std::string mime() const;
53 [[nodiscard]] bool success() const;
54 void setSuccess(bool status);
55
56 private:
57 uint32_t _format;
58 std::string _mime;
59 bool _success;
60};
61
63{
64 public:
65 CliprdrFormat(uint32_t formatID, const char* formatName);
66
67 [[nodiscard]] uint32_t formatId() const;
68 [[nodiscard]] const char* formatName() const;
69
70 private:
71 uint32_t _formatID;
72 std::string _formatName;
73};
74
77{
78 public:
79 explicit sdlClip(SdlContext* sdl);
80 virtual ~sdlClip();
81
82 sdlClip(const sdlClip&) = delete;
83 sdlClip(sdlClip&&) = delete;
84
85 sdlClip& operator=(const sdlClip&) = delete;
86 sdlClip& operator=(sdlClip&&) = delete;
87
88 [[nodiscard]] bool init(CliprdrClientContext* clip);
89 [[nodiscard]] bool uninit(CliprdrClientContext* clip);
90
91 [[nodiscard]] bool handleEvent(const SDL_ClipboardEvent& ev);
92
93 /* Answers the queued server CB_FORMAT_DATA_REQUESTs. Runs on the SDL main thread: the SDL
94 * clipboard API is main-thread only, and ReceiveFormatDataRequest only queues them. */
95 void handleDataRequests();
96
97 private:
98 [[nodiscard]] UINT SendClientCapabilities();
99 void clearServerFormats();
100 [[nodiscard]] UINT SendFormatListResponse(BOOL status);
101 [[nodiscard]] UINT SendDataResponse(const BYTE* data, size_t size);
102 [[nodiscard]] UINT SendDataRequest(uint32_t formatID, const std::string& mime);
103
104 [[nodiscard]] std::string getServerFormat(uint32_t id);
105 [[nodiscard]] uint32_t serverIdForMime(const std::string& mime);
106
107 [[nodiscard]] bool contains(const char** mime_types, Sint32 count);
108 [[nodiscard]] bool ownsClipboard() const;
109
110 [[nodiscard]] static UINT MonitorReady(CliprdrClientContext* context,
111 const CLIPRDR_MONITOR_READY* monitorReady);
112
113 [[nodiscard]] static UINT ReceiveServerCapabilities(CliprdrClientContext* context,
114 const CLIPRDR_CAPABILITIES* capabilities);
115 [[nodiscard]] static UINT ReceiveServerFormatList(CliprdrClientContext* context,
116 const CLIPRDR_FORMAT_LIST* formatList);
117 [[nodiscard]] static UINT
118 ReceiveFormatListResponse(CliprdrClientContext* context,
119 const CLIPRDR_FORMAT_LIST_RESPONSE* formatListResponse);
120 [[nodiscard]] std::shared_ptr<BYTE> getLocalData(uint32_t formatId, uint32_t& len);
121 [[nodiscard]] static UINT
122 ReceiveFormatDataRequest(CliprdrClientContext* context,
123 const CLIPRDR_FORMAT_DATA_REQUEST* formatDataRequest);
124 [[nodiscard]] static UINT
125 ReceiveFormatDataResponse(CliprdrClientContext* context,
126 const CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse);
127
128 [[nodiscard]] static const void* SDLCALL ClipDataCb(void* userdata, const char* mime_type,
129 size_t* size);
130 static void SDLCALL ClipCleanCb(void* userdata);
131
132 [[nodiscard]] static bool mime_is_file(const std::string& mime);
133 [[nodiscard]] static bool mime_is_text(const std::string& mime);
134 [[nodiscard]] static bool mime_is_utf8(const std::string& mime);
135 [[nodiscard]] static bool mime_is_image(const std::string& mime);
136 [[nodiscard]] static bool mime_is_bmp(const std::string& mime);
137 [[nodiscard]] static bool mime_is_html(const std::string& mime);
138
139 SdlContext* _sdl = nullptr;
140 CliprdrFileContext* _file = nullptr;
141 CliprdrClientContext* _ctx = nullptr;
142 wLog* _log = nullptr;
143 wClipboard* _system = nullptr;
144 std::atomic<bool> _sync = false;
145 HANDLE _event = nullptr;
146 Uint64 _last_timestamp = 0;
147
148 std::vector<CliprdrFormat> _serverFormats;
149 CriticalSection _lock;
150
151 std::queue<ClipRequest> _request_queue;
152
153 struct cache_entry
154 {
155 cache_entry(size_t len, std::shared_ptr<void> p) : size(len), ptr(std::move(p))
156 {
157 }
158
159 size_t size;
160 std::shared_ptr<void> ptr;
161 };
162 std::map<std::string, cache_entry> _cache_data;
163 /* mime types of the latest server format list, not yet handed to SDL (guarded by _lock) */
164 std::vector<std::string> _current_mimetypes;
165 /* guarded by _lock: server data requests not answered yet, and whether ClipDataCb is
166 * waiting for the server (a local application is reading our offer of server data) */
167 std::deque<uint32_t> _server_requests;
168 bool _reading_server = false;
169 std::string _uuid;
170 std::string _mime_uuid;
171};
a clipboard format request
Definition sdl_clip.hpp:40
object that handles clipboard context for the SDL3 client
Definition sdl_clip.hpp:77