VirtualBox

Changeset 19219 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Apr 27, 2009 3:53:25 PM (16 years ago)
Author:
vboxsync
Message:

GuestHost/clipboard/x11: use Xt caching atom functions and fix the testcase a bit

File:
1 edited

Legend:

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

    r19169 r19219  
    2424
    2525#include <errno.h>
    26 #include <vector>
    2726
    2827#include <unistd.h>
     
    5857
    5958/** The different clipboard formats which we support. */
    60 enum g_eClipboardFormats
     59enum CLIPFORMAT
    6160{
    6261    INVALID = 0,
     
    6665};
    6766
    68 /** The X11 clipboard uses several names for the same format.  This
    69  * structure maps an X11 name to a format. */
    70 typedef struct {
    71     Atom atom;
    72     g_eClipboardFormats format;
    73     unsigned guestFormat;
    74 } VBOXCLIPBOARDFORMAT;
     67/** The table mapping X11 names to data formats and to the corresponding
     68 * VBox clipboard formats (currently only Unicode) */
     69static struct _CLIPFORMATTABLE
     70{
     71    /** The X11 atom name of the format (several names can match one format)
     72     */
     73    const char *pcszAtom;
     74    /** The format corresponding to the name */
     75    CLIPFORMAT enmFormat;
     76    /** The corresponding VBox clipboard format */
     77    uint32_t   u32VBoxFormat;
     78} g_aFormats[] =
     79{
     80    { "UTF8_STRING", UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     81    { "text/plain;charset=UTF-8", UTF8,
     82      VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     83    { "text/plain;charset=utf-8", UTF8,
     84      VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     85    { "STRING", UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     86    { "TEXT", UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     87    { "text/plain", UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     88    { "COMPOUND_TEXT", CTEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT }
     89};
    7590
    7691/** Global context information used by the X11 clipboard backend */
     
    87102    Widget widget;
    88103
    89     /** X11 atom refering to the clipboard: CLIPBOARD */
    90     Atom atomClipboard;
    91     /** X11 atom refering to the selection: PRIMARY */
    92     Atom atomPrimary;
    93     /** X11 atom refering to the clipboard targets: TARGETS */
    94     Atom atomTargets;
    95     /** X11 atom refering to the clipboard multiple target: MULTIPLE */
    96     Atom atomMultiple;
    97     /** X11 atom refering to the clipboard timestamp target: TIMESTAMP */
    98     Atom atomTimestamp;
    99     /** X11 atom refering to the clipboard utf8 text format: UTF8_STRING */
    100     Atom atomUtf8;
    101     /** X11 atom refering to the clipboard compound text format: COMPOUND_TEXT */
    102     Atom atomCText;
    103 
    104     /** A list of the X11 formats which we support, mapped to our identifier for them, in the
    105         order we prefer to have them in. */
    106     std::vector<VBOXCLIPBOARDFORMAT> formatList;
    107 
    108104    /** Does VBox currently own the clipboard?  If so, we don't need to poll
    109105     * X11 for supported formats. */
     
    111107
    112108    /** What is the best text format X11 has to offer?  INVALID for none. */
    113     g_eClipboardFormats X11TextFormat;
     109    CLIPFORMAT X11TextFormat;
    114110    /** Atom corresponding to the X11 text format */
    115111    Atom atomX11TextFormat;
    116112    /** What is the best bitmap format X11 has to offer?  INVALID for none.
    117113     */
    118     g_eClipboardFormats X11BitmapFormat;
     114    CLIPFORMAT X11BitmapFormat;
    119115    /** Atom corresponding to the X11 Bitmap format */
    120116    Atom atomX11BitmapFormat;
     
    210206}
    211207
     208/** Convert an atom name string to an X11 atom, looking it up in a cache
     209 * before asking the server */
     210static Atom clipGetAtom(Widget widget, const char *pszName)
     211{
     212    AssertPtrReturn(pszName, None);
     213    Atom retval = None;
     214    XrmValue nameVal, atomVal;
     215    nameVal.addr = (char *) pszName;
     216    nameVal.size = strlen(pszName);
     217    atomVal.size = sizeof(Atom);
     218    atomVal.addr = (char *) &retval;
     219    XtConvertAndStore(widget, XtRString, &nameVal, XtRAtom, &atomVal);
     220    return retval;
     221}
     222
    212223/* Are we actually connected to the X server? */
    213224static bool g_fHaveX11;
     
    311322    /* First convert the compound text to Utf8 */
    312323    property.value = reinterpret_cast<unsigned char *>(pValue);
    313     property.encoding = pCtx->atomCText;
     324    property.encoding = clipGetAtom(pCtx->widget, "COMPOUND_TEXT");
    314325    property.format = 8;
    315326    property.nitems = cbSrcLen;
     
    515526    Atom *atomTargets = reinterpret_cast<Atom *>(pValue);
    516527    unsigned cAtoms = *pcLen;
    517     g_eClipboardFormats eBestTarget = INVALID;
     528    CLIPFORMAT enmBestTarget = INVALID;
     529    CLIPFORMAT enmRequiredTarget = INVALID;
    518530    Atom atomBestTarget = None;
    519531
     
    529541    }
    530542
     543    /* Debugging stuff */
     544    if (g_testUtf8)
     545        enmRequiredTarget = UTF8;
     546    else if (g_testCText)
     547        enmRequiredTarget = CTEXT;
     548
    531549    for (unsigned i = 0; i < cAtoms; ++i)
    532550    {
    533         for (unsigned j = 0; j != pCtx->formatList.size(); ++j)
    534             if (pCtx->formatList[j].atom == atomTargets[i])
     551        for (unsigned j = 0; j < RT_ELEMENTS(g_aFormats); ++j)
     552        {
     553            Atom formatAtom = clipGetAtom(pCtx->widget,
     554                                          g_aFormats[j].pcszAtom);
     555            if (atomTargets[i] == formatAtom)
    535556            {
    536                 if (eBestTarget < pCtx->formatList[j].format)
     557                if (   enmBestTarget < g_aFormats[j].enmFormat
     558                    /* debugging stuff */
     559                    && (   enmRequiredTarget == INVALID
     560                        || enmRequiredTarget == g_aFormats[j].enmFormat))
    537561                {
    538                     eBestTarget = pCtx->formatList[j].format;
    539                     atomBestTarget = pCtx->formatList[j].atom;
     562                    enmBestTarget = g_aFormats[j].enmFormat;
     563                    atomBestTarget = formatAtom;
    540564                }
    541565                break;
    542566            }
     567        }
    543568        if (g_debugClipboard)
    544569        {
     
    554579    }
    555580    pCtx->atomX11TextFormat = atomBestTarget;
    556     if ((eBestTarget != pCtx->X11TextFormat) || (pCtx->notifyVBox == true))
     581    if ((enmBestTarget != pCtx->X11TextFormat) || (pCtx->notifyVBox == true))
    557582    {
    558583        uint32_t u32Formats = 0;
     
    581606            }
    582607        }
    583         pCtx->X11TextFormat = eBestTarget;
    584         if (eBestTarget != INVALID)
     608        pCtx->X11TextFormat = enmBestTarget;
     609        if (enmBestTarget != INVALID)
    585610            u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
    586611        VBoxX11ClipboardReportX11Formats(pCtx->pFrontend, u32Formats);
     
    609634        Log3 (("%s: requesting the targets that the host clipboard offers\n",
    610635               __PRETTY_FUNCTION__));
    611         XtGetSelectionValue(pCtx->widget, pCtx->atomClipboard,
    612                             pCtx->atomTargets,
     636        XtGetSelectionValue(pCtx->widget, clipGetAtom(pCtx->widget, "CLIPBOARD"),
     637                            clipGetAtom(pCtx->widget, "TARGETS"),
    613638                            vboxClipboardGetTargetsFromX11, pCtx,
    614639                            CurrentTime);
     
    617642    XtAppAddTimeOut(pCtx->appContext, 200 /* ms */,
    618643                    vboxClipboardPollX11ForTargets, pCtx);
    619 }
    620 
    621 /** We store information about the target formats we can handle in a global
    622  * vector for internal use.
    623  * @note  X11 backend code.
    624  */
    625 static void vboxClipboardAddFormat(VBOXCLIPBOARDCONTEXTX11 *pCtx,
    626                                    const char *pszName,
    627                                    g_eClipboardFormats eFormat,
    628                                    unsigned guestFormat)
    629 {
    630     VBOXCLIPBOARDFORMAT sFormat;
    631     /* Get an atom from the X server for that target format */
    632     Atom atomFormat = XInternAtom(XtDisplay(pCtx->widget), pszName, false);
    633     sFormat.atom   = atomFormat;
    634     sFormat.format = eFormat;
    635     sFormat.guestFormat = guestFormat;
    636     pCtx->formatList.push_back(sFormat);
    637     LogFlow (("vboxClipboardAddFormat: added format %s (%d)\n", pszName, eFormat));
    638644}
    639645
     
    654660    while (XtAppGetExitFlag(pCtx->appContext) == FALSE)
    655661        XtAppProcessEvent(pCtx->appContext, XtIMAll);
    656     pCtx->formatList.clear();
    657662    LogRel(("Shared clipboard: host clipboard thread terminated successfully\n"));
    658663    return VINF_SUCCESS;
     
    744749        XtSetMappedWhenManaged(pCtx->widget, false);
    745750        XtRealizeWidget(pCtx->widget);
    746 
    747         /* Get hold of the atoms which we need */
    748         pCtx->atomClipboard = XInternAtom(XtDisplay(pCtx->widget), "CLIPBOARD", false /* only_if_exists */);
    749         pCtx->atomPrimary   = XInternAtom(XtDisplay(pCtx->widget), "PRIMARY",   false);
    750         pCtx->atomTargets   = XInternAtom(XtDisplay(pCtx->widget), "TARGETS",   false);
    751         pCtx->atomMultiple  = XInternAtom(XtDisplay(pCtx->widget), "MULTIPLE",  false);
    752         pCtx->atomTimestamp = XInternAtom(XtDisplay(pCtx->widget), "TIMESTAMP", false);
    753         pCtx->atomUtf8      = XInternAtom(XtDisplay(pCtx->widget), "UTF_STRING", false);
    754         /* And build up the vector of supported formats */
    755         pCtx->atomCText     = XInternAtom(XtDisplay(pCtx->widget), "COMPOUND_TEXT", false);
    756         /* And build up the vector of supported formats */
    757         if (!g_testCText)
    758         {
    759             vboxClipboardAddFormat(pCtx, "UTF8_STRING", UTF8,
    760                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    761             vboxClipboardAddFormat(pCtx, "text/plain;charset=UTF-8", UTF8,
    762                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    763             vboxClipboardAddFormat(pCtx, "text/plain;charset=utf-8", UTF8,
    764                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    765             vboxClipboardAddFormat(pCtx, "STRING", UTF8,
    766                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    767             vboxClipboardAddFormat(pCtx, "TEXT", UTF8,
    768                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    769             vboxClipboardAddFormat(pCtx, "text/plain", UTF8,
    770                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    771 }
    772         if (!g_testUtf8)
    773             vboxClipboardAddFormat(pCtx, "COMPOUND_TEXT", CTEXT,
    774                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
    775751    }
    776752    /* Create the pipes */
     
    949925                                                 int *piFormatReturn)
    950926{
    951     unsigned uListSize = pCtx->formatList.size();
     927    unsigned uListSize = RT_ELEMENTS(g_aFormats);
    952928    Atom *atomTargets = reinterpret_cast<Atom *>(XtMalloc((uListSize + 3) * sizeof(Atom)));
    953929    unsigned cTargets = 0;
     
    956932    for (unsigned i = 0; i < uListSize; ++i)
    957933    {
    958         if (   ((pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) != 0)
    959             && (   pCtx->formatList[i].guestFormat
     934        if (   (pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     935            && (   g_aFormats[i].u32VBoxFormat
    960936                == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT))
    961937        {
    962             atomTargets[cTargets] = pCtx->formatList[i].atom;
     938            atomTargets[cTargets] = clipGetAtom(pCtx->widget,
     939                                                g_aFormats[i].pcszAtom);
    963940            ++cTargets;
    964941        }
    965942    }
    966     atomTargets[cTargets] = pCtx->atomTargets;
    967     atomTargets[cTargets + 1] = pCtx->atomMultiple;
    968     atomTargets[cTargets + 2] = pCtx->atomTimestamp;
     943    atomTargets[cTargets] = clipGetAtom(pCtx->widget, "TARGETS");
     944    atomTargets[cTargets + 1] = clipGetAtom(pCtx->widget, "MULTIPLE");
     945    atomTargets[cTargets + 2] = clipGetAtom(pCtx->widget, "TIMESTAMP");
    969946    if (g_debugClipboard)
    970947    {
     
    11341111    LogFlowFunc (("converted string is %.*s. Returning.\n", cbDestLen, pu8DestText));
    11351112    RTMemFree(pvVBox);
    1136     *atomTypeReturn = pCtx->atomUtf8;
     1113    *atomTypeReturn = clipGetAtom(pCtx->widget, "UTF8_STRING");
    11371114    *pValReturn = reinterpret_cast<XtPointer>(pu8DestText);
    11381115    *pcLenReturn = cbDestLen;
     
    12821259                                          int *piFormatReturn)
    12831260{
    1284     g_eClipboardFormats eFormat = INVALID;
     1261    CLIPFORMAT enmFormat = INVALID;
    12851262    VBOXCLIPBOARDCONTEXTX11 *pCtx = vboxClipboardFindContext(widget);
    12861263
     
    12891266    if (!pCtx->fOwnsClipboard)
    12901267        return false;
    1291     if (   (*atomSelection != pCtx->atomClipboard)
    1292         && (*atomSelection != pCtx->atomPrimary)
     1268    if (   (*atomSelection != clipGetAtom(pCtx->widget, "CLIPBOARD"))
     1269        && (*atomSelection != clipGetAtom(pCtx->widget, "PRIMARY"))
    12931270       )
    12941271    {
     
    13091286        }
    13101287    }
    1311     if (*atomTarget == pCtx->atomTargets)
    1312     {
    1313         eFormat = TARGETS;
     1288    if (*atomTarget == clipGetAtom(pCtx->widget, "TARGETS"))
     1289    {
     1290        enmFormat = TARGETS;
    13141291    }
    13151292    else
    13161293    {
    1317         for (unsigned i = 0; i != pCtx->formatList.size(); ++i)
    1318         {
    1319             if (pCtx->formatList[i].atom == *atomTarget)
     1294        for (unsigned i = 0; i < RT_ELEMENTS(g_aFormats); ++i)
     1295        {
     1296            if (*atomTarget == clipGetAtom(pCtx->widget,
     1297                                           g_aFormats[i].pcszAtom))
    13201298            {
    1321                 eFormat = pCtx->formatList[i].format;
     1299                enmFormat = g_aFormats[i].enmFormat;
    13221300                break;
    13231301            }
    13241302        }
    13251303    }
    1326     switch (eFormat)
     1304    switch (enmFormat)
    13271305    {
    13281306    case TARGETS:
     
    13911369    {
    13921370        /* This is just an automatism, not a genuine anouncement */
    1393         XtDisownSelection(pCtx->widget, pCtx->atomClipboard, CurrentTime);
     1371        XtDisownSelection(pCtx->widget, clipGetAtom(pCtx->widget, "CLIPBOARD"), CurrentTime);
    13941372        pCtx->fOwnsClipboard = false;
    13951373        LogFlowFunc(("returning\n"));
     
    13971375    }
    13981376    Log2 (("%s: giving the guest clipboard ownership\n", __PRETTY_FUNCTION__));
    1399     if (XtOwnSelection(pCtx->widget, pCtx->atomClipboard, CurrentTime,
     1377    if (XtOwnSelection(pCtx->widget, clipGetAtom(pCtx->widget, "CLIPBOARD"), CurrentTime,
    14001378                       vboxClipboardConvertForX11, vboxClipboardReturnToX11,
    14011379                       0) == True)
     
    14031381        pCtx->fOwnsClipboard = true;
    14041382        /* Grab the middle-button paste selection too. */
    1405         XtOwnSelection(pCtx->widget, pCtx->atomPrimary, CurrentTime,
     1383        XtOwnSelection(pCtx->widget, clipGetAtom(pCtx->widget, "PRIMARY"), CurrentTime,
    14061384                       vboxClipboardConvertForX11, NULL, 0);
    14071385    }
     
    14751453                /* Send out a request for the data to the current clipboard
    14761454                 * owner */
    1477                 XtGetSelectionValue(pCtx->widget, pCtx->atomClipboard,
     1455                XtGetSelectionValue(pCtx->widget, clipGetAtom(pCtx->widget, "CLIPBOARD"),
    14781456                                    pCtx->atomX11TextFormat,
    14791457                                    vboxClipboardGetDataFromX11,
     
    17421720    int rc = VINF_SUCCESS;
    17431721    int status = 0;
     1722    g_debugClipboard = true;
    17441723    /* We can't test anything without an X session, so just return success
    17451724     * in that case. */
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