VirtualBox

Changeset 100328 in vbox


Ignore:
Timestamp:
Jun 29, 2023 9:47:33 AM (23 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
158043
Message:

Shared Clipboard: Implemented a (very) basic and generic clipboard cache; to be used on the guest and host side. bugref:9437

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/GuestHost/SharedClipboard.h

    r100204 r100328  
    6969 *  @since 7.1
    7070 */
    71 # define VBOX_SHCL_FMT_URI_LIST     RT_BIT(3)
     71#define VBOX_SHCL_FMT_URI_LIST      RT_BIT(3)
     72/** Shared Clipboard format valid mask. */
     73#define VBOX_SHCL_FMT_VALID_MASK    0xf
     74/** Maximum number of Shared Clipboard formats.
     75 *  This currently ASSUMES that there are no gaps in the bit mask. */
     76#define VBOX_SHCL_FMT_MAX           VBOX_SHCL_FMT_VALID_MASK
    7277/** @}  */
    7378
     
    249254} SHCLSOURCE;
    250255
     256/** @name Shared Clipboard caching.
     257 *  @{
     258 */
     259/**
     260 * A single Shared CLipboard cache entry.
     261 */
     262typedef struct _SHCLCACHEENTRY
     263{
     264    /** Entry data.
     265     *  Acts as a beacon for entry validation. */
     266    void  *pvData;
     267    /** Entry data size (in bytes). */
     268    size_t cbData;
     269} SHCLCACHEENTRY;
     270/** Pointer to a Shared Clipboard cache entry. */
     271typedef SHCLCACHEENTRY *PSHCLCACHEENTRY;
     272
     273/**
     274 * A (very simple) Shared Clipboard cache.
     275 */
     276typedef struct _SHCLCACHE
     277{
     278    /** Entries for all formats.
     279     *  Right now this is static to keep it simple. */
     280    SHCLCACHEENTRY aEntries[VBOX_SHCL_FMT_MAX];
     281} SHCLCACHE;
     282/** Pointer to a Shared Clipboard cache. */
     283typedef SHCLCACHE *PSHCLCACHE;
     284
     285void ShClCacheEntryGet(PSHCLCACHEENTRY pCacheEntry, void **pvData, size_t *pcbData);
     286
     287void ShClCacheInit(PSHCLCACHE pCache);
     288void ShClCacheDestroy(PSHCLCACHE pCache);
     289void ShClCacheInvalidate(PSHCLCACHE pCache);
     290void ShClCacheInvalidateEntry(PSHCLCACHE pCache, SHCLFORMAT uFmt);
     291PSHCLCACHEENTRY ShClCacheGet(PSHCLCACHE pCache, SHCLFORMAT uFmt);
     292int ShClCacheSet(PSHCLCACHE pCache, SHCLFORMAT uFmt, const void *pvData, size_t cbData);
     293/** @}  */
     294
    251295/** Opaque data structure for the X11/VBox frontend/glue code.
    252296 * @{ */
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-common.cpp

    r100204 r100328  
    12481248}
    12491249
     1250
     1251/*********************************************************************************************************************************
     1252*   Shared Clipboard Cache                                                                                                       *
     1253*********************************************************************************************************************************/
     1254
     1255/**
     1256 * Returns (mutable) data of a cache entry.
     1257 *
     1258 * @param   pCacheEntry         Cache entry to return data for.
     1259 * @param   pvData              Where to return the (mutable) data pointer.
     1260 * @param   pcbData             Where to return the data size.
     1261 */
     1262void ShClCacheEntryGet(PSHCLCACHEENTRY pCacheEntry, void **pvData, size_t *pcbData)
     1263{
     1264    AssertPtrReturnVoid(pCacheEntry);
     1265    AssertPtrReturnVoid(pvData);
     1266    AssertReturnVoid(pcbData);
     1267
     1268    *pvData  = pCacheEntry->pvData;
     1269    *pcbData = pCacheEntry->cbData;
     1270}
     1271
     1272/**
     1273 * Initializes a cache entry.
     1274 *
     1275 * @returns VBox status code.
     1276 * @param   pCacheEntry         Cache entry to init.
     1277 * @param   pvData              Data to copy to entry. Can be NULL to initialize an emptry entry.
     1278 * @param   cbData              Size (in bytes) of \a pvData to copy to entry. Must be 0 if \a pvData is NULL.
     1279 */
     1280static int shClCacheEntryInit(PSHCLCACHEENTRY pCacheEntry, const void *pvData, size_t cbData)
     1281{
     1282    AssertReturn(RT_VALID_PTR(pvData) || cbData == 0, VERR_INVALID_PARAMETER);
     1283
     1284    RT_BZERO(pCacheEntry, sizeof(SHCLCACHEENTRY));
     1285
     1286    if (pvData)
     1287    {
     1288        pCacheEntry->pvData = RTMemDup(pvData, cbData);
     1289        AssertPtrReturn(pCacheEntry->pvData, VERR_NO_MEMORY);
     1290        pCacheEntry->cbData = cbData;
     1291    }
     1292
     1293    return VINF_SUCCESS;
     1294}
     1295
     1296/**
     1297 * Returns whether a cache entry is valid (cache hit) or not.
     1298 *
     1299 * @returns \c true if valid, or \c false if not.
     1300 * @param   pCacheEntry         Cache entry to check for.
     1301 */
     1302DECLINLINE(bool) shClCacheEntryIsValid(PSHCLCACHEENTRY pCacheEntry)
     1303{
     1304    return pCacheEntry->pvData != NULL;
     1305}
     1306
     1307/**
     1308 * Destroys a cache entry.
     1309 *
     1310 * @param   pCacheEntry         Cache entry to destroy.
     1311 */
     1312DECLINLINE(void) shClCacheEntryDestroy(PSHCLCACHEENTRY pCacheEntry)
     1313{
     1314    if (pCacheEntry->pvData)
     1315    {
     1316        Assert(pCacheEntry->cbData);
     1317        RTMemFree(pCacheEntry->pvData);
     1318        pCacheEntry->pvData = NULL;
     1319        pCacheEntry->cbData = 0;
     1320    }
     1321}
     1322
     1323/**
     1324 * Initializes a cache.
     1325 *
     1326 * @param   pCache              Cache to init.
     1327 */
     1328void ShClCacheInit(PSHCLCACHE pCache)
     1329{
     1330    AssertPtrReturnVoid(pCache);
     1331
     1332    RT_BZERO(pCache, sizeof(SHCLCACHE));
     1333
     1334    for (size_t i = 0; i < RT_ELEMENTS(pCache->aEntries); i++)
     1335        shClCacheEntryInit(&pCache->aEntries[i], NULL, 0);
     1336}
     1337
     1338/**
     1339 * Destroys all entries of a cache.
     1340 *
     1341 * @param   pCache              Cache to destroy entries for.
     1342 */
     1343DECLINLINE(void) shClCacheDestroyEntries(PSHCLCACHE pCache)
     1344{
     1345    for (size_t i = 0; i < RT_ELEMENTS(pCache->aEntries); i++)
     1346        shClCacheEntryDestroy(&pCache->aEntries[i]);
     1347}
     1348
     1349/**
     1350 * Destroys a cache.
     1351 *
     1352 * @param   pCache              Cache to destroy.
     1353 */
     1354void ShClCacheDestroy(PSHCLCACHE pCache)
     1355{
     1356    AssertPtrReturnVoid(pCache);
     1357
     1358    shClCacheDestroyEntries(pCache);
     1359
     1360    RT_BZERO(pCache, sizeof(SHCLCACHE));
     1361}
     1362
     1363/**
     1364 * Invalidates a cache.
     1365 *
     1366 * @param   pCache              Cache to invalidate.
     1367 */
     1368void ShClCacheInvalidate(PSHCLCACHE pCache)
     1369{
     1370    AssertPtrReturnVoid(pCache);
     1371
     1372    shClCacheDestroyEntries(pCache);
     1373}
     1374
     1375/**
     1376 * Invalidates a specific cache entry.
     1377 *
     1378 * @param   pCache              Cache to invalidate.
     1379 * @param   uFmt                Format to invalidate entry for.
     1380 */
     1381void ShClCacheInvalidateEntry(PSHCLCACHE pCache, SHCLFORMAT uFmt)
     1382{
     1383    AssertPtrReturnVoid(pCache);
     1384    AssertReturnVoid(uFmt < VBOX_SHCL_FMT_MAX);
     1385    shClCacheEntryDestroy(&pCache->aEntries[uFmt]);
     1386}
     1387
     1388/**
     1389 * Gets an entry for a Shared Clipboard format.
     1390 *
     1391 * @returns Pointer to entry if cached, or NULL if not in cache (cache miss).
     1392 * @param   pCache              Cache to get entry for.
     1393 * @param   uFmt                Format to get entry for.
     1394 */
     1395PSHCLCACHEENTRY ShClCacheGet(PSHCLCACHE pCache, SHCLFORMAT uFmt)
     1396{
     1397    AssertReturn(uFmt < VBOX_SHCL_FMT_MAX, NULL);
     1398    return shClCacheEntryIsValid(&pCache->aEntries[uFmt]) ? &pCache->aEntries[uFmt] : NULL;
     1399}
     1400
     1401/**
     1402 * Sets data to cache for a specific clipboard format.
     1403 *
     1404 * @returns VBox status code.
     1405 * @param   pCache              Cache to set data for.
     1406 * @param   uFmt                Clipboard format to set data for.
     1407 * @param   pvData              Data to set.
     1408 * @param   cbData              Size (in bytes) of data to set.
     1409 */
     1410int ShClCacheSet(PSHCLCACHE pCache, SHCLFORMAT uFmt, const void *pvData, size_t cbData)
     1411{
     1412    AssertPtrReturn(pCache, VERR_INVALID_POINTER);
     1413
     1414    if (!pvData) /* Nothing to cache? */
     1415        return VINF_SUCCESS;
     1416
     1417    AssertReturn(cbData, VERR_INVALID_PARAMETER);
     1418    AssertReturn(uFmt < VBOX_SHCL_FMT_MAX, VERR_INVALID_PARAMETER);
     1419    AssertReturn(shClCacheEntryIsValid(&pCache->aEntries[uFmt]) == false, VERR_ALREADY_EXISTS);
     1420
     1421    return shClCacheEntryInit(&pCache->aEntries[uFmt], pvData, cbData);
     1422}
     1423
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