23 #include <freerdp/config.h>
25 #include <winpr/crt.h>
26 #include <winpr/stream.h>
27 #include <winpr/clipboard.h>
29 #include <freerdp/client/channels.h>
30 #include <freerdp/client/cliprdr.h>
32 #include "ios_cliprdr.h"
34 UINT ios_cliprdr_send_client_format_list(CliprdrClientContext *cliprdr)
36 UINT rc = ERROR_INTERNAL_ERROR;
40 const char *formatName;
45 return ERROR_INVALID_PARAMETER;
49 if (!afc || !afc->cliprdr)
50 return ERROR_INVALID_PARAMETER;
53 numFormats = ClipboardGetFormatIds(afc->clipboard, &pFormatIds);
59 for (UINT32 index = 0; index < numFormats; index++)
61 formatId = pFormatIds[index];
62 formatName = ClipboardGetFormatName(afc->clipboard, formatId);
63 formats[index].formatId = formatId;
64 formats[index].formatName = NULL;
66 if ((formatId > CF_MAX) && formatName)
68 formats[index].formatName = _strdup(formatName);
70 if (!formats[index].formatName)
75 formatList.common.msgFlags = 0;
76 formatList.numFormats = numFormats;
77 formatList.formats = formats;
78 formatList.common.msgType = CB_FORMAT_LIST;
80 if (!afc->cliprdr->ClientFormatList)
83 rc = afc->cliprdr->ClientFormatList(afc->cliprdr, &formatList);
90 static UINT ios_cliprdr_send_client_format_data_request(CliprdrClientContext *cliprdr,
93 UINT rc = ERROR_INVALID_PARAMETER;
102 if (!afc || !afc->clipboardRequestEvent || !cliprdr->ClientFormatDataRequest)
105 formatDataRequest.common.msgType = CB_FORMAT_DATA_REQUEST;
106 formatDataRequest.common.msgFlags = 0;
107 formatDataRequest.requestedFormatId = formatId;
108 afc->requestedFormatId = formatId;
109 (void)ResetEvent(afc->clipboardRequestEvent);
110 rc = cliprdr->ClientFormatDataRequest(cliprdr, &formatDataRequest);
115 static UINT ios_cliprdr_send_client_capabilities(CliprdrClientContext *cliprdr)
120 if (!cliprdr || !cliprdr->ClientCapabilities)
121 return ERROR_INVALID_PARAMETER;
123 capabilities.cCapabilitiesSets = 1;
125 generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
126 generalCapabilitySet.capabilitySetLength = 12;
127 generalCapabilitySet.version = CB_CAPS_VERSION_2;
128 generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
129 return cliprdr->ClientCapabilities(cliprdr, &capabilities);
137 static UINT ios_cliprdr_monitor_ready(CliprdrClientContext *cliprdr,
143 if (!cliprdr || !monitorReady)
144 return ERROR_INVALID_PARAMETER;
149 return ERROR_INVALID_PARAMETER;
151 if ((rc = ios_cliprdr_send_client_capabilities(cliprdr)) != CHANNEL_RC_OK)
154 if ((rc = ios_cliprdr_send_client_format_list(cliprdr)) != CHANNEL_RC_OK)
157 afc->clipboardSync = TRUE;
158 return CHANNEL_RC_OK;
166 static UINT ios_cliprdr_server_capabilities(CliprdrClientContext *cliprdr,
172 if (!cliprdr || !capabilities)
173 return ERROR_INVALID_PARAMETER;
178 return ERROR_INVALID_PARAMETER;
180 for (UINT32 index = 0; index < capabilities->cCapabilitiesSets; index++)
182 capabilitySet = &(capabilities->capabilitySets[index]);
184 if ((capabilitySet->capabilitySetType == CB_CAPSTYPE_GENERAL) &&
185 (capabilitySet->capabilitySetLength >= CB_CAPSTYPE_GENERAL_LEN))
189 afc->clipboardCapabilities = generalCapabilitySet->generalFlags;
194 return CHANNEL_RC_OK;
202 static UINT ios_cliprdr_server_format_list(CliprdrClientContext *cliprdr,
209 if (!cliprdr || !formatList)
210 return ERROR_INVALID_PARAMETER;
215 return ERROR_INVALID_PARAMETER;
217 if (afc->serverFormats)
219 for (UINT32 index = 0; index < afc->numServerFormats; index++)
220 free(afc->serverFormats[index].formatName);
222 free(afc->serverFormats);
223 afc->serverFormats = NULL;
224 afc->numServerFormats = 0;
227 if (formatList->numFormats < 1)
228 return CHANNEL_RC_OK;
230 afc->numServerFormats = formatList->numFormats;
233 if (!afc->serverFormats)
234 return CHANNEL_RC_NO_MEMORY;
236 for (UINT32 index = 0; index < afc->numServerFormats; index++)
238 afc->serverFormats[index].formatId = formatList->formats[index].formatId;
239 afc->serverFormats[index].formatName = NULL;
241 if (formatList->formats[index].formatName)
243 afc->serverFormats[index].formatName = _strdup(formatList->formats[index].formatName);
245 if (!afc->serverFormats[index].formatName)
246 return CHANNEL_RC_NO_MEMORY;
250 BOOL unicode = FALSE;
252 for (UINT32 index = 0; index < afc->numServerFormats; index++)
254 format = &(afc->serverFormats[index]);
256 if (format->formatId == CF_UNICODETEXT)
259 else if (format->formatId == CF_TEXT)
264 return ios_cliprdr_send_client_format_data_request(cliprdr, CF_UNICODETEXT);
266 return ios_cliprdr_send_client_format_data_request(cliprdr, CF_TEXT);
267 return CHANNEL_RC_OK;
276 ios_cliprdr_server_format_list_response(CliprdrClientContext *cliprdr,
279 if (!cliprdr || !formatListResponse)
280 return ERROR_INVALID_PARAMETER;
282 return CHANNEL_RC_OK;
291 ios_cliprdr_server_lock_clipboard_data(CliprdrClientContext *cliprdr,
294 if (!cliprdr || !lockClipboardData)
295 return ERROR_INVALID_PARAMETER;
297 return CHANNEL_RC_OK;
306 ios_cliprdr_server_unlock_clipboard_data(CliprdrClientContext *cliprdr,
309 if (!cliprdr || !unlockClipboardData)
310 return ERROR_INVALID_PARAMETER;
312 return CHANNEL_RC_OK;
321 ios_cliprdr_server_format_data_request(CliprdrClientContext *cliprdr,
331 if (!cliprdr || !formatDataRequest || !cliprdr->ClientFormatDataResponse)
332 return ERROR_INVALID_PARAMETER;
337 return ERROR_INVALID_PARAMETER;
339 formatId = formatDataRequest->requestedFormatId;
340 data = (BYTE *)ClipboardGetData(afc->clipboard, formatId, &size);
341 response.common.msgFlags = CB_RESPONSE_OK;
342 response.common.dataLen = size;
343 response.requestedFormatData = data;
347 response.common.msgFlags = CB_RESPONSE_FAIL;
348 response.common.dataLen = 0;
349 response.requestedFormatData = NULL;
352 rc = cliprdr->ClientFormatDataResponse(cliprdr, &response);
363 ios_cliprdr_server_format_data_response(CliprdrClientContext *cliprdr,
373 if (!cliprdr || !formatDataResponse)
374 return ERROR_INVALID_PARAMETER;
379 return ERROR_INVALID_PARAMETER;
381 instance = ((rdpContext *)afc)->instance;
384 return ERROR_INVALID_PARAMETER;
386 for (UINT32 index = 0; index < afc->numServerFormats; index++)
388 if (afc->requestedFormatId == afc->serverFormats[index].formatId)
389 format = &(afc->serverFormats[index]);
394 (void)SetEvent(afc->clipboardRequestEvent);
395 return ERROR_INTERNAL_ERROR;
398 if (format->formatName)
399 formatId = ClipboardRegisterFormat(afc->clipboard, format->formatName);
401 formatId = format->formatId;
403 size = formatDataResponse->common.dataLen;
405 ClipboardLock(afc->clipboard);
406 if (!ClipboardSetData(afc->clipboard, formatId, formatDataResponse->requestedFormatData, size))
407 return ERROR_INTERNAL_ERROR;
409 (void)SetEvent(afc->clipboardRequestEvent);
411 if ((formatId == CF_TEXT) || (formatId == CF_UNICODETEXT))
413 formatId = ClipboardRegisterFormat(afc->clipboard,
"UTF8_STRING");
414 data = (BYTE *)ClipboardGetData(afc->clipboard, formatId, &size);
415 size = (UINT32)strnlen(data, size);
416 if (afc->ServerCutText != NULL)
418 afc->ServerCutText((rdpContext *)afc, (uint8_t *)data, size);
421 ClipboardUnlock(afc->clipboard);
423 return CHANNEL_RC_OK;
432 ios_cliprdr_server_file_contents_request(CliprdrClientContext *cliprdr,
435 if (!cliprdr || !fileContentsRequest)
436 return ERROR_INVALID_PARAMETER;
438 return CHANNEL_RC_OK;
446 static UINT ios_cliprdr_server_file_contents_response(
449 if (!cliprdr || !fileContentsResponse)
450 return ERROR_INVALID_PARAMETER;
452 return CHANNEL_RC_OK;
455 BOOL ios_cliprdr_init(
mfContext *afc, CliprdrClientContext *cliprdr)
457 wClipboard *clipboard;
460 if (!afc || !cliprdr)
463 if (!(hevent = CreateEvent(NULL, TRUE, FALSE, NULL)))
466 if (!(clipboard = ClipboardCreate()))
468 (void)CloseHandle(hevent);
472 afc->cliprdr = cliprdr;
473 afc->clipboard = clipboard;
474 afc->clipboardRequestEvent = hevent;
475 cliprdr->custom = (
void *)afc;
476 cliprdr->MonitorReady = ios_cliprdr_monitor_ready;
477 cliprdr->ServerCapabilities = ios_cliprdr_server_capabilities;
478 cliprdr->ServerFormatList = ios_cliprdr_server_format_list;
479 cliprdr->ServerFormatListResponse = ios_cliprdr_server_format_list_response;
480 cliprdr->ServerLockClipboardData = ios_cliprdr_server_lock_clipboard_data;
481 cliprdr->ServerUnlockClipboardData = ios_cliprdr_server_unlock_clipboard_data;
482 cliprdr->ServerFormatDataRequest = ios_cliprdr_server_format_data_request;
483 cliprdr->ServerFormatDataResponse = ios_cliprdr_server_format_data_response;
484 cliprdr->ServerFileContentsRequest = ios_cliprdr_server_file_contents_request;
485 cliprdr->ServerFileContentsResponse = ios_cliprdr_server_file_contents_response;
489 BOOL ios_cliprdr_uninit(
mfContext *afc, CliprdrClientContext *cliprdr)
491 if (!afc || !cliprdr)
494 cliprdr->custom = NULL;
496 ClipboardDestroy(afc->clipboard);
497 (void)CloseHandle(afc->clipboardRequestEvent);