22#include <freerdp/config.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"
36UINT 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);
92static 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);
117static 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);
139static 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;
168static 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;
204static 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;
283android_cliprdr_server_format_list_response(CliprdrClientContext* cliprdr,
286 if (!cliprdr || !formatListResponse)
287 return ERROR_INVALID_PARAMETER;
289 return CHANNEL_RC_OK;
298android_cliprdr_server_lock_clipboard_data(CliprdrClientContext* cliprdr,
301 if (!cliprdr || !lockClipboardData)
302 return ERROR_INVALID_PARAMETER;
304 return CHANNEL_RC_OK;
312static UINT android_cliprdr_server_unlock_clipboard_data(
315 if (!cliprdr || !unlockClipboardData)
316 return ERROR_INVALID_PARAMETER;
318 return CHANNEL_RC_OK;
327android_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);
369android_cliprdr_server_format_data_response(CliprdrClientContext* cliprdr,
374 if (!cliprdr || !formatDataResponse)
375 return ERROR_INVALID_PARAMETER;
380 return ERROR_INVALID_PARAMETER;
382 freerdp* instance = ((rdpContext*)afc)->instance;
385 return ERROR_INVALID_PARAMETER;
387 for (UINT32 index = 0; index < afc->numServerFormats; index++)
389 if (afc->requestedFormatId == afc->serverFormats[index].formatId)
390 format = &(afc->serverFormats[index]);
395 (void)SetEvent(afc->clipboardRequestEvent);
396 return ERROR_INTERNAL_ERROR;
399 UINT32 formatId = format->formatId;
400 if (format->formatName)
401 formatId = ClipboardRegisterFormat(afc->clipboard, format->formatName);
403 uint32_t size = formatDataResponse->common.dataLen;
405 if (!ClipboardSetData(afc->clipboard, formatId, formatDataResponse->requestedFormatData, size))
406 return ERROR_INTERNAL_ERROR;
408 (void)SetEvent(afc->clipboardRequestEvent);
410 if ((formatId == CF_TEXT) || (formatId == CF_UNICODETEXT))
413 formatId = ClipboardRegisterFormat(afc->clipboard,
"text/plain");
414 char* data = (
char*)ClipboardGetData(afc->clipboard, formatId, &size);
415 jboolean attached = jni_attach_thread(&env);
416 size = strnlen(data, size);
417 jstring jdata = jniNewStringUTF(env, data, size);
418 freerdp_callback(
"OnRemoteClipboardChanged",
"(JLjava/lang/String;)V", (jlong)instance,
420 (*env)->DeleteLocalRef(env, jdata);
422 if (attached == JNI_TRUE)
426 return CHANNEL_RC_OK;
434static UINT android_cliprdr_server_file_contents_request(
437 if (!cliprdr || !fileContentsRequest)
438 return ERROR_INVALID_PARAMETER;
440 return CHANNEL_RC_OK;
448static UINT android_cliprdr_server_file_contents_response(
451 if (!cliprdr || !fileContentsResponse)
452 return ERROR_INVALID_PARAMETER;
454 return CHANNEL_RC_OK;
457BOOL android_cliprdr_init(
androidContext* afc, CliprdrClientContext* cliprdr)
459 wClipboard* clipboard;
462 if (!afc || !cliprdr)
465 if (!(hevent = CreateEvent(NULL, TRUE, FALSE, NULL)))
468 if (!(clipboard = ClipboardCreate()))
470 (void)CloseHandle(hevent);
474 afc->cliprdr = cliprdr;
475 afc->clipboard = clipboard;
476 afc->clipboardRequestEvent = hevent;
477 cliprdr->custom = (
void*)afc;
478 cliprdr->MonitorReady = android_cliprdr_monitor_ready;
479 cliprdr->ServerCapabilities = android_cliprdr_server_capabilities;
480 cliprdr->ServerFormatList = android_cliprdr_server_format_list;
481 cliprdr->ServerFormatListResponse = android_cliprdr_server_format_list_response;
482 cliprdr->ServerLockClipboardData = android_cliprdr_server_lock_clipboard_data;
483 cliprdr->ServerUnlockClipboardData = android_cliprdr_server_unlock_clipboard_data;
484 cliprdr->ServerFormatDataRequest = android_cliprdr_server_format_data_request;
485 cliprdr->ServerFormatDataResponse = android_cliprdr_server_format_data_response;
486 cliprdr->ServerFileContentsRequest = android_cliprdr_server_file_contents_request;
487 cliprdr->ServerFileContentsResponse = android_cliprdr_server_file_contents_response;
491BOOL android_cliprdr_uninit(
androidContext* afc, CliprdrClientContext* cliprdr)
493 if (!afc || !cliprdr)
496 cliprdr->custom = NULL;
498 ClipboardDestroy(afc->clipboard);
499 (void)CloseHandle(afc->clipboardRequestEvent);