VirtualBox

Changeset 92160 in vbox


Ignore:
Timestamp:
Oct 30, 2021 1:40:42 AM (3 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
147983
Message:

ValKit/ClipUtil: Quick OS/2 implementation (untested). bugref:10133

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/utils/clipboard/ClipUtil.cpp

    r92159 r92160  
    138138typedef CLIPUTILTARGET const *PCCLIPUTILTARGET;
    139139#endif /* MULTI_TARGET_CLIPBOARD */
     140
     141
     142#ifdef RT_OS_OS2
     143/** Header for Odin32 specific clipboard entries.
     144 * (Used to get the correct size of the data.)
     145 */
     146typedef struct _Odin32ClipboardHeader
     147{
     148    /** Magic (CLIPHEADER_MAGIC) */
     149    char        achMagic[8];
     150    /** Size of the following data.
     151     * (The interpretation depends on the type.) */
     152    unsigned    cbData;
     153    /** Odin32 format number. */
     154    unsigned    uFormat;
     155} CLIPHEADER, *PCLIPHEADER;
     156
     157#define CLIPHEADER_MAGIC "Odin\1\0\1"
     158#endif
    140159
    141160
     
    211230/** The message queue handle.   */
    212231static HMQ      g_hOs2MsgQueue = NULLHANDLE;
     232/** Windows that becomes clipboard owner when setting data. */
     233static HWND     g_hOs2Wnd = NULLHANDLE;
    213234/** Set if we've opened the clipboard. */
    214235static bool     g_fOs2OpenedClipboard = false;
     236/** Set if we're the clipboard owner. */
     237static bool     g_fOs2ClipboardOwner = false;
    215238
    216239#elif defined(RT_OS_WINDOWS)
     
    252275                g_aFormats[i].fFormat = WinAddAtom(WinQuerySystemAtomTable(), g_aFormats[i].pszFormat);
    253276                if (g_aFormats[i].fFormat == 0)
    254                     RTMsgError("WinAddAtom(,%s) failed: %u (%#x)", g_aFormats[i].pszFormat, WinGetLastError(), WinGetLastError());
     277                    RTMsgError("WinAddAtom(,%s) failed: %#x", g_aFormats[i].pszFormat, WinGetLastError(g_hOs2Hab));
    255278            }
    256279
     
    281304
    282305#elif defined(RT_OS_OS2)
    283     AdHoc.pszFormat   = pszDesc;
    284     AdHoc.fFormat     = WinAddAtom(WinQuerySystemAtomTable(), pwszDesc);
     306    AdHoc.pszFormat   = pszFormat;
     307    AdHoc.fFormat     = WinAddAtom(WinQuerySystemAtomTable(), pszFormat);
    285308    if (AdHoc.fFormat == 0)
    286309    {
    287         RTMsgError("Invalid format '%s' (%u (%#x))", pszFormat, WinGetLastError(), WinGetLastError());
     310        RTMsgError("Invalid format '%s' (%#x)", pszFormat, WinGetLastError(g_hOs2Hab));
    288311        return NULL;
    289312    }
     
    320343
    321344/**
     345 * The window procedure for the object window.
     346 *
     347 * @returns Message result.
     348 *
     349 * @param   hwnd    The window handle.
     350 * @param   msg     The message.
     351 * @param   mp1     Message parameter 1.
     352 * @param   mp2     Message parameter 2.
     353 */
     354static MRESULT EXPENTRY CuOs2WinProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
     355{
     356    if (g_uVerbosity > 2)
     357        RTMsgInfo("CuOs2WinProc: hwnd=%#lx msg=%#lx mp1=%#lx mp2=%#lx\n", hwnd, msg, mp1, mp2);
     358
     359    switch (msg)
     360    {
     361        case WM_CREATE:
     362            return NULL; /* FALSE(/NULL) == Continue*/
     363        case WM_DESTROY:
     364            break;
     365
     366        /*
     367         * Clipboard viewer message - the content has been changed.
     368         * This is sent *after* releasing the clipboard sem
     369         * and during the WinSetClipbrdViewer call.
     370         */
     371        case WM_DRAWCLIPBOARD:
     372            break;
     373
     374        /*
     375         * Clipboard owner message - the content was replaced.
     376         * This is sent by someone with an open clipboard, so don't try open it now.
     377         */
     378        case WM_DESTROYCLIPBOARD:
     379            break;
     380
     381        /*
     382         * Clipboard owner message - somebody is requesting us to render a format.
     383         * This is called by someone which owns the clipboard, but that's fine.
     384         */
     385        case WM_RENDERFMT:
     386            break;
     387
     388        /*
     389         * Clipboard owner message - we're about to quit and should render all formats.
     390         */
     391        case WM_RENDERALLFMTS:
     392            break;
     393
     394        /*
     395         * Clipboard owner messages dealing with owner drawn content.
     396         * We shouldn't be seeing any of these.
     397         */
     398        case WM_PAINTCLIPBOARD:
     399        case WM_SIZECLIPBOARD:
     400        case WM_HSCROLLCLIPBOARD:
     401        case WM_VSCROLLCLIPBOARD:
     402            AssertMsgFailed(("msg=%lx (%ld)\n", msg, msg));
     403            break;
     404
     405        /*
     406         * We shouldn't be seeing any other messages according to the docs.
     407         * But for whatever reason, PM sends us a WM_ADJUSTWINDOWPOS message
     408         * during WinCreateWindow. So, ignore that and assert on anything else.
     409         */
     410        default:
     411            AssertMsgFailed(("msg=%lx (%ld)\n", msg, msg));
     412        case WM_ADJUSTWINDOWPOS:
     413            break;
     414    }
     415    return NULL;
     416}
     417
     418/**
    322419 * Initialize the OS/2 bits.
    323420 */
     
    326423    g_hOs2Hab = WinInitialize(0);
    327424    if (g_hOs2Hab == NULLHANDLE)
    328         return RTMsgErrorExitFailure("WinInitialize failed: %u", WinGetLastError());
     425        return RTMsgErrorExitFailure("WinInitialize failed!");
    329426
    330427    g_hOs2MsgQueue = WinCreateMsgQueue(g_hOs2Hab, 10);
    331428    if (g_hOs2MsgQueue == NULLHANDLE)
    332         return RTMsgErrorExitFailure("WinCreateMsgQueue failed: %u", WinGetLastError());
     429        return RTMsgErrorExitFailure("WinCreateMsgQueue failed: %#x", WinGetLastError(g_hOs2Hab));
     430
     431    static char s_szClass[] = "VBox-ClipUtilClipboardClass";
     432    if (!WinRegisterClass(g_hOs2Wnd, (PCSZ)s_szClass, CuOs2WinProc, 0, 0))
     433        return RTMsgErrorExitFailure("WinRegisterClass failed: %#x", WinGetLastError(g_hOs2Hab));
     434
     435    g_hOs2Wnd = WinCreateWindow(HWND_OBJECT,                             /* hwndParent */
     436                                (PCSZ)s_szClass,                         /* pszClass */
     437                                (PCSZ)"VirtualBox Clipboard Utility",    /* pszName */
     438                                0,                                       /* flStyle */
     439                                0, 0, 0, 0,                              /* x, y, cx, cy */
     440                                NULLHANDLE,                              /* hwndOwner */
     441                                HWND_BOTTOM,                             /* hwndInsertBehind */
     442                                42,                                      /* id */
     443                                NULL,                                    /* pCtlData */
     444                                NULL);                                   /* pPresParams */
     445    if (g_hOs2Wnd == NULLHANDLE)
     446        return RTMsgErrorExitFailure("WinCreateWindow failed: %#x", WinGetLastError(g_hOs2Hab));
     447
    333448    return RTEXITCODE_SUCCESS;
    334449}
     
    343458    {
    344459        if (!WinCloseClipbrd(g_hOs2Hab))
    345             return RTMsgErrorExitFailure("WinCloseClipbrd failed: %u", WinGetLastError());
     460            return RTMsgErrorExitFailure("WinCloseClipbrd failed: %#x", WinGetLastError(g_hOs2Hab));
    346461        g_fOs2OpenedClipboard = false;
    347462    }
    348463
    349     WinDestroyMsgQueue(g_hOs2Hab, g_hOs2MsgQueue);
     464    WinDestroyWindow(g_hOs2Wnd);
     465    g_hOs2Wnd = NULLHANDLE;
     466
     467    WinDestroyMsgQueue(g_hOs2MsgQueue);
    350468    g_hOs2MsgQueue = NULLHANDLE;
    351469
     
    354472
    355473    return RTEXITCODE_SUCCESS;
     474}
     475
     476
     477/**
     478 * Opens the OS/2 clipboard.
     479 */
     480static RTEXITCODE CuOs2OpenClipboardIfNecessary(void)
     481{
     482    if (g_fOs2OpenedClipboard)
     483        return RTEXITCODE_SUCCESS;
     484    if (WinOpenClipbrd(g_hOs2Hab))
     485    {
     486        g_fOs2OpenedClipboard = true;
     487        return RTEXITCODE_SUCCESS;
     488    }
     489    return RTMsgErrorExitFailure("WinOpenClipbrd failed: %#x", WinGetLastError(g_hOs2Hab));
    356490}
    357491
     
    456590static RTEXITCODE ListClipboardContent(void)
    457591{
    458 #ifdef RT_OS_WINDOWS
     592#if defined(RT_OS_OS2)
     593    RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary();
     594    if (rcExit == RTEXITCODE_SUCCESS)
     595    {
     596        HATOMTBL const hAtomTbl  = WinQuerySystemAtomTable();
     597        uint32_t       idx       = 0;
     598        ULONG          fFormat   = 0;
     599        while ((fFormat = WinEnumClipbrdFmts(g_hOs2Hab)) != 0)
     600        {
     601            char szName[256] = {0};
     602            ULONG cchRet = WinQueryAtomName(hAtomTbl, fFormat, szName, sizeof(szName));
     603            if (cchRet != 0)
     604                RTPrintf("#%u: %#06x - %s\n", idx, fFormat, szName);
     605            else
     606            {
     607                const char *pszName = NULL;
     608                switch (fFormat)
     609                {
     610                    case CF_TEXT: pszName = "CF_TEXT"; break;
     611                    case CF_BITMAP: pszName = "CF_BITMAP"; break;
     612                    case CF_DSPTEXT: pszName = "CF_DSPTEXT"; break;
     613                    case CF_DSPBITMAP: pszName = "CF_DSPBITMAP"; break;
     614                    case CF_METAFILE: pszName = "CF_METAFILE"; break;
     615                    case CF_DSPMETAFILE: pszName = "CF_DSPMETAFILE"; break;
     616                    case CF_PALETTE: pszName = "CF_PALETTE"; break;
     617                    default:
     618                        break;
     619                }
     620                if (pszName)
     621                    RTPrintf("#%02u: %#06x - %s\n", idx, fFormat, pszName);
     622                else
     623                    RTPrintf("#%02u: %#06x\n", idx, fFormat);
     624            }
     625
     626            idx++;
     627        }
     628    }
     629
     630    return rcExit;
     631
     632#elif defined(RT_OS_WINDOWS)
    459633    RTEXITCODE rcExit = WinOpenClipboardIfNecessary();
    460634    if (rcExit == RTEXITCODE_SUCCESS)
     
    508682
    509683#elif defined(CU_X11)
    510 
     684    /* Request the TARGETS property: */
    511685    Atom uAtomDst = g_uX11AtomTargets;
    512686    int rc = XConvertSelection(g_pX11Display, g_pTarget->uAtom, g_uX11AtomTargets, uAtomDst, g_hX11Window, CurrentTime);
     
    514688        RTPrintf("XConvertSelection -> %d\n", rc);
    515689
     690    /* Wait for the reply: */
    516691    for (;;)
    517692    {
     
    527702                    return RTMsgErrorExitFailure("XConvertSelection(,%s,TARGETS,) failed", g_pTarget->pszName);
    528703
     704                /* Get the TARGETS property data: */
    529705                Atom            uAtomRetType = 0;
    530706                int             iActualFmt   = 0;
     
    540716                if (pbData && cItems > 0)
    541717                {
     718                    /* Display the TARGETS: */
    542719                    Atom const *paTargets = (Atom const *)pbData;
    543720                    for (unsigned long i = 0; i < cItems; i++)
     
    581758    *pcbData = 0;
    582759
    583 #ifdef RT_OS_WINDOWS
     760#if defined(RT_OS_OS2)
     761    RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary();
     762    if (rcExit == RTEXITCODE_SUCCESS)
     763    {
     764        ULONG fFmtInfo = 0;
     765        if (WinQueryClipbrdFmtInfo(g_hOs2Hab, pFmtDesc->fFormat, &fFmtInfo))
     766        {
     767            ULONG uData = WinQueryClipbrdData(g_hOs2Hab, pFmtDesc->fFormat);
     768            if (fFmtInfo & CFI_POINTER)
     769            {
     770                PCLIPHEADER pOdinHdr = (PCLIPHEADER)uData;
     771                if (pFmtDesc->fFormat == CF_TEXT)
     772                {
     773                    if (pFmtDesc->fFlags & CLIPUTILFORMAT_F_CONVERT_UTF8)
     774                    {
     775                        char *pszUtf8 = NULL;
     776                        int rc = RTStrCurrentCPToUtf8(&pszUtf8, (const char *)uData);
     777                        if (RT_SUCCESS(rc))
     778                        {
     779                            *pcbData = strlen(pszUtf8) + 1;
     780                            *ppvData = RTMemDup(pszUtf8, *pcbData);
     781                            RTStrFree(pszUtf8);
     782                        }
     783                        else
     784                            return RTMsgErrorExitFailure("RTStrCurrentCPToUtf8 failed: %Rrc", rc);
     785                    }
     786                    else
     787                    {
     788                        *pcbData = strlen((const char *)uData) + 1;
     789                        *ppvData = RTMemDup((const char *)uData, *pcbData);
     790                    }
     791                }
     792                else if (   strcmp(pFmtDesc->pszFormat, "Odin32 UnicodeText") == 0
     793                         && memcmp(pOdinHdr->achMagic, CLIPHEADER_MAGIC, sizeof(pOdinHdr->achMagic)) == 0)
     794                {
     795                    *pcbData = pOdinHdr->cbData;
     796                    *ppvData = RTMemDup(pOdinHdr + 1, pOdinHdr->cbData);
     797                }
     798                else
     799                {
     800                    /* We could use DosQueryMem here to figure out the size of the allocation... */
     801                    *pcbData = PAGE_SIZE - (uData & PAGE_OFFSET_MASK);
     802                    *ppvData = RTMemDup((void const *)uData, *pcbData);
     803                }
     804            }
     805            else
     806            {
     807                *pcbData = sizeof(uData);
     808                *ppvData = RTMemDup(&uData, sizeof(uData));
     809            }
     810            if (!*ppvData)
     811                rcExit = RTMsgErrorExitFailure("Out of memory allocating %#zx bytes.", *pcbData);
     812        }
     813        else
     814            rcExit = RTMsgErrorExitFailure("WinQueryClipbrdFmtInfo(,%s,) failed: %#x\n",
     815                                           pFmtDesc->pszName, WinGetLastError(g_hOs2Hab));
     816    }
     817    return rcExit;
     818
     819#elif defined(RT_OS_WINDOWS)
    584820    RTEXITCODE rcExit = WinOpenClipboardIfNecessary();
    585821    if (rcExit == RTEXITCODE_SUCCESS)
     
    701937static RTEXITCODE WriteClipboardData(PCCLIPUTILFORMAT pFmtDesc, void const *pvData, size_t cbData)
    702938{
    703 #ifdef RT_OS_WINDOWS
     939#if defined(RT_OS_OS2)
     940    RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary();
     941    if (rcExit == RTEXITCODE_SUCCESS)
     942    {
     943        /** @todo do we need to become owner? */
     944
     945        /* Convert to local code page if needed: */
     946        char *pszLocale = NULL;
     947        if (pFmtDesc->fFlags & CLIPUTILFORMAT_F_CONVERT_UTF8)
     948        {
     949            int rc = RTStrUtf8ToCurrentCPEx(&pszLocale, (char *)pvData, cbData);
     950            if (RT_SUCCESS(rc))
     951            {
     952                pvData = pszLocale;
     953                cbData = strlen(pszLocale) + 1;
     954            }
     955            else
     956                return RTMsgErrorExitFailure("RTStrUtf8ToCurrentCPEx failed: %Rrc\n", rc);
     957        }
     958
     959        /* Allocate a bunch of shared memory for the object. */
     960        PVOID  pvShared = NULL;
     961        APIRET orc = DosAllocSharedMem(&pvShared, NULL, cbData,
     962                                       OBJ_GIVEABLE | OBJ_GETTABLE | OBJ_TILE | PAG_READ | PAG_WRITE | PAG_COMMIT);
     963        if (orc == NO_ERROR)
     964        {
     965            memcpy(pvShared, pvData, cbData);
     966
     967            if (WinSetClipbrdData(g_hOs2Hab, (uintptr_t)pvShared, pFmtDesc->fFormat, CFI_POINTER))
     968                rcExit = RTEXITCODE_SUCCESS;
     969            else
     970            {
     971                rcExit = RTMsgErrorExitFailure("WinSetClipbrdData(,%p LB %#x,%s,) failed: %#x\n",
     972                                               pvShared, cbData, pFmtDesc->pszName, WinGetLastError(g_hOs2Hab));
     973                DosFreeMem(pvShared);
     974            }
     975        }
     976        else
     977            rcExit = RTMsgErrorExitFailure("DosAllocSharedMem(,, %#x,) -> %u", cbData, orc);
     978        RTStrFree(pszLocale);
     979    }
     980    return rcExit;
     981
     982
     983#elif defined(RT_OS_WINDOWS)
    704984    RTEXITCODE rcExit = WinOpenClipboardIfNecessary();
    705985    if (rcExit == RTEXITCODE_SUCCESS)
     
    9411221static RTEXITCODE CheckFormatNotOnClipboard(PCCLIPUTILFORMAT pFmtDesc)
    9421222{
    943 #ifdef RT_OS_WINDOWS
     1223#if defined(RT_OS_OS2)
     1224    RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary();
     1225    if (rcExit == RTEXITCODE_SUCCESS)
     1226    {
     1227        ULONG fFmtInfo = 0;
     1228        if (WinQueryClipbrdFmtInfo(g_hOs2Hab, pFmtDesc->fFormat, &fFmtInfo))
     1229            rcExit = RTMsgErrorExitFailure("Format '%s' is present");
     1230    }
     1231    return rcExit;
     1232
     1233#elif defined(RT_OS_WINDOWS)
    9441234    RTEXITCODE rcExit = WinOpenClipboardIfNecessary();
    9451235    if (rcExit == RTEXITCODE_SUCCESS)
     
    9641254static RTEXITCODE ZapAllClipboardData(void)
    9651255{
    966 #ifdef RT_OS_WINDOWS
     1256#if defined(RT_OS_OS2)
     1257    RTEXITCODE rcExit = CuOs2OpenClipboardIfNecessary();
     1258    if (rcExit == RTEXITCODE_SUCCESS)
     1259    {
     1260        ULONG fFmtInfo = 0;
     1261        if (WinEmptyClipbrd(g_hOs2Hab))
     1262        {
     1263            WinSetClipbrdOwner(g_hOs2Hab, g_hOs2Wnd); /* Probably unnecessary? */
     1264            WinSetClipbrdOwner(g_hOs2Hab, NULLHANDLE);
     1265            g_fOs2ClipboardOwner = false;
     1266        }
     1267        else
     1268            rcExit = RTMsgErrorExitFailure("WinEmptyClipbrd() failed: %#x\n", WinGetLastError(g_hOs2Hab));
     1269    }
     1270    return rcExit;
     1271
     1272#elif defined(RT_OS_WINDOWS)
    9671273    RTEXITCODE rcExit = WinOpenClipboardIfNecessary();
    9681274    if (rcExit == RTEXITCODE_SUCCESS)
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