VirtualBox

source: vbox/trunk/src/VBox/Additions/darwin/VBoxClient/VBoxClientClipboardHostToGuest.cpp@ 72293

Last change on this file since 72293 was 69500, checked in by vboxsync, 7 years ago

*: scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1/** $Id: VBoxClientClipboardHostToGuest.cpp 69500 2017-10-28 15:14:05Z vboxsync $ */
2/** @file
3 * VBoxClient - Shared Clipboard Host -> Guest copying, Darwin.
4 */
5
6/*
7 * Copyright (C) 2007-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <Carbon/Carbon.h>
23#include <signal.h>
24#include <stdlib.h>
25
26#include <iprt/thread.h>
27#include <iprt/mem.h>
28#include <iprt/stream.h>
29#include <iprt/initterm.h>
30#include <iprt/message.h>
31#include <VBox/VBoxGuestLib.h>
32#include <VBox/HostServices/VBoxClipboardSvc.h>
33#include <VBox/GuestHost/clipboard-helper.h>
34#include "VBoxClientInternal.h"
35
36/**
37 * Allocate memory for host buffer and receive it.
38 *
39 * @param u32ClientId Host connection.
40 * @param fFormat Buffer data format.
41 * @param pData Where to store received data.
42 * @param cbDataSize The size of the received data.
43 * @param cbMemSize The actual size of memory occupied by *pData.
44 *
45 * @returns IPRT status code.
46 */
47static int vbclClipboardReadHostData(uint32_t u32ClientId, uint32_t fFormat, void **pData, uint32_t *cbDataSize, uint32_t *cbMemSize)
48{
49 int rc;
50
51 AssertReturn(pData && cbDataSize && cbMemSize, VERR_INVALID_PARAMETER);
52
53 uint32_t cbDataSizeInternal = _4K;
54 uint32_t cbMemSizeInternal = cbDataSizeInternal;
55 void *pDataInternal = RTMemPageAllocZ(cbDataSizeInternal);
56
57 if (!pDataInternal)
58 return VERR_NO_MEMORY;
59
60 rc = VbglR3ClipboardReadData(u32ClientId, fFormat, pDataInternal, cbMemSizeInternal, &cbDataSizeInternal);
61 if (rc == VINF_BUFFER_OVERFLOW)
62 {
63 /* Reallocate bigger buffer and receive all the data */
64 RTMemPageFree(pDataInternal, cbMemSizeInternal);
65 cbDataSizeInternal = cbMemSizeInternal = RT_ALIGN_32(cbDataSizeInternal, PAGE_SIZE);
66 pDataInternal = RTMemPageAllocZ(cbMemSizeInternal);
67 if (!pDataInternal)
68 return VERR_NO_MEMORY;
69
70 rc = VbglR3ClipboardReadData(u32ClientId, fFormat, pDataInternal, cbMemSizeInternal, &cbDataSizeInternal);
71 }
72
73 /* Error occurred of zero-sized buffer */
74 if (RT_FAILURE(rc))
75 {
76 RTMemPageFree(pDataInternal, cbMemSizeInternal);
77 return VERR_NO_MEMORY;
78 }
79
80 *pData = pDataInternal;
81 *cbDataSize = cbDataSizeInternal;
82 *cbMemSize = cbMemSizeInternal;
83
84 return rc;
85}
86
87/**
88 * Release memory occupied by host buffer.
89 *
90 * @param pData Pointer to memory occupied by host buffer.
91 * @param cbMemSize The actual size of memory occupied by *pData.
92 */
93static void vbclClipboardReleaseHostData(void **pData, uint32_t cbMemSize)
94{
95 AssertReturnVoid(pData && cbMemSize > 0);
96 RTMemPageFree(*pData, cbMemSize);
97}
98
99/**
100 * Paste buffer into guest clipboard.
101 *
102 * @param pPasteboard Guest PasteBoard reference.
103 * @param pData Data to be pasted.
104 * @param cbDataSize The size of *pData.
105 * @param fFormat Buffer data format.
106 * @param fClear Whether or not clear guest clipboard before insert data.
107 *
108 * @returns IPRT status code.
109 */
110static int vbclClipboardGuestPasteData(PasteboardRef pPasteboard, UInt8 *pData, CFIndex cbDataSize, CFStringRef sFormat, bool fClear)
111{
112 PasteboardItemID itemId = (PasteboardItemID)1;
113 CFDataRef textData = NULL;
114 OSStatus rc;
115
116 /* Ignoring sunchronization flags here */
117 PasteboardSynchronize(pPasteboard);
118
119 if (fClear)
120 {
121 rc = PasteboardClear(pPasteboard);
122 AssertReturn(rc == noErr, VERR_NOT_SUPPORTED);
123 }
124
125 /* Create a CData object which we could pass to the pasteboard */
126 if ((textData = CFDataCreate(kCFAllocatorDefault, pData, cbDataSize)))
127 {
128 /* Put the Utf-8 version to the pasteboard */
129 rc = PasteboardPutItemFlavor(pPasteboard, itemId, sFormat, textData, 0);
130 CFRelease(textData);
131 if (rc != noErr)
132 {
133 VBoxClientVerbose(3, "unable to put data into guest's clipboard: %d\n", rc);
134 return VERR_GENERAL_FAILURE;
135 }
136 }
137 else
138 return VERR_NO_MEMORY;
139
140 /* Synchronize updated content */
141 PasteboardSynchronize(pPasteboard);
142
143 return VINF_SUCCESS;
144}
145
146/**
147 * Paste text data into guest clipboard.
148 *
149 * @param pPasteboard Guest PasteBoard reference.
150 * @param pData Data to be pasted.
151 * @param cbDataSize Size of *pData.
152 */
153static int vbclClipboardGuestPasteText(PasteboardRef pPasteboard, void *pData, uint32_t cbDataSize)
154{
155 size_t cbActualLen;
156 int rc;
157 char *pszUtf8Buf;
158 RTUTF16 *pDataInternal;
159
160 AssertReturn(pData, VERR_INVALID_PARAMETER);
161
162 /* Skip zero-sized buffer */
163 AssertReturn(cbDataSize > 0, VINF_SUCCESS);
164
165 /* If buffer content is Unicode text, then deliver
166 it in both formats UTF16 (original) and UTF8. */
167
168 /* Convert END-OF-LINE */
169 rc = vboxClipboardUtf16GetLinSize((RTUTF16 *)pData, cbDataSize / 2, &cbActualLen);
170 AssertReturn(RT_SUCCESS(rc), rc);
171 pDataInternal = (RTUTF16 *)RTMemAlloc(cbActualLen * 2);
172 AssertReturn(pDataInternal, VERR_NO_MEMORY);
173 rc = vboxClipboardUtf16WinToLin((RTUTF16 *)pData, cbDataSize / 2, pDataInternal, cbActualLen);
174
175 /* Do actual paste */
176 if (RT_SUCCESS(rc))
177 {
178 /* Paste UTF16 */
179 rc = vbclClipboardGuestPasteData(pPasteboard, (UInt8 *)pDataInternal, cbActualLen * 2, kUTTypeUTF16PlainText, true);
180 if (RT_SUCCESS(rc))
181 {
182 /* Paste UTF8 */
183 rc = RTUtf16ToUtf8((RTUTF16 *)pDataInternal, &pszUtf8Buf);
184 if (RT_SUCCESS(rc))
185 {
186 rc = vbclClipboardGuestPasteData(pPasteboard, (UInt8 *)pszUtf8Buf, strlen(pszUtf8Buf), kUTTypeUTF8PlainText, false);
187 RTStrFree(pszUtf8Buf);
188 }
189 }
190
191 }
192
193 RTMemFree(pDataInternal);
194
195 return rc;
196}
197
198/**
199 * Paste picture data into guest clipboard.
200 *
201 * @param pPasteboard Guest PasteBoard reference.
202 * @param pData Data to be pasted.
203 * @param cbDataSize The size of *pData.
204 *
205 * @returns IPRT status code.
206 */
207static int vbclClipboardGuestPastePicture(PasteboardRef pPasteboard, void *pData, uint32_t cbDataSize)
208{
209 int rc;
210 void *pBmp;
211 size_t cbBmpSize;
212
213 AssertReturn(pData, VERR_INVALID_PARAMETER);
214 /* Skip zero-sized buffer */
215 AssertReturn(cbDataSize > 0, VINF_SUCCESS);
216
217 rc = vboxClipboardDibToBmp(pData, cbDataSize, &pBmp, &cbBmpSize);
218 AssertReturn(RT_SUCCESS(rc), rc);
219
220 rc = vbclClipboardGuestPasteData(pPasteboard, (UInt8 *)pBmp, cbBmpSize, kUTTypeBMP, true);
221 RTMemFree(pBmp);
222
223 return rc;
224}
225
226/**
227 * Read host's clipboard buffer and put its content to guest clipboard.
228 *
229 * @param u32ClientId Host connection.
230 * @param pPasteboard Guest PasteBoard reference.
231 * @param fFormats List of data formats (bit field) received from host.
232 *
233 * @returns IPRT status code.
234 */
235int vbclClipboardForwardToGuest(uint32_t u32ClientId, PasteboardRef pPasteboard, uint32_t fFormats)
236{
237 int rc = VERR_INVALID_PARAMETER;
238 void *pData;
239 uint32_t cbDataSize, cbMemSize;
240 uint32_t fFormatsInternal = fFormats;
241
242 /* Walk across all item(s) formats */
243 while (fFormatsInternal)
244 {
245 if (fFormatsInternal & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
246 {
247 VBoxClientVerbose(3, "found VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT: %d\n", fFormatsInternal);
248
249 rc = vbclClipboardReadHostData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pData, &cbDataSize, &cbMemSize);
250 if (RT_SUCCESS(rc))
251 {
252 /* Store data in guest buffer */
253 rc = vbclClipboardGuestPasteText(pPasteboard, pData, cbDataSize);
254
255 /* Release occupied resources */
256 vbclClipboardReleaseHostData(&pData, cbMemSize);
257 }
258
259 fFormatsInternal &= ~((uint32_t)VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
260 }
261
262 else if (fFormatsInternal & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
263 {
264 VBoxClientVerbose(3, "found VBOX_SHARED_CLIPBOARD_FMT_BITMAP: %d\n", fFormatsInternal);
265
266 rc = vbclClipboardReadHostData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, &pData, &cbDataSize, &cbMemSize);
267 if (RT_SUCCESS(rc))
268 {
269 /* Store data in guest buffer */
270 rc = vbclClipboardGuestPastePicture(pPasteboard, pData, cbDataSize);
271
272 /* Release occupied resources */
273 vbclClipboardReleaseHostData(&pData, cbMemSize);
274 }
275
276 fFormatsInternal &= ~((uint32_t)VBOX_SHARED_CLIPBOARD_FMT_BITMAP);
277 }
278
279 else if (fFormatsInternal & VBOX_SHARED_CLIPBOARD_FMT_HTML)
280 {
281 VBoxClientVerbose(3, "found VBOX_SHARED_CLIPBOARD_FMT_HTML: %d\n", fFormatsInternal);
282
283 rc = vbclClipboardReadHostData(u32ClientId, VBOX_SHARED_CLIPBOARD_FMT_HTML, &pData, &cbDataSize, &cbMemSize);
284 if (RT_SUCCESS(rc))
285 {
286 /* Store data in guest buffer */
287 rc = vbclClipboardGuestPasteData(pPasteboard, (UInt8 *)pData, cbDataSize, kUTTypeHTML, true);
288
289 /* Release occupied resources */
290 vbclClipboardReleaseHostData(&pData, cbMemSize);
291 }
292
293 fFormatsInternal &= ~((uint32_t)VBOX_SHARED_CLIPBOARD_FMT_HTML);
294 }
295
296 else
297 {
298 VBoxClientVerbose(3, "received data in unsupported format: %d\n", fFormats);
299 break;
300 }
301 }
302
303 return rc;
304}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette