VirtualBox

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

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

Shared Clipboard/HostService: More renaming.

  • 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.1 KB
Line 
1/* $Id: VBoxSharedClipboardSvc-darwin.cpp 80995 2019-09-25 07:07:18Z 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 VBoxSvcClipboardLock();
107 vboxClipboardChanged(pCtx);
108 VBoxSvcClipboardUnlock();
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 Log(("vboxClipboardInit\n"));
122
123 g_ctx.fTerminate = false;
124
125 int rc = initPasteboard(&g_ctx.pasteboard);
126 AssertRCReturn(rc, rc);
127
128 rc = RTThreadCreate(&g_ctx.thread, vboxClipboardThread, &g_ctx, 0,
129 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
130 if (RT_FAILURE(rc))
131 {
132 g_ctx.thread = NIL_RTTHREAD;
133 destroyPasteboard(&g_ctx.pasteboard);
134 }
135
136 return rc;
137}
138
139void ShClSvcImplDestroy(void)
140{
141 /*
142 * Signal the termination of the polling thread and wait for it to respond.
143 */
144 ASMAtomicWriteBool(&g_ctx.fTerminate, true);
145 int rc = RTThreadUserSignal(g_ctx.thread);
146 AssertRC(rc);
147 rc = RTThreadWait(g_ctx.thread, RT_INDEFINITE_WAIT, NULL);
148 AssertRC(rc);
149
150 /*
151 * Destroy the pasteboard and uninitialize the global context record.
152 */
153 destroyPasteboard(&g_ctx.pasteboard);
154 g_ctx.thread = NIL_RTTHREAD;
155 g_ctx.pClient = NULL;
156}
157
158int ShClSvcImplConnect(PSHCLCLIENT pClient, bool fHeadless)
159{
160 RT_NOREF(fHeadless);
161
162 if (g_ctx.pClient != NULL)
163 {
164 /* One client only. */
165 return VERR_NOT_SUPPORTED;
166 }
167
168 VBoxSvcClipboardLock();
169
170 pClient->State.pCtx = &g_ctx;
171 pClient->State.pCtx->pClient = pClient;
172
173 /* Initially sync the host clipboard content with the client. */
174 int rc = ShClSvcImplSync(pClient);
175
176 VBoxSvcClipboardUnlock();
177 return rc;
178}
179
180int ShClSvcImplSync(PSHCLCLIENT pClient)
181{
182 /* Sync the host clipboard content with the client. */
183 VBoxSvcClipboardLock();
184
185 int rc = vboxClipboardChanged(pClient->State.pCtx);
186
187 VBoxSvcClipboardUnlock();
188
189 return rc;
190}
191
192int ShClSvcImplDisconnect(PSHCLCLIENT pClient)
193{
194 VBoxSvcClipboardLock();
195
196 pClient->State.pCtx->pClient = NULL;
197
198 VBoxSvcClipboardUnlock();
199
200 return VINF_SUCCESS;
201}
202
203int ShClSvcImplFormatAnnounce(PSHCLCLIENT pClient,
204 PSHCLCLIENTCMDCTX pCmdCtx, PSHCLFORMATDATA pFormats)
205{
206 RT_NOREF(pCmdCtx);
207
208 LogFlowFunc(("uFormats=%02X\n", pFormats->uFormats));
209
210 if (pFormats->uFormats == VBOX_SHCL_FMT_NONE)
211 {
212 /* This is just an automatism, not a genuine announcement */
213 return VINF_SUCCESS;
214 }
215
216#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
217 if (pFormats->uFormats & VBOX_SHCL_FMT_URI_LIST) /* No transfer support yet. */
218 return VINF_SUCCESS;
219#endif
220
221 SHCLDATAREQ dataReq;
222 RT_ZERO(dataReq);
223
224 dataReq.uFmt = pFormats->uFormats;
225 dataReq.cbSize = _64K; /** @todo Make this more dynamic. */
226
227 return shclSvcDataReadRequest(pClient, &dataReq, NULL /* puEvent */);
228}
229
230/**
231 * Called by the HGCM clipboard subsystem when the guest wants to read the host clipboard.
232 *
233 * @param pClient Context information about the guest VM.
234 * @param pCmdCtx Command context to use for reading the data. Currently unused.
235 * @param pData Data block to put read data into.
236 * @param pcbActual Where to write the actual size of the written data.
237 */
238int ShClSvcImplReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
239 PSHCLDATABLOCK pData, uint32_t *pcbActual)
240{
241 RT_NOREF(pCmdCtx);
242
243 VBoxSvcClipboardLock();
244
245 /* Default to no data available. */
246 *pcbActual = 0;
247
248 int rc = readFromPasteboard(pClient->State.pCtx->pasteboard,
249 pData->uFormat, pData->pvData, pData->cbData, pcbActual);
250
251 VBoxSvcClipboardUnlock();
252
253 return rc;
254}
255
256/**
257 * Called by the HGCM clipboard subsystem when we have requested data and that data arrives.
258 *
259 *
260 * @param pClient Context information about the guest VM.
261 * @param pCmdCtx Command context to use for writing the data. Currently unused.
262 * @param pData Data block to write to clipboard.
263 */
264int ShClSvcImplWriteData(PSHCLCLIENT pClient,
265 PSHCLCLIENTCMDCTX pCmdCtx, PSHCLDATABLOCK pData)
266{
267 RT_NOREF(pCmdCtx);
268
269 VBoxSvcClipboardLock();
270
271 writeToPasteboard(pClient->State.pCtx->pasteboard, pData->pvData, pData->cbData, pData->uFormat);
272
273 VBoxSvcClipboardUnlock();
274
275 return VINF_SUCCESS;
276}
277
278#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
279int ShClSvcImplTransferReadDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
280{
281 RT_NOREF(pClient, pDirData);
282 return VERR_NOT_IMPLEMENTED;
283}
284
285int ShClSvcImplTransferWriteDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
286{
287 RT_NOREF(pClient, pDirData);
288 return VERR_NOT_IMPLEMENTED;
289}
290
291int ShClSvcImplTransferReadFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
292{
293 RT_NOREF(pClient, pFileHdr);
294 return VERR_NOT_IMPLEMENTED;
295}
296
297int ShClSvcImplTransferWriteFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
298{
299 RT_NOREF(pClient, pFileHdr);
300 return VERR_NOT_IMPLEMENTED;
301}
302
303int ShClSvcImplTransferReadFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
304{
305 RT_NOREF(pClient, pFileData);
306 return VERR_NOT_IMPLEMENTED;
307}
308
309int ShClSvcImplTransferWriteFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
310{
311 RT_NOREF(pClient, pFileData);
312 return VERR_NOT_IMPLEMENTED;
313}
314#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
315
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