VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/VBoxClient/wayland-helper.h@ 101878

Last change on this file since 101878 was 101878, checked in by vboxsync, 13 months ago

Additions: X11/Wayland: Add initial support for clipboard sharing with Gnome and Plasma Wayland guests (not yet enabled), bugref:10194.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 11.7 KB
Line 
1/* $Id: wayland-helper.h 101878 2023-11-06 15:36:24Z vboxsync $ */
2/** @file
3 * Guest Additions - Definitions for Wayland helpers.
4 */
5
6/*
7 * Copyright (C) 2006-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#ifndef GA_INCLUDED_SRC_x11_VBoxClient_wayland_helper_h
29#define GA_INCLUDED_SRC_x11_VBoxClient_wayland_helper_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <iprt/asm.h>
35#include <iprt/time.h>
36
37#include <VBox/VBoxGuestLib.h>
38#include <VBox/GuestHost/clipboard-helper.h>
39
40#include "clipboard.h"
41
42/** Helper capabilities list. */
43
44/** Indicates that helper does not support any functionality (initializer). */
45#define VBOX_WAYLAND_HELPER_CAP_NONE (0)
46/** Indicates that helper supported shared clipboard functionality. */
47#define VBOX_WAYLAND_HELPER_CAP_CLIPBOARD RT_BIT(1)
48/** Indicates that helper supported drag-and-drop functionality. */
49#define VBOX_WAYLAND_HELPER_CAP_DND RT_BIT(2)
50
51/** Default time interval to wait for value to arrive over IPC. */
52#define VBCL_WAYLAND_VALUE_WAIT_TIMEOUT_MS (1000)
53/** Default time interval to wait for clipboard content to arrive over IPC. */
54#define VBCL_WAYLAND_DATA_WAIT_TIMEOUT_MS (2000)
55/** Generic relax interval while polling value changes. */
56#define VBCL_WAYLAND_RELAX_INTERVAL_MS (50)
57/** Maximum number of participants who can join session. */
58#define VBCL_WAYLAND_SESSION_USERS_MAX (10)
59/** Value which determines if session structure was initialized. */
60#define VBCL_WAYLAND_SESSION_MAGIC (0xDEADBEEF)
61
62/** Session states. */
63typedef enum
64{
65 /** Session is not active. */
66 VBCL_WL_SESSION_STATE_IDLE,
67 /** Session is being initialized. */
68 VBCL_WL_SESSION_STATE_STARTING,
69 /** Session has started and now can be joined. */
70 VBCL_WL_SESSION_STATE_STARTED,
71 /** Session is terminating. */
72 VBCL_WL_SESSION_STATE_TERMINATING
73} vbcl_wl_session_state_t;
74
75/** Session type.
76 *
77 * Type determines the purpose of session. It is
78 * also serves a sanity check purpose when different
79 * participants join session with certain intention.
80 * Session type can only be set when session is
81 * in STARTING state and reset when session is TERMINATING.
82 */
83typedef enum
84{
85 /** Initializer. */
86 VBCL_WL_SESSION_TYPE_INVALID,
87 /** Copy clipboard data to the guest. */
88 VBCL_WL_CLIPBOARD_SESSION_TYPE_COPY_TO_GUEST,
89 /** Announce clipboard formats to the host. */
90 VBCL_WL_CLIPBOARD_SESSION_TYPE_ANNOUNCE_TO_HOST,
91 /** Copy clipboard data to the host. */
92 VBCL_WL_CLIPBOARD_SESSION_TYPE_COPY_TO_HOST,
93} vbcl_wl_session_type_t;
94
95/** Session private data. */
96typedef struct
97{
98 /** Magic number which indicates if session
99 * was previously initialized. */
100 volatile uint32_t u32Magic;
101
102 /** Session state, synchronization element. */
103 volatile vbcl_wl_session_state_t enmState;
104
105 /** Session type. */
106 vbcl_wl_session_type_t enmType;
107
108 /** Session description, used for logging purpose
109 * to distinguish between operations flow. */
110 const char *pcszDesc;
111
112 /** Current number of session users. When session
113 * switches into TERMINATING state, it will wait
114 * number of participants to drop to 1 before releasing
115 * session resources and resetting internal data to
116 * default values. */
117 volatile uint32_t cUsers;
118} vbcl_wl_session_t;
119
120/** Session state change callback.
121 *
122 * Data which belongs to a session must be accessed from
123 * session callback only. It ensures session data integrity
124 * and prevents access to data when session is not yet
125 * initialized or already terminated.
126 *
127 * @returns IPRT status code.
128 * @param enmSessionType Session type, provided for consistency
129 * check to make sure given callback is
130 * intended to be triggered in context of
131 * given session type.
132 * @param pvUser Optional user data.
133 */
134typedef DECLCALLBACKTYPE(int, FNVBCLWLSESSIONCB, (vbcl_wl_session_type_t enmSessionType, void *pvUser));
135/** Pointer to FNVBCLWLSESSIONCB. */
136typedef FNVBCLWLSESSIONCB *PFNVBCLWLSESSIONCB;
137
138/**
139 * Wayland Desktop Environment helper definition structure.
140 */
141typedef struct
142{
143 /** A short helper name. 16 chars maximum (RTTHREAD_NAME_LEN). */
144 const char *pszName;
145
146 /**
147 * Probing callback.
148 *
149 * Called in attempt to detect if user is currently running Desktop Environment
150 * which is compatible with the helper.
151 *
152 * @returns Helpercapabilities bitmask as described by VBOX_WAYLAND_HELPER_CAP_XXX.
153 */
154 DECLCALLBACKMEMBER(int, pfnProbe, (void));
155
156 /**
157 * Initialization callback.
158 *
159 * @returns IPRT status code.
160 */
161 DECLCALLBACKMEMBER(int, pfnInit, (void));
162
163 /**
164 * Termination callback.
165 *
166 * @returns IPRT status code.
167 */
168 DECLCALLBACKMEMBER(int, pfnTerm, (void));
169
170 /**
171 * Callback to set host clipboard connection handle.
172 *
173 * @param pCtx Host service connection context.
174 */
175 DECLCALLBACKMEMBER(void, pfnSetClipboardCtx, (PVBGLR3SHCLCMDCTX pCtx));
176
177 /**
178 * Callback to force guest to announce its clipboard content.
179 *
180 * @returns IPRT status code.
181 */
182 DECLCALLBACKMEMBER(int, pfnPopup, (void));
183
184 PFNHOSTCLIPREPORTFMTS pfnHGClipReport;
185 PFNHOSTCLIPREAD pfnGHClipRead;
186
187} VBCLWAYLANDHELPER;
188
189namespace vbcl
190{
191 /**
192 * This is abstract one-shot data type which can be set by writer and waited
193 * by reader in a thread-safe way.
194 *
195 * Method wait() will wait within predefined interval of time until
196 * value of this type will be changed to anything different from default
197 * value which is defined during initialization. Reader must compare
198 * returned value with what defaults() method returns in order to make
199 * sure that value was actually set by writer.
200 *
201 * Method reset() will atomically reset current value to defaults and
202 * return previous value. This is useful when writer has previously
203 * dynamically allocated chunk of memory and reader needs to deallocete
204 * it in the end.
205 */
206 template <class T> class Waitable
207 {
208 public:
209
210 Waitable()
211 {};
212
213 /**
214 * Initialize data type.
215 *
216 * @param default_value Default value, used while
217 * waiting for value change.
218 * @param timeoutMs Time interval to wait for
219 * value change before returning.
220 */
221 void init(T default_value, uint64_t timeoutMs)
222 {
223 m_Value = default_value;
224 m_Default = default_value;
225 m_TimeoutMs = timeoutMs;
226 }
227
228 /**
229 * Atomically set value.
230 *
231 * @param value Value to set.
232 */
233 void set(T value)
234 {
235 ASMAtomicWriteU64(&m_Value, value);
236 }
237
238 /**
239 * Atomically reset value to defaults and return previous value.
240 *
241 * @returns Value which was assigned before reset.
242 */
243 uint64_t reset()
244 {
245 return ASMAtomicXchgU64(&m_Value, m_Default);
246 }
247
248 /**
249 * Wait until value will be changed from defaults and return it.
250 *
251 * @returns Current value.
252 */
253 T wait()
254 {
255 uint64_t tsStart = RTTimeMilliTS();
256
257 while( (RTTimeMilliTS() - tsStart) < m_TimeoutMs
258 && (ASMAtomicReadU64(&m_Value)) == m_Default)
259 {
260 RTThreadSleep(VBCL_WAYLAND_RELAX_INTERVAL_MS);
261 }
262
263 return m_Value;
264 }
265
266 /**
267 * Get default value which was set during initialization.
268 *
269 * @returns Default value.
270 */
271 T defaults()
272 {
273 return m_Default;
274 }
275
276 protected:
277
278 /** Value itself. */
279 uint64_t m_Value;
280 /** Default value. */
281 uint64_t m_Default;
282 /** Value change waiting timeout. */
283 uint64_t m_TimeoutMs;
284 };
285}
286
287/**
288 * Initialize session.
289 *
290 * This function should be called only once, during initialization step.
291 *
292 * @param pSession A pointer to session data.
293 */
294RTDECL(void) vbcl_wayland_session_init(vbcl_wl_session_t *pSession);
295
296/**
297 * Start new session.
298 *
299 * Attempt to change session state from IDLE to STARTED and
300 * execute initialization callback in between. If current
301 * session state is different from IDLE, state transition will
302 * not be possible and error will be returned.
303 *
304 * @returns IPRT status code.
305 * @param pSession Session object.
306 * @param enmType Session type.
307 * @param pfnStart Initialization callback.
308 * @param pvUser User data to pass to initialization callback.
309 */
310RTDECL(int) vbcl_wayland_session_start(vbcl_wl_session_t *pSession,
311 vbcl_wl_session_type_t enmType,
312 PFNVBCLWLSESSIONCB pfnStart,
313 void *pvUser);
314
315/**
316 * Join session.
317 *
318 * Attempt to grab a reference to a session, execute provided
319 * callback while holding a reference and release reference.
320 * This function will fail if current session state is different
321 * from STARTED.
322 *
323 * @returns IPRT status code.
324 * @param pSession Session object.
325 * @param pfnJoin A callback to run while holding session reference.
326 * @param pvUser User data to pass to callback.
327 * @param pcszCallee Text tag which corresponds to calling function (only
328 * for logging)
329 */
330RTDECL(int) vbcl_wayland_session_join_ex(vbcl_wl_session_t *pSession,
331 PFNVBCLWLSESSIONCB pfnJoin, void *pvUser,
332 const char *pcszCallee);
333
334/**
335 * Join session (wrapper for vbcl_wayland_session_join_ex).
336 */
337#define vbcl_wayland_session_join(pSession, pfnJoin, pvUser) \
338 vbcl_wayland_session_join_ex(pSession, pfnJoin, pvUser, __func__)
339
340/**
341 * End session.
342 *
343 * Attempt to wait until session is no longer in use, execute
344 * terminating callback and reset session to IDLE state.
345 *
346 * @returns IPRT status code.
347 * @param pSession Session object.
348 * @param pfnEnd Termination callback.
349 * @param pvUser User data to pass to termination callback.
350 */
351RTDECL(int) vbcl_wayland_session_end(vbcl_wl_session_t *pSession,
352 PFNVBCLWLSESSIONCB pfnEnd, void *pvUser);
353
354/**
355 * Check if session was started.
356 *
357 * @returns True if session is started, False otherwise.
358 * @param pSession Session object.
359 */
360RTDECL(bool) vbcl_wayland_session_is_started(vbcl_wl_session_t *pSession);
361
362/** Wayland helper which uses GTK library. */
363extern const VBCLWAYLANDHELPER g_WaylandHelperGtk;
364/** Wayland helper which uses Data Control Protocol. */
365extern const VBCLWAYLANDHELPER g_WaylandHelperDcp;
366
367#endif /* !GA_INCLUDED_SRC_x11_VBoxClient_wayland_helper_h */
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