168{
169 if (!_ctx || !_sync || ev.owner)
170 {
171
172 if (ev.owner && (ev.reserved == 0x42))
173 {
174 _cache_data.clear();
175 auto rc =
176 SDL_SetClipboardData(sdlClip::ClipDataCb, sdlClip::ClipCleanCb, this, ev.mime_types,
177 WINPR_ASSERTING_INT_CAST(size_t, ev.num_mime_types));
178 _current_mimetypes.clear();
179 return rc;
180 }
181 return true;
182 }
183
184 clearServerFormats();
185
186 std::string mime_html = s_mime_html;
187
188 std::vector<std::string> mime_bitmap = { BMP_MIME_LIST };
189 std::string mime_webp = s_mime_webp;
190 std::string mime_png = s_mime_png;
191 std::string mime_jpeg = s_mime_jpg;
192 std::string mime_tiff = s_mime_tiff;
193 std::vector<std::string> mime_images = { mime_webp, mime_png, mime_jpeg, mime_tiff };
194
195 std::vector<std::string> clientFormatNames;
196 std::vector<CLIPRDR_FORMAT> clientFormats;
197
198 size_t nformats = WINPR_ASSERTING_INT_CAST(size_t, ev.num_mime_types);
199 const char** clipboard_mime_formats = ev.mime_types;
200
201 WLog_Print(_log, WLOG_TRACE, "SDL has %d formats", nformats);
202
203 bool textPushed = false;
204 bool imgPushed = false;
205
206 for (size_t i = 0; i < nformats; i++)
207 {
208 std::string local_mime = clipboard_mime_formats[i];
209 WLog_Print(_log, WLOG_TRACE, " - %s", local_mime.c_str());
210
211 if (std::find(s_mime_text().begin(), s_mime_text().end(), local_mime) !=
212 s_mime_text().end())
213 {
214
215 if (!textPushed)
216 {
217 clientFormats.push_back({ CF_TEXT, nullptr });
218 clientFormats.push_back({ CF_OEMTEXT, nullptr });
219 clientFormats.push_back({ CF_UNICODETEXT, nullptr });
220 textPushed = true;
221 }
222 }
223 else if (local_mime == mime_html)
224
225 clientFormatNames.emplace_back(s_type_HtmlFormat);
226 else if ((std::find(mime_bitmap.begin(), mime_bitmap.end(), local_mime) !=
227 mime_bitmap.end()) ||
228 (std::find(mime_images.begin(), mime_images.end(), local_mime) !=
229 mime_images.end()))
230 {
231
232 if (!imgPushed)
233 {
234 clientFormats.push_back({ CF_DIB, nullptr });
235#if defined(WINPR_UTILS_IMAGE_DIBv5)
236 clientFormats.push_back({ CF_DIBV5, nullptr });
237#endif
238
239 for (auto& bmp : mime_bitmap)
240 clientFormatNames.push_back(bmp);
241
242 for (auto& img : mime_images)
243 clientFormatNames.push_back(img);
244
245 clientFormatNames.emplace_back(s_type_HtmlFormat);
246 imgPushed = true;
247 }
248 }
249 }
250
251 for (auto& name : clientFormatNames)
252 {
253 clientFormats.push_back({ ClipboardRegisterFormat(_system, name.c_str()), name.data() });
254 }
255
256 std::sort(clientFormats.begin(), clientFormats.end(),
257 [](const auto& a, const auto& b) { return a < b; });
258 auto u = std::unique(clientFormats.begin(), clientFormats.end());
259 clientFormats.erase(u, clientFormats.end());
260
262 { CB_FORMAT_LIST, 0, 0 },
263 static_cast<UINT32>(clientFormats.size()),
264 clientFormats.data(),
265 };
266
267 WLog_Print(_log, WLOG_TRACE,
268 "-------------- client format list [%" PRIu32 "] ------------------",
269 formatList.numFormats);
270 for (UINT32 x = 0; x < formatList.numFormats; x++)
271 {
272 auto format = &formatList.formats[x];
273 WLog_Print(_log, WLOG_TRACE, "client announces %" PRIu32 " [%s][%s]", format->formatId,
274 ClipboardGetFormatIdString(format->formatId), format->formatName);
275 }
276
277 WINPR_ASSERT(_ctx);
278 WINPR_ASSERT(_ctx->ClientFormatList);
279 return _ctx->ClientFormatList(_ctx, &formatList) == CHANNEL_RC_OK;
280}