VirtualBox

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

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

r=bird: some missing docs, fixed incorrect cleanup order and made cleanup a little bit faster (user sem, not sleep).

  • 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 7162 2008-02-27 02:28:43Z 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/thread.h>
22
23#include "VBoxClipboard.h"
24/* We do the work in a separate cpp file because
25 * of the conflicting typedef "OSType". This is
26 * defined in Carbon and in VBox/ostypes.h also. */
27#include "darwin-pasteboard.h"
28
29/** Global clipboard context information */
30struct _VBOXCLIPBOARDCONTEXT
31{
32 /** We have a separate thread to poll for new clipboard content */
33 RTTHREAD thread;
34 bool volatile fTerminate;
35
36 /** The reference to the current pasteboard */
37 PasteboardRef pasteboard;
38
39 VBOXCLIPBOARDCLIENTDATA *pClient;
40};
41
42/** Only one client is supported. There seems to be no need for more clients. */
43static VBOXCLIPBOARDCONTEXT g_ctx;
44
45
46/**
47 * Checks if something is present on the clipboard and calls vboxSvcClipboardReportMsg.
48 *
49 * @returns IPRT status code (ignored).
50 * @param pCtx The context.
51 *
52 * @todo r=bird: This function does not check if something has _changed_ like indicated by
53 * the name. It will instead notify the client every 200ms as long as something
54 * is on the clipboard. When the clipboard is cleared it will do nothing.
55 * I somehow cannot think that this intentional behavior...
56 */
57static int vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx)
58{
59 if (pCtx->pClient == NULL)
60 return VINF_SUCCESS;
61
62 uint32_t fFormats = 0;
63 /* Retrieve the formats currently in the clipboard and supported by vbox */
64 int rc = queryPasteboardFormats (pCtx->pasteboard, &fFormats);
65
66 if (fFormats > 0)
67 {
68 vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, fFormats);
69 Log (("vboxClipboardChanged fFormats %02X\n", fFormats));
70 }
71
72 return rc;
73}
74
75
76/**
77 * The poller thread.
78 *
79 * This thread will check for the arrival of new data on the clipboard.
80 *
81 * @returns VINF_SUCCESS (not used).
82 * @param Thread Our thread handle.
83 * @param pvUser Pointer to the VBOXCLIPBOARDCONTEXT structure.
84 *
85 */
86static int vboxClipboardThread (RTTHREAD ThreadSelf, void *pvUser)
87{
88 Log (("vboxClipboardThread: starting clipboard thread\n"));
89
90 AssertPtrReturn (pvUser, VERR_INVALID_PARAMETER);
91 VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *) pvUser;
92
93 while (!pCtx->fTerminate)
94 {
95 vboxClipboardChanged (pCtx);
96 /* Sleep for 200 msecs before next poll */
97 RTThreadUserWait (self, 200);
98 }
99
100 Log (("vboxClipboardThread: clipboard thread terminated successfully with return code %Rrc\n", VINF_SUCCESS));
101 return VINF_SUCCESS;
102}
103
104/*
105 * Public platform dependent functions.
106 */
107
108/** Initialise the host side of the shared clipboard - called by the hgcm layer. */
109int vboxClipboardInit (void)
110{
111 Log (("vboxClipboardInit\n"));
112
113 g_ctx.fTerminate = false;
114
115 int rc = initPasteboard (&g_ctx.pasteboard);
116 AssertRCReturn (rc, rc);
117
118 rc = RTThreadCreate (&g_ctx.thread, vboxClipboardThread, &g_ctx, 0,
119 RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
120 if (RT_FAILURE (rc))
121 {
122 g_ctx.thread = NIL_RTTHREAD;
123 destroyPasteboard (&g_ctx.pasteboard);
124 }
125
126 return rc;
127}
128
129/** Terminate the host side of the shared clipboard - called by the hgcm layer. */
130void vboxClipboardDestroy (void)
131{
132 Log (("vboxClipboardDestroy\n"));
133
134 /*
135 * Signal the termination of the polling thread and wait for it to respond.
136 */
137 ASMAtomicWriteBool (&g_ctx.fTerminate, true);
138 int rc = RTThreadUserSignal (g_ctx.thread);
139 AssertRC (rc);
140 rc = RTThreadWait (g_ctx.thread, RT_INDEFINITE_WAIT, NULL);
141 AssertRC (rc);
142
143 /*
144 * Destroy the pasteboard and uninitialize the global context record.
145 */
146 destroyPasteboard (&g_ctx.pasteboard);
147 g_ctx.thread = NIL_RTTHREAD;
148 g_ctx.pClient = NULL;
149}
150
151/**
152 * Enable the shared clipboard - called by the hgcm clipboard subsystem.
153 *
154 * @param pClient Structure containing context information about the guest system
155 * @returns RT status code
156 */
157int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient)
158{
159 if (g_ctx.pClient != NULL)
160 {
161 /* One client only. */
162 return VERR_NOT_SUPPORTED;
163 }
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 return rc;
172}
173
174/**
175 * Synchronise the contents of the host clipboard with the guest, called by the HGCM layer
176 * after a save and restore of the guest.
177 */
178int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient)
179{
180 /* Sync the host clipboard content with the client. */
181 int rc = vboxClipboardChanged (pClient->pCtx);
182
183 return rc;
184}
185
186/**
187 * Shut down the shared clipboard subsystem and "disconnect" the guest.
188 */
189void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA * /* pClient */)
190{
191 Log (("vboxClipboardDisconnect\n"));
192
193 g_ctx.pClient = NULL;
194}
195
196/**
197 * The guest is taking possession of the shared clipboard. Called by the HGCM clipboard
198 * subsystem.
199 *
200 * @param pClient Context data for the guest system
201 * @param u32Formats Clipboard formats the the guest is offering
202 */
203void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA * /* pClient */,
204 uint32_t u32Formats)
205{
206 Log (("vboxClipboardFormatAnnounce u32Formats %02X\n", u32Formats));
207 if (u32Formats == 0)
208 {
209 /* This is just an automatism, not a genuine anouncement */
210 return;
211 }
212
213 vboxSvcClipboardReportMsg (g_ctx.pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
214 u32Formats);
215}
216
217/**
218 * Called by the HGCM clipboard subsystem when the guest wants to read the host clipboard.
219 *
220 * @param pClient Context information about the guest VM
221 * @param u32Format The format that the guest would like to receive the data in
222 * @param pv Where to write the data to
223 * @param cb The size of the buffer to write the data to
224 * @param pcbActual Where to write the actual size of the written data
225 */
226int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA * /* pClient */, uint32_t u32Format,
227 void *pv, uint32_t cb, uint32_t * pcbActual)
228{
229 /* Default to no data available. */
230 *pcbActual = 0;
231 int rc = readFromPasteboard (g_ctx.pasteboard, u32Format, pv, cb, pcbActual);
232
233 return rc;
234}
235
236/**
237 * Called by the HGCM clipboard subsystem when we have requested data and that data arrives.
238 *
239 * @param pClient Context information about the guest VM
240 * @param pv Buffer to which the data was written
241 * @param cb The size of the data written
242 * @param u32Format The format of the data written
243 */
244void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA * /* pClient */, void *pv,
245 uint32_t cb, uint32_t u32Format)
246{
247 writeToPasteboard (g_ctx.pasteboard, pv, cb, u32Format);
248}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette