darwin-pasteboard.cpp revision 4107f90f7a6b87b4caeba2fa9273651f778edfd0
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync/* $Id$ */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/** @file
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Shared Clipboard: Mac OS X host implementation.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/*
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync * Copyright (C) 2008 Sun Microsystems, Inc.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
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 *
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 */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/stdint.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <Carbon/Carbon.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/mem.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include <iprt/assert.h>
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include "iprt/err.h"
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#define LOG_GROUP LOG_GROUP_HGCM
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include "VBox/log.h"
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include "VBox/HostServices/VBoxClipboardSvc.h"
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync#include "VBox/GuestHost/clipboard-helper.h"
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/* For debugging */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync//#define SHOW_CLIPBOARD_CONTENT
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/**
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Initialize the global pasteboard and return a reference to it.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @param pPasteboardRef Reference to the global pasteboard.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns IPRT status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncint initPasteboard (PasteboardRef *pPasteboardRef)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync{
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync int rc = VINF_SUCCESS;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync if (PasteboardCreate (kPasteboardClipboard, pPasteboardRef))
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync rc = VERR_NOT_SUPPORTED;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync return rc;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync}
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync/**
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * Release the reference to the global pasteboard.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync *
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @param pPasteboardRef Reference to the global pasteboard.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsyncvoid destroyPasteboard (PasteboardRef *pPasteboardRef)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync{
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync CFRelease (*pPasteboardRef);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *pPasteboardRef = NULL;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync}
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync/**
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * Inspect the global pasteboard for new content. Check if there is some type
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * that is supported by vbox and return it.
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync *
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 *
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync * @returns IPRT status code. (Always VINF_SUCCESS atm.)
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsyncint queryNewPasteboardFormats (PasteboardRef pPasteboard, uint32_t *pfFormats, bool *pfChanged)
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync{
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync Log (("queryNewPasteboardFormats\n"));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync OSStatus err = noErr;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *pfChanged = true;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync PasteboardSyncFlags syncFlags;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Make sure all is in sync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync syncFlags = PasteboardSynchronize (pPasteboard);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* If nothing changed return */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (!(syncFlags & kPasteboardModified))
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync {
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync *pfChanged = false;
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync return VINF_SUCCESS;
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync }
bf8889d6b20936475381d2ed2b80b06eaf2a03d1vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Are some items in the pasteboard? */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync ItemCount itemCount;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync if (itemCount < 1)
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync return VINF_SUCCESS;
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync /* The id of the first element in the pasteboard */
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync int rc = VINF_SUCCESS;
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync PasteboardItemID itemID;
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync {
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync /* Retrieve all flavors in the pasteboard, maybe there
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync * is something we can use. */
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync CFArrayRef flavorTypeArray;
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync if (!(err = PasteboardCopyItemFlavors (pPasteboard, itemID, &flavorTypeArray)))
6b07d9a23ed1c650aa0a3b8de9d19f51b6b67e9fvboxsync {
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync CFIndex flavorCount;
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync flavorCount = CFArrayGetCount (flavorTypeArray);
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync for (CFIndex flavorIndex = 0; flavorIndex < flavorCount; flavorIndex++)
07557d07616212d7ba6e7ab3059e85cb14633775vboxsync {
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync CFStringRef flavorType;
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync flavorType = static_cast <CFStringRef> (CFArrayGetValueAtIndex (flavorTypeArray,
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync flavorIndex));
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /* Currently only unicode supported */
e94ff1af89bf631c68367d4e291ddbb491b5e5c0vboxsync if (UTTypeConformsTo (flavorType, CFSTR ("public.utf8-plain-text")) ||
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync UTTypeConformsTo (flavorType, CFSTR ("public.utf16-plain-text")))
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync {
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync Log (("Unicode flavor detected.\n"));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *pfFormats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync }
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync CFRelease (flavorTypeArray);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
529e6bec97f5ef2e005c99c205c9624583ecb7f0vboxsync Log (("queryNewPasteboardFormats: rc = %02X\n", rc));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync return rc;
e94ff1af89bf631c68367d4e291ddbb491b5e5c0vboxsync}
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync/**
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * Read content from the host clipboard and write it to the internal clipboard
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * structure for further processing.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync *
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 *
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync * @returns IPRT status code.
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsyncint readFromPasteboard (PasteboardRef pPasteboard, uint32_t fFormat, void *pv, uint32_t cb, uint32_t *pcbActual)
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync{
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync Log (("readFromPasteboard: fFormat = %02X\n", fFormat));
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync OSStatus err = noErr;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Make sure all is in sync */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync PasteboardSynchronize (pPasteboard);
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync /* Are some items in the pasteboard? */
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync ItemCount itemCount;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync err = PasteboardGetItemCount (pPasteboard, &itemCount);
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync if (itemCount < 1)
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync return VINF_SUCCESS;
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /* The id of the first element in the pasteboard */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync int rc = VERR_NOT_SUPPORTED;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync PasteboardItemID itemID;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (!(err = PasteboardGetItemIdentifier (pPasteboard, 1, &itemID)))
290f895ae2ac655ba90c8904a0e2687d8aa0837dvboxsync {
290f895ae2ac655ba90c8904a0e2687d8aa0837dvboxsync /* The guest request unicode */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync {
290f895ae2ac655ba90c8904a0e2687d8aa0837dvboxsync CFDataRef outData;
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync PRTUTF16 pwszTmp = NULL;
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync /* Try utf-16 first */
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf16-plain-text"), &outData)))
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync {
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync Log (("Clipboard content is utf-16\n"));
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync rc = RTUtf16DupEx (&pwszTmp, (PRTUTF16)CFDataGetBytePtr (outData), 0);
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync }
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync /* Second try is utf-8 */
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync else
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync if (!(err = PasteboardCopyItemFlavorData (pPasteboard, itemID, CFSTR ("public.utf8-plain-text"), &outData)))
e12084fc5287a5fa65e3a28bbeb05af29c22dad7vboxsync {
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync Log (("readFromPasteboard: clipboard content is utf-8\n"));
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync rc = RTStrToUtf16 ((const char*)CFDataGetBytePtr (outData), &pwszTmp);
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync }
290f895ae2ac655ba90c8904a0e2687d8aa0837dvboxsync if (pwszTmp)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Check how much longer will the converted text will be. */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync size_t cwSrc = RTUtf16Len (pwszTmp);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync size_t cwDest;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16GetWinSize (pwszTmp, cwSrc, &cwDest);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (RT_FAILURE (rc))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync RTUtf16Free (pwszTmp);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16GetWinSize returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync AssertRCReturn (rc, rc);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Set the actually needed data size */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync *pcbActual = cwDest * 2;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Return success state */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = VINF_SUCCESS;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Do not copy data if the dst buffer is not big enough. */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (*pcbActual <= cb)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16LinToWin (pwszTmp, RTUtf16Len (pwszTmp), static_cast <PRTUTF16> (pv), cb / 2);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (RT_FAILURE (rc))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync RTUtf16Free (pwszTmp);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16LinToWin() returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync AssertRCReturn (rc, rc);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync#ifdef SHOW_CLIPBOARD_CONTENT
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("readFromPasteboard: clipboard content: %ls\n", static_cast <PRTUTF16> (pv)));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync#endif
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Free the temp string */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync RTUtf16Free (pwszTmp);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("readFromPasteboard: rc = %02X\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync return rc;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync}
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync/**
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * Write clipboard content to the host clipboard from the internal clipboard
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * structure.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync *
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 *
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync * @returns IPRT status code.
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsyncint writeToPasteboard (PasteboardRef pPasteboard, void *pv, uint32_t cb, uint32_t fFormat)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync{
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: fFormat = %02X\n", fFormat));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Clear the pasteboard */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (PasteboardClear (pPasteboard))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync return VERR_NOT_SUPPORTED;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Make sure all is in sync */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync PasteboardSynchronize (pPasteboard);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync int rc = VERR_NOT_SUPPORTED;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Handle the unicode text */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (fFormat & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync PRTUTF16 pwszSrcText = static_cast <PRTUTF16> (pv);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync size_t cwSrc = cb / 2;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync size_t cwDest = 0;
290f895ae2ac655ba90c8904a0e2687d8aa0837dvboxsync /* How long will the converted text be? */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16GetLinSize (pwszSrcText, cwSrc, &cwDest);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (RT_FAILURE (rc))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16GetLinSize returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync AssertRCReturn (rc, rc);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Empty clipboard? Not critical */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (cwDest == 0)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: received empty clipboard data from the guest, returning false.\n"));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync return VINF_SUCCESS;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Allocate the necessary memory */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync PRTUTF16 pwszDestText = static_cast <PRTUTF16> (RTMemAlloc (cwDest * 2));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (pwszDestText == NULL)
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: failed to allocate %d bytes\n", cwDest * 2));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync return VERR_NO_MEMORY;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Convert the EOL */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = vboxClipboardUtf16WinToLin (pwszSrcText, cwSrc, pwszDestText, cwDest);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (RT_FAILURE (rc))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync Log (("writeToPasteboard: clipboard conversion failed. vboxClipboardUtf16WinToLin() returned %Rrc. Abandoning.\n", rc));
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync RTMemFree (pwszDestText);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync AssertRCReturn (rc, rc);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync CFDataRef textData = NULL;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Item id is 1. Nothing special here. */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync PasteboardItemID itemId = (PasteboardItemID)1;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Create a CData object which we could pass to the pasteboard */
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if ((textData = CFDataCreate (kCFAllocatorDefault,
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync reinterpret_cast<UInt8*> (pwszDestText), cwDest * 2)))
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync {
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Put the Utf-16 version to the pasteboard */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync PasteboardPutItemFlavor (pPasteboard, itemId,
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync CFSTR ("public.utf16-plain-text"),
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync textData, 0);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync /* Create a Utf-8 version */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync char *pszDestText;
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync rc = RTUtf16ToUtf8 (pwszDestText, &pszDestText);
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync if (RT_SUCCESS (rc))
ba6cd8af51db6aeff784fd6d73cadaf13ec45996vboxsync {
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync /* Create a CData object which we could pass to the pasteboard */
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync if ((textData = CFDataCreate (kCFAllocatorDefault,
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync reinterpret_cast<UInt8*> (pszDestText), strlen(pszDestText))))
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync {
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync /* Put the Utf-8 version to the pasteboard */
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync PasteboardPutItemFlavor (pPasteboard, itemId,
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync CFSTR ("public.utf8-plain-text"),
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync textData, 0);
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTStrFree (pszDestText);
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync }
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync
930b5f872e89407f445d4000d4e4aaecaa6a0998vboxsync RTMemFree (pwszDestText);
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync rc = VINF_SUCCESS;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync }
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync else
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync rc = VERR_NOT_IMPLEMENTED;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync Log (("writeToPasteboard: rc = %02X\n", rc));
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync return rc;
9a379ef11a4bb232c8e41c12b82ec94c8e10d9a0vboxsync}
1f1f533d5b88c35cf740dca55c6f1937d1035a36vboxsync