22 #include <freerdp/config.h>
26 #include <winpr/crt.h>
27 #include <winpr/stream.h>
29 #include <freerdp/client/channels.h>
30 #include <freerdp/client/cliprdr.h>
32 #include "android_cliprdr.h"
33 #include "android_jni_utils.h"
34 #include "android_jni_callback.h"
36 UINT android_cliprdr_send_client_format_list(CliprdrClientContext* cliprdr)
38 UINT rc = ERROR_INTERNAL_ERROR;
42 const char* formatName;
47 return ERROR_INVALID_PARAMETER;
51 if (!afc || !afc->cliprdr)
52 return ERROR_INVALID_PARAMETER;
55 numFormats = ClipboardGetFormatIds(afc->clipboard, &pFormatIds);
61 for (UINT32 index = 0; index < numFormats; index++)
63 formatId = pFormatIds[index];
64 formatName = ClipboardGetFormatName(afc->clipboard, formatId);
65 formats[index].formatId = formatId;
66 formats[index].formatName = NULL;
68 if ((formatId > CF_MAX) && formatName)
70 formats[index].formatName = _strdup(formatName);
72 if (!formats[index].formatName)
77 formatList.common.msgFlags = 0;
78 formatList.numFormats = numFormats;
79 formatList.formats = formats;
80 formatList.common.msgType = CB_FORMAT_LIST;
82 if (!afc->cliprdr->ClientFormatList)
85 rc = afc->cliprdr->ClientFormatList(afc->cliprdr, &formatList);
92 static UINT android_cliprdr_send_client_format_data_request(CliprdrClientContext* cliprdr,
95 UINT rc = ERROR_INVALID_PARAMETER;
104 if (!afc || !afc->clipboardRequestEvent || !cliprdr->ClientFormatDataRequest)
107 formatDataRequest.common.msgType = CB_FORMAT_DATA_REQUEST;
108 formatDataRequest.common.msgFlags = 0;
109 formatDataRequest.requestedFormatId = formatId;
110 afc->requestedFormatId = formatId;
111 (void)ResetEvent(afc->clipboardRequestEvent);
112 rc = cliprdr->ClientFormatDataRequest(cliprdr, &formatDataRequest);
117 static UINT android_cliprdr_send_client_capabilities(CliprdrClientContext* cliprdr)
122 if (!cliprdr || !cliprdr->ClientCapabilities)
123 return ERROR_INVALID_PARAMETER;
125 capabilities.cCapabilitiesSets = 1;
127 generalCapabilitySet.capabilitySetType = CB_CAPSTYPE_GENERAL;
128 generalCapabilitySet.capabilitySetLength = 12;
129 generalCapabilitySet.version = CB_CAPS_VERSION_2;
130 generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
131 return cliprdr->ClientCapabilities(cliprdr, &capabilities);
139 static UINT android_cliprdr_monitor_ready(CliprdrClientContext* cliprdr,
145 if (!cliprdr || !monitorReady)
146 return ERROR_INVALID_PARAMETER;
151 return ERROR_INVALID_PARAMETER;
153 if ((rc = android_cliprdr_send_client_capabilities(cliprdr)) != CHANNEL_RC_OK)
156 if ((rc = android_cliprdr_send_client_format_list(cliprdr)) != CHANNEL_RC_OK)
159 afc->clipboardSync = TRUE;
160 return CHANNEL_RC_OK;
168 static UINT android_cliprdr_server_capabilities(CliprdrClientContext* cliprdr,
174 if (!cliprdr || !capabilities)
175 return ERROR_INVALID_PARAMETER;
180 return ERROR_INVALID_PARAMETER;
182 for (UINT32 index = 0; index < capabilities->cCapabilitiesSets; index++)
184 capabilitySet = &(capabilities->capabilitySets[index]);
186 if ((capabilitySet->capabilitySetType == CB_CAPSTYPE_GENERAL) &&
187 (capabilitySet->capabilitySetLength >= CB_CAPSTYPE_GENERAL_LEN))
191 afc->clipboardCapabilities = generalCapabilitySet->generalFlags;
196 return CHANNEL_RC_OK;
204 static UINT android_cliprdr_server_format_list(CliprdrClientContext* cliprdr,
211 if (!cliprdr || !formatList)
212 return ERROR_INVALID_PARAMETER;
217 return ERROR_INVALID_PARAMETER;
219 if (afc->serverFormats)
221 for (UINT32 index = 0; index < afc->numServerFormats; index++)
222 free(afc->serverFormats[index].formatName);
224 free(afc->serverFormats);
225 afc->serverFormats = NULL;
226 afc->numServerFormats = 0;
229 if (formatList->numFormats < 1)
230 return CHANNEL_RC_OK;
232 afc->numServerFormats = formatList->numFormats;
235 if (!afc->serverFormats)
236 return CHANNEL_RC_NO_MEMORY;
238 for (UINT32 index = 0; index < afc->numServerFormats; index++)
240 afc->serverFormats[index].formatId = formatList->formats[index].formatId;
241 afc->serverFormats[index].formatName = NULL;
243 if (formatList->formats[index].formatName)
245 afc->serverFormats[index].formatName = _strdup(formatList->formats[index].formatName);
247 if (!afc->serverFormats[index].formatName)
248 return CHANNEL_RC_NO_MEMORY;
252 for (UINT32 index = 0; index < afc->numServerFormats; index++)
254 format = &(afc->serverFormats[index]);
256 if (format->formatId == CF_UNICODETEXT)
258 if ((rc = android_cliprdr_send_client_format_data_request(cliprdr, CF_UNICODETEXT)) !=
264 else if (format->formatId == CF_TEXT)
266 if ((rc = android_cliprdr_send_client_format_data_request(cliprdr, CF_TEXT)) !=
274 return CHANNEL_RC_OK;
283 android_cliprdr_server_format_list_response(CliprdrClientContext* cliprdr,
286 if (!cliprdr || !formatListResponse)
287 return ERROR_INVALID_PARAMETER;
289 return CHANNEL_RC_OK;
298 android_cliprdr_server_lock_clipboard_data(CliprdrClientContext* cliprdr,
301 if (!cliprdr || !lockClipboardData)
302 return ERROR_INVALID_PARAMETER;
304 return CHANNEL_RC_OK;
312 static UINT android_cliprdr_server_unlock_clipboard_data(
315 if (!cliprdr || !unlockClipboardData)
316 return ERROR_INVALID_PARAMETER;
318 return CHANNEL_RC_OK;
327 android_cliprdr_server_format_data_request(CliprdrClientContext* cliprdr,
337 if (!cliprdr || !formatDataRequest || !cliprdr->ClientFormatDataResponse)
338 return ERROR_INVALID_PARAMETER;
343 return ERROR_INVALID_PARAMETER;
345 formatId = formatDataRequest->requestedFormatId;
346 data = (BYTE*)ClipboardGetData(afc->clipboard, formatId, &size);
347 response.common.msgFlags = CB_RESPONSE_OK;
348 response.common.dataLen = size;
349 response.requestedFormatData = data;
353 response.common.msgFlags = CB_RESPONSE_FAIL;
354 response.common.dataLen = 0;
355 response.requestedFormatData = NULL;
358 rc = cliprdr->ClientFormatDataResponse(cliprdr, &response);
369 android_cliprdr_server_format_data_response(CliprdrClientContext* cliprdr,
379 if (!cliprdr || !formatDataResponse)
380 return ERROR_INVALID_PARAMETER;
385 return ERROR_INVALID_PARAMETER;
387 instance = ((rdpContext*)afc)->instance;
390 return ERROR_INVALID_PARAMETER;
392 for (UINT32 index = 0; index < afc->numServerFormats; index++)
394 if (afc->requestedFormatId == afc->serverFormats[index].formatId)
395 format = &(afc->serverFormats[index]);
400 (void)SetEvent(afc->clipboardRequestEvent);
401 return ERROR_INTERNAL_ERROR;
404 if (format->formatName)
405 formatId = ClipboardRegisterFormat(afc->clipboard, format->formatName);
407 formatId = format->formatId;
409 size = formatDataResponse->common.dataLen;
411 if (!ClipboardSetData(afc->clipboard, formatId, formatDataResponse->requestedFormatData, size))
412 return ERROR_INTERNAL_ERROR;
414 (void)SetEvent(afc->clipboardRequestEvent);
416 if ((formatId == CF_TEXT) || (formatId == CF_UNICODETEXT))
421 formatId = ClipboardRegisterFormat(afc->clipboard,
"text/plain");
422 data = (
void*)ClipboardGetData(afc->clipboard, formatId, &size);
423 attached = jni_attach_thread(&env);
424 size = strnlen(data, size);
425 jdata = jniNewStringUTF(env, data, size);
426 freerdp_callback(
"OnRemoteClipboardChanged",
"(JLjava/lang/String;)V", (jlong)instance,
428 (*env)->DeleteLocalRef(env, jdata);
430 if (attached == JNI_TRUE)
434 return CHANNEL_RC_OK;
442 static UINT android_cliprdr_server_file_contents_request(
445 if (!cliprdr || !fileContentsRequest)
446 return ERROR_INVALID_PARAMETER;
448 return CHANNEL_RC_OK;
456 static UINT android_cliprdr_server_file_contents_response(
459 if (!cliprdr || !fileContentsResponse)
460 return ERROR_INVALID_PARAMETER;
462 return CHANNEL_RC_OK;
465 BOOL android_cliprdr_init(
androidContext* afc, CliprdrClientContext* cliprdr)
467 wClipboard* clipboard;
470 if (!afc || !cliprdr)
473 if (!(hevent = CreateEvent(NULL, TRUE, FALSE, NULL)))
476 if (!(clipboard = ClipboardCreate()))
478 (void)CloseHandle(hevent);
482 afc->cliprdr = cliprdr;
483 afc->clipboard = clipboard;
484 afc->clipboardRequestEvent = hevent;
485 cliprdr->custom = (
void*)afc;
486 cliprdr->MonitorReady = android_cliprdr_monitor_ready;
487 cliprdr->ServerCapabilities = android_cliprdr_server_capabilities;
488 cliprdr->ServerFormatList = android_cliprdr_server_format_list;
489 cliprdr->ServerFormatListResponse = android_cliprdr_server_format_list_response;
490 cliprdr->ServerLockClipboardData = android_cliprdr_server_lock_clipboard_data;
491 cliprdr->ServerUnlockClipboardData = android_cliprdr_server_unlock_clipboard_data;
492 cliprdr->ServerFormatDataRequest = android_cliprdr_server_format_data_request;
493 cliprdr->ServerFormatDataResponse = android_cliprdr_server_format_data_response;
494 cliprdr->ServerFileContentsRequest = android_cliprdr_server_file_contents_request;
495 cliprdr->ServerFileContentsResponse = android_cliprdr_server_file_contents_response;
499 BOOL android_cliprdr_uninit(
androidContext* afc, CliprdrClientContext* cliprdr)
501 if (!afc || !cliprdr)
504 cliprdr->custom = NULL;
506 ClipboardDestroy(afc->clipboard);
507 (void)CloseHandle(afc->clipboardRequestEvent);