VirtualBox

Changeset 93495 in vbox


Ignore:
Timestamp:
Jan 31, 2022 1:08:33 PM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
149618
Message:

Shared Clipboard: Implemented backend callbacks and a dedicated backend context, together with a new testcase which mocks HGCM to also test the guest-side clipboard code (disabled by default for now). Work in progress, only tested on Linux so far.

Location:
trunk
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/GuestHost/SharedClipboard-x11.h

    r93321 r93495  
    9292{
    9393    /** Opaque data structure describing the front-end. */
    94     PSHCLCONTEXT pFrontend;
     94    PSHCLCONTEXT     pFrontend;
     95    /** Our callback table to use. */
     96    SHCLCALLBACKS    Callbacks;
    9597    /** Is an X server actually available? */
    96     bool fHaveX11;
     98    bool             fHaveX11;
    9799    /** The X Toolkit application context structure. */
    98     XtAppContext pAppContext;
    99 
     100    XtAppContext     pAppContext;
    100101    /** We have a separate thread to wait for window and clipboard events. */
    101     RTTHREAD Thread;
     102    RTTHREAD         Thread;
    102103    /** Flag indicating that the thread is in a started state. */
    103     bool fThreadStarted;
    104 
     104    bool             fThreadStarted;
    105105    /** The X Toolkit widget which we use as our clipboard client.  It is never made visible. */
    106     Widget pWidget;
    107 
     106    Widget           pWidget;
    108107    /** Should we try to grab the clipboard on startup? */
    109     bool fGrabClipboardOnStart;
    110 
     108    bool             fGrabClipboardOnStart;
    111109    /** The best text format X11 has to offer, as an index into the formats table. */
    112     SHCLX11FMTIDX idxFmtText;
     110    SHCLX11FMTIDX    idxFmtText;
    113111    /** The best bitmap format X11 has to offer, as an index into the formats table. */
    114     SHCLX11FMTIDX idxFmtBmp;
     112    SHCLX11FMTIDX    idxFmtBmp;
    115113    /** The best HTML format X11 has to offer, as an index into the formats table. */
    116     SHCLX11FMTIDX idxFmtHTML;
     114    SHCLX11FMTIDX    idxFmtHTML;
    117115#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    118116    /** The best HTML format X11 has to offer, as an index into the formats table. */
    119     SHCLX11FMTIDX   idxFmtURI;
     117    SHCLX11FMTIDX    idxFmtURI;
    120118# ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP
    121119    /** HTTP transfer context data. */
    122     SHCLHTTPCONTEXT HttpCtx;
     120    SHCLHTTPCONTEXT  HttpCtx;
    123121# endif
    124122#endif
    125123    /** What kind of formats does VBox have to offer? */
    126     SHCLFORMATS vboxFormats;
     124    SHCLFORMATS      vboxFormats;
    127125    /** Cache of the last unicode data that we received. */
    128     void *pvUnicodeCache;
     126    void            *pvUnicodeCache;
    129127    /** Size of the unicode data in the cache. */
    130     uint32_t cbUnicodeCache;
     128    uint32_t         cbUnicodeCache;
    131129    /** When we wish the clipboard to exit, we have to wake up the event
    132130     * loop.  We do this by writing into a pipe.  This end of the pipe is
    133131     * the end that another thread can write to. */
    134     int wakeupPipeWrite;
     132    int              wakeupPipeWrite;
    135133    /** The reader end of the pipe. */
    136     int wakeupPipeRead;
     134    int              wakeupPipeRead;
    137135    /** A pointer to the XFixesSelectSelectionInput function. */
    138136    void (*fixesSelectInput)(Display *, Window, Atom, unsigned long);
    139137    /** The first XFixes event number. */
    140     int fixesEventBase;
     138    int              fixesEventBase;
    141139#ifdef VBOX_WITH_SHARED_CLIPBOARD_XT_BUSY
    142140    /** XtGetSelectionValue on some versions of libXt isn't re-entrant
    143141     * so block overlapping requests on this flag. */
    144     bool fXtBusy;
     142    bool             fXtBusy;
    145143    /** If a request is blocked on the previous flag, set this flag to request
    146144     * an update later - the first callback should check and clear this flag
    147145     * before processing the callback event. */
    148     bool fXtNeedsUpdate;
     146    bool             fXtNeedsUpdate;
    149147#endif
    150148} SHCLX11CTX, *PSHCLX11CTX;
     149
     150/**
     151 * Structure for keeping a X11 read data request.
     152 */
     153typedef struct _SHCLX11READDATAREQ
     154{
     155    /** Actual read request to handle. */
     156    CLIPREADCBREQ *pReq;
     157    /** Result code of the operation on completion. */
     158    int            rcCompletion;
     159} SHCLX11READDATAREQ;
     160/** Pointer to a send data request. */
     161typedef SHCLX11READDATAREQ *PSHCLX11READDATAREQ;
    151162
    152163/** @name Shared Clipboard APIs for X11.
    153164 * @{
    154165 */
    155 int ShClX11Init(PSHCLX11CTX pCtx, PSHCLCONTEXT pParent, bool fHeadless);
     166int ShClX11Init(PSHCLX11CTX pCtx, PSHCLCALLBACKS pCallbacks, PSHCLCONTEXT pParent, bool fHeadless);
    156167void ShClX11Destroy(PSHCLX11CTX pCtx);
    157168int ShClX11ThreadStart(PSHCLX11CTX pCtx, bool grab);
     169int ShClX11ThreadStartEx(PSHCLX11CTX pCtx, const char *pszName, bool fGrab);
    158170int ShClX11ThreadStop(PSHCLX11CTX pCtx);
    159171int ShClX11ReportFormatsToX11(PSHCLX11CTX pCtx, SHCLFORMATS vboxFormats);
    160172int ShClX11ReadDataFromX11(PSHCLX11CTX pCtx, SHCLFORMATS vboxFormat, CLIPREADCBREQ *pReq);
    161 /** @} */
    162 
    163 /** @name Shared Clipboard callbacks which have to be implemented by tools using the X11
    164  *        clipboard, e.g. VBoxClient (on guest side) or the X11 host service backend.
    165  * @{
    166  */
    167 /**
    168  * Callback for reporting supported formats of current clipboard data from X11 to VBox.
    169  *
    170  * @note   Runs in Xt event thread.
    171  *
    172  * @param  pCtx                 Opaque context pointer for the glue code.
    173  * @param  fFormats             The formats available.
    174  */
    175 DECLCALLBACK(void) ShClX11ReportFormatsCallback(PSHCLCONTEXT pCtx, SHCLFORMATS fFormats);
    176 
    177 /**
    178  * Callback for requesting clipboard data for X11.
    179  * The function will be invoked for every single target the clipboard requests.
    180  *
    181  * @note Runs in Xt event thread.
    182  *
    183  * @returns VBox status code. VERR_NO_DATA if no data available.
    184  * @param   pCtx                Pointer to the host clipboard structure.
    185  * @param   uFmt                The format in which the data should be transferred
    186  *                              (VBOX_SHCL_FMT_XXX).
    187  * @param   ppv                 Returns an allocated buffer with data read from the guest on success.
    188  *                              Needs to be free'd with RTMemFree() by the caller.
    189  * @param   pcb                 Returns the amount of data read (in bytes) on success.
    190  */
    191 DECLCALLBACK(int) ShClX11RequestDataCallback(PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb);
    192 
    193 /**
    194  * Callback for reporting that clipboard data from X11 is available.
    195  *
    196  * @param  pCtx                 Our context information.
    197  * @param  rcCompletion         The completion status of the request.
    198  * @param  pReq                 The request structure that we passed in when we started
    199  *                              the request.  We RTMemFree() this in this function.
    200  * @param  pv                   The clipboard data returned from X11 if the request succeeded (see @a rcCompletion).
    201  * @param  cb                   The size of the data in @a pv.
    202  */
    203 DECLCALLBACK(void) ShClX11ReportDataCallback(PSHCLCONTEXT pCtx, int rcCompletion,
    204                                              CLIPREADCBREQ *pReq, void *pv, uint32_t cb);
     173void ShClX11SetCallbacks(PSHCLX11CTX pCtx, PSHCLCALLBACKS pCallbacks);
    205174/** @} */
    206175
  • trunk/include/VBox/GuestHost/SharedClipboard.h

    r93115 r93495  
    232232typedef SHCLCONTEXT *PSHCLCONTEXT;
    233233
     234/**
     235 * @name Shared Clipboard callback table.
     236 *
     237 * This table gets used by
     238 *   - the backends on the host (where required)
     239 *   - guest side implementations (e.g. VBoxClient)
     240 *   - by the underlying core code (e.g. X11 backend -> X11 common code -> callback)
     241 *
     242 * Some clipboard mechanisms (e.g. X11) require asynchronous and/or event-driven handling
     243 * of clipboard data, making it hard to control our program flow when testing stuff.
     244 *
     245 * So overriding required callbacks on runtime for testing purposes makes this approach much
     246 * more flexible without implementing separate code paths for production code and test units.
     247 *
     248 * @{
     249 */
     250typedef struct _SHCLCALLBACKS
     251{
     252    /**
     253     * Callback for reporting supported clipoard formats of current clipboard data.
     254     *
     255     * @note On X11:
     256     *         Runs in Xt event thread for the X11 code.
     257     *
     258     * @returns VBox status code.
     259     * @param   pCtx            Opaque context pointer for the glue code.
     260     * @param   fFormats        The formats available.
     261     */
     262    DECLCALLBACKMEMBER(int, pfnReportFormats, (PSHCLCONTEXT pCtx, SHCLFORMATS fFormats, void *pvUser));
     263
     264    /**
     265     * Callback for reading data from the clipboard.
     266     * Optional and can be NULL.
     267     *
     268     * @note Used for testing X11 clipboard code.
     269     *
     270     * @returns VBox status code.
     271     * @param   pCtx            Opaque context pointer for the glue code.
     272     * @param   uFmt            The format in which the data should be read
     273     *                          (VBOX_SHCL_FMT_XXX).
     274     * @param   ppv             Returns an allocated buffer with data from on success.
     275     *                          Needs to be free'd with RTMemFree() by the caller.
     276     * @param   pcb             Returns the amount of data read (in bytes) on success.
     277     * @param   pvUser          Implementation-dependent pointer to data for fullfilling the request.
     278     *                          Optional and can be NULL.
     279     */
     280    DECLCALLBACKMEMBER(int, pfnOnClipboardRead, (PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, size_t *pcb, void *pvUser));
     281
     282    /**
     283     * Callback for writing data to the clipboard.
     284     * Optional and can be NULL.
     285     *
     286     * @note Used for testing X11 clipboard code.
     287     *
     288     * @returns VBox status code.
     289     * @param   pCtx            Opaque context pointer for the glue code.
     290     * @param   uFmt            The format in which the data should be written as
     291     *                          (VBOX_SHCL_FMT_XXX).
     292     * @param   pv              The clipboard data to write.
     293     * @param   cb              The size of the data in @a pv.
     294     * @param   pvUser          Implementation-dependent pointer to data for fullfilling the request.
     295     *                          Optional and can be NULL.
     296     */
     297    DECLCALLBACKMEMBER(int, pfnOnClipboardWrite, (PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void *pv, size_t cb, void *pvUser));
     298
     299    /**
     300     * Callback for requesting clipboard data from the source.
     301     *
     302     * @note On X11:
     303     *         The function will be invoked for every single target the clipboard requests.
     304     *         Runs in Xt event thread for the X11 code.
     305     *
     306     * @returns VBox status code. VERR_NO_DATA if no data available.
     307     * @param   pCtx            Opaque context pointer for the glue code.
     308     * @param   uFmt            The format in which the data should be transferred
     309     *                          (VBOX_SHCL_FMT_XXX).
     310     * @param   ppv             Returns an allocated buffer with data read from the guest on success.
     311     *                          Needs to be free'd with RTMemFree() by the caller.
     312     * @param   pcb             Returns the amount of data read (in bytes) on success.
     313     * @param   pvUser          Implementation-dependent pointer to data for fullfilling the request.
     314     *                          Optional and can be NULL.
     315     *                          On X11: Of type PSHCLX11READDATAREQ; We RTMemFree() this in this function.
     316     */
     317    DECLCALLBACKMEMBER(int, pfnOnRequestDataFromSource, (PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser));
     318
     319    /**
     320     * Callback for sending clipboard data to the destination.
     321     *
     322     * @note On X11:
     323     *         (see @a rcCompletion)
     324     *
     325     * @returns VBox status code.
     326     * @param   pCtx            Opaque context pointer for the glue code.
     327     * @param   pv              The clipboard data returned if the request succeeded.
     328     * @param   cb              The size of the data in @a pv.
     329     * @param   pvUser          Implementation-dependent pointer to data for fullfilling the request.
     330     *                          Optional and can be NULL.
     331     */
     332    DECLCALLBACKMEMBER(int, pfnOnSendDataToDest, (PSHCLCONTEXT pCtx, void *pv, uint32_t cb, void *pvUser));
     333} SHCLCALLBACKS;
     334typedef SHCLCALLBACKS *PSHCLCALLBACKS;
     335/** @} */
     336
    234337/** Opaque request structure for X11 clipboard data.
    235338 * @{ */
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp

    r93327 r93495  
    177177    LogFlowFuncEnter();
    178178
    179     int rc = ShClX11Init(&g_Ctx.X11, &g_Ctx, false /* fHeadless */);
     179    int rc = ShClX11Init(&g_Ctx.X11, NULL /* pCallbacks */, &g_Ctx, false /* fHeadless */);
    180180    if (RT_SUCCESS(rc))
    181181    {
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp

    r93321 r93495  
    449449#endif
    450450
    451     ShClX11ReportFormatsCallback(pCtx->pFrontend, vboxFmt);
     451    pCtx->Callbacks.pfnReportFormats(pCtx->pFrontend, vboxFmt, NULL /* pvUser */);
    452452}
    453453
     
    742742    unsigned cFormats = *pcLen;
    743743
    744     LogRel2(("Shared Clipboard: %u formats were found\n", cFormats));
     744    LogRel2(("Shared Clipboard: Querying X11 formats ...\n", cFormats));
     745    LogRel2(("Shared Clipboard: %u X11 formats were found\n", cFormats));
    745746
    746747    SHCLX11FMTIDX *paIdxFmt = NULL;
     
    761762            {
    762763                char *pszName = XGetAtomName(XtDisplay(widget), pAtoms[i]);
    763                 LogRel2(("Shared Clipboard: Found target '%s'\n", pszName));
     764                LogRel2(("Shared Clipboard: Found X11 format '%s'\n", pszName));
    764765                XFree(pszName);
    765766            }
     
    783784#if !defined(TESTCASE)
    784785            if (paIdxFmt[i] != SHCLX11FMT_INVALID)
    785                 LogRel2(("Shared Clipboard: Reporting format '%s'\n", g_aFormats[paIdxFmt[i]].pcszAtom));
     786                LogRel2(("Shared Clipboard: Reporting X11 format '%s'\n", g_aFormats[paIdxFmt[i]].pcszAtom));
    786787#endif
    787788        }
     
    11501151
    11511152/**
     1153 * Sets the callback table, internal version.
     1154 *
     1155 * @param   pCtx                The clipboard context.
     1156 * @param   pCallbacks          Callback table to set. If NULL, the current callback table will be cleared.
     1157 */
     1158static void shClX11SetCallbacksInternal(PSHCLX11CTX pCtx, PSHCLCALLBACKS pCallbacks)
     1159{
     1160    if (pCallbacks)
     1161    {
     1162        memcpy(&pCtx->Callbacks, pCallbacks, sizeof(SHCLCALLBACKS));
     1163    }
     1164    else
     1165        RT_ZERO(pCtx->Callbacks);
     1166}
     1167
     1168/**
     1169 * Sets the callback table.
     1170 *
     1171 * @param   pCtx                The clipboard context.
     1172 * @param   pCallbacks          Callback table to set. If NULL, the current callback table will be cleared.
     1173 */
     1174void ShClX11SetCallbacks(PSHCLX11CTX pCtx, PSHCLCALLBACKS pCallbacks)
     1175{
     1176    shClX11SetCallbacksInternal(pCtx, pCallbacks);
     1177}
     1178
     1179/**
    11521180 * Initializes a X11 context of the Shared Clipboard.
    11531181 *
    11541182 * @returns VBox status code.
    11551183 * @param   pCtx                The clipboard context to initialize.
     1184 * @param   pCallbacks          Callback table to use.
    11561185 * @param   pParent             Parent context to use.
    11571186 * @param   fHeadless           Whether the code runs in a headless environment or not.
    11581187 */
    1159 int ShClX11Init(PSHCLX11CTX pCtx, PSHCLCONTEXT pParent, bool fHeadless)
    1160 {
    1161     AssertPtrReturn(pCtx,    VERR_INVALID_POINTER);
    1162 #if !defined(SMOKETEST) && !defined(TESTCASE)
    1163     /* Smoktests / Testcases don't have a (valid) parent. */
    1164     AssertPtrReturn(pParent, VERR_INVALID_POINTER);
    1165 #endif
     1188int ShClX11Init(PSHCLX11CTX pCtx, PSHCLCALLBACKS pCallbacks, PSHCLCONTEXT pParent, bool fHeadless)
     1189{
     1190    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
    11661191
    11671192    LogFlowFunc(("pCtx=%p\n", pCtx));
     
    11821207    }
    11831208
     1209    /* Install given callbacks. */
     1210    shClX11SetCallbacksInternal(pCtx, pCallbacks);
     1211
    11841212    pCtx->fHaveX11       = !fHeadless;
    11851213    pCtx->pFrontend      = pParent;
     
    12371265#ifndef TESTCASE
    12381266/**
    1239  * Starts our own Xt even thread for handling Shared Clipboard messages.
     1267 * Starts our own Xt even thread for handling Shared Clipboard messages, extended version.
    12401268 *
    12411269 * @returns VBox status code.
    12421270 * @param   pCtx                The X11 clipboard context to use.
     1271 * @param   pszName             Thread name to use.
    12431272 * @param   fGrab               Whether we should try to grab the shared clipboard at once.
    12441273 */
    1245 int ShClX11ThreadStart(PSHCLX11CTX pCtx, bool fGrab)
     1274int ShClX11ThreadStartEx(PSHCLX11CTX pCtx, const char *pszName, bool fGrab)
    12461275{
    12471276    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     
    12841313
    12851314        rc = RTThreadCreate(&pCtx->Thread, clipThreadMain, pCtx, 0,
    1286                             RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLX11");
     1315                            RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, pszName);
    12871316        if (RT_SUCCESS(rc))
    12881317            rc = RTThreadUserWait(pCtx->Thread, RT_MS_30SEC /* msTimeout */);
     
    13061335    LogFlowFuncLeaveRC(rc);
    13071336    return rc;
     1337}
     1338
     1339/**
     1340 * Starts our own Xt even thread for handling Shared Clipboard messages.
     1341 *
     1342 * @returns VBox status code.
     1343 * @param   pCtx                The X11 clipboard context to use.
     1344 * @param   fGrab               Whether we should try to grab the shared clipboard at once.
     1345 */
     1346int ShClX11ThreadStart(PSHCLX11CTX pCtx, bool fGrab)
     1347{
     1348    return ShClX11ThreadStartEx(pCtx, "SHCLX11", fGrab);
    13081349}
    13091350
     
    14531494    {
    14541495        if (pCtx->pvUnicodeCache == NULL) /** @todo r=andy Using string cache here? */
    1455             rc = ShClX11RequestDataCallback(pCtx->pFrontend, uFmt,
    1456                                             &pCtx->pvUnicodeCache,
    1457                                             &pCtx->cbUnicodeCache);
    1458         if (RT_SUCCESS(rc))
     1496            rc = pCtx->Callbacks.pfnOnRequestDataFromSource(pCtx->pFrontend, uFmt, &pCtx->pvUnicodeCache, &pCtx->cbUnicodeCache,
     1497                                                            NULL /* pvUser */);
     1498        if (   RT_SUCCESS(rc)
     1499            /* Catch misbehaving callbacks. */
     1500            && pCtx->pvUnicodeCache
     1501            && pCtx->cbUnicodeCache)
    14591502        {
    14601503            pv = RTMemDup(pCtx->pvUnicodeCache, pCtx->cbUnicodeCache);
     
    14661509    }
    14671510    else
    1468         rc = ShClX11RequestDataCallback(pCtx->pFrontend, uFmt, &pv, &cb);
     1511        rc = pCtx->Callbacks.pfnOnRequestDataFromSource(pCtx->pFrontend, uFmt, &pv, &cb, NULL /* pvUser */);
    14691512
    14701513
     
    17811824        return False;
    17821825
     1826    XSelectionRequestEvent* req =
     1827        XtGetSelectionRequest(widget, *atomSelection, (XtRequestId)NULL);
     1828
    17831829    /* Is this the rigt selection (clipboard) we were asked for? */
    17841830    if (!clipIsSupportedSelectionType(pCtx, *atomSelection))
     
    17931839                                  pValReturn, pcLenReturn, piFormatReturn);
    17941840
    1795     LogFlowFunc(("returning %RTbool, rc=%Rrc\n", RT_SUCCESS(rc), rc));
     1841
     1842    LogFlowFunc(("returning pVBoxWnd=%#x, ownerWnd=%#x, reqWnd=%#x, %RTbool, rc=%Rrc\n",
     1843                 XtWindow(pCtx->pWidget), req->owner, req->requestor, RT_SUCCESS(rc), rc));
    17961844    return RT_SUCCESS(rc) ? True : False;
     1845}
     1846
     1847static void clipXtConvertSelectionProcLose(Widget widget, Atom *atomSelection)
     1848{
     1849    RT_NOREF(widget, atomSelection);
     1850    LogFlowFuncEnter();
     1851}
     1852
     1853static void clipXtConvertSelectionProcDone(Widget widget, Atom *atomSelection, Atom *atomTarget)
     1854{
     1855    RT_NOREF(widget, atomSelection, atomTarget);
     1856    LogFlowFuncEnter();
    17971857}
    17981858
     
    18341894    LogFlowFuncEnter();
    18351895
     1896    /** @ŧodo r=andy The docs say: "the value CurrentTime is not acceptable" here!? */
    18361897    if (XtOwnSelection(pCtx->pWidget, clipGetAtom(pCtx, "CLIPBOARD"),
    1837                        CurrentTime, clipXtConvertSelectionProc, NULL, 0))
     1898                       CurrentTime,
     1899                       clipXtConvertSelectionProc, clipXtConvertSelectionProcLose, clipXtConvertSelectionProcDone))
    18381900    {
    18391901        pCtx->vboxFormats = uFormats;
     
    18741936    RTMemFree(pFormats);
    18751937
    1876     LogFlowFunc (("fFormats=0x%x\n", fFormats));
     1938#ifdef LOG_ENABLED
     1939    char *pszFmts = ShClFormatsToStrA(fFormats);
     1940    AssertPtrReturnVoid(pszFmts);
     1941    LogRel2(("Shared Clipboard: Reported available VBox formats %s to X11\n", pszFmts));
     1942    RTStrFree(pszFmts);
     1943#endif
    18771944
    18781945    clipInvalidateClipboardCache(pCtx);
     
    19061973        pFormats->pCtx    = pCtx;
    19071974        pFormats->Formats = uFormats;
    1908 
    19091975        rc = clipThreadScheduleCall(pCtx, ShClX11ReportFormatsToX11Worker,
    19101976                                    (XtPointer)pFormats);
     
    19692035            {
    19702036                size_t cwDst;
    1971 
    19722037                /* If we are given broken UTF-8, we treat it as Latin1. */ /** @todo BUGBUG Is this acceptable? */
    19732038                if (RT_SUCCESS(RTStrValidateEncodingEx((char *)pvSrc, cbSrc, 0)))
     
    21512216                g_aFormats[pReq->idxFmtX11].pcszAtom, pReq->idxFmtX11, pReq->uFmtVBox, rc));
    21522217
    2153     ShClX11ReportDataCallback(pReq->pCtx->pFrontend, rc, pReq->pReq, pvDst, cbDst);
     2218    SHCLX11READDATAREQ SendData;
     2219    RT_ZERO(SendData);
     2220    SendData.pReq         = pReq->pReq;
     2221    SendData.rcCompletion = rc;
     2222
     2223    pCtx->Callbacks.pfnOnSendDataToDest(pReq->pCtx->pFrontend, pvDst, cbDst, &SendData);
    21542224
    21552225    RTMemFree(pvDst);
     
    21752245        clipConvertDataFromX11Worker(pClient, NULL, 0);
    21762246    else
    2177         clipConvertDataFromX11Worker(pClient, pvSrc, (*pcLen) * (*piFormat) / 8);
     2247    {
     2248        CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *)pClient;
     2249        if (pReq->pCtx->Callbacks.pfnOnClipboardRead)
     2250        {
     2251            void  *pvData = NULL;
     2252            size_t cbData = 0;
     2253            int rc = pReq->pCtx->Callbacks.pfnOnClipboardRead(pReq->pCtx->pFrontend, pReq->uFmtVBox, &pvData, &cbData, NULL);
     2254            if (RT_SUCCESS(rc))
     2255            {
     2256                /* Feed to conversion worker. */
     2257                clipConvertDataFromX11Worker(pClient, pvData, cbData);
     2258                RTMemFree(pvData);
     2259            }
     2260            else
     2261                clipConvertDataFromX11Worker(pClient, NULL, 0);
     2262        }
     2263        else /* Call with current data provided by X (default). */
     2264            clipConvertDataFromX11Worker(pClient, pvSrc, (*pcLen) * (*piFormat) / 8);
     2265    }
    21782266
    21792267    XtFree((char *)pvSrc);
     
    22092297    CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *)pvUserData;
    22102298    SHCLX11CTX       *pCtx = pReq->pCtx;
    2211 
    2212     LogFlowFunc(("pReq->mFormat = %02x\n", pReq->uFmtVBox));
     2299    AssertPtrReturnVoid(pCtx);
     2300
     2301    LogFlowFunc(("pReq->uFmtVBox=%#x, idxFmtX11=%#x\n", pReq->uFmtVBox, pReq->idxFmtX11));
    22132302
    22142303    int rc = VERR_NO_DATA; /* VBox thinks we have data and we don't. */
     
    22742363        /* The clipboard callback was never scheduled, so we must signal
    22752364         * that the request processing is finished and clean up ourselves. */
    2276         ShClX11ReportDataCallback(pReq->pCtx->pFrontend, rc, pReq->pReq,
    2277                                   NULL /* pv */ ,0 /* cb */);
     2365        SHCLX11READDATAREQ SendData;
     2366        RT_ZERO(SendData);
     2367        SendData.pReq         = pReq->pReq;
     2368        SendData.rcCompletion = rc;
     2369
     2370        pCtx->Callbacks.pfnOnSendDataToDest(pReq->pCtx->pFrontend, NULL /* pv */ ,0 /* cb */, &SendData);
    22782371        RTMemFree(pReq);
    22792372    }
     
    22892382 * @retval  VERR_NOT_IMPLEMENTED if the format is not implemented.
    22902383 * @param   pCtx                Context data for the clipboard backend.
    2291  * @param   Format              The format that the VBox would like to receive the data in.
     2384 * @param   uFmt                The format that the VBox would like to receive the data in.
    22922385 * @param   pReq                Read callback request to use. Will be free'd in the callback on success.
    22932386 *                              Otherwise the caller has to free this again on error.
     
    22952388 * @note   We allocate a request structure which must be freed by the worker.
    22962389 */
    2297 int ShClX11ReadDataFromX11(PSHCLX11CTX pCtx, SHCLFORMAT Format, CLIPREADCBREQ *pReq)
     2390int ShClX11ReadDataFromX11(PSHCLX11CTX pCtx, SHCLFORMAT uFmt, CLIPREADCBREQ *pReq)
    22982391{
    22992392    AssertPtrReturn(pReq, VERR_INVALID_POINTER);
    2300 
    23012393    /*
    23022394     * Immediately return if we are not connected to the X server.
     
    23112403    {
    23122404        pX11Req->pCtx     = pCtx;
    2313         pX11Req->uFmtVBox = Format;
     2405        pX11Req->uFmtVBox = uFmt;
    23142406        pX11Req->pReq     = pReq;
    23152407
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-darwin.cpp

    r93115 r93495  
    120120
    121121
    122 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable)
    123 {
    124     RT_NOREF(pTable);
     122int ShClBackendInit(PSHCLBACKEND pBackend, VBOXHGCMSVCFNTABLE *pTable)
     123{
     124    RT_NOREF(pBackend, pTable);
    125125    g_ctx.fTerminate = false;
    126126
     
    139139}
    140140
    141 void ShClBackendDestroy(void)
    142 {
     141void ShClBackendDestroy(PSHCLBACKEND pBackend)
     142{
     143    RT_NOREF(pBackend);
     144
    143145    /*
    144146     * Signal the termination of the polling thread and wait for it to respond.
     
    158160}
    159161
    160 int ShClBackendConnect(PSHCLCLIENT pClient, bool fHeadless)
    161 {
    162     RT_NOREF(fHeadless);
     162int ShClBackendConnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, bool fHeadless)
     163{
     164    RT_NOREF(pBackend, fHeadless);
    163165
    164166    if (g_ctx.pClient != NULL)
     
    178180}
    179181
    180 int ShClBackendSync(PSHCLCLIENT pClient)
    181 {
     182int ShClBackendSync(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
     183{
     184    RT_NOREF(pBackend);
     185
    182186    /* Sync the host clipboard content with the client. */
    183187    ShClSvcLock();
     
    190194}
    191195
    192 int ShClBackendDisconnect(PSHCLCLIENT pClient)
    193 {
     196int ShClBackendDisconnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
     197{
     198    RT_NOREF(pBackend);
     199
    194200    ShClSvcLock();
    195201
     
    201207}
    202208
    203 int ShClBackendFormatAnnounce(PSHCLCLIENT pClient, SHCLFORMATS fFormats)
    204 {
     209int ShClBackendFormatAnnounce(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, SHCLFORMATS fFormats)
     210{
     211    RT_NOREF(pBackend);
     212
    205213    LogFlowFunc(("fFormats=%02X\n", fFormats));
    206214
     
    247255}
    248256
    249 int ShClBackendReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT fFormat,
     257int ShClBackendReadData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT fFormat,
    250258                        void *pvData, uint32_t cbData, uint32_t *pcbActual)
    251259{
     
    255263    AssertPtrReturn(pcbActual, VERR_INVALID_POINTER);
    256264
    257     RT_NOREF(pCmdCtx);
     265    RT_NOREF(pBackend, pCmdCtx);
    258266
    259267    ShClSvcLock();
     
    271279}
    272280
    273 int ShClBackendWriteData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT fFormat, void *pvData, uint32_t cbData)
    274 {
    275     RT_NOREF(pCmdCtx);
     281int ShClBackendWriteData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT fFormat, void *pvData, uint32_t cbData)
     282{
     283    RT_NOREF(pBackend, pCmdCtx);
    276284
    277285    LogFlowFuncEnter();
     
    289297#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    290298
    291 int ShClBackendTransferReadDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
    292 {
    293     RT_NOREF(pClient, pDirData);
    294     return VERR_NOT_IMPLEMENTED;
    295 }
    296 
    297 int ShClBackendTransferWriteDir(PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
    298 {
    299     RT_NOREF(pClient, pDirData);
    300     return VERR_NOT_IMPLEMENTED;
    301 }
    302 
    303 int ShClBackendTransferReadFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
    304 {
    305     RT_NOREF(pClient, pFileHdr);
    306     return VERR_NOT_IMPLEMENTED;
    307 }
    308 
    309 int ShClBackendTransferWriteFileHdr(PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
    310 {
    311     RT_NOREF(pClient, pFileHdr);
    312     return VERR_NOT_IMPLEMENTED;
    313 }
    314 
    315 int ShClBackendTransferReadFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
    316 {
    317     RT_NOREF(pClient, pFileData);
    318     return VERR_NOT_IMPLEMENTED;
    319 }
    320 
    321 int ShClBackendTransferWriteFileData(PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
    322 {
    323     RT_NOREF(pClient, pFileData);
     299int ShClBackendTransferReadDir(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
     300{
     301    RT_NOREF(pBackend, pClient, pDirData);
     302    return VERR_NOT_IMPLEMENTED;
     303}
     304
     305int ShClBackendTransferWriteDir(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLDIRDATA pDirData)
     306{
     307    RT_NOREF(pBackend, pClient, pDirData);
     308    return VERR_NOT_IMPLEMENTED;
     309}
     310
     311int ShClBackendTransferReadFileHdr(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
     312{
     313    RT_NOREF(pBackend, pClient, pFileHdr);
     314    return VERR_NOT_IMPLEMENTED;
     315}
     316
     317int ShClBackendTransferWriteFileHdr(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLFILEHDR pFileHdr)
     318{
     319    RT_NOREF(pBackend, pClient, pFileHdr);
     320    return VERR_NOT_IMPLEMENTED;
     321}
     322
     323int ShClBackendTransferReadFileData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
     324{
     325    RT_NOREF(pBackend, pClient, pFileData);
     326    return VERR_NOT_IMPLEMENTED;
     327}
     328
     329int ShClBackendTransferWriteFileData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLFILEDATA pFileData)
     330{
     331    RT_NOREF(pBackend, pClient, pFileData);
    324332    return VERR_NOT_IMPLEMENTED;
    325333}
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-internal.h

    r93115 r93495  
    139139    struct SHCLCLIENTSTATE *pPrev;
    140140
     141    /** Backend-dependent opaque context structure.
     142     *  This contains data only known to a certain backend implementation.
     143     *  Optional and can be NULL. */
    141144    SHCLCONTEXT            *pCtx;
    142 
    143145    /** The client's HGCM ID. Not related to the session ID below! */
    144146    uint32_t                uClientID;
     
    177179#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
    178180
     181/** Prototypes for the Shared Clipboard backend. */
     182struct SHCLBACKEND;
     183typedef SHCLBACKEND *PSHCLBACKEND;
     184
    179185/**
    180186 * Structure for keeping data per (connected) HGCM client.
     
    182188typedef struct _SHCLCLIENT
    183189{
     190    /** Pointer to associated backend, if any.
     191     *  Might be NULL if not being used. */
     192    PSHCLBACKEND                pBackend;
    184193    /** General client state data. */
    185194    SHCLCLIENTSTATE             State;
     
    296305int ShClSvcGuestDataSignal(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData);
    297306int ShClSvcHostReportFormats(PSHCLCLIENT pClient, SHCLFORMATS fFormats);
     307PSHCLBACKEND ShClSvcGetBackend(void);
    298308uint32_t ShClSvcGetMode(void);
    299309bool ShClSvcGetHeadless(void);
     
    311321/** @} */
    312322
    313 
    314 /** @name Platform-dependent implementations for the Shared Clipboard host service, called *only* by the host service.
     323/** @name Platform-dependent implementations for the Shared Clipboard host service ("backends"),
     324 *        called *only* by the host service.
    315325 * @{
    316326 */
    317327/**
     328 * Structure for keeping Shared Clipboard backend instance data.
     329 */
     330typedef struct SHCLBACKEND
     331{
     332    /** Callback table to use.
     333     *  Some callbacks might be optional and therefore NULL -- see the table for more details. */
     334    SHCLCALLBACKS Callbacks;
     335} SHCLBACKEND;
     336/** Pointer to a Shared Clipboard backend. */
     337typedef SHCLBACKEND *PSHCLBACKEND;
     338
     339/**
    318340 * Called on initialization.
    319341 *
     342 * @param   pBackend    Shared Clipboard backend to initialize.
    320343 * @param   pTable      The HGCM service call and parameter table.  Mainly for
    321344 *                      adjusting the limits.
    322345 */
    323 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable);
     346int ShClBackendInit(PSHCLBACKEND pBackend, VBOXHGCMSVCFNTABLE *pTable);
    324347
    325348/**
    326349 * Called on destruction.
    327  */
    328 void ShClBackendDestroy(void);
     350 *
     351 * @param   pBackend    Shared Clipboard backend to destroy.
     352 */
     353void ShClBackendDestroy(PSHCLBACKEND pBackend);
    329354
    330355/**
     
    332357 *
    333358 * @returns VBox status code.
     359 * @param   pBackend            Shared Clipboard backend to set callbacks for.
     360 * @param   pCallbacks          Backend callbacks to use.
     361 *                              When NULL is specified, the backend's default callbacks are being used.
     362 */
     363void ShClBackendSetCallbacks(PSHCLBACKEND pBackend, PSHCLCALLBACKS pCallbacks);
     364
     365/**
     366 * Called when a new HGCM client connects.
     367 *
     368 * @returns VBox status code.
     369 * @param   pBackend            Shared Clipboard backend to connect to.
    334370 * @param   pClient             Shared Clipboard client context.
    335371 * @param   fHeadless           Whether this is a headless connection or not.
    336372 */
    337 int ShClBackendConnect(PSHCLCLIENT pClient, bool fHeadless);
     373int ShClBackendConnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, bool fHeadless);
    338374
    339375/**
     
    341377 *
    342378 * @returns VBox status code.
    343  * @param   pClient             Shared Clipboard client context.
    344  */
    345 int ShClBackendDisconnect(PSHCLCLIENT pClient);
     379 * @param   pBackend            Shared Clipboard backend to disconnect from.
     380 * @param   pClient             Shared Clipboard client context.
     381 */
     382int ShClBackendDisconnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient);
    346383
    347384/**
     
    349386 *
    350387 * @returns VBox status code.
     388 * @param   pBackend            Shared Clipboard backend to announce formats to.
    351389 * @param   pClient             Shared Clipboard client context.
    352390 * @param   fFormats            The announced formats from the guest,
    353391 *                              VBOX_SHCL_FMT_XXX.
    354392 */
    355 int ShClBackendFormatAnnounce(PSHCLCLIENT pClient, SHCLFORMATS fFormats);
     393int ShClBackendFormatAnnounce(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, SHCLFORMATS fFormats);
    356394
    357395/**
     
    359397 *
    360398 * @returns VBox status code.
     399 * @param   pBackend            Shared Clipboard backend to read data from.
    361400 * @param   pClient             Shared Clipboard client context.
    362401 * @param   pCmdCtx             Shared Clipboard command context.
     
    369408 *          data
    370409 */
    371 int ShClBackendReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat,
     410int ShClBackendReadData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat,
    372411                        void *pvData, uint32_t cbData, uint32_t *pcbActual);
    373412
     
    376415 *
    377416 * @returns VBox status code.
     417 * @param   pBackend            Shared Clipboard backend to write data to.
    378418 * @param   pClient             Shared Clipboard client context.
    379419 * @param   pCmdCtx             Shared Clipboard command context.
     
    382422 * @param   cbData              Size (in bytes) of buffer clipboard data to write.
    383423 */
    384 int ShClBackendWriteData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData);
     424int ShClBackendWriteData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData);
    385425
    386426/**
     
    388428 *
    389429 * @returns VBox status code.
    390  * @param   pClient             Shared Clipboard client context.
    391  */
    392 int ShClBackendSync(PSHCLCLIENT pClient);
     430 * @param   pBackend            Shared Clipboard backend to synchronize.
     431 * @param   pClient             Shared Clipboard client context.
     432 */
     433int ShClBackendSync(PSHCLBACKEND pBackend, PSHCLCLIENT pClient);
    393434/** @} */
    394435
     
    401442 *
    402443 * @returns VBox status code.
     444 * @param   pBackend            Shared Clipboard backend to use.
    403445 * @param   pClient             Shared Clipboard client context.
    404446 * @param   pTransfer           Shared Clipboard transfer created.
    405447 */
    406 int ShClBackendTransferCreate(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
     448int ShClBackendTransferCreate(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
    407449/**
    408450 * Called before a transfer gets destroyed.
    409451 *
    410452 * @returns VBox status code.
     453 * @param   pBackend            Shared Clipboard backend to use.
    411454 * @param   pClient             Shared Clipboard client context.
    412455 * @param   pTransfer           Shared Clipboard transfer to destroy.
    413456 */
    414 int ShClBackendTransferDestroy(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
     457int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
    415458/**
    416459 * Called when getting (determining) the transfer roots on the host side.
    417460 *
    418461 * @returns VBox status code.
     462 * @param   pBackend            Shared Clipboard backend to use.
    419463 * @param   pClient             Shared Clipboard client context.
    420464 * @param   pTransfer           Shared Clipboard transfer to get roots for.
    421465 */
    422 int ShClBackendTransferGetRoots(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
     466int ShClBackendTransferGetRoots(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer);
    423467/** @} */
    424468#endif
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-transfers.cpp

    r93115 r93495  
    7777    PSHCLTRANSFER pTransfer;
    7878    while ((pTransfer = ShClTransferCtxGetTransferByIndex(&pClient->Transfers.Ctx, uIdx++)))
    79         ShClBackendTransferDestroy(pClient, pTransfer);
     79        ShClBackendTransferDestroy(pClient->pBackend, pClient, pTransfer);
    8080
    8181    ShClTransferCtxDestroy(&pClient->Transfers.Ctx);
     
    13641364            {
    13651365                /* Get roots if this is a local write transfer (host -> guest). */
    1366                 rc = ShClBackendTransferGetRoots(pClient, pTransfer);
     1366                rc = ShClBackendTransferGetRoots(pClient->pBackend, pClient, pTransfer);
    13671367            }
    13681368            else
     
    18931893                    if (RT_SUCCESS(rc))
    18941894                    {
    1895                         rc = ShClBackendTransferCreate(pClient, pTransfer);
     1895                        rc = ShClBackendTransferCreate(pClient->pBackend, pClient, pTransfer);
    18961896                        if (RT_SUCCESS(rc))
    18971897                        {
     
    19541954            if (RT_FAILURE(rc))
    19551955            {
    1956                 ShClBackendTransferDestroy(pClient, pTransfer);
     1956                ShClBackendTransferDestroy(pClient->pBackend, pClient, pTransfer);
    19571957                ShClTransferDestroy(pTransfer);
    19581958
     
    20092009    if (RT_SUCCESS(rc2))
    20102010    {
    2011         ShClBackendTransferDestroy(pClient, pTransfer);
     2011        ShClBackendTransferDestroy(pClient->pBackend, pClient, pTransfer);
    20122012        ShClTransferDestroy(pTransfer);
    20132013        pTransfer = NULL;
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-win.cpp

    r93115 r93495  
    622622 */
    623623
    624 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable)
    625 {
    626     RT_NOREF(pTable);
     624int ShClBackendInit(PSHCLBACKEND pBackend, VBOXHGCMSVCFNTABLE *pTable)
     625{
     626    RT_NOREF(pBackend, pTable);
    627627#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    628628    HRESULT hr = OleInitialize(NULL);
     
    639639}
    640640
    641 void ShClBackendDestroy(void)
    642 {
     641void ShClBackendDestroy(PSHCLBACKEND pBackend)
     642{
     643    RT_NOREF(pBackend);
     644
    643645#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    644646    OleSetClipboard(NULL); /* Make sure to flush the clipboard on destruction. */
     
    647649}
    648650
    649 int ShClBackendConnect(PSHCLCLIENT pClient, bool fHeadless)
    650 {
    651     RT_NOREF(fHeadless);
     651int ShClBackendConnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, bool fHeadless)
     652{
     653    RT_NOREF(pBackend, fHeadless);
    652654
    653655    LogFlowFuncEnter();
     
    680682}
    681683
    682 int ShClBackendSync(PSHCLCLIENT pClient)
    683 {
     684int ShClBackendSync(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
     685{
     686    RT_NOREF(pBackend);
     687
    684688    /* Sync the host clipboard content with the client. */
    685689    return vboxClipboardSvcWinSyncInternal(pClient->State.pCtx);
    686690}
    687691
    688 int ShClBackendDisconnect(PSHCLCLIENT pClient)
    689 {
     692int ShClBackendDisconnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
     693{
     694    RT_NOREF(pBackend);
     695
    690696    AssertPtrReturn(pClient, VERR_INVALID_POINTER);
    691697
     
    727733}
    728734
    729 int ShClBackendFormatAnnounce(PSHCLCLIENT pClient, SHCLFORMATS fFormats)
    730 {
     735int ShClBackendFormatAnnounce(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, SHCLFORMATS fFormats)
     736{
     737    RT_NOREF(pBackend);
     738
    731739    AssertPtrReturn(pClient, VERR_INVALID_POINTER);
    732740
     
    747755}
    748756
    749 int ShClBackendReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
     757int ShClBackendReadData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
    750758                        SHCLFORMAT uFmt, void *pvData, uint32_t cbData, uint32_t *pcbActual)
    751759{
     
    755763    AssertPtrReturn(pcbActual, VERR_INVALID_POINTER);
    756764
    757     RT_NOREF(pCmdCtx);
     765    RT_NOREF(pBackend, pCmdCtx);
    758766
    759767    AssertPtrReturn(pClient->State.pCtx, VERR_INVALID_POINTER);
     
    861869}
    862870
    863 int ShClBackendWriteData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
     871int ShClBackendWriteData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
    864872                         SHCLFORMAT uFormat, void *pvData, uint32_t cbData)
    865873{
    866     RT_NOREF(pClient, pCmdCtx, uFormat, pvData, cbData);
     874    RT_NOREF(pBackend, pClient, pCmdCtx, uFormat, pvData, cbData);
    867875
    868876    LogFlowFuncEnter();
     
    875883
    876884#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    877 int ShClBackendTransferCreate(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
    878 {
    879     RT_NOREF(pClient, pTransfer);
     885int ShClBackendTransferCreate(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     886{
     887    RT_NOREF(pBackend, pClient, pTransfer);
    880888
    881889    LogFlowFuncEnter();
     
    884892}
    885893
    886 int ShClBackendTransferDestroy(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
    887 {
     894int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     895{
     896    RT_NOREF(pBackend);
     897
    888898    LogFlowFuncEnter();
    889899
     
    893903}
    894904
    895 int ShClBackendTransferGetRoots(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
    896 {
     905int ShClBackendTransferGetRoots(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     906{
     907    RT_NOREF(pBackend);
     908
    897909    LogFlowFuncEnter();
    898910
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11-stubs.cpp

    r93115 r93495  
    4141 * Initialise the host side of the shared clipboard - called by the hgcm layer.
    4242 */
    43 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable)
     43int ShClBackendInit(PSHCLBACKEND pBackend, VBOXHGCMSVCFNTABLE *pTable)
    4444{
    4545    RT_NOREF(pTable);
     
    5151 * Terminate the host side of the shared clipboard - called by the hgcm layer.
    5252 */
    53 void ShClBackendDestroy(void)
     53void ShClBackendDestroy(PSHCLBACKEND pBackend)
    5454{
     55    RT_NOREF(pBackend);
    5556    LogFlowFunc(("called, returning\n"));
    5657}
    5758
    58 int ShClBackendConnect(PSHCLCLIENT pClient, bool fHeadless)
     59int ShClBackendConnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, bool fHeadless)
    5960{
    60     RT_NOREF(pClient, fHeadless);
     61    RT_NOREF(pBackend, pClient, fHeadless);
    6162    LogFlowFunc(("called, returning VINF_SUCCESS\n"));
    6263    return VINF_SUCCESS;
     
    6768 * after a save and restore of the guest.
    6869 */
    69 int ShClBackendSync(PSHCLCLIENT pClient)
     70int ShClBackendSync(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
    7071{
    71     RT_NOREF(pClient);
     72    RT_NOREF(pBackend, pClient);
    7273    LogFlowFunc(("called, returning VINF_SUCCESS\n"));
    7374    return VINF_SUCCESS;
    7475}
    7576
    76 int ShClBackendDisconnect(PSHCLCLIENT pClient)
     77int ShClBackendDisconnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
    7778{
    78     RT_NOREF(pClient);
     79    RT_NOREF(pBackend, pClient);
    7980    return VINF_SUCCESS;
    8081}
     
    8485 * Called by the HGCM clipboard subsystem.
    8586 */
    86 int ShClBackendFormatAnnounce(PSHCLCLIENT pClient, SHCLFORMATS fFormats)
     87int ShClBackendFormatAnnounce(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, SHCLFORMATS fFormats)
    8788{
    88     RT_NOREF(pClient, fFormats);
     89    RT_NOREF(pBackend, pClient, fFormats);
    8990    return VINF_SUCCESS;
    9091}
     
    9394 * Called by the HGCM clipboard subsystem when the guest wants to read the host clipboard.
    9495 */
    95 int ShClBackendReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
     96int ShClBackendReadData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
    9697                        SHCLFORMAT uFormat, void *pvData, uint32_t cbData, uint32_t *pcbActual)
    9798{
    98     RT_NOREF(pClient, pCmdCtx, uFormat, pvData, cbData);
     99    RT_NOREF(pBackend, pClient, pCmdCtx, uFormat, pvData, cbData);
    99100
    100101    /* No data available. */
     
    104105}
    105106
    106 int ShClBackendWriteData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
     107int ShClBackendWriteData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx,
    107108                         SHCLFORMAT uFormat, void *pvData, uint32_t cbData)
    108109{
    109     RT_NOREF(pClient, pCmdCtx, uFormat, pvData, cbData);
     110    RT_NOREF(pBackend, pClient, pCmdCtx, uFormat, pvData, cbData);
    110111    return VERR_NOT_IMPLEMENTED;
    111112}
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp

    r93326 r93495  
    6060};
    6161
    62 
    63 int ShClBackendInit(VBOXHGCMSVCFNTABLE *pTable)
    64 {
     62/*********************************************************************************************************************************
     63*   Prototypes                                                                                                                   *
     64*********************************************************************************************************************************/
     65static DECLCALLBACK(int) shClReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats, void *pvUser);
     66static DECLCALLBACK(int) shClSendDataToDestCallback(PSHCLCONTEXT pCtx, void *pv, uint32_t cb, void *pvUser);
     67static DECLCALLBACK(int) shClRequestDataFromSourceCallback(PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser);
     68
     69
     70int ShClBackendInit(PSHCLBACKEND pBackend, VBOXHGCMSVCFNTABLE *pTable)
     71{
     72    RT_NOREF(pBackend);
     73
    6574    LogFlowFuncEnter();
    6675
     
    6978        pTable->acMaxClients[i] = RT_MIN(VBOX_SHARED_CLIPBOARD_X11_CONNECTIONS_MAX, pTable->acMaxClients[i]);
    7079
     80    RT_ZERO(pBackend->Callbacks);
     81    /* Use internal callbacks by default. */
     82    pBackend->Callbacks.pfnReportFormats           = shClReportFormatsCallback;
     83    pBackend->Callbacks.pfnOnRequestDataFromSource = shClRequestDataFromSourceCallback;
     84    pBackend->Callbacks.pfnOnSendDataToDest        = shClSendDataToDestCallback;
     85
    7186    return VINF_SUCCESS;
    7287}
    7388
    74 void ShClBackendDestroy(void)
    75 {
     89void ShClBackendDestroy(PSHCLBACKEND pBackend)
     90{
     91    RT_NOREF(pBackend);
     92
    7693    LogFlowFuncEnter();
     94}
     95
     96void ShClBackendSetCallbacks(PSHCLBACKEND pBackend, PSHCLCALLBACKS pCallbacks)
     97{
     98#define SET_FN_IF_NOT_NULL(a_Fn) \
     99    if (pCallbacks->pfn##a_Fn) \
     100        pBackend->Callbacks.pfn##a_Fn = pCallbacks->pfn##a_Fn;
     101
     102    SET_FN_IF_NOT_NULL(ReportFormats);
     103    SET_FN_IF_NOT_NULL(OnClipboardRead);
     104    SET_FN_IF_NOT_NULL(OnClipboardWrite);
     105    SET_FN_IF_NOT_NULL(OnRequestDataFromSource);
     106    SET_FN_IF_NOT_NULL(OnSendDataToDest);
     107
     108#undef SET_FN_IF_NOT_NULL
    77109}
    78110
     
    81113 *        the clipboard and leave ownership to X11.
    82114 */
    83 int ShClBackendConnect(PSHCLCLIENT pClient, bool fHeadless)
     115int ShClBackendConnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, bool fHeadless)
    84116{
    85117    int rc;
     
    99131        if (RT_SUCCESS(rc))
    100132        {
    101             rc = ShClX11Init(&pCtx->X11, pCtx, fHeadless);
     133            rc = ShClX11Init(&pCtx->X11, &pBackend->Callbacks, pCtx, fHeadless);
    102134            if (RT_SUCCESS(rc))
    103135            {
     
    133165}
    134166
    135 int ShClBackendSync(PSHCLCLIENT pClient)
    136 {
     167int ShClBackendSync(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
     168{
     169    RT_NOREF(pBackend);
     170
    137171    LogFlowFuncEnter();
    138172
     
    149183 * Note!  Host glue code
    150184 */
    151 int ShClBackendDisconnect(PSHCLCLIENT pClient)
    152 {
     185int ShClBackendDisconnect(PSHCLBACKEND pBackend, PSHCLCLIENT pClient)
     186{
     187    RT_NOREF(pBackend);
     188
    153189    LogFlowFuncEnter();
    154190
     
    178214}
    179215
    180 int ShClBackendFormatAnnounce(PSHCLCLIENT pClient, SHCLFORMATS fFormats)
    181 {
     216int ShClBackendFormatAnnounce(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, SHCLFORMATS fFormats)
     217{
     218    RT_NOREF(pBackend);
     219
    182220    int rc = ShClX11ReportFormatsToX11(&pClient->State.pCtx->X11, fFormats);
    183221
     
    205243 *         the backend code.
    206244 */
    207 int ShClBackendReadData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat,
     245int ShClBackendReadData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat,
    208246                        void *pvData, uint32_t cbData, uint32_t *pcbActual)
    209247{
     248    RT_NOREF(pBackend);
     249
    210250    AssertPtrReturn(pClient,   VERR_INVALID_POINTER);
    211251    AssertPtrReturn(pCmdCtx,   VERR_INVALID_POINTER);
     
    215255    RT_NOREF(pCmdCtx);
    216256
    217     LogFlowFunc(("pClient=%p, uFormat=%02X, pv=%p, cb=%u, pcbActual=%p\n",
     257    LogFlowFunc(("pClient=%p, uFormat=%#x, pv=%p, cb=%RU32, pcbActual=%p\n",
    218258                 pClient, uFormat, pvData, cbData, pcbActual));
    219259
     
    269309}
    270310
    271 int ShClBackendWriteData(PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData)
    272 {
    273     RT_NOREF(pClient, pCmdCtx, uFormat, pvData, cbData);
     311int ShClBackendWriteData(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLCLIENTCMDCTX pCmdCtx, SHCLFORMAT uFormat, void *pvData, uint32_t cbData)
     312{
     313    RT_NOREF(pBackend, pClient, pCmdCtx, uFormat, pvData, cbData);
    274314
    275315    LogFlowFuncEnter();
     
    281321}
    282322
    283 DECLCALLBACK(void) ShClX11ReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats)
    284 {
     323/** @copydoc SHCLBACKENDCALLBACKS::pfnReportFormats */
     324static DECLCALLBACK(int) shClReportFormatsCallback(PSHCLCONTEXT pCtx, uint32_t fFormats, void *pvUser)
     325{
     326    RT_NOREF(pvUser);
     327
    285328    LogFlowFunc(("pCtx=%p, fFormats=%#x\n", pCtx, fFormats));
    286329
     
    305348
    306349    LogFlowFuncLeaveRC(rc);
    307 }
    308 
    309 DECLCALLBACK(void) ShClX11ReportDataCallback(PSHCLCONTEXT pCtx, int rcCompletion,
    310                                              CLIPREADCBREQ *pReq, void *pv, uint32_t cb)
    311 {
    312     AssertPtrReturnVoid(pCtx);
    313     AssertPtrReturnVoid(pReq);
    314 
    315     LogFlowFunc(("rcCompletion=%Rrc, pReq=%p, pv=%p, cb=%RU32, idEvent=%RU32\n", rcCompletion, pReq, pv, cb, pReq->idEvent));
     350    return rc;
     351}
     352
     353/** @copydoc SHCLBACKENDCALLBACKS::pfnOnSendDataToDest */
     354static DECLCALLBACK(int) shClSendDataToDestCallback(PSHCLCONTEXT pCtx, void *pv, uint32_t cb, void *pvUser)
     355{
     356    AssertPtrReturn(pCtx,   VERR_INVALID_POINTER);
     357    AssertPtrReturn(pvUser, VERR_INVALID_POINTER);
     358
     359    PSHCLX11READDATAREQ pData = (PSHCLX11READDATAREQ)pvUser;
     360    CLIPREADCBREQ      *pReq  = pData->pReq;
     361
     362    LogFlowFunc(("rcCompletion=%Rrc, pReq=%p, pv=%p, cb=%RU32, idEvent=%RU32\n",
     363                 pData->rcCompletion, pReq, pv, cb, pReq->idEvent));
    316364
    317365    if (pReq->idEvent != NIL_SHCLEVENTID)
     
    320368
    321369        PSHCLEVENTPAYLOAD pPayload = NULL;
    322         if (   RT_SUCCESS(rcCompletion)
     370        if (   RT_SUCCESS(pData->rcCompletion)
    323371            && pv
    324372            && cb)
     
    348396        RTMemFree(pReq);
    349397
    350     LogRel2(("Shared Clipboard: Reading X11 clipboard data from host completed with %Rrc\n", rcCompletion));
    351 }
    352 
    353 DECLCALLBACK(int) ShClX11RequestDataCallback(PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb)
    354 {
     398    LogRel2(("Shared Clipboard: Reading X11 clipboard data from host completed with %Rrc\n", pData->rcCompletion));
     399
     400    return VINF_SUCCESS;
     401}
     402
     403/** @copydoc SHCLBACKENDCALLBACKS::pfnOnRequestDataFromSource */
     404static DECLCALLBACK(int) shClRequestDataFromSourceCallback(PSHCLCONTEXT pCtx, SHCLFORMAT uFmt, void **ppv, uint32_t *pcb, void *pvUser)
     405{
     406    RT_NOREF(pvUser);
     407
    355408    LogFlowFunc(("pCtx=%p, uFmt=0x%x\n", pCtx, uFmt));
    356409
     
    437490#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    438491
    439 int ShClBackendTransferCreate(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
    440 {
     492int ShClBackendTransferCreate(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     493{
     494    RT_NOREF(pBackend);
    441495#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP
    442496    return ShClHttpTransferRegister(&pClient->State.pCtx->X11.HttpCtx, pTransfer);
     
    447501}
    448502
    449 int ShClBackendTransferDestroy(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
    450 {
     503int ShClBackendTransferDestroy(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     504{
     505    RT_NOREF(pBackend);
    451506#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS_HTTP
    452507    return ShClHttpTransferUnregister(&pClient->State.pCtx->X11.HttpCtx, pTransfer);
     
    458513}
    459514
    460 int ShClBackendTransferGetRoots(PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
    461 {
     515int ShClBackendTransferGetRoots(PSHCLBACKEND pBackend, PSHCLCLIENT pClient, PSHCLTRANSFER pTransfer)
     516{
     517    RT_NOREF(pBackend);
     518
    462519    LogFlowFuncEnter();
    463520
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r93444 r93495  
    242242*   Global Variables                                                                                                             *
    243243*********************************************************************************************************************************/
     244/** The backend instance data.
     245 *  Only one backend at a time is supported currently. */
     246SHCLBACKEND         g_ShClBackend;
    244247PVBOXHGCMSVCHELPERS g_pHelpers;
    245248
     
    282285{
    283286    return g_uMode;
     287}
     288
     289/**
     290 * Returns the Shared Clipboard backend in use.
     291 *
     292 * @returns Pointer to backend instance.
     293 */
     294PSHCLBACKEND ShClSvcGetBackend(void)
     295{
     296    return &g_ShClBackend;
    284297}
    285298
     
    15631576                    }
    15641577#endif
    1565                     rc = ShClBackendFormatAnnounce(pClient, fFormats);
     1578                    rc = ShClBackendFormatAnnounce(&g_ShClBackend, pClient, fFormats);
    15661579                    if (RT_FAILURE(rc))
    15671580                        LogRel(("Shared Clipboard: Reporting guest clipboard formats to the host failed with %Rrc\n", rc));
     
    17171730    else
    17181731    {
    1719         rc = ShClBackendReadData(pClient, &cmdCtx, uFormat, pvData, cbData, &cbActual);
     1732        rc = ShClBackendReadData(&g_ShClBackend, pClient, &cmdCtx, uFormat, pvData, cbData, &cbActual);
    17201733        if (RT_SUCCESS(rc))
    17211734            LogRel2(("Shared Clipboard: Read host clipboard data (max %RU32 bytes), got %RU32 bytes\n", cbData, cbActual));
     
    18921905    {
    18931906        /* Let the backend implementation know. */
    1894         rc = ShClBackendWriteData(pClient, &cmdCtx, uFormat, pvData, cbData);
     1907        rc = ShClBackendWriteData(&g_ShClBackend, pClient, &cmdCtx, uFormat, pvData, cbData);
    18951908        if (RT_FAILURE(rc))
    18961909            LogRel(("Shared Clipboard: Writing guest clipboard data to the host failed with %Rrc\n", rc));
     
    19701983        shClSvcModeSet(VBOX_SHCL_MODE_OFF);
    19711984
    1972         rc = ShClBackendInit(pTable);
     1985        rc = ShClBackendInit(ShClSvcGetBackend(), pTable);
    19731986
    19741987        /* Clean up on failure, because 'svnUnload' will not be called
     
    19882001    LogFlowFuncEnter();
    19892002
    1990     ShClBackendDestroy();
     2003    ShClBackendDestroy(ShClSvcGetBackend());
    19912004
    19922005    RTCritSectDelete(&g_CritSect);
     
    20162029#endif
    20172030
    2018     ShClBackendDisconnect(pClient);
     2031    ShClBackendDisconnect(&g_ShClBackend, pClient);
    20192032
    20202033    shClSvcClientDestroy(pClient);
     
    20392052         *        crash any worse that racing map insertion/removal. */
    20402053        g_mapClients[u32ClientID] = pClient; /** @todo Handle OOM / collisions? */
    2041 
    2042         rc = ShClBackendConnect(pClient, ShClSvcGetHeadless());
     2054        rc = ShClBackendConnect(&g_ShClBackend, pClient, ShClSvcGetHeadless());
    20432055        if (RT_SUCCESS(rc))
    20442056        {
    20452057            /* Sync the host clipboard content with the client. */
    2046             rc = ShClBackendSync(pClient);
     2058            rc = ShClBackendSync(&g_ShClBackend, pClient);
    20472059            if (RT_SUCCESS(rc))
    20482060            {
     
    20632075
    20642076            LogFunc(("ShClBackendSync failed: %Rrc\n", rc));
    2065             ShClBackendDisconnect(pClient);
     2077            ShClBackendDisconnect(&g_ShClBackend, pClient);
    20662078        }
    20672079        else
     
    26542666
    26552667    /* Actual host data are to be reported to guest (SYNC). */
    2656     ShClBackendSync(pClient);
     2668    ShClBackendSync(&g_ShClBackend, pClient);
    26572669
    26582670#else  /* UNIT_TEST */
  • trunk/src/VBox/HostServices/SharedClipboard/testcase/Makefile.kmk

    r93401 r93495  
    2020
    2121if defined(VBOX_WITH_TESTCASES) && !defined(VBOX_ONLY_ADDITIONS) && !defined(VBOX_ONLY_SDK)
     22
     23 if 0
     24        #
     25        # Testcase which mocks HGCM to also test the VbglR3-side of Shared Clipboard.
     26        #
     27        # Goal is to use and test as much guest side code as possible as a self-contained
     28        # binary on the host here.
     29        #
     30        # Note: No #ifdef TESTCASE hacks or similar allowed, has to run
     31        #       without #ifdef modifications to the core code!
     32        #
     33        PROGRAMS += tstClipboardMockHGCM
     34        tstClipboardMockHGCM_TEMPLATE = VBOXR3TSTEXE
     35        tstClipboardMockHGCM_DEFS     = VBOX_WITH_HGCM VBOX_WITH_SHARED_CLIPBOARD
     36        tstClipboardMockHGCM_SOURCES  = \
     37                ../VBoxSharedClipboardSvc.cpp \
     38                $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp \
     39                $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp \
     40                $(PATH_ROOT)/src/VBox/HostServices/common/message.cpp \
     41                tstClipboardMockHGCM.cpp
     42        tstClipboardMockHGCM_LIBS     = $(LIB_RUNTIME)
     43
     44        if1of ($(KBUILD_TARGET), linux)
     45         tstClipboardMockHGCM_SOURCES.linux  += \
     46                $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp \
     47                ../VBoxSharedClipboardSvc-x11.cpp
     48         tstClipboardMockHGCM_LIBPATH = \
     49                $(VBOX_LIBPATH_X11)
     50         tstClipboardMockHGCM_LIBS   += \
     51                Xt \
     52                X11
     53        endif
     54
     55        tstClipboardMockHGCM_SOURCES.darwin += ../VBoxSharedClipboardSvc-darwin.cpp
     56        tstClipboardMockHGCM_SOURCES.win    += ../VBoxSharedClipboardSvc-win.cpp
     57
     58        tstClipboardMockHGCM_CLEAN           = $(tstClipboardMockHGCM_0_OUTDIR)/tstClipboardMockHGCM.run
     59
     60        if defined(VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS)
     61         tstClipboardMockHGCM_DEFS    += VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
     62         tstClipboardMockHGCM_SOURCES += \
     63                ../VBoxSharedClipboardSvc-transfers.cpp \
     64         $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-transfers.cpp
     65        endif
     66 endif
    2267
    2368 #
  • trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceHost.cpp

    r93115 r93495  
    310310}
    311311
    312 int ShClBackendInit(VBOXHGCMSVCFNTABLE *) { return VINF_SUCCESS; }
    313 void ShClBackendDestroy() { }
    314 int ShClBackendDisconnect(PSHCLCLIENT) { return VINF_SUCCESS; }
    315 int ShClBackendConnect(PSHCLCLIENT, bool) { return VINF_SUCCESS; }
    316 int ShClBackendFormatAnnounce(PSHCLCLIENT, SHCLFORMATS) { AssertFailed(); return VINF_SUCCESS; }
    317 int ShClBackendReadData(PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t, unsigned int *) { AssertFailed(); return VERR_WRONG_ORDER; }
    318 int ShClBackendWriteData(PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t) { AssertFailed(); return VINF_SUCCESS; }
    319 int ShClBackendSync(PSHCLCLIENT) { return VINF_SUCCESS; }
     312int ShClBackendInit(PSHCLBACKEND, VBOXHGCMSVCFNTABLE *) { return VINF_SUCCESS; }
     313void ShClBackendDestroy(PSHCLBACKEND) { }
     314int ShClBackendDisconnect(PSHCLBACKEND, PSHCLCLIENT) { return VINF_SUCCESS; }
     315int ShClBackendConnect(PSHCLBACKEND, PSHCLCLIENT, bool) { return VINF_SUCCESS; }
     316int ShClBackendFormatAnnounce(PSHCLBACKEND, PSHCLCLIENT, SHCLFORMATS) { AssertFailed(); return VINF_SUCCESS; }
     317int ShClBackendReadData(PSHCLBACKEND, PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t, unsigned int *) { AssertFailed(); return VERR_WRONG_ORDER; }
     318int ShClBackendWriteData(PSHCLBACKEND, PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t) { AssertFailed(); return VINF_SUCCESS; }
     319int ShClBackendSync(PSHCLBACKEND, PSHCLCLIENT) { return VINF_SUCCESS; }
    320320
    321321#ifdef VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS
    322 int ShClBackendTransferCreate(PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; }
    323 int ShClBackendTransferDestroy(PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; }
    324 int ShClBackendTransferGetRoots(PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; }
     322int ShClBackendTransferCreate(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; }
     323int ShClBackendTransferDestroy(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; }
     324int ShClBackendTransferGetRoots(PSHCLBACKEND, PSHCLCLIENT, PSHCLTRANSFER) { return VINF_SUCCESS; }
    325325#endif /* VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS */
    326326
  • trunk/src/VBox/HostServices/SharedClipboard/testcase/tstClipboardServiceImpl.cpp

    r93401 r93495  
    2727#include <iprt/test.h>
    2828
    29 extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable);
     29extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad(VBOXHGCMSVCFNTABLE *ptable);
    3030
    3131static SHCLCLIENT g_Client;
     
    5555}
    5656
    57 int ShClBackendInit(VBOXHGCMSVCFNTABLE *) { return VINF_SUCCESS; }
    58 void ShClBackendDestroy(void) { }
    59 int ShClBackendDisconnect(PSHCLCLIENT) { return VINF_SUCCESS; }
    60 int ShClBackendConnect(PSHCLCLIENT, bool) { return VINF_SUCCESS; }
    61 int ShClBackendFormatAnnounce(PSHCLCLIENT, SHCLFORMATS) { AssertFailed(); return VINF_SUCCESS; }
    62 int ShClBackendReadData(PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t, unsigned int *) { AssertFailed(); return VERR_WRONG_ORDER; }
    63 int ShClBackendWriteData(PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t) { AssertFailed(); return VINF_SUCCESS; }
    64 int ShClBackendSync(PSHCLCLIENT) { return VINF_SUCCESS; }
     57int ShClBackendInit(PSHCLBACKEND, VBOXHGCMSVCFNTABLE *) { return VINF_SUCCESS; }
     58void ShClBackendDestroy(PSHCLBACKEND) { }
     59int ShClBackendDisconnect(PSHCLBACKEND, PSHCLCLIENT) { return VINF_SUCCESS; }
     60int ShClBackendConnect(PSHCLBACKEND, PSHCLCLIENT, bool) { return VINF_SUCCESS; }
     61int ShClBackendFormatAnnounce(PSHCLBACKEND, PSHCLCLIENT, SHCLFORMATS) { AssertFailed(); return VINF_SUCCESS; }
     62int ShClBackendReadData(PSHCLBACKEND, PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t, unsigned int *) { AssertFailed(); return VERR_WRONG_ORDER; }
     63int ShClBackendWriteData(PSHCLBACKEND, PSHCLCLIENT, PSHCLCLIENTCMDCTX, SHCLFORMAT, void *, uint32_t) { AssertFailed(); return VINF_SUCCESS; }
     64int ShClBackendSync(PSHCLBACKEND, PSHCLCLIENT) { return VINF_SUCCESS; }
    6565
    6666static void testAnnounceAndReadData(void)
Note: See TracChangeset for help on using the changeset viewer.

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