int android_cliprdr_send_client_format_list(CliprdrClientContext* cliprdr) { UINT32 index; UINT32 formatId; UINT32 numFormats; UINT32* pFormatIds; const char* formatName; CLIPRDR_FORMAT* formats; CLIPRDR_FORMAT_LIST formatList; androidContext* afc = (androidContext*) cliprdr->custom; ZeroMemory(&formatList, sizeof(CLIPRDR_FORMAT_LIST)); pFormatIds = NULL; numFormats = ClipboardGetFormatIds(afc->clipboard, &pFormatIds); formats = (CLIPRDR_FORMAT*) calloc(numFormats, sizeof(CLIPRDR_FORMAT)); if (!formats) return -1; for (index = 0; index < numFormats; index++) { formatId = pFormatIds[index]; formatName = ClipboardGetFormatName(afc->clipboard, formatId); formats[index].formatId = formatId; formats[index].formatName = NULL; if ((formatId > CF_MAX) && formatName) formats[index].formatName = _strdup(formatName); } formatList.msgFlags = CB_RESPONSE_OK; formatList.numFormats = numFormats; formatList.formats = formats; afc->cliprdr->ClientFormatList(afc->cliprdr, &formatList); free(pFormatIds); free(formats); return 1; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ static UINT xf_cliprdr_server_format_data_response(CliprdrClientContext* context, CLIPRDR_FORMAT_DATA_RESPONSE* formatDataResponse) { BOOL bSuccess; BYTE* pDstData; UINT32 DstSize; UINT32 SrcSize; UINT32 srcFormatId; UINT32 dstFormatId; BOOL nullTerminated = FALSE; UINT32 size = formatDataResponse->dataLen; BYTE* data = formatDataResponse->requestedFormatData; xfClipboard* clipboard = (xfClipboard*) context->custom; xfContext* xfc = clipboard->xfc; if (!clipboard->respond) return CHANNEL_RC_OK; xf_cliprdr_clear_cached_data(clipboard); pDstData = NULL; DstSize = 0; srcFormatId = 0; dstFormatId = 0; if (clipboard->data_raw_format) { srcFormatId = CF_RAW; dstFormatId = CF_RAW; } else if (clipboard->data_format_name) { if (strcmp(clipboard->data_format_name, "HTML Format") == 0) { srcFormatId = ClipboardGetFormatId(clipboard->system, "HTML Format"); dstFormatId = ClipboardGetFormatId(clipboard->system, "text/html"); nullTerminated = TRUE; } } else { switch (clipboard->data_format_id) { case CF_TEXT: srcFormatId = CF_TEXT; dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_OEMTEXT: srcFormatId = CF_OEMTEXT; dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_UNICODETEXT: srcFormatId = CF_UNICODETEXT; dstFormatId = ClipboardGetFormatId(clipboard->system, "UTF8_STRING"); nullTerminated = TRUE; break; case CF_DIB: srcFormatId = CF_DIB; dstFormatId = ClipboardGetFormatId(clipboard->system, "image/bmp"); break; } } SrcSize = (UINT32) size; bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize); if (bSuccess) { DstSize = 0; pDstData = (BYTE*) ClipboardGetData(clipboard->system, dstFormatId, &DstSize); if (!pDstData) { WLog_ERR(TAG, "failed to get clipboard data in format %s [source format %s]", ClipboardGetFormatName(clipboard, dstFormatId), ClipboardGetFormatName(clipboard, srcFormatId)); return ERROR_INTERNAL_ERROR; } if (nullTerminated) { while (DstSize > 0 && pDstData[DstSize - 1] == '\0') DstSize--; } } /* Cache converted and original data to avoid doing a possibly costly * conversion again on subsequent requests */ clipboard->data = pDstData; clipboard->data_length = DstSize; /* We have to copy the original data again, as pSrcData is now owned * by clipboard->system. Memory allocation failure is not fatal here * as this is only a cached value. */ clipboard->data_raw = (BYTE*) malloc(size); if (clipboard->data_raw) { CopyMemory(clipboard->data_raw, data, size); clipboard->data_raw_length = size; } else { WLog_WARN(TAG, "failed to allocate %"PRIu32" bytes for a copy of raw clipboard data", size); } xf_cliprdr_provide_data(clipboard, clipboard->respond, pDstData, DstSize); XSendEvent(xfc->display, clipboard->respond->xselection.requestor, 0, 0, clipboard->respond); XFlush(xfc->display); free(clipboard->respond); clipboard->respond = NULL; return CHANNEL_RC_OK; }