VirtualBox

Changeset 13454 in vbox


Ignore:
Timestamp:
Oct 21, 2008 4:43:12 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
38239
Message:

HostServices/SharedClipboard: x11 fixes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedClipboard/x11.cpp

    r13315 r13454  
    5151#include <X11/Xproto.h>
    5252#include <X11/StringDefs.h>
     53
     54/** Do we want to test Utf16 by disabling other text formats? */
     55static bool g_testUtf16 = false;
     56/** Do we want to test Utf8 by disabling other text formats? */
     57static bool g_testUtf8 = false;
     58/** Do we want to test compount text by disabling other text formats? */
     59static bool g_testCText = false;
    5360
    5461/** The different clipboard formats which we support. */
     
    237244    PRTUTF16 pu16SrcText = reinterpret_cast<PRTUTF16>(pValue);
    238245    PRTUTF16 pu16DestText = reinterpret_cast<PRTUTF16>(pv);
    239     int rc;
    240246
    241247    LogFlowFunc (("converting Utf-16 to Utf-16LE.  cwSrcLen=%d, cb=%d, pu16SrcText+1=%.*ls\n",
    242248                   cwSrcLen, cb, cwSrcLen - 1, pu16SrcText + 1));
     249    *pcbActual = 0;  /* Only set this to the right value on success. */
    243250    /* How long will the converted text be? */
    244     rc = vboxClipboardUtf16GetWinSize(pu16SrcText, cwSrcLen, &cwDestLen);
    245     if (RT_FAILURE(rc))
    246     {
    247         XtFree(reinterpret_cast<char *>(pValue));
    248         LogRel(("vboxClipboardGetUtf16: clipboard conversion failed.  vboxClipboardUtf16GetLinSize returned %Vrc.  Abandoning.\n", rc));
     251    int rc = vboxClipboardUtf16GetWinSize(pu16SrcText, cwSrcLen, &cwDestLen);
     252    if (RT_SUCCESS(rc) && (cb < cwDestLen * 2))
     253    {
     254        /* Not enough buffer space provided - report the amount needed. */
    249255        LogFlowFunc (("guest buffer too small: size %d bytes, needed %d.  Returning.\n",
    250256                       cb, cwDestLen * 2));
    251257        *pcbActual = cwDestLen * 2;
    252         RTSemEventSignal(g_ctx.waitForData);
    253         AssertReturnVoid(RT_SUCCESS(rc));
    254     }
    255     if (cb < cwDestLen * 2)
    256     {
    257         XtFree(reinterpret_cast<char *>(pValue));
    258         /* Report the amount of buffer space needed for the transfer */
    259         LogFlowFunc (("guest buffer too small: size %d bytes, needed %d.  Returning.\n",
    260                        cb, cwDestLen * 2));
     258        rc = VERR_BUFFER_OVERFLOW;
     259    }
     260    /* Convert the text. */
     261    if (RT_SUCCESS(rc))
     262        rc = vboxClipboardUtf16LinToWin(pu16SrcText, cwSrcLen, pu16DestText, cb / 2);
     263    if (RT_SUCCESS(rc))
     264    {
     265        LogFlowFunc (("converted string is %.*ls\n", cwDestLen, pu16DestText));
    261266        *pcbActual = cwDestLen * 2;
    262         RTSemEventSignal(g_ctx.waitForData);
    263         return;
    264     }
    265     /* Convert the text. */
    266     rc = vboxClipboardUtf16LinToWin(pu16SrcText, cwSrcLen, pu16DestText, cb / 2);
    267     if (RT_FAILURE(rc))
    268     {
    269         LogRel(("vboxClipboardGetUtf16: clipboard conversion failed.  vboxClipboardUtf16LinToWin returned %Vrc.  Abandoning.\n", rc));
    270         XtFree(reinterpret_cast<char *>(pValue));
    271         *pcbActual = 0;
    272         RTSemEventSignal(g_ctx.waitForData);
    273         return;
    274     }
    275     LogFlowFunc (("converted string is %.*ls. Returning.\n", cwDestLen, pu16DestText));
    276     *pcbActual = cwDestLen * 2;
     267    }
     268    /* We need to do this whether we succeed or fail. */
    277269    XtFree(reinterpret_cast<char *>(pValue));
    278270    RTSemEventSignal(g_ctx.waitForData);
     271    LogFlowFunc(("Returning.  Status is %Rrc\n", rc));
    279272}
    280273
     
    295288    size_t cwSrcLen, cwDestLen;
    296289    char *pu8SrcText = reinterpret_cast<char *>(pValue);
    297     PRTUTF16 pu16SrcText;
     290    PRTUTF16 pu16SrcText = NULL;
    298291    PRTUTF16 pu16DestText = reinterpret_cast<PRTUTF16>(pv);
    299     int rc;
    300292
    301293    LogFlowFunc (("converting Utf-8 to Utf-16LE.  cbSrcLen=%d, cb=%d, pu8SrcText=%.*s\n",
    302294                   cbSrcLen, cb, cbSrcLen, pu8SrcText));
     295    *pcbActual = 0;  /* Only set this to the right value on success. */
    303296    /* First convert the UTF8 to UTF16 */
    304     rc = RTStrToUtf16Ex(pu8SrcText, cbSrcLen, &pu16SrcText, 0, &cwSrcLen);
    305     XtFree(reinterpret_cast<char *>(pValue));
    306     if (RT_FAILURE(rc))
    307     {
    308         LogRel(("vboxClipboardGetUtf8: clipboard conversion failed.  RTStrToUtf16Ex returned %Vrc.  Abandoning.\n", rc));
    309         *pcbActual = 0;
    310         RTSemEventSignal(g_ctx.waitForData);
    311         return;
    312     }
     297    int rc = RTStrToUtf16Ex(pu8SrcText, cbSrcLen, &pu16SrcText, 0, &cwSrcLen);
    313298    /* Check how much longer will the converted text will be. */
    314     rc = vboxClipboardUtf16GetWinSize(pu16SrcText, cwSrcLen, &cwDestLen);
    315     if (RT_FAILURE(rc))
    316     {
    317         LogRel(("vboxClipboardGetUtf8: clipboard conversion failed.  vboxClipboardUtf16GetLinSize returned %Vrc.  Abandoning.\n", rc));
    318         LogFlowFunc (("guest buffer too small: size %d bytes, needed %d.  Returning.\n",
    319                        cb, cwDestLen * 2));
    320         RTUtf16Free(pu16SrcText);
    321         *pcbActual = cwDestLen * 2;
    322         RTSemEventSignal(g_ctx.waitForData);
    323         AssertReturnVoid(RT_SUCCESS(rc));
    324     }
    325     if (cb < cwDestLen * 2)
    326     {
    327         RTUtf16Free(pu16SrcText);
    328         /* Report the amount of buffer space needed for the transfer */
     299    if (RT_SUCCESS(rc))
     300        rc = vboxClipboardUtf16GetWinSize(pu16SrcText, cwSrcLen, &cwDestLen);
     301    if (RT_SUCCESS(rc) && (cb < cwDestLen * 2))
     302    {
     303        /* Not enough buffer space provided - report the amount needed. */
    329304        LogFlowFunc (("guest buffer too small: size %d bytes, needed %d.  Returning.\n",
    330305                       cb, cwDestLen * 2));
    331306        *pcbActual = cwDestLen * 2;
    332         RTSemEventSignal(g_ctx.waitForData);
    333         return;
     307        rc = VERR_BUFFER_OVERFLOW;
    334308    }
    335309    /* Convert the text. */
    336     rc = vboxClipboardUtf16LinToWin(pu16SrcText, cwSrcLen, pu16DestText, cb / 2);
     310    if (RT_SUCCESS(rc))
     311        rc = vboxClipboardUtf16LinToWin(pu16SrcText, cwSrcLen, pu16DestText, cb / 2);
     312    if (RT_SUCCESS(rc))
     313    {
     314        LogFlowFunc (("converted string is %.*ls.\n", cwDestLen, pu16DestText));
     315        *pcbActual = cwDestLen * 2;
     316    }
     317    XtFree(reinterpret_cast<char *>(pValue));
    337318    RTUtf16Free(pu16SrcText);
    338     if (RT_FAILURE(rc))
    339     {
    340         LogRel(("vboxClipboardGetUtf8: clipboard conversion failed.  vboxClipboardUtf16LinToWin returned %Vrc.  Abandoning.\n", rc));
    341         *pcbActual = 0;
    342         RTSemEventSignal(g_ctx.waitForData);
    343         return;
    344     }
    345     LogFlowFunc (("converted string is %.*ls. Returning.\n", cwDestLen, pu16DestText));
    346     *pcbActual = cwDestLen * 2;
    347319    RTSemEventSignal(g_ctx.waitForData);
     320    LogFlowFunc(("Returning.  Status is %Rrc", rc));
    348321}
    349322
     
    363336{
    364337    size_t cwSrcLen, cwDestLen;
    365     char **ppu8SrcText;
    366     PRTUTF16 pu16SrcText;
     338    char **ppu8SrcText = NULL;
     339    PRTUTF16 pu16SrcText = NULL;
    367340    PRTUTF16 pu16DestText = reinterpret_cast<PRTUTF16>(pv);
    368341    XTextProperty property;
     
    371344    LogFlowFunc (("converting COMPOUND TEXT to Utf-16LE.  cbSrcLen=%d, cb=%d, pu8SrcText=%.*s\n",
    372345                   cbSrcLen, cb, cbSrcLen, reinterpret_cast<char *>(pValue)));
     346    *pcbActual = 0;  /* Only set this to the right value on success. */
    373347    /* First convert the compound text to Utf8 */
    374348    property.value = reinterpret_cast<unsigned char *>(pValue);
     
    377351    property.nitems = cbSrcLen;
    378352#ifdef RT_OS_SOLARIS
    379     rc = XmbTextPropertyToTextList(XtDisplay(g_ctx.widget), &property, &ppu8SrcText, &cProps);
     353    int xrc = XmbTextPropertyToTextList(XtDisplay(g_ctx.widget), &property, &ppu8SrcText, &cProps);
    380354#else
    381     rc = Xutf8TextPropertyToTextList(XtDisplay(g_ctx.widget), &property, &ppu8SrcText, &cProps);
     355    int xrc = Xutf8TextPropertyToTextList(XtDisplay(g_ctx.widget), &property, &ppu8SrcText, &cProps);
    382356#endif
    383357    XtFree(reinterpret_cast<char *>(pValue));
    384     if (rc < 0)
    385     {
    386         const char *pcReason;
    387         switch(rc)
     358    if (xrc < 0)
     359        switch(xrc)
    388360        {
    389361        case XNoMemory:
    390             pcReason = "out of memory";
     362            rc = VERR_NO_MEMORY;
    391363            break;
    392364        case XLocaleNotSupported:
    393             pcReason = "locale (Utf8) not supported";
    394             break;
    395365        case XConverterNotFound:
    396             pcReason = "converter not found";
     366            rc = VERR_NOT_SUPPORTED;
    397367            break;
    398368        default:
    399             pcReason = "unknown error";
    400         }
    401         XFreeStringList(ppu8SrcText);
    402         LogRel(("vboxClipboardGetCText: Xutf8TextPropertyToTextList failed.  Reason: %s\n",
    403                 pcReason));
    404         *pcbActual = 0;
    405         RTSemEventSignal(g_ctx.waitForData);
    406         return;
    407     }
     369            rc = VERR_UNRESOLVED_ERROR;
     370        }
    408371    /* Now convert the UTF8 to UTF16 */
    409     rc = RTStrToUtf16Ex(*ppu8SrcText, cbSrcLen, &pu16SrcText, 0, &cwSrcLen);
    410     XFreeStringList(ppu8SrcText);
    411     if (RT_FAILURE(rc))
    412     {
    413         LogRel(("vboxClipboardGetCText: clipboard conversion failed.  RTStrToUtf16Ex returned %Vrc.  Abandoning.\n", rc));
    414         *pcbActual = 0;
    415         RTSemEventSignal(g_ctx.waitForData);
    416         return;
    417     }
     372    if (RT_SUCCESS(rc))
     373        rc = RTStrToUtf16Ex(*ppu8SrcText, cbSrcLen, &pu16SrcText, 0, &cwSrcLen);
    418374    /* Check how much longer will the converted text will be. */
    419     rc = vboxClipboardUtf16GetWinSize(pu16SrcText, cwSrcLen, &cwDestLen);
    420     if (RT_FAILURE(rc))
    421     {
    422         LogRel(("vboxClipboardGetCText: clipboard conversion failed.  vboxClipboardUtf16GetLinSize returned %Vrc.  Abandoning.\n", rc));
    423         LogFlowFunc (("guest buffer too small: size %d bytes, needed %d.  Returning.\n",
    424                        cb, cwDestLen * 2));
    425         RTUtf16Free(pu16SrcText);
    426         *pcbActual = cwDestLen * 2;
    427         RTSemEventSignal(g_ctx.waitForData);
    428         AssertReturnVoid(RT_SUCCESS(rc));
    429     }
    430     if (cb < cwDestLen * 2)
    431     {
    432         RTUtf16Free(pu16SrcText);
    433         /* Report the amount of buffer space needed for the transfer */
     375    if (RT_SUCCESS(rc))
     376        rc = vboxClipboardUtf16GetWinSize(pu16SrcText, cwSrcLen, &cwDestLen);
     377    if (RT_SUCCESS(rc) && (cb < cwDestLen * 2))
     378    {
     379        /* Not enough buffer space provided - report the amount needed. */
    434380        LogFlowFunc (("guest buffer too small: size %d bytes, needed %d.  Returning.\n",
    435381                       cb, cwDestLen * 2));
    436382        *pcbActual = cwDestLen * 2;
    437         RTSemEventSignal(g_ctx.waitForData);
    438         return;
     383        rc = VERR_BUFFER_OVERFLOW;
    439384    }
    440385    /* Convert the text. */
    441     rc = vboxClipboardUtf16LinToWin(pu16SrcText, cwSrcLen, pu16DestText, cb / 2);
     386    if (RT_SUCCESS(rc))
     387        rc = vboxClipboardUtf16LinToWin(pu16SrcText, cwSrcLen, pu16DestText, cb / 2);
     388    if (RT_SUCCESS(rc))
     389    {
     390        LogFlowFunc (("converted string is %.*ls\n", cwDestLen, pu16DestText));
     391        *pcbActual = cwDestLen * 2;
     392    }
     393    if (ppu8SrcText != NULL)
     394        XFreeStringList(ppu8SrcText);
    442395    RTUtf16Free(pu16SrcText);
    443     if (RT_FAILURE(rc))
    444     {
    445         LogRel(("vboxClipboardGetCText: clipboard conversion failed.  vboxClipboardUtf16LinToWin returned %Vrc.  Abandoning.\n", rc));
    446         *pcbActual = 0;
    447         RTSemEventSignal(g_ctx.waitForData);
    448         return;
    449     }
    450     LogFlowFunc (("converted string is %.*ls. Returning.\n", cwDestLen, pu16DestText));
    451     *pcbActual = cwDestLen * 2;
     396    LogFlowFunc(("Returning.  Status is %Rrc\n", rc));
    452397    RTSemEventSignal(g_ctx.waitForData);
    453398}
     
    471416    char *pu8SourceText = reinterpret_cast<char *>(pValue);
    472417    PRTUTF16 pu16DestText = reinterpret_cast<PRTUTF16>(pv);
     418    int rc = VINF_SUCCESS;
    473419
    474420    LogFlow (("vboxClipboardGetLatin1: converting Latin1 to Utf-16LE.  Original is %.*s\n",
    475421              cbSourceLen, pu8SourceText));
     422    *pcbActual = 0;  /* Only set this to the right value on success. */
    476423    for (unsigned i = 0; i < cbSourceLen; i++)
    477424        if (pu8SourceText[i] == LINEFEED)
     
    479426    if (cb < cwDestLen * 2)
    480427    {
    481         XtFree(reinterpret_cast<char *>(pValue));
    482         /* Report the amount of buffer space needed for the transfer */
    483         Log2 (("vboxClipboardGetLatin1: guest buffer too small: size %d bytes\n", cb));
     428        /* Not enough buffer space provided - report the amount needed. */
     429        LogFlowFunc (("guest buffer too small: size %d bytes\n", cb));
    484430        *pcbActual = cwDestLen * 2;
    485         RTSemEventSignal(g_ctx.waitForData);
    486         return;
    487     }
    488     for (unsigned i = 0, j = 0; i < cbSourceLen; ++i, ++j)
    489         if (pu8SourceText[i] != LINEFEED)
    490             pu16DestText[j] = pu8SourceText[i];  /* latin1 < utf-16LE */
    491         else
    492         {
    493             pu16DestText[j] = CARRIAGERETURN;
    494             ++j;
    495             pu16DestText[j] = LINEFEED;
    496         }
    497     pu16DestText[cwDestLen - 1] = 0;
    498     *pcbActual = cwDestLen * 2;
    499     Log2 (("vboxClipboardGetLatin1: converted text is %.*ls\n", cwDestLen, pu16DestText));
     431        rc = VERR_BUFFER_OVERFLOW;
     432    }
     433    if (RT_SUCCESS(rc))
     434    {
     435        for (unsigned i = 0, j = 0; i < cbSourceLen; ++i, ++j)
     436            if (pu8SourceText[i] != LINEFEED)
     437                pu16DestText[j] = pu8SourceText[i];  /* latin1 < utf-16LE */
     438            else
     439            {
     440                pu16DestText[j] = CARRIAGERETURN;
     441                ++j;
     442                pu16DestText[j] = LINEFEED;
     443            }
     444        pu16DestText[cwDestLen - 1] = 0;
     445        *pcbActual = cwDestLen * 2;
     446        LogFlowFunc (("converted text is %.*ls\n", cwDestLen, pu16DestText));
     447    }
    500448    XtFree(reinterpret_cast<char *>(pValue));
    501449    RTSemEventSignal(g_ctx.waitForData);
     450    LogFlowFunc(("Returning.  Status is %Rrc\n", rc));
    502451}
    503452
     
    758707        g_ctx.atomCText     = XInternAtom(XtDisplay(g_ctx.widget), "COMPOUND_TEXT", false);
    759708        /* And build up the vector of supported formats */
    760 #ifdef USE_UTF16
    761         vboxClipboardAddFormat("text/plain;charset=ISO-10646-UCS-2", UTF16,
    762                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    763 #endif
    764 #ifdef USE_UTF8
    765         vboxClipboardAddFormat("UTF8_STRING", UTF8,
    766                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    767         vboxClipboardAddFormat("text/plain;charset=UTF-8", UTF8,
    768                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    769         vboxClipboardAddFormat("text/plain;charset=utf-8", UTF8,
    770                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    771         vboxClipboardAddFormat("STRING", UTF8,
    772                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    773         vboxClipboardAddFormat("TEXT", UTF8,
    774                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    775         vboxClipboardAddFormat("text/plain", UTF8,
    776                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    777 #endif
    778 #ifdef USE_CTEXT
    779         vboxClipboardAddFormat("COMPOUND_TEXT", CTEXT,
    780                                VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    781 #endif
     709        if (!g_testUtf8 && !g_testCText)
     710            vboxClipboardAddFormat("text/plain;charset=ISO-10646-UCS-2", UTF16,
     711                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
     712        if (!g_testUtf16 && !g_testCText)
     713        {
     714            vboxClipboardAddFormat("UTF8_STRING", UTF8,
     715                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
     716            vboxClipboardAddFormat("text/plain;charset=UTF-8", UTF8,
     717                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
     718            vboxClipboardAddFormat("text/plain;charset=utf-8", UTF8,
     719                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
     720            vboxClipboardAddFormat("STRING", UTF8,
     721                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
     722            vboxClipboardAddFormat("TEXT", UTF8,
     723                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
     724            vboxClipboardAddFormat("text/plain", UTF8,
     725                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
     726}
     727        if (!g_testUtf16 && !g_testUtf8)
     728            vboxClipboardAddFormat("COMPOUND_TEXT", CTEXT,
     729                                   VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    782730    }
    783731    return rc;
     
    799747        g_fHaveX11 = false;
    800748        return VINF_SUCCESS;
     749    }
     750
     751    if (RTEnvGet("VBOX_CBTEST_UTF16"))
     752    {
     753        g_testUtf16 = true;
     754        LogRel(("Host clipboard: testing Utf16\n"));
     755    }
     756    else if (RTEnvGet("VBOX_CBTEST_UTF8"))
     757    {
     758        g_testUtf8 = true;
     759        LogRel(("Host clipboard: testing Utf8\n"));
     760    }
     761    else if (RTEnvGet("VBOX_CBTEST_CTEXT"))
     762    {
     763        g_testCText = true;
     764        LogRel(("Host clipboard: testing compound text\n"));
    801765    }
    802766
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