VirtualBox

Ignore:
Timestamp:
Nov 6, 2023 3:36:24 PM (15 months ago)
Author:
vboxsync
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/wayland-helper.h

    r100246 r101878  
    11/* $Id$ */
    22/** @file
    3  * Guest Additions - Definitions for Wayland Desktop Environments helpers.
     3 * Guest Additions - Definitions for Wayland helpers.
    44 */
    55
     
    3232#endif
    3333
    34 #include <iprt/cdefs.h>
    35 #include <iprt/err.h>
    36 
     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"
    3741
    3842/** 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. */
    3963typedef enum
    4064{
    41     /** Indicates that helper does not support any functionality (initializer). */
    42     VBOX_WAYLAND_HELPER_CAP_NONE = 0,
    43     /** Indicates that helper supported shared clipboard functionality. */
    44     VBOX_WAYLAND_HELPER_CAP_CLIPBOARD,
    45     /** Indicates that helper supported drag-and-drop functionality. */
    46     VBOX_WAYLAND_HELPER_CAP_DND
    47 } vbox_wayland_helper_cap_t;
     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;
    48137
    49138/**
     
    61150     * which is compatible with the helper.
    62151     *
    63      * @returns Helpercapabilities bitmask as described by vbox_wayland_helper_cap_t.
     152     * @returns Helpercapabilities bitmask as described by VBOX_WAYLAND_HELPER_CAP_XXX.
    64153     */
    65154    DECLCALLBACKMEMBER(int, pfnProbe, (void));
     
    79168    DECLCALLBACKMEMBER(int, pfnTerm, (void));
    80169
     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
    81187} 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);
    82361
    83362/** Wayland helper which uses GTK library. */
Note: See TracChangeset for help on using the changeset viewer.

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