Changeset 78151 in vbox for trunk/src/VBox/HostServices/SharedClipboard
- Timestamp:
- Apr 17, 2019 12:03:42 PM (6 years ago)
- svn:sync-xref-src-repo-rev:
- 130066
- Location:
- trunk/src/VBox/HostServices/SharedClipboard
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk
r76970 r78151 35 35 VBoxSharedClipboard_SOURCES.win = \ 36 36 VBoxClipboard-win.cpp \ 37 $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp \ 37 38 VBoxSharedClipboardSvc.rc 38 39 VBoxSharedClipboard_SOURCES.darwin = \ -
trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp
r76553 r78151 24 24 25 25 #include <VBox/HostServices/VBoxClipboardSvc.h> 26 #include <VBox/GuestHost/SharedClipboard-win.h> 26 27 27 28 #include <iprt/alloc.h> … … 35 36 #include "VBoxClipboard.h" 36 37 37 #define dprintf Log 38 39 static char gachWindowClassName[] = "VBoxSharedClipboardClass"; 40 41 enum { CBCHAIN_TIMEOUT = 5000 /* ms */ }; 42 43 /* Dynamically load clipboard functions from User32.dll. */ 44 typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND); 45 typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER; 46 47 typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND); 48 typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER; 49 38 /** Static window class name. */ 39 static char s_szClipWndClassName[] = VBOX_CLIPBOARD_WNDCLASS_NAME; 50 40 51 41 /********************************************************************************************************************************* … … 55 45 static int ConvertMimeToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput); 56 46 static bool IsWindowsHTML(const char *source); 57 58 59 #ifndef WM_CLIPBOARDUPDATE 60 #define WM_CLIPBOARDUPDATE 0x031D 61 #endif 47 static int vboxClipboardSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx); 62 48 63 49 struct _VBOXCLIPBOARDCONTEXT 64 50 { 65 HWND hwnd; 66 HWND hwndNextInChain; 67 68 UINT timerRefresh; 69 70 bool fCBChainPingInProcess; 71 72 RTTHREAD thread; 73 74 HANDLE hRenderEvent; 75 76 VBOXCLIPBOARDCLIENTDATA *pClient; 77 78 PFNADDCLIPBOARDFORMATLISTENER pfnAddClipboardFormatListener; 79 PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener; 80 51 /** Handle for window message handling thread. */ 52 RTTHREAD hThread; 53 /** Event which gets triggered if the host clipboard needs to render its data. */ 54 HANDLE hRenderEvent; 55 /** Structure for keeping and communicating with client data (from the guest). */ 56 PVBOXCLIPBOARDCLIENTDATA pClient; 57 /** Windows-specific context data. */ 58 VBOXCLIPBOARDWINCTX Win; 81 59 }; 82 60 … … 86 64 87 65 #ifdef LOG_ENABLED 88 void vboxClipboardDump(const void *pv, size_t cb, uint32_t u32Format)66 static void vboxClipboardDump(const void *pv, size_t cb, uint32_t u32Format) 89 67 { 90 68 if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 91 69 { 92 Log (("DUMP:VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT:\n"));70 LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT:\n")); 93 71 if (pv && cb) 94 Log (("%ls\n", pv));72 LogFunc(("%ls\n", pv)); 95 73 else 96 Log (("%p %d\n", pv, cb));74 LogFunc(("%p %zu\n", pv, cb)); 97 75 } 98 76 else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 99 dprintf(("DUMP:VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));77 LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n")); 100 78 else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_HTML) 101 79 { 102 Log (("DUMP:VBOX_SHARED_CLIPBOARD_FMT_HTML:\n"));80 LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_HTML:\n")); 103 81 if (pv && cb) 104 82 { 105 Log (("%s\n", pv));83 LogFunc(("%s\n", pv)); 106 84 107 85 //size_t cb = RTStrNLen(pv, ); … … 114 92 } 115 93 116 Log (("%s\n", pszBuf));94 LogFunc(("%s\n", pszBuf)); 117 95 RTMemFree(pszBuf); 118 96 } 119 97 else 120 Log (("%p %d\n", pv, cb));98 LogFunc(("%p %zu\n", pv, cb)); 121 99 } 122 100 else 123 dprintf(("DUMP: invalid format %02X\n", u32Format));101 LogFunc(("Invalid format %02X\n", u32Format)); 124 102 } 125 103 #else /* !LOG_ENABLED */ … … 127 105 #endif /* !LOG_ENABLED */ 128 106 129 130 static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)131 {132 RTLDRMOD hUser32 = NIL_RTLDRMOD;133 int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32);134 if (RT_SUCCESS(rc))135 {136 rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener);137 if (RT_SUCCESS(rc))138 {139 rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener);140 }141 142 RTLdrClose(hUser32);143 }144 145 if (RT_SUCCESS(rc))146 {147 Log(("New Clipboard API is enabled\n"));148 }149 else150 {151 pCtx->pfnAddClipboardFormatListener = NULL;152 pCtx->pfnRemoveClipboardFormatListener = NULL;153 Log(("New Clipboard API is not available. rc = %Rrc\n", rc));154 }155 }156 157 static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)158 {159 return pCtx->pfnAddClipboardFormatListener != NULL;160 }161 162 163 static int vboxOpenClipboard(HWND hwnd)164 {165 /* "OpenClipboard fails if another window has the clipboard open."166 * So try a few times and wait up to 1 second.167 */168 BOOL fOpened = FALSE;169 170 int i = 0;171 for (;;)172 {173 if (OpenClipboard(hwnd))174 {175 fOpened = TRUE;176 break;177 }178 179 if (i >= 10) /* sleep interval = [1..512] ms */180 break;181 182 RTThreadSleep(1 << i);183 ++i;184 }185 186 #ifdef LOG_ENABLED187 if (i > 0)188 LogFlowFunc(("%d times tried to open clipboard.\n", i + 1));189 #endif190 191 int rc;192 if (fOpened)193 rc = VINF_SUCCESS;194 else195 {196 const DWORD err = GetLastError();197 LogFlowFunc(("error %d\n", err));198 rc = RTErrConvertFromWin32(err);199 }200 201 return rc;202 }203 204 205 107 /** @todo Someone please explain the protocol wrt overflows... */ 206 108 static void vboxClipboardGetData (uint32_t u32Format, const void *pvSrc, uint32_t cbSrc, 207 109 void *pvDst, uint32_t cbDst, uint32_t *pcbActualDst) 208 110 { 209 dprintf (("vboxClipboardGetData.\n"));210 211 111 LogFlow(("vboxClipboardGetData cbSrc = %d, cbDst = %d\n", cbSrc, cbDst)); 212 112 … … 270 170 } 271 171 272 static void vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx)273 {274 LogFlow(("vboxClipboardChanged\n"));275 276 if (pCtx->pClient == NULL)277 {278 return;279 }280 281 /* Query list of available formats and report to host. */282 int rc = vboxOpenClipboard(pCtx->hwnd);283 if (RT_SUCCESS(rc))284 {285 uint32_t u32Formats = 0;286 287 UINT format = 0;288 289 while ((format = EnumClipboardFormats (format)) != 0)290 {291 LogFlow(("vboxClipboardChanged format %#x\n", format));292 switch (format)293 {294 case CF_UNICODETEXT:295 case CF_TEXT:296 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;297 break;298 299 case CF_DIB:300 case CF_BITMAP:301 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;302 break;303 304 default:305 if (format >= 0xC000)306 {307 TCHAR szFormatName[256];308 309 int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));310 311 if (cActual)312 {313 if (strcmp (szFormatName, "HTML Format") == 0)314 {315 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML;316 }317 }318 }319 break;320 }321 }322 323 CloseClipboard ();324 325 LogFlow(("vboxClipboardChanged u32Formats %02X\n", u32Formats));326 327 vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, u32Formats);328 }329 else330 {331 LogFlow(("vboxClipboardChanged: error in open clipboard. hwnd: %x. err: %Rrc\n", pCtx->hwnd, rc));332 }333 }334 335 /* Add ourselves into the chain of cliboard listeners */336 static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx)337 {338 if (vboxClipboardIsNewAPI(pCtx))339 pCtx->pfnAddClipboardFormatListener(pCtx->hwnd);340 else341 pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd);342 }343 344 /* Remove ourselves from the chain of cliboard listeners */345 static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx)346 {347 if (vboxClipboardIsNewAPI(pCtx))348 {349 pCtx->pfnRemoveClipboardFormatListener(pCtx->hwnd);350 }351 else352 {353 ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain);354 pCtx->hwndNextInChain = NULL;355 }356 }357 358 /* Callback which is invoked when we have successfully pinged ourselves down the359 * clipboard chain. We simply unset a boolean flag to say that we are responding.360 * There is a race if a ping returns after the next one is initiated, but nothing361 * very bad is likely to happen. */362 VOID CALLBACK CBChainPingProc(HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)363 {364 (void) hwnd;365 (void) uMsg;366 (void) lResult;367 VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)dwData;368 pCtx->fCBChainPingInProcess = FALSE;369 }370 371 172 static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 372 173 { 373 174 LRESULT rc = 0; 374 175 375 VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;176 PVBOXCLIPBOARDCONTEXT pCtx = &g_ctx; 376 177 377 178 switch (msg) … … 383 184 if (GetClipboardOwner() != hwnd) 384 185 { 385 /* Clipboard was updated by another application. */ 386 vboxClipboardChanged(pCtx); 186 /* Clipboard was updated by another application, retrieve formats and report back. */ 187 int vboxrc = vboxClipboardSyncInternal(pCtx); 188 AssertRC(vboxrc); 387 189 } 388 190 } break; … … 392 194 Log(("WM_CHANGECBCHAIN\n")); 393 195 394 if ( vboxClipboardIsNewAPI(pCtx))196 if (VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI)) 395 197 { 396 198 rc = DefWindowProc(hwnd, msg, wParam, lParam); … … 401 203 HWND hwndNext = (HWND)lParam; 402 204 403 if (hwndRemoved == pCtx-> hwndNextInChain)205 if (hwndRemoved == pCtx->Win.hWndNextInChain) 404 206 { 405 207 /* The window that was next to our in the chain is being removed. 406 208 * Relink to the new next window. 407 209 */ 408 pCtx-> hwndNextInChain = hwndNext;210 pCtx->Win.hWndNextInChain = hwndNext; 409 211 } 410 212 else 411 213 { 412 if (pCtx-> hwndNextInChain)214 if (pCtx->Win.hWndNextInChain) 413 215 { 414 216 /* Pass the message further. */ 415 217 DWORD_PTR dwResult; 416 rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult); 218 rc = SendMessageTimeout(pCtx->Win.hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, 219 VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, 220 &dwResult); 417 221 if (!rc) 418 222 rc = (LRESULT)dwResult; … … 425 229 Log(("WM_DRAWCLIPBOARD\n")); 426 230 427 if (GetClipboardOwner () != hwnd) 428 { 429 /* Clipboard was updated by another application. */ 430 vboxClipboardChanged (pCtx); 431 } 432 433 if (pCtx->hwndNextInChain) 434 { 435 Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain)); 231 if (GetClipboardOwner() != hwnd) 232 { 233 /* Clipboard was updated by another application, retrieve formats and report back. */ 234 int vboxrc = vboxClipboardSyncInternal(pCtx); 235 AssertRC(vboxrc); 236 } 237 238 if (pCtx->Win.hWndNextInChain) 239 { 240 Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->Win.hWndNextInChain)); 436 241 /* Pass the message to next windows in the clipboard chain. */ 437 242 DWORD_PTR dwResult; 438 rc = SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult); 243 rc = SendMessageTimeout(pCtx->Win.hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, 244 &dwResult); 439 245 if (!rc) 440 246 rc = dwResult; … … 444 250 case WM_TIMER: 445 251 { 446 if ( vboxClipboardIsNewAPI(pCtx))252 if (VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI)) 447 253 break; 448 254 … … 451 257 /* Re-register ourselves in the clipboard chain if our last ping 452 258 * timed out or there seems to be no valid chain. */ 453 if (!hViewer || pCtx->fCBChainPingInProcess) 454 { 455 removeFromCBChain(pCtx); 456 addToCBChain(pCtx); 457 } 259 if (!hViewer || pCtx->Win.oldAPI.fCBChainPingInProcess) 260 { 261 VBoxClipboardWinRemoveFromCBChain(&pCtx->Win); 262 VBoxClipboardWinAddToCBChain(&pCtx->Win); 263 } 264 458 265 /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be 459 266 * processed by ourselves to the chain. */ 460 pCtx->fCBChainPingInProcess = TRUE; 267 pCtx->Win.oldAPI.fCBChainPingInProcess = TRUE; 268 461 269 hViewer = GetClipboardViewer(); 462 270 if (hViewer) 463 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx); 271 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, 272 (WPARAM)pCtx->Win.hWndNextInChain, (LPARAM)pCtx->Win.hWndNextInChain, 273 VBoxClipboardWinChainPingProc, (ULONG_PTR)pCtx); 464 274 } break; 465 275 … … 511 321 int vboxrc = vboxClipboardReadDataFromClient (pCtx, u32Format); 512 322 513 dprintf(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",323 LogFunc(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n", 514 324 vboxrc, pCtx->pClient->data.pv, pCtx->pClient->data.cb, pCtx->pClient->data.u32Format)); 515 325 … … 521 331 HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb); 522 332 523 dprintf(("hMem %p\n", hMem));333 LogFunc(("hMem %p\n", hMem)); 524 334 525 335 if (hMem) … … 527 337 void *pMem = GlobalLock (hMem); 528 338 529 dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));339 LogFunc(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem))); 530 340 531 341 if (pMem) … … 552 362 HANDLE hClip = SetClipboardData (format, hMem); 553 363 554 dprintf(("vboxClipboardHostEvent hClip %p\n", hClip));364 LogFunc(("vboxClipboardHostEvent hClip %p\n", hClip)); 555 365 556 366 if (hClip) … … 571 381 572 382 /* Something went wrong. */ 573 EmptyClipboard();383 VBoxClipboardWinClear(); 574 384 } 575 385 } break; … … 582 392 * windows is to be destroyed and therefore the guest side becomes inactive. 583 393 */ 584 int vboxrc = vboxOpenClipboard(hwnd);394 int vboxrc = VBoxClipboardWinOpen(hwnd); 585 395 if (RT_SUCCESS(vboxrc)) 586 396 { 587 EmptyClipboard(); 588 589 CloseClipboard(); 397 VBoxClipboardWinClear(); 398 VBoxClipboardWinClose(); 590 399 } 591 400 else … … 595 404 } break; 596 405 597 case WM_USER:406 case VBOX_CLIPBOARD_WM_SET_FORMATS: 598 407 { 599 408 if (pCtx->pClient == NULL || pCtx->pClient->fMsgFormats) … … 602 411 * because host clipboard has more priority. 603 412 */ 604 Log((" WM_USERignored\n"));413 Log(("VBOX_CLIPBOARD_WM_SET_FORMATS ignored\n")); 605 414 break; 606 415 } … … 609 418 uint32_t u32Formats = (uint32_t)lParam; 610 419 611 Log((" WM_USER u32Formats =%02X\n", u32Formats));612 613 int vboxrc = vboxOpenClipboard(hwnd);420 Log(("VBOX_CLIPBOARD_WM_SET_FORMATS: u32Formats=%02X\n", u32Formats)); 421 422 int vboxrc = VBoxClipboardWinOpen(hwnd); 614 423 if (RT_SUCCESS(vboxrc)) 615 424 { 616 EmptyClipboard();617 618 Log((" WM_USERemptied clipboard\n"));425 VBoxClipboardWinClear(); 426 427 Log(("VBOX_CLIPBOARD_WM_SET_FORMATS emptied clipboard\n")); 619 428 620 429 HANDLE hClip = NULL; 621 430 622 431 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) 623 { 624 dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n")); 625 626 hClip = SetClipboardData (CF_UNICODETEXT, NULL); 627 } 432 hClip = SetClipboardData(CF_UNICODETEXT, NULL); 628 433 629 434 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) 630 { 631 dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n")); 632 633 hClip = SetClipboardData (CF_DIB, NULL); 634 } 435 hClip = SetClipboardData(CF_DIB, NULL); 635 436 636 437 if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML) 637 438 { 638 439 UINT format = RegisterClipboardFormat ("HTML Format"); 639 dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));640 440 if (format != 0) 641 441 { … … 644 444 } 645 445 646 CloseClipboard(); 647 648 dprintf(("window proc WM_USER: hClip %p, err %d\n", hClip, GetLastError ())); 649 } 650 else 651 { 652 dprintf(("window proc WM_USER: failed to open clipboard. rc: %Rrc\n", vboxrc)); 446 VBoxClipboardWinClose(); 447 448 LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError ())); 653 449 } 654 450 } break; … … 656 452 case WM_DESTROY: 657 453 { 658 /* MS recommends to remove from Clipboard chain in this callback */ 659 Assert(pCtx->hwnd); 660 removeFromCBChain(pCtx); 661 if (pCtx->timerRefresh) 662 KillTimer(pCtx->hwnd, 0); 454 /* MS recommends to remove from Clipboard chain in this callback. */ 455 VBoxClipboardWinRemoveFromCBChain(&pCtx->Win); 456 if (pCtx->Win.oldAPI.timerRefresh) 457 { 458 Assert(pCtx->Win.hWnd); 459 KillTimer(pCtx->Win.hWnd, 0); 460 } 663 461 PostQuitMessage(0); 664 462 } break; … … 683 481 LogFlow(("VBoxClipboardThread\n")); 684 482 685 VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;483 const PVBOXCLIPBOARDCONTEXT pCtx = &g_ctx; 686 484 687 485 HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL); … … 695 493 wc.hInstance = hInstance; 696 494 wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1); 697 wc.lpszClassName = gachWindowClassName;495 wc.lpszClassName = s_szClipWndClassName; 698 496 699 497 ATOM atomWindowClass = RegisterClass(&wc); … … 707 505 { 708 506 /* Create the window. */ 709 pCtx->hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, 710 gachWindowClassName, gachWindowClassName, 711 WS_POPUPWINDOW, 712 -200, -200, 100, 100, NULL, NULL, hInstance, NULL); 713 714 if (pCtx->hwnd == NULL) 507 pCtx->Win.hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST, 508 s_szClipWndClassName, s_szClipWndClassName, 509 WS_POPUPWINDOW, 510 -200, -200, 100, 100, NULL, NULL, hInstance, NULL); 511 if (pCtx->Win.hWnd == NULL) 715 512 { 716 513 Log(("Failed to create window\n")); … … 719 516 else 720 517 { 721 SetWindowPos(pCtx-> hwnd, HWND_TOPMOST, -200, -200, 0, 0,518 SetWindowPos(pCtx->Win.hWnd, HWND_TOPMOST, -200, -200, 0, 0, 722 519 SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE); 723 520 724 addToCBChain(pCtx);725 if (! vboxClipboardIsNewAPI(pCtx))726 pCtx-> timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL);521 VBoxClipboardWinAddToCBChain(&pCtx->Win); 522 if (!VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI)) 523 pCtx->Win.oldAPI.timerRefresh = SetTimer(pCtx->Win.hWnd, 0, 10 * 1000, NULL); 727 524 728 525 MSG msg; … … 743 540 } 744 541 745 pCtx-> hwnd = NULL;542 pCtx->Win.hWnd = NULL; 746 543 747 544 if (atomWindowClass != 0) 748 545 { 749 UnregisterClass ( gachWindowClassName, hInstance);546 UnregisterClass (s_szClipWndClassName, hInstance); 750 547 atomWindowClass = 0; 751 548 } 752 549 753 550 return 0; 551 } 552 553 /** 554 * Synchronizes the host and the guest clipboard formats by sending all supported host clipboard 555 * formats to the guest. 556 * 557 * @returns VBox status code. 558 * @param pCtx Clipboard context to synchronize. 559 */ 560 static int vboxClipboardSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx) 561 { 562 uint32_t uFormats; 563 int rc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats); 564 if (RT_SUCCESS(rc)) 565 vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, uFormats); 566 567 return rc; 754 568 } 755 569 … … 763 577 RT_ZERO(g_ctx); 764 578 765 /* Check that new Clipboard API is available */766 vboxClipboardInitNewAPI(&g_ctx);579 /* Check that new Clipboard API is available. */ 580 VBoxClipboardWinCheckAndInitNewAPI(&g_ctx.Win.newAPI); 767 581 768 582 g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 769 583 770 rc = RTThreadCreate (&g_ctx. thread, VBoxClipboardThread, NULL, 65536,584 rc = RTThreadCreate (&g_ctx.hThread, VBoxClipboardThread, NULL, 65536, 771 585 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP"); 772 586 … … 783 597 Log(("vboxClipboardDestroy\n")); 784 598 785 if (g_ctx. hwnd)786 { 787 PostMessage (g_ctx. hwnd, WM_CLOSE, 0, 0);599 if (g_ctx.Win.hWnd) 600 { 601 PostMessage (g_ctx.Win.hWnd, WM_CLOSE, 0, 0); 788 602 } 789 603 … … 791 605 792 606 /* Wait for the window thread to terminate. */ 793 RTThreadWait (g_ctx. thread, RT_INDEFINITE_WAIT, NULL);794 795 g_ctx. thread = NIL_RTTHREAD;607 RTThreadWait (g_ctx.hThread, RT_INDEFINITE_WAIT, NULL); 608 609 g_ctx.hThread = NIL_RTTHREAD; 796 610 } 797 611 … … 820 634 { 821 635 /* Sync the host clipboard content with the client. */ 822 vboxClipboardChanged (pClient->pCtx); 823 824 return VINF_SUCCESS; 636 return vboxClipboardSyncInternal(pClient->pCtx); 825 637 } 826 638 … … 838 650 * The guest announces formats. Forward to the window thread. 839 651 */ 840 PostMessage (pClient->pCtx-> hwnd, WM_USER, 0, u32Formats);652 PostMessage (pClient->pCtx->Win.hWnd, WM_USER, 0, u32Formats); 841 653 } 842 654 … … 880 692 * The guest wants to read data in the given format. 881 693 */ 882 int rc = vboxOpenClipboard(pClient->pCtx->hwnd);694 int rc = VBoxClipboardWinOpen(pClient->pCtx->Win.hWnd); 883 695 if (RT_SUCCESS(rc)) 884 696 { 885 dprintf(("Clipboard opened.\n"));697 LogFunc(("Clipboard opened.\n")); 886 698 887 699 if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP) … … 895 707 if (lp != NULL) 896 708 { 897 dprintf(("CF_DIB\n"));709 LogFunc(("CF_DIB\n")); 898 710 899 711 vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_BITMAP, lp, GlobalSize (hClip), … … 918 730 if (uniString != NULL) 919 731 { 920 dprintf(("CF_UNICODETEXT\n"));732 LogFunc(("CF_UNICODETEXT\n")); 921 733 922 734 vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, uniString, (lstrlenW (uniString) + 1) * 2, … … 945 757 if (lp != NULL) 946 758 { 947 dprintf(("CF_HTML\n"));759 LogFunc(("CF_HTML\n")); 948 760 949 761 vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize (hClip), … … 961 773 } 962 774 963 CloseClipboard();775 VBoxClipboardWinClose(); 964 776 } 965 777 else 966 778 { 967 dprintf(("vboxClipboardReadData: failed to open clipboard, rc: %Rrc\n", rc));779 LogFunc(("vboxClipboardReadData: failed to open clipboard, rc: %Rrc\n", rc)); 968 780 } 969 781 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h
r76570 r78151 25 25 #include <VBox/log.h> 26 26 27 struct _VBOXCLIPBOARDCONTEXT; 28 typedef struct _VBOXCLIPBOARDCONTEXT VBOXCLIPBOARDCONTEXT; 29 27 #include <VBox/GuestHost/SharedClipboard.h> 30 28 31 29 typedef struct _VBOXCLIPBOARDCLIENTDATA … … 64 62 uint32_t u32RequestedFormat; 65 63 66 } VBOXCLIPBOARDCLIENTDATA ;64 } VBOXCLIPBOARDCLIENTDATA, *PVBOXCLIPBOARDCLIENTDATA; 67 65 68 66 /* 69 67 * The service functions. Locking is between the service thread and the platform dependent windows thread. 70 68 */ 71 bool vboxSvcClipboardLock (void);72 void vboxSvcClipboardUnlock (void);73 74 69 void vboxSvcClipboardReportMsg (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Msg, uint32_t u32Formats); 75 76 70 void vboxSvcClipboardCompleteReadData(VBOXCLIPBOARDCLIENTDATA *pClient, int rc, uint32_t cbActual); 77 78 bool vboxSvcClipboardGetHeadless(void);79 71 80 72 /* … … 86 78 int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless); 87 79 void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient); 88 89 80 void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats); 90 91 81 int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual); 92 93 82 void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_t cb, uint32_t u32Format); 94 83 -
trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp
r76970 r78151 109 109 static bool g_fHeadless = false; 110 110 111 static bool vboxSvcClipboardGetHeadless(void); 112 static bool vboxSvcClipboardLock(void); 113 static void vboxSvcClipboardUnlock(void); 114 111 115 112 116 static void VBoxHGCMParmUInt32Set (VBOXHGCMSVCPARM *pParm, uint32_t u32) … … 163 167 164 168 /** Getter for headless setting */ 165 bool vboxSvcClipboardGetHeadless(void)169 static bool vboxSvcClipboardGetHeadless(void) 166 170 { 167 171 return g_fHeadless; … … 184 188 } 185 189 186 bool vboxSvcClipboardLock (void)190 static bool vboxSvcClipboardLock (void) 187 191 { 188 192 return RT_SUCCESS(RTCritSectEnter (&critsect)); 189 193 } 190 194 191 void vboxSvcClipboardUnlock(void)195 static void vboxSvcClipboardUnlock(void) 192 196 { 193 197 RTCritSectLeave (&critsect);
Note:
See TracChangeset
for help on using the changeset viewer.