darwin-pasteboard.cpp revision 32ded45b3caba42c8a2315a20bbfabb513fa54c1
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync * Shared Clipboard: Mac OS X host implementation.
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * Copyright (C) 2008 innotek GmbH
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.
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync/// @todo: same as defined in VBoxClipboardSvc.h
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync/// @todo r-bird: why don't you include it?
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync//#define SHOW_CLIPBOARD_CONTENT
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (PasteboardCreate (kPasteboardClipboard, pPasteboardRef))
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncvoid destroyPasteboard (PasteboardRef *pPasteboardRef)
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncint queryPasteboardFormats (PasteboardRef pPasteboard, uint32_t pfFormats)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Make sure all is in sync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* If nothing changed return */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Are some items in the pasteboard? */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* The id of the first element in the pastboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync /* Retrieve all flavors in the pasteboard, maybe there
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * is something we can use. */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardCopyItemFlavors (pPasteboard, itemID, &flavorTypeArray)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync flavorType = static_cast <CFStringRef> (CFArrayGetValueAtIndex (flavorTypeArray,
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Currently only unicode supported */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (UTTypeConformsTo (flavorType, CFSTR ("public.utf8-plain-text")) ||
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync UTTypeConformsTo (flavorType, CFSTR ("public.utf16-plain-text")))
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync *pfFormats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncint readFromPasteboard (PasteboardRef pPasteboard, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcbActual)
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync Log (("readFromPastboard: fFormat = %02X\n", fFormat));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Make sure all is in sync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Are some items in the pasteboard? */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* The id of the first element in the pastboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* The guest request unicode */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync /* Utf-16 is currently broken on more than one line.
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync * Has to be investigated. */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Try utf-16 first */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf16-plain-text"), &outData)))
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = RTUtf16DupEx (&pwszTmp, (PRTUTF16)CFDataGetBytePtr (outData), 0);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Second try is utf-8 */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf8-plain-text"), &outData)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard content is utf-8\n"));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = RTStrToUtf16 ((const char*)CFDataGetBytePtr (outData), &pwszTmp);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Check how much longer will the converted text will be. */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16GetWinSize (pwszTmp, cwSrc, &cwDest);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard conversion failed. vboxClipboardUtf16GetWinSize returned %Vrc. Abandoning.\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Set the actually needed data size */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Return success state */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Do not copy data if the dst buffer is not big enough. */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16LinToWin (pwszTmp, RTUtf16Len (pwszTmp), static_cast <PRTUTF16> (pv), cb / 2);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard conversion failed. vboxClipboardUtf16LinToWin() returned %Vrc. Abandoning.\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("readFromPastboard: clipboard content: %ls\n", static_cast <PRTUTF16> (pv)));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Free the temp string */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsyncint writeToPasteboard (PasteboardRef pPasteboard, void *pv, uint32_t cb, uint32_t fFormat)
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync Log (("writeToPasteboard: fFormat = %02X\n", fFormat));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Clear the pastboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Make sure all is in sync */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Handle the unicode text */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync PRTUTF16 pwszSrcText = static_cast <PRTUTF16> (pv);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* How long will the converted text be? */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16GetLinSize (pwszSrcText, cwSrc, &cwDest);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16GetLinSize returned %Vrc. Abandoning.\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Empty clipboard? Not critical */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("writeToPasteboard: received empty clipboard data from the guest, returning false.\n"));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Allocate the necessary memory */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync PRTUTF16 pwszDestText = static_cast <PRTUTF16> (RTMemAlloc (cwDest * 2));
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync Log (("writeToPasteboard: failed to allocate %d bytes\n", cwDest * 2));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Convert the EOL */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync rc = vboxClipboardUtf16WinToLin (pwszSrcText, cwSrc, pwszDestText, cwDest);
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16WinToLin() returned %Vrc. Abandoning.\n", rc));
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Item id is 1. Nothing special here. */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Create a CData object which we could pass to the pasteboard */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync reinterpret_cast<UInt8*> (pwszDestText), cwDest * 2)))
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Put the Utf-16 version to the pasteboard */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Create a Utf-8 version */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Create a CData object which we could pass to the pasteboard */
32ded45b3caba42c8a2315a20bbfabb513fa54c1vboxsync reinterpret_cast<UInt8*> (pszDestText), RTUtf16CalcUtf8Len (pwszDestText)))) /** @todo r=bird: why not strlen(pszDestText)? */
dc23707aec4dc2ce2c6b6f51af21eef72bb8bf2evboxsync /* Put the Utf-8 version to the pasteboard */