VirtualBox

Ignore:
Timestamp:
Feb 12, 2024 6:21:23 PM (12 months ago)
Author:
vboxsync
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
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