darwin-pasteboard.cpp revision 32ded45b3caba42c8a2315a20bbfabb513fa54c1
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync/* $Id$ */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync/** @file
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync * Shared Clipboard: Mac OS X host implementation.
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync/*
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * Copyright (C) 2008 innotek GmbH
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync *
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * available from http://www.virtualbox.org. This file is free software;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * you can redistribute it and/or modify it under the terms of the GNU
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * General Public License (GPL) as published by the Free Software
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync/// @todo: same as defined in VBoxClipboardSvc.h
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync/// @todo r-bird: why don't you include it?
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#define VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT 0x01
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#define VBOX_SHARED_CLIPBOARD_FMT_BITMAP 0x02
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#define VBOX_SHARED_CLIPBOARD_FMT_HTML 0x04
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#include <Carbon/Carbon.h>
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#include <iprt/mem.h>
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#include <iprt/assert.h>
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#include "iprt/err.h"
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#define LOG_GROUP LOG_GROUP_HGCM
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#include "VBox/log.h"
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#include "clipboard-helper.h"
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync//#define SHOW_CLIPBOARD_CONTENT
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncint initPasteboard (PasteboardRef *pPasteboardRef)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync{
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync int rc = VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (PasteboardCreate (kPasteboardClipboard, pPasteboardRef))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync rc = VERR_NOT_SUPPORTED;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return rc;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync}
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncvoid destroyPasteboard (PasteboardRef *pPasteboardRef)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync{
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync CFRelease (*pPasteboardRef);
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync *pPasteboardRef = NULL;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync}
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncint queryPasteboardFormats (PasteboardRef pPasteboard, uint32_t pfFormats)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync{
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("queryPasteboardFormats\n"));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync OSStatus err = noErr;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardSyncFlags syncFlags;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Make sure all is in sync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync syncFlags = PasteboardSynchronize (pPasteboard);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* If nothing changed return */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(syncFlags & kPasteboardModified))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Are some items in the pasteboard? */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync ItemCount itemCount;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (itemCount < 1)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* The id of the first element in the pastboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync int rc = VERR_NOT_SUPPORTED;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardItemID itemID;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync /* Retrieve all flavors in the pasteboard, maybe there
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * is something we can use. */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFArrayRef flavorTypeArray;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardCopyItemFlavors (pPasteboard, itemID, &flavorTypeArray)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFIndex flavorCount;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync flavorCount = CFArrayGetCount (flavorTypeArray);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFStringRef flavorType;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync flavorType = static_cast <CFStringRef> (CFArrayGetValueAtIndex (flavorTypeArray,
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync flavorIndex));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Currently only unicode supported */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (UTTypeConformsTo (flavorType, CFSTR ("public.utf8-plain-text")) ||
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync UTTypeConformsTo (flavorType, CFSTR ("public.utf16-plain-text")))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("Unicode flavor detected.\n"));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync *pfFormats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync rc = VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFRelease (flavorTypeArray);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("queryPasteboardFormats: rc = %02X\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return rc;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync}
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncint readFromPasteboard (PasteboardRef pPasteboard, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcbActual)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync{
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync Log (("readFromPastboard: fFormat = %02X\n", fFormat));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync OSStatus err = noErr;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Make sure all is in sync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardSynchronize (pPasteboard);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Are some items in the pasteboard? */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync ItemCount itemCount;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (itemCount < 1)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* The id of the first element in the pastboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync int rc = VERR_NOT_SUPPORTED;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardItemID itemID;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* The guest request unicode */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFDataRef outData;
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync PRTUTF16 pwszTmp = NULL;
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync /* Utf-16 is currently broken on more than one line.
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * Has to be investigated. */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#if 0
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Try utf-16 first */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf16-plain-text"), &outData)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("Clipboard content is utf-16\n"));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = RTUtf16DupEx (&pwszTmp, (PRTUTF16)CFDataGetBytePtr (outData), 0);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Second try is utf-8 */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync else
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync#endif
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf8-plain-text"), &outData)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard content is utf-8\n"));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = RTStrToUtf16 ((const char*)CFDataGetBytePtr (outData), &pwszTmp);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (pwszTmp)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Check how much longer will the converted text will be. */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync size_t cwSrc = RTUtf16Len (pwszTmp);
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync size_t cwDest;
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16GetWinSize (pwszTmp, cwSrc, &cwDest);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (RT_FAILURE (rc))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync RTUtf16Free (pwszTmp);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard conversion failed. vboxClipboardUtf16GetWinSize returned %Vrc. Abandoning.\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync AssertRCReturn (rc, rc);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Set the actually needed data size */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync *pcbActual = cwDest * 2;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Return success state */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync rc = VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Do not copy data if the dst buffer is not big enough. */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (*pcbActual <= cb)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16LinToWin (pwszTmp, RTUtf16Len (pwszTmp), static_cast <PRTUTF16> (pv), cb / 2);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (RT_FAILURE (rc))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync RTUtf16Free (pwszTmp);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard conversion failed. vboxClipboardUtf16LinToWin() returned %Vrc. Abandoning.\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync AssertRCReturn (rc, rc);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#ifdef SHOW_CLIPBOARD_CONTENT
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard content: %ls\n", static_cast <PRTUTF16> (pv)));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync#endif
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Free the temp string */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync RTUtf16Free (pwszTmp);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: rc = %02X\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return rc;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync}
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncint writeToPasteboard (PasteboardRef pPasteboard, void *pv, uint32_t cb, uint32_t fFormat)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync{
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync Log (("writeToPasteboard: fFormat = %02X\n", fFormat));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Clear the pastboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (PasteboardClear (pPasteboard))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return VERR_NOT_SUPPORTED;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Make sure all is in sync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardSynchronize (pPasteboard);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync int rc = VERR_NOT_SUPPORTED;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Handle the unicode text */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync PRTUTF16 pwszSrcText = static_cast <PRTUTF16> (pv);
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync size_t cwSrc = cb / 2;
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync size_t cwDest = 0;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* How long will the converted text be? */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16GetLinSize (pwszSrcText, cwSrc, &cwDest);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (RT_FAILURE (rc))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16GetLinSize returned %Vrc. Abandoning.\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync AssertRCReturn (rc, rc);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Empty clipboard? Not critical */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (cwDest == NULL)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("writeToPasteboard: received empty clipboard data from the guest, returning false.\n"));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Allocate the necessary memory */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync PRTUTF16 pwszDestText = static_cast <PRTUTF16> (RTMemAlloc (cwDest * 2));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (pwszDestText == NULL)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync Log (("writeToPasteboard: failed to allocate %d bytes\n", cwDest * 2));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return VERR_NO_MEMORY;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Convert the EOL */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16WinToLin (pwszSrcText, cwSrc, pwszDestText, cwDest);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (RT_FAILURE (rc))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16WinToLin() returned %Vrc. Abandoning.\n", rc));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync RTMemFree (pwszDestText);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync AssertRCReturn (rc, rc);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFDataRef textData = NULL;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Item id is 1. Nothing special here. */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardItemID itemId = (PasteboardItemID)1;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Create a CData object which we could pass to the pasteboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if ((textData = CFDataCreate (kCFAllocatorDefault,
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync reinterpret_cast<UInt8*> (pwszDestText), cwDest * 2)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Put the Utf-16 version to the pasteboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardPutItemFlavor (pPasteboard, itemId,
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFSTR ("public.utf16-plain-text"),
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync textData, 0);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Create a Utf-8 version */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync char *pszDestText;
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = RTUtf16ToUtf8 (pwszDestText, &pszDestText);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (RT_SUCCESS (rc))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Create a CData object which we could pass to the pasteboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if ((textData = CFDataCreate (kCFAllocatorDefault,
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync reinterpret_cast<UInt8*> (pszDestText), RTUtf16CalcUtf8Len (pwszDestText)))) /** @todo r=bird: why not strlen(pszDestText)? */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync {
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Put the Utf-8 version to the pasteboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync PasteboardPutItemFlavor (pPasteboard, itemId,
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync CFSTR ("public.utf8-plain-text"),
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync textData, 0);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync RTStrFree (pszDestText);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync RTMemFree (pwszDestText);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync rc = VINF_SUCCESS;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync }
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync else
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync rc = VERR_NOT_IMPLEMENTED;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("writeToPasteboard: rc = %02X\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync return rc;
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync}