VirtualBox

Changeset 78581 in vbox for trunk/src


Ignore:
Timestamp:
May 18, 2019 3:48:41 PM (6 years ago)
Author:
vboxsync
Message:

Shared Clipboard/URI: Update.

Location:
trunk/src/VBox
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/VBoxTray/VBoxClipboard.cpp

    r78501 r78581  
    3939#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    4040/** !!! HACK ALERT !!! Dynamically resolve functions! */
    41 #ifdef _WIN32_IE
    42 #undef _WIN32_IE
    43 #define _WIN32_IE 0x0501
    44 #endif
    45 #include <iprt/win/shlobj.h>
    46 #include <iprt/win/shlwapi.h>
     41# ifdef _WIN32_IE
     42#  undef _WIN32_IE
     43#  define _WIN32_IE 0x0501
     44# endif
     45# include <iprt/win/shlobj.h>
     46# include <iprt/win/shlwapi.h>
    4747#endif
    4848
     
    7373
    7474
    75 static LRESULT vboxClipboardProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
     75static LRESULT vboxClipboardWinProcessMsg(PVBOXCLIPBOARDCONTEXT pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    7676{
    7777    AssertPtr(pCtx);
     
    8383    switch (msg)
    8484    {
    85         case WM_CLIPBOARDUPDATE:
    86         {
     85       case WM_CLIPBOARDUPDATE:
     86       {
    8787           if (GetClipboardOwner() != hwnd)
    8888           {
     
    9898           else
    9999               LogFlowFunc(("WM_CLIPBOARDUPDATE: No change (VBoxTray is owner)\n"));
    100         }
    101         break;
    102 
    103         case WM_CHANGECBCHAIN:
    104         {
     100       }
     101       break;
     102
     103       case WM_CHANGECBCHAIN:
     104       {
    105105           if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
    106106           {
     
    132132               }
    133133           }
    134         }
    135         break;
    136 
    137         case WM_DRAWCLIPBOARD:
    138         {
    139             LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd));
    140 
    141             if (GetClipboardOwner() != hwnd)
    142             {
     134       }
     135       break;
     136
     137       case WM_DRAWCLIPBOARD:
     138       {
     139           LogFlowFunc(("WM_DRAWCLIPBOARD, hwnd %p\n", pWinCtx->hWnd));
     140
     141           if (GetClipboardOwner() != hwnd)
     142           {
    143143               /* Clipboard was updated by another application. */
    144144               /* WM_DRAWCLIPBOARD always expects a return code of 0, so don't change "rc" here. */
     
    147147               if (RT_SUCCESS(rc))
    148148                   rc = VbglR3ClipboardReportFormats(pCtx->u32ClientID, fFormats);
    149             }
    150 
    151             if (pWinCtx->hWndNextInChain)
    152             {
     149           }
     150
     151           if (pWinCtx->hWndNextInChain)
     152           {
    153153               /* Pass the message to next windows in the clipboard chain. */
    154154               SendMessageTimeout(pWinCtx->hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS, NULL);
    155             }
    156         }
    157         break;
    158 
    159         case WM_TIMER:
    160         {
    161             if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
    162                 break;
    163 
    164             HWND hViewer = GetClipboardViewer();
    165 
    166             /* Re-register ourselves in the clipboard chain if our last ping
    167             * timed out or there seems to be no valid chain. */
    168             if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess)
    169             {
    170                 VBoxClipboardWinRemoveFromCBChain(pWinCtx);
    171                 VBoxClipboardWinAddToCBChain(pWinCtx);
    172             }
    173 
    174             /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
    175             * processed by ourselves to the chain. */
    176             pWinCtx->oldAPI.fCBChainPingInProcess = TRUE;
    177 
    178             hViewer = GetClipboardViewer();
    179             if (hViewer)
    180                 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain,
    181                                     VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx);
    182         }
    183         break;
    184 
    185         case WM_CLOSE:
    186         {
    187             /* Do nothing. Ignore the message. */
    188         }
    189         break;
    190 
    191         case WM_RENDERFORMAT:
    192         {
    193             LogFunc(("WM_RENDERFORMAT\n"));
    194 
    195             /* Insert the requested clipboard format data into the clipboard. */
    196             const UINT cfFormat = (UINT)wParam;
    197 
    198             const VBOXCLIPBOARDFORMAT fFormat = VBoxClipboardWinClipboardFormatToVBox(cfFormat);
    199 
    200             LogFunc(("WM_RENDERFORMAT: cfFormat=%u -> fFormat=0x%x\n", cfFormat, fFormat));
    201 
    202             if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE)
    203             {
    204                 LogFunc(("WM_RENDERFORMAT: Unsupported format requested\n"));
    205                 VBoxClipboardWinClear();
    206             }
    207             else
    208             {
    209                 const uint32_t cbPrealloc = _4K;
    210                 uint32_t cb = 0;
    211 
    212                 /* Preallocate a buffer, most of small text transfers will fit into it. */
    213                 HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
    214                 LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));
    215 
    216                 if (hMem)
    217                 {
    218                     void *pMem = GlobalLock(hMem);
    219                     LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
    220 
    221                     if (pMem)
    222                     {
    223                         /* Read the host data to the preallocated buffer. */
    224                         int rc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb);
    225                         LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  rc));
    226 
    227                         if (RT_SUCCESS(rc))
    228                         {
    229                             if (cb == 0)
    230                             {
    231                                 /* 0 bytes returned means the clipboard is empty.
    232                                  * Deallocate the memory and set hMem to NULL to get to
    233                                  * the clipboard empty code path. */
    234                                 GlobalUnlock(hMem);
    235                                 GlobalFree(hMem);
    236                                 hMem = NULL;
    237                             }
    238                             else if (cb > cbPrealloc)
    239                             {
    240                                 GlobalUnlock(hMem);
    241 
    242                                 /* The preallocated buffer is too small, adjust the size. */
    243                                 hMem = GlobalReAlloc(hMem, cb, 0);
    244                                 LogFlowFunc(("Reallocated hMem = %p\n", hMem));
    245 
    246                                 if (hMem)
    247                                 {
    248                                     pMem = GlobalLock(hMem);
    249                                     LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
    250 
    251                                     if (pMem)
    252                                     {
    253                                         /* Read the host data to the preallocated buffer. */
    254                                         uint32_t cbNew = 0;
    255                                         rc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);
    256                                         LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n",
    257                                                      rc, cb, cbNew));
    258 
    259                                         if (RT_SUCCESS(rc)
    260                                             && cbNew <= cb)
    261                                         {
    262                                             cb = cbNew;
    263                                         }
    264                                         else
    265                                         {
    266                                             GlobalUnlock(hMem);
    267                                             GlobalFree(hMem);
    268                                             hMem = NULL;
    269                                         }
    270                                     }
    271                                     else
    272                                     {
    273                                         GlobalFree(hMem);
    274                                         hMem = NULL;
    275                                     }
    276                                 }
    277                             }
    278 
    279                             if (hMem)
    280                             {
    281                                 /* pMem is the address of the data. cb is the size of returned data. */
    282                                 /* Verify the size of returned text, the memory block for clipboard
    283                                  * must have the exact string size.
    284                                  */
    285                                 if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    286                                 {
    287                                     size_t cbActual = 0;
    288                                     HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
    289                                     if (FAILED(hrc))
    290                                     {
    291                                         /* Discard invalid data. */
    292                                         GlobalUnlock(hMem);
    293                                         GlobalFree(hMem);
    294                                         hMem = NULL;
    295                                     }
    296                                     else
    297                                     {
    298                                         /* cbActual is the number of bytes, excluding those used
    299                                          * for the terminating null character.
    300                                          */
    301                                         cb = (uint32_t)(cbActual + 2);
    302                                     }
    303                                 }
    304                             }
    305 
    306                             if (hMem)
    307                             {
    308                                 GlobalUnlock(hMem);
    309 
    310                                 hMem = GlobalReAlloc(hMem, cb, 0);
    311                                 LogFlowFunc(("Reallocated hMem = %p\n", hMem));
    312 
    313                                 if (hMem)
    314                                 {
    315                                     /* 'hMem' contains the host clipboard data.
    316                                      * size is 'cb' and format is 'format'. */
    317                                     HANDLE hClip = SetClipboardData(cfFormat, hMem);
    318                                     LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));
    319 
    320                                     if (hClip)
    321                                     {
    322                                         /* The hMem ownership has gone to the system. Finish the processing. */
    323                                         break;
    324                                     }
    325 
    326                                     /* Cleanup follows. */
    327                                 }
    328                             }
    329                         }
    330                         if (hMem)
    331                             GlobalUnlock(hMem);
    332                     }
    333                     if (hMem)
    334                         GlobalFree(hMem);
    335                 }
    336             }
    337         }
    338         break;
    339 
    340         case WM_RENDERALLFORMATS:
    341         {
    342             /* Do nothing. The clipboard formats will be unavailable now, because the
    343             * windows is to be destroyed and therefore the guest side becomes inactive.
    344             */
    345             int rc = VBoxClipboardWinOpen(hwnd);
    346             if (RT_SUCCESS(rc))
    347             {
     155           }
     156       }
     157       break;
     158
     159       case WM_TIMER:
     160       {
     161           if (VBoxClipboardWinIsNewAPI(&pWinCtx->newAPI))
     162               break;
     163
     164           HWND hViewer = GetClipboardViewer();
     165
     166           /* Re-register ourselves in the clipboard chain if our last ping
     167           * timed out or there seems to be no valid chain. */
     168           if (!hViewer || pWinCtx->oldAPI.fCBChainPingInProcess)
     169           {
     170               VBoxClipboardWinRemoveFromCBChain(pWinCtx);
     171               VBoxClipboardWinAddToCBChain(pWinCtx);
     172           }
     173
     174           /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
     175           * processed by ourselves to the chain. */
     176           pWinCtx->oldAPI.fCBChainPingInProcess = TRUE;
     177
     178           hViewer = GetClipboardViewer();
     179           if (hViewer)
     180               SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pWinCtx->hWndNextInChain, (LPARAM)pWinCtx->hWndNextInChain,
     181                                   VBoxClipboardWinChainPingProc, (ULONG_PTR)pWinCtx);
     182       }
     183       break;
     184
     185       case WM_CLOSE:
     186       {
     187           /* Do nothing. Ignore the message. */
     188       }
     189       break;
     190
     191       case WM_RENDERFORMAT:
     192       {
     193           LogFunc(("WM_RENDERFORMAT\n"));
     194
     195           /* Insert the requested clipboard format data into the clipboard. */
     196           const UINT cfFormat = (UINT)wParam;
     197
     198           const VBOXCLIPBOARDFORMAT fFormat = VBoxClipboardWinClipboardFormatToVBox(cfFormat);
     199
     200           LogFunc(("WM_RENDERFORMAT: cfFormat=%u -> fFormat=0x%x\n", cfFormat, fFormat));
     201
     202           if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_NONE)
     203           {
     204               LogFunc(("WM_RENDERFORMAT: Unsupported format requested\n"));
     205               VBoxClipboardWinClear();
     206           }
     207           else
     208           {
     209               const uint32_t cbPrealloc = _4K;
     210               uint32_t cb = 0;
     211
     212               /* Preallocate a buffer, most of small text transfers will fit into it. */
     213               HANDLE hMem = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cbPrealloc);
     214               LogFlowFunc(("Preallocated handle hMem = %p\n", hMem));
     215
     216               if (hMem)
     217               {
     218                   void *pMem = GlobalLock(hMem);
     219                   LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
     220
     221                   if (pMem)
     222                   {
     223                       /* Read the host data to the preallocated buffer. */
     224                       int rc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cbPrealloc, &cb);
     225                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc\n",  rc));
     226
     227                       if (RT_SUCCESS(rc))
     228                       {
     229                           if (cb == 0)
     230                           {
     231                               /* 0 bytes returned means the clipboard is empty.
     232                                * Deallocate the memory and set hMem to NULL to get to
     233                                * the clipboard empty code path. */
     234                               GlobalUnlock(hMem);
     235                               GlobalFree(hMem);
     236                               hMem = NULL;
     237                           }
     238                           else if (cb > cbPrealloc)
     239                           {
     240                               GlobalUnlock(hMem);
     241
     242                               /* The preallocated buffer is too small, adjust the size. */
     243                               hMem = GlobalReAlloc(hMem, cb, 0);
     244                               LogFlowFunc(("Reallocated hMem = %p\n", hMem));
     245
     246                               if (hMem)
     247                               {
     248                                   pMem = GlobalLock(hMem);
     249                                   LogFlowFunc(("Locked pMem = %p, GlobalSize = %ld\n", pMem, GlobalSize(hMem)));
     250
     251                                   if (pMem)
     252                                   {
     253                                       /* Read the host data to the preallocated buffer. */
     254                                       uint32_t cbNew = 0;
     255                                       rc = VbglR3ClipboardReadData(pCtx->u32ClientID, fFormat, pMem, cb, &cbNew);
     256                                       LogFlowFunc(("VbglR3ClipboardReadData returned with rc = %Rrc, cb = %d, cbNew = %d\n",
     257                                                    rc, cb, cbNew));
     258
     259                                       if (RT_SUCCESS(rc)
     260                                           && cbNew <= cb)
     261                                       {
     262                                           cb = cbNew;
     263                                       }
     264                                       else
     265                                       {
     266                                           GlobalUnlock(hMem);
     267                                           GlobalFree(hMem);
     268                                           hMem = NULL;
     269                                       }
     270                                   }
     271                                   else
     272                                   {
     273                                       GlobalFree(hMem);
     274                                       hMem = NULL;
     275                                   }
     276                               }
     277                           }
     278
     279                           if (hMem)
     280                           {
     281                               /* pMem is the address of the data. cb is the size of returned data. */
     282                               /* Verify the size of returned text, the memory block for clipboard
     283                                * must have the exact string size.
     284                                */
     285                               if (fFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     286                               {
     287                                   size_t cbActual = 0;
     288                                   HRESULT hrc = StringCbLengthW((LPWSTR)pMem, cb, &cbActual);
     289                                   if (FAILED(hrc))
     290                                   {
     291                                       /* Discard invalid data. */
     292                                       GlobalUnlock(hMem);
     293                                       GlobalFree(hMem);
     294                                       hMem = NULL;
     295                                   }
     296                                   else
     297                                   {
     298                                       /* cbActual is the number of bytes, excluding those used
     299                                        * for the terminating null character.
     300                                        */
     301                                       cb = (uint32_t)(cbActual + 2);
     302                                   }
     303                               }
     304                           }
     305
     306                           if (hMem)
     307                           {
     308                               GlobalUnlock(hMem);
     309
     310                               hMem = GlobalReAlloc(hMem, cb, 0);
     311                               LogFlowFunc(("Reallocated hMem = %p\n", hMem));
     312
     313                               if (hMem)
     314                               {
     315                                   /* 'hMem' contains the host clipboard data.
     316                                    * size is 'cb' and format is 'format'. */
     317                                   HANDLE hClip = SetClipboardData(cfFormat, hMem);
     318                                   LogFlowFunc(("WM_RENDERFORMAT hClip = %p\n", hClip));
     319
     320                                   if (hClip)
     321                                   {
     322                                       /* The hMem ownership has gone to the system. Finish the processing. */
     323                                       break;
     324                                   }
     325
     326                                   /* Cleanup follows. */
     327                               }
     328                           }
     329                       }
     330                       if (hMem)
     331                           GlobalUnlock(hMem);
     332                   }
     333                   if (hMem)
     334                       GlobalFree(hMem);
     335               }
     336           }
     337       }
     338       break;
     339
     340       case WM_RENDERALLFORMATS:
     341       {
     342           /* Do nothing. The clipboard formats will be unavailable now, because the
     343           * windows is to be destroyed and therefore the guest side becomes inactive.
     344           */
     345           int rc = VBoxClipboardWinOpen(hwnd);
     346           if (RT_SUCCESS(rc))
     347           {
    348348               VBoxClipboardWinClear();
    349349               VBoxClipboardWinClose();
    350             }
    351         }
    352         break;
    353 
    354         case VBOX_CLIPBOARD_WM_SET_FORMATS:
    355         {
     350           }
     351       }
     352       break;
     353
     354       case VBOX_CLIPBOARD_WM_SET_FORMATS:
     355       {
    356356           /* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
    357357           VBOXCLIPBOARDFORMATS fFormats = (uint32_t)lParam;
     
    389389               else if (fFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    390390               {
    391                    LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: VBOX_CLIPBOARD_WIN_REGFMT_URI_LIST\n"));
    392                    if (pWinCtx->URI.pDataObj == NULL) /* Only allow one transfer at a time. */
     391                   LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: VBOX_CLIPBOARD_WIN_REGFMT_URI_LIST cTransfers=%RU32\n",
     392                            pWinCtx->URI.cTransfers));
     393                   if (pWinCtx->URI.cTransfers == 0) /* Only allow one transfer at a time for now. */
    393394                   {
    394                        pWinCtx->URI.pDataObj = new VBoxClipboardWinDataObject(/* No additional formats needed right now */);
    395                        if (pWinCtx->URI.pDataObj)
     395                       pWinCtx->URI.Transfer.pDataObj = new VBoxClipboardWinDataObject(/* No additional formats needed right now */);
     396                       if (pWinCtx->URI.Transfer.pDataObj)
    396397                       {
    397                            rc = pWinCtx->URI.pDataObj->Init(pCtx->u32ClientID);
     398                           rc = pWinCtx->URI.Transfer.pDataObj->Init(pCtx->u32ClientID);
    398399                           if (RT_SUCCESS(rc))
    399400                           {
     
    405406                                *        OleSetClipboard() will fail. Needs fixing. */
    406407
    407                                HRESULT hr = OleSetClipboard(pWinCtx->URI.pDataObj);
    408                                if (FAILED(hr))
     408                               HRESULT hr = OleSetClipboard(pWinCtx->URI.Transfer.pDataObj);
     409                               if (SUCCEEDED(hr))
     410                               {
     411                                   pWinCtx->URI.cTransfers++;
     412                               }
     413                               else
    409414                                   LogRel(("Clipboard: Failed with %Rhrc when setting data object to clipboard\n", hr));
    410415                           }
     
    423428               LogFunc(("VBOX_WM_SHCLPB_SET_FORMATS: cfFormat=%u, lastErr=%ld\n", cfFormat, GetLastError()));
    424429           }
    425         }
    426         break;
    427 
    428         case VBOX_CLIPBOARD_WM_READ_DATA:
    429         {
    430             /* Send data in the specified format to the host. */
    431             uint32_t u32Formats = (uint32_t)lParam;
    432             HANDLE hClip = NULL;
    433 
    434             LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: u32Formats=0x%x\n", u32Formats));
    435 
    436             int rc = VBoxClipboardWinOpen(hwnd);
    437             if (RT_SUCCESS(rc))
    438             {
    439                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     430       }
     431       break;
     432
     433       case VBOX_CLIPBOARD_WM_READ_DATA:
     434       {
     435           /* Send data in the specified format to the host. */
     436           VBOXCLIPBOARDFORMAT uFormat = (uint32_t)lParam;
     437           HANDLE hClip = NULL;
     438
     439           LogFlowFunc(("VBOX_WM_SHCLPB_READ_DATA: uFormat=0x%x\n", uFormat));
     440
     441           int rc = VBoxClipboardWinOpen(hwnd);
     442           if (RT_SUCCESS(rc))
     443           {
     444               if (uFormat == VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    440445               {
    441446                   hClip = GetClipboardData(CF_DIB);
     
    455460                   }
    456461               }
    457                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     462               else if (uFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    458463               {
    459464                   hClip = GetClipboardData(CF_UNICODETEXT);
     
    473478                   }
    474479               }
    475                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
     480               else if (uFormat == VBOX_SHARED_CLIPBOARD_FMT_HTML)
    476481               {
    477482                   UINT format = RegisterClipboardFormat(VBOX_CLIPBOARD_WIN_REGFMT_HTML);
     
    497502               }
    498503#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    499                else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     504               else if (uFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
    500505               {
    501506                   /* The data data in CF_HDROP format, as the files are locally present and don't need to be
     
    507512                       if (hDrop)
    508513                       {
    509         /*                    vboxrc = VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST,
    510                                                              );*/
     514                           char *pszList;
     515                           size_t cbList;
     516                           rc = VBoxClipboardWinDropFilesToStringList((DROPFILES *)hDrop, &pszList, &cbList);
     517                           if (RT_SUCCESS(rc))
     518                           {
     519                               rc = VbglR3ClipboardWriteData(pCtx->u32ClientID, uFormat, pszList, (uint32_t)cbList);
     520                               RTMemFree(pszList);
     521                           }
     522
    511523                           GlobalUnlock(hClip);
    512524                       }
     
    518530               }
    519531#endif
     532               if (hClip == NULL)
     533               {
     534                   LogFunc(("VBOX_WM_SHCLPB_READ_DATA: hClip=NULL, lastError=%ld\n", GetLastError()));
     535
     536                   /* Requested clipboard format is not available, send empty data. */
     537                   VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_NONE, NULL, 0);
     538               }
     539
    520540               VBoxClipboardWinClose();
    521             }
    522 
    523             if (hClip == NULL)
    524             {
    525                /* Requested clipboard format is not available, send empty data. */
    526                VbglR3ClipboardWriteData(pCtx->u32ClientID, VBOX_SHARED_CLIPBOARD_FMT_NONE, NULL, 0);
    527             }
    528         }
    529         break;
    530 
    531         case WM_DESTROY:
    532         {
    533             VBoxClipboardWinRemoveFromCBChain(pWinCtx);
    534             if (pWinCtx->oldAPI.timerRefresh)
     541           }
     542       }
     543       break;
     544
     545       case WM_DESTROY:
     546       {
     547           VBoxClipboardWinRemoveFromCBChain(pWinCtx);
     548           if (pWinCtx->oldAPI.timerRefresh)
    535549               KillTimer(pWinCtx->hWnd, 0);
    536             /*
    537             * don't need to call PostQuitMessage cause
    538             * the VBoxTray already finished a message loop
    539             */
    540         }
    541         break;
    542 
    543         default:
    544         {
    545             lresultRc = DefWindowProc(hwnd, msg, wParam, lParam);
    546         }
    547         break;
     550           /*
     551           * don't need to call PostQuitMessage cause
     552           * the VBoxTray already finished a message loop
     553           */
     554       }
     555       break;
     556
     557       default:
     558       {
     559           lresultRc = DefWindowProc(hwnd, msg, wParam, lParam);
     560       }
     561       break;
    548562    }
    549563
     
    554568}
    555569
    556 static LRESULT CALLBACK vboxClipboardWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
     570static LRESULT CALLBACK vboxClipboardWinWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
    557571
    558572static int vboxClipboardCreateWindow(PVBOXCLIPBOARDCONTEXT pCtx)
     
    573587    {
    574588        wc.style         = CS_NOCLOSE;
    575         wc.lpfnWndProc   = vboxClipboardWndProc;
     589        wc.lpfnWndProc   = vboxClipboardWinWndProc;
    576590        wc.hInstance     = pCtx->pEnv->hInstance;
    577591        wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
     
    626640}
    627641
    628 static LRESULT CALLBACK vboxClipboardWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
     642static LRESULT CALLBACK vboxClipboardWinWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    629643{
    630644    PVBOXCLIPBOARDCONTEXT pCtx = &g_Ctx; /** @todo r=andy Make pCtx available through SetWindowLongPtr() / GWL_USERDATA. */
     
    632646
    633647    /* Forward with proper context. */
    634     return vboxClipboardProcessMsg(pCtx, hWnd, uMsg, wParam, lParam);
     648    return vboxClipboardWinProcessMsg(pCtx, hWnd, uMsg, wParam, lParam);
    635649}
    636650
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibClipboard.cpp

    r78315 r78581  
    499499        /*
    500500         * Send the (meta) data; in case of URIs it's the (non-recursive) file/directory
    501          * URI list the host needs to know upfront to set up the drag'n drop operation.
     501         * URI list the host needs to know upfront to set up the Shared Clipboard operation.
    502502         */
    503503        RTCString strRootDest = lstURI.GetRootEntries();
  • trunk/src/VBox/Additions/x11/VBoxClient/Makefile.kmk

    r78307 r78581  
    103103        clipboard.cpp
    104104 ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
    105   ifdef VBOX_WITH_LIBFUSE
     105 VBoxClient_SOURCES += \
     106        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIList.cpp \
     107        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardURIObject.cpp \
     108        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/ClipboardPath.cpp
     109  ifdef VBOX_WITH_LIBFUSE_DISABLED
    106110   VBoxClient_SOURCES += \
    107111        clipboard-fuse.cpp
     
    170174
    171175include $(FILE_KBUILD_SUB_FOOTER)
    172 
  • trunk/src/VBox/Additions/x11/VBoxClient/clipboard.cpp

    r78346 r78581  
    181181 * @returns VBox status code
    182182 */
    183 int vboxClipboardConnect(void)
     183int VBoxClipboardSvcImplConnect(void)
    184184{
    185185    int rc = VINF_SUCCESS;
     
    294294    if (RT_FAILURE(rc))
    295295        VBClFatalError(("Failed to connect to the VirtualBox kernel service, rc=%Rrc\n", rc));
    296     rc = vboxClipboardConnect();
     296    rc = VBoxClipboardSvcImplConnect();
    297297    /* Not RT_SUCCESS: VINF_PERMISSION_DENIED is host service not present. */
    298298    if (rc == VINF_SUCCESS)
  • trunk/src/VBox/GuestHost/SharedClipboard/ClipboardCache.cpp

    r78501 r78581  
    7575uint16_t SharedClipboardCache::AddRef(void)
    7676{
    77     return ASMAtomicIncU16(&m_cRefs);
     77    return ASMAtomicIncU32(&m_cRefs);
    7878}
    7979
     
    8686{
    8787    Assert(m_cRefs);
    88     return ASMAtomicDecU16(&m_cRefs);
     88    return ASMAtomicDecU32(&m_cRefs);
    8989}
    9090
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp

    r78501 r78581  
    594594/**
    595595 * Converts a DROPFILES (HDROP) structure to a string list, separated by \r\n.
     596 * Does not do any locking on the input data.
    596597 *
    597598 * @returns VBox status code.
    598599 * @param   pDropFiles          Pointer to DROPFILES structure to convert.
    599  * @param   ppvData             Where to return the converted (allocated) data on success.
     600 * @param   ppszData            Where to return the converted (allocated) data on success.
     601 *                              Must be free'd by the caller with RTMemFree().
    600602 * @param   pcbData             Size (in bytes) of the allocated data returned.
    601603 */
    602 int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, void **ppvData, size_t *pcbData)
     604int VBoxClipboardWinDropFilesToStringList(DROPFILES *pDropFiles, char **ppszbData, size_t *pcbData)
    603605{
    604606    AssertPtrReturn(pDropFiles, VERR_INVALID_POINTER);
    605     AssertPtrReturn(ppvData,    VERR_INVALID_POINTER);
     607    AssertPtrReturn(ppszbData,  VERR_INVALID_POINTER);
    606608    AssertPtrReturn(pcbData,    VERR_INVALID_POINTER);
    607609
     
    725727                memcpy(pvData, strRoot.c_str(), cbRoot);
    726728
    727                 *ppvData = pvData;
    728                 *pcbData = cbRoot;
     729                *ppszbData = (char *)pvData;
     730                *pcbData   = cbRoot;
    729731            }
    730732            else
  • trunk/src/VBox/GuestHost/SharedClipboard/clipboard-x11.cpp

    r78161 r78581  
    7575*   Structures and Typedefs                                                                                                      *
    7676*********************************************************************************************************************************/
    77 /** The different clipboard formats which we support. */
    78 enum CLIPFORMAT
    79 {
    80     INVALID = 0,
    81     TARGETS,
    82     TEXT,  /* Treat this as Utf8, but it may really be ascii */
    83     UTF8,
    84     BMP,
    85     HTML
    86 };
    87 
    88 typedef unsigned CLIPX11FORMAT;
     77/** The different X11 clipboard format targets. */
     78typedef enum _CLIPX11FORMATTARGET
     79{
     80    CLIPX11FORMATTARGET_INVALID = 0,
     81    CLIPX11FORMATTARGET_TARGETS,
     82    CLIPX11FORMATTARGET_TEXT,  /* Treat this as Utf8, but it may really be ascii */
     83    CLIPX11FORMATTARGET_UTF8,
     84    CLIPX11FORMATTARGET_BMP,
     85    CLIPX11FORMATTARGET_HTML,
     86#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     87    CLIPX11FORMATTARGET_URI_LIST
     88#endif
     89} CLIPX11FORMATTARGET;
     90
     91/** Index into the format array. */
     92typedef unsigned CLIPX11FORMATIDX;
    8993
    9094
     
    101105/** The table mapping X11 names to data formats and to the corresponding
    102106 * VBox clipboard formats (currently only Unicode) */
    103 static struct _CLIPFORMATTABLE
    104 {
    105     /** The X11 atom name of the format (several names can match one format)
    106      */
     107static struct _CLIPX11FORMATTABLE
     108{
     109    /** The X11 atom name of the format (several names can match one format) */
    107110    const char *pcszAtom;
    108     /** The format corresponding to the name */
    109     CLIPFORMAT  enmFormat;
     111    /** The format target corresponding to the atom name */
     112    CLIPX11FORMATTARGET enmTarget;
    110113    /** The corresponding VBox clipboard format */
    111     uint32_t    u32VBoxFormat;
     114    VBOXCLIPBOARDFORMAT vboxFormat;
    112115} g_aFormats[] =
    113116{
    114     { "INVALID", INVALID, 0 },
    115     { "UTF8_STRING", UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
    116     { "text/plain;charset=UTF-8", UTF8,
    117       VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
    118     { "text/plain;charset=utf-8", UTF8,
    119       VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
    120     { "STRING", TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
    121     { "TEXT", TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
    122     { "text/plain", TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
    123     { "text/html", HTML, VBOX_SHARED_CLIPBOARD_FMT_HTML },
    124     { "text/html;charset=utf-8", HTML,
    125       VBOX_SHARED_CLIPBOARD_FMT_HTML },
    126     { "image/bmp", BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
    127     { "image/x-bmp", BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
    128     { "image/x-MS-bmp", BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP }
    129 
    130 
     117    { "INVALID", CLIPX11FORMATTARGET_INVALID, 0 },
     118    { "UTF8_STRING", CLIPX11FORMATTARGET_UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     119    { "text/plain;charset=UTF-8", CLIPX11FORMATTARGET_UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     120    { "text/plain;charset=utf-8", CLIPX11FORMATTARGET_UTF8, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     121    { "STRING", CLIPX11FORMATTARGET_TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     122    { "TEXT", CLIPX11FORMATTARGET_TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     123    { "text/plain", CLIPX11FORMATTARGET_TEXT, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT },
     124    { "text/html", CLIPX11FORMATTARGET_HTML, VBOX_SHARED_CLIPBOARD_FMT_HTML },
     125    { "text/html;charset=utf-8", CLIPX11FORMATTARGET_HTML, VBOX_SHARED_CLIPBOARD_FMT_HTML },
     126    { "image/bmp", CLIPX11FORMATTARGET_BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
     127    { "image/x-bmp", CLIPX11FORMATTARGET_BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
     128    { "image/x-MS-bmp", CLIPX11FORMATTARGET_BMP, VBOX_SHARED_CLIPBOARD_FMT_BITMAP },
     129#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     130    { "text/uri-list", CLIPX11FORMATTARGET_URI_LIST, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST },
     131    { "x-special/gnome-copied-files", CLIPX11FORMATTARGET_URI_LIST, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST }
     132#endif
    131133    /** @todo Inkscape exports image/png but not bmp... */
    132134};
     
    134136enum
    135137{
    136     NIL_CLIPX11FORMAT = 0,
    137     MAX_CLIP_X11_FORMATS = RT_ELEMENTS(g_aFormats)
     138    CLIPX11FORMATIDX_NIL = 0,
     139    CLIPX11FORMATIDX_MAX = RT_ELEMENTS(g_aFormats)
    138140};
    139141
    140142
    141 /** Return the atom corresponding to a supported X11 format.
     143/** Returnx the atom name corresponding to a supported X11 format index.
    142144 * @param widget a valid Xt widget
    143145 */
    144 static Atom clipAtomForX11Format(CLIPBACKEND *pCtx, CLIPX11FORMAT format)
    145 {
    146     return clipGetAtom(pCtx, g_aFormats[format].pcszAtom);
    147 }
    148 
    149 /** Return the CLIPFORMAT corresponding to a supported X11 format. */
    150 static CLIPFORMAT clipRealFormatForX11Format(CLIPX11FORMAT format)
    151 {
    152     return g_aFormats[format].enmFormat;
    153 }
    154 
    155 /** Return the atom corresponding to a supported X11 format. */
    156 static uint32_t clipVBoxFormatForX11Format(CLIPX11FORMAT format)
    157 {
    158     return g_aFormats[format].u32VBoxFormat;
    159 }
    160 
    161 /** Lookup the X11 format matching a given X11 atom.
    162  * @returns the format on success, NIL_CLIPX11FORMAT on failure
     146static Atom clipGetAtomFromFmtIdx(CLIPBACKEND *pCtx, CLIPX11FORMATIDX formatIdx)
     147{
     148    return clipGetAtom(pCtx, g_aFormats[formatIdx].pcszAtom);
     149}
     150
     151/** Returns the format target corresponding to a supported X11 format index. */
     152static CLIPX11FORMATTARGET clipGetTargetFmtFromFmtIdx(CLIPX11FORMATIDX formatIdx)
     153{
     154    return g_aFormats[formatIdx].enmTarget;
     155}
     156
     157/** Returns the VBox format corresponding to a supported X11 format index. */
     158static VBOXCLIPBOARDFORMAT clipGetVBoxFmtFromFmtIdx(CLIPX11FORMATIDX formatIdx)
     159{
     160    return g_aFormats[formatIdx].vboxFormat;
     161}
     162
     163/**
     164 * Looks up the X11 format index matching a given X11 atom.
     165 *
     166 * @returns the format on success, CLIPX11FORMATIDX_NIL on failure.
    163167 * @param   widget a valid Xt widget
    164168 */
    165 static CLIPX11FORMAT clipFindX11FormatByAtom(CLIPBACKEND *pCtx, Atom atomFormat)
     169static CLIPX11FORMATIDX clipGetFmtIdxFromAtom(CLIPBACKEND *pCtx, Atom atomFormat)
    166170{
    167171    for (unsigned i = 0; i < RT_ELEMENTS(g_aFormats); ++i)
    168         if (clipAtomForX11Format(pCtx, i) == atomFormat)
     172        if (clipGetAtomFromFmtIdx(pCtx, i) == atomFormat)
    169173            return i;
    170     return NIL_CLIPX11FORMAT;
     174    return CLIPX11FORMATIDX_NIL;
    171175}
    172176
     
    176180 * @param   widget a valid Xt widget
    177181 */
    178 static CLIPX11FORMAT clipFindX11FormatByAtomText(const char *pcsz)
     182static CLIPX11FORMATIDX clipGetFmtIdxFromAtomText(const char *pcsz)
    179183{
    180184    for (unsigned i = 0; i < RT_ELEMENTS(g_aFormats); ++i)
    181185        if (!strcmp(g_aFormats[i].pcszAtom, pcsz))
    182186            return i;
    183     return NIL_CLIPX11FORMAT;
    184 }
    185 #endif
    186 
    187 /**
    188  * Enumerates supported X11 clipboard formats corresponding to a given VBox
    189  * format.
     187    return CLIPX11FORMATIDX_NIL;
     188}
     189#endif
     190
     191/**
     192 * Enumerates supported X11 clipboard formats corresponding to a given VBox format.
     193 *
    190194 * @returns the next matching X11 format in the list, or NIL_CLIPX11FORMAT if
    191195 *          there are no more
    192  * @param lastFormat  The value returned from the last call of this function.
    193  *                    Use NIL_CLIPX11FORMAT to start the enumeration.
    194  */
    195 static CLIPX11FORMAT clipEnumX11Formats(uint32_t u32VBoxFormats,
    196                                         CLIPX11FORMAT lastFormat)
    197 {
    198     for (unsigned i = lastFormat + 1; i < RT_ELEMENTS(g_aFormats); ++i)
    199         if (u32VBoxFormats & clipVBoxFormatForX11Format(i))
     196 * @param lastFmtIdx  The format index returned from the last call of this function.
     197 *                    Use CLIPX11FORMATIDX_NIL to start the enumeration.
     198 */
     199static CLIPX11FORMATIDX clipEnumFmtIdxForVBoxFmt(VBOXCLIPBOARDFORMAT vboxFormat,
     200                                                 CLIPX11FORMATIDX lastFmtIdx)
     201{
     202    for (unsigned i = lastFmtIdx + 1; i < RT_ELEMENTS(g_aFormats); ++i)
     203        if (vboxFormat & clipGetVBoxFmtFromFmtIdx(i))
    200204            return i;
    201     return NIL_CLIPX11FORMAT;
     205    return CLIPX11FORMATIDX_NIL;
    202206}
    203207
     
    222226    /** The best text format X11 has to offer, as an index into the formats
    223227     * table */
    224     CLIPX11FORMAT X11TextFormat;
     228    CLIPX11FORMATIDX X11TextFmtIdx;
    225229    /** The best bitmap format X11 has to offer, as an index into the formats
    226230     * table */
    227     CLIPX11FORMAT X11BitmapFormat;
     231    CLIPX11FORMATIDX X11BitmapFmtIdx;
    228232    /** The best HTML format X11 has to offer, as an index into the formats
    229233     * table */
    230     CLIPX11FORMAT X11HTMLFormat;
     234    CLIPX11FORMATIDX X11HTMLFmtIdx;
     235#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     236    /** The best URI list format X11 has to offer, as an index into the formats
     237     * table */
     238    CLIPX11FORMATIDX X11URListFmtIdx;
     239#endif
    231240    /** What formats does VBox have on offer? */
    232     uint32_t vboxFormats;
     241    VBOXCLIPBOARDFORMATS vboxFormats;
    233242    /** Cache of the last unicode data that we received */
    234243    void *pvUnicodeCache;
     
    358367                    (XtPointer)client_data);
    359368    ssize_t cbWritten = write(pCtx->wakeupPipeWrite, WAKE_UP_STRING, WAKE_UP_STRING_LEN);
    360     NOREF(cbWritten);
     369    RT_NOREF(cbWritten);
    361370#else
    362     RT_NOREF1(pCtx);
     371    RT_NOREF(pCtx);
    363372    testQueueToEventThread(proc, client_data);
    364373#endif
     
    370379static void clipReportFormatsToVBox(CLIPBACKEND *pCtx)
    371380{
    372     uint32_t u32VBoxFormats = clipVBoxFormatForX11Format(pCtx->X11TextFormat);
    373     u32VBoxFormats |= clipVBoxFormatForX11Format(pCtx->X11BitmapFormat);
    374     u32VBoxFormats |= clipVBoxFormatForX11Format(pCtx->X11HTMLFormat);
    375     LogRelFlowFunc(("clipReportFormatsToVBox format: %d\n", u32VBoxFormats));
    376     LogRelFlowFunc(("clipReportFormatsToVBox txt: %d, bitm: %d, html:%d, u32VBoxFormats: %d\n",
    377                     pCtx->X11TextFormat, pCtx->X11BitmapFormat, pCtx->X11HTMLFormat,
    378                     u32VBoxFormats ));
    379     ClipReportX11Formats(pCtx->pFrontend, u32VBoxFormats);
     381    VBOXCLIPBOARDFORMATS vboxFormats = clipGetVBoxFmtFromFmtIdx(pCtx->X11TextFmtIdx);
     382    vboxFormats |= clipGetVBoxFmtFromFmtIdx(pCtx->X11BitmapFmtIdx);
     383    vboxFormats |= clipGetVBoxFmtFromFmtIdx(pCtx->X11HTMLFmtIdx);
     384
     385    LogRelFlowFunc(("clipReportFormatsToVBox formats: 0x%x\n", vboxFormats));
     386    LogRelFlowFunc(("clipReportFormatsToVBox txt: %d, bitm: %d, html:%d, vboxFormat: %d\n",
     387                    pCtx->X11TextFmtIdx, pCtx->X11BitmapFmtIdx, pCtx->X11HTMLFmtIdx,
     388                    vboxFormats));
     389
     390    ClipReportX11Formats(pCtx->pFrontend, vboxFormats);
    380391}
    381392
     
    385396static void clipResetX11Formats(CLIPBACKEND *pCtx)
    386397{
    387     pCtx->X11TextFormat = INVALID;
    388     pCtx->X11BitmapFormat = INVALID;
    389     pCtx->X11HTMLFormat = INVALID;
     398    pCtx->X11TextFmtIdx   = CLIPX11FORMATIDX_NIL;
     399    pCtx->X11BitmapFmtIdx = CLIPX11FORMATIDX_NIL;
     400    pCtx->X11HTMLFmtIdx   = CLIPX11FORMATIDX_NIL;
     401#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     402    pCtx->X11URListFmtIdx = CLIPX11FORMATIDX_NIL;
     403#endif
    390404}
    391405
     
    397411}
    398412
    399 /**
    400  * Go through an array of X11 clipboard targets to see if they contain a text
     413#ifdef TESTCASE
     414static bool clipTestTextFormatConversion(CLIPBACKEND *pCtx)
     415{
     416    bool success = true;
     417    CLIPX11FORMAT targets[2];
     418    CLIPX11FORMAT x11Format;
     419    targets[0] = clipGetFmtIdxFromAtomText("text/plain");
     420    targets[1] = clipGetFmtIdxFromAtomText("image/bmp");
     421    x11Format = clipGetTextFormatFromTargets(pCtx, targets, 2);
     422    if (clipGetTargetFmtFromFmtIdx(x11Format) != TEXT)
     423        success = false;
     424    targets[0] = clipGetFmtIdxFromAtomText("UTF8_STRING");
     425    targets[1] = clipGetFmtIdxFromAtomText("text/plain");
     426    x11Format = clipGetTextFormatFromTargets(pCtx, targets, 2);
     427    if (clipGetTargetFmtFromFmtIdx(x11Format) != UTF8)
     428        success = false;
     429    return success;
     430}
     431#endif
     432
     433/**
     434 * Go through an array of X11 clipboard targets to see if they contain a bitmap
    401435 * format we can support, and if so choose the ones we prefer (e.g. we like
    402  * Utf8 better than plain text).
     436 * BMP better than PNG because we don't have to convert).
     437 *
    403438 * @param  pCtx      the clipboard backend context structure
    404439 * @param  pTargets  the list of targets
    405440 * @param  cTargets  the size of the list in @a pTargets
    406441 */
    407 static CLIPX11FORMAT clipGetTextFormatFromTargets(CLIPBACKEND *pCtx,
    408                                                   CLIPX11FORMAT *pTargets,
    409                                                   size_t cTargets)
    410 {
    411     CLIPX11FORMAT bestTextFormat = NIL_CLIPX11FORMAT;
    412     CLIPFORMAT enmBestTextTarget = INVALID;
    413     AssertPtrReturn(pCtx, NIL_CLIPX11FORMAT);
    414     AssertReturn(VALID_PTR(pTargets) || cTargets == 0, NIL_CLIPX11FORMAT);
     442static CLIPX11FORMATIDX clipGetBestFmtIdxFromTargets(CLIPBACKEND *pCtx,
     443                                                     VBOXCLIPBOARDFORMAT vboxFormat,
     444                                                     CLIPX11FORMATIDX   *paTargets, size_t cTargets)
     445{
     446    AssertPtrReturn(pCtx, CLIPX11FORMATIDX_NIL);
     447    AssertReturn(VALID_PTR(paTargets) || cTargets == 0, CLIPX11FORMATIDX_NIL);
     448
     449    CLIPX11FORMATIDX    bestFmtIdx    = CLIPX11FORMATIDX_NIL;
     450    CLIPX11FORMATTARGET enmBestTarget = CLIPX11FORMATTARGET_INVALID;
     451
    415452    for (unsigned i = 0; i < cTargets; ++i)
    416453    {
    417         CLIPX11FORMAT format = pTargets[i];
    418         if (format != NIL_CLIPX11FORMAT)
    419         {
    420             if (   (clipVBoxFormatForX11Format(format)
    421                             == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    422                     && enmBestTextTarget < clipRealFormatForX11Format(format))
     454        CLIPX11FORMATIDX format = paTargets[i];
     455        if (format != CLIPX11FORMATIDX_NIL)
     456        {
     457            if (   (clipGetVBoxFmtFromFmtIdx(format) == vboxFormat)
     458                && enmBestTarget < clipGetTargetFmtFromFmtIdx(format))
    423459            {
    424                 enmBestTextTarget = clipRealFormatForX11Format(format);
    425                 bestTextFormat = format;
     460                enmBestTarget = clipGetTargetFmtFromFmtIdx(format);
     461                bestFmtIdx = format;
    426462            }
    427463        }
    428464    }
    429     return bestTextFormat;
    430 }
    431 
    432 #ifdef TESTCASE
    433 static bool clipTestTextFormatConversion(CLIPBACKEND *pCtx)
    434 {
    435     bool success = true;
    436     CLIPX11FORMAT targets[2];
    437     CLIPX11FORMAT x11Format;
    438     targets[0] = clipFindX11FormatByAtomText("text/plain");
    439     targets[1] = clipFindX11FormatByAtomText("image/bmp");
    440     x11Format = clipGetTextFormatFromTargets(pCtx, targets, 2);
    441     if (clipRealFormatForX11Format(x11Format) != TEXT)
    442         success = false;
    443     targets[0] = clipFindX11FormatByAtomText("UTF8_STRING");
    444     targets[1] = clipFindX11FormatByAtomText("text/plain");
    445     x11Format = clipGetTextFormatFromTargets(pCtx, targets, 2);
    446     if (clipRealFormatForX11Format(x11Format) != UTF8)
    447         success = false;
    448     return success;
    449 }
    450 #endif
    451 
    452 /**
    453  * Go through an array of X11 clipboard targets to see if they contain a bitmap
    454  * format we can support, and if so choose the ones we prefer (e.g. we like
    455  * BMP better than PNG because we don't have to convert).
     465    return bestFmtIdx;
     466}
     467
     468/**
     469 * Go through an array of X11 clipboard targets to see if we can support any
     470 * of them and if relevant to choose the ones we prefer (e.g. we like Utf8
     471 * better than plain text).
     472 *
    456473 * @param  pCtx      the clipboard backend context structure
    457474 * @param  pTargets  the list of targets
    458475 * @param  cTargets  the size of the list in @a pTargets
    459476 */
    460 static CLIPX11FORMAT clipGetBitmapFormatFromTargets(CLIPBACKEND *pCtx,
    461                                                     CLIPX11FORMAT *pTargets,
    462                                                     size_t cTargets)
    463 {
    464     CLIPX11FORMAT bestBitmapFormat = NIL_CLIPX11FORMAT;
    465     CLIPFORMAT enmBestBitmapTarget = INVALID;
    466     AssertPtrReturn(pCtx, NIL_CLIPX11FORMAT);
    467     AssertReturn(VALID_PTR(pTargets) || cTargets == 0, NIL_CLIPX11FORMAT);
    468     for (unsigned i = 0; i < cTargets; ++i)
    469     {
    470         CLIPX11FORMAT format = pTargets[i];
    471         if (format != NIL_CLIPX11FORMAT)
    472         {
    473             if (   (clipVBoxFormatForX11Format(format)
    474                             == VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    475                     && enmBestBitmapTarget < clipRealFormatForX11Format(format))
    476             {
    477                 enmBestBitmapTarget = clipRealFormatForX11Format(format);
    478                 bestBitmapFormat = format;
    479             }
    480         }
    481     }
    482     return bestBitmapFormat;
    483 }
    484 
    485 /**
    486  * Go through an array of X11 clipboard targets to see if they contain a HTML
    487  * format we can support, and if so choose the ones we prefer
    488  * @param  pCtx      the clipboard backend context structure
    489  * @param  pTargets  the list of targets
    490  * @param  cTargets  the size of the list in @a pTargets
    491  */
    492 static CLIPX11FORMAT clipGetHtmlFormatFromTargets(CLIPBACKEND *pCtx,
    493                                                   CLIPX11FORMAT *pTargets,
    494                                                   size_t cTargets)
    495 {
    496     CLIPX11FORMAT bestHTMLFormat = NIL_CLIPX11FORMAT;
    497     CLIPFORMAT enmBestHtmlTarget = INVALID;
    498     AssertPtrReturn(pCtx, NIL_CLIPX11FORMAT);
    499     AssertReturn(VALID_PTR(pTargets) || cTargets == 0, NIL_CLIPX11FORMAT);
    500     for (unsigned i = 0; i < cTargets; ++i)
    501     {
    502         CLIPX11FORMAT format = pTargets[i];
    503         if (format != NIL_CLIPX11FORMAT)
    504         {
    505             if (   (clipVBoxFormatForX11Format(format) == VBOX_SHARED_CLIPBOARD_FMT_HTML)
    506                 && enmBestHtmlTarget < clipRealFormatForX11Format(format))
    507             {
    508                 enmBestHtmlTarget = clipRealFormatForX11Format(format);
    509                 bestHTMLFormat = format;
    510             }
    511         }
    512     }
    513     return bestHTMLFormat;
    514 }
    515 
    516 
    517 /**
    518  * Go through an array of X11 clipboard targets to see if we can support any
    519  * of them and if relevant to choose the ones we prefer (e.g. we like Utf8
    520  * better than plain text).
    521  * @param  pCtx      the clipboard backend context structure
    522  * @param  pTargets  the list of targets
    523  * @param  cTargets  the size of the list in @a pTargets
    524  */
    525477static void clipGetFormatsFromTargets(CLIPBACKEND *pCtx,
    526                                       CLIPX11FORMAT *pTargets, size_t cTargets)
     478                                      CLIPX11FORMATIDX *paTargets, size_t cTargets)
    527479{
    528480    AssertPtrReturnVoid(pCtx);
    529     AssertPtrReturnVoid(pTargets);
    530     CLIPX11FORMAT bestTextFormat;
    531     CLIPX11FORMAT bestBitmapFormat;
    532     CLIPX11FORMAT bestHtmlFormat;
    533     bestTextFormat = clipGetTextFormatFromTargets(pCtx, pTargets, cTargets);
    534     if (pCtx->X11TextFormat != bestTextFormat)
    535     {
    536         pCtx->X11TextFormat = bestTextFormat;
    537     }
    538     pCtx->X11BitmapFormat = INVALID;  /* not yet supported */
    539     bestBitmapFormat = clipGetBitmapFormatFromTargets(pCtx, pTargets, cTargets);
    540     if (pCtx->X11BitmapFormat != bestBitmapFormat)
    541     {
    542         pCtx->X11BitmapFormat = bestBitmapFormat;
    543     }
    544     bestHtmlFormat = clipGetHtmlFormatFromTargets(pCtx, pTargets, cTargets);
    545     if(pCtx->X11HTMLFormat != bestHtmlFormat)
    546     {
    547         pCtx->X11HTMLFormat = bestHtmlFormat;
    548     }
     481    AssertPtrReturnVoid(paTargets);
     482
     483    CLIPX11FORMATIDX bestFmtIdx = clipGetBestFmtIdxFromTargets(pCtx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
     484                                                               paTargets, cTargets);
     485    if (pCtx->X11TextFmtIdx != bestFmtIdx)
     486        pCtx->X11TextFmtIdx = bestFmtIdx;
     487
     488    pCtx->X11BitmapFmtIdx = CLIPX11FORMATIDX_NIL;  /* not yet supported */
     489    bestFmtIdx = clipGetBestFmtIdxFromTargets(pCtx, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, paTargets, cTargets);
     490    if (pCtx->X11BitmapFmtIdx != bestFmtIdx)
     491        pCtx->X11BitmapFmtIdx = bestFmtIdx;
     492
     493    bestFmtIdx = clipGetBestFmtIdxFromTargets(pCtx, VBOX_SHARED_CLIPBOARD_FMT_HTML, paTargets, cTargets);
     494    if(pCtx->X11HTMLFmtIdx != bestFmtIdx)
     495        pCtx->X11HTMLFmtIdx = bestFmtIdx;
     496
     497#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     498    bestFmtIdx = clipGetBestFmtIdxFromTargets(pCtx, VBOX_SHARED_CLIPBOARD_FMT_URI_LIST, paTargets, cTargets);
     499    if(pCtx->X11URListFmtIdx != bestFmtIdx)
     500        pCtx->X11URListFmtIdx = bestFmtIdx;
     501#endif
    549502}
    550503
     
    554507 * Update the context's information about targets currently supported by X11,
    555508 * based on an array of X11 atoms.
     509 *
    556510 * @param  pCtx      the context to be updated
    557511 * @param  pTargets  the array of atoms describing the targets supported
    558512 * @param  cTargets  the size of the array @a pTargets
    559513 */
    560 static void clipUpdateX11Targets(CLIPBACKEND *pCtx, CLIPX11FORMAT *pTargets,
    561                                  size_t cTargets)
    562 {
    563     LogRel2 (("%s: called\n", __FUNCTION__));
     514static void clipUpdateX11Targets(CLIPBACKEND *pCtx, CLIPX11FORMATIDX *paTargetFmtIdx, size_t cTargets)
     515{
     516    LogRel2(("Shared clipboard: clipUpdateX11Targets called\n"));
     517
    564518#ifndef VBOX_AFTER_5_2
    565519    pCtx->fBusy = false;
     
    572526    }
    573527#endif
    574     if (pTargets == NULL) {
     528
     529    if (paTargetFmtIdx == NULL)
     530    {
    575531        /* No data available */
    576532        clipReportEmptyX11CB(pCtx);
    577533        return;
    578534    }
    579     clipGetFormatsFromTargets(pCtx, pTargets, cTargets);
     535
     536    clipGetFormatsFromTargets(pCtx, paTargetFmtIdx, cTargets);
    580537    clipReportFormatsToVBox(pCtx);
    581538}
     
    588545 *        unit test.  So keep it simple, be paranoid and log everything.
    589546 */
    590 static void clipConvertX11Targets(Widget widget, XtPointer pClientData,
     547static void clipConvertX11Targets(Widget widget, XtPointer pSvcCtxData,
    591548                                  Atom * /* selection */, Atom *atomType,
    592549                                  XtPointer pValue, long unsigned int *pcLen,
    593550                                  int *piFormat)
    594551{
    595     RT_NOREF1(piFormat);
    596     CLIPBACKEND *pCtx = reinterpret_cast<CLIPBACKEND *>(pClientData);
     552    RT_NOREF(piFormat);
     553
     554    CLIPBACKEND *pCtx = reinterpret_cast<CLIPBACKEND *>(pSvcCtxData);
    597555    Atom *pAtoms = (Atom *)pValue;
    598556    unsigned i, j;
    599     LogRel2(("%s: pValue=%p, *pcLen=%u, *atomType=%d%s\n", __FUNCTION__,
     557
     558    LogRel2(("Shared clipboard: pValue=%p, *pcLen=%u, *atomType=%d%s\n",
    600559             pValue, *pcLen, *atomType,
    601560             *atomType == XT_CONVERT_FAIL ? " (XT_CONVERT_FAIL)" : ""));
    602     CLIPX11FORMAT *pFormats = NULL;
     561
     562    CLIPX11FORMATIDX *paFmtIdx = NULL;
     563
    603564    if (*pcLen && pValue && (*atomType != XT_CONVERT_FAIL /* time out */))
    604         pFormats = (CLIPX11FORMAT *)RTMemAllocZ(*pcLen * sizeof(CLIPX11FORMAT));
     565        paFmtIdx = (CLIPX11FORMATIDX *)RTMemAllocZ(*pcLen * sizeof(CLIPX11FORMATIDX));
     566
    605567#if defined(DEBUG) && !defined(TESTCASE)
    606568    if (pValue)
    607569    {
    608570        for (i = 0; i < *pcLen; ++i)
     571        {
    609572            if (pAtoms[i])
    610573            {
    611574                char *pszName = XGetAtomName(XtDisplay(widget), pAtoms[i]);
    612                 LogRel2(("%s: found target %s\n", __FUNCTION__,
    613                          pszName));
     575                LogRel(("Shared clipboard: Found target %s\n", pszName));
    614576                XFree(pszName);
    615577            }
    616578            else
    617                 LogRel2(("%s: found empty target.\n", __FUNCTION__));
    618     }
    619 #endif
    620     if (pFormats)
     579                LogRel(("Shared clipboard: Found empty target\n"));
     580        }
     581    }
     582#endif
     583
     584    if (paFmtIdx)
    621585    {
    622586        for (i = 0; i < *pcLen; ++i)
     
    624588            for (j = 0; j < RT_ELEMENTS(g_aFormats); ++j)
    625589            {
    626                 Atom target = XInternAtom(XtDisplay(widget),
    627                                           g_aFormats[j].pcszAtom, False);
     590                Atom target = XInternAtom(XtDisplay(widget), g_aFormats[j].pcszAtom, False);
    628591                if (*(pAtoms + i) == target)
    629                     pFormats[i] = j;
     592                    paFmtIdx[i] = j;
    630593            }
    631594#if defined(DEBUG) && !defined(TESTCASE)
    632             LogRel2(("%s: reporting format %d (%s)\n", __FUNCTION__,
    633                      pFormats[i], g_aFormats[pFormats[i]].pcszAtom));
     595            LogRel(("Shared clipboard: Reporting format %d (%s)\n",
     596                    paFmtIdx[i], g_aFormats[paFmtIdx[i]].pcszAtom));
    634597#endif
    635598        }
    636599    }
    637600    else
    638         LogRel2(("%s: reporting empty targets (none reported or allocation failure).\n",
    639                  __FUNCTION__));
    640     clipUpdateX11Targets(pCtx, pFormats, *pcLen);
    641     RTMemFree(pFormats);
     601        LogRel2(("Shared clipboard: Reporting empty targets (none reported or allocation failure)\n"));
     602
     603    clipUpdateX11Targets(pCtx, paFmtIdx, *pcLen);
     604
     605    RTMemFree(paFmtIdx);
    642606    XtFree(reinterpret_cast<char *>(pValue));
    643607}
     
    652616static void clipQueryX11CBFormats(CLIPBACKEND *pCtx)
    653617{
    654     LogRel2 (("%s: requesting the targets that the X11 clipboard offers\n",
    655            __PRETTY_FUNCTION__));
     618    LogRel2 (("Shared clipboard: Requesting the targets that the X11 clipboard offers\n"));
     619
    656620#ifndef VBOX_AFTER_5_2
    657621    if (pCtx->fBusy)
     
    718682static DECLCALLBACK(int) clipEventThread(RTTHREAD hThreadSelf, void *pvUser)
    719683{
    720     RT_NOREF1(hThreadSelf);
     684    RT_NOREF(hThreadSelf);
     685
    721686    LogRel(("Shared clipboard: Starting shared clipboard thread\n"));
    722687
     
    725690    if (pCtx->fGrabClipboardOnStart)
    726691        clipQueryX11CBFormats(pCtx);
     692
    727693    while (XtAppGetExitFlag(pCtx->appContext) == FALSE)
    728694    {
     
    730696        XtAppProcessEvent(pCtx->appContext, XtIMAll);
    731697    }
     698
    732699    LogRel(("Shared clipboard: Shared clipboard thread terminated successfully\n"));
    733700    return VINF_SUCCESS;
     
    764731static void clipStopEventThreadWorker(void *pUserData, void *)
    765732{
    766 
    767733    CLIPBACKEND *pCtx = (CLIPBACKEND *)pUserData;
    768734
     
    829795#endif
    830796
    831 /** This is the callback which is scheduled when data is available on the
    832  * wakeup pipe.  It simply reads all data from the pipe. */
     797/**
     798 * This is the callback which is scheduled when data is available on the
     799 * wakeup pipe.  It simply reads all data from the pipe.
     800 */
    833801static void clipDrainWakeupPipe(XtPointer pUserData, int *, XtInputId *)
    834802{
     
    836804    char acBuf[WAKE_UP_STRING_LEN];
    837805
    838     LogRel2(("clipDrainWakeupPipe: called\n"));
     806    LogRel2(("Shared clipboard: clipDrainWakeupPipe called\n"));
     807
    839808    while (read(pCtx->wakeupPipeRead, acBuf, sizeof(acBuf)) > 0) {}
    840809}
    841810
    842 /** X11 specific initialisation for the shared clipboard.
     811/**
     812 * X11 specific initialisation for the shared clipboard.
     813 *
    843814 * @note  X11 backend code.
    844815 */
     
    861832    if (NULL == pDisplay)
    862833    {
    863         LogRel(("Shared clipboard: Failed to connect to the X11 clipboard - the window system may not be running.\n"));
     834        LogRel(("Shared clipboard: Failed to connect to the X11 clipboard - the window system may not be running\n"));
    864835        rc = VERR_NOT_SUPPORTED;
    865836    }
     
    869840        rc = clipLoadXFixes(pDisplay, pCtx);
    870841        if (RT_FAILURE(rc))
    871            LogRel(("Shared clipboard: Failed to load the XFIXES extension.\n"));
     842           LogRel(("Shared clipboard: Failed to load the XFIXES extension\n"));
    872843    }
    873844#endif
     
    880851        if (NULL == pCtx->widget)
    881852        {
    882             LogRel(("Shared clipboard: Failed to construct the X11 window for the shared clipboard manager.\n"));
     853            LogRel(("Shared clipboard: Failed to construct the X11 window for the shared clipboard manager\n"));
    883854            rc = VERR_NO_MEMORY;
    884855        }
     
    911882            rc = RTErrConvertFromErrno(errno);
    912883        if (RT_FAILURE(rc))
    913             LogRel(("Shared clipboard: Failed to setup the termination mechanism.\n"));
     884            LogRel(("Shared clipboard: Failed to setup the termination mechanism\n"));
    914885    }
    915886    else
     
    923894
    924895/**
    925  * Construct the X11 backend of the shared clipboard.
     896 * Constructs the X11 backend of the shared clipboard.
     897 *
    926898 * @note  X11 backend code
    927899 */
     
    937909         * This is important for VBoxHeadless.
    938910         */
    939         LogRelFunc(("X11 DISPLAY variable not set -- disabling shared clipboard\n"));
     911        LogRel(("Shared clipboard: X11 DISPLAY variable not set -- disabling Shared Clipboard\n"));
    940912        pCtx->fHaveX11 = false;
    941913        return pCtx;
     
    945917
    946918    LogRel(("Shared clipboard: Initializing X11 clipboard backend\n"));
     919
    947920    if (pCtx)
    948921        pCtx->pFrontend = pFrontend;
     
    951924
    952925/**
    953  * Destruct the shared clipboard X11 backend.
     926 * Destructs the shared clipboard X11 backend.
     927 *
    954928 * @note  X11 backend code
    955929 */
     
    965939
    966940/**
    967  * Announce to the X11 backend that we are ready to start.
     941 * Announces to the X11 backend that we are ready to start.
     942 *
    968943 * @param  grab  whether we should try to grab the shared clipboard at once
    969944 */
     
    971946{
    972947    int rc = VINF_SUCCESS;
    973     LogRelFlowFunc(("\n"));
     948
     949    LogRel2(("Shared clipboard: Starting\n"));
     950
    974951    /*
    975952     * Immediately return if we are not connected to the X server.
     
    991968        if (RT_FAILURE(rc))
    992969        {
    993             LogRel(("Shared clipboard: Failed to start the shared clipboard thread.\n"));
     970            LogRel(("Shared clipboard: Failed to start the shared clipboard thread, rc=%Rrc\n", rc));
    994971            clipUninit(pCtx);
    995972        }
     
    1000977
    1001978/**
    1002  * Shut down the shared clipboard X11 backend.
    1003  * @note  X11 backend code
     979 * Shuts down the shared clipboard X11 backend.
     980 *
     981 * @note  X11 backend code.
    1004982 * @note  Any requests from this object to get clipboard data from VBox
    1005983 *        *must* have completed or aborted before we are called, as
     
    1017995        return VINF_SUCCESS;
    1018996
    1019     LogRelFunc(("stopping the shared clipboard X11 backend\n"));
     997    LogRel(("Shared clipboard: Stopping X11 backend\n"));
     998
    1020999    /* Write to the "stop" pipe */
    10211000    clipQueueToEventThread(pCtx, clipStopEventThreadWorker, (XtPointer) pCtx);
     
    10351014        AssertRC(rcThread);
    10361015    else
    1037         LogRelFunc(("rc=%Rrc\n", rc));
     1016        LogRel(("Shared clipboard: Stopping X11 backend failed with rc=%Rrc\n", rc));
     1017
    10381018    clipUninit(pCtx);
    1039     LogRelFlowFunc(("returning %Rrc.\n", rc));
     1019
    10401020    RT_NOREF_PV(rcThread);
    10411021    return rc;
     
    10451025 * Satisfy a request from X11 for clipboard targets supported by VBox.
    10461026 *
    1047  * @returns iprt status code
    1048  * @param  atomTypeReturn The type of the data we are returning
     1027 * @returns IPRT status code.
     1028 * @param  atomTypeReturn The type of the data we are returning.
    10491029 * @param  pValReturn     A pointer to the data we are returning.  This
    10501030 *                        should be set to memory allocated by XtMalloc,
    10511031 *                        which will be freed later by the Xt toolkit.
    1052  * @param  pcLenReturn    The length of the data we are returning
     1032 * @param  pcLenReturn    The length of the data we are returning.
    10531033 * @param  piFormatReturn The format (8bit, 16bit, 32bit) of the data we are
    1054  *                        returning
     1034 *                        returning.
     1035 *
    10551036 * @note  X11 backend code, called by the XtOwnSelection callback.
    10561037 */
     
    10601041                                int *piFormatReturn)
    10611042{
    1062     Atom *atomTargets = (Atom *)XtMalloc(  (MAX_CLIP_X11_FORMATS + 3)
    1063                                          * sizeof(Atom));
     1043    Atom *atomTargets = (Atom *)XtMalloc((CLIPX11FORMATIDX_MAX + 3) * sizeof(Atom));
    10641044    unsigned cTargets = 0;
     1045
    10651046    LogRelFlowFunc (("called\n"));
    1066     CLIPX11FORMAT format = NIL_CLIPX11FORMAT;
     1047
     1048    CLIPX11FORMATIDX fmtIdx = CLIPX11FORMATIDX_NIL;
     1049
    10671050    do
    10681051    {
    1069         format = clipEnumX11Formats(pCtx->vboxFormats, format);
    1070         if (format != NIL_CLIPX11FORMAT)
    1071         {
    1072             atomTargets[cTargets] = clipAtomForX11Format(pCtx, format);
     1052        fmtIdx = clipEnumFmtIdxForVBoxFmt(pCtx->vboxFormats, fmtIdx);
     1053        if (fmtIdx != CLIPX11FORMATIDX_NIL)
     1054        {
     1055            atomTargets[cTargets] = clipGetAtomFromFmtIdx(pCtx, fmtIdx);
    10731056            ++cTargets;
    10741057        }
    1075     } while (format != NIL_CLIPX11FORMAT);
     1058    } while (fmtIdx != CLIPX11FORMATIDX_NIL);
     1059
    10761060    /* We always offer these */
    1077     atomTargets[cTargets] = clipGetAtom(pCtx, "TARGETS");
     1061    atomTargets[cTargets]     = clipGetAtom(pCtx, "TARGETS");
    10781062    atomTargets[cTargets + 1] = clipGetAtom(pCtx, "MULTIPLE");
    10791063    atomTargets[cTargets + 2] = clipGetAtom(pCtx, "TIMESTAMP");
     1064
    10801065    *atomTypeReturn = XA_ATOM;
    10811066    *pValReturn = (XtPointer)atomTargets;
    10821067    *pcLenReturn = cTargets + 3;
    10831068    *piFormatReturn = 32;
     1069
    10841070    return VINF_SUCCESS;
    10851071}
    10861072
    1087 /** This is a wrapper around ClipRequestDataForX11 that will cache the
     1073/**
     1074 * This is a wrapper around ClipRequestDataForX11 that will cache the
    10881075 * data returned.
    10891076 */
    1090 static int clipReadVBoxClipboard(CLIPBACKEND *pCtx, uint32_t u32Format,
     1077static int clipReadVBoxClipboard(CLIPBACKEND *pCtx, VBOXCLIPBOARDFORMAT vboxFormat,
    10911078                                 void **ppv, uint32_t *pcb)
    10921079{
    10931080    int rc = VINF_SUCCESS;
    1094     LogRelFlowFunc(("pCtx=%p, u32Format=%02X, ppv=%p, pcb=%p\n", pCtx,
    1095                  u32Format, ppv, pcb));
    1096     if (u32Format == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
     1081    LogRelFlowFunc(("pCtx=%p, vboxFormat=%02X, ppv=%p, pcb=%p\n", pCtx,
     1082                 vboxFormat, ppv, pcb));
     1083    if (vboxFormat == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    10971084    {
    10981085        if (pCtx->pvUnicodeCache == NULL)
    1099             rc = ClipRequestDataForX11(pCtx->pFrontend, u32Format,
     1086            rc = ClipRequestDataForX11(pCtx->pFrontend, vboxFormat,
    11001087                                              &pCtx->pvUnicodeCache,
    11011088                                              &pCtx->cbUnicodeCache);
     
    11091096    }
    11101097    else
    1111         rc = ClipRequestDataForX11(pCtx->pFrontend, u32Format,
     1098        rc = ClipRequestDataForX11(pCtx->pFrontend, vboxFormat,
    11121099                                          ppv, pcb);
    11131100    LogRelFlowFunc(("returning %Rrc\n", rc));
     
    11181105
    11191106/**
    1120  * Calculate a buffer size large enough to hold the source Windows format
    1121  * text converted into Unix Utf8, including the null terminator
    1122  * @returns iprt status code
    1123  * @param  pwsz       the source text in UCS-2 with Windows EOLs
     1107 * Calculates a buffer size large enough to hold the source Windows format
     1108 * text converted into Unix Utf8, including the null terminator.
     1109 *
     1110 * @returns IPRT status code.
     1111 * @param  pwsz       the source text in UCS-2 with Windows EOLs.
    11241112 * @param  cwc        the size in USC-2 elements of the source text, with or
    1125  *                    without the terminator
    1126  * @param  pcbActual  where to store the buffer size needed
     1113 *                    without the terminator.
     1114 * @param  pcbActual  where to store the buffer size needed.
    11271115 */
    11281116static int clipWinTxtBufSizeForUtf8(PRTUTF16 pwsz, size_t cwc,
     
    11371125
    11381126/**
    1139  * Convert text from Windows format (UCS-2 with CRLF line endings) to standard
     1127 * Converts text from Windows format (UCS-2 with CRLF line endings) to standard
    11401128 * Utf-8.
    11411129 *
    1142  * @returns iprt status code
    1143  *
    1144  * @param  pwszSrc    the text to be converted
    1145  * @param  cbSrc      the length of @a pwszSrc in bytes
    1146  * @param  pszBuf     where to write the converted string
    1147  * @param  cbBuf      the size of the buffer pointed to by @a pszBuf
     1130 * @returns IPRT status code.
     1131 * @param  pwszSrc    the text to be converted.
     1132 * @param  cbSrc      the length of @a pwszSrc in bytes.
     1133 * @param  pszBuf     where to write the converted string.
     1134 * @param  cbBuf      the size of the buffer pointed to by @a pszBuf.
    11481135 * @param  pcbActual  where to store the size of the converted string.
    11491136 *                    optional.
     
    11791166    LogRelFlowFunc(("returning %Rrc\n", rc));
    11801167    if (RT_SUCCESS(rc))
    1181         LogRelFlowFunc (("converted string is %.*s. Returning.\n", cbDest,
     1168        LogRelFlowFunc (("converted string is %.*s. Returning\n", cbDest,
    11821169                      pszBuf));
    11831170    return rc;
     
    11851172
    11861173/**
    1187  * Satisfy a request from X11 to convert the clipboard text to Utf-8.  We
     1174 * Satisfies a request from X11 to convert the clipboard text to Utf-8.  We
    11881175 * return null-terminated text, but can cope with non-null-terminated input.
    11891176 *
    1190  * @returns iprt status code
     1177 * @returns IPRT status code.
    11911178 * @param  pDisplay        an X11 display structure, needed for conversions
    1192  *                         performed by Xlib
    1193  * @param  pv              the text to be converted (UCS-2 with Windows EOLs)
    1194  * @param  cb              the length of the text in @cb in bytes
     1179 *                         performed by Xlib.
     1180 * @param  pv              the text to be converted (UCS-2 with Windows EOLs).
     1181 * @param  cb              the length of the text in @cb in bytes.
    11951182 * @param  atomTypeReturn  where to store the atom for the type of the data
    1196  *                         we are returning
     1183 *                         we are returning.
    11971184 * @param  pValReturn      where to store the pointer to the data we are
    11981185 *                         returning.  This should be to memory allocated by
     
    12001187 *                         later.
    12011188 * @param  pcLenReturn     where to store the length of the data we are
    1202  *                         returning
     1189 *                         returning.
    12031190 * @param  piFormatReturn  where to store the bit width (8, 16, 32) of the
    1204  *                         data we are returning
     1191 *                         data we are returning.
    12051192 */
    12061193static int clipWinTxtToUtf8ForX11CB(Display *pDisplay, PRTUTF16 pwszSrc,
     
    12111198                                    int *piFormatReturn)
    12121199{
    1213     RT_NOREF2(pDisplay, pcLenReturn);
     1200    RT_NOREF(pDisplay, pcLenReturn);
    12141201
    12151202    /* This may slightly overestimate the space needed. */
     
    12351222
    12361223/**
    1237  * Satisfy a request from X11 to convert the clipboard HTML fragment to Utf-8.  We
     1224 * Satisfies a request from X11 to convert the clipboard HTML fragment to Utf-8.  We
    12381225 * return null-terminated text, but can cope with non-null-terminated input.
    12391226 *
    1240  * @returns iprt status code
     1227 * @returns IPRT status code.
    12411228 * @param  pDisplay        an X11 display structure, needed for conversions
    1242  *                         performed by Xlib
    1243  * @param  pv              the text to be converted (UTF8 with Windows EOLs)
    1244  * @param  cb              the length of the text in @cb in bytes
     1229 *                         performed by Xlib.
     1230 * @param  pv              the text to be converted (UTF8 with Windows EOLs).
     1231 * @param  cb              the length of the text in @cb in bytes.
    12451232 * @param  atomTypeReturn  where to store the atom for the type of the data
    1246  *                         we are returning
     1233 *                         we are returning.
    12471234 * @param  pValReturn      where to store the pointer to the data we are
    12481235 *                         returning.  This should be to memory allocated by
     
    12501237 *                         later.
    12511238 * @param  pcLenReturn     where to store the length of the data we are
    1252  *                         returning
     1239 *                         returning.
    12531240 * @param  piFormatReturn  where to store the bit width (8, 16, 32) of the
    1254  *                         data we are returning
     1241 *                         data we are returning.
    12551242 */
    12561243static int clipWinHTMLToUtf8ForX11CB(Display *pDisplay, const char *pszSrc,
     
    12611248                                    int *piFormatReturn)
    12621249{
    1263     RT_NOREF2(pDisplay, pValReturn);
     1250    RT_NOREF(pDisplay, pValReturn);
    12641251
    12651252    /* This may slightly overestimate the space needed. */
     
    12801267}
    12811268
    1282 
    12831269/**
    12841270 * Does this atom correspond to one of the two selection types we support?
     1271 *
    12851272 * @param  widget   a valid Xt widget
    12861273 * @param  selType  the atom in question
     
    12931280
    12941281/**
    1295  * Remove a trailing nul character from a string by adjusting the string
     1282 * Removes a trailing nul character from a string by adjusting the string
    12961283 * length.  Some X11 applications don't like zero-terminated text...
     1284 *
    12971285 * @param  pText   the text in question
    12981286 * @param  pcText  the length of the text, adjusted on return
     
    13001288 */
    13011289static void clipTrimTrailingNul(XtPointer pText, unsigned long *pcText,
    1302                                 CLIPFORMAT format)
     1290                                CLIPX11FORMATTARGET format)
    13031291{
    13041292    AssertPtrReturnVoid(pText);
    13051293    AssertPtrReturnVoid(pcText);
    1306     AssertReturnVoid((format == UTF8) || (format == TEXT) || (format == HTML));
     1294    AssertReturnVoid(   (format == CLIPX11FORMATTARGET_UTF8)
     1295                     || (format == CLIPX11FORMATTARGET_TEXT)
     1296                     || (format == CLIPX11FORMATTARGET_HTML));
    13071297    if (((char *)pText)[*pcText - 1] == '\0')
    13081298       --(*pcText);
     
    13161306{
    13171307    int rc = VINF_SUCCESS;
    1318     CLIPX11FORMAT x11Format = clipFindX11FormatByAtom(pCtx, *atomTarget);
    1319     CLIPFORMAT format = clipRealFormatForX11Format(x11Format);
    1320     if (   ((format == UTF8) || (format == TEXT))
     1308
     1309    CLIPX11FORMATIDX    fmtIdx = clipGetFmtIdxFromAtom(pCtx, *atomTarget);
     1310    CLIPX11FORMATTARGET fmtTgt = clipGetTargetFmtFromFmtIdx(fmtIdx);
     1311
     1312    if (   ((fmtTgt == CLIPX11FORMATTARGET_UTF8) || (fmtTgt == CLIPX11FORMATTARGET_TEXT))
    13211313        && (pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT))
    13221314    {
    13231315        void *pv = NULL;
    13241316        uint32_t cb = 0;
    1325         rc = clipReadVBoxClipboard(pCtx,
    1326                                    VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT,
    1327                                    &pv, &cb);
     1317        rc = clipReadVBoxClipboard(pCtx, VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, &pv, &cb);
    13281318        if (RT_SUCCESS(rc) && (cb == 0))
    13291319            rc = VERR_NO_DATA;
    1330         if (RT_SUCCESS(rc) && ((format == UTF8) || (format == TEXT)))
     1320
     1321        if (RT_SUCCESS(rc) && (   (fmtTgt == CLIPX11FORMATTARGET_UTF8)
     1322                               || (fmtTgt == CLIPX11FORMATTARGET_TEXT)))
     1323        {
    13311324            rc = clipWinTxtToUtf8ForX11CB(XtDisplay(pCtx->widget),
    13321325                                          (PRTUTF16)pv, cb, atomTarget,
    13331326                                          atomTypeReturn, pValReturn,
    13341327                                          pcLenReturn, piFormatReturn);
     1328        }
     1329
    13351330        if (RT_SUCCESS(rc))
    1336             clipTrimTrailingNul(*(XtPointer *)pValReturn, pcLenReturn, format);
     1331            clipTrimTrailingNul(*(XtPointer *)pValReturn, pcLenReturn, fmtTgt);
     1332
    13371333        RTMemFree(pv);
    13381334    }
    1339     else if (   (format == BMP)
     1335    else if (   (fmtTgt == CLIPX11FORMATTARGET_BMP)
    13401336             && (pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP))
    13411337    {
    13421338        void *pv = NULL;
    13431339        uint32_t cb = 0;
    1344         rc = clipReadVBoxClipboard(pCtx,
    1345                                    VBOX_SHARED_CLIPBOARD_FMT_BITMAP,
    1346                                    &pv, &cb);
     1340        rc = clipReadVBoxClipboard(pCtx, VBOX_SHARED_CLIPBOARD_FMT_BITMAP, &pv, &cb);
    13471341        if (RT_SUCCESS(rc) && (cb == 0))
    13481342            rc = VERR_NO_DATA;
    1349         if (RT_SUCCESS(rc) && (format == BMP))
    1350         {
    1351             /* Create a full BMP from it */
     1343
     1344        if (RT_SUCCESS(rc) && (fmtTgt == CLIPX11FORMATTARGET_BMP))
     1345        {
     1346            /* Create a full BMP from it. */
    13521347            rc = vboxClipboardDibToBmp(pv, cb, (void **)pValReturn,
    13531348                                       (size_t *)pcLenReturn);
     
    13611356            *piFormatReturn = 8;
    13621357        }
     1358
    13631359        RTMemFree(pv);
    13641360    }
    1365     else if ( (format == HTML)
    1366             && (pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML))
     1361    else if (   (fmtTgt == CLIPX11FORMATTARGET_HTML)
     1362             && (pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_HTML))
    13671363    {
    13681364        void *pv = NULL;
    13691365        uint32_t cb = 0;
    1370         rc = clipReadVBoxClipboard(pCtx,
    1371                                    VBOX_SHARED_CLIPBOARD_FMT_HTML,
    1372                                    &pv, &cb);
     1366        rc = clipReadVBoxClipboard(pCtx, VBOX_SHARED_CLIPBOARD_FMT_HTML, &pv, &cb);
    13731367        if (RT_SUCCESS(rc) && (cb == 0))
    13741368            rc = VERR_NO_DATA;
     1369
    13751370        if (RT_SUCCESS(rc))
    13761371        {
     
    13841379            */
    13851380            rc = clipWinHTMLToUtf8ForX11CB(XtDisplay(pCtx->widget),
    1386                 (const char*)pv, cb, atomTarget,
    1387                 atomTypeReturn, pValReturn,
    1388                 pcLenReturn, piFormatReturn);
    1389 
    1390 
     1381                                           (const char*)pv, cb, atomTarget,
     1382                                           atomTypeReturn, pValReturn,
     1383                                           pcLenReturn, piFormatReturn);
    13911384            if (RT_SUCCESS(rc))
    1392                 clipTrimTrailingNul(*(XtPointer *)pValReturn, pcLenReturn, format);
     1385                clipTrimTrailingNul(*(XtPointer *)pValReturn, pcLenReturn, fmtTgt);
     1386
    13931387            RTMemFree(pv);
    13941388        }
    13951389    }
     1390#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     1391    else if (   (fmtTgt == CLIPX11FORMATTARGET_URI_LIST)
     1392             && (pCtx->vboxFormats & VBOX_SHARED_CLIPBOARD_FMT_URI_LIST))
     1393    {
     1394        /** Nothing to do here yet. */
     1395    }
     1396#endif
    13961397    else
    13971398        rc = VERR_NOT_SUPPORTED;
     
    14001401
    14011402/**
    1402  * Return VBox's clipboard data for an X11 client.
    1403  * @note  X11 backend code, callback for XtOwnSelection
     1403 * Returns VBox's clipboard data for an X11 client.
     1404 *
     1405 * @note  X11 backend code, callback for XtOwnSelection.
    14041406 */
    14051407static Boolean clipXtConvertSelectionProc(Widget widget, Atom *atomSelection,
     
    14341436    CLIPBACKEND *pCtx;
    14351437    /** Formats supported by VBox */
    1436     uint32_t formats;
     1438    VBOXCLIPBOARDFORMATS vboxFormats;
    14371439} CLIPNEWVBOXFORMATS;
    14381440
     
    14481450
    14491451/**
    1450  * Take possession of the X11 clipboard (and middle-button selection).
    1451  */
    1452 static void clipGrabX11CB(CLIPBACKEND *pCtx, uint32_t u32Formats)
     1452 * Takes possession of the X11 clipboard (and middle-button selection).
     1453 */
     1454static void clipGrabX11CB(CLIPBACKEND *pCtx, VBOXCLIPBOARDFORMATS vboxFormats)
    14531455{
    14541456    if (XtOwnSelection(pCtx->widget, clipGetAtom(pCtx, "CLIPBOARD"),
    14551457                       CurrentTime, clipXtConvertSelectionProc, NULL, 0))
    14561458    {
    1457         pCtx->vboxFormats = u32Formats;
     1459        pCtx->vboxFormats = vboxFormats;
     1460
    14581461        /* Grab the middle-button paste selection too. */
    14591462        XtOwnSelection(pCtx->widget, clipGetAtom(pCtx, "PRIMARY"),
     
    14751478 * Worker function for ClipAnnounceFormatToX11 which runs on the
    14761479 * event thread.
     1480 *
    14771481 * @param pUserData  Pointer to a CLIPNEWVBOXFORMATS structure containing
    14781482 *                   information about the VBox formats available and the
    14791483 *                   clipboard context data.  Must be freed by the worker.
    14801484 */
    1481 static void clipNewVBoxFormatsWorker(void *pUserData,
    1482                                      void * /* interval */)
     1485static void clipNewVBoxFormatsWorker(void *pUserData, void * /* interval */)
    14831486{
    14841487    CLIPNEWVBOXFORMATS *pFormats = (CLIPNEWVBOXFORMATS *)pUserData;
     1488
    14851489    CLIPBACKEND *pCtx = pFormats->pCtx;
    1486     uint32_t u32Formats = pFormats->formats;
     1490    VBOXCLIPBOARDFORMAT vboxFormat = pFormats->vboxFormats;
     1491
    14871492    RTMemFree(pFormats);
    1488     LogRelFlowFunc (("u32Formats=%d\n", u32Formats));
     1493
     1494    LogRelFlowFunc (("vboxFormat=%RU32\n", vboxFormat));
     1495
    14891496    clipInvalidateVBoxCBCache(pCtx);
    1490     clipGrabX11CB(pCtx, u32Formats);
     1497    clipGrabX11CB(pCtx, vboxFormat);
    14911498    clipResetX11Formats(pCtx);
     1499
    14921500    LogRelFlowFunc(("returning\n"));
    14931501}
     
    14961504 * VBox is taking possession of the shared clipboard.
    14971505 *
    1498  * @param u32Formats Clipboard formats that VBox is offering
     1506 * @param vboxFormats Clipboard formats that VBox is offering
    14991507 * @note  X11 backend code
    15001508 */
    1501 void ClipAnnounceFormatToX11(CLIPBACKEND *pCtx,
    1502                                         uint32_t u32Formats)
     1509int ClipAnnounceFormatToX11(CLIPBACKEND *pCtx, VBOXCLIPBOARDFORMATS vboxFormats)
    15031510{
    15041511    /*
     
    15061513     */
    15071514    if (!pCtx->fHaveX11)
    1508         return;
     1515        return VINF_SUCCESS;
     1516
     1517    int rc;
     1518
    15091519    /* This must be freed by the worker callback */
    15101520    CLIPNEWVBOXFORMATS *pFormats =
    15111521        (CLIPNEWVBOXFORMATS *) RTMemAlloc(sizeof(CLIPNEWVBOXFORMATS));
     1522
    15121523    if (pFormats != NULL)  /* if it is we will soon have other problems */
    15131524    {
    15141525        pFormats->pCtx = pCtx;
    1515         pFormats->formats = u32Formats;
     1526        pFormats->vboxFormats = vboxFormats;
    15161527        clipQueueToEventThread(pCtx, clipNewVBoxFormatsWorker,
    15171528                               (XtPointer) pFormats);
    1518     }
    1519 }
    1520 
    1521 /**
    1522  * Massage generic Utf16 with CR end-of-lines into the format Windows expects
     1529        rc = VINF_SUCCESS;
     1530    }
     1531    else
     1532        rc = VERR_NO_MEMORY;
     1533
     1534    return rc;
     1535}
     1536
     1537/**
     1538 * Massages generic Utf16 with CR end-of-lines into the format Windows expects
    15231539 * and return the result in a RTMemAlloc allocated buffer.
    1524  * @returns  IPRT status code
    1525  * @param  pwcSrc     The source Utf16
     1540 *
     1541 * @returns IPRT status code.
     1542 * @param  pwcSrc     The source Utf16.
    15261543 * @param  cwcSrc     The number of 16bit elements in @a pwcSrc, not counting
    1527  *                    the terminating zero
    1528  * @param  ppwszDest  Where to store the buffer address
     1544 *                    the terminating zero.
     1545 * @param  ppwszDest  Where to store the buffer address.
    15291546 * @param  pcbDest    On success, where to store the number of bytes written.
    1530  *                    Undefined otherwise.  Optional
     1547 *                    Undefined otherwise.  Optional.
    15311548 */
    15321549static int clipUtf16ToWinTxt(RTUTF16 *pwcSrc, size_t cwcSrc,
     
    15671584
    15681585/**
    1569  * Convert Utf-8 text with CR end-of-lines into Utf-16 as Windows expects it
     1586 * Converts Utf-8 text with CR end-of-lines into Utf-16 as Windows expects it
    15701587 * and return the result in a RTMemAlloc allocated buffer.
    1571  * @returns  IPRT status code
    1572  * @param  pcSrc      The source Utf-8
     1588 *
     1589 * @returns  IPRT status code.
     1590 * @param  pcSrc      The source Utf-8.
    15731591 * @param  cbSrc      The size of the source in bytes, not counting the
    1574  *                    terminating zero
    1575  * @param  ppwszDest  Where to store the buffer address
     1592 *                    terminating zero.
     1593 * @param  ppwszDest  Where to store the buffer address.
    15761594 * @param  pcbDest    On success, where to store the number of bytes written.
    1577  *                    Undefined otherwise.  Optional
     1595 *                    Undefined otherwise.  Optional.
    15781596 */
    15791597static int clipUtf8ToWinTxt(const char *pcSrc, unsigned cbSrc,
     
    16001618
    16011619/**
    1602  * Convert Latin-1 text with CR end-of-lines into Utf-16 as Windows expects
     1620 * Converts Latin-1 text with CR end-of-lines into Utf-16 as Windows expects
    16031621 * it and return the result in a RTMemAlloc allocated buffer.
    1604  * @returns  IPRT status code
    1605  * @param  pcSrc      The source text
     1622 *
     1623 * @returns IPRT status code.
     1624 * @param  pcSrc      The source text.
    16061625 * @param  cbSrc      The size of the source in bytes, not counting the
    1607  *                    terminating zero
    1608  * @param  ppwszDest  Where to store the buffer address
     1626 *                    terminating zero.
     1627 * @param  ppwszDest  Where to store the buffer address.
    16091628 * @param  pcbDest    On success, where to store the number of bytes written.
    1610  *                    Undefined otherwise.  Optional
     1629 *                    Undefined otherwise.  Optional.
    16111630 */
    16121631static int clipLatin1ToWinTxt(char *pcSrc, unsigned cbSrc,
     
    16621681
    16631682/**
    1664 * Convert Utf16 text into UTF8 as Windows expects
    1665 * it and return the result in a RTMemAlloc allocated buffer.
    1666 * @returns  IPRT status code
    1667 * @param  pcSrc      The source text
    1668 * @param  cbSrc      The size of the source in bytes, not counting the
    1669 *                    terminating zero
    1670 * @param  ppwszDest  Where to store the buffer address
    1671 * @param  pcbDest    On success, where to store the number of bytes written.
    1672 *                    Undefined otherwise.  Optional
    1673 */
     1683 * Converts Utf16 text into UTF8 as Windows expects
     1684 * it and return the result in a RTMemAlloc allocated buffer.
     1685 *
     1686 * @returns  IPRT status code.
     1687 * @param  pcSrc      The source text.
     1688 * @param  cbSrc      The size of the source in bytes, not counting the
     1689 *                    terminating zero.
     1690 * @param  ppwszDest  Where to store the buffer address.
     1691 * @param  pcbDest    On success, where to store the number of bytes written.
     1692 *                    Undefined otherwise.  Optional.
     1693 */
    16741694int  clipUTF16ToWinHTML(RTUTF16 *pwcBuf, size_t cb, char **ppszOut, uint32_t *pcOut)
    16751695{
     
    17321752}
    17331753
    1734 
    1735 
    17361754/** A structure containing information about where to store a request
    17371755 * for the X11 clipboard contents. */
    17381756struct _CLIPREADX11CBREQ
    17391757{
     1758    /** @todo r=andy Why all those different CLIPX11FORMAT members? Shouldn't be one enough? */
     1759
    17401760    /** The format VBox would like the data in */
    1741     uint32_t mFormat;
     1761    VBOXCLIPBOARDFORMAT mFormat;
    17421762    /** The text format we requested from X11 if we requested text */
    1743     CLIPX11FORMAT mTextFormat;
     1763    CLIPX11FORMATIDX mTextFmtIdx;
    17441764    /** The bitmap format we requested from X11 if we requested bitmap */
    1745     CLIPX11FORMAT mBitmapFormat;
     1765    CLIPX11FORMATIDX mBitmapFmtIdx;
    17461766    /** The HTML format we requested from X11 if we requested HTML */
    1747     CLIPX11FORMAT mHtmlFormat;
     1767    CLIPX11FORMATIDX mHtmlFmtIdx;
     1768#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     1769    /** The URI list format we requested from X11 if we requested URI list */
     1770    CLIPX11FORMATIDX mURIListFmtIdx;
     1771#endif
    17481772    /** The clipboard context this request is associated with */
    17491773    CLIPBACKEND *mCtx;
     
    17551779
    17561780/**
    1757  * Convert the data obtained from the X11 clipboard to the required format,
     1781 * Converts the data obtained from the X11 clipboard to the required format,
    17581782 * place it in the buffer supplied and signal that data has arrived.
    17591783 * Convert the text obtained UTF-16LE with Windows EOLs.
    17601784 * Convert full BMP data to DIB format.
     1785 *
    17611786 * @note  X11 backend code, callback for XtGetSelectionValue, for use when
    17621787 *        the X11 clipboard contains a format we understand.
    17631788 */
    1764 static void clipConvertX11CB(void *pClientData, void *pvSrc, unsigned cbSrc)
    1765 {
    1766     CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *) pClientData;
     1789static void clipConvertX11CB(void *pSvcCtxData, void *pvSrc, unsigned cbSrc)
     1790{
     1791    CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *) pSvcCtxData;
    17671792    LogRelFlowFunc(("pReq->mFormat=%02X, pReq->mTextFormat=%u, "
    17681793                "pReq->mBitmapFormat=%u, pReq->mHtmlFormat=%u, pReq->mCtx=%p\n",
    1769                  pReq->mFormat, pReq->mTextFormat, pReq->mBitmapFormat,
    1770                  pReq->mHtmlFormat, pReq->mCtx));
     1794                 pReq->mFormat, pReq->mTextFmtIdx, pReq->mBitmapFmtIdx,
     1795                 pReq->mHtmlFmtIdx, pReq->mCtx));
    17711796    AssertPtr(pReq->mCtx);
    17721797    Assert(pReq->mFormat != 0);  /* sanity */
     
    17891814    {
    17901815        /* In which format is the clipboard data? */
    1791         switch (clipRealFormatForX11Format(pReq->mTextFormat))
    1792         {
    1793             case UTF8:
    1794             case TEXT:
     1816        switch (clipGetTargetFmtFromFmtIdx(pReq->mTextFmtIdx))
     1817        {
     1818            case CLIPX11FORMATTARGET_UTF8:
     1819            case CLIPX11FORMATTARGET_TEXT:
    17951820            {
    17961821                /* If we are given broken Utf-8, we treat it as Latin1.  Is
     
    18121837    {
    18131838        /* In which format is the clipboard data? */
    1814         switch (clipRealFormatForX11Format(pReq->mBitmapFormat))
    1815         {
    1816             case BMP:
     1839        switch (clipGetTargetFmtFromFmtIdx(pReq->mBitmapFmtIdx))
     1840        {
     1841            case CLIPX11FORMATTARGET_BMP:
    18171842            {
    18181843                const void *pDib;
     
    18401865    {
    18411866        /* In which format is the clipboard data? */
    1842         switch (clipRealFormatForX11Format(pReq->mHtmlFormat))
    1843         {
    1844             case HTML:
     1867        switch (clipGetTargetFmtFromFmtIdx(pReq->mHtmlFmtIdx))
     1868        {
     1869            case CLIPX11FORMATTARGET_HTML:
    18451870            {
    18461871                /* The common VBox HTML encoding will be - Utf8
     
    18891914        }
    18901915    }
     1916#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     1917    else if (pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     1918    {
     1919        // @todo
     1920    }
     1921#endif
    18911922    else
    18921923        rc = VERR_NOT_IMPLEMENTED;
     
    19001931#ifndef TESTCASE
    19011932/**
    1902  * Convert the data obtained from the X11 clipboard to the required format,
     1933 * Converts the data obtained from the X11 clipboard to the required format,
    19031934 * place it in the buffer supplied and signal that data has arrived.
    19041935 * Convert the text obtained UTF-16LE with Windows EOLs.
    19051936 * Convert full BMP data to DIB format.
     1937 *
    19061938 * @note  X11 backend code, callback for XtGetSelectionValue, for use when
    19071939 *        the X11 clipboard contains a format we understand.
    19081940 */
    1909 static void cbConvertX11CB(Widget widget, XtPointer pClientData,
     1941static void cbConvertX11CB(Widget widget, XtPointer pSvcCtxData,
    19101942                           Atom * /* selection */, Atom *atomType,
    19111943                           XtPointer pvSrc, long unsigned int *pcLen,
    19121944                           int *piFormat)
    19131945{
    1914     RT_NOREF1(widget);
     1946    RT_NOREF(widget);
    19151947    if (*atomType == XT_CONVERT_FAIL) /* Xt timeout */
    1916         clipConvertX11CB(pClientData, NULL, 0);
     1948        clipConvertX11CB(pSvcCtxData, NULL, 0);
    19171949    else
    1918         clipConvertX11CB(pClientData, pvSrc, (*pcLen) * (*piFormat) / 8);
     1950        clipConvertX11CB(pSvcCtxData, pvSrc, (*pcLen) * (*piFormat) / 8);
    19191951
    19201952    XtFree((char *)pvSrc);
     
    19231955
    19241956#ifdef TESTCASE
    1925 static void testRequestData(CLIPBACKEND* pCtx, CLIPX11FORMAT target,
     1957static void testRequestData(CLIPBACKEND* pCtx, CLIPX11FORMATTARGET target,
    19261958                            void *closure);
    19271959#endif
    19281960
    1929 static void getSelectionValue(CLIPBACKEND *pCtx, CLIPX11FORMAT format,
     1961static void getSelectionValue(CLIPBACKEND *pCtx, CLIPX11FORMATIDX format,
    19301962                              CLIPREADX11CBREQ *pReq)
    19311963{
    19321964#ifndef TESTCASE
    19331965    XtGetSelectionValue(pCtx->widget, clipGetAtom(pCtx, "CLIPBOARD"),
    1934                         clipAtomForX11Format(pCtx, format),
     1966                        clipGetAtomFromFmtIdx(pCtx, format),
    19351967                        cbConvertX11CB,
    19361968                        reinterpret_cast<XtPointer>(pReq),
     
    19431975/** Worker function for ClipRequestDataFromX11 which runs on the event
    19441976 * thread. */
    1945 static void vboxClipboardReadX11Worker(void *pUserData,
    1946                                        void * /* interval */)
     1977static void vboxClipboardReadX11Worker(void *pUserData, void * /* interval */)
    19471978{
    19481979    CLIPREADX11CBREQ *pReq = (CLIPREADX11CBREQ *)pUserData;
     
    19551986    pCtx->fBusy = true;
    19561987    if (fBusy)
     1988    {
    19571989        /* If the clipboard is busy just fend off the request. */
    19581990        rc = VERR_TRY_AGAIN;
     1991    }
    19591992    else
    19601993#endif
     
    19641997         * VBox wants to read data in the given format.
    19651998         */
    1966         pReq->mTextFormat = pCtx->X11TextFormat;
    1967         if (pReq->mTextFormat == INVALID)
     1999        pReq->mTextFmtIdx = pCtx->X11TextFmtIdx;
     2000        if (pReq->mTextFmtIdx == CLIPX11FORMATIDX_NIL)
     2001        {
    19682002            /* VBox thinks we have data and we don't */
    19692003            rc = VERR_NO_DATA;
     2004        }
     2005        else
     2006        {
     2007            /* Send out a request for the data to the current clipboard owner */
     2008            getSelectionValue(pCtx, pCtx->X11TextFmtIdx, pReq);
     2009        }
     2010    }
     2011    else if (pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     2012    {
     2013        pReq->mBitmapFmtIdx = pCtx->X11BitmapFmtIdx;
     2014        if (pReq->mBitmapFmtIdx == CLIPX11FORMATIDX_NIL)
     2015        {
     2016            /* VBox thinks we have data and we don't */
     2017            rc = VERR_NO_DATA;
     2018        }
     2019        else
     2020        {
     2021            /* Send out a request for the data to the current clipboard
     2022             * owner */
     2023            getSelectionValue(pCtx, pCtx->X11BitmapFmtIdx, pReq);
     2024        }
     2025    }
     2026    else if(pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_HTML)
     2027    {
     2028        /* Send out a request for the data to the current clipboard owner */
     2029        pReq->mHtmlFmtIdx = pCtx->X11HTMLFmtIdx;
     2030        if(pReq->mHtmlFmtIdx == CLIPX11FORMATIDX_NIL)
     2031        {
     2032             /* VBox thinks we have data and we don't */
     2033            rc = VERR_NO_DATA;
     2034        }
    19702035        else
    19712036            /* Send out a request for the data to the current clipboard
    19722037             * owner */
    1973             getSelectionValue(pCtx, pCtx->X11TextFormat, pReq);
    1974     }
    1975     else if (pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    1976     {
    1977         pReq->mBitmapFormat = pCtx->X11BitmapFormat;
    1978         if (pReq->mBitmapFormat == INVALID)
    1979             /* VBox thinks we have data and we don't */
    1980             rc = VERR_NO_DATA;
    1981         else
    1982             /* Send out a request for the data to the current clipboard
    1983              * owner */
    1984             getSelectionValue(pCtx, pCtx->X11BitmapFormat, pReq);
    1985     }
    1986     else if(pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_HTML)
    1987     {
    1988         /* Send out a request for the data to the current clipboard
    1989              * owner */
    1990         pReq->mHtmlFormat = pCtx->X11HTMLFormat;
    1991         if(pReq->mHtmlFormat == INVALID)
     2038            getSelectionValue(pCtx, pCtx->X11HTMLFmtIdx, pReq);
     2039    }
     2040#ifdef VBOX_WITH_SHARED_CLIPBOARD_URI_LIST
     2041    else if(pReq->mFormat == VBOX_SHARED_CLIPBOARD_FMT_URI_LIST)
     2042    {
     2043        /* Send out a request for the data to the current clipboard owner */
     2044        pReq->mURIListFmtIdx = pCtx->X11URListFmtIdx;
     2045        if(pReq->mURIListFmtIdx == CLIPX11FORMATIDX_NIL)
     2046        {
    19922047                    /* VBox thinks we have data and we don't */
    19932048            rc = VERR_NO_DATA;
     2049        }
    19942050        else
    1995             /* Send out a request for the data to the current clipboard
    1996              * owner */
    1997             getSelectionValue(pCtx, pCtx->X11HTMLFormat, pReq);
    1998     }
     2051        {
     2052            /* Send out a request for the data to the current clipboard owner */
     2053            getSelectionValue(pCtx, pCtx->X11HTMLFmtIdx, pReq);
     2054        }
     2055    }
     2056#endif
    19992057    else
    20002058    {
     
    20042062#endif
    20052063    }
     2064
    20062065    if (RT_FAILURE(rc))
    20072066    {
     
    20122071        RTMemFree(pReq);
    20132072    }
     2073
    20142074    LogRelFlowFunc(("status %Rrc\n", rc));
    20152075}
     
    20182078 * Called when VBox wants to read the X11 clipboard.
    20192079 *
    2020  * @returns iprt status code
    2021  * @param  pCtx      Context data for the clipboard backend
    2022  * @param  u32Format The format that the VBox would like to receive the data
    2023  *                   in
    2024  * @param  pv        Where to write the data to
    2025  * @param  cb        The size of the buffer to write the data to
    2026  * @param  pcbActual Where to write the actual size of the written data
    2027  * @note   We allocate a request structure which must be freed by the worker
    2028  */
    2029 int ClipRequestDataFromX11(CLIPBACKEND *pCtx, uint32_t u32Format,
     2080 * @returns IPRT status code.
     2081 * @param  pCtx      Context data for the clipboard backend.
     2082 * @param  vboxFormat The format that the VBox would like to receive the data in.
     2083 * @param  pv        Where to write the data to.
     2084 * @param  cb        The size of the buffer to write the data to.
     2085 * @param  pcbActual Where to write the actual size of the written data.
     2086 *
     2087 * @note   We allocate a request structure which must be freed by the worker.
     2088 */
     2089int ClipRequestDataFromX11(CLIPBACKEND *pCtx, VBOXCLIPBOARDFORMAT vboxFormat,
    20302090                           CLIPREADCBREQ *pReq)
    20312091{
     
    20422102    else
    20432103    {
    2044         pX11Req->mFormat = u32Format;
     2104        pX11Req->mFormat = vboxFormat;
    20452105        pX11Req->mCtx = pCtx;
    20462106        pX11Req->mReq = pReq;
     
    21162176
    21172177/* Return the data in the simulated VBox clipboard. */
    2118 int ClipRequestDataForX11(VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, void **ppv, uint32_t *pcb)
    2119 {
    2120     RT_NOREF2(pCtx, u32Format);
     2178int ClipRequestDataForX11(VBOXCLIPBOARDCONTEXT *pCtx, VBOXCLIPBOARDFORMAT vboxFormat, void **ppv, uint32_t *pcb)
     2179{
     2180    RT_NOREF(pCtx, vboxFormat);
    21212181    *pcb = g_vboxDatacb;
    21222182    if (g_vboxDatapv != NULL)
     
    21312191
    21322192Display *XtDisplay(Widget w)
    2133 { NOREF(w); return (Display *) 0xffff; }
    2134 
    2135 void XtAppSetExitFlag(XtAppContext app_context) { NOREF(app_context); }
    2136 
    2137 void XtDestroyWidget(Widget w) { NOREF(w); }
     2193{ RT_NOREF(w); return (Display *) 0xffff; }
     2194
     2195void XtAppSetExitFlag(XtAppContext app_context) { RT_NOREF(app_context); }
     2196
     2197void XtDestroyWidget(Widget w) { RT_NOREF(w); }
    21382198
    21392199XtAppContext XtCreateApplicationContext(void) { return (XtAppContext)0xffff; }
    21402200
    2141 void XtDestroyApplicationContext(XtAppContext app_context) { NOREF(app_context); }
     2201void XtDestroyApplicationContext(XtAppContext app_context) { RT_NOREF(app_context); }
    21422202
    21432203void XtToolkitInitialize(void) {}
     
    21632223}
    21642224
    2165 void XtSetMappedWhenManaged(Widget widget, _XtBoolean mapped_when_managed) { RT_NOREF2(widget, mapped_when_managed); }
    2166 
    2167 void XtRealizeWidget(Widget widget) { NOREF(widget); }
     2225void XtSetMappedWhenManaged(Widget widget, _XtBoolean mapped_when_managed) { RT_NOREF(widget, mapped_when_managed); }
     2226
     2227void XtRealizeWidget(Widget widget) { RT_NOREF(widget); }
    21682228
    21692229XtInputId XtAppAddInput(XtAppContext app_context, int source, XtPointer condition, XtInputCallbackProc proc, XtPointer closure)
     
    22122272void testRequestData(CLIPBACKEND *pCtx, CLIPX11FORMAT target, void *closure)
    22132273{
    2214     RT_NOREF1(pCtx);
     2274    RT_NOREF(pCtx);
    22152275    unsigned long count = 0;
    22162276    int format = 0;
     
    22392299void ClipReportX11Formats(VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Formats)
    22402300{
    2241     RT_NOREF1(pCtx);
     2301    RT_NOREF(pCtx);
    22422302    g_fX11Formats = u32Formats;
    22432303}
     
    22682328                       XtSelectionDoneProc done)
    22692329{
    2270     RT_NOREF2(widget, time);
     2330    RT_NOREF(widget, time);
    22712331    if (selection != XInternAtom(NULL, "CLIPBOARD", 0))
    22722332        return True;  /* We don't really care about this. */
     
    23192379{
    23202380    Atom clipAtom = XInternAtom(NULL, "CLIPBOARD", 0);
    2321     g_selTargets[0] = clipFindX11FormatByAtomText(pcszTarget);
     2381    g_selTargets[0] = clipGetFmtIdxFromAtomText(pcszTarget);
    23222382    g_cTargets = 1;
    23232383    g_selType = type;
     
    23452405char *XGetAtomName(Display *display, Atom atom)
    23462406{
    2347     RT_NOREF1(display);
     2407    RT_NOREF(display);
    23482408    AssertReturn((unsigned)atom < RT_ELEMENTS(g_aFormats) + 1, NULL);
    23492409    const char *pcszName = NULL;
     
    23872447void ClipCompleteDataRequestFromX11(VBOXCLIPBOARDCONTEXT *pCtx, int rc, CLIPREADCBREQ *pReq, void *pv, uint32_t cb)
    23882448{
    2389     RT_NOREF1(pCtx);
     2449    RT_NOREF(pCtx);
    23902450    if (cb <= MAX_BUF_SIZE)
    23912451    {
     
    25402600static void testStringFromVBox(RTTEST hTest, CLIPBACKEND *pCtx, const char *pcszTarget, Atom typeExp,  const char *valueExp)
    25412601{
    2542     RT_NOREF1(pCtx);
     2602    RT_NOREF(pCtx);
    25432603    bool retval = false;
    25442604    Atom type;
     
    25812641static void testStringFromVBoxFailed(RTTEST hTest, CLIPBACKEND *pCtx, const char *pcszTarget)
    25822642{
    2583     RT_NOREF1(pCtx);
     2643    RT_NOREF(pCtx);
    25842644    Atom type;
    25852645    XtPointer value = NULL;
     
    25962656static void testNoSelectionOwnership(CLIPBACKEND *pCtx, const char *pcszTestCtx)
    25972657{
    2598     RT_NOREF1(pCtx);
     2658    RT_NOREF(pCtx);
    25992659    RTTESTI_CHECK_MSG(!g_ownsSel, ("context: %s\n", pcszTestCtx));
    26002660}
     
    26222682        clipSendTargetUpdate(pCtx);
    26232683        if (clipQueryFormats() == VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    2624             RTTestFailed(hTest, "Failed to report targets after bad host request.\n");
     2684            RTTestFailed(hTest, "Failed to report targets after bad host request\n");
    26252685    }
    26262686}
     
    28892949void ClipReportX11Formats(VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Formats)
    28902950{
    2891     RT_NOREF2(pCtx, u32Formats);
     2951    RT_NOREF(pCtx, u32Formats);
    28922952}
    28932953
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h

    r78580 r78581  
    4949    struct {
    5050        VBOXHGCMCALLHANDLE callHandle;
    51         VBOXHGCMSVCPARM *paParms;
     51        VBOXHGCMSVCPARM   *paParms;
    5252    } async;
    5353
    5454    struct {
    5555        VBOXHGCMCALLHANDLE callHandle;
    56         VBOXHGCMSVCPARM *paParms;
     56        VBOXHGCMSVCPARM   *paParms;
    5757    } asyncRead;
    5858
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc-x11.cpp

    r78580 r78581  
    507507}
    508508
    509 void ClipAnnounceFormatToX11(CLIPBACKEND *pBackend, uint32_t u32Formats)
    510 {
    511     pBackend->formats = u32Formats;
    512 }
    513 
    514 extern int ClipRequestDataFromX11(CLIPBACKEND *pBackend, uint32_t u32Format,
     509void ClipAnnounceFormatToX11(CLIPBACKEND *pBackend, VBOXCLIPBOARDFORMATS vboxFormats)
     510{
     511    pBackend->formats = vboxFormats;
     512}
     513
     514extern int ClipRequestDataFromX11(CLIPBACKEND *pBackend, VBOXCLIPBOARDFORMAT vboxFormat,
    515515                                  CLIPREADCBREQ *pReq)
    516516{
    517     pBackend->readData.format = u32Format;
     517    pBackend->readData.format = vboxFormat;
    518518    pBackend->readData.pReq = pReq;
    519519    return pBackend->readData.rc;
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r78580 r78581  
    513513                uint32_t u32Formats;
    514514
    515                 rc = VBoxHGCMParmUInt32Get (&paParms[0], &u32Formats);
     515                rc = VBoxHGCMParmUInt32Get(&paParms[0], &u32Formats);
    516516
    517517                if (RT_SUCCESS (rc))
     
    562562                uint32_t cb;
    563563
    564                 rc = VBoxHGCMParmUInt32Get (&paParms[0], &u32Format);
     564                rc = VBoxHGCMParmUInt32Get(&paParms[0], &u32Format);
    565565
    566566                if (RT_SUCCESS (rc))
    567567                {
    568                     rc = VBoxHGCMParmPtrGet (&paParms[1], &pv, &cb);
     568                    rc = VBoxHGCMParmPtrGet(&paParms[1], &pv, &cb);
    569569
    570570                    if (RT_SUCCESS (rc))
     
    629629                        else if (RT_SUCCESS (rc))
    630630                        {
    631                             VBoxHGCMParmUInt32Set (&paParms[2], cbActual);
     631                            VBoxHGCMParmUInt32Set(&paParms[2], cbActual);
    632632                        }
    633633                    }
     
    657657                uint32_t u32Format;
    658658
    659                 rc = VBoxHGCMParmUInt32Get (&paParms[0], &u32Format);
     659                rc = VBoxHGCMParmUInt32Get(&paParms[0], &u32Format);
    660660
    661661                if (RT_SUCCESS (rc))
    662662                {
    663                     rc = VBoxHGCMParmPtrGet (&paParms[1], &pv, &cb);
     663                    rc = VBoxHGCMParmPtrGet(&paParms[1], &pv, &cb);
    664664
    665665                    if (RT_SUCCESS (rc))
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