VirtualBox

Changeset 18416 in vbox for trunk/src/VBox/HostServices


Ignore:
Timestamp:
Mar 27, 2009 5:26:44 PM (16 years ago)
Author:
vboxsync
Message:

HostServices/SharedClipboard: split up the global context structure into a host-specific and a back-end-specific part

File:
1 edited

Legend:

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

    r18408 r18416  
    9595} VBOXBITMAPFILEHEADER;
    9696
    97 /** Global clipboard context information */
     97/** Global context information used by the host clipboard subsystem */
    9898struct _VBOXCLIPBOARDCONTEXT
     99{
     100    /** Since the clipboard data moves asynchronously, we use an event
     101     * semaphore to wait for it.  When a function issues a request for
     102     * clipboard data it must wait for this semaphore, which is triggered
     103     * when the data arrives. */
     104    RTSEMEVENT waitForData;
     105    /** Who (if anyone) is currently waiting for data?  Used for sanity
     106     * checks when data arrives. */
     107    volatile uint32_t waiter;
     108    /** This mutex is grabbed during any critical operations on the clipboard
     109     * which might clash with others. */
     110    /** @todo this is still used in X11 backend parts, disentangle it. */
     111    RTSEMMUTEX clipboardMutex;
     112
     113    /** @todo both the VBox subsystem and the X11 backend need the following
     114     * members, so we need to transfer them between the two contexts at
     115     * an appropriate time */
     116    /** Format which we are reading from the X11 clipboard (valid during a
     117     * request for its contents) */
     118    g_eClipboardFormats requestX11Format;
     119    /** The buffer to write X11 clipboard data to (valid during a request
     120     * for the clipboard contents) */
     121    void *requestBuffer;
     122    /** The size of the buffer to write X11 clipboard data to (valid during
     123     * a request for the clipboard contents) */
     124    unsigned requestBufferSize;
     125    /** The size of the X11 clipboard data written to the buffer (valid
     126     * during a request for the clipboard contents) */
     127    uint32_t *requestActualSize;
     128
     129    /** Pointer to the client data structure */
     130    VBOXCLIPBOARDCLIENTDATA *pClient;
     131};
     132
     133/** Global context information used by the X11 clipboard backend */
     134struct _VBOXCLIPBOARDCONTEXTX11
    99135{
    100136    /** The X Toolkit application context structure */
     
    127163    std::vector<VBOXCLIPBOARDFORMAT> formatList;
    128164
    129     /** Does the host or the guest currently own the clipboard? */
     165    /** Does VBox or X11 currently own the clipboard? */
    130166    volatile enum g_eOwner eOwner;
    131167
    132     /** What is the best text format the host has to offer?  INVALID for none. */
    133     g_eClipboardFormats hostTextFormat;
    134     /** Atom corresponding to the host text format */
    135     Atom atomHostTextFormat;
    136     /** What is the best bitmap format the host has to offer?  INVALID for none. */
    137     g_eClipboardFormats hostBitmapFormat;
    138     /** Atom corresponding to the host Bitmap format */
    139     Atom atomHostBitmapFormat;
    140     /** What formats does the guest have on offer? */
    141     int guestFormats;
    142     /** Windows caches the clipboard data it receives.  Since we have no way of knowing whether
    143         that data is still valid, we always send a "data changed" message after a successful
    144         transfer to invalidate the cache. */
    145     bool notifyGuest;
    146 
    147     /** Since the clipboard data moves asynchronously, we use an event semaphore to wait for
    148         it.  When a function issues a request for clipboard data it must wait for this
    149         semaphore, which is triggered when the data arrives. */
     168    /** What is the best text format X11 has to offer?  INVALID for none. */
     169    g_eClipboardFormats X11TextFormat;
     170    /** Atom corresponding to the X11 text format */
     171    Atom atomX11TextFormat;
     172    /** What is the best bitmap format X11 has to offer?  INVALID for none. */
     173    g_eClipboardFormats X11BitmapFormat;
     174    /** Atom corresponding to the X11 Bitmap format */
     175    Atom atomX11BitmapFormat;
     176    /** What formats does VBox have on offer? */
     177    int vboxFormats;
     178    /** Windows hosts and guests cache the clipboard data they receive.
     179     * Since we have no way of knowing whether their cache is still valid,
     180     * we always send a "data changed" message after a successful transfer
     181     * to invalidate it. */
     182    bool notifyVBox;
     183
     184    /** Since the clipboard data moves asynchronously, we use an event
     185     * semaphore to wait for it.  When a function issues a request for
     186     * clipboard data it must wait for this semaphore, which is triggered
     187     * when the data arrives. */
    150188    RTSEMEVENT waitForData;
    151     /** Who (if anyone) is currently waiting for data?  Used for sanity checks
    152      *  when data arrives. */
    153     volatile uint32_t waiter;
    154     /** This mutex is grabbed during any critical operations on the clipboard
    155      * which might clash with others. */
    156     RTSEMMUTEX clipboardMutex;
    157 
    158     /** Format which we are reading from the host clipboard (valid during a request for the
    159         host clipboard) */
    160     g_eClipboardFormats requestHostFormat;
    161     /** The guest buffer to write host clipboard data to (valid during a request for the host
    162         clipboard) */
     189
     190    /** Format which we are reading from the X11 clipboard (valid during a
     191     * request for its contents) */
     192    g_eClipboardFormats requestX11Format;
     193    /** The buffer to write X11 clipboard data to (valid during a request
     194     * for the clipboard contents) */
    163195    void *requestBuffer;
    164     /** The size of the guest buffer to write host clipboard data to (valid during a request for
    165         the host clipboard) */
     196    /** The size of the buffer to write X11 clipboard data to (valid during
     197     * a request for the clipboard contents) */
    166198    unsigned requestBufferSize;
    167     /** The size of the host clipboard data written to the guest buffer (valid during a request
    168         for the host clipboard) */
     199    /** The size of the X11 clipboard data written to the buffer (valid
     200     * during a request for the clipboard contents) */
    169201    uint32_t *requestActualSize;
    170 
    171     /** Pointer to the client data structure */
    172     VBOXCLIPBOARDCLIENTDATA *pClient;
    173202};
    174203
    175 /* Only one client is supported. There seems to be no need for more clients. */
    176 static VBOXCLIPBOARDCONTEXT g_ctx;
    177 
    178 /* Are we actually connected to the X11 servicer? */
     204typedef struct _VBOXCLIPBOARDCONTEXTX11 VBOXCLIPBOARDCONTEXTX11;
     205
     206/* Only one client is supported. There seems to be no need for more clients.
     207 */
     208static VBOXCLIPBOARDCONTEXT g_ctxHost;
     209static VBOXCLIPBOARDCONTEXTX11 g_ctxX11;
     210
     211/* Are we actually connected to the X server? */
    179212static bool g_fHaveX11;
    180213
     
    200233         * data from X11. */
    201234        LogFunc(("host requested guest clipboard data after guest had disconnected.\n"));
    202         pCtx->guestFormats = 0;
     235        /** @todo call vboxClipboardFormatAnnounce to do this. */
     236        g_ctxX11.vboxFormats = 0; 
    203237        pCtx->waiter = NONE;
    204238        return VERR_TIMEOUT;
     
    230264     * are still waiting after it acquires the mutex.  After we release the
    231265     * mutex, we finally do our check to see whether the data was delivered. */
    232     RTSemMutexRequest(g_ctx.clipboardMutex, RT_INDEFINITE_WAIT);
     266    RTSemMutexRequest(g_ctxHost.clipboardMutex, RT_INDEFINITE_WAIT);
    233267    pCtx->waiter = NONE;
    234     RTSemMutexRelease(g_ctx.clipboardMutex);
     268    RTSemMutexRelease(g_ctxHost.clipboardMutex);
    235269    AssertLogRelRCSuccess(rc);
    236270    if (RT_FAILURE(rc))
     
    239273         * to prove the contrary. */
    240274        RTMemFree(pClient->data.pv);
    241         g_ctx.pClient->data.pv = 0;
    242         g_ctx.pClient->data.cb = 0;
    243         g_ctx.pClient->data.u32Format = 0;
    244         pCtx->guestFormats = 0;
     275        g_ctxHost.pClient->data.pv = 0;
     276        g_ctxHost.pClient->data.cb = 0;
     277        g_ctxHost.pClient->data.u32Format = 0;
     278        /** @todo call vboxClipboardFormatAnnounce to do this. */
     279        g_ctxX11.vboxFormats = 0;
    245280        return rc;
    246281    }
     
    250285    *ppv = pClient->data.pv;
    251286    *pcb = pClient->data.cb;
    252     g_ctx.pClient->data.pv = 0;
    253     g_ctx.pClient->data.cb = 0;
    254     g_ctx.pClient->data.u32Format = 0;
     287    g_ctxHost.pClient->data.pv = 0;
     288    g_ctxHost.pClient->data.cb = 0;
     289    g_ctxHost.pClient->data.u32Format = 0;
    255290    return VINF_SUCCESS;
    256291}
     
    298333    /* We need to do this whether we succeed or fail. */
    299334    XtFree(reinterpret_cast<char *>(pValue));
    300     RTSemEventSignal(g_ctx.waitForData);
     335    RTSemEventSignal(g_ctxX11.waitForData);
    301336    LogFlowFunc(("Returning.  Status is %Rrc\n", rc));
    302337}
     
    350385    XtFree(reinterpret_cast<char *>(pValue));
    351386    RTUtf16Free(pu16SrcText);
    352     RTSemEventSignal(g_ctx.waitForData);
     387    RTSemEventSignal(g_ctxX11.waitForData);
    353388    LogFlowFunc(("Returning.  Status is %Rrc", rc));
    354389}
     
    384419    /* First convert the compound text to Utf8 */
    385420    property.value = reinterpret_cast<unsigned char *>(pValue);
    386     property.encoding = g_ctx.atomCText;
     421    property.encoding = g_ctxX11.atomCText;
    387422    property.format = 8;
    388423    property.nitems = cbSrcLen;
    389424#ifdef RT_OS_SOLARIS
    390     int xrc = XmbTextPropertyToTextList(XtDisplay(g_ctx.widget), &property, &ppu8SrcText, &cProps);
     425    int xrc = XmbTextPropertyToTextList(XtDisplay(g_ctxX11.widget), &property, &ppu8SrcText, &cProps);
    391426#else
    392     int xrc = Xutf8TextPropertyToTextList(XtDisplay(g_ctx.widget), &property, &ppu8SrcText, &cProps);
     427    int xrc = Xutf8TextPropertyToTextList(XtDisplay(g_ctxX11.widget), &property, &ppu8SrcText, &cProps);
    393428#endif
    394429    XtFree(reinterpret_cast<char *>(pValue));
     
    432467    RTUtf16Free(pu16SrcText);
    433468    LogFlowFunc(("Returning.  Status is %Rrc\n", rc));
    434     RTSemEventSignal(g_ctx.waitForData);
     469    RTSemEventSignal(g_ctxX11.waitForData);
    435470}
    436471
     
    486521    }
    487522    XtFree(reinterpret_cast<char *>(pValue));
    488     RTSemEventSignal(g_ctx.waitForData);
     523    RTSemEventSignal(g_ctxX11.waitForData);
    489524    LogFlowFunc(("Returning.  Status is %Rrc\n", rc));
    490525}
     
    503538{
    504539    LogFlowFunc(("pClientData=%p, *pcLen=%lu, *piFormat=%d\n", pClientData, *pcLen, *piFormat));
    505     LogFlowFunc(("g_ctx.requestHostFormat=%d, g_ctx.requestBufferSize=%d\n",
    506                  g_ctx.requestHostFormat, g_ctx.requestBufferSize));
     540    LogFlowFunc(("g_ctxHost.requestX11Format=%d, g_ctxHost.requestBufferSize=%d\n",
     541                 g_ctxHost.requestX11Format, g_ctxHost.requestBufferSize));
    507542    unsigned cTextLen = (*pcLen) * (*piFormat) / 8;
    508543    /* The X Toolkit may have failed to get the clipboard selection for us. */
     
    514549    /* We grab this mutex whenever an asynchronous clipboard operation completes and while
    515550       disconnecting a client from the clipboard to stop these operations colliding. */
    516     RTSemMutexRequest(g_ctx.clipboardMutex, RT_INDEFINITE_WAIT);
    517     if (reinterpret_cast<VBOXCLIPBOARDCLIENTDATA *>(pClientData) != g_ctx.pClient)
     551    RTSemMutexRequest(g_ctxHost.clipboardMutex, RT_INDEFINITE_WAIT);
     552    if (reinterpret_cast<VBOXCLIPBOARDCLIENTDATA *>(pClientData) != g_ctxHost.pClient)
    518553    {
    519554        /* If the client is no longer connected, just return. */
    520555        XtFree(reinterpret_cast<char *>(pValue));
    521556        LogFlowFunc(("client is no longer connected, returning\n"));
    522         RTSemMutexRelease(g_ctx.clipboardMutex);
     557        RTSemMutexRelease(g_ctxHost.clipboardMutex);
    523558        return;
    524559    }
    525560
    526561    /* In which format did we request the clipboard data? */
    527     switch (g_ctx.requestHostFormat)
     562    switch (g_ctxHost.requestX11Format)
    528563    {
    529564    case UTF16:
    530         vboxClipboardGetUtf16(pValue, cTextLen / 2, g_ctx.requestBuffer, g_ctx.requestBufferSize,
    531                               g_ctx.requestActualSize);
     565        vboxClipboardGetUtf16(pValue, cTextLen / 2, g_ctxHost.requestBuffer, g_ctxHost.requestBufferSize,
     566                              g_ctxHost.requestActualSize);
    532567        break;
    533568    case CTEXT:
    534         vboxClipboardGetCTextFromX11(pValue, cTextLen, g_ctx.requestBuffer, g_ctx.requestBufferSize,
    535                               g_ctx.requestActualSize);
     569        vboxClipboardGetCTextFromX11(pValue, cTextLen, g_ctxHost.requestBuffer, g_ctxHost.requestBufferSize,
     570                              g_ctxHost.requestActualSize);
    536571        break;
    537572    case UTF8:
     
    541576        char *pu8SourceText = reinterpret_cast<char *>(pValue);
    542577
    543         if ((g_ctx.requestHostFormat == UTF8)
     578        if ((g_ctxHost.requestX11Format == UTF8)
    544579            && (RTStrUniLenEx(pu8SourceText, *pcLen, &cStringLen) == VINF_SUCCESS))
    545580        {
    546             vboxClipboardGetUtf8FromX11(pValue, cTextLen, g_ctx.requestBuffer, g_ctx.requestBufferSize,
    547                                  g_ctx.requestActualSize);
     581            vboxClipboardGetUtf8FromX11(pValue, cTextLen, g_ctxHost.requestBuffer, g_ctxHost.requestBufferSize,
     582                                 g_ctxHost.requestActualSize);
    548583            break;
    549584        }
    550585        else
    551586        {
    552             vboxClipboardGetLatin1FromX11(pValue, cTextLen, g_ctx.requestBuffer, g_ctx.requestBufferSize,
    553                                    g_ctx.requestActualSize);
     587            vboxClipboardGetLatin1FromX11(pValue, cTextLen, g_ctxHost.requestBuffer, g_ctxHost.requestBufferSize,
     588                                   g_ctxHost.requestActualSize);
    554589            break;
    555590        }
     
    558593        LogFunc (("bad target format\n"));
    559594        XtFree(reinterpret_cast<char *>(pValue));
    560         RTSemMutexRelease(g_ctx.clipboardMutex);
     595        RTSemMutexRelease(g_ctxHost.clipboardMutex);
    561596        return;
    562597    }
    563     g_ctx.notifyGuest = true;
    564     RTSemMutexRelease(g_ctx.clipboardMutex);
     598    g_ctxX11.notifyVBox = true;
     599    RTSemMutexRelease(g_ctxHost.clipboardMutex);
    565600}
    566601
     
    591626    /* We grab this mutex whenever an asynchronous clipboard operation completes and while
    592627       disconnecting a client from the clipboard to stop these operations colliding. */
    593     RTSemMutexRequest(g_ctx.clipboardMutex, RT_INDEFINITE_WAIT);
    594     if (reinterpret_cast<VBOXCLIPBOARDCLIENTDATA *>(pClientData) != g_ctx.pClient)
     628    RTSemMutexRequest(g_ctxHost.clipboardMutex, RT_INDEFINITE_WAIT);
     629    if (reinterpret_cast<VBOXCLIPBOARDCLIENTDATA *>(pClientData) != g_ctxHost.pClient)
    595630    {
    596631        /* If the client is no longer connected, just return. */
    597632        LogFlowFunc(("client is no longer connected, returning\n"));
    598         RTSemMutexRelease(g_ctx.clipboardMutex);
     633        RTSemMutexRelease(g_ctxHost.clipboardMutex);
    599634        return;
    600635    }
     
    602637    for (unsigned i = 0; i < cAtoms; ++i)
    603638    {
    604         for (unsigned j = 0; j != g_ctx.formatList.size(); ++j)
    605             if (g_ctx.formatList[j].atom == atomTargets[i])
     639        for (unsigned j = 0; j != g_ctxX11.formatList.size(); ++j)
     640            if (g_ctxX11.formatList[j].atom == atomTargets[i])
    606641            {
    607                 if (eBestTarget < g_ctx.formatList[j].format)
     642                if (eBestTarget < g_ctxX11.formatList[j].format)
    608643                {
    609                     eBestTarget = g_ctx.formatList[j].format;
    610                     atomBestTarget = g_ctx.formatList[j].atom;
     644                    eBestTarget = g_ctxX11.formatList[j].format;
     645                    atomBestTarget = g_ctxX11.formatList[j].atom;
    611646                }
    612647                break;
     
    614649        if (g_debugClipboard)
    615650        {
    616             char *szAtomName = XGetAtomName(XtDisplay(g_ctx.widget), atomTargets[i]);
     651            char *szAtomName = XGetAtomName(XtDisplay(g_ctxX11.widget), atomTargets[i]);
    617652            if (szAtomName != 0)
    618653            {
     
    623658        }
    624659    }
    625     g_ctx.atomHostTextFormat = atomBestTarget;
    626     if ((eBestTarget != g_ctx.hostTextFormat) || (g_ctx.notifyGuest == true))
     660    g_ctxX11.atomX11TextFormat = atomBestTarget;
     661    if ((eBestTarget != g_ctxX11.X11TextFormat) || (g_ctxX11.notifyVBox == true))
    627662    {
    628663        uint32_t u32Formats = 0;
     
    631666            if (atomBestTarget != None)
    632667            {
    633                 char *szAtomName = XGetAtomName(XtDisplay(g_ctx.widget), atomBestTarget);
     668                char *szAtomName = XGetAtomName(XtDisplay(g_ctxX11.widget), atomBestTarget);
    634669                Log2 (("%s: switching to host text target %s.  Available targets are:\n",
    635670                       __PRETTY_FUNCTION__, szAtomName));
     
    641676            for (unsigned i = 0; i < cAtoms; ++i)
    642677            {
    643                 char *szAtomName = XGetAtomName(XtDisplay(g_ctx.widget), atomTargets[i]);
     678                char *szAtomName = XGetAtomName(XtDisplay(g_ctxX11.widget), atomTargets[i]);
    644679                if (szAtomName != 0)
    645680                {
     
    649684            }
    650685        }
    651         g_ctx.hostTextFormat = eBestTarget;
     686        g_ctxX11.X11TextFormat = eBestTarget;
    652687        if (eBestTarget != INVALID)
    653688            u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
    654         vboxSvcClipboardReportMsg (g_ctx.pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS,
     689        vboxSvcClipboardReportMsg (g_ctxHost.pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS,
    655690                                   u32Formats);
    656         g_ctx.notifyGuest = false;
     691        g_ctxX11.notifyVBox = false;
    657692    }
    658693    XtFree(reinterpret_cast<char *>(pValue));
    659     RTSemMutexRelease(g_ctx.clipboardMutex);
     694    RTSemMutexRelease(g_ctxHost.clipboardMutex);
    660695}
    661696
     
    670705    Log3 (("%s: called\n", __PRETTY_FUNCTION__));
    671706    /* Get the current clipboard contents */
    672     if (g_ctx.eOwner == X11 && g_ctx.pClient != 0)
     707    if (g_ctxX11.eOwner == X11 && g_ctxHost.pClient != 0)
    673708    {
    674709        Log3 (("%s: requesting the targets that the host clipboard offers\n",
    675710               __PRETTY_FUNCTION__));
    676         XtGetSelectionValue(g_ctx.widget, g_ctx.atomClipboard, g_ctx.atomTargets,
    677                             vboxClipboardGetTargetsFromX11, reinterpret_cast<XtPointer>(g_ctx.pClient),
     711        XtGetSelectionValue(g_ctxX11.widget, g_ctxX11.atomClipboard, g_ctxX11.atomTargets,
     712                            vboxClipboardGetTargetsFromX11, reinterpret_cast<XtPointer>(g_ctxHost.pClient),
    678713                            CurrentTime);
    679714    }
    680715    /* Re-arm our timer */
    681     XtAppAddTimeOut(g_ctx.appContext, 200 /* ms */, vboxClipboardPollX11ForTargets, 0);
     716    XtAppAddTimeOut(g_ctxX11.appContext, 200 /* ms */, vboxClipboardPollX11ForTargets, 0);
    682717}
    683718
     
    689724    VBOXCLIPBOARDFORMAT sFormat;
    690725    /* Get an atom from the X server for that target format */
    691     Atom atomFormat = XInternAtom(XtDisplay(g_ctx.widget), pszName, false);
     726    Atom atomFormat = XInternAtom(XtDisplay(g_ctxX11.widget), pszName, false);
    692727    sFormat.atom   = atomFormat;
    693728    sFormat.format = eFormat;
    694729    sFormat.guestFormat = guestFormat;
    695     g_ctx.formatList.push_back(sFormat);
     730    g_ctxX11.formatList.push_back(sFormat);
    696731    LogFlow (("vboxClipboardAddFormat: added format %s (%d)\n", pszName, eFormat));
    697732}
     
    706741
    707742    /* Set up a timer to poll the host clipboard */
    708     XtAppAddTimeOut(g_ctx.appContext, 200 /* ms */, vboxClipboardPollX11ForTargets, 0);
    709 
    710     XtAppMainLoop(g_ctx.appContext);
    711     g_ctx.formatList.clear();
     743    XtAppAddTimeOut(g_ctxX11.appContext, 200 /* ms */, vboxClipboardPollX11ForTargets, 0);
     744
     745    XtAppMainLoop(g_ctxX11.appContext);
     746    g_ctxX11.formatList.clear();
    712747    LogRel(("Shared clipboard: host clipboard thread terminated successfully\n"));
    713748    return VINF_SUCCESS;
     
    730765       can't get an X11 display. */
    731766    XtToolkitInitialize();
    732     g_ctx.appContext = XtCreateApplicationContext();
    733     // XtAppSetFallbackResources(g_ctx.appContext, szFallbackResources);
    734     pDisplay = XtOpenDisplay(g_ctx.appContext, 0, 0, "VBoxClipboard", 0, 0, &cArgc, &pcArgv);
     767    g_ctxX11.appContext = XtCreateApplicationContext();
     768    // XtAppSetFallbackResources(g_ctxX11.appContext, szFallbackResources);
     769    pDisplay = XtOpenDisplay(g_ctxX11.appContext, 0, 0, "VBoxClipboard", 0, 0, &cArgc, &pcArgv);
    735770    if (NULL == pDisplay)
    736771    {
     
    740775    if (RT_SUCCESS(rc))
    741776    {
    742         g_ctx.widget = XtVaAppCreateShell(0, "VBoxClipboard", applicationShellWidgetClass, pDisplay,
     777        g_ctxX11.widget = XtVaAppCreateShell(0, "VBoxClipboard", applicationShellWidgetClass, pDisplay,
    743778                                          XtNwidth, 1, XtNheight, 1, NULL);
    744         if (NULL == g_ctx.widget)
     779        if (NULL == g_ctxX11.widget)
    745780        {
    746781            LogRel(("Shared clipboard: failed to construct the X11 window for the host clipboard manager.\n"));
     
    750785    if (RT_SUCCESS(rc))
    751786    {
    752         XtSetMappedWhenManaged(g_ctx.widget, false);
    753         XtRealizeWidget(g_ctx.widget);
     787        XtSetMappedWhenManaged(g_ctxX11.widget, false);
     788        XtRealizeWidget(g_ctxX11.widget);
    754789
    755790        /* Get hold of the atoms which we need */
    756         g_ctx.atomClipboard = XInternAtom(XtDisplay(g_ctx.widget), "CLIPBOARD", false /* only_if_exists */);
    757         g_ctx.atomPrimary   = XInternAtom(XtDisplay(g_ctx.widget), "PRIMARY",   false);
    758         g_ctx.atomTargets   = XInternAtom(XtDisplay(g_ctx.widget), "TARGETS",   false);
    759         g_ctx.atomMultiple  = XInternAtom(XtDisplay(g_ctx.widget), "MULTIPLE",  false);
    760         g_ctx.atomTimestamp = XInternAtom(XtDisplay(g_ctx.widget), "TIMESTAMP", false);
    761         g_ctx.atomUtf16     = XInternAtom(XtDisplay(g_ctx.widget),
     791        g_ctxX11.atomClipboard = XInternAtom(XtDisplay(g_ctxX11.widget), "CLIPBOARD", false /* only_if_exists */);
     792        g_ctxX11.atomPrimary   = XInternAtom(XtDisplay(g_ctxX11.widget), "PRIMARY",   false);
     793        g_ctxX11.atomTargets   = XInternAtom(XtDisplay(g_ctxX11.widget), "TARGETS",   false);
     794        g_ctxX11.atomMultiple  = XInternAtom(XtDisplay(g_ctxX11.widget), "MULTIPLE",  false);
     795        g_ctxX11.atomTimestamp = XInternAtom(XtDisplay(g_ctxX11.widget), "TIMESTAMP", false);
     796        g_ctxX11.atomUtf16     = XInternAtom(XtDisplay(g_ctxX11.widget),
    762797                                          "text/plain;charset=ISO-10646-UCS-2", false);
    763         g_ctx.atomUtf8      = XInternAtom(XtDisplay(g_ctx.widget), "UTF_STRING", false);
     798        g_ctxX11.atomUtf8      = XInternAtom(XtDisplay(g_ctxX11.widget), "UTF_STRING", false);
    764799        /* And build up the vector of supported formats */
    765         g_ctx.atomCText     = XInternAtom(XtDisplay(g_ctx.widget), "COMPOUND_TEXT", false);
     800        g_ctxX11.atomCText     = XInternAtom(XtDisplay(g_ctxX11.widget), "COMPOUND_TEXT", false);
    766801        /* And build up the vector of supported formats */
    767802        if (!g_testUtf8 && !g_testCText)
     
    835870
    836871    LogRel(("Initializing host clipboard service\n"));
    837     RTSemEventCreate(&g_ctx.waitForData);
    838     RTSemMutexCreate(&g_ctx.clipboardMutex);
     872    RTSemEventCreate(&g_ctxHost.waitForData);
     873    RTSemEventCreate(&g_ctxX11.waitForData);
     874    RTSemMutexCreate(&g_ctxHost.clipboardMutex);
    839875    rc = vboxClipboardInitX11();
    840876    if (RT_SUCCESS(rc))
    841877    {
    842         rc = RTThreadCreate(&g_ctx.thread, vboxClipboardThread, 0, 0,
     878        rc = RTThreadCreate(&g_ctxX11.thread, vboxClipboardThread, 0, 0,
    843879                            RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
    844880        if (RT_FAILURE(rc))
     
    847883    if (RT_FAILURE(rc))
    848884    {
    849         RTSemEventDestroy(g_ctx.waitForData);
    850         RTSemMutexDestroy(g_ctx.clipboardMutex);
     885        RTSemEventDestroy(g_ctxHost.waitForData);
     886        RTSemEventDestroy(g_ctxX11.waitForData);
     887        RTSemMutexDestroy(g_ctxHost.clipboardMutex);
    851888    }
    852889    return rc;
     
    875912     * cause any outstanding clipboard data requests from X11 to fail
    876913     * immediately. */
    877     g_ctx.pClient = NULL;
    878     if (g_ctx.eOwner == VB)
     914    g_ctxHost.pClient = NULL;
     915    if (g_ctxX11.eOwner == VB)
    879916        /* X11 may be waiting for data from VBox.  At this point it is no
    880917         * longer going to arrive, and we must release it to allow the event
     
    883920         * return "no data" to X11.  Any subsequent attempts to get the data
    884921         * from VBox will fail immediately as the client reference is gone. */
    885         RTSemEventSignal(g_ctx.waitForData);
     922        RTSemEventSignal(g_ctxHost.waitForData);
    886923    /* Set the termination flag.  This has been observed to block if it was set
    887924     * during a request for clipboard data coming from X11, so only we do it
    888925     * after releasing any such requests. */
    889     XtAppSetExitFlag(g_ctx.appContext);
     926    XtAppSetExitFlag(g_ctxX11.appContext);
    890927    /* Wake up the event loop */
    891928    memset(&ev, 0, sizeof(ev));
    892929    ev.xclient.type = ClientMessage;
    893930    ev.xclient.format = 8;
    894     XSendEvent(XtDisplay(g_ctx.widget), XtWindow(g_ctx.widget), false, 0, &ev);
    895     XFlush(XtDisplay(g_ctx.widget));
     931    XSendEvent(XtDisplay(g_ctxX11.widget), XtWindow(g_ctxX11.widget), false, 0, &ev);
     932    XFlush(XtDisplay(g_ctxX11.widget));
    896933    do
    897934    {
    898         rc = RTThreadWait(g_ctx.thread, 1000, &rcThread);
     935        rc = RTThreadWait(g_ctxX11.thread, 1000, &rcThread);
    899936        ++count;
    900937        Assert(RT_SUCCESS(rc) || ((VERR_TIMEOUT == rc) && (count != 5)));
     
    910947         *      successfully.
    911948         */
    912         RTSemEventDestroy(g_ctx.waitForData);
    913         RTSemMutexDestroy(g_ctx.clipboardMutex);
     949        RTSemEventDestroy(g_ctxHost.waitForData);
     950        RTSemEventDestroy(g_ctxX11.waitForData);
     951        RTSemMutexDestroy(g_ctxHost.clipboardMutex);
    914952        AssertRC(rcThread);
    915953    }
    916954    else
    917955        LogRel(("vboxClipboardDestroy: rc=%Rrc\n", rc));
    918     XtCloseDisplay(XtDisplay(g_ctx.widget));
     956    XtCloseDisplay(XtDisplay(g_ctxX11.widget));
    919957    LogFlowFunc(("returning.\n"));
    920958}
     
    939977
    940978    /* Only one client is supported for now */
    941     AssertLogRelReturn(g_ctx.pClient == 0, VERR_NOT_SUPPORTED);
    942 
    943     pClient->pCtx = &g_ctx;
     979    AssertLogRelReturn(g_ctxHost.pClient == 0, VERR_NOT_SUPPORTED);
     980
     981    pClient->pCtx = &g_ctxHost;
    944982    pClient->pCtx->pClient = pClient;
    945     g_ctx.eOwner = X11;
    946     g_ctx.notifyGuest = true;
     983    g_ctxX11.eOwner = X11;
     984    g_ctxX11.notifyVBox = true;
    947985    return VINF_SUCCESS;
    948986}
     
    9661004       of synchronising, we tell the guest to empty its clipboard, and we set the cached
    9671005       flag so that we report formats to the guest next time we poll for them. */
    968     vboxSvcClipboardReportMsg (g_ctx.pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, 0);
    969     g_ctx.notifyGuest = true;
     1006    vboxSvcClipboardReportMsg (g_ctxHost.pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, 0);
     1007    g_ctxX11.notifyVBox = true;
    9701008
    9711009    return VINF_SUCCESS;
     
    9871025    LogFlow(("vboxClipboardDisconnect\n"));
    9881026
    989     RTSemMutexRequest(g_ctx.clipboardMutex, RT_INDEFINITE_WAIT);
    990     g_ctx.pClient = NULL;
    991     g_ctx.eOwner = NONE;
    992     g_ctx.hostTextFormat = INVALID;
    993     g_ctx.hostBitmapFormat = INVALID;
    994     RTSemMutexRelease(g_ctx.clipboardMutex);
     1027    RTSemMutexRequest(g_ctxHost.clipboardMutex, RT_INDEFINITE_WAIT);
     1028    g_ctxHost.pClient = NULL;
     1029    g_ctxX11.eOwner = NONE;
     1030    g_ctxX11.X11TextFormat = INVALID;
     1031    g_ctxX11.X11BitmapFormat = INVALID;
     1032    RTSemMutexRelease(g_ctxHost.clipboardMutex);
    9951033}
    9961034
     
    10111049                                                 unsigned long *pcLenReturn, int *piFormatReturn)
    10121050{
    1013     unsigned uListSize = g_ctx.formatList.size();
     1051    unsigned uListSize = g_ctxX11.formatList.size();
    10141052    Atom *atomTargets = reinterpret_cast<Atom *>(XtMalloc((uListSize + 3) * sizeof(Atom)));
    10151053    unsigned cTargets = 0;
     
    10181056    for (unsigned i = 0; i < uListSize; ++i)
    10191057    {
    1020         if (   ((g_ctx.guestFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) != 0)
    1021             && (g_ctx.formatList[i].guestFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT))
     1058        if (   ((g_ctxX11.vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT) != 0)
     1059            && (g_ctxX11.formatList[i].guestFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT))
    10221060        {
    1023             atomTargets[cTargets] = g_ctx.formatList[i].atom;
     1061            atomTargets[cTargets] = g_ctxX11.formatList[i].atom;
    10241062            ++cTargets;
    10251063        }
    10261064    }
    1027     atomTargets[cTargets] = g_ctx.atomTargets;
    1028     atomTargets[cTargets + 1] = g_ctx.atomMultiple;
    1029     atomTargets[cTargets + 2] = g_ctx.atomTimestamp;
     1065    atomTargets[cTargets] = g_ctxX11.atomTargets;
     1066    atomTargets[cTargets + 1] = g_ctxX11.atomMultiple;
     1067    atomTargets[cTargets + 2] = g_ctxX11.atomTimestamp;
    10301068    if (g_debugClipboard)
    10311069    {
    10321070        for (unsigned i = 0; i < cTargets + 3; i++)
    10331071        {
    1034             char *szAtomName = XGetAtomName(XtDisplay(g_ctx.widget), atomTargets[i]);
     1072            char *szAtomName = XGetAtomName(XtDisplay(g_ctxX11.widget), atomTargets[i]);
    10351073            if (szAtomName != 0)
    10361074            {
     
    10541092
    10551093/**
    1056  * Satisfy a request from VBox to convert the clipboard text to Utf16.  We return non-zero
     1094 * Satisfy a request from X11 to convert the clipboard text to Utf16.  We return non-zero
    10571095 * terminated text.
    10581096 *
     
    10751113
    10761114    LogFlowFunc (("called\n"));
    1077     rc = vboxClipboardReadDataFromVBox(&g_ctx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pvVBox, &cbVBox);
     1115    rc = vboxClipboardReadDataFromVBox(&g_ctxHost, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pvVBox, &cbVBox);
    10781116    if ((RT_FAILURE(rc)) || (cbVBox == 0))
    10791117    {
     
    11181156    LogFlowFunc (("converted string is %.*ls. Returning.\n", cwDestLen, pu16DestText));
    11191157    RTMemFree(pvVBox);
    1120     *atomTypeReturn = g_ctx.atomUtf16;
     1158    *atomTypeReturn = g_ctxX11.atomUtf16;
    11211159    *pValReturn = reinterpret_cast<XtPointer>(pu16DestText);
    11221160    *pcLenReturn = cwDestLen;
     
    11261164
    11271165/**
    1128  * Satisfy a request from the host to convert the clipboard text to Utf8.
     1166 * Satisfy a request from X11 to convert the clipboard text to Utf8.
    11291167 *
    11301168 * @returns true if we successfully convert the data to the format requested, false otherwise.
     
    11521190    LogFlowFunc (("called\n"));
    11531191    /* Read the clipboard data from the guest. */
    1154     rc = vboxClipboardReadDataFromVBox(&g_ctx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pvVBox, &cbVBox);
     1192    rc = vboxClipboardReadDataFromVBox(&g_ctxHost, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pvVBox, &cbVBox);
    11551193    if ((rc != VINF_SUCCESS) || (cbVBox == 0))
    11561194    {
     
    12161254    LogFlowFunc (("converted string is %.*s. Returning.\n", cbDestLen, pu8DestText));
    12171255    RTMemFree(pvVBox);
    1218     *atomTypeReturn = g_ctx.atomUtf8;
     1256    *atomTypeReturn = g_ctxX11.atomUtf8;
    12191257    *pValReturn = reinterpret_cast<XtPointer>(pu8DestText);
    12201258    *pcLenReturn = cbDestLen;
     
    12241262
    12251263/**
    1226  * Satisfy a request from the host to convert the clipboard text to COMPOUND_TEXT.
     1264 * Satisfy a request from X11 to convert the clipboard text to COMPOUND_TEXT.
    12271265 *
    12281266 * @returns true if we successfully convert the data to the format requested, false otherwise.
     
    12511289    LogFlowFunc (("called\n"));
    12521290    /* Read the clipboard data from the guest. */
    1253     rc = vboxClipboardReadDataFromVBox(&g_ctx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pvVBox, &cbVBox);
     1291    rc = vboxClipboardReadDataFromVBox(&g_ctxHost, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pvVBox, &cbVBox);
    12541292    if ((rc != VINF_SUCCESS) || (cbVBox == 0))
    12551293    {
     
    13031341    /* And finally (!) convert the Utf8 text to compound text. */
    13041342#ifdef RT_OS_SOLARIS
    1305     rc = XmbTextListToTextProperty(XtDisplay(g_ctx.widget), &pu8DestText, 1,
     1343    rc = XmbTextListToTextProperty(XtDisplay(g_ctxX11.widget), &pu8DestText, 1,
    13061344                                     XCompoundTextStyle, &property);
    13071345#else
    1308     rc = Xutf8TextListToTextProperty(XtDisplay(g_ctx.widget), &pu8DestText, 1,
     1346    rc = Xutf8TextListToTextProperty(XtDisplay(g_ctxX11.widget), &pu8DestText, 1,
    13091347                                     XCompoundTextStyle, &property);
    13101348#endif
     
    13581396    LogFlowFunc(("\n"));
    13591397    /* Drop requests that we receive too late. */
    1360     if (g_ctx.eOwner != VB)
    1361         return false;
    1362     if (   (*atomSelection != g_ctx.atomClipboard)
    1363         && (*atomSelection != g_ctx.atomPrimary)
     1398    if (g_ctxX11.eOwner != VB)
     1399        return false;
     1400    if (   (*atomSelection != g_ctxX11.atomClipboard)
     1401        && (*atomSelection != g_ctxX11.atomPrimary)
    13641402       )
    13651403    {
     
    13691407    if (g_debugClipboard)
    13701408    {
    1371         char *szAtomName = XGetAtomName(XtDisplay(g_ctx.widget), *atomTarget);
     1409        char *szAtomName = XGetAtomName(XtDisplay(g_ctxX11.widget), *atomTarget);
    13721410        if (szAtomName != 0)
    13731411        {
     
    13801418        }
    13811419    }
    1382     if (*atomTarget == g_ctx.atomTargets)
     1420    if (*atomTarget == g_ctxX11.atomTargets)
    13831421    {
    13841422        eFormat = TARGETS;
     
    13861424    else
    13871425    {
    1388         for (unsigned i = 0; i != g_ctx.formatList.size(); ++i)
     1426        for (unsigned i = 0; i != g_ctxX11.formatList.size(); ++i)
    13891427        {
    1390             if (g_ctx.formatList[i].atom == *atomTarget)
     1428            if (g_ctxX11.formatList[i].atom == *atomTarget)
    13911429            {
    1392                 eFormat = g_ctx.formatList[i].format;
     1430                eFormat = g_ctxX11.formatList[i].format;
    13931431                break;
    13941432            }
     
    14241462{
    14251463    LogFlowFunc (("called, giving VBox clipboard ownership\n"));
    1426     g_ctx.eOwner = X11;
    1427     g_ctx.notifyGuest = true;
     1464    g_ctxX11.eOwner = X11;
     1465    g_ctxX11.notifyVBox = true;
    14281466}
    14291467
     
    14441482        return;
    14451483
    1446     pClient->pCtx->guestFormats = u32Formats;
     1484    g_ctxX11.vboxFormats = u32Formats;
    14471485    LogFlowFunc (("u32Formats=%d\n", u32Formats));
    14481486    if (u32Formats == 0)
     
    14521490        return;
    14531491    }
    1454     if (g_ctx.eOwner == VB)
     1492    if (g_ctxX11.eOwner == VB)
    14551493    {
    14561494        /* We already own the clipboard, so no need to grab it, especially as that can lead
     
    14611499    }
    14621500    Log2 (("%s: giving the guest clipboard ownership\n", __PRETTY_FUNCTION__));
    1463     g_ctx.eOwner = VB;
    1464     g_ctx.hostTextFormat = INVALID;
    1465     g_ctx.hostBitmapFormat = INVALID;
    1466     if (XtOwnSelection(g_ctx.widget, g_ctx.atomClipboard, CurrentTime, vboxClipboardConvertForX11,
     1501    g_ctxX11.eOwner = VB;
     1502    g_ctxX11.X11TextFormat = INVALID;
     1503    g_ctxX11.X11BitmapFormat = INVALID;
     1504    if (XtOwnSelection(g_ctxX11.widget, g_ctxX11.atomClipboard, CurrentTime, vboxClipboardConvertForX11,
    14671505                       vboxClipboardReturnToX11, 0) != True)
    14681506    {
     
    14701508        /* We set this so that the guest gets notified when we take the clipboard, even if no
    14711509          guest formats are found which we understand. */
    1472         g_ctx.notifyGuest = true;
    1473         g_ctx.eOwner = X11;
    1474     }
    1475     XtOwnSelection(g_ctx.widget, g_ctx.atomPrimary, CurrentTime, vboxClipboardConvertForX11,
     1510        g_ctxX11.notifyVBox = true;
     1511        g_ctxX11.eOwner = X11;
     1512    }
     1513    XtOwnSelection(g_ctxX11.widget, g_ctxX11.atomPrimary, CurrentTime, vboxClipboardConvertForX11,
    14761514                   NULL, 0);
    14771515    LogFlowFunc(("returning\n"));
     
    15101548    if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    15111549    {
    1512         if (g_ctx.hostTextFormat == INVALID)
     1550        if (g_ctxX11.X11TextFormat == INVALID)
    15131551        {
    15141552            /* No data available. */
     
    15191557         * requests from VBox are serialised and the second because X11 previously
    15201558         * grabbed the clipboard, so it should not be waiting for data from us. */
    1521         AssertLogRelReturn (ASMAtomicCmpXchgU32(&g_ctx.waiter, VB, NONE), VERR_DEADLOCK);
    1522         g_ctx.requestHostFormat = g_ctx.hostTextFormat;
    1523         g_ctx.requestBuffer = pv;
    1524         g_ctx.requestBufferSize = cb;
    1525         g_ctx.requestActualSize = pcbActual;
     1559        AssertLogRelReturn (ASMAtomicCmpXchgU32(&g_ctxHost.waiter, VB, NONE), VERR_DEADLOCK);
     1560        g_ctxHost.requestX11Format = g_ctxX11.X11TextFormat;
     1561        g_ctxHost.requestBuffer = pv;
     1562        g_ctxHost.requestBufferSize = cb;
     1563        g_ctxHost.requestActualSize = pcbActual;
    15261564        /* Initially set the size of the data read to zero in case we fail
    15271565         * somewhere. */
    15281566        *pcbActual = 0;
    15291567        /* Send out a request for the data to the current clipboard owner */
    1530         XtGetSelectionValue(g_ctx.widget, g_ctx.atomClipboard, g_ctx.atomHostTextFormat,
    1531                             vboxClipboardGetDataFromX11, reinterpret_cast<XtPointer>(g_ctx.pClient),
     1568        XtGetSelectionValue(g_ctxX11.widget, g_ctxX11.atomClipboard, g_ctxX11.atomX11TextFormat,
     1569                            vboxClipboardGetDataFromX11, reinterpret_cast<XtPointer>(g_ctxHost.pClient),
    15321570                            CurrentTime);
    15331571        /* When the data arrives, the vboxClipboardGetDataFromX11 callback will be called.  The
    15341572           callback will signal the event semaphore when it has processed the data for us. */
    15351573
    1536         int rc = RTSemEventWait(g_ctx.waitForData, RT_INDEFINITE_WAIT);
     1574        int rc = RTSemEventWait(g_ctxX11.waitForData, RT_INDEFINITE_WAIT);
    15371575        if (RT_FAILURE(rc))
    15381576        {
    1539             g_ctx.waiter = NONE;
     1577            g_ctxHost.waiter = NONE;
    15401578            return rc;
    15411579        }
    1542         g_ctx.waiter = NONE;
     1580        g_ctxHost.waiter = NONE;
    15431581    }
    15441582    else
     
    15741612    /* Grab the mutex and check that X11 is still waiting for the data before
    15751613     * delivering it.  See the explanation in vboxClipboardReadDataFromVBox. */
    1576     RTSemMutexRequest(g_ctx.clipboardMutex, RT_INDEFINITE_WAIT);
    1577     if (g_ctx.waiter == X11 && cb > 0)
     1614    RTSemMutexRequest(g_ctxHost.clipboardMutex, RT_INDEFINITE_WAIT);
     1615    if (g_ctxHost.waiter == X11 && cb > 0)
    15781616    {
    15791617        pClient->data.pv = RTMemAlloc (cb);
     
    15861624        }
    15871625    }
    1588     RTSemMutexRelease(g_ctx.clipboardMutex);
    1589 
    1590     RTSemEventSignal(g_ctx.waitForData);
    1591 }
    1592 
     1626    RTSemMutexRelease(g_ctxHost.clipboardMutex);
     1627
     1628    RTSemEventSignal(g_ctxHost.waitForData);
     1629}
     1630
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