VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-darwin.cpp@ 80585

Last change on this file since 80585 was 80447, checked in by vboxsync, 5 years ago

Shared Clipboard/URI: MacOS build fix.

  • Property eol-style set to native
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
Line 
1/* $Id: VBoxSharedClipboardSvc-darwin.cpp 80447 2019-08-27 18:09:09Z vboxsync $ */
2/** @file
3 * Shared Clipboard Service - Mac OS X host.
4 */
5
6/*
7 * Copyright (C) 2008-2019 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#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
23#include <VBox/HostServices/VBoxClipboardSvc.h>
24
25#include <iprt/assert.h>
26#include <iprt/asm.h>
27#include <iprt/thread.h>
28
29#include "VBoxSharedClipboardSvc-internal.h"
30#include "darwin-pasteboard.h"
31
32
33/*********************************************************************************************************************************
34* Structures and Typedefs *
35*********************************************************************************************************************************/
36/** Global clipboard context information */
37struct _VBOXCLIPBOARDCONTEXT
38{
39 /** We have a separate thread to poll for new clipboard content */
40 RTTHREAD thread;
41 bool volatile fTerminate;
42
43 /** The reference to the current pasteboard */
44 PasteboardRef pasteboard;
45
46 PVBOXCLIPBOARDCLIENT pClient;
47};
48
49
50/*********************************************************************************************************************************
51* Global Variables *
52*********************************************************************************************************************************/
53/** Only one client is supported. There seems to be no need for more clients. */
54static VBOXCLIPBOARDCONTEXT g_ctx;
55
56
57/**
58 * Checks if something is present on the clipboard and calls vboxSvcClipboardReportMsg.
59 *
60 * @returns IPRT status code (ignored).
61 * @param pCtx The context.
62 */
63static int vboxClipboardChanged(VBOXCLIPBOARDCONTEXT *pCtx)
64{
65 if (pCtx->pClient == NULL)
66 return VINF_SUCCESS;
67
68 uint32_t fFormats = 0;
69 bool fChanged = false;
70 /* Retrieve the formats currently in the clipboard and supported by vbox */
71 int rc = queryNewPasteboardFormats(pCtx->pasteboard, &fFormats, &fChanged);
72 if (RT_SUCCESS(rc) && fChanged)
73 {
74 vboxSvcClipboardOldReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS_WRITE, fFormats);
75 Log(("vboxClipboardChanged fFormats %02X\n", fFormats));
76 }
77
78 return rc;
79}
80
81
82/**
83 * The poller thread.
84 *
85 * This thread will check for the arrival of new data on the clipboard.
86 *
87 * @returns VINF_SUCCESS (not used).
88 * @param ThreadSelf Our thread handle.
89 * @param pvUser Pointer to the VBOXCLIPBOARDCONTEXT structure.
90 *
91 */
92static int vboxClipboardThread(RTTHREAD ThreadSelf, void *pvUser)
93{
94 Log(("vboxClipboardThread: starting clipboard thread\n"));
95
96 AssertPtrReturn(pvUser, VERR_INVALID_PARAMETER);
97 VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)pvUser;
98
99 while (!pCtx->fTerminate)
100 {
101 /* call this behind the lock because we don't know if the api is
102 thread safe and in any case we're calling several methods. */
103 VBoxSvcClipboardLock();
104 vboxClipboardChanged(pCtx);
105 VBoxSvcClipboardUnlock();
106
107 /* Sleep for 200 msecs before next poll */
108 RTThreadUserWait(ThreadSelf, 200);
109 }
110
111 Log(("vboxClipboardThread: clipboard thread terminated successfully with return code %Rrc\n", VINF_SUCCESS));
112 return VINF_SUCCESS;
113}
114
115/*
116 * Public platform dependent functions.
117 */
118
119/** Initialise the host side of the shared clipboard - called by the hgcm layer. */
120int VBoxClipboardSvcImplInit(void)
121{
122 Log(("vboxClipboardInit\n"));
123
124 g_ctx.fTerminate = false;
125
126 int rc = initPasteboard(&g_ctx.pasteboard);
127 AssertRCReturn(rc, rc);
128
129 rc = RTThreadCreate(&g_ctx.thread, vboxClipboardThread, &g_ctx, 0,
130 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
131 if (RT_FAILURE(rc))
132 {
133 g_ctx.thread = NIL_RTTHREAD;
134 destroyPasteboard(&g_ctx.pasteboard);
135 }
136
137 return rc;
138}
139
140/** Terminate the host side of the shared clipboard - called by the hgcm layer. */
141void VBoxClipboardSvcImplDestroy(void)
142{
143 Log(("vboxClipboardDestroy\n"));
144
145 /*
146 * Signal the termination of the polling thread and wait for it to respond.
147 */
148 ASMAtomicWriteBool(&g_ctx.fTerminate, true);
149 int rc = RTThreadUserSignal(g_ctx.thread);
150 AssertRC(rc);
151 rc = RTThreadWait(g_ctx.thread, RT_INDEFINITE_WAIT, NULL);
152 AssertRC(rc);
153
154 /*
155 * Destroy the pasteboard and uninitialize the global context record.
156 */
157 destroyPasteboard(&g_ctx.pasteboard);
158 g_ctx.thread = NIL_RTTHREAD;
159 g_ctx.pClient = NULL;
160}
161
162int VBoxClipboardSvcImplConnect(PVBOXCLIPBOARDCLIENT pClient, bool fHeadless)
163{
164 RT_NOREF(fHeadless);
165
166 if (g_ctx.pClient != NULL)
167 {
168 /* One client only. */
169 return VERR_NOT_SUPPORTED;
170 }
171
172 VBoxSvcClipboardLock();
173
174 pClient->State.pCtx = &g_ctx;
175 pClient->State.pCtx->pClient = pClient;
176
177 /* Initially sync the host clipboard content with the client. */
178 int rc = VBoxClipboardSvcImplSync(pClient);
179
180 VBoxSvcClipboardUnlock();
181 return rc;
182}
183
184int VBoxClipboardSvcImplSync(PVBOXCLIPBOARDCLIENT pClient)
185{
186 /* Sync the host clipboard content with the client. */
187 VBoxSvcClipboardLock();
188 int rc = vboxClipboardChanged(pClient->State.pCtx);
189 VBoxSvcClipboardUnlock();
190
191 return rc;
192}
193
194int VBoxClipboardSvcImplDisconnect(PVBOXCLIPBOARDCLIENT pClient)
195{
196 VBoxSvcClipboardLock();
197 pClient->State.pCtx->pClient = NULL;
198 VBoxSvcClipboardUnlock();
199
200 return VINF_SUCCESS;
201}
202
203int VBoxClipboardSvcImplFormatAnnounce(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDCLIENTCMDCTX pCmdCtx,
204 PSHAREDCLIPBOARDFORMATDATA pFormats)
205{
206 RT_NOREF(pCmdCtx);
207
208 LogFlowFunc(("uFormats=%02X\n", pFormats->uFormats));
209
210 if (pFormats->uFormats == 0)
211 {
212 /* This is just an automatism, not a genuine announcement */
213 return VINF_SUCCESS;
214 }
215
216#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
217 if (pFormats->uFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST) /* No URI support yet. */
218 return VINF_SUCCESS;
219#endif
220
221 return vboxSvcClipboardOldReportMsg(pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA, pFormats->uFormats);
222}
223
224/**
225 * Called by the HGCM clipboard subsystem when the guest wants to read the host clipboard.
226 *
227 * @param pClient Context information about the guest VM.
228 * @param pCmdCtx Command context to use for reading the data. Currently unused.
229 * @param pData Data block to put read data into.
230 * @param pcbActual Where to write the actual size of the written data.
231 */
232int VBoxClipboardSvcImplReadData(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDCLIENTCMDCTX pCmdCtx,
233 PSHAREDCLIPBOARDDATABLOCK pData, uint32_t *pcbActual)
234{
235 RT_NOREF(pCmdCtx);
236
237 VBoxSvcClipboardLock();
238
239 /* Default to no data available. */
240 *pcbActual = 0;
241
242 int rc = readFromPasteboard(pClient->State.pCtx->pasteboard,
243 pData->uFormat, pData->pvData, pData->cbData, pcbActual);
244
245 VBoxSvcClipboardUnlock();
246
247 return rc;
248}
249
250/**
251 * Called by the HGCM clipboard subsystem when we have requested data and that data arrives.
252 *
253 *
254 * @param pClient Context information about the guest VM.
255 * @param pCmdCtx Command context to use for writing the data. Currently unused.
256 * @param pData Data block to write to clipboard.
257 */
258int VBoxClipboardSvcImplWriteData(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDCLIENTCMDCTX pCmdCtx, PSHAREDCLIPBOARDDATABLOCK pData)
259{
260 RT_NOREF(pCmdCtx);
261
262 VBoxSvcClipboardLock();
263
264 writeToPasteboard(pClient->State.pCtx->pasteboard, pData->pvData, pData->cbData, pData->uFormat);
265
266 VBoxSvcClipboardUnlock();
267
268 return VINF_SUCCESS;
269}
270
271#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
272int VBoxClipboardSvcImplURIReadDir(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDDIRDATA pDirData)
273{
274 RT_NOREF(pClient, pDirData);
275 return VERR_NOT_IMPLEMENTED;
276}
277
278int VBoxClipboardSvcImplURIWriteDir(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDDIRDATA pDirData)
279{
280 RT_NOREF(pClient, pDirData);
281 return VERR_NOT_IMPLEMENTED;
282}
283
284int VBoxClipboardSvcImplURIReadFileHdr(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDFILEHDR pFileHdr)
285{
286 RT_NOREF(pClient, pFileHdr);
287 return VERR_NOT_IMPLEMENTED;
288}
289
290int VBoxClipboardSvcImplURIWriteFileHdr(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDFILEHDR pFileHdr)
291{
292 RT_NOREF(pClient, pFileHdr);
293 return VERR_NOT_IMPLEMENTED;
294}
295
296int VBoxClipboardSvcImplURIReadFileData(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDFILEDATA pFileData)
297{
298 RT_NOREF(pClient, pFileData);
299 return VERR_NOT_IMPLEMENTED;
300}
301
302int VBoxClipboardSvcImplURIWriteFileData(PVBOXCLIPBOARDCLIENT pClient, PVBOXCLIPBOARDFILEDATA pFileData)
303{
304 RT_NOREF(pClient, pFileData);
305 return VERR_NOT_IMPLEMENTED;
306}
307#endif /* VBOX_WITH_SHARED_CLIPBOARD_URI_LIST */
308
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