Index: /trunk/src/VBox/Additions/x11/VBoxClient/wayland-helper-gtk.cpp
===================================================================
--- /trunk/src/VBox/Additions/x11/VBoxClient/wayland-helper-gtk.cpp	(revision 106806)
+++ /trunk/src/VBox/Additions/x11/VBoxClient/wayland-helper-gtk.cpp	(revision 106807)
@@ -85,6 +85,25 @@
 } vbox_wl_gtk_ctx_t;
 
+/** Private data for a callback when host reports clipboard formats. */
+struct vbcl_wayland_hlp_gtk_clip_hg_report_priv
+{
+    /** Helper context. */
+    vbox_wl_gtk_ctx_t *pCtx;
+    /** Clipboard formats. */
+    SHCLFORMATS fFormats;
+};
+
+/** Private data for a callback when host requests clipboard
+ *  data in specified format. */
+struct vbcl_wayland_hlp_gtk_clip_gh_read_priv
+{
+    /** Helper context. */
+    vbox_wl_gtk_ctx_t *pCtx;
+    /** Clipboard format. */
+    SHCLFORMAT uFormat;
+};
+
 /** Helper context. */
-static vbox_wl_gtk_ctx_t g_GtkCtx;
+static vbox_wl_gtk_ctx_t g_GtkClipCtx;
 
 /**
@@ -205,14 +224,17 @@
  * @returns IPRT status code.
  * @param   enmSessionType      Session type (unused).
- * @param   pvUser              User data (unused).
+ * @param   pvUser              User data.
  */
 static DECLCALLBACK(int) vbcl_wayland_hlp_gtk_session_start_generic_cb(
     vbcl_wl_session_type_t enmSessionType, void *pvUser)
 {
-    RT_NOREF(enmSessionType, pvUser);
-
-    VBCL_LOG_CALLBACK;
-
-    return vbcl_wayland_hlp_gtk_session_prepare(&g_GtkCtx.Session);
+    VBCL_LOG_CALLBACK;
+
+    vbox_wl_gtk_ctx_t *pCtx = (vbox_wl_gtk_ctx_t *)pvUser;
+    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
+
+    RT_NOREF(enmSessionType);
+
+    return vbcl_wayland_hlp_gtk_session_prepare(&pCtx->Session);
 }
 
@@ -222,5 +244,5 @@
  * @returns IPRT status code.
  * @param   enmSessionType      Session type (unused).
- * @param   pvUser              User data (session to reset).
+ * @param   pvUser              User data.
  */
 static DECLCALLBACK(int) vbcl_wayland_hlp_gtk_session_end_cb(
@@ -269,6 +291,6 @@
     vbcl_wl_session_type_t enmSessionType, void *pvUser)
 {
-    PRTLOCALIPCSESSION phIpcSession = (RTLOCALIPCSESSION *)pvUser;
-    AssertPtrReturn(phIpcSession, VERR_INVALID_PARAMETER);
+    vbox_wl_gtk_ctx_t *pCtx = (vbox_wl_gtk_ctx_t *)pvUser;
+    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
 
     const vbcl::ipc::flow_t *pFlow;
@@ -279,5 +301,5 @@
 
     /* Make sure valid session is in progress. */
-    AssertReturn(g_GtkCtx.Session.uSessionId > 0, VERR_INVALID_PARAMETER);
+    AssertReturn(pCtx->Session.uSessionId > 0, VERR_INVALID_PARAMETER);
 
     /* Select corresponding IPC flow depending on session type. */
@@ -296,5 +318,5 @@
     /* Proceed with selected flow. */
     if (RT_VALID_PTR(pFlow))
-        rc = g_GtkCtx.Session.oDataIpc->flow(pFlow, *phIpcSession);
+        rc = pCtx->Session.oDataIpc->flow(pFlow, pCtx->Session.hIpcSession);
 
     return rc;
@@ -335,7 +357,5 @@
         while (!ASMAtomicReadBool(&pCtx->fShutdown))
         {
-            RTLOCALIPCSESSION hClientSession;
-
-            rc = RTLocalIpcServerListen(pCtx->hIpcServer, &hClientSession);
+            rc = RTLocalIpcServerListen(pCtx->hIpcServer, &pCtx->Session.hIpcSession);
             if (RT_SUCCESS(rc))
             {
@@ -344,5 +364,5 @@
                 /* Authenticate remote user. Only allow connection from
                  * process who belongs to the same UID. */
-                rc = RTLocalIpcSessionQueryUserId(hClientSession, &uUid);
+                rc = RTLocalIpcSessionQueryUserId(pCtx->Session.hIpcSession, &uUid);
                 if (RT_SUCCESS(rc))
                 {
@@ -355,5 +375,5 @@
                         rc = vbcl_wayland_session_join(&pCtx->Session.Base,
                                                        &vbcl_wayland_hlp_gtk_worker_join_cb,
-                                                       &hClientSession);
+                                                       pCtx);
 
                         VBClLogVerbose(1, "IPC flow completed, rc=%Rrc\n", rc);
@@ -372,5 +392,5 @@
                     VBClLogError("failed to get remote IPC UID, rc=%Rrc\n", rc);
 
-                RTLocalIpcSessionClose(hClientSession);
+                RTLocalIpcSessionClose(pCtx->Session.hIpcSession);
             }
             else if (rc != VERR_CANCELLED)
@@ -408,7 +428,7 @@
     VBCL_LOG_CALLBACK;
 
-    RT_ZERO(g_GtkCtx);
-
-    return vbcl_wayland_thread_start(&g_GtkCtx.Thread, vbcl_wayland_hlp_gtk_worker, "wl-gtk-ipc", &g_GtkCtx);
+    RT_ZERO(g_GtkClipCtx);
+
+    return vbcl_wayland_thread_start(&g_GtkClipCtx.Thread, vbcl_wayland_hlp_gtk_worker, "wl-gtk-ipc", &g_GtkClipCtx);
 }
 
@@ -420,10 +440,11 @@
     int rc;
     int rcThread = 0;
+    vbox_wl_gtk_ctx_t *pCtx = &g_GtkClipCtx;
 
     /* Set termination flag. */
-    g_GtkCtx.fShutdown = true;
+    pCtx->fShutdown = true;
 
     /* Cancel IPC loop. */
-    rc = RTLocalIpcServerCancel(g_GtkCtx.hIpcServer);
+    rc = RTLocalIpcServerCancel(pCtx->hIpcServer);
     if (RT_FAILURE(rc))
         VBClLogError("unable to notify IPC server about shutdown, rc=%Rrc\n", rc);
@@ -432,5 +453,5 @@
     {
         /* Wait for Gtk event loop thread to shutdown. */
-        rc = RTThreadWait(g_GtkCtx.Thread, RT_MS_30SEC, &rcThread);
+        rc = RTThreadWait(pCtx->Thread, RT_MS_30SEC, &rcThread);
         VBClLogInfo("gtk event thread exited with status, rc=%Rrc\n", rcThread);
     }
@@ -446,5 +467,5 @@
 static DECLCALLBACK(void) vbcl_wayland_hlp_gtk_clip_set_ctx(PVBGLR3SHCLCMDCTX pCtx)
 {
-    g_GtkCtx.pClipboardCtx = pCtx;
+    g_GtkClipCtx.pClipboardCtx = pCtx;
 }
 
@@ -459,5 +480,5 @@
  * @param   enmSessionType      Session type, must be verified as
  *                              a consistency check.
- * @param   pvUser              User data (unused).
+ * @param   pvUser              User data.
  */
 static DECLCALLBACK(int) vbcl_wayland_hlp_gtk_clip_popup_join_cb(
@@ -467,13 +488,14 @@
              ? VINF_SUCCESS : VERR_WRONG_ORDER;
 
-    RT_NOREF(pvUser);
-
-    VBCL_LOG_CALLBACK;
-
-    if (RT_SUCCESS(rc))
-    {
-        SHCLFORMATS fFmts = g_GtkCtx.Session.oDataIpc->m_fFmts.wait();
-        if (fFmts !=  g_GtkCtx.Session.oDataIpc->m_fFmts.defaults())
-            rc = VbglR3ClipboardReportFormats(g_GtkCtx.pClipboardCtx->idClient, fFmts);
+    VBCL_LOG_CALLBACK;
+
+    vbox_wl_gtk_ctx_t *pCtx = (vbox_wl_gtk_ctx_t *)pvUser;
+    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
+
+    if (RT_SUCCESS(rc))
+    {
+        SHCLFORMATS fFmts = pCtx->Session.oDataIpc->m_fFmts.wait();
+        if (fFmts !=  pCtx->Session.oDataIpc->m_fFmts.defaults())
+            rc = VbglR3ClipboardReportFormats(pCtx->pClipboardCtx->idClient, fFmts);
         else
             rc = VERR_TIMEOUT;
@@ -489,16 +511,17 @@
 {
     int rc;
-
-    VBCL_LOG_CALLBACK;
-
-    rc = vbcl_wayland_session_start(&g_GtkCtx.Session.Base,
+    vbox_wl_gtk_ctx_t *pCtx = &g_GtkClipCtx;
+
+    VBCL_LOG_CALLBACK;
+
+    rc = vbcl_wayland_session_start(&pCtx->Session.Base,
                                     VBCL_WL_CLIPBOARD_SESSION_TYPE_ANNOUNCE_TO_HOST,
                                     &vbcl_wayland_hlp_gtk_session_start_generic_cb,
-                                    &g_GtkCtx.Session);
-    if (RT_SUCCESS(rc))
-    {
-        rc = vbcl_wayland_session_join(&g_GtkCtx.Session.Base,
+                                    pCtx);
+    if (RT_SUCCESS(rc))
+    {
+        rc = vbcl_wayland_session_join(&pCtx->Session.Base,
                                        &vbcl_wayland_hlp_gtk_clip_popup_join_cb,
-                                       NULL);
+                                       pCtx);
     }
 
@@ -526,6 +549,7 @@
     vbcl_wl_session_type_t enmSessionType, void *pvUser)
 {
-    SHCLFORMATS *pfFmts = (SHCLFORMATS *)pvUser;
-    AssertPtrReturn(pfFmts, VERR_INVALID_PARAMETER);
+    struct vbcl_wayland_hlp_gtk_clip_hg_report_priv *pPriv =
+        (struct vbcl_wayland_hlp_gtk_clip_hg_report_priv *)pvUser;
+    AssertPtrReturn(pPriv, VERR_INVALID_POINTER);
 
     SHCLFORMAT uFmt;
@@ -538,17 +562,17 @@
     if (RT_SUCCESS(rc))
     {
-        g_GtkCtx.Session.oDataIpc->m_fFmts.set(*pfFmts);
-
-        uFmt = g_GtkCtx.Session.oDataIpc->m_uFmt.wait();
-        if (uFmt != g_GtkCtx.Session.oDataIpc->m_uFmt.defaults())
+        pPriv->pCtx->Session.oDataIpc->m_fFmts.set(pPriv->fFormats);
+
+        uFmt = pPriv->pCtx->Session.oDataIpc->m_uFmt.wait();
+        if (uFmt != pPriv->pCtx->Session.oDataIpc->m_uFmt.defaults())
         {
             void *pvData;
             uint32_t cbData;
 
-            rc = VBClClipboardReadHostClipboard(g_GtkCtx.pClipboardCtx, uFmt, &pvData, &cbData);
+            rc = VBClClipboardReadHostClipboard(pPriv->pCtx->pClipboardCtx, uFmt, &pvData, &cbData);
             if (RT_SUCCESS(rc))
             {
-                g_GtkCtx.Session.oDataIpc->m_pvDataBuf.set((uint64_t)pvData);
-                g_GtkCtx.Session.oDataIpc->m_cbDataBuf.set((uint64_t)cbData);
+                pPriv->pCtx->Session.oDataIpc->m_pvDataBuf.set((uint64_t)pvData);
+                pPriv->pCtx->Session.oDataIpc->m_cbDataBuf.set((uint64_t)cbData);
             }
         }
@@ -566,4 +590,5 @@
 {
     int rc = VERR_NO_DATA;
+    vbox_wl_gtk_ctx_t *pCtx = &g_GtkClipCtx;
 
     VBCL_LOG_CALLBACK;
@@ -571,13 +596,15 @@
     if (fFormats != VBOX_SHCL_FMT_NONE)
     {
-        rc = vbcl_wayland_session_start(&g_GtkCtx.Session.Base,
+        rc = vbcl_wayland_session_start(&pCtx->Session.Base,
                                         VBCL_WL_CLIPBOARD_SESSION_TYPE_COPY_TO_GUEST,
                                         &vbcl_wayland_hlp_gtk_session_start_generic_cb,
-                                        &g_GtkCtx.Session);
+                                        pCtx);
         if (RT_SUCCESS(rc))
         {
-            rc = vbcl_wayland_session_join(&g_GtkCtx.Session.Base,
+            struct vbcl_wayland_hlp_gtk_clip_hg_report_priv priv = { pCtx, fFormats };
+
+            rc = vbcl_wayland_session_join(&pCtx->Session.Base,
                                            &vbcl_wayland_hlp_gtk_clip_hg_report_join_cb,
-                                           &fFormats);
+                                           &priv);
         }
     }
@@ -605,6 +632,7 @@
     vbcl_wl_session_type_t enmSessionType, void *pvUser)
 {
-    SHCLFORMAT *puFmt = (SHCLFORMAT *)pvUser;
-    AssertPtrReturn(puFmt, VERR_INVALID_PARAMETER);
+    struct vbcl_wayland_hlp_gtk_clip_gh_read_priv *pPriv =
+        (struct vbcl_wayland_hlp_gtk_clip_gh_read_priv *)pvUser;
+    AssertPtrReturn(pPriv, VERR_INVALID_POINTER);
 
     int rc = (   enmSessionType == VBCL_WL_CLIPBOARD_SESSION_TYPE_COPY_TO_HOST
@@ -620,14 +648,14 @@
 
         /* Store requested clipboard format to the session. */
-        g_GtkCtx.Session.oDataIpc->m_uFmt.set(*puFmt);
+        pPriv->pCtx->Session.oDataIpc->m_uFmt.set(pPriv->uFormat);
 
         /* Wait for data in requested format. */
-        pvData = (void *)g_GtkCtx.Session.oDataIpc->m_pvDataBuf.wait();
-        cbData = g_GtkCtx.Session.oDataIpc->m_cbDataBuf.wait();
-        if (   cbData != g_GtkCtx.Session.oDataIpc->m_cbDataBuf.defaults()
-            && pvData != (void *)g_GtkCtx.Session.oDataIpc->m_pvDataBuf.defaults())
+        pvData = (void *)pPriv->pCtx->Session.oDataIpc->m_pvDataBuf.wait();
+        cbData = pPriv->pCtx->Session.oDataIpc->m_cbDataBuf.wait();
+        if (   cbData != pPriv->pCtx->Session.oDataIpc->m_cbDataBuf.defaults()
+            && pvData != (void *)pPriv->pCtx->Session.oDataIpc->m_pvDataBuf.defaults())
         {
             /* Send clipboard data to the host. */
-            rc = VbglR3ClipboardWriteDataEx(g_GtkCtx.pClipboardCtx, *puFmt, pvData, cbData);
+            rc = VbglR3ClipboardWriteDataEx(pPriv->pCtx->pClipboardCtx, pPriv->uFormat, pvData, cbData);
         }
         else
@@ -644,4 +672,5 @@
 {
     int rc = VINF_SUCCESS;
+    vbox_wl_gtk_ctx_t *pCtx = &g_GtkClipCtx;
 
     VBCL_LOG_CALLBACK;
@@ -667,17 +696,19 @@
          * vboxwl tool again
          */
-        if (!vbcl_wayland_session_is_started(&g_GtkCtx.Session.Base))
+        if (!vbcl_wayland_session_is_started(&pCtx->Session.Base))
         {
-            rc = vbcl_wayland_session_start(&g_GtkCtx.Session.Base,
+            rc = vbcl_wayland_session_start(&pCtx->Session.Base,
                                             VBCL_WL_CLIPBOARD_SESSION_TYPE_COPY_TO_HOST,
                                             &vbcl_wayland_hlp_gtk_session_start_generic_cb,
-                                            NULL);
+                                            pCtx);
         }
 
         if (RT_SUCCESS(rc))
         {
-            rc = vbcl_wayland_session_join(&g_GtkCtx.Session.Base,
+            struct vbcl_wayland_hlp_gtk_clip_gh_read_priv priv = { pCtx, uFmt };
+
+            rc = vbcl_wayland_session_join(&pCtx->Session.Base,
                                            &vbcl_wayland_hlp_gtk_clip_gh_read_join_cb,
-                                           &uFmt);
+                                           &priv);
         }
     }
