/** * Paste text data into guest clipboard. * * @param pPasteboard Guest PasteBoard reference. * @param pData Data to be pasted. * @param cbDataSize Size of *pData. */ static int vbclClipboardGuestPasteText(PasteboardRef pPasteboard, void *pData, uint32_t cbDataSize) { size_t cbActualLen; int rc; char *pszUtf8Buf; RTUTF16 *pDataInternal; AssertReturn(pData, VERR_INVALID_PARAMETER); /* Skip zero-sized buffer */ AssertReturn(cbDataSize > 0, VINF_SUCCESS); /* If buffer content is Unicode text, then deliver it in both formats UTF16 (original) and UTF8. */ /* Convert END-OF-LINE */ rc = vboxClipboardUtf16GetLinSize((RTUTF16 *)pData, cbDataSize / 2, &cbActualLen); AssertReturn(RT_SUCCESS(rc), rc); pDataInternal = (RTUTF16 *)RTMemAlloc(cbActualLen * 2); AssertReturn(pDataInternal, VERR_NO_MEMORY); rc = vboxClipboardUtf16WinToLin((RTUTF16 *)pData, cbDataSize / 2, pDataInternal, cbActualLen); /* Do actual paste */ if (RT_SUCCESS(rc)) { /* Paste UTF16 */ rc = vbclClipboardGuestPasteData(pPasteboard, (UInt8 *)pDataInternal, cbActualLen * 2, kUTTypeUTF16PlainText, true); if (RT_SUCCESS(rc)) { /* Paste UTF8 */ rc = RTUtf16ToUtf8((RTUTF16 *)pDataInternal, &pszUtf8Buf); if (RT_SUCCESS(rc)) { rc = vbclClipboardGuestPasteData(pPasteboard, (UInt8 *)pszUtf8Buf, strlen(pszUtf8Buf), kUTTypeUTF8PlainText, false); RTStrFree(pszUtf8Buf); } } } RTMemFree(pDataInternal); return rc; }
/** * Write clipboard content to the host clipboard from the internal clipboard * structure. * * @param pPasteboardRef Reference to the global pasteboard. * @param pv The source buffer. * @param cb The size of the source buffer. * @param fFormats The format type which should be written. * * @returns IPRT status code. */ int writeToPasteboard(PasteboardRef pPasteboard, void *pv, uint32_t cb, uint32_t fFormat) { Log(("writeToPasteboard: fFormat = %02X\n", fFormat)); /* Clear the pasteboard */ if (PasteboardClear(pPasteboard)) return VERR_NOT_SUPPORTED; /* Make sure all is in sync */ PasteboardSynchronize(pPasteboard); int rc = VERR_NOT_SUPPORTED; /* Handle the unicode text */ if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) { PRTUTF16 pwszSrcText = static_cast <PRTUTF16>(pv); size_t cwSrc = cb / 2; size_t cwDest = 0; /* How long will the converted text be? */ rc = vboxClipboardUtf16GetLinSize(pwszSrcText, cwSrc, &cwDest); if (RT_FAILURE(rc)) { Log(("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16GetLinSize returned %Rrc. Abandoning.\n", rc)); AssertRCReturn(rc, rc); } /* Empty clipboard? Not critical */ if (cwDest == 0) { Log(("writeToPasteboard: received empty clipboard data from the guest, returning false.\n")); return VINF_SUCCESS; } /* Allocate the necessary memory */ PRTUTF16 pwszDestText = static_cast <PRTUTF16>(RTMemAlloc(cwDest * 2)); if (pwszDestText == NULL) { Log(("writeToPasteboard: failed to allocate %d bytes\n", cwDest * 2)); return VERR_NO_MEMORY; } /* Convert the EOL */ rc = vboxClipboardUtf16WinToLin(pwszSrcText, cwSrc, pwszDestText, cwDest); if (RT_FAILURE(rc)) { Log(("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16WinToLin() returned %Rrc. Abandoning.\n", rc)); RTMemFree(pwszDestText); AssertRCReturn(rc, rc); } CFDataRef textData = NULL; /* Item id is 1. Nothing special here. */ PasteboardItemID itemId = (PasteboardItemID)1; /* Create a CData object which we could pass to the pasteboard */ if ((textData = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8*>(pwszDestText), cwDest * 2))) { /* Put the Utf-16 version to the pasteboard */ PasteboardPutItemFlavor(pPasteboard, itemId, kUTTypeUTF16PlainText, textData, 0); } /* Create a Utf-8 version */ char *pszDestText; rc = RTUtf16ToUtf8(pwszDestText, &pszDestText); if (RT_SUCCESS(rc)) { /* Create a CData object which we could pass to the pasteboard */ if ((textData = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8*>(pszDestText), strlen(pszDestText)))) { /* Put the Utf-8 version to the pasteboard */ PasteboardPutItemFlavor(pPasteboard, itemId, kUTTypeUTF8PlainText, textData, 0); } RTStrFree(pszDestText); } RTMemFree(pwszDestText); rc = VINF_SUCCESS; } /* Handle the bitmap */ else if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) { /* Create a full BMP from it */ void *pBmp; size_t cbBmpSize; CFDataRef bmpData = NULL; /* Item id is 1. Nothing special here. */ PasteboardItemID itemId = (PasteboardItemID)1; rc = vboxClipboardDibToBmp(pv, cb, &pBmp, &cbBmpSize); if (RT_SUCCESS(rc)) { /* Create a CData object which we could pass to the pasteboard */ if ((bmpData = CFDataCreate(kCFAllocatorDefault, reinterpret_cast<UInt8*>(pBmp), cbBmpSize))) { /* Put the Utf-8 version to the pasteboard */ PasteboardPutItemFlavor(pPasteboard, itemId, kUTTypeBMP, bmpData, 0); } RTMemFree(pBmp); } rc = VINF_SUCCESS; } else rc = VERR_NOT_IMPLEMENTED; Log(("writeToPasteboard: rc = %02X\n", rc)); return rc; }