darwin-pasteboard.cpp revision 4107f90f7a6b87b4caeba2fa9273651f778edfd0
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Shared Clipboard: Mac OS X host implementation.
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * available from http://www.virtualbox.org. This file is free software;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * you can redistribute it and/or modify it under the terms of the GNU
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * General Public License (GPL) as published by the Free Software
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * additional information or have any questions.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/* For debugging */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//#define SHOW_CLIPBOARD_CONTENT
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Initialize the global pasteboard and return a reference to it.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pPasteboardRef Reference to the global pasteboard.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns IPRT status code.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync if (PasteboardCreate (kPasteboardClipboard, pPasteboardRef))
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * Release the reference to the global pasteboard.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @param pPasteboardRef Reference to the global pasteboard.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncvoid destroyPasteboard (PasteboardRef *pPasteboardRef)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * Inspect the global pasteboard for new content. Check if there is some type
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * that is supported by vbox and return it.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @param pPasteboardRef Reference to the global pasteboard.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @param pfFormats Pointer for the bit combination of the
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * supported types.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pbChanged True if something has changed after the
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * last call.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @returns IPRT status code. (Always VINF_SUCCESS atm.)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsyncint queryNewPasteboardFormats (PasteboardRef pPasteboard, uint32_t *pfFormats, bool *pfChanged)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Make sure all is in sync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* If nothing changed return */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Are some items in the pasteboard? */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync /* The id of the first element in the pasteboard */
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync /* Retrieve all flavors in the pasteboard, maybe there
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * is something we can use. */
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync if (!(err = PasteboardCopyItemFlavors (pPasteboard, itemID, &flavorTypeArray)))
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync flavorType = static_cast <CFStringRef> (CFArrayGetValueAtIndex (flavorTypeArray,
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /* Currently only unicode supported */
e94ff1af89bf631c68367d4e291ddbb491b5e5c0vboxsync if (UTTypeConformsTo (flavorType, CFSTR ("public.utf8-plain-text")) ||
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync UTTypeConformsTo (flavorType, CFSTR ("public.utf16-plain-text")))
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *pfFormats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync Log (("queryNewPasteboardFormats: rc = %02X\n", rc));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Read content from the host clipboard and write it to the internal clipboard
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * structure for further processing.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pPasteboardRef Reference to the global pasteboard.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param fFormats The format type which should be read.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pv The destination buffer.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param cb The size of the destination buffer.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pcbActual The size which is needed to transfer the content.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns IPRT status code.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsyncint readFromPasteboard (PasteboardRef pPasteboard, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcbActual)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync Log (("readFromPasteboard: fFormat = %02X\n", fFormat));
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Make sure all is in sync */
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync /* Are some items in the pasteboard? */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /* The id of the first element in the pasteboard */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
290f895ae2ac655ba90c8904a0e2687d8aa0837dvboxsync /* The guest request unicode */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Try utf-16 first */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf16-plain-text"), &outData)))
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync rc = RTUtf16DupEx (&pwszTmp, (PRTUTF16)CFDataGetBytePtr (outData), 0);
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync /* Second try is utf-8 */
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf8-plain-text"), &outData)))
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync Log (("readFromPasteboard: clipboard content is utf-8\n"));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = RTStrToUtf16 ((const char*)CFDataGetBytePtr (outData), &pwszTmp);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Check how much longer will the converted text will be. */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16GetWinSize (pwszTmp, cwSrc, &cwDest);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16GetWinSize returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Set the actually needed data size */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Return success state */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Do not copy data if the dst buffer is not big enough. */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16LinToWin (pwszTmp, RTUtf16Len (pwszTmp), static_cast <PRTUTF16> (pv), cb / 2);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16LinToWin() returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("readFromPasteboard: clipboard content: %ls\n", static_cast <PRTUTF16> (pv)));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Free the temp string */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * Write clipboard content to the host clipboard from the internal clipboard
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * structure.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * @param pPasteboardRef Reference to the global pasteboard.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * @param pv The source buffer.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * @param cb The size of the source buffer.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * @param fFormats The format type which should be written.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * @returns IPRT status code.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsyncint writeToPasteboard (PasteboardRef pPasteboard, void *pv, uint32_t cb, uint32_t fFormat)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: fFormat = %02X\n", fFormat));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Clear the pasteboard */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Make sure all is in sync */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Handle the unicode text */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync PRTUTF16 pwszSrcText = static_cast <PRTUTF16> (pv);
290f895ae2ac655ba90c8904a0e2687d8aa0837dvboxsync /* How long will the converted text be? */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16GetLinSize (pwszSrcText, cwSrc, &cwDest);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16GetLinSize returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Empty clipboard? Not critical */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: received empty clipboard data from the guest, returning false.\n"));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Allocate the necessary memory */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync PRTUTF16 pwszDestText = static_cast <PRTUTF16> (RTMemAlloc (cwDest * 2));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: failed to allocate %d bytes\n", cwDest * 2));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Convert the EOL */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16WinToLin (pwszSrcText, cwSrc, pwszDestText, cwDest);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16WinToLin() returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Item id is 1. Nothing special here. */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Create a CData object which we could pass to the pasteboard */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync reinterpret_cast<UInt8*> (pwszDestText), cwDest * 2)))
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Put the Utf-16 version to the pasteboard */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Create a Utf-8 version */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Create a CData object which we could pass to the pasteboard */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync reinterpret_cast<UInt8*> (pszDestText), strlen(pszDestText))))
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /* Put the Utf-8 version to the pasteboard */