Changeset 83633 in vbox for trunk/src/VBox/HostServices/SharedClipboard
- Timestamp:
- Apr 9, 2020 12:16:43 AM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/darwin-pasteboard.cpp
r83632 r83633 30 30 #include <iprt/utf16.h> 31 31 32 #include "VBox/log.h"33 #include "VBox/HostServices/VBoxClipboardSvc.h"34 #include "VBox/GuestHost/SharedClipboard.h"35 #include "VBox/GuestHost/clipboard-helper.h"32 #include <VBox/log.h> 33 #include <VBox/HostServices/VBoxClipboardSvc.h> 34 #include <VBox/GuestHost/SharedClipboard.h> 35 #include <VBox/GuestHost/clipboard-helper.h> 36 36 37 37 … … 39 39 * Defined Constants And Macros * 40 40 *********************************************************************************************************************************/ 41 /*#define WITH_HTML_H2G*/ 42 41 43 /* For debugging */ 42 44 //#define SHOW_CLIPBOARD_CONTENT … … 153 155 *pfFormats |= VBOX_SHCL_FMT_UNICODETEXT; 154 156 } 157 #ifdef WITH_HTML_H2G 158 else if (UTTypeConformsTo(hStrFlavor, kUTTypeHTML)) 159 { 160 Log(("queryNewPasteboardFormats: HTML flavor detected.\n")); 161 *pfFormats |= VBOX_SHCL_FMT_HTML; 162 } 163 #endif 155 164 #ifdef LOG_ENABLED 156 165 else if (LogIs2Enabled()) … … 200 209 Log(("readFromPasteboard: fFormat = %02X\n", fFormat)); 201 210 202 OSStatus err = noErr;203 204 211 /* Make sure all is in sync */ 205 212 PasteboardSynchronize(pPasteboard); 206 213 207 214 /* Are some items in the pasteboard? */ 208 ItemCount itemCount;209 err = PasteboardGetItemCount(pPasteboard, &itemCount);210 if ( itemCount< 1)215 ItemCount cItems; 216 OSStatus orc = PasteboardGetItemCount(pPasteboard, &cItems); 217 if (cItems < 1) 211 218 return VINF_SUCCESS; 212 219 213 /* The id of the first element in the pasteboard */ 220 /* 221 * Our default response... 222 */ 214 223 int rc = VERR_NOT_SUPPORTED; 215 PasteboardItemID itemID; 216 if (!(err = PasteboardGetItemIdentifier(pPasteboard, 1, &itemID))) 217 { 218 /* The guest request unicode */ 224 225 /* 226 * The id of the first element in the pasteboard 227 */ 228 PasteboardItemID idItem; 229 orc = PasteboardGetItemIdentifier(pPasteboard, 1, &idItem); 230 if (orc == 0) 231 { 232 CFDataRef hDataCopy = 0; 233 size_t cbDataCopy = 0; 234 235 /* 236 * The guest request unicode 237 */ 219 238 if (fFormat & VBOX_SHCL_FMT_UNICODETEXT) 220 239 { 221 CFDataRef outData; 222 PRTUTF16 pwszTmp = NULL; 223 /* Try utf-16 first */ 224 if (!(err = PasteboardCopyItemFlavorData(pPasteboard, itemID, kUTTypeUTF16PlainText, &outData))) 225 { 226 Log(("Clipboard content is utf-16\n")); 227 228 PRTUTF16 pwszString = (PRTUTF16)CFDataGetBytePtr(outData); 229 if (pwszString) 230 rc = RTUtf16DupEx(&pwszTmp, pwszString, 0); 231 else 232 rc = VERR_INVALID_PARAMETER; 233 } 234 /* Second try is utf-8 */ 240 PRTUTF16 pwszSrcFree = NULL; 241 PCRTUTF16 pwszSrc = NULL; 242 size_t cwcSrc = 0; 243 244 /* First preference is plain UTF-16 text: */ 245 orc = PasteboardCopyItemFlavorData(pPasteboard, idItem, kUTTypeUTF16PlainText, &hDataCopy); 246 if (orc == 0) 247 { 248 cbDataCopy = CFDataGetLength(hDataCopy); 249 Log(("Clipboard content is utf-16 (%zu bytes)\n", cbDataCopy)); 250 pwszSrc = (PCRTUTF16)CFDataGetBytePtr(hDataCopy); 251 if (pwszSrc) 252 { 253 cwcSrc = RTUtf16NLen(pwszSrc, cbDataCopy / sizeof(RTUTF16)); 254 if (cwcSrc >= cbDataCopy / sizeof(RTUTF16)) 255 { 256 pwszSrcFree = RTUtf16Alloc((cwcSrc + 1) * sizeof(RTUTF16)); 257 if (pwszSrcFree) 258 { 259 memcpy(pwszSrcFree, pwszSrc, cwcSrc * sizeof(RTUTF16)); 260 pwszSrcFree[cwcSrc] = '\0'; 261 pwszSrc = pwszSrcFree; 262 } 263 else 264 { 265 rc = VERR_NO_UTF16_MEMORY; 266 pwszSrc = NULL; 267 } 268 } 269 } 270 else 271 rc = VERR_GENERAL_FAILURE; 272 } 273 /* Second preference is plain UTF-8 text: */ 235 274 else 236 if (!(err = PasteboardCopyItemFlavorData(pPasteboard, itemID, kUTTypeUTF8PlainText, &outData))) 237 { 238 Log(("readFromPasteboard: clipboard content is utf-8\n")); 239 const char *pszString = (const char *)CFDataGetBytePtr(outData); 240 if (pszString) 241 rc = RTStrToUtf16(pszString, &pwszTmp); 275 { 276 orc = PasteboardCopyItemFlavorData(pPasteboard, idItem, kUTTypeUTF8PlainText, &hDataCopy); 277 if (orc == 0) 278 { 279 cbDataCopy = CFDataGetLength(hDataCopy); 280 Log(("readFromPasteboard: clipboard content is utf-8 (%zu bytes)\n", cbDataCopy)); 281 const char *pszSrc = (const char *)CFDataGetBytePtr(hDataCopy); 282 if (pszSrc) 283 { 284 size_t cchSrc = RTStrNLen(pszSrc, cbDataCopy); 285 rc = RTStrToUtf16Ex(pszSrc, cchSrc, &pwszSrcFree, 0, &cwcSrc); 286 if (RT_SUCCESS(rc)) 287 pwszSrc = pwszSrcFree; 288 } 242 289 else 243 rc = VERR_INVALID_PARAMETER; 244 } 245 if (pwszTmp) 246 { 247 /* Check how much longer will the converted text will be. */ 248 size_t cwSrc = RTUtf16Len(pwszTmp); 249 size_t cwDest; 250 rc = ShClUtf16GetWinSize(pwszTmp, cwSrc, &cwDest); 251 if (RT_FAILURE(rc)) 252 { 253 RTUtf16Free(pwszTmp); 254 Log(("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16GetWinSize returned %Rrc. Abandoning.\n", rc)); 255 AssertRCReturn(rc, rc); 256 } 257 /* Set the actually needed data size */ 258 *pcbActual = cwDest * 2; 259 /* Return success state */ 260 rc = VINF_SUCCESS; 261 /* Do not copy data if the dst buffer is not big enough. */ 262 if (*pcbActual <= cb) 263 { 264 rc = ShClUtf16LinToWin(pwszTmp, RTUtf16Len(pwszTmp), static_cast <PRTUTF16>(pv), cb / 2); 265 if (RT_FAILURE(rc)) 266 { 267 RTUtf16Free(pwszTmp); 268 Log(("readFromPasteboard: clipboard conversion failed. vboxClipboardUtf16LinToWin() returned %Rrc. Abandoning.\n", rc)); 269 AssertRCReturn(rc, rc); 270 } 290 rc = VERR_GENERAL_FAILURE; 291 } 292 } 293 if (pwszSrc) 294 { 295 /* 296 * Convert to windows UTF-16. 297 */ 298 Assert(cwcSrc == RTUtf16Len(pwszSrc)); 299 size_t cwcDst = 0; 300 rc = ShClUtf16GetWinSize(pwszSrc, cwcSrc, &cwcDst); 301 if (RT_SUCCESS(rc)) 302 { 303 *pcbActual = cwcDst * sizeof(RTUTF16); 304 if (*pcbActual <= cb) 305 { 306 rc = ShClUtf16LinToWin(pwszSrc, cwcSrc, (PRTUTF16)pv, cb / sizeof(RTUTF16)); 307 if (RT_SUCCESS(rc)) 308 { 271 309 #ifdef SHOW_CLIPBOARD_CONTENT 272 Log(("readFromPasteboard: clipboard content: %ls\n", static_cast <PRTUTF16>(pv)));310 Log(("readFromPasteboard: clipboard content: %ls\n", (PCRTUTF16)pv)); 273 311 #endif 274 } 275 /* Free the temp string */ 276 RTUtf16Free(pwszTmp); 277 } 278 } 279 /* The guest request BITMAP */ 312 } 313 else 314 { 315 Log(("readFromPasteboard: ShClUtf16LinToWin failed - %Rrc!\n", rc)); 316 AssertRC(rc); 317 } 318 } 319 else 320 { 321 Log(("readFromPasteboard: Insufficient (text) buffer space: %#zx, need %#zx\n", cb, *pcbActual)); 322 rc = VINF_SUCCESS; 323 } 324 } 325 else 326 { 327 Log(("readFromPasteboard: ShClUtf16GetWinSize failed - %Rrc!\n", rc)); 328 AssertRC(rc); 329 } 330 RTUtf16Free(pwszSrcFree); 331 } 332 } 333 /* 334 * The guest request BITMAP 335 */ 280 336 else if (fFormat & VBOX_SHCL_FMT_BITMAP) 281 337 { 282 CFDataRef outData; 283 const void *pTmp = NULL; 284 size_t cbTmpSize; 285 /* Get the data from the pasteboard */ 286 if (!(err = PasteboardCopyItemFlavorData(pPasteboard, itemID, kUTTypeBMP, &outData))) 287 { 288 Log(("Clipboard content is BMP\n")); 289 pTmp = CFDataGetBytePtr(outData); 290 cbTmpSize = CFDataGetLength(outData); 291 } 292 if (pTmp) 293 { 294 const void *pDib; 295 size_t cbDibSize; 296 rc = ShClBmpGetDib(pTmp, cbTmpSize, &pDib, &cbDibSize); 297 if (RT_FAILURE(rc)) 298 { 299 rc = VERR_NOT_SUPPORTED; 300 Log(("readFromPasteboard: unknown bitmap format. vboxClipboardBmpGetDib returned %Rrc. Abandoning.\n", rc)); 301 AssertRCReturn(rc, rc); 302 } 303 304 *pcbActual = cbDibSize; 305 /* Return success state */ 306 rc = VINF_SUCCESS; 307 /* Do not copy data if the dst buffer is not big enough. */ 308 if (*pcbActual <= cb) 309 { 310 memcpy(pv, pDib, cbDibSize); 338 /* Get the BMP data from the pasteboard */ 339 orc = PasteboardCopyItemFlavorData(pPasteboard, idItem, kUTTypeBMP, &hDataCopy); 340 if (orc == 0) 341 { 342 cbDataCopy = CFDataGetLength(hDataCopy); 343 Log(("Clipboard content is BMP (%zu bytes)\n", cbDataCopy)); 344 const void *pvSrc = CFDataGetBytePtr(hDataCopy); 345 if (pvSrc) 346 { 347 /* 348 * Try get the device independent bitmap (DIB) bit from it. 349 */ 350 const void *pvDib; 351 size_t cbDib; 352 rc = ShClBmpGetDib(pvSrc, cbDataCopy, &pvDib, &cbDib); 353 if (RT_SUCCESS(rc)) 354 { 355 *pcbActual = cbDib; 356 if (*pcbActual <= cb) 357 { 358 memcpy(pv, pvDib, cbDib); 311 359 #ifdef SHOW_CLIPBOARD_CONTENT 312 Log(("readFromPasteboard: clipboard content bitmap %d bytes\n", cbDibSize));360 Log(("readFromPasteboard: clipboard content bitmap %zx bytes\n", cbDib)); 313 361 #endif 314 } 315 } 316 } 317 } 318 319 Log(("readFromPasteboard: rc = %02X\n", rc)); 362 } 363 else 364 Log(("readFromPasteboard: Insufficient (bitmap) buffer space: %#zx, need %#zx\n", cb, cbDib)); 365 rc = VINF_SUCCESS; 366 } 367 else 368 { 369 AssertRC(rc); 370 Log(("readFromPasteboard: ShClBmpGetDib failed - %Rrc - unknown bitmap format??\n", rc)); 371 rc = VERR_NOT_SUPPORTED; 372 } 373 } 374 else 375 rc = VERR_GENERAL_FAILURE; 376 } 377 else 378 LogFlow(("readFromPasteboard: PasteboardCopyItemFlavorData/kUTTypeBMP -> %d (%#x)\n", orc, orc)); 379 } 380 #ifdef WITH_HTML_H2G 381 /* 382 * The guest request HTML. It expects a UTF-8 reply and we assume 383 * that's what's on the pasteboard too. 384 */ 385 else if (fFormat & VBOX_SHCL_FMT_HTML) 386 { 387 orc = PasteboardCopyItemFlavorData(pPasteboard, idItem, kUTTypeHTML, &hDataCopy); 388 if (orc == 0) 389 { 390 cbDataCopy = CFDataGetLength(hDataCopy); 391 Log(("Clipboard content is HTML (%zu bytes):\n", cbDataCopy)); 392 const char *pszSrc = (const char *)CFDataGetBytePtr(hDataCopy); 393 if (pszSrc) 394 { 395 Log3(("%.*Rhxd\n", cbDataCopy, pszSrc)); 396 rc = RTStrValidateEncodingEx(pszSrc, cbDataCopy, 0 /*fFlags*/); 397 if (RT_SUCCESS(rc)) 398 { 399 size_t cchSrc = RTStrNLen(pszSrc, cbDataCopy); 400 *pcbActual = cchSrc; 401 if (cchSrc <= cb) 402 memcpy(pv, pszSrc, cchSrc); 403 else 404 Log(("readFromPasteboard: Insufficient (HTML) buffer space: %#zx, need %#zx\n", cb, cchSrc)); 405 rc = VINF_SUCCESS; 406 } 407 else 408 { 409 Log(("readFromPasteboard: Invalid UTF-8 encoding on pasteboard: %Rrc\n", rc)); 410 rc = VERR_NOT_SUPPORTED; 411 } 412 } 413 else 414 rc = VERR_GENERAL_FAILURE; 415 } 416 else 417 LogFlow(("readFromPasteboard: PasteboardCopyItemFlavorData/kUTTypeHTML -> %d (%#x)\n", orc, orc)); 418 } 419 #endif 420 else 421 { 422 Log2(("readFromPasteboard: Unsupported format: %#x\n", fFormat)); 423 rc = VERR_NOT_SUPPORTED; 424 } 425 426 /* 427 * Release the data copy, if we got one. There are no returns above! 428 */ 429 if (hDataCopy) 430 CFRelease(hDataCopy); 431 } 432 else 433 { 434 Log(("readFromPasteboard: PasteboardGetItemIdentifier failed: %u (%#x)\n", orc, orc)); 435 rc = VERR_NOT_SUPPORTED; 436 } 437 438 Log(("readFromPasteboard: rc=%Rrc *pcbActual=%#zx\n", rc, *pcbActual)); 320 439 return rc; 321 440 }
Note:
See TracChangeset
for help on using the changeset viewer.