VirtualBox

Ignore:
Timestamp:
May 8, 2009 9:26:00 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
47101
Message:

GuestHost/SharedClipboard/x11: cleanup

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/SharedClipboard/x11-clipboard.cpp

    r19541 r19552  
    437437}
    438438
     439/** A structure containing information about where to store a request
     440 * for the X11 clipboard contents. */
     441struct _CLIPX11CLIPBOARDREQ
     442{
     443    /** The buffer to write X11 clipboard data to (valid during a request
     444     * for the clipboard contents) */
     445    void *pv;
     446    /** The size of the buffer to write X11 clipboard data to (valid during
     447     * a request for the clipboard contents) */
     448    unsigned cb;
     449    /** The size of the X11 clipboard data written to the buffer (valid
     450     * during a request for the clipboard contents) */
     451    uint32_t *pcbActual;
     452    /** The format VBox would like the data in */
     453    uint32_t format;
     454    /** Return code for the request processing code */
     455    int rc;
     456    /** Semaphore which is signalled when the request is completed */
     457    RTSEMEVENT finished;
     458    /** The clipboard context this request is associated with */
     459    CLIPBACKEND *pCtx;
     460};
     461
     462typedef struct _CLIPX11CLIPBOARDREQ CLIPX11CLIPBOARDREQ;
     463
    439464/**
    440465 * Convert the text obtained from the X11 clipboard to UTF-16LE with Windows
     
    443468 *        the X11 clipboard contains a text format we understand.
    444469 */
    445 static void vboxClipboardGetDataFromX11(Widget, XtPointer pClientData,
    446                                         Atom * /* selection */,
    447                                         Atom *atomType,
    448                                         XtPointer pValue,
    449                                         long unsigned int *pcLen,
    450                                         int *piFormat)
    451 {
    452     VBOXCLIPBOARDREQUEST *pRequest
    453         = reinterpret_cast<VBOXCLIPBOARDREQUEST *>(pClientData);
    454     CLIPBACKEND *pCtx = pRequest->pCtx;
    455     if (pCtx->fOwnsClipboard == true)
    456     {
     470static void clipConvertX11CB(Widget widget, XtPointer pClientData,
     471                             Atom * /* selection */, Atom *atomType,
     472                             XtPointer pvSrc, long unsigned int *pcLen,
     473                             int *piFormat)
     474{
     475    CLIPX11CLIPBOARDREQ *pReq = (CLIPX11CLIPBOARDREQ *) pClientData;
     476    LogFlowFunc(("pReq->pv=%p, pReq->cb=%u, pReq->format=%02X, pReq->pCtx=%p\n",
     477                 pReq->pv, pReq->cb, pReq->format, pReq->pCtx));
     478    AssertPtr(pReq->pv);    /* We can't really return either... */
     479    AssertPtr(pReq->pCtx);
     480    Assert(pReq->format != 0);  /* sanity */
     481    int rc = VINF_SUCCESS;
     482    CLIPBACKEND *pCtx = pReq->pCtx;
     483    unsigned cbSrc = (*pcLen) * (*piFormat) / 8;
     484
     485    if (   pCtx->fOwnsClipboard
    457486        /* We don't want to request data from ourselves! */
    458         pRequest->rc = VERR_NO_DATA;
    459         RTSemEventSignal(pRequest->finished);
    460         return;
    461     }
    462     pRequest->rc = VINF_SUCCESS;
    463     LogFlowFunc(("pClientData=%p, *pcLen=%lu, *piFormat=%d\n", pClientData,
    464                  *pcLen, *piFormat));
    465     LogFlowFunc(("pCtx->X11TextFormat=%d, pRequest->cb=%d\n",
    466                  pCtx->X11TextFormat, pRequest->cb));
    467     unsigned cTextLen = (*pcLen) * (*piFormat) / 8;
    468     /* The X Toolkit may have failed to get the clipboard selection for us. */
    469     if (*atomType == XT_CONVERT_FAIL) /* timeout */
    470     {
    471         pRequest->rc = VERR_TIMEOUT;
    472         RTSemEventSignal(pRequest->finished);
    473         return;
    474     }
    475     /* The clipboard selection may have changed before we could get it. */
    476     if (NULL == pValue)
    477     {
    478         pRequest->rc = VERR_NO_DATA;
    479         RTSemEventSignal(pRequest->finished);
    480         return;
    481     }
    482     /* In which format is the clipboard data? */
    483     switch (pCtx->X11TextFormat)
    484     {
    485     case CTEXT:
    486         pRequest->rc = clipCTextToWinTxt(pCtx->widget,
    487                                          (unsigned char *)pValue, cTextLen,
    488                                          pRequest->pv, pRequest->cb,
    489                                          pRequest->pcbActual);
    490         XtFree(reinterpret_cast<char *>(pValue));
    491         RTSemEventSignal(pRequest->finished);
    492         break;
    493     case UTF8:
    494     {
    495         /* If we are given broken Utf-8, we treat it as Latin1.  Is this acceptable? */
    496         size_t cStringLen;
    497         char *pu8SourceText = reinterpret_cast<char *>(pValue);
    498 
    499         if ((pCtx->X11TextFormat == UTF8)
    500             && (RTStrUniLenEx(pu8SourceText, *pcLen, &cStringLen) == VINF_SUCCESS))
     487        || (pvSrc == NULL)
     488        /* The clipboard selection may have changed before we could get it. */
     489       )
     490        rc = VERR_NO_DATA;
     491    else if (*atomType == XT_CONVERT_FAIL) /* Xt timeout */
     492        rc = VERR_TIMEOUT;
     493    else
     494    {
     495        /* In which format is the clipboard data? */
     496        switch (pCtx->X11TextFormat)
    501497        {
    502             pRequest->rc = clipUtf8ToWinTxt((const char *)pValue, cTextLen,
    503                                             pRequest->pv, pRequest->cb,
    504                                             pRequest->pcbActual);
    505             XtFree(reinterpret_cast<char *>(pValue));
    506             RTSemEventSignal(pRequest->finished);
    507             break;
     498            case CTEXT:
     499                rc = clipCTextToWinTxt(widget, (unsigned char *)pvSrc, cbSrc,
     500                                       pReq->pv, pReq->cb, pReq->pcbActual);
     501                break;
     502            case UTF8:
     503            {
     504                /* If we are given broken Utf-8, we treat it as Latin1.  Is
     505                 * this acceptable? */
     506                if (RT_SUCCESS(RTStrValidateEncoding((char *)pvSrc)))
     507                    rc = clipUtf8ToWinTxt((const char *)pvSrc, cbSrc,
     508                                          pReq->pv, pReq->cb,
     509                                          pReq->pcbActual);
     510                else
     511                    rc = clipLatin1ToWinTxt((char *) pvSrc, cbSrc,
     512                                            pReq->pv, pReq->cb,
     513                                            pReq->pcbActual);
     514                break;
     515            }
     516            default:
     517                rc = VERR_INVALID_PARAMETER;
    508518        }
    509         else
    510         {
    511             pRequest->rc = clipLatin1ToWinTxt((char *) pValue, cTextLen,
    512                                               pRequest->pv, pRequest->cb,
    513                                               pRequest->pcbActual);
    514             XtFree(reinterpret_cast<char *>(pValue));
    515             RTSemEventSignal(pRequest->finished);
    516             break;
    517         }
    518     }
    519     default:
    520         LogFunc (("bad target format\n"));
    521         XtFree(reinterpret_cast<char *>(pValue));
    522         pRequest->rc = VERR_INVALID_PARAMETER;
    523         RTSemEventSignal(pRequest->finished);
    524         return;
    525     }
    526     pCtx->notifyVBox = true;
     519    }
     520    if (RT_SUCCESS(rc))
     521        /* The other end may cache the data, so invalidate it again. */
     522        pCtx->notifyVBox = true;
     523    else
     524    {
     525        pCtx->X11TextFormat = INVALID;
     526        pCtx->X11BitmapFormat = INVALID;
     527    }
     528    XtFree((char *)pvSrc);
     529    pReq->rc = rc;
     530    RTSemEventSignal(pReq->finished);
     531    LogFlowFunc(("rc=%Rrc\n", rc));
    527532}
    528533
     
    13861391                                       XtIntervalId * /* interval */)
    13871392{
    1388     VBOXCLIPBOARDREQUEST *pRequest = (VBOXCLIPBOARDREQUEST *)pUserData;
     1393    CLIPX11CLIPBOARDREQ *pRequest = (CLIPX11CLIPBOARDREQ *)pUserData;
    13891394    CLIPBACKEND *pCtx = pRequest->pCtx;
    13901395    LogFlowFunc (("u32Format = %d, cb = %d\n", pRequest->format,
     
    14121417                XtGetSelectionValue(pCtx->widget, clipGetAtom(pCtx->widget, "CLIPBOARD"),
    14131418                                    pCtx->atomX11TextFormat,
    1414                                     vboxClipboardGetDataFromX11,
     1419                                    clipConvertX11CB,
    14151420                                    reinterpret_cast<XtPointer>(pRequest),
    14161421                                    CurrentTime);
     
    14531458        return VINF_SUCCESS;
    14541459
    1455     VBOXCLIPBOARDREQUEST request;
     1460    CLIPX11CLIPBOARDREQ request;
    14561461    request.rc = VERR_WRONG_ORDER;
    14571462    request.pv = pv;
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