VirtualBox

Ignore:
Timestamp:
Jun 4, 2013 1:48:19 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
86203
Message:

GuestHost/SharedClipboard: more X11 unit test clean-up.

File:
1 edited

Legend:

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

    r46335 r46383  
    138138 * @param   widget a valid Xt widget
    139139 */
    140 static CLIPX11FORMAT clipFindX11FormatByAtomText(CLIPBACKEND *pCtx, const char *pcsz)
     140static CLIPX11FORMAT clipFindX11FormatByAtomText(const char *pcsz)
    141141{
    142142    for (unsigned i = 0; i < RT_ELEMENTS(g_aFormats); ++i)
     
    291291}
    292292
    293 static void clipQueueToEventThread(CLIPBACKEND *pCtx,
    294                                    XtTimerCallbackProc proc,
    295                                    XtPointer client_data);
     293#ifdef TESTCASE
     294static void testQueueToEventThread(void (*proc)(void *, void *),
     295                                   void *client_data);
     296#endif
    296297
    297298/** String written to the wakeup pipe. */
     
    300301#define WAKE_UP_STRING_LEN  ( sizeof(WAKE_UP_STRING) - 1 )
    301302
    302 #ifndef TESTCASE
    303303/** Schedule a function call to run on the Xt event thread by passing it to
    304304 * the application context as a 0ms timeout and waking up the event loop by
    305305 * writing to the wakeup pipe which it monitors. */
    306306void clipQueueToEventThread(CLIPBACKEND *pCtx,
    307                             XtTimerCallbackProc proc,
    308                             XtPointer client_data)
     307                            void (*proc)(void *, void *),
     308                            void *client_data)
    309309{
    310310    LogRel2(("clipQueueToEventThread: proc=%p, client_data=%p\n",
    311311             proc, client_data));
    312     XtAppAddTimeOut(pCtx->appContext, 0, proc, client_data);
     312#ifndef TESTCASE
     313    XtAppAddTimeOut(pCtx->appContext, 0, (XtTimerCallbackProc)proc,
     314                    (XtPointer)client_data);
    313315    write(pCtx->wakeupPipeWrite, WAKE_UP_STRING, WAKE_UP_STRING_LEN);
    314 }
     316#else
     317    testQueueToEventThread(proc, client_data);
    315318#endif
     319}
    316320
    317321/**
     
    380384    CLIPX11FORMAT targets[2];
    381385    CLIPX11FORMAT x11Format;
    382     targets[0] = clipFindX11FormatByAtomText(pCtx, "text/plain");
    383     targets[1] = clipFindX11FormatByAtomText(pCtx, "image/bmp");
     386    targets[0] = clipFindX11FormatByAtomText("text/plain");
     387    targets[1] = clipFindX11FormatByAtomText("image/bmp");
    384388    x11Format = clipGetTextFormatFromTargets(pCtx, targets, 2);
    385389    if (clipRealFormatForX11Format(x11Format) != TEXT)
    386390        success = false;
    387     targets[0] = clipFindX11FormatByAtomText(pCtx, "UTF8_STRING");
    388     targets[1] = clipFindX11FormatByAtomText(pCtx, "text/plain");
     391    targets[0] = clipFindX11FormatByAtomText("UTF8_STRING");
     392    targets[1] = clipFindX11FormatByAtomText("text/plain");
    389393    x11Format = clipGetTextFormatFromTargets(pCtx, targets, 2);
    390394    if (clipRealFormatForX11Format(x11Format) != UTF8)
     
    455459}
    456460
     461static void clipQueryX11CBFormats(CLIPBACKEND *pCtx);
     462
    457463/**
    458464 * Update the context's information about targets currently supported by X11,
     
    465471                                 size_t cTargets)
    466472{
    467     LogRel2 (("%s: called\n", __PRETTY_FUNCTION__));
     473    LogRel2 (("%s: called\n", __FUNCTION__));
     474    pCtx->fBusy = false;
     475    if (pCtx->fUpdateNeeded)
     476    {
     477        /* We may already be out of date. */
     478        pCtx->fUpdateNeeded = false;
     479        clipQueryX11CBFormats(pCtx);
     480        return;
     481    }
     482    if (pTargets == NULL) {
     483        /* No data available */
     484        clipReportEmptyX11CB(pCtx);
     485        return;
     486    }
    468487    clipGetFormatsFromTargets(pCtx, pTargets, cTargets);
    469488    clipReportFormatsToVBox(pCtx);
    470489}
    471490
    472 static void clipQueryX11CBFormats(CLIPBACKEND *pCtx);
    473 
    474491/**
    475492 * Notify the VBox clipboard about available data formats, based on the
    476493 * "targets" information obtained from the X11 clipboard.
    477  * @note  callback for XtGetSelectionValue
     494 * @note  Callback for XtGetSelectionValue
     495 * @note  This function is treated as API glue, and as such is not part of any
     496 *        unit test.  So keep it simple, be paranoid and log everything.
    478497 */
    479498static void clipConvertX11Targets(Widget widget, XtPointer pClientData,
     
    484503    CLIPBACKEND *pCtx =
    485504            reinterpret_cast<CLIPBACKEND *>(pClientData);
    486     LogRel2(("clipConvertX11Targets: pValue=%p, *pcLen=%u, *atomType=%d, XT_CONVERT_FAIL=%d\n",
    487              pValue, *pcLen, *atomType, XT_CONVERT_FAIL));
     505    Atom *pAtoms = (Atom *)pValue;
     506    unsigned i, j;
     507    LogRel2(("%s: pValue=%p, *pcLen=%u, *atomType=%d%s\n", __FUNCTION__,
     508             pValue, *pcLen, *atomType,
     509             *atomType == XT_CONVERT_FAIL ? " (XT_CONVERT_FAIL)" : ""));
    488510    CLIPX11FORMAT *pFormats = NULL;
    489     if (*pcLen)
    490     {
     511    if (*pcLen && pValue && (*atomType != XT_CONVERT_FAIL /* time out */))
    491512        pFormats = (CLIPX11FORMAT *)RTMemAllocZ(*pcLen * sizeof(CLIPX11FORMAT));
    492         if (!pFormats)
    493         {
    494             XtFree((char *)pValue);
    495             return;
    496         }
    497     }
     513#if defined(DEBUG) && !defined(TESTCASE)
    498514    if (pValue)
    499     {
    500         Atom *pAtoms = (Atom *)pValue;
    501         unsigned i, j;
    502 #if defined(DEBUG) && !defined(TESTCASE)
    503515        for (i = 0; i < *pcLen; ++i)
    504516            if (pAtoms[i])
    505517            {
    506518                char *pszName = XGetAtomName(XtDisplay(widget), pAtoms[i]);
    507                 LogRel2(("%s: found target %s\n", __PRETTY_FUNCTION__,
     519                LogRel2(("%s: found target %s\n", __FUNCTION__,
    508520                         pszName));
    509521                XFree(pszName);
    510522            }
     523            else
     524                LogRel2(("%s: found empty target.\n", __FUNCTION__));
    511525#endif
     526    if (pFormats)
     527    {
    512528        for (i = 0; i < *pcLen; ++i)
     529        {
    513530            for (j = 0; j < RT_ELEMENTS(g_aFormats); ++j)
    514531            {
     
    518535                    pFormats[i] = j;
    519536            }
    520     }
    521     pCtx->fBusy = false;
    522     if (pCtx->fUpdateNeeded)
    523     {
    524         /* We may already be out of date. */
    525         pCtx->fUpdateNeeded = false;
    526         clipQueryX11CBFormats(pCtx);
     537#if defined(DEBUG) && !defined(TESTCASE)
     538            LogRel2(("%s: reporting format %d (%s)\n", __FUNCTION__,
     539                     pFormats[i], g_aFormats[pFormats[i]].pcszAtom));
     540#endif
     541        }
    527542    }
    528543    else
    529     {
    530         if (   (*atomType == XT_CONVERT_FAIL)  /* timeout */
    531                || (pValue == NULL))               /* No data available */
    532         {
    533             clipReportEmptyX11CB(pCtx);
    534             RTMemFree(pFormats);
    535             return;
    536         }
    537         clipUpdateX11Targets(pCtx, pFormats, *pcLen);
    538     }
     544        LogRel2(("%s: reporting empty targets (none reported or allocation failure).\n",
     545                 __FUNCTION__));
     546    clipUpdateX11Targets(pCtx, pFormats, *pcLen);
    539547    RTMemFree(pFormats);
    540548    XtFree(reinterpret_cast<char *>(pValue));
    541549}
     550
     551#ifdef TESTCASE
     552    void testRequestTargets(CLIPBACKEND *pCtx);
     553#endif
    542554
    543555/**
     
    554566    }
    555567    pCtx->fBusy = true;
     568#ifndef TESTCASE
    556569    XtGetSelectionValue(pCtx->widget,
    557570                        clipGetAtom(pCtx, "CLIPBOARD"),
     
    559572                        clipConvertX11Targets, pCtx,
    560573                        CurrentTime);
     574#else
     575    testRequestTargets(pCtx);
     576#endif
    561577}
    562578
     
    649665/** Worker function for stopping the clipboard which runs on the event
    650666 * thread. */
    651 static void clipStopEventThreadWorker(XtPointer pUserData, XtIntervalId *)
     667static void clipStopEventThreadWorker(void *pUserData, void *)
    652668{
    653669
     
    12691285 *                   clipboard context data.  Must be freed by the worker.
    12701286 */
    1271 static void clipNewVBoxFormatsWorker(XtPointer pUserData,
    1272                                      XtIntervalId * /* interval */)
     1287static void clipNewVBoxFormatsWorker(void *pUserData,
     1288                                     void * /* interval */)
    12731289{
    12741290    CLIPNEWVBOXFORMATS *pFormats = (CLIPNEWVBOXFORMATS *)pUserData;
     
    14761492 *        the X11 clipboard contains a format we understand.
    14771493 */
    1478 static void clipConvertX11CB(Widget widget, XtPointer pClientData,
    1479                              Atom * /* selection */, Atom *atomType,
    1480                              XtPointer pvSrc, long unsigned int *pcLen,
    1481                              int *piFormat)
     1494static void clipConvertX11CB(void *pClientData, void *pvSrc, unsigned cbSrc)
    14821495{
    14831496    CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *) pClientData;
     
    14901503    int rc = VINF_SUCCESS;
    14911504    CLIPBACKEND *pCtx = pReq->mCtx;
    1492     unsigned cbSrc = (*pcLen) * (*piFormat) / 8;
    14931505    void *pvDest = NULL;
    14941506    uint32_t cbDest = 0;
     
    15001512        /* The clipboard selection may have changed before we could get it. */
    15011513        rc = VERR_NO_DATA;
    1502     else if (*atomType == XT_CONVERT_FAIL) /* Xt timeout */
    1503         rc = VERR_TIMEOUT;
    15041514    else if (pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    15051515    {
     
    15551565    else
    15561566        rc = VERR_NOT_IMPLEMENTED;
    1557     XtFree((char *)pvSrc);
    15581567    ClipCompleteDataRequestFromX11(pReq->mCtx->pFrontend, rc, pReq->mReq,
    15591568                                   pvDest, cbDest);
     
    15631572}
    15641573
     1574/**
     1575 * Convert the data obtained from the X11 clipboard to the required format,
     1576 * place it in the buffer supplied and signal that data has arrived.
     1577 * Convert the text obtained UTF-16LE with Windows EOLs.
     1578 * Convert full BMP data to DIB format.
     1579 * @note  X11 backend code, callback for XtGetSelectionValue, for use when
     1580 *        the X11 clipboard contains a format we understand.
     1581 */
     1582static void cbConvertX11CB(Widget widget, XtPointer pClientData,
     1583                           Atom * /* selection */, Atom *atomType,
     1584                           XtPointer pvSrc, long unsigned int *pcLen,
     1585                           int *piFormat)
     1586{
     1587    if (*atomType == XT_CONVERT_FAIL) /* Xt timeout */
     1588        clipConvertX11CB(pClientData, NULL, 0);
     1589    else
     1590        clipConvertX11CB(pClientData, pvSrc, (*pcLen) * (*piFormat) / 8);
     1591
     1592    XtFree((char *)pvSrc);
     1593}
     1594
     1595#ifdef TESTCASE
     1596static void testRequestData(CLIPBACKEND* pCtx, CLIPX11FORMAT target,
     1597                            void *closure);
     1598#endif
     1599
     1600static void getSelectionValue(CLIPBACKEND *pCtx, CLIPX11FORMAT format,
     1601                              CLIPREADX11CBREQ *pReq)
     1602{
     1603#ifndef TESTCASE
     1604    XtGetSelectionValue(pCtx->widget, clipGetAtom(pCtx, "CLIPBOARD"),
     1605                        clipAtomForX11Format(pCtx, format),
     1606                        cbConvertX11CB,
     1607                        reinterpret_cast<XtPointer>(pReq),
     1608                        CurrentTime);
     1609#else
     1610    testRequestData(pCtx, format, (void *)pReq);
     1611#endif
     1612}
     1613
    15651614/** Worker function for ClipRequestDataFromX11 which runs on the event
    15661615 * thread. */
    1567 static void vboxClipboardReadX11Worker(XtPointer pUserData,
    1568                                        XtIntervalId * /* interval */)
     1616static void vboxClipboardReadX11Worker(void *pUserData,
     1617                                       void * /* interval */)
    15691618{
    15701619    CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *)pUserData;
     
    15901639            /* Send out a request for the data to the current clipboard
    15911640             * owner */
    1592             XtGetSelectionValue(pCtx->widget, clipGetAtom(pCtx, "CLIPBOARD"),
    1593                                 clipAtomForX11Format(pCtx, pCtx->X11TextFormat),
    1594                                 clipConvertX11CB,
    1595                                 reinterpret_cast<XtPointer>(pReq),
    1596                                 CurrentTime);
     1641            getSelectionValue(pCtx, pCtx->X11TextFormat, pReq);
    15971642    }
    15981643    else if (pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     
    16051650            /* Send out a request for the data to the current clipboard
    16061651             * owner */
    1607             XtGetSelectionValue(pCtx->widget, clipGetAtom(pCtx, "CLIPBOARD"),
    1608                                 clipAtomForX11Format(pCtx,
    1609                                                      pCtx->X11BitmapFormat),
    1610                                 clipConvertX11CB,
    1611                                 reinterpret_cast<XtPointer>(pReq),
    1612                                 CurrentTime);
     1652            getSelectionValue(pCtx, pCtx->X11BitmapFormat, pReq);
    16131653    }
    16141654    else
     
    16771717/* For the purpose of the test case, we just execute the procedure to be
    16781718 * scheduled, as we are running single threaded. */
    1679 void clipQueueToEventThread(CLIPBACKEND *pCtx,
    1680                             XtTimerCallbackProc proc,
    1681                             XtPointer client_data)
     1719void testQueueToEventThread(void (*proc)(void *, void *),
     1720                            void *client_data)
    16821721{
    16831722    proc(client_data, NULL);
     
    18001839}
    18011840
     1841/* Take a request for the targets we are currently offering. */
     1842static CLIPX11FORMAT g_selTargets[10] = { 0 };
     1843static size_t g_cTargets = 0;
     1844
     1845void testRequestTargets(CLIPBACKEND* pCtx)
     1846{
     1847    clipUpdateX11Targets(pCtx, g_selTargets, g_cTargets);
     1848}
     1849
    18021850/* The current values of the X selection, which will be returned to the
    18031851 * XtGetSelectionValue callback. */
    1804 static Atom g_selTarget[1] = { 0 };
    18051852static Atom g_selType = 0;
    18061853static const void *g_pSelData = NULL;
    18071854static unsigned long g_cSelData = 0;
    18081855static int g_selFormat = 0;
    1809 static bool g_fTargetsTimeout = false;
    1810 static bool g_fTargetsFailure = false;
    1811 
    1812 void XtGetSelectionValue(Widget widget, Atom selection, Atom target,
    1813                          XtSelectionCallbackProc callback,
    1814                          XtPointer closure, Time time)
     1856
     1857void testRequestData(CLIPBACKEND* pCtx, CLIPX11FORMAT target, void *closure)
    18151858{
    18161859    unsigned long count = 0;
    18171860    int format = 0;
    1818     Atom type = XA_STRING;
    1819     if (   (   selection != XInternAtom(NULL, "PRIMARY", 0)
    1820             && selection != XInternAtom(NULL, "CLIPBOARD", 0)
    1821             && selection != XInternAtom(NULL, "TARGETS", 0))
    1822         || (   target != g_selTarget[0]
    1823             && target != XInternAtom(NULL, "TARGETS", 0)))
    1824     {
    1825         /* Otherwise this is probably a caller error. */
    1826         Assert(target != g_selTarget[0]);
    1827         callback(widget, closure, &selection, &type, NULL, &count, &format);
    1828                 /* Could not convert to target. */
     1861    if (target != g_selTargets[0])
     1862    {
     1863        clipConvertX11CB(closure, NULL, 0); /* Could not convert to target. */
    18291864        return;
    18301865    }
    1831     XtPointer pValue = NULL;
    1832     if (target == XInternAtom(NULL, "TARGETS", 0))
    1833     {
    1834         if (g_fTargetsFailure)
    1835             pValue = NULL;
    1836         else
    1837             pValue = (XtPointer) RTMemDup(&g_selTarget, sizeof(g_selTarget));
    1838         type = g_fTargetsTimeout ? XT_CONVERT_FAIL : XA_ATOM;
    1839         count = g_fTargetsFailure ? 0 : RT_ELEMENTS(g_selTarget);
    1840         format = 32;
    1841     }
    1842     else
    1843     {
    1844         pValue = (XtPointer) g_pSelData ? RTMemDup(g_pSelData, g_cSelData)
    1845                                         : NULL;
    1846         type = g_selType;
    1847         count = g_pSelData ? g_cSelData : 0;
    1848         format = g_selFormat;
    1849     }
     1866    void *pValue = NULL;
     1867    pValue = g_pSelData ? RTMemDup(g_pSelData, g_cSelData) : NULL;
     1868    count = g_pSelData ? g_cSelData : 0;
     1869    format = g_selFormat;
    18501870    if (!pValue)
    18511871    {
     
    18531873        format = 0;
    18541874    }
    1855     callback(widget, closure, &selection, &type, pValue,
    1856              &count, &format);
     1875    clipConvertX11CB(closure, pValue, count * format / 8);
    18571876}
    18581877
     
    19401959{
    19411960    Atom clipAtom = XInternAtom(NULL, "CLIPBOARD", 0);
    1942     g_selTarget[0] = XInternAtom(NULL, pcszTarget, 0);
     1961    g_selTargets[0] = clipFindX11FormatByAtomText(pcszTarget);
     1962    g_cTargets = 1;
    19431963    g_selType = type;
    19441964    g_pSelData = data;
     
    19481968        g_pfnSelLose(TEST_WIDGET, &clipAtom);
    19491969    g_ownsSel = false;
    1950     g_fTargetsTimeout = false;
    1951     g_fTargetsFailure = false;
    19521970}
    19531971
    19541972static void clipSendTargetUpdate(CLIPBACKEND *pCtx)
    19551973{
    1956     CLIPX11FORMAT selTarget[RT_ELEMENTS(g_selTarget)];
    1957     unsigned i, j;
    1958     RT_ZERO(selTarget);
    1959     for (i = 0; i < RT_ELEMENTS(g_selTarget); ++i)
    1960         for (j = 0; j < RT_ELEMENTS(g_aFormats); ++j)
    1961             if (XInternAtom(NULL, g_aFormats[j].pcszAtom, 0) == g_selTarget[i])
    1962                 selTarget[i] = j;
    1963     clipUpdateX11Targets(pCtx, selTarget, RT_ELEMENTS(selTarget));
     1974    clipQueryX11CBFormats(pCtx);
    19641975}
    19651976
    19661977/* Configure if and how the X11 TARGETS clipboard target will fail */
    1967 static void clipSetTargetsFailure(bool fTimeout, bool fFailure)
    1968 {
    1969     g_fTargetsTimeout = fTimeout;
    1970     g_fTargetsFailure = fFailure;
     1978static void clipSetTargetsFailure(void)
     1979{
     1980    g_cTargets = 0;
    19711981}
    19721982
     
    23202330    /*** Timeout from X11 ***/
    23212331    RTTestSub(hTest, "X11 timeout");
    2322     clipSetSelectionValues("UTF8_STRING", XT_CONVERT_FAIL, "hello world",
    2323                            sizeof("hello world"), 8);
    2324     testStringFromX11(hTest, pCtx, "hello world", VERR_TIMEOUT);
     2332    clipSetSelectionValues("UTF8_STRING", XT_CONVERT_FAIL, NULL,0, 8);
     2333    testStringFromX11(hTest, pCtx, "", VERR_NO_DATA);
    23252334
    23262335    /*** No data in X11 clipboard ***/
     
    23602369    clipSetSelectionValues("UTF8_STRING", XA_STRING, "hello world",
    23612370                           sizeof("hello world"), 8);
    2362     clipSetTargetsFailure(false, true);
     2371    clipSetTargetsFailure();
    23632372    Atom atom = XA_STRING;
    23642373    long unsigned int cLen = 0;
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