VirtualBox

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

Last change on this file since 7932 was 7249, checked in by vboxsync, 17 years ago

Use the critsect to serialize access to the pastboard so that the polling thread doesn't enter it at the same time as the service thread. Fixed the return code handling around queryNewPasteboardFormats (VERR_NOT_SUPPORTED should not propagate to Connect and Sync, even if returns codes are generally ignored by the service layer). Use pClient instead of the global (/me hates globals).

  • Property eol-style set to native
  • Property svn:keywords set to Date Revision Author Id
File size: 7.4 KB
Line 
1/* $Id: darwin.cpp 7249 2008-03-03 17:50:55Z vboxsync $ */
2/** @file
3 * Shared Clipboard: Mac OS X host.
4 */
5
6/*
7 * Copyright (C) 2008 innotek GmbH
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#include <VBox/HostServices/VBoxClipboardSvc.h>
19
20#include <iprt/assert.h>
21#include <iprt/asm.h>
22#include <iprt/thread.h>
23
24#include "VBoxClipboard.h"
25#include "darwin-pasteboard.h"
26
27/** Global clipboard context information */
28struct _VBOXCLIPBOARDCONTEXT
29{
30 /** We have a separate thread to poll for new clipboard content */
31 RTTHREAD thread;
32 bool volatile fTerminate;
33
34 /** The reference to the current pasteboard */
35 PasteboardRef pasteboard;
36
37 VBOXCLIPBOARDCLIENTDATA *pClient;
38};
39
40/** Only one client is supported. There seems to be no need for more clients. */
41static VBOXCLIPBOARDCONTEXT g_ctx;
42
43
44/**
45 * Checks if something is present on the clipboard and calls vboxSvcClipboardReportMsg.
46 *
47 * @returns IPRT status code (ignored).
48 * @param pCtx The context.
49 */
50static int vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx)
51{
52 if (pCtx->pClient == NULL)
53 return VINF_SUCCESS;
54
55 uint32_t fFormats = 0;
56 bool fChanged = false;
57 /* Retrieve the formats currently in the clipboard and supported by vbox */
58 int rc = queryNewPasteboardFormats (pCtx->pasteboard, &fFormats, &fChanged);
59 if (RT_SUCCESS (rc) && fChanged)
60 {
61 vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, fFormats);
62 Log (("vboxClipboardChanged fFormats %02X\n", fFormats));
63 }
64
65 return rc;
66}
67
68
69/**
70 * The poller thread.
71 *
72 * This thread will check for the arrival of new data on the clipboard.
73 *
74 * @returns VINF_SUCCESS (not used).
75 * @param Thread Our thread handle.
76 * @param pvUser Pointer to the VBOXCLIPBOARDCONTEXT structure.
77 *
78 */
79static int vboxClipboardThread (RTTHREAD ThreadSelf, void *pvUser)
80{
81 Log (("vboxClipboardThread: starting clipboard thread\n"));
82
83 AssertPtrReturn (pvUser, VERR_INVALID_PARAMETER);
84 VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *) pvUser;
85
86 while (!pCtx->fTerminate)
87 {
88 /* call this behind the lock because we don't know if the api is
89 thread safe and in any case we're calling several methods. */
90 vboxSvcClipboardLock();
91 vboxClipboardChanged (pCtx);
92 vboxSvcClipboardUnlock();
93
94 /* Sleep for 200 msecs before next poll */
95 RTThreadUserWait (ThreadSelf, 200);
96 }
97
98 Log (("vboxClipboardThread: clipboard thread terminated successfully with return code %Rrc\n", VINF_SUCCESS));
99 return VINF_SUCCESS;
100}
101
102/*
103 * Public platform dependent functions.
104 */
105
106/** Initialise the host side of the shared clipboard - called by the hgcm layer. */
107int vboxClipboardInit (void)
108{
109 Log (("vboxClipboardInit\n"));
110
111 g_ctx.fTerminate = false;
112
113 int rc = initPasteboard (&g_ctx.pasteboard);
114 AssertRCReturn (rc, rc);
115
116 rc = RTThreadCreate (&g_ctx.thread, vboxClipboardThread, &g_ctx, 0,
117 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
118 if (RT_FAILURE (rc))
119 {
120 g_ctx.thread = NIL_RTTHREAD;
121 destroyPasteboard (&g_ctx.pasteboard);
122 }
123
124 return rc;
125}
126
127/** Terminate the host side of the shared clipboard - called by the hgcm layer. */
128void vboxClipboardDestroy (void)
129{
130 Log (("vboxClipboardDestroy\n"));
131
132 /*
133 * Signal the termination of the polling thread and wait for it to respond.
134 */
135 ASMAtomicWriteBool (&g_ctx.fTerminate, true);
136 int rc = RTThreadUserSignal (g_ctx.thread);
137 AssertRC (rc);
138 rc = RTThreadWait (g_ctx.thread, RT_INDEFINITE_WAIT, NULL);
139 AssertRC (rc);
140
141 /*
142 * Destroy the pasteboard and uninitialize the global context record.
143 */
144 destroyPasteboard (&g_ctx.pasteboard);
145 g_ctx.thread = NIL_RTTHREAD;
146 g_ctx.pClient = NULL;
147}
148
149/**
150 * Enable the shared clipboard - called by the hgcm clipboard subsystem.
151 *
152 * @param pClient Structure containing context information about the guest system
153 * @returns RT status code
154 */
155int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient)
156{
157 if (g_ctx.pClient != NULL)
158 {
159 /* One client only. */
160 return VERR_NOT_SUPPORTED;
161 }
162
163 vboxSvcClipboardLock();
164
165 pClient->pCtx = &g_ctx;
166 pClient->pCtx->pClient = pClient;
167
168 /* Initially sync the host clipboard content with the client. */
169 int rc = vboxClipboardSync (pClient);
170
171 vboxSvcClipboardUnlock();
172 return rc;
173}
174
175/**
176 * Synchronise the contents of the host clipboard with the guest, called by the HGCM layer
177 * after a save and restore of the guest.
178 */
179int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient)
180{
181 /* Sync the host clipboard content with the client. */
182 vboxSvcClipboardLock();
183 int rc = vboxClipboardChanged (pClient->pCtx);
184 vboxSvcClipboardUnlock();
185
186 return rc;
187}
188
189/**
190 * Shut down the shared clipboard subsystem and "disconnect" the guest.
191 */
192void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient)
193{
194 Log (("vboxClipboardDisconnect\n"));
195
196 vboxSvcClipboardLock();
197 pClient->pCtx->pClient = NULL;
198 vboxSvcClipboardUnlock();
199}
200
201/**
202 * The guest is taking possession of the shared clipboard. Called by the HGCM clipboard
203 * subsystem.
204 *
205 * @param pClient Context data for the guest system
206 * @param u32Formats Clipboard formats the the guest is offering
207 */
208void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats)
209{
210 Log (("vboxClipboardFormatAnnounce u32Formats %02X\n", u32Formats));
211 if (u32Formats == 0)
212 {
213 /* This is just an automatism, not a genuine anouncement */
214 return;
215 }
216
217 vboxSvcClipboardReportMsg (pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
218 u32Formats);
219}
220
221/**
222 * Called by the HGCM clipboard subsystem when the guest wants to read the host clipboard.
223 *
224 * @param pClient Context information about the guest VM
225 * @param u32Format The format that the guest would like to receive the data in
226 * @param pv Where to write the data to
227 * @param cb The size of the buffer to write the data to
228 * @param pcbActual Where to write the actual size of the written data
229 */
230int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format,
231 void *pv, uint32_t cb, uint32_t * pcbActual)
232{
233 vboxSvcClipboardLock();
234
235 /* Default to no data available. */
236 *pcbActual = 0;
237 int rc = readFromPasteboard (pClient->pCtx->pasteboard, u32Format, pv, cb, pcbActual);
238
239 vboxSvcClipboardUnlock();
240 return rc;
241}
242
243/**
244 * Called by the HGCM clipboard subsystem when we have requested data and that data arrives.
245 *
246 * @param pClient Context information about the guest VM
247 * @param pv Buffer to which the data was written
248 * @param cb The size of the data written
249 * @param u32Format The format of the data written
250 */
251void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv,
252 uint32_t cb, uint32_t u32Format)
253{
254 vboxSvcClipboardLock();
255
256 writeToPasteboard (pClient->pCtx->pasteboard, pv, cb, u32Format);
257
258 vboxSvcClipboardUnlock();
259}
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