/**
 * 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;
}
Ejemplo n.º 2
0
/**
 * 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;
}