VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/clipboard-common.cpp@ 103363

Last change on this file since 103363 was 103363, checked in by vboxsync, 14 months ago

Shared Clipboard: Added a dedicated VERR_SHCLPB_NO_DATA error code, to indicate that clipboard data for a format currently is not available.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 5.3 KB
Line 
1/** $Id: clipboard-common.cpp 103363 2024-02-14 17:23:47Z vboxsync $ */
2/** @file
3 * Guest Additions - Shared Clipboard common code.
4 */
5
6/*
7 * Copyright (C) 2007-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
32
33#ifdef LOG_GROUP
34# undef LOG_GROUP
35#endif
36#define LOG_GROUP LOG_GROUP_SHARED_CLIPBOARD
37#include <iprt/log.h>
38#include <iprt/mem.h>
39#include <iprt/err.h>
40
41#include "VBoxClient.h"
42#include "clipboard.h"
43
44RTDECL(int) VBClClipboardThreadStart(PRTTHREAD pThread, PFNRTTHREAD pfnThread, const char *pszName, void *pvUser)
45{
46 int rc;
47
48 rc = RTThreadCreate(pThread, pfnThread, pvUser, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, pszName);
49 if (RT_SUCCESS(rc))
50 rc = RTThreadUserWait(*pThread, RT_MS_30SEC /* msTimeout */);
51
52 if (RT_SUCCESS(rc))
53 VBClLogVerbose(1, "started %s thread\n", pszName);
54 else
55 LogRel(("unable to start %s thread, rc=%Rrc\n", pszName, rc));
56
57 return rc;
58}
59
60RTDECL(int) VBClClipboardReadHostEvent(PSHCLCONTEXT pCtx, const PFNHOSTCLIPREPORTFMTS pfnHGClipReport,
61 const PFNHOSTCLIPREAD pfnGHClipRead)
62{
63 int rc;
64
65 uint32_t idMsg = 0;
66 uint32_t cParms = 0;
67
68 AssertPtrReturn(pfnHGClipReport, VERR_INVALID_PARAMETER);
69 AssertPtrReturn(pfnGHClipRead, VERR_INVALID_PARAMETER);
70
71 PVBGLR3CLIPBOARDEVENT pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
72 AssertPtrReturn(pEvent, VERR_NO_MEMORY);
73
74 rc = VbglR3ClipboardMsgPeekWait(&pCtx->CmdCtx, &idMsg, &cParms, NULL /* pidRestoreCheck */);
75 if (RT_SUCCESS(rc))
76 rc = VbglR3ClipboardEventGetNext(idMsg, cParms, &pCtx->CmdCtx, pEvent);
77
78 if (RT_SUCCESS(rc))
79 {
80 switch (pEvent->enmType)
81 {
82 /* Host reports new clipboard data is now available. */
83 case VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS:
84 {
85 rc = pfnHGClipReport(pEvent->u.fReportedFormats);
86 break;
87 }
88
89 /* Host wants to read data from guest clipboard. */
90 case VBGLR3CLIPBOARDEVENTTYPE_READ_DATA:
91 {
92 rc = pfnGHClipRead(pEvent->u.fReadData);
93 break;
94 }
95
96 default:
97 {
98 AssertMsgFailedBreakStmt(("Event type %RU32 not implemented\n", pEvent->enmType), rc = VERR_NOT_SUPPORTED);
99 }
100 }
101 }
102 else
103 LogFlowFunc(("Getting next event failed with %Rrc\n", rc));
104
105 VbglR3ClipboardEventFree(pEvent);
106
107 LogFlowFuncLeaveRC(rc);
108 return rc;
109}
110
111/**
112 * Reads clipboard from the host.
113 *
114 * @returns VBox status code.
115 * @retval VERR_SHCLPB_NO_DATA if no clipboard data is available.
116 * @param pCtx Shared Clipbaord context to use.
117 * @param uFmt The format to read clipboard data in.
118 * @param ppv Where to return the allocated data read.
119 * Must be free'd by the caller.
120 * @param pcb Where to return number of bytes read.
121 */
122RTDECL(int) VBClClipboardReadHostClipboard(PVBGLR3SHCLCMDCTX pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb)
123{
124 int rc;
125
126 uint32_t cbRead = 0;
127 uint32_t cbData = _4K;
128
129 void *pvData;
130
131 pvData = RTMemAllocZ(cbData);
132 if (pvData)
133 {
134 rc = VbglR3ClipboardReadDataEx(pCtx, uFmt, pvData, cbData, &cbRead);
135
136 /*
137 * A return value of VINF_BUFFER_OVERFLOW tells us to try again with a
138 * larger buffer. The size of the buffer needed is placed in *pcb.
139 * So we start all over again.
140 */
141 if (rc == VINF_BUFFER_OVERFLOW)
142 {
143 /* cbRead contains the size required. */
144 pvData = RTMemReallocZ(pvData, cbData, cbRead);
145 cbData = cbRead;
146 if (pvData)
147 {
148 rc = VbglR3ClipboardReadDataEx(pCtx, uFmt, pvData, cbData, &cbRead);
149 if (rc == VINF_BUFFER_OVERFLOW)
150 rc = VERR_BUFFER_OVERFLOW;
151 }
152 else
153 rc = VERR_NO_MEMORY;
154 }
155
156 if (RT_SUCCESS(rc))
157 {
158 *pcb = cbRead; /* Actual bytes read. */
159 *ppv = pvData;
160 }
161 }
162 else
163 rc = VERR_NO_MEMORY;
164
165 if (!cbRead)
166 rc = VERR_SHCLPB_NO_DATA;
167
168 if (RT_FAILURE(rc))
169 RTMemFree(pvData);
170
171 return rc;
172}
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