VirtualBox

source: vbox/trunk/src/VBox/HostServices/SharedClipboard/darwin.cpp@ 76570

Last change on this file since 76570 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property eol-style set to native
  • Property svn:eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 8.7 KB
Line 
1/* $Id: darwin.cpp 76553 2019-01-01 01:45:53Z 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 "VBoxClipboard.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 VBOXCLIPBOARDCLIENTDATA *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 vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, 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 vboxClipboardInit (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 vboxClipboardDestroy (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
162/**
163 * Enable the shared clipboard - called by the hgcm clipboard subsystem.
164 *
165 * @param pClient Structure containing context information about the guest system
166 * @param fHeadless Whether headless.
167 * @returns RT status code
168 */
169int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless)
170{
171 NOREF(fHeadless);
172 if (g_ctx.pClient != NULL)
173 {
174 /* One client only. */
175 return VERR_NOT_SUPPORTED;
176 }
177
178 vboxSvcClipboardLock();
179
180 pClient->pCtx = &g_ctx;
181 pClient->pCtx->pClient = pClient;
182
183 /* Initially sync the host clipboard content with the client. */
184 int rc = vboxClipboardSync (pClient);
185
186 vboxSvcClipboardUnlock();
187 return rc;
188}
189
190/**
191 * Synchronise the contents of the host clipboard with the guest, called by the HGCM layer
192 * after a save and restore of the guest.
193 */
194int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient)
195{
196 /* Sync the host clipboard content with the client. */
197 vboxSvcClipboardLock();
198 int rc = vboxClipboardChanged (pClient->pCtx);
199 vboxSvcClipboardUnlock();
200
201 return rc;
202}
203
204/**
205 * Shut down the shared clipboard subsystem and "disconnect" the guest.
206 */
207void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient)
208{
209 Log (("vboxClipboardDisconnect\n"));
210
211 vboxSvcClipboardLock();
212 pClient->pCtx->pClient = NULL;
213 vboxSvcClipboardUnlock();
214}
215
216/**
217 * The guest is taking possession of the shared clipboard. Called by the HGCM clipboard
218 * subsystem.
219 *
220 * @param pClient Context data for the guest system
221 * @param u32Formats Clipboard formats the guest is offering
222 */
223void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats)
224{
225 Log (("vboxClipboardFormatAnnounce u32Formats %02X\n", u32Formats));
226 if (u32Formats == 0)
227 {
228 /* This is just an automatism, not a genuine announcement */
229 return;
230 }
231
232 vboxSvcClipboardReportMsg (pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
233 u32Formats);
234}
235
236/**
237 * Called by the HGCM clipboard subsystem when the guest wants to read the host clipboard.
238 *
239 * @param pClient Context information about the guest VM
240 * @param u32Format The format that the guest would like to receive the data in
241 * @param pv Where to write the data to
242 * @param cb The size of the buffer to write the data to
243 * @param pcbActual Where to write the actual size of the written data
244 */
245int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format,
246 void *pv, uint32_t cb, uint32_t * pcbActual)
247{
248 vboxSvcClipboardLock();
249
250 /* Default to no data available. */
251 *pcbActual = 0;
252 int rc = readFromPasteboard (pClient->pCtx->pasteboard, u32Format, pv, cb, pcbActual);
253
254 vboxSvcClipboardUnlock();
255 return rc;
256}
257
258/**
259 * Called by the HGCM clipboard subsystem when we have requested data and that data arrives.
260 *
261 * @param pClient Context information about the guest VM
262 * @param pv Buffer to which the data was written
263 * @param cb The size of the data written
264 * @param u32Format The format of the data written
265 */
266void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv,
267 uint32_t cb, uint32_t u32Format)
268{
269 vboxSvcClipboardLock();
270
271 writeToPasteboard (pClient->pCtx->pasteboard, pv, cb, u32Format);
272
273 vboxSvcClipboardUnlock();
274}
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