status_t VBoxClipboardService::_ServiceThread() { printf("VBoxClipboardService::%s()\n", __FUNCTION__); /* The thread waits for incoming messages from the host. */ for (;;) { uint32_t u32Msg; uint32_t u32Formats; int rc = VbglR3ClipboardGetHostMsg(fClientId, &u32Msg, &u32Formats); if (RT_SUCCESS(rc)) { switch (u32Msg) { case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: { /* * The host has announced available clipboard formats. Forward * the information to the handler. */ LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS u32Formats=%x\n", u32Formats)); BMessage msg(VBOX_GUEST_CLIPBOARD_HOST_MSG_FORMATS); msg.AddInt32("Formats", (uint32)u32Formats); Looper()->PostMessage(&msg, this); break; } case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: { /* The host needs data in the specified format. */ LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA u32Formats=%x\n", u32Formats)); BMessage msg(VBOX_GUEST_CLIPBOARD_HOST_MSG_READ_DATA); msg.AddInt32("Formats", (uint32)u32Formats); Looper()->PostMessage(&msg, this); break; } case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: { /* The host is terminating. */ LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT\n")); fExiting = true; return VERR_INTERRUPTED; } default: Log(("VBoxClipboardService::%s: Unsupported message from host! Message = %u\n", __FUNCTION__, u32Msg)); } } else fExiting = true; LogRelFlow(("processed host event rc = %d\n", rc)); if (fExiting) break; } return 0; }
DECLCALLBACK(int) VBoxClipboardWorker(void *pInstance, bool volatile *pfShutdown) { AssertPtr(pInstance); LogFlowFunc(("pInstance=%p\n", pInstance)); /* * Tell the control thread that it can continue * spawning services. */ RTThreadUserSignal(RTThreadSelf()); PVBOXCLIPBOARDCONTEXT pCtx = (PVBOXCLIPBOARDCONTEXT)pInstance; AssertPtr(pCtx); int rc; /* The thread waits for incoming messages from the host. */ for (;;) { uint32_t u32Msg; uint32_t u32Formats; rc = VbglR3ClipboardGetHostMsg(pCtx->u32ClientID, &u32Msg, &u32Formats); if (RT_FAILURE(rc)) { if (rc == VERR_INTERRUPTED) break; LogFlowFunc(("Error getting host message, rc=%Rrc\n", rc)); if (*pfShutdown) break; /* Wait a bit before retrying. */ RTThreadSleep(1000); continue; } else { LogFlowFunc(("u32Msg=%RU32, u32Formats=0x%x\n", u32Msg, u32Formats)); switch (u32Msg) { /** @todo r=andy: Use a \#define for WM_USER (+1). */ case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: { /* The host has announced available clipboard formats. * Forward the information to the window, so it can later * respond to WM_RENDERFORMAT message. */ ::PostMessage(pCtx->hwnd, WM_USER, 0, u32Formats); } break; case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: { /* The host needs data in the specified format. */ ::PostMessage(pCtx->hwnd, WM_USER + 1, 0, u32Formats); } break; case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: { /* The host is terminating. */ LogRel(("Clipboard: Terminating ...\n")); ASMAtomicXchgBool(pfShutdown, true); } break; default: { LogFlowFunc(("Unsupported message from host, message=%RU32\n", u32Msg)); /* Wait a bit before retrying. */ RTThreadSleep(1000); } break; } } if (*pfShutdown) break; } LogFlowFuncLeaveRC(rc); return rc; }
unsigned __stdcall VBoxClipboardThread(void *pInstance) { Log(("VBoxTray: VBoxClipboardThread\n")); VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)pInstance; AssertPtr(pCtx); /* The thread waits for incoming messages from the host. */ for (;;) { uint32_t u32Msg; uint32_t u32Formats; int rc = VbglR3ClipboardGetHostMsg(pCtx->u32ClientID, &u32Msg, &u32Formats); if (RT_FAILURE(rc)) { Log(("VBoxTray: VBoxClipboardThread: Failed to call the driver for host message! rc = %Rrc\n", rc)); if (rc == VERR_INTERRUPTED) { /* Wait for termination event. */ WaitForSingleObject(pCtx->pEnv->hStopEvent, INFINITE); break; } /* Wait a bit before retrying. */ AssertPtr(pCtx->pEnv); if (WaitForSingleObject(pCtx->pEnv->hStopEvent, 1000) == WAIT_OBJECT_0) { break; } continue; } else { Log(("VBoxTray: VBoxClipboardThread: VbglR3ClipboardGetHostMsg u32Msg = %ld, u32Formats = %ld\n", u32Msg, u32Formats)); switch (u32Msg) { case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: { /* The host has announced available clipboard formats. * Forward the information to the window, so it can later * respond to WM_RENDERFORMAT message. */ ::PostMessage (pCtx->hwnd, WM_USER, 0, u32Formats); } break; case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: { /* The host needs data in the specified format. */ ::PostMessage (pCtx->hwnd, WM_USER + 1, 0, u32Formats); } break; case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: { /* The host is terminating. */ rc = VERR_INTERRUPTED; } break; default: { Log(("VBoxTray: VBoxClipboardThread: Unsupported message from host! Message = %ld\n", u32Msg)); } } } } return 0; }
/** * The main loop of our clipboard reader. */ int vboxClipboardMain(void) { int rc; LogRelFlowFunc(("Starting guest clipboard service\n")); bool fExiting = false; while (!fExiting) { uint32_t Msg; uint32_t fFormats; rc = VbglR3ClipboardGetHostMsg(g_ctx.client, &Msg, &fFormats); if (RT_SUCCESS(rc)) { switch (Msg) { case VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS: { /* The host has announced available clipboard formats. * Save the information so that it is available for * future requests from guest applications. */ LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS fFormats=%x\n", fFormats)); ClipAnnounceFormatToX11(g_ctx.pBackend, fFormats); break; } case VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA: { /* The host needs data in the specified format. */ LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA fFormats=%x\n", fFormats)); CLIPREADCBREQ *pReq; pReq = (CLIPREADCBREQ *)RTMemAllocZ(sizeof(*pReq)); if (!pReq) { rc = VERR_NO_MEMORY; fExiting = true; } else { pReq->u32Format = fFormats; ClipRequestDataFromX11(g_ctx.pBackend, fFormats, pReq); } break; } case VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT: { /* The host is terminating. */ LogRelFlowFunc(("VBOX_SHARED_CLIPBOARD_HOST_MSG_QUIT\n")); if (RT_SUCCESS(ClipStopX11(g_ctx.pBackend))) ClipDestructX11(g_ctx.pBackend); fExiting = true; break; } default: LogRel2(("Unsupported message from host!!!\n")); } } LogRelFlow(("processed host event rc = %d\n", rc)); } LogRelFlowFunc(("rc=%d\n", rc)); return rc; }