VirtualBox

Changeset 103323 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 12, 2024 6:21:23 PM (12 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
161624
Message:

Shared Clipboard: Condensed the X11 clipboard reading code even more (also removes duplicate code); added ShClX11ReadDataFromX11Ex() for that.

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard-x11.cpp

    r102920 r103323  
    7979        case SHCLTRANSFERDIR_TO_REMOTE: /* G->H */
    8080        {
    81             PSHCLEVENT pEvent;
    82             rc = ShClEventSourceGenerateAndRegisterEvent(&pCtx->EventSrc, &pEvent);
     81            void    *pvData;
     82            uint32_t cbData;
     83            rc = ShClX11ReadDataFromX11Ex(&g_Ctx.X11, &pCtx->EventSrc, SHCL_TIMEOUT_DEFAULT_MS, VBOX_SHCL_FMT_URI_LIST,
     84                                          &pvData, &cbData);
    8385            if (RT_SUCCESS(rc))
    8486            {
    85                 rc = ShClX11ReadDataFromX11Async(&g_Ctx.X11, VBOX_SHCL_FMT_URI_LIST, UINT32_MAX, pEvent);
    86                 if (RT_SUCCESS(rc))
    87                 {
    88                     int               rcEvent;
    89                     PSHCLEVENTPAYLOAD pPayload;
    90                     rc = ShClEventWaitEx(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &rcEvent, &pPayload);
    91                     if (RT_SUCCESS(rc))
    92                     {
    93                         if (pPayload)
    94                         {
    95                             AssertReturnVoid(pPayload->cbData == sizeof(SHCLX11RESPONSE));
    96                             AssertReturnVoid(pPayload->pvData);
    97                             PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData;
    98                             AssertReturnVoid(pResp->enmType == SHCLX11EVENTTYPE_READ);
    99 
    100                             rc = ShClTransferRootsInitFromStringListEx(pTransfer, (const char *)pResp->Read.pvData, pResp->Read.cbData,
    101                                                                        "\n" /* X11-based Desktop environments separate entries with "\n" */);
    102 
    103                             RTMemFree(pResp->Read.pvData);
    104                             pResp->Read.cbData = 0;
    105 
    106                             ShClPayloadFree(pPayload);
    107                         }
    108                         else /* No payload given; could happen on invalid / not-expected formats. */
    109                             rc = VERR_NO_DATA;
    110                     }
    111                     else if (rc == VERR_SHCLPB_EVENT_FAILED)
    112                         rc = rcEvent;
    113                 }
    114 
    115                 ShClEventRelease(pEvent);
    116                 pEvent = NULL;
     87                rc = ShClTransferRootsInitFromStringListEx(pTransfer, (const char *)pvData, cbData,
     88                                                           "\n" /* X11-based Desktop environments separate entries with "\n" */);
     89                RTMemFree(pvData);
    11790            }
    11891            break;
     
    528501                case VBGLR3CLIPBOARDEVENTTYPE_READ_DATA:
    529502                {
    530                     PSHCLEVENT pReadDataEvent;
    531                     rc = ShClEventSourceGenerateAndRegisterEvent(&pCtx->EventSrc, &pReadDataEvent);
     503                    void    *pvData;
     504                    uint32_t cbData;
     505                    rc = ShClX11ReadDataFromX11Ex(&g_Ctx.X11, &pCtx->EventSrc, SHCL_TIMEOUT_DEFAULT_MS, pEvent->u.fReadData,
     506                                                  &pvData, &cbData);
    532507                    if (RT_SUCCESS(rc))
    533508                    {
    534                         rc = ShClX11ReadDataFromX11Async(&g_Ctx.X11, pEvent->u.fReadData, UINT32_MAX, pReadDataEvent);
    535                         if (RT_SUCCESS(rc))
    536                         {
    537                             int               rcEvent;
    538                             PSHCLEVENTPAYLOAD pPayload;
    539                             rc = ShClEventWaitEx(pReadDataEvent, SHCL_TIMEOUT_DEFAULT_MS, &rcEvent, &pPayload);
    540                             if (RT_SUCCESS(rc))
    541                             {
    542                                 if (pPayload)
    543                                 {
    544                                     AssertBreakStmt(pPayload->cbData == sizeof(SHCLX11RESPONSE), rc = VERR_INVALID_PARAMETER);
    545                                     AssertPtrBreakStmt(pPayload->pvData, rc = VERR_INVALID_POINTER);
    546                                     PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData;
    547                                     AssertBreakStmt(pResp->enmType == SHCLX11EVENTTYPE_READ, rc = VERR_INVALID_PARAMETER);
    548 
    549                                     rc = VbglR3ClipboardWriteDataEx(&pCtx->CmdCtx, pEvent->u.fReadData,
    550                                                                     pResp->Read.pvData, pResp->Read.cbData);
    551 
    552                                     RTMemFree(pResp->Read.pvData);
    553                                     pResp->Read.cbData = 0;
    554 
    555                                     ShClPayloadFree(pPayload);
    556                                 }
    557                                 else /* No payload given; could happen on invalid / not-expected formats. */
    558                                     rc = VERR_NO_DATA;
    559                             }
    560                             else if (rc == VERR_SHCLPB_EVENT_FAILED)
    561                                 rc = rcEvent;
    562                         }
    563 
    564                         ShClEventRelease(pReadDataEvent);
    565                         pReadDataEvent = NULL;
     509                        rc = VbglR3ClipboardWriteDataEx(&pCtx->CmdCtx, pEvent->u.fReadData, pvData, cbData);
     510                        RTMemFree(pvData);
    566511                    }
    567512
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp

    r103240 r103323  
    15691569    LogFlowFunc(("Returning pv=%p, cb=%RU32, rc=%Rrc\n", pv, cb, rc));
    15701570    return rc;
     1571}
     1572
     1573/**
     1574 * Free's an allocated SHCLX11RESPONSE struct.
     1575 *
     1576 * @param   pResp               Pointer to response to free.
     1577 *                              The pointer will be invalid after return.
     1578 */
     1579static void shClX11ResponseFree(PSHCLX11RESPONSE pResp)
     1580{
     1581    if (!pResp)
     1582        return;
     1583
     1584    switch (pResp->enmType)
     1585    {
     1586        case SHCLX11EVENTTYPE_READ:
     1587        {
     1588            Assert(pResp->Read.cbData);
     1589            RTMemFree(pResp->Read.pvData);
     1590            break;
     1591        }
     1592
     1593        case SHCLX11EVENTTYPE_REPORT_FORMATS:
     1594            RT_FALL_THROUGH();
     1595        case SHCLX11EVENTTYPE_WRITE:
     1596            RT_FALL_THROUGH();
     1597        default:
     1598            break;
     1599    }
     1600
     1601    RTMemFree(pResp);
    15711602}
    15721603
     
    26702701
    26712702/**
     2703 * Reads from the X11 clipboard, internal version.
     2704 *
     2705 * @returns VBox status code.
     2706 * @retval  VERR_NO_DATA if format is supported but no data is available currently.
     2707 * @retval  VERR_NOT_IMPLEMENTED if the format is not implemented.
     2708 * @param   pCtx                Context data for the clipboard backend.
     2709 * @param   pEventSource        Event source to use.
     2710 * @param   msTimeout           Timeout (in ms) for waiting.
     2711 * @param   uFmt                The format that the VBox would like to receive the data in.
     2712 * @param   cbMax               Maximum size (in bytes) to read.
     2713 * @param   pResp               Where to return the allocated SHCLX11RESPONSE on success.
     2714 *                              Must be free'd via shClX11ResponseFree() by the caller.
     2715 */
     2716static int shClX11ReadDataFromX11Internal(PSHCLX11CTX pCtx, PSHCLEVENTSOURCE pEventSource, RTMSINTERVAL msTimeout,
     2717                                          SHCLFORMAT uFmt, uint32_t cbMax, PSHCLX11RESPONSE *ppResp)
     2718{
     2719    PSHCLEVENT pEvent;
     2720    int rc = ShClEventSourceGenerateAndRegisterEvent(pEventSource, &pEvent);
     2721    if (RT_SUCCESS(rc))
     2722    {
     2723        rc = ShClX11ReadDataFromX11Async(pCtx, uFmt, cbMax, pEvent);
     2724        if (RT_SUCCESS(rc))
     2725        {
     2726            PSHCLEVENTPAYLOAD pPayload;
     2727            int               rcEvent;
     2728            rc = ShClEventWaitEx(pEvent, msTimeout, &rcEvent, &pPayload);
     2729            if (RT_SUCCESS(rc))
     2730            {
     2731                if (pPayload)
     2732                {
     2733                    AssertReturn(pPayload->cbData == sizeof(SHCLX11RESPONSE), VERR_INVALID_PARAMETER);
     2734                    AssertPtrReturn(pPayload->pvData, VERR_INVALID_POINTER);
     2735                    PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData;
     2736                    AssertReturn(pResp->enmType == SHCLX11EVENTTYPE_READ, VERR_INVALID_PARAMETER);
     2737                    AssertReturn(pResp->Read.cbData <= cbMax, VERR_BUFFER_OVERFLOW); /* Paranoia. */
     2738
     2739                    pPayload->pvData = NULL; /* pvData (pResp) is owned by ppResp now. */
     2740                    pPayload->cbData = 0;
     2741
     2742                    ShClPayloadFree(pPayload);
     2743
     2744                    *ppResp = pResp;
     2745                }
     2746                else /* No payload given; could happen on invalid / not-expected formats. */
     2747                    rc = VERR_NO_DATA;
     2748            }
     2749            else if (rc == VERR_SHCLPB_EVENT_FAILED)
     2750                rc = rcEvent;
     2751        }
     2752
     2753        ShClEventRelease(pEvent);
     2754    }
     2755
     2756    LogFlowFuncLeaveRC(rc);
     2757    return rc;
     2758}
     2759
     2760/**
     2761 * Reads from the X11 clipboard, extended version.
     2762 *
     2763 * @returns VBox status code.
     2764 * @retval  VERR_NO_DATA if format is supported but no data is available currently.
     2765 * @retval  VERR_NOT_IMPLEMENTED if the format is not implemented.
     2766 * @param   pCtx                Context data for the clipboard backend.
     2767 * @param   pEventSource        Event source to use.
     2768 * @param   msTimeout           Timeout (in ms) for waiting.
     2769 * @param   uFmt                The format that the VBox would like to receive the data in.
     2770 * @param   ppvBuf              Where to return the allocated received data on success.
     2771 *                              Must be free'd by the caller.
     2772 * @param   pcbBuf              Where to return the size (in bytes) of \a ppvBuf.
     2773 */
     2774int ShClX11ReadDataFromX11Ex(PSHCLX11CTX pCtx, PSHCLEVENTSOURCE pEventSource, RTMSINTERVAL msTimeout,
     2775                             SHCLFORMAT uFmt, void **ppvBuf, uint32_t *pcbBuf)
     2776{
     2777    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2778    AssertPtrReturn(pEventSource, VERR_INVALID_POINTER);
     2779    AssertPtrReturn(ppvBuf, VERR_INVALID_POINTER);
     2780    AssertPtrReturn(pcbBuf, VERR_INVALID_POINTER);
     2781
     2782    if (shClX11HeadlessIsEnabled(pCtx))
     2783    {
     2784        *pcbBuf = 0;
     2785        return VINF_SUCCESS;
     2786    }
     2787
     2788    PSHCLX11RESPONSE pResp;
     2789    int rc = shClX11ReadDataFromX11Internal(pCtx, pEventSource, msTimeout, uFmt, UINT32_MAX, &pResp);
     2790    if (RT_SUCCESS(rc))
     2791    {
     2792        *ppvBuf = pResp->Read.pvData;
     2793        *pcbBuf = pResp->Read.cbData;
     2794
     2795        pResp->Read.pvData = NULL; /* Is owned by ppvBuf now. */
     2796        pResp->Read.cbData = 0;
     2797
     2798        shClX11ResponseFree(pResp);
     2799    }
     2800
     2801    LogFlowFuncLeaveRC(rc);
     2802    return rc;
     2803}
     2804
     2805/**
    26722806 * Reads from the X11 clipboard.
    26732807 *
     
    26992833    }
    27002834
    2701     PSHCLEVENT pEvent;
    2702     int rc = ShClEventSourceGenerateAndRegisterEvent(pEventSource, &pEvent);
     2835    PSHCLX11RESPONSE pResp;
     2836    int rc = shClX11ReadDataFromX11Internal(pCtx, pEventSource, msTimeout, uFmt, cbBuf, &pResp);
    27032837    if (RT_SUCCESS(rc))
    27042838    {
    2705         rc = ShClX11ReadDataFromX11Async(pCtx, uFmt, cbBuf, pEvent);
    2706         if (RT_SUCCESS(rc))
    2707         {
    2708             int               rcEvent;
    2709             PSHCLEVENTPAYLOAD pPayload;
    2710             rc = ShClEventWaitEx(pEvent, msTimeout, &rcEvent, &pPayload);
    2711             if (RT_SUCCESS(rc))
    2712             {
    2713                 if (pPayload)
    2714                 {
    2715                     AssertReturn(pPayload->cbData == sizeof(SHCLX11RESPONSE), VERR_INVALID_PARAMETER);
    2716                     AssertPtrReturn(pPayload->pvData, VERR_INVALID_POINTER);
    2717                     PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData;
    2718                     AssertReturn(pResp->enmType == SHCLX11EVENTTYPE_READ, VERR_INVALID_PARAMETER);
    2719 
    2720                     memcpy(pvBuf, pResp->Read.pvData, RT_MIN(cbBuf, pResp->Read.cbData));
    2721                     if (pcbRead)
    2722                         *pcbRead = pResp->Read.cbData;
    2723 
    2724                     RTMemFree(pResp->Read.pvData);
    2725                     pResp->Read.cbData = 0;
    2726 
    2727                     ShClPayloadFree(pPayload);
    2728                 }
    2729                 else /* No payload given; could happen on invalid / not-expected formats. */
    2730                 {
    2731                     rc = VERR_NO_DATA;
    2732                     if (pcbRead)
    2733                         *pcbRead = 0;
    2734                 }
    2735             }
    2736             else if (rc == VERR_SHCLPB_EVENT_FAILED)
    2737                 rc = rcEvent;
    2738         }
    2739 
    2740         ShClEventRelease(pEvent);
     2839        memcpy(pvBuf, pResp->Read.pvData, RT_MIN(cbBuf, pResp->Read.cbData));
     2840        if (pcbRead)
     2841            *pcbRead = pResp->Read.cbData;
     2842
     2843        shClX11ResponseFree(pResp);
    27412844    }
    27422845
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp

    r102818 r103323  
    293293                 pClient, uFormat, pvData, cbData, pcbActual));
    294294
    295     PSHCLEVENT pEvent;
    296     int rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent);
     295    uint32_t cbRead;
     296    int rc = ShClX11ReadDataFromX11(&pClient->State.pCtx->X11, &pClient->EventSrc,
     297                                    SHCL_TIMEOUT_DEFAULT_MS, uFormat, pvData, cbData, &cbRead);
    297298    if (RT_SUCCESS(rc))
    298299    {
    299         rc = ShClX11ReadDataFromX11Async(&pClient->State.pCtx->X11, uFormat, cbData, pEvent);
    300         if (RT_SUCCESS(rc))
    301         {
    302             int               rcEvent;
    303             PSHCLEVENTPAYLOAD pPayload;
    304             rc = ShClEventWaitEx(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &rcEvent, &pPayload);
    305             if (RT_SUCCESS(rc))
    306             {
    307                 if (pPayload)
    308                 {
    309                     AssertReturn(pPayload->cbData == sizeof(SHCLX11RESPONSE), VERR_INVALID_PARAMETER);
    310                     AssertPtrReturn(pPayload->pvData, VERR_INVALID_POINTER);
    311                     PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData;
    312                     AssertReturn(pResp->enmType == SHCLX11EVENTTYPE_READ, VERR_INVALID_PARAMETER);
    313 
    314                     uint32_t const cbRead = pResp->Read.cbData;
    315 
    316                     size_t const cbToCopy = RT_MIN(cbData, cbRead);
    317                     if (cbToCopy) /* memcpy doesn't like 0 byte inputs. */
    318                         memcpy(pvData, pResp->Read.pvData, RT_MIN(cbData, cbRead));
    319 
    320                     LogRel2(("Shared Clipboard: Read %RU32 bytes host X11 clipboard data\n", cbRead));
    321 
    322                     *pcbActual = cbRead;
    323 
    324                     RTMemFree(pResp->Read.pvData);
    325                     pResp->Read.cbData = 0;
    326 
    327                     ShClPayloadFree(pPayload);
    328                 }
    329                 else /* No payload given; could happen on invalid / not-expected formats. */
    330                     *pcbActual = 0;
    331             }
    332             else if (rc == VERR_SHCLPB_EVENT_FAILED)
    333                 rc = rcEvent;
    334         }
    335 
    336         ShClEventRelease(pEvent);
     300        LogRel2(("Shared Clipboard: Read %RU32 bytes host X11 clipboard data\n", cbRead));
     301
     302        if (pcbActual)
     303            *pcbActual = cbRead;
    337304    }
    338305
     
    699666    PSHCLX11CTX pX11 = &pClient->State.pCtx->X11;
    700667
    701     PSHCLEVENT pEvent;
    702     int rc = ShClEventSourceGenerateAndRegisterEvent(&pClient->EventSrc, &pEvent);
     668    /* X supplies the data asynchronously, so we need to wait for data to arrive first. */
     669    void    *pvData;
     670    uint32_t cbData;
     671    int rc = ShClX11ReadDataFromX11Ex(pX11, &pClient->EventSrc, SHCL_TIMEOUT_DEFAULT_MS, VBOX_SHCL_FMT_URI_LIST,
     672                                      &pvData, &cbData);
    703673    if (RT_SUCCESS(rc))
    704674    {
    705         rc = ShClX11ReadDataFromX11Async(pX11, VBOX_SHCL_FMT_URI_LIST, UINT32_MAX, pEvent);
     675        rc = ShClTransferRootsInitFromStringList(pCtx->pTransfer, (const char *)pvData, cbData);
    706676        if (RT_SUCCESS(rc))
    707         {
    708             /* X supplies the data asynchronously, so we need to wait for data to arrive first. */
    709             int               rcEvent;
    710             PSHCLEVENTPAYLOAD pPayload;
    711             rc = ShClEventWaitEx(pEvent, SHCL_TIMEOUT_DEFAULT_MS, &rcEvent, &pPayload);
    712             if (RT_SUCCESS(rc))
    713             {
    714                 if (pPayload)
    715                 {
    716                     AssertReturn(pPayload->cbData == sizeof(SHCLX11RESPONSE), VERR_INVALID_PARAMETER);
    717                     AssertPtrReturn(pPayload->pvData, VERR_INVALID_POINTER);
    718                     PSHCLX11RESPONSE pResp = (PSHCLX11RESPONSE)pPayload->pvData;
    719                     AssertReturn(pResp->enmType == SHCLX11EVENTTYPE_READ, VERR_INVALID_PARAMETER);
    720 
    721                     rc = ShClTransferRootsInitFromStringList(pCtx->pTransfer,
    722                                                              (char *)pResp->Read.pvData, pResp->Read.cbData + 1 /* Include zero terminator */);
    723                     if (RT_SUCCESS(rc))
    724                         LogRel2(("Shared Clipboard: Host reported %RU64 X11 root entries for transfer to guest\n",
    725                                  ShClTransferRootsCount(pCtx->pTransfer)));
    726 
    727                     RTMemFree(pResp->Read.pvData);
    728                     pResp->Read.cbData = 0;
    729 
    730                     ShClPayloadFree(pPayload);
    731                     pPayload = NULL;
    732                 }
    733                 else /* No payload given; could happen on invalid / not-expected formats. */
    734                     rc = VERR_NO_DATA;
    735             }
    736             else if (rc == VERR_SHCLPB_EVENT_FAILED)
    737                 rc = rcEvent;
    738         }
    739 
    740         ShClEventRelease(pEvent);
    741     }
    742     else
    743         rc = VERR_SHCLPB_MAX_EVENTS_REACHED;
     677            LogRel2(("Shared Clipboard: Host reported %RU64 X11 root entries for transfer to guest\n",
     678                     ShClTransferRootsCount(pCtx->pTransfer)));
     679
     680        RTMemFree(pvData);
     681    }
    744682
    745683    LogFlowFuncLeaveRC(rc);
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