VirtualBox

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

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

GuestHost/SharedClipboard.h: Got rid of all the leading underscores that I could spot. Shuffled the members of SHCLDATABLOCK so we save 8 bytes on 64-bit machines. bugref:9437

  • 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.1 KB
Line 
1/* $Id: VBoxSharedClipboardSvc-darwin.cpp 82480 2019-12-07 00:32:57Z 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.Formats = 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 ShClSvcUnlock();
172
173 return VINF_SUCCESS;
174}
175
176int ShClSvcImplSync(PSHCLCLIENT pClient)
177{
178 /* Sync the host clipboard content with the client. */
179 ShClSvcLock();
180
181 int rc = vboxClipboardChanged(pClient->State.pCtx);
182
183 ShClSvcUnlock();
184
185 return rc;
186}
187
188int ShClSvcImplDisconnect(PSHCLCLIENT pClient)
189{
190 ShClSvcLock();
191
192 pClient->State.pCtx->pClient = NULL;
193
194 ShClSvcUnlock();
195
196 return VINF_SUCCESS;
197}
198
199int ShClSvcImplFormatAnnounce(PSHCLCLIENT pClient,
200 PSHCLCLIENTCMDCTX pCmdCtx, PSHCLFORMATDATA pFormats)
201{
202 RT_NOREF(pCmdCtx);
203
204 LogFlowFunc(("uFormats=%02X\n", pFormats->Formats));
205
206 if (pFormats->Formats == VBOX_SHCL_FMT_NONE)
207 {
208 /* This is just an automatism, not a genuine announcement */
209 return VINF_SUCCESS;
210 }
211
212#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
213 if (pFormats->Formats & VBOX_SHCL_FMT_URI_LIST) /* No transfer support yet. */
214 return VINF_SUCCESS;
215#endif
216
217 SHCLDATAREQ dataReq;
218 RT_ZERO(dataReq);
219
220 dataReq.uFmt = pFormats->Formats;
221 dataReq.cbSize = _64K; /** @todo Make this more dynamic. */
222
223 return ShClSvcDataReadRequest(pClient, &dataReq, NULL /* puEvent */);
224}
225
226int ShClSvcImplReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
227 PSHCLDATABLOCK pData, uint32_t *pcbActual)
228{
229 RT_NOREF(pCmdCtx);
230
231 ShClSvcLock();
232
233 /* Default to no data available. */
234 *pcbActual = 0;
235
236 int rc = readFromPasteboard(pClient->State.pCtx->pasteboard,
237 pData->uFormat, pData->pvData, pData->cbData, pcbActual);
238
239 ShClSvcUnlock();
240
241 return rc;
242}
243
244int ShClSvcImplWriteData(PSHCLCLIENT pClient,
245 PSHCLCLIENTCMDCTX pCmdCtx, PSHCLDATABLOCK pData)
246{
247 RT_NOREF(pCmdCtx);
248
249 ShClSvcLock();
250
251 writeToPasteboard(pClient->State.pCtx->pasteboard, pData->pvData, pData->cbData, pData->uFormat);
252
253 ShClSvcUnlock();
254
255 return VINF_SUCCESS;
256}
257
258#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
259int ShClSvcImplTransferReadDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
260{
261 RT_NOREF(pClient, pDirData);
262 return VERR_NOT_IMPLEMENTED;
263}
264
265int ShClSvcImplTransferWriteDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
266{
267 RT_NOREF(pClient, pDirData);
268 return VERR_NOT_IMPLEMENTED;
269}
270
271int ShClSvcImplTransferReadFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
272{
273 RT_NOREF(pClient, pFileHdr);
274 return VERR_NOT_IMPLEMENTED;
275}
276
277int ShClSvcImplTransferWriteFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
278{
279 RT_NOREF(pClient, pFileHdr);
280 return VERR_NOT_IMPLEMENTED;
281}
282
283int ShClSvcImplTransferReadFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
284{
285 RT_NOREF(pClient, pFileData);
286 return VERR_NOT_IMPLEMENTED;
287}
288
289int ShClSvcImplTransferWriteFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
290{
291 RT_NOREF(pClient, pFileData);
292 return VERR_NOT_IMPLEMENTED;
293}
294#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
295
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