VirtualBox

vbox的更動 61589 路徑 trunk/src/VBox/GuestHost


忽略:
時間撮記:
2016-6-8 下午04:05:44 (8 年 以前)
作者:
vboxsync
訊息:

Additions/SharedClipboard: fix for ​bugref:8363: added HTML clipboard support to Linux. Added ability to copy HTML clipboard data between Windows and Linux.

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/GuestHost/SharedClipboard/x11-clipboard.cpp

    r57413 r61589  
    5454#include <VBox/HostServices/VBoxClipboardSvc.h>
    5555
     56class formats;
    5657static Atom clipGetAtom(CLIPBACKEND *pCtx, const char *pszName);
    5758
     
    6364    TEXT,  /* Treat this as Utf8, but it may really be ascii */
    6465    UTF8,
    65     BMP
     66    BMP,
     67        HTML
    6668};
    6769
     
    8890    { "TEXT", TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
    8991    { "text/plain", TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     92    { "text/html", HTML, VBOX_SHARED_CLIPBOARD_FMT_HTML },
     93    { "text/html;charset=utf-8", HTML,
     94      VBOX_SHARED_CLIPBOARD_FMT_HTML },
    9095    { "image/bmp", BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
    9196    { "image/x-bmp", BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
    92     { "image/x-MS-bmp", BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
     97    { "image/x-MS-bmp", BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP }
     98   
     99       
    93100    /* TODO: Inkscape exports image/png but not bmp... */
    94101};
     
    187194     * table */
    188195    CLIPX11FORMAT X11BitmapFormat;
     196    /** The best HTML format X11 has to offer, as an index into the formats
     197     * table */
     198    CLIPX11FORMAT X11HTMLFormat;
    189199    /** What formats does VBox have on offer? */
    190200    uint32_t vboxFormats;
     
    327337    uint32_t u32VBoxFormats = clipVBoxFormatForX11Format(pCtx->X11TextFormat);
    328338    u32VBoxFormats |= clipVBoxFormatForX11Format(pCtx->X11BitmapFormat);
     339    u32VBoxFormats |= clipVBoxFormatForX11Format(pCtx->X11HTMLFormat);
     340    LogRelFlowFunc(("clipReportFormatsToVBox format: %d\n", u32VBoxFormats));
     341    LogRelFlowFunc(("clipReportFormatsToVBox txt: %d, bitm: %d, html:%d, u32VBoxFormats: %d\n",
     342                    pCtx->X11TextFormat, pCtx->X11BitmapFormat, pCtx->X11HTMLFormat,
     343                    u32VBoxFormats ));
    329344    ClipReportX11Formats(pCtx->pFrontend, u32VBoxFormats);
    330345}
     
    337352    pCtx->X11TextFormat = INVALID;
    338353    pCtx->X11BitmapFormat = INVALID;
     354    pCtx->X11HTMLFormat = INVALID;
    339355}
    340356
     
    433449
    434450/**
     451 * Go through an array of X11 clipboard targets to see if they contain a HTML
     452 * format we can support, and if so choose the ones we prefer
     453 * @param  pCtx      the clipboard backend context structure
     454 * @param  pTargets  the list of targets
     455 * @param  cTargets  the size of the list in @a pTargets
     456 */
     457static CLIPX11FORMAT clipGetHtmlFormatFromTargets(CLIPBACKEND *pCtx,
     458                                                  CLIPX11FORMAT *pTargets,
     459                                                  size_t cTargets)
     460{
     461    CLIPX11FORMAT bestHTMLFormat = NIL_CLIPX11FORMAT;
     462    CLIPFORMAT enmBestHtmlTarget = INVALID;
     463    AssertPtrReturn(pCtx, NIL_CLIPX11FORMAT);
     464    AssertReturn(VALID_PTR(pTargets) || cTargets == 0, NIL_CLIPX11FORMAT);
     465    for (unsigned i = 0; i < cTargets; ++i)
     466    {
     467        CLIPX11FORMAT format = pTargets[i];
     468        if (format != NIL_CLIPX11FORMAT)
     469        {
     470            if (   (clipVBoxFormatForX11Format(format) == VBOX_SHARED_CLIPBOARD_FMT_HTML)
     471                    && enmBestHtmlTarget < clipRealFormatForX11Format(format))
     472            {
     473                enmBestHtmlTarget = clipRealFormatForX11Format(format);
     474                bestHTMLFormat = format;
     475            }
     476        }
     477    }
     478    return bestHTMLFormat;
     479}
     480
     481
     482/**
    435483 * Go through an array of X11 clipboard targets to see if we can support any
    436484 * of them and if relevant to choose the ones we prefer (e.g. we like Utf8
     
    447495    CLIPX11FORMAT bestTextFormat;
    448496    CLIPX11FORMAT bestBitmapFormat;
     497    CLIPX11FORMAT bestHtmlFormat;
    449498    bestTextFormat = clipGetTextFormatFromTargets(pCtx, pTargets, cTargets);
    450499    if (pCtx->X11TextFormat != bestTextFormat)
     
    457506    {
    458507        pCtx->X11BitmapFormat = bestBitmapFormat;
     508    }
     509    bestHtmlFormat = clipGetHtmlFormatFromTargets(pCtx, pTargets, cTargets);
     510    if(pCtx->X11HTMLFormat != bestHtmlFormat)
     511    {
     512        pCtx->X11HTMLFormat = bestHtmlFormat;
    459513    }
    460514}
     
    11201174
    11211175/**
     1176 * Satisfy a request from X11 to convert the clipboard HTML fragment to Utf-8.  We
     1177 * return null-terminated text, but can cope with non-null-terminated input.
     1178 *
     1179 * @returns iprt status code
     1180 * @param  pDisplay        an X11 display structure, needed for conversions
     1181 *                         performed by Xlib
     1182 * @param  pv              the text to be converted (UTF8 with Windows EOLs)
     1183 * @param  cb              the length of the text in @cb in bytes
     1184 * @param  atomTypeReturn  where to store the atom for the type of the data
     1185 *                         we are returning
     1186 * @param  pValReturn      where to store the pointer to the data we are
     1187 *                         returning.  This should be to memory allocated by
     1188 *                         XtMalloc, which will be freed by the Xt toolkit
     1189 *                         later.
     1190 * @param  pcLenReturn     where to store the length of the data we are
     1191 *                         returning
     1192 * @param  piFormatReturn  where to store the bit width (8, 16, 32) of the
     1193 *                         data we are returning
     1194 */
     1195static int clipWinHTMLToUtf8ForX11CB(Display *pDisplay, const char* pszSrc,
     1196                                    size_t cbSrc, Atom *atomTarget,
     1197                                    Atom *atomTypeReturn,
     1198                                    XtPointer *pValReturn,
     1199                                    unsigned long *pcLenReturn,
     1200                                    int *piFormatReturn)
     1201{
     1202    /* This may slightly overestimate the space needed. */
     1203    LogRelFlowFunc(("source: %s", pszSrc));
     1204
     1205    char *pszDest = (char *)XtMalloc(cbSrc);
     1206    if(pszDest == NULL)
     1207        return VERR_NO_MEMORY;
     1208       
     1209    memcpy(pszDest, pszSrc, cbSrc);
     1210
     1211    *atomTypeReturn = *atomTarget;
     1212    *pValReturn = (XtPointer)pszDest;
     1213    *pcLenReturn = cbSrc;
     1214    *piFormatReturn = 8;
     1215   
     1216    return VINF_SUCCESS;
     1217}
     1218
     1219
     1220/**
    11221221 * Does this atom correspond to one of the two selection types we support?
    11231222 * @param  widget   a valid Xt widget
     
    11421241    AssertPtrReturnVoid(pText);
    11431242    AssertPtrReturnVoid(pcText);
    1144     AssertReturnVoid((format == UTF8) || (format == TEXT));
     1243    AssertReturnVoid((format == UTF8) || (format == TEXT) || (format == HTML));
    11451244    if (((char *)pText)[*pcText - 1] == '\0')
    11461245       --(*pcText);
     
    12001299        }
    12011300        RTMemFree(pv);
     1301    }
     1302    else if ( (format == HTML)
     1303            && (pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML))
     1304    {
     1305        void *pv = NULL;
     1306        uint32_t cb = 0;
     1307        rc = clipReadVBoxClipboard(pCtx,
     1308                                   VBOX_SHARED_CLIPBOARD_FMT_HTML,
     1309                                   &pv, &cb);
     1310        if (RT_SUCCESS(rc) && (cb == 0))
     1311            rc = VERR_NO_DATA;
     1312        if (RT_SUCCESS(rc))
     1313        {
     1314            /*
     1315            * The common VBox HTML encoding will be - Utf8
     1316            * becuase it more general for HTML formats then UTF16
     1317            * X11 clipboard returns UTF16, so before sending it we should
     1318            * convert it to UTF8
     1319            * It's very strange but here we get utf16 from x11 clipboard
     1320            * in same time we send utf8 to x11 clipboard and it's work
     1321            */
     1322            rc = clipWinHTMLToUtf8ForX11CB(XtDisplay(pCtx->widget),
     1323                (const char*)pv, cb, atomTarget,
     1324                atomTypeReturn, pValReturn,
     1325                pcLenReturn, piFormatReturn);
     1326
     1327
     1328            if (RT_SUCCESS(rc))
     1329                clipTrimTrailingNul(*(XtPointer *)pValReturn, pcLenReturn, format);
     1330            RTMemFree(pv);
     1331        }
    12021332    }
    12031333    else
     
    14671597}
    14681598
     1599
     1600/**
     1601* Convert Utf16 text into UTF8 as Windows expects
     1602* it and return the result in a RTMemAlloc allocated buffer.
     1603* @returns  IPRT status code
     1604* @param  pcSrc      The source text
     1605* @param  cbSrc      The size of the source in bytes, not counting the
     1606*                    terminating zero
     1607* @param  ppwszDest  Where to store the buffer address
     1608* @param  pcbDest    On success, where to store the number of bytes written.
     1609*                    Undefined otherwise.  Optional
     1610*/
     1611int  clipUTF16ToWinHTML(RTUTF16* buffer, size_t cb, char **output, uint32_t *outsz)
     1612{
     1613    Assert(buffer);
     1614    Assert(cb);
     1615    Assert(output);
     1616    Assert(outsz);
     1617
     1618    size_t i = 0;
     1619    RTUTF16* p = buffer;
     1620    char* result = NULL;
     1621    size_t resultLen = 0;
     1622    LogRelFlowFunc(("clipUTF16ToWinHTML src= %ls cb=%d i=%i, %x %x\n", buffer, cb, i, output, outsz));
     1623    while (i != cb / 2)
     1624    {
     1625        /* find  zero symbol (end of string) */
     1626        for (; i < cb / 2 && buffer[i] != 0; i++);
     1627        LogRelFlowFunc(("skipped nulls i=%d cb/2=%d\n", i, cb / 2));
     1628
     1629        /* convert found string */
     1630        char* cTmp = NULL;
     1631        size_t sz = 0;
     1632        int rc = RTUtf16ToUtf8Ex(p, cb / 2, &cTmp, p - buffer, &sz);
     1633        LogRelFlowFunc(("utf16toutf8 src= %ls res=%s i=%i\n", p, cTmp, i));
     1634        if (!RT_SUCCESS(rc))
     1635            return rc;
     1636
     1637        /* append new substring */
     1638        result = (char*)RTMemRealloc(result, resultLen + sz + 1);
     1639        if (result == NULL)
     1640        {
     1641            RTStrFree(cTmp);
     1642            cTmp = NULL;
     1643            return VERR_NO_MEMORY;
     1644        }
     1645        memcpy(result + resultLen, cTmp, sz + 1);
     1646        LogRelFlowFunc(("Temp result res=%s\n", result + resultLen));
     1647
     1648        /* remove temporary buffer */
     1649        RTStrFree(cTmp);
     1650        resultLen += sz + 1;
     1651        /* skip zero symbols */
     1652        for (; i < cb / 2 && buffer[i] == 0; i++);
     1653        /* remember start of string */
     1654        p += i;
     1655    }
     1656    *output = result;
     1657    *outsz = resultLen;
     1658
     1659    return VINF_SUCCESS;
     1660}
     1661
     1662
     1663
    14691664/** A structure containing information about where to store a request
    14701665 * for the X11 clipboard contents. */
     
    14771672    /** The bitmap format we requested from X11 if we requested bitmap */
    14781673    CLIPX11FORMAT mBitmapFormat;
     1674    /** The HTML format we requested from X11 if we requested HTML */
     1675    CLIPX11FORMAT mHtmlFormat;
    14791676    /** The clipboard context this request is associated with */
    14801677    CLIPBACKEND *mCtx;
     
    14971694    CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *) pClientData;
    14981695    LogRelFlowFunc(("pReq->mFormat=%02X, pReq->mTextFormat=%u, "
    1499                 "pReq->mBitmapFormat=%u, pReq->mCtx=%p\n",
     1696                "pReq->mBitmapFormat=%u, pReq->mHtmlFormat=%u, pReq->mCtx=%p\n",
    15001697                 pReq->mFormat, pReq->mTextFormat, pReq->mBitmapFormat,
    1501                  pReq->mCtx));
     1698                 pReq->mHtmlFormat, pReq->mCtx));
    15021699    AssertPtr(pReq->mCtx);
    15031700    Assert(pReq->mFormat != 0);  /* sanity */
     
    15641761        }
    15651762    }
     1763    else if(pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_HTML)
     1764    {
     1765        /* In which format is the clipboard data? */
     1766        switch (clipRealFormatForX11Format(pReq->mHtmlFormat))
     1767        {
     1768            case HTML:
     1769            {
     1770                /* The common VBox HTML encoding will be - Utf8
     1771                * becuase it more general for HTML formats then UTF16
     1772                * X11 clipboard returns UTF16, so before sending it we should
     1773                * convert it to UTF8
     1774                */
     1775                pvDest = NULL;
     1776                cbDest = 0;
     1777                rc = clipUTF16ToWinHTML((RTUTF16*)pvSrc, cbSrc,
     1778                    (char**)&pvDest, &cbDest);
     1779                LogRelFlowFunc(("Source unicode %ls, cbSrc = %d\n", pvSrc, cbSrc));
     1780                LogRelFlowFunc(("converted to win unicode %s, cbDest = %d, rc = %Rrc\n", pvDest, cbDest, rc));
     1781                rc = VINF_SUCCESS;
     1782                break;
     1783            }
     1784            default:
     1785            {
     1786                rc = VERR_INVALID_PARAMETER;
     1787            }
     1788        }
     1789    }
    15661790    else
    15671791        rc = VERR_NOT_IMPLEMENTED;
     
    16531877            getSelectionValue(pCtx, pCtx->X11BitmapFormat, pReq);
    16541878    }
    1655     else
     1879    else if(pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_HTML)
     1880    {
     1881        /* Send out a request for the data to the current clipboard
     1882             * owner */
     1883        pReq->mHtmlFormat = pCtx->X11HTMLFormat;
     1884        if(pReq->mHtmlFormat == INVALID)
     1885                    /* VBox thinks we have data and we don't */
     1886            rc = VERR_NO_DATA;
     1887        else
     1888            /* Send out a request for the data to the current clipboard
     1889             * owner */
     1890            getSelectionValue(pCtx, pCtx->X11HTMLFormat, pReq);
     1891    }
     1892    else   
    16561893        rc = VERR_NOT_IMPLEMENTED;
    16571894    if (RT_FAILURE(rc))
     
    25452782
    25462783#endif /* SMOKETEST defined */
     2784
     2785                   
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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