VirtualBox

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

Last change on this file since 81428 was 81174, checked in by vboxsync, 5 years ago

Shared Clipboard: Docs.

  • Property eol-style set to native
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.2 KB
Line 
1/* $Id: VBoxSharedClipboardSvc-darwin.cpp 81174 2019-10-09 09:06:38Z 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 _SHCLCONTEXT
38{
39 /** We have a separate thread to poll for new clipboard content */
40 RTTHREAD thread;
41 bool volatile fTerminate;
42 /** The reference to the current pasteboard */
43 PasteboardRef pasteboard;
44 PSHCLCLIENT pClient;
45};
46
47
48/*********************************************************************************************************************************
49* Global Variables *
50*********************************************************************************************************************************/
51/** Only one client is supported. There seems to be no need for more clients. */
52static SHCLCONTEXT g_ctx;
53
54
55/**
56 * Checks if something is present on the clipboard and calls shclSvcReportMsg.
57 *
58 * @returns IPRT status code (ignored).
59 * @param pCtx The context.
60 */
61static int vboxClipboardChanged(SHCLCONTEXT *pCtx)
62{
63 if (pCtx->pClient == NULL)
64 return VINF_SUCCESS;
65
66 uint32_t fFormats = 0;
67 bool fChanged = false;
68 /* Retrieve the formats currently in the clipboard and supported by vbox */
69 int rc = queryNewPasteboardFormats(pCtx->pasteboard, &fFormats, &fChanged);
70 if ( RT_SUCCESS(rc)
71 && fChanged)
72 {
73 SHCLFORMATDATA formatData;
74 RT_ZERO(formatData);
75
76 formatData.uFormats = fFormats;
77
78 rc = shclSvcFormatsReport(pCtx->pClient, &formatData);
79 }
80
81 LogFlowFuncLeaveRC(rc);
82 return rc;
83}
84
85/**
86 * The poller thread.
87 *
88 * This thread will check for the arrival of new data on the clipboard.
89 *
90 * @returns VINF_SUCCESS (not used).
91 * @param ThreadSelf Our thread handle.
92 * @param pvUser Pointer to the SHCLCONTEXT structure.
93 *
94 */
95static int vboxClipboardThread(RTTHREAD ThreadSelf, void *pvUser)
96{
97 LogFlowFuncEnter();
98
99 AssertPtrReturn(pvUser, VERR_INVALID_PARAMETER);
100 SHCLCONTEXT *pCtx = (SHCLCONTEXT *)pvUser;
101
102 while (!pCtx->fTerminate)
103 {
104 /* call this behind the lock because we don't know if the api is
105 thread safe and in any case we're calling several methods. */
106 ShClSvcLock();
107 vboxClipboardChanged(pCtx);
108 ShClSvcUnlock();
109
110 /* Sleep for 200 msecs before next poll */
111 RTThreadUserWait(ThreadSelf, 200);
112 }
113
114 LogFlowFuncLeaveRC(VINF_SUCCESS);
115 return VINF_SUCCESS;
116}
117
118
119int ShClSvcImplInit(void)
120{
121 g_ctx.fTerminate = false;
122
123 int rc = initPasteboard(&g_ctx.pasteboard);
124 AssertRCReturn(rc, rc);
125
126 rc = RTThreadCreate(&g_ctx.thread, vboxClipboardThread, &g_ctx, 0,
127 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
128 if (RT_FAILURE(rc))
129 {
130 g_ctx.thread = NIL_RTTHREAD;
131 destroyPasteboard(&g_ctx.pasteboard);
132 }
133
134 return rc;
135}
136
137void ShClSvcImplDestroy(void)
138{
139 /*
140 * Signal the termination of the polling thread and wait for it to respond.
141 */
142 ASMAtomicWriteBool(&g_ctx.fTerminate, true);
143 int rc = RTThreadUserSignal(g_ctx.thread);
144 AssertRC(rc);
145 rc = RTThreadWait(g_ctx.thread, RT_INDEFINITE_WAIT, NULL);
146 AssertRC(rc);
147
148 /*
149 * Destroy the pasteboard and uninitialize the global context record.
150 */
151 destroyPasteboard(&g_ctx.pasteboard);
152 g_ctx.thread = NIL_RTTHREAD;
153 g_ctx.pClient = NULL;
154}
155
156int ShClSvcImplConnect(PSHCLCLIENT pClient, bool fHeadless)
157{
158 RT_NOREF(fHeadless);
159
160 if (g_ctx.pClient != NULL)
161 {
162 /* One client only. */
163 return VERR_NOT_SUPPORTED;
164 }
165
166 ShClSvcLock();
167
168 pClient->State.pCtx = &g_ctx;
169 pClient->State.pCtx->pClient = pClient;
170
171 /* Initially sync the host clipboard content with the client. */
172 int rc = ShClSvcImplSync(pClient);
173
174 ShClSvcUnlock();
175 return rc;
176}
177
178int ShClSvcImplSync(PSHCLCLIENT pClient)
179{
180 /* Sync the host clipboard content with the client. */
181 ShClSvcLock();
182
183 int rc = vboxClipboardChanged(pClient->State.pCtx);
184
185 ShClSvcUnlock();
186
187 return rc;
188}
189
190int ShClSvcImplDisconnect(PSHCLCLIENT pClient)
191{
192 ShClSvcLock();
193
194 pClient->State.pCtx->pClient = NULL;
195
196 ShClSvcUnlock();
197
198 return VINF_SUCCESS;
199}
200
201int ShClSvcImplFormatAnnounce(PSHCLCLIENT pClient,
202 PSHCLCLIENTCMDCTX pCmdCtx, PSHCLFORMATDATA pFormats)
203{
204 RT_NOREF(pCmdCtx);
205
206 LogFlowFunc(("uFormats=%02X\n", pFormats->uFormats));
207
208 if (pFormats->uFormats == VBOX_SHCL_FMT_NONE)
209 {
210 /* This is just an automatism, not a genuine announcement */
211 return VINF_SUCCESS;
212 }
213
214#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
215 if (pFormats->uFormats & VBOX_SHCL_FMT_URI_LIST) /* No transfer support yet. */
216 return VINF_SUCCESS;
217#endif
218
219 SHCLDATAREQ dataReq;
220 RT_ZERO(dataReq);
221
222 dataReq.uFmt = pFormats->uFormats;
223 dataReq.cbSize = _64K; /** @todo Make this more dynamic. */
224
225 return shclSvcDataReadRequest(pClient, &dataReq, NULL /* puEvent */);
226}
227
228int ShClSvcImplReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
229 PSHCLDATABLOCK pData, uint32_t *pcbActual)
230{
231 RT_NOREF(pCmdCtx);
232
233 ShClSvcLock();
234
235 /* Default to no data available. */
236 *pcbActual = 0;
237
238 int rc = readFromPasteboard(pClient->State.pCtx->pasteboard,
239 pData->uFormat, pData->pvData, pData->cbData, pcbActual);
240
241 ShClSvcUnlock();
242
243 return rc;
244}
245
246int ShClSvcImplWriteData(PSHCLCLIENT pClient,
247 PSHCLCLIENTCMDCTX pCmdCtx, PSHCLDATABLOCK pData)
248{
249 RT_NOREF(pCmdCtx);
250
251 ShClSvcLock();
252
253 writeToPasteboard(pClient->State.pCtx->pasteboard, pData->pvData, pData->cbData, pData->uFormat);
254
255 ShClSvcUnlock();
256
257 return VINF_SUCCESS;
258}
259
260#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
261int ShClSvcImplTransferReadDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
262{
263 RT_NOREF(pClient, pDirData);
264 return VERR_NOT_IMPLEMENTED;
265}
266
267int ShClSvcImplTransferWriteDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
268{
269 RT_NOREF(pClient, pDirData);
270 return VERR_NOT_IMPLEMENTED;
271}
272
273int ShClSvcImplTransferReadFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
274{
275 RT_NOREF(pClient, pFileHdr);
276 return VERR_NOT_IMPLEMENTED;
277}
278
279int ShClSvcImplTransferWriteFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
280{
281 RT_NOREF(pClient, pFileHdr);
282 return VERR_NOT_IMPLEMENTED;
283}
284
285int ShClSvcImplTransferReadFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
286{
287 RT_NOREF(pClient, pFileData);
288 return VERR_NOT_IMPLEMENTED;
289}
290
291int ShClSvcImplTransferWriteFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
292{
293 RT_NOREF(pClient, pFileData);
294 return VERR_NOT_IMPLEMENTED;
295}
296#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
297
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