VirtualBox

Changeset 99590 in vbox


Ignore:
Timestamp:
May 3, 2023 3:59:12 PM (19 months ago)
Author:
vboxsync
Message:

Guest Additions/VBoxClient: Moved the X11-specific code for Shared Clipboard into an own submodule and using the actual service as a (runtime) wrapper (for also the Wayland-specific code later). bugref:10427

Location:
trunk/src/VBox/Additions/x11/VBoxClient
Files:
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk

    r99586 r99590  
    175175        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \
    176176        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp \
    177         clipboard.cpp
     177        clipboard.cpp \
     178        clipboard-x11.cpp
    178179 ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    179180  VBoxClient_DEFS    += VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS VBOX_WITH_SHARED_CLIPBOARD_GUEST
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard-x11.cpp

    r99586 r99590  
    11/** $Id$ */
    22/** @file
    3  * Guest Additions - X11 Shared Clipboard.
     3 * Guest Additions - X11 Shared Clipboard implementation.
    44 */
    55
     
    5151
    5252
    53 /*********************************************************************************************************************************
    54 *   Global Variables                                                                                                             *
    55 *********************************************************************************************************************************/
    56 
    57 /** Only one context is supported at a time for now. */
    58 SHCLCONTEXT g_Ctx;
    59 
    60 
    61 static DECLCALLBACK(int) vbclOnRequestDataFromSourceCallback(PSHCLCONTEXT pCtx,
    62                                                              SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser)
     53static DECLCALLBACK(int) vbclX11OnRequestDataFromSourceCallback(PSHCLCONTEXT pCtx,
     54                                                                SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser)
    6355{
    6456    RT_NOREF(pvUser);
     
    147139};
    148140
    149 static DECLCALLBACK(int) vbclReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats, void *pvUser)
     141static DECLCALLBACK(int) vbclX11ReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats, void *pvUser)
    150142{
    151143    RT_NOREF(pvUser);
     
    159151}
    160152
    161 static DECLCALLBACK(int) vbclOnSendDataToDestCallback(PSHCLCONTEXT pCtx, void *pv, uint32_t cb, void *pvUser)
     153static DECLCALLBACK(int) vbclX11OnSendDataToDestCallback(PSHCLCONTEXT pCtx, void *pv, uint32_t cb, void *pvUser)
    162154{
    163155    PSHCLX11READDATAREQ pData = (PSHCLX11READDATAREQ)pvUser;
     
    177169
    178170/**
    179  * Connect the guest clipboard to the host.
     171 * Initializes the X11-specifc Shared Clipboard code.
    180172 *
    181173 * @returns VBox status code.
    182174 */
    183 static int vboxClipboardConnect(void)
     175int VBClX11ClipboardInit(void)
    184176{
    185177    LogFlowFuncEnter();
     
    187179    SHCLCALLBACKS Callbacks;
    188180    RT_ZERO(Callbacks);
    189     Callbacks.pfnReportFormats           = vbclReportFormatsCallback;
    190     Callbacks.pfnOnRequestDataFromSource = vbclOnRequestDataFromSourceCallback;
    191     Callbacks.pfnOnSendDataToDest        = vbclOnSendDataToDestCallback;
     181    Callbacks.pfnReportFormats           = vbclX11ReportFormatsCallback;
     182    Callbacks.pfnOnRequestDataFromSource = vbclX11OnRequestDataFromSourceCallback;
     183    Callbacks.pfnOnSendDataToDest        = vbclX11OnSendDataToDestCallback;
    192184
    193185    int rc = ShClX11Init(&g_Ctx.X11, &Callbacks, &g_Ctx, false /* fHeadless */);
     
    218210
    219211/**
    220  * The main loop of our clipboard reader.
    221  */
    222 int vboxClipboardMain(void)
     212 * Destroys the X11-specifc Shared Clipboard code.
     213 *
     214 * @returns VBox status code.
     215 */
     216int VBClX11ClipboardDestroy(void)
     217{
     218    /* Nothing to do here currently. */
     219    return VINF_SUCCESS;
     220}
     221
     222/**
     223 * The main loop of the X11-specifc Shared Clipboard code.
     224 *
     225 * @returns VBox status code.
     226 */
     227int VBClX11ClipboardMain(void)
    223228{
    224229    int rc;
     
    334339}
    335340
    336 /**
    337  * @interface_method_impl{VBCLSERVICE,pfnInit}
    338  */
    339 static DECLCALLBACK(int) vbclShClInit(void)
    340 {
    341     int rc;
    342 
    343 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    344     rc = ShClTransferCtxInit(&g_Ctx.TransferCtx);
    345 #else
    346     rc = VINF_SUCCESS;
    347 #endif
    348 
    349     LogFlowFuncLeaveRC(rc);
    350     return rc;
    351 }
    352 
    353 /**
    354  * @interface_method_impl{VBCLSERVICE,pfnWorker}
    355  */
    356 static DECLCALLBACK(int) vbclShClWorker(bool volatile *pfShutdown)
    357 {
    358     RT_NOREF(pfShutdown);
    359 
    360     /* Initialise the guest library. */
    361     int rc = vboxClipboardConnect();
    362     if (RT_SUCCESS(rc))
    363     {
    364         /* Let the main thread know that it can continue spawning services. */
    365         RTThreadUserSignal(RTThreadSelf());
    366 
    367         rc = vboxClipboardMain();
    368     }
    369 
    370     if (RT_FAILURE(rc))
    371         VBClLogError("Service terminated abnormally with %Rrc\n", rc);
    372 
    373     if (rc == VERR_HGCM_SERVICE_NOT_FOUND)
    374         rc = VINF_SUCCESS; /* Prevent automatic restart by daemon script if host service not available. */
    375 
    376     return rc;
    377 }
    378 
    379 /**
    380  * @interface_method_impl{VBCLSERVICE,pfnStop}
    381  */
    382 static DECLCALLBACK(void) vbclShClStop(void)
    383 {
    384     /* Disconnect from the host service.
    385      * This will also send a VBOX_SHCL_HOST_MSG_QUIT from the host so that we can break out from our message worker. */
    386     VbglR3ClipboardDisconnect(g_Ctx.CmdCtx.idClient);
    387     g_Ctx.CmdCtx.idClient = 0;
    388 }
    389 
    390 /**
    391  * @interface_method_impl{VBCLSERVICE,pfnTerm}
    392  */
    393 static DECLCALLBACK(int) vbclShClTerm(void)
    394 {
    395 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    396     ShClTransferCtxDestroy(&g_Ctx.TransferCtx);
    397 #endif
    398 
    399     return VINF_SUCCESS;
    400 }
    401 
    402 VBCLSERVICE g_SvcClipboard =
    403 {
    404     "shcl",                      /* szName */
    405     "Shared Clipboard",          /* pszDescription */
    406     ".vboxclient-clipboard",     /* pszPidFilePathTemplate */
    407     NULL,                        /* pszUsage */
    408     NULL,                        /* pszOptions */
    409     NULL,                        /* pfnOption */
    410     vbclShClInit,                /* pfnInit */
    411     vbclShClWorker,              /* pfnWorker */
    412     vbclShClStop,                /* pfnStop*/
    413     vbclShClTerm                 /* pfnTerm */
    414 };
    415 
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard-x11.h

    r99557 r99590  
    2626 */
    2727
    28 #ifndef GA_INCLUDED_SRC_x11_VBoxClient_clipboard_h
    29 #define GA_INCLUDED_SRC_x11_VBoxClient_clipboard_h
     28#ifndef GA_INCLUDED_SRC_x11_VBoxClient_clipboard_x11_h
     29#define GA_INCLUDED_SRC_x11_VBoxClient_clipboard_x11_h
    3030#ifndef RT_WITHOUT_PRAGMA_ONCE
    3131# pragma once
    3232#endif
    3333
    34 /**
    35  * Struct keeping a Shared Clipboard context.
    36  */
    37 struct SHCLCONTEXT
    38 {
    39     /** Client command context */
    40     VBGLR3SHCLCMDCTX CmdCtx;
    41 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    42     /** Associated transfer data. */
    43     SHCLTRANSFERCTX  TransferCtx;
    44 #endif
    45     /** X11 clipboard context. */
    46     SHCLX11CTX       X11;
    47 };
     34int VBClX11ClipboardInit(void);
     35int VBClX11ClipboardDestroy(void);
     36int VBClX11ClipboardMain(void);
    4837
    49 #endif /* !GA_INCLUDED_SRC_x11_VBoxClient_clipboard_h */
     38#endif /* !GA_INCLUDED_SRC_x11_VBoxClient_clipboard_x11_h */
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp

    r99586 r99590  
    11/** $Id$ */
    22/** @file
    3  * Guest Additions - X11 Shared Clipboard.
     3 * Guest Additions - Common Shared Clipboard wrapper service.
    44 */
    55
     
    4949
    5050#include "clipboard.h"
     51#include "clipboard-x11.h"
    5152
    5253
    53 /*********************************************************************************************************************************
    54 *   Global Variables                                                                                                             *
    55 *********************************************************************************************************************************/
    56 
    57 /** Only one context is supported at a time for now. */
     54/** Shared Clipboard context.
     55 *  Only one context is supported at a time for now. */
    5856SHCLCONTEXT g_Ctx;
    5957
    60 
    61 static DECLCALLBACK(int) vbclOnRequestDataFromSourceCallback(PSHCLCONTEXT pCtx,
    62                                                              SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser)
    63 {
    64     RT_NOREF(pvUser);
    65 
    66     LogFlowFunc(("pCtx=%p, uFmt=%#x\n", pCtx, uFmt));
    67 
    68     int rc = VINF_SUCCESS;
    69 
    70 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    71     if (uFmt == VBOX_SHCL_FMT_URI_LIST)
    72     {
    73         //rc = VbglR3ClipboardRootListRead()
    74         rc = VERR_NO_DATA;
    75     }
    76     else
    77 #endif
    78     {
    79         uint32_t cbRead = 0;
    80 
    81         uint32_t cbData = _4K; /** @todo Make this dynamic. */
    82         void    *pvData = RTMemAlloc(cbData);
    83         if (pvData)
    84         {
    85             rc = VbglR3ClipboardReadDataEx(&pCtx->CmdCtx, uFmt, pvData, cbData, &cbRead);
    86         }
    87         else
    88             rc = VERR_NO_MEMORY;
    89 
    90         /*
    91          * A return value of VINF_BUFFER_OVERFLOW tells us to try again with a
    92          * larger buffer.  The size of the buffer needed is placed in *pcb.
    93          * So we start all over again.
    94          */
    95         if (rc == VINF_BUFFER_OVERFLOW)
    96         {
    97             /* cbRead contains the size required. */
    98 
    99             cbData = cbRead;
    100             pvData = RTMemRealloc(pvData, cbRead);
    101             if (pvData)
    102             {
    103                 rc = VbglR3ClipboardReadDataEx(&pCtx->CmdCtx, uFmt, pvData, cbData, &cbRead);
    104                 if (rc == VINF_BUFFER_OVERFLOW)
    105                     rc = VERR_BUFFER_OVERFLOW;
    106             }
    107             else
    108                 rc = VERR_NO_MEMORY;
    109         }
    110 
    111         if (!cbRead)
    112             rc = VERR_NO_DATA;
    113 
    114         if (RT_SUCCESS(rc))
    115         {
    116             *pcb = cbRead; /* Actual bytes read. */
    117             *ppv = pvData;
    118         }
    119         else
    120         {
    121             /*
    122              * Catch other errors. This also catches the case in which the buffer was
    123              * too small a second time, possibly because the clipboard contents
    124              * changed half-way through the operation.  Since we can't say whether or
    125              * not this is actually an error, we just return size 0.
    126              */
    127             RTMemFree(pvData);
    128         }
    129     }
    130 
    131     if (RT_FAILURE(rc))
    132         LogRel(("Requesting data in format %#x from host failed with %Rrc\n", uFmt, rc));
    133 
    134     LogFlowFuncLeaveRC(rc);
    135     return rc;
    136 }
    137 
    138 /**
    139  * Opaque data structure describing a request from the host for clipboard
    140  * data, passed in when the request is forwarded to the X11 backend so that
    141  * it can be completed correctly.
    142  */
    143 struct CLIPREADCBREQ
    144 {
    145     /** The data format that was requested. */
    146     SHCLFORMAT uFmt;
    147 };
    148 
    149 static DECLCALLBACK(int) vbclReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats, void *pvUser)
    150 {
    151     RT_NOREF(pvUser);
    152 
    153     LogFlowFunc(("fFormats=%#x\n", fFormats));
    154 
    155     int rc = VbglR3ClipboardReportFormats(pCtx->CmdCtx.idClient, fFormats);
    156     LogFlowFuncLeaveRC(rc);
    157 
    158     return rc;
    159 }
    160 
    161 static DECLCALLBACK(int) vbclOnSendDataToDestCallback(PSHCLCONTEXT pCtx, void *pv, uint32_t cb, void *pvUser)
    162 {
    163     PSHCLX11READDATAREQ pData = (PSHCLX11READDATAREQ)pvUser;
    164     AssertPtrReturn(pData, VERR_INVALID_POINTER);
    165 
    166     LogFlowFunc(("rcCompletion=%Rrc, Format=0x%x, pv=%p, cb=%RU32\n", pData->rcCompletion, pData->pReq->uFmt, pv, cb));
    167 
    168     Assert((cb == 0 && pv == NULL) || (cb != 0 && pv != NULL));
    169     pData->rcCompletion = VbglR3ClipboardWriteDataEx(&pCtx->CmdCtx, pData->pReq->uFmt, pv, cb);
    170 
    171     RTMemFree(pData->pReq);
    172 
    173     LogFlowFuncLeaveRC(pData->rcCompletion);
    174 
    175     return VINF_SUCCESS;
    176 }
    177 
    178 /**
    179  * Connect the guest clipboard to the host.
    180  *
    181  * @returns VBox status code.
    182  */
    183 static int vboxClipboardConnect(void)
    184 {
    185     LogFlowFuncEnter();
    186 
    187     SHCLCALLBACKS Callbacks;
    188     RT_ZERO(Callbacks);
    189     Callbacks.pfnReportFormats           = vbclReportFormatsCallback;
    190     Callbacks.pfnOnRequestDataFromSource = vbclOnRequestDataFromSourceCallback;
    191     Callbacks.pfnOnSendDataToDest        = vbclOnSendDataToDestCallback;
    192 
    193     int rc = ShClX11Init(&g_Ctx.X11, &Callbacks, &g_Ctx, false /* fHeadless */);
    194     if (RT_SUCCESS(rc))
    195     {
    196         rc = ShClX11ThreadStart(&g_Ctx.X11, false /* grab */);
    197         if (RT_SUCCESS(rc))
    198         {
    199             rc = VbglR3ClipboardConnectEx(&g_Ctx.CmdCtx, VBOX_SHCL_GF_0_CONTEXT_ID);
    200             if (RT_FAILURE(rc))
    201                 ShClX11ThreadStop(&g_Ctx.X11);
    202         }
    203     }
    204     else
    205         rc = VERR_NO_MEMORY;
    206 
    207     if (RT_FAILURE(rc))
    208     {
    209         VBClLogError("Error connecting to host service, rc=%Rrc\n", rc);
    210 
    211         VbglR3ClipboardDisconnectEx(&g_Ctx.CmdCtx);
    212         ShClX11Destroy(&g_Ctx.X11);
    213     }
    214 
    215     LogFlowFuncLeaveRC(rc);
    216     return rc;
    217 }
    218 
    219 /**
    220  * The main loop of our clipboard reader.
    221  */
    222 int vboxClipboardMain(void)
    223 {
    224     int rc;
    225 
    226     PSHCLCONTEXT pCtx = &g_Ctx;
    227 
    228     bool fShutdown = false;
    229 
    230     /* The thread waits for incoming messages from the host. */
    231     for (;;)
    232     {
    233         PVBGLR3CLIPBOARDEVENT pEvent = (PVBGLR3CLIPBOARDEVENT)RTMemAllocZ(sizeof(VBGLR3CLIPBOARDEVENT));
    234         AssertPtrBreakStmt(pEvent, rc = VERR_NO_MEMORY);
    235 
    236         LogFlowFunc(("Waiting for host message (fUseLegacyProtocol=%RTbool, fHostFeatures=%#RX64) ...\n",
    237                      pCtx->CmdCtx.fUseLegacyProtocol, pCtx->CmdCtx.fHostFeatures));
    238 
    239         uint32_t idMsg  = 0;
    240         uint32_t cParms = 0;
    241         rc = VbglR3ClipboardMsgPeekWait(&pCtx->CmdCtx, &idMsg, &cParms, NULL /* pidRestoreCheck */);
    242         if (RT_SUCCESS(rc))
    243         {
    244 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    245             rc = VbglR3ClipboardEventGetNextEx(idMsg, cParms, &pCtx->CmdCtx, &pCtx->TransferCtx, pEvent);
    246 #else
    247             rc = VbglR3ClipboardEventGetNext(idMsg, cParms, &pCtx->CmdCtx, pEvent);
    248 #endif
    249         }
    250 
    251         if (RT_FAILURE(rc))
    252         {
    253             LogFlowFunc(("Getting next event failed with %Rrc\n", rc));
    254 
    255             VbglR3ClipboardEventFree(pEvent);
    256             pEvent = NULL;
    257 
    258             if (fShutdown)
    259                 break;
    260 
    261             /* Wait a bit before retrying. */
    262             RTThreadSleep(1000);
    263             continue;
    264         }
    265         else
    266         {
    267             AssertPtr(pEvent);
    268             LogFlowFunc(("Event uType=%RU32\n", pEvent->enmType));
    269 
    270             switch (pEvent->enmType)
    271             {
    272                 case VBGLR3CLIPBOARDEVENTTYPE_REPORT_FORMATS:
    273                 {
    274                     ShClX11ReportFormatsToX11(&g_Ctx.X11, pEvent->u.fReportedFormats);
    275                     break;
    276                 }
    277 
    278                 case VBGLR3CLIPBOARDEVENTTYPE_READ_DATA:
    279                 {
    280                     /* The host needs data in the specified format. */
    281                     CLIPREADCBREQ *pReq;
    282                     pReq = (CLIPREADCBREQ *)RTMemAllocZ(sizeof(CLIPREADCBREQ));
    283                     if (pReq)
    284                     {
    285                         pReq->uFmt = pEvent->u.fReadData;
    286                         ShClX11ReadDataFromX11(&g_Ctx.X11, pReq->uFmt, pReq);
    287                     }
    288                     else
    289                         rc = VERR_NO_MEMORY;
    290                     break;
    291                 }
    292 
    293                 case VBGLR3CLIPBOARDEVENTTYPE_QUIT:
    294                 {
    295                     VBClLogVerbose(2, "Host requested termination\n");
    296                     fShutdown = true;
    297                     break;
    298                 }
    299 
    300 #ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    301                 case VBGLR3CLIPBOARDEVENTTYPE_TRANSFER_STATUS:
    302                 {
    303                     /* Nothing to do here. */
    304                     rc = VINF_SUCCESS;
    305                     break;
    306                 }
    307 #endif
    308                 case VBGLR3CLIPBOARDEVENTTYPE_NONE:
    309                 {
    310                     /* Nothing to do here. */
    311                     rc = VINF_SUCCESS;
    312                     break;
    313                 }
    314 
    315                 default:
    316                 {
    317                     AssertMsgFailedBreakStmt(("Event type %RU32 not implemented\n", pEvent->enmType), rc = VERR_NOT_SUPPORTED);
    318                 }
    319             }
    320 
    321             if (pEvent)
    322             {
    323                 VbglR3ClipboardEventFree(pEvent);
    324                 pEvent = NULL;
    325             }
    326         }
    327 
    328         if (fShutdown)
    329             break;
    330     }
    331 
    332     LogFlowFuncLeaveRC(rc);
    333     return rc;
    334 }
    33558
    33659/**
     
    35881    RT_NOREF(pfShutdown);
    35982
    360     /* Initialise the guest library. */
    361     int rc = vboxClipboardConnect();
    362     if (RT_SUCCESS(rc))
     83    int rc = VINF_SUCCESS;
     84
     85    if (VBClGetSessionType() == VBGHSESSIONTYPE_X11)
    36386    {
    364         /* Let the main thread know that it can continue spawning services. */
    365         RTThreadUserSignal(RTThreadSelf());
     87        rc = VBClX11ClipboardInit();
     88        if (RT_SUCCESS(rc))
     89        {
     90            /* Let the main thread know that it can continue spawning services. */
     91            RTThreadUserSignal(RTThreadSelf());
    36692
    367         rc = vboxClipboardMain();
     93            rc = VBClX11ClipboardMain();
     94        }
    36895    }
     96#if 0
     97    else (VBClGetSessionType() == VBGHSESSIONTYPE_WAYLAND)
     98    {
     99
     100    }
     101#endif
    369102
    370103    if (RT_FAILURE(rc))
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard.h

    r98103 r99590  
    4343    SHCLTRANSFERCTX  TransferCtx;
    4444#endif
    45     /** X11 clipboard context. */
    46     SHCLX11CTX       X11;
     45    union
     46    {
     47        /** X11 clipboard context. */
     48        SHCLX11CTX       X11;
     49        /** @todo Way clipboard context goes here. */
     50        /* SHCLWAYLANDCTX Wl; */
     51    };
    4752};
    4853
     54/** Shared Clipboard context.
     55 *  Only one context is supported at a time for now. */
     56extern SHCLCONTEXT g_Ctx;
     57
    4958#endif /* !GA_INCLUDED_SRC_x11_VBoxClient_clipboard_h */
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