VirtualBox

Ignore:
Timestamp:
Apr 17, 2019 12:03:42 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
130066
Message:

Shared Clipboard: Got rid of a lot of duplicated code between Windows hosts / guests, plus a lot of renaming / cleanup, some more documentation.

Location:
trunk/src/VBox/HostServices/SharedClipboard
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/SharedClipboard/Makefile.kmk

    r76970 r78151  
    3535VBoxSharedClipboard_SOURCES.win = \
    3636        VBoxClipboard-win.cpp \
     37        $(PATH_ROOT)/src/VBox/GuestHost/SharedClipboard/clipboard-win.cpp \
    3738        VBoxSharedClipboardSvc.rc
    3839VBoxSharedClipboard_SOURCES.darwin = \
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard-win.cpp

    r76553 r78151  
    2424
    2525#include <VBox/HostServices/VBoxClipboardSvc.h>
     26#include <VBox/GuestHost/SharedClipboard-win.h>
    2627
    2728#include <iprt/alloc.h>
     
    3536#include "VBoxClipboard.h"
    3637
    37 #define dprintf Log
    38 
    39 static char gachWindowClassName[] = "VBoxSharedClipboardClass";
    40 
    41 enum { CBCHAIN_TIMEOUT = 5000 /* ms */ };
    42 
    43 /* Dynamically load clipboard functions from User32.dll. */
    44 typedef BOOL WINAPI FNADDCLIPBOARDFORMATLISTENER(HWND);
    45 typedef FNADDCLIPBOARDFORMATLISTENER *PFNADDCLIPBOARDFORMATLISTENER;
    46 
    47 typedef BOOL WINAPI FNREMOVECLIPBOARDFORMATLISTENER(HWND);
    48 typedef FNREMOVECLIPBOARDFORMATLISTENER *PFNREMOVECLIPBOARDFORMATLISTENER;
    49 
     38/** Static window class name. */
     39static char s_szClipWndClassName[] = VBOX_CLIPBOARD_WNDCLASS_NAME;
    5040
    5141/*********************************************************************************************************************************
     
    5545static int ConvertMimeToCFHTML(const char *pszSource, size_t cb, char **ppszOutput, uint32_t *pcbOutput);
    5646static bool IsWindowsHTML(const char *source);
    57 
    58 
    59 #ifndef WM_CLIPBOARDUPDATE
    60 #define WM_CLIPBOARDUPDATE 0x031D
    61 #endif
     47static int vboxClipboardSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx);
    6248
    6349struct _VBOXCLIPBOARDCONTEXT
    6450{
    65     HWND    hwnd;
    66     HWND    hwndNextInChain;
    67 
    68     UINT     timerRefresh;
    69 
    70     bool     fCBChainPingInProcess;
    71 
    72     RTTHREAD thread;
    73 
    74     HANDLE hRenderEvent;
    75 
    76     VBOXCLIPBOARDCLIENTDATA *pClient;
    77 
    78     PFNADDCLIPBOARDFORMATLISTENER    pfnAddClipboardFormatListener;
    79     PFNREMOVECLIPBOARDFORMATLISTENER pfnRemoveClipboardFormatListener;
    80 
     51    /** Handle for window message handling thread. */
     52    RTTHREAD                 hThread;
     53    /** Event which gets triggered if the host clipboard needs to render its data. */
     54    HANDLE                   hRenderEvent;
     55    /** Structure for keeping and communicating with client data (from the guest). */
     56    PVBOXCLIPBOARDCLIENTDATA pClient;
     57    /** Windows-specific context data. */
     58    VBOXCLIPBOARDWINCTX      Win;
    8159};
    8260
     
    8664
    8765#ifdef LOG_ENABLED
    88 void vboxClipboardDump(const void *pv, size_t cb, uint32_t u32Format)
     66static void vboxClipboardDump(const void *pv, size_t cb, uint32_t u32Format)
    8967{
    9068    if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    9169    {
    92         Log(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT:\n"));
     70        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT:\n"));
    9371        if (pv && cb)
    94             Log(("%ls\n", pv));
     72            LogFunc(("%ls\n", pv));
    9573        else
    96             Log(("%p %d\n", pv, cb));
     74            LogFunc(("%p %zu\n", pv, cb));
    9775    }
    9876    else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    99         dprintf(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
     77        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
    10078    else if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_HTML)
    10179    {
    102         Log(("DUMP: VBOX_SHARED_CLIPBOARD_FMT_HTML:\n"));
     80        LogFunc(("VBOX_SHARED_CLIPBOARD_FMT_HTML:\n"));
    10381        if (pv && cb)
    10482        {
    105             Log(("%s\n", pv));
     83            LogFunc(("%s\n", pv));
    10684
    10785            //size_t cb = RTStrNLen(pv, );
     
    11492            }
    11593
    116             Log(("%s\n", pszBuf));
     94            LogFunc(("%s\n", pszBuf));
    11795            RTMemFree(pszBuf);
    11896        }
    11997        else
    120             Log(("%p %d\n", pv, cb));
     98            LogFunc(("%p %zu\n", pv, cb));
    12199    }
    122100    else
    123         dprintf(("DUMP: invalid format %02X\n", u32Format));
     101        LogFunc(("Invalid format %02X\n", u32Format));
    124102}
    125103#else  /* !LOG_ENABLED */
     
    127105#endif /* !LOG_ENABLED */
    128106
    129 
    130 static void vboxClipboardInitNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
    131 {
    132     RTLDRMOD hUser32 = NIL_RTLDRMOD;
    133     int rc = RTLdrLoadSystem("User32.dll", /* fNoUnload = */ true, &hUser32);
    134     if (RT_SUCCESS(rc))
    135     {
    136         rc = RTLdrGetSymbol(hUser32, "AddClipboardFormatListener", (void**)&pCtx->pfnAddClipboardFormatListener);
    137         if (RT_SUCCESS(rc))
    138         {
    139             rc = RTLdrGetSymbol(hUser32, "RemoveClipboardFormatListener", (void**)&pCtx->pfnRemoveClipboardFormatListener);
    140         }
    141 
    142         RTLdrClose(hUser32);
    143     }
    144 
    145     if (RT_SUCCESS(rc))
    146     {
    147         Log(("New Clipboard API is enabled\n"));
    148     }
    149     else
    150     {
    151         pCtx->pfnAddClipboardFormatListener = NULL;
    152         pCtx->pfnRemoveClipboardFormatListener = NULL;
    153         Log(("New Clipboard API is not available. rc = %Rrc\n", rc));
    154     }
    155 }
    156 
    157 static bool vboxClipboardIsNewAPI(VBOXCLIPBOARDCONTEXT *pCtx)
    158 {
    159     return pCtx->pfnAddClipboardFormatListener != NULL;
    160 }
    161 
    162 
    163 static int vboxOpenClipboard(HWND hwnd)
    164 {
    165     /* "OpenClipboard fails if another window has the clipboard open."
    166      * So try a few times and wait up to 1 second.
    167      */
    168     BOOL fOpened = FALSE;
    169 
    170     int i = 0;
    171     for (;;)
    172     {
    173         if (OpenClipboard(hwnd))
    174         {
    175             fOpened = TRUE;
    176             break;
    177         }
    178 
    179         if (i >= 10) /* sleep interval = [1..512] ms */
    180             break;
    181 
    182         RTThreadSleep(1 << i);
    183         ++i;
    184     }
    185 
    186 #ifdef LOG_ENABLED
    187     if (i > 0)
    188         LogFlowFunc(("%d times tried to open clipboard.\n", i + 1));
    189 #endif
    190 
    191     int rc;
    192     if (fOpened)
    193         rc = VINF_SUCCESS;
    194     else
    195     {
    196         const DWORD err = GetLastError();
    197         LogFlowFunc(("error %d\n", err));
    198         rc = RTErrConvertFromWin32(err);
    199     }
    200 
    201     return rc;
    202 }
    203 
    204 
    205107/** @todo Someone please explain the protocol wrt overflows...  */
    206108static void vboxClipboardGetData (uint32_t u32Format, const void *pvSrc, uint32_t cbSrc,
    207109                                  void *pvDst, uint32_t cbDst, uint32_t *pcbActualDst)
    208110{
    209     dprintf (("vboxClipboardGetData.\n"));
    210 
    211111    LogFlow(("vboxClipboardGetData cbSrc = %d, cbDst = %d\n", cbSrc, cbDst));
    212112
     
    270170}
    271171
    272 static void vboxClipboardChanged (VBOXCLIPBOARDCONTEXT *pCtx)
    273 {
    274     LogFlow(("vboxClipboardChanged\n"));
    275 
    276     if (pCtx->pClient == NULL)
    277     {
    278         return;
    279     }
    280 
    281     /* Query list of available formats and report to host. */
    282     int rc = vboxOpenClipboard(pCtx->hwnd);
    283     if (RT_SUCCESS(rc))
    284     {
    285         uint32_t u32Formats = 0;
    286 
    287         UINT format = 0;
    288 
    289         while ((format = EnumClipboardFormats (format)) != 0)
    290         {
    291             LogFlow(("vboxClipboardChanged format %#x\n", format));
    292             switch (format)
    293             {
    294                 case CF_UNICODETEXT:
    295                 case CF_TEXT:
    296                     u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT;
    297                     break;
    298 
    299                 case CF_DIB:
    300                 case CF_BITMAP:
    301                     u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_BITMAP;
    302                     break;
    303 
    304                 default:
    305                     if (format >= 0xC000)
    306                     {
    307                         TCHAR szFormatName[256];
    308 
    309                         int cActual = GetClipboardFormatName(format, szFormatName, sizeof(szFormatName)/sizeof (TCHAR));
    310 
    311                         if (cActual)
    312                         {
    313                             if (strcmp (szFormatName, "HTML Format") == 0)
    314                             {
    315                                 u32Formats |= VBOX_SHARED_CLIPBOARD_FMT_HTML;
    316                             }
    317                         }
    318                     }
    319                     break;
    320             }
    321         }
    322 
    323         CloseClipboard ();
    324 
    325         LogFlow(("vboxClipboardChanged u32Formats %02X\n", u32Formats));
    326 
    327         vboxSvcClipboardReportMsg (pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, u32Formats);
    328     }
    329     else
    330     {
    331         LogFlow(("vboxClipboardChanged: error in open clipboard. hwnd: %x. err: %Rrc\n", pCtx->hwnd, rc));
    332     }
    333 }
    334 
    335 /* Add ourselves into the chain of cliboard listeners */
    336 static void addToCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
    337 {
    338     if (vboxClipboardIsNewAPI(pCtx))
    339         pCtx->pfnAddClipboardFormatListener(pCtx->hwnd);
    340     else
    341         pCtx->hwndNextInChain = SetClipboardViewer(pCtx->hwnd);
    342 }
    343 
    344 /* Remove ourselves from the chain of cliboard listeners */
    345 static void removeFromCBChain (VBOXCLIPBOARDCONTEXT *pCtx)
    346 {
    347     if (vboxClipboardIsNewAPI(pCtx))
    348     {
    349         pCtx->pfnRemoveClipboardFormatListener(pCtx->hwnd);
    350     }
    351     else
    352     {
    353         ChangeClipboardChain(pCtx->hwnd, pCtx->hwndNextInChain);
    354         pCtx->hwndNextInChain = NULL;
    355     }
    356 }
    357 
    358 /* Callback which is invoked when we have successfully pinged ourselves down the
    359  * clipboard chain.  We simply unset a boolean flag to say that we are responding.
    360  * There is a race if a ping returns after the next one is initiated, but nothing
    361  * very bad is likely to happen. */
    362 VOID CALLBACK CBChainPingProc(HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
    363 {
    364     (void) hwnd;
    365     (void) uMsg;
    366     (void) lResult;
    367     VBOXCLIPBOARDCONTEXT *pCtx = (VBOXCLIPBOARDCONTEXT *)dwData;
    368     pCtx->fCBChainPingInProcess = FALSE;
    369 }
    370 
    371172static LRESULT CALLBACK vboxClipboardWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    372173{
    373174    LRESULT rc = 0;
    374175
    375     VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;
     176    PVBOXCLIPBOARDCONTEXT pCtx = &g_ctx;
    376177
    377178    switch (msg)
     
    383184            if (GetClipboardOwner() != hwnd)
    384185            {
    385                 /* Clipboard was updated by another application. */
    386                 vboxClipboardChanged(pCtx);
     186                /* Clipboard was updated by another application, retrieve formats and report back. */
     187                int vboxrc = vboxClipboardSyncInternal(pCtx);
     188                AssertRC(vboxrc);
    387189            }
    388190        } break;
     
    392194            Log(("WM_CHANGECBCHAIN\n"));
    393195
    394             if (vboxClipboardIsNewAPI(pCtx))
     196            if (VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI))
    395197            {
    396198                rc = DefWindowProc(hwnd, msg, wParam, lParam);
     
    401203            HWND hwndNext    = (HWND)lParam;
    402204
    403             if (hwndRemoved == pCtx->hwndNextInChain)
     205            if (hwndRemoved == pCtx->Win.hWndNextInChain)
    404206            {
    405207                /* The window that was next to our in the chain is being removed.
    406208                 * Relink to the new next window.
    407209                 */
    408                 pCtx->hwndNextInChain = hwndNext;
     210                pCtx->Win.hWndNextInChain = hwndNext;
    409211            }
    410212            else
    411213            {
    412                 if (pCtx->hwndNextInChain)
     214                if (pCtx->Win.hWndNextInChain)
    413215                {
    414216                    /* Pass the message further. */
    415217                    DWORD_PTR dwResult;
    416                     rc = SendMessageTimeout(pCtx->hwndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
     218                    rc = SendMessageTimeout(pCtx->Win.hWndNextInChain, WM_CHANGECBCHAIN, wParam, lParam, 0,
     219                                            VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS,
     220                                            &dwResult);
    417221                    if (!rc)
    418222                        rc = (LRESULT)dwResult;
     
    425229            Log(("WM_DRAWCLIPBOARD\n"));
    426230
    427             if (GetClipboardOwner () != hwnd)
    428             {
    429                 /* Clipboard was updated by another application. */
    430                 vboxClipboardChanged (pCtx);
    431             }
    432 
    433             if (pCtx->hwndNextInChain)
    434             {
    435                 Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->hwndNextInChain));
     231            if (GetClipboardOwner() != hwnd)
     232            {
     233                /* Clipboard was updated by another application, retrieve formats and report back. */
     234                int vboxrc = vboxClipboardSyncInternal(pCtx);
     235                AssertRC(vboxrc);
     236            }
     237
     238            if (pCtx->Win.hWndNextInChain)
     239            {
     240                Log(("WM_DRAWCLIPBOARD next %p\n", pCtx->Win.hWndNextInChain));
    436241                /* Pass the message to next windows in the clipboard chain. */
    437242                DWORD_PTR dwResult;
    438                 rc = SendMessageTimeout(pCtx->hwndNextInChain, msg, wParam, lParam, 0, CBCHAIN_TIMEOUT, &dwResult);
     243                rc = SendMessageTimeout(pCtx->Win.hWndNextInChain, msg, wParam, lParam, 0, VBOX_CLIPBOARD_CBCHAIN_TIMEOUT_MS,
     244                                        &dwResult);
    439245                if (!rc)
    440246                    rc = dwResult;
     
    444250        case WM_TIMER:
    445251        {
    446             if (vboxClipboardIsNewAPI(pCtx))
     252            if (VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI))
    447253                break;
    448254
     
    451257            /* Re-register ourselves in the clipboard chain if our last ping
    452258             * timed out or there seems to be no valid chain. */
    453             if (!hViewer || pCtx->fCBChainPingInProcess)
    454             {
    455                 removeFromCBChain(pCtx);
    456                 addToCBChain(pCtx);
    457             }
     259            if (!hViewer || pCtx->Win.oldAPI.fCBChainPingInProcess)
     260            {
     261                VBoxClipboardWinRemoveFromCBChain(&pCtx->Win);
     262                VBoxClipboardWinAddToCBChain(&pCtx->Win);
     263            }
     264
    458265            /* Start a new ping by passing a dummy WM_CHANGECBCHAIN to be
    459266             * processed by ourselves to the chain. */
    460             pCtx->fCBChainPingInProcess = TRUE;
     267            pCtx->Win.oldAPI.fCBChainPingInProcess = TRUE;
     268
    461269            hViewer = GetClipboardViewer();
    462270            if (hViewer)
    463                 SendMessageCallback(hViewer, WM_CHANGECBCHAIN, (WPARAM)pCtx->hwndNextInChain, (LPARAM)pCtx->hwndNextInChain, CBChainPingProc, (ULONG_PTR) pCtx);
     271                SendMessageCallback(hViewer, WM_CHANGECBCHAIN,
     272                                    (WPARAM)pCtx->Win.hWndNextInChain, (LPARAM)pCtx->Win.hWndNextInChain,
     273                                    VBoxClipboardWinChainPingProc, (ULONG_PTR)pCtx);
    464274        } break;
    465275
     
    511321                int vboxrc = vboxClipboardReadDataFromClient (pCtx, u32Format);
    512322
    513                 dprintf(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",
     323                LogFunc(("vboxClipboardReadDataFromClient vboxrc = %d, pv %p, cb %d, u32Format %d\n",
    514324                          vboxrc, pCtx->pClient->data.pv, pCtx->pClient->data.cb, pCtx->pClient->data.u32Format));
    515325
     
    521331                    HANDLE hMem = GlobalAlloc (GMEM_DDESHARE | GMEM_MOVEABLE, pCtx->pClient->data.cb);
    522332
    523                     dprintf(("hMem %p\n", hMem));
     333                    LogFunc(("hMem %p\n", hMem));
    524334
    525335                    if (hMem)
     
    527337                        void *pMem = GlobalLock (hMem);
    528338
    529                         dprintf(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));
     339                        LogFunc(("pMem %p, GlobalSize %d\n", pMem, GlobalSize (hMem)));
    530340
    531341                        if (pMem)
     
    552362                            HANDLE hClip = SetClipboardData (format, hMem);
    553363
    554                             dprintf(("vboxClipboardHostEvent hClip %p\n", hClip));
     364                            LogFunc(("vboxClipboardHostEvent hClip %p\n", hClip));
    555365
    556366                            if (hClip)
     
    571381
    572382                /* Something went wrong. */
    573                 EmptyClipboard ();
     383                VBoxClipboardWinClear();
    574384            }
    575385        } break;
     
    582392             * windows is to be destroyed and therefore the guest side becomes inactive.
    583393             */
    584             int vboxrc = vboxOpenClipboard(hwnd);
     394            int vboxrc = VBoxClipboardWinOpen(hwnd);
    585395            if (RT_SUCCESS(vboxrc))
    586396            {
    587                 EmptyClipboard();
    588 
    589                 CloseClipboard();
     397                VBoxClipboardWinClear();
     398                VBoxClipboardWinClose();
    590399            }
    591400            else
     
    595404        } break;
    596405
    597         case WM_USER:
     406        case VBOX_CLIPBOARD_WM_SET_FORMATS:
    598407        {
    599408            if (pCtx->pClient == NULL || pCtx->pClient->fMsgFormats)
     
    602411                 * because host clipboard has more priority.
    603412                 */
    604                 Log(("WM_USER ignored\n"));
     413                Log(("VBOX_CLIPBOARD_WM_SET_FORMATS ignored\n"));
    605414                break;
    606415            }
     
    609418            uint32_t u32Formats = (uint32_t)lParam;
    610419
    611             Log(("WM_USER u32Formats = %02X\n", u32Formats));
    612 
    613             int vboxrc = vboxOpenClipboard(hwnd);
     420            Log(("VBOX_CLIPBOARD_WM_SET_FORMATS: u32Formats=%02X\n", u32Formats));
     421
     422            int vboxrc = VBoxClipboardWinOpen(hwnd);
    614423            if (RT_SUCCESS(vboxrc))
    615424            {
    616                 EmptyClipboard();
    617 
    618                 Log(("WM_USER emptied clipboard\n"));
     425                VBoxClipboardWinClear();
     426
     427                Log(("VBOX_CLIPBOARD_WM_SET_FORMATS emptied clipboard\n"));
    619428
    620429                HANDLE hClip = NULL;
    621430
    622431                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
    623                 {
    624                     dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));
    625 
    626                     hClip = SetClipboardData (CF_UNICODETEXT, NULL);
    627                 }
     432                    hClip = SetClipboardData(CF_UNICODETEXT, NULL);
    628433
    629434                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
    630                 {
    631                     dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
    632 
    633                     hClip = SetClipboardData (CF_DIB, NULL);
    634                 }
     435                    hClip = SetClipboardData(CF_DIB, NULL);
    635436
    636437                if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
    637438                {
    638439                    UINT format = RegisterClipboardFormat ("HTML Format");
    639                     dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_HTML 0x%04X\n", format));
    640440                    if (format != 0)
    641441                    {
     
    644444                }
    645445
    646                 CloseClipboard();
    647 
    648                 dprintf(("window proc WM_USER: hClip %p, err %d\n", hClip, GetLastError ()));
    649             }
    650             else
    651             {
    652                 dprintf(("window proc WM_USER: failed to open clipboard. rc: %Rrc\n", vboxrc));
     446                VBoxClipboardWinClose();
     447
     448                LogFunc(("VBOX_CLIPBOARD_WM_SET_FORMATS: hClip=%p, lastErr=%ld\n", hClip, GetLastError ()));
    653449            }
    654450        } break;
     
    656452        case WM_DESTROY:
    657453        {
    658             /* MS recommends to remove from Clipboard chain in this callback */
    659             Assert(pCtx->hwnd);
    660             removeFromCBChain(pCtx);
    661             if (pCtx->timerRefresh)
    662                 KillTimer(pCtx->hwnd, 0);
     454            /* MS recommends to remove from Clipboard chain in this callback. */
     455            VBoxClipboardWinRemoveFromCBChain(&pCtx->Win);
     456            if (pCtx->Win.oldAPI.timerRefresh)
     457            {
     458                Assert(pCtx->Win.hWnd);
     459                KillTimer(pCtx->Win.hWnd, 0);
     460            }
    663461            PostQuitMessage(0);
    664462        } break;
     
    683481    LogFlow(("VBoxClipboardThread\n"));
    684482
    685     VBOXCLIPBOARDCONTEXT *pCtx = &g_ctx;
     483    const PVBOXCLIPBOARDCONTEXT pCtx = &g_ctx;
    686484
    687485    HINSTANCE hInstance = (HINSTANCE)GetModuleHandle(NULL);
     
    695493    wc.hInstance     = hInstance;
    696494    wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
    697     wc.lpszClassName = gachWindowClassName;
     495    wc.lpszClassName = s_szClipWndClassName;
    698496
    699497    ATOM atomWindowClass = RegisterClass(&wc);
     
    707505    {
    708506        /* Create the window. */
    709         pCtx->hwnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
    710                                      gachWindowClassName, gachWindowClassName,
    711                                      WS_POPUPWINDOW,
    712                                      -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
    713 
    714         if (pCtx->hwnd == NULL)
     507        pCtx->Win.hWnd = CreateWindowEx (WS_EX_TOOLWINDOW | WS_EX_TRANSPARENT | WS_EX_TOPMOST,
     508                                         s_szClipWndClassName, s_szClipWndClassName,
     509                                         WS_POPUPWINDOW,
     510                                         -200, -200, 100, 100, NULL, NULL, hInstance, NULL);
     511        if (pCtx->Win.hWnd == NULL)
    715512        {
    716513            Log(("Failed to create window\n"));
     
    719516        else
    720517        {
    721             SetWindowPos(pCtx->hwnd, HWND_TOPMOST, -200, -200, 0, 0,
     518            SetWindowPos(pCtx->Win.hWnd, HWND_TOPMOST, -200, -200, 0, 0,
    722519                         SWP_NOACTIVATE | SWP_HIDEWINDOW | SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_NOSIZE);
    723520
    724             addToCBChain(pCtx);
    725             if (!vboxClipboardIsNewAPI(pCtx))
    726                 pCtx->timerRefresh = SetTimer(pCtx->hwnd, 0, 10 * 1000, NULL);
     521            VBoxClipboardWinAddToCBChain(&pCtx->Win);
     522            if (!VBoxClipboardWinIsNewAPI(&pCtx->Win.newAPI))
     523                pCtx->Win.oldAPI.timerRefresh = SetTimer(pCtx->Win.hWnd, 0, 10 * 1000, NULL);
    727524
    728525            MSG msg;
     
    743540    }
    744541
    745     pCtx->hwnd = NULL;
     542    pCtx->Win.hWnd = NULL;
    746543
    747544    if (atomWindowClass != 0)
    748545    {
    749         UnregisterClass (gachWindowClassName, hInstance);
     546        UnregisterClass (s_szClipWndClassName, hInstance);
    750547        atomWindowClass = 0;
    751548    }
    752549
    753550    return 0;
     551}
     552
     553/**
     554 * Synchronizes the host and the guest clipboard formats by sending all supported host clipboard
     555 * formats to the guest.
     556 *
     557 * @returns VBox status code.
     558 * @param   pCtx                Clipboard context to synchronize.
     559 */
     560static int vboxClipboardSyncInternal(PVBOXCLIPBOARDCONTEXT pCtx)
     561{
     562    uint32_t uFormats;
     563    int rc = VBoxClipboardWinGetFormats(&pCtx->Win, &uFormats);
     564    if (RT_SUCCESS(rc))
     565        vboxSvcClipboardReportMsg(pCtx->pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS, uFormats);
     566
     567    return rc;
    754568}
    755569
     
    763577    RT_ZERO(g_ctx);
    764578
    765     /* Check that new Clipboard API is available */
    766     vboxClipboardInitNewAPI(&g_ctx);
     579    /* Check that new Clipboard API is available. */
     580    VBoxClipboardWinCheckAndInitNewAPI(&g_ctx.Win.newAPI);
    767581
    768582    g_ctx.hRenderEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    769583
    770     rc = RTThreadCreate (&g_ctx.thread, VBoxClipboardThread, NULL, 65536,
     584    rc = RTThreadCreate (&g_ctx.hThread, VBoxClipboardThread, NULL, 65536,
    771585                         RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SHCLIP");
    772586
     
    783597    Log(("vboxClipboardDestroy\n"));
    784598
    785     if (g_ctx.hwnd)
    786     {
    787         PostMessage (g_ctx.hwnd, WM_CLOSE, 0, 0);
     599    if (g_ctx.Win.hWnd)
     600    {
     601        PostMessage (g_ctx.Win.hWnd, WM_CLOSE, 0, 0);
    788602    }
    789603
     
    791605
    792606    /* Wait for the window thread to terminate. */
    793     RTThreadWait (g_ctx.thread, RT_INDEFINITE_WAIT, NULL);
    794 
    795     g_ctx.thread = NIL_RTTHREAD;
     607    RTThreadWait (g_ctx.hThread, RT_INDEFINITE_WAIT, NULL);
     608
     609    g_ctx.hThread = NIL_RTTHREAD;
    796610}
    797611
     
    820634{
    821635    /* Sync the host clipboard content with the client. */
    822     vboxClipboardChanged (pClient->pCtx);
    823 
    824     return VINF_SUCCESS;
     636    return vboxClipboardSyncInternal(pClient->pCtx);
    825637}
    826638
     
    838650     * The guest announces formats. Forward to the window thread.
    839651     */
    840     PostMessage (pClient->pCtx->hwnd, WM_USER, 0, u32Formats);
     652    PostMessage (pClient->pCtx->Win.hWnd, WM_USER, 0, u32Formats);
    841653}
    842654
     
    880692     * The guest wants to read data in the given format.
    881693     */
    882     int rc = vboxOpenClipboard(pClient->pCtx->hwnd);
     694    int rc = VBoxClipboardWinOpen(pClient->pCtx->Win.hWnd);
    883695    if (RT_SUCCESS(rc))
    884696    {
    885         dprintf(("Clipboard opened.\n"));
     697        LogFunc(("Clipboard opened.\n"));
    886698
    887699        if (u32Format & VBOX_SHARED_CLIPBOARD_FMT_BITMAP)
     
    895707                if (lp != NULL)
    896708                {
    897                     dprintf(("CF_DIB\n"));
     709                    LogFunc(("CF_DIB\n"));
    898710
    899711                    vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_BITMAP, lp, GlobalSize (hClip),
     
    918730                if (uniString != NULL)
    919731                {
    920                     dprintf(("CF_UNICODETEXT\n"));
     732                    LogFunc(("CF_UNICODETEXT\n"));
    921733
    922734                    vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT, uniString, (lstrlenW (uniString) + 1) * 2,
     
    945757                    if (lp != NULL)
    946758                    {
    947                         dprintf(("CF_HTML\n"));
     759                        LogFunc(("CF_HTML\n"));
    948760
    949761                        vboxClipboardGetData (VBOX_SHARED_CLIPBOARD_FMT_HTML, lp, GlobalSize (hClip),
     
    961773        }
    962774
    963         CloseClipboard ();
     775        VBoxClipboardWinClose();
    964776    }
    965777    else
    966778    {
    967         dprintf(("vboxClipboardReadData: failed to open clipboard, rc: %Rrc\n", rc));
     779        LogFunc(("vboxClipboardReadData: failed to open clipboard, rc: %Rrc\n", rc));
    968780    }
    969781
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxClipboard.h

    r76570 r78151  
    2525#include <VBox/log.h>
    2626
    27 struct _VBOXCLIPBOARDCONTEXT;
    28 typedef struct _VBOXCLIPBOARDCONTEXT VBOXCLIPBOARDCONTEXT;
    29 
     27#include <VBox/GuestHost/SharedClipboard.h>
    3028
    3129typedef struct _VBOXCLIPBOARDCLIENTDATA
     
    6462    uint32_t u32RequestedFormat;
    6563
    66 } VBOXCLIPBOARDCLIENTDATA;
     64} VBOXCLIPBOARDCLIENTDATA, *PVBOXCLIPBOARDCLIENTDATA;
    6765
    6866/*
    6967 * The service functions. Locking is between the service thread and the platform dependent windows thread.
    7068 */
    71 bool vboxSvcClipboardLock (void);
    72 void vboxSvcClipboardUnlock (void);
    73 
    7469void vboxSvcClipboardReportMsg (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Msg, uint32_t u32Formats);
    75 
    7670void vboxSvcClipboardCompleteReadData(VBOXCLIPBOARDCLIENTDATA *pClient, int rc, uint32_t cbActual);
    77 
    78 bool vboxSvcClipboardGetHeadless(void);
    7971
    8072/*
     
    8678int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless);
    8779void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient);
    88 
    8980void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Formats);
    90 
    9181int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual);
    92 
    9382void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv, uint32_t cb, uint32_t u32Format);
    9483
  • trunk/src/VBox/HostServices/SharedClipboard/VBoxSharedClipboardSvc.cpp

    r76970 r78151  
    109109static bool g_fHeadless = false;
    110110
     111static bool vboxSvcClipboardGetHeadless(void);
     112static bool vboxSvcClipboardLock(void);
     113static void vboxSvcClipboardUnlock(void);
     114
    111115
    112116static void VBoxHGCMParmUInt32Set (VBOXHGCMSVCPARM *pParm, uint32_t u32)
     
    163167
    164168/** Getter for headless setting */
    165 bool vboxSvcClipboardGetHeadless(void)
     169static bool vboxSvcClipboardGetHeadless(void)
    166170{
    167171    return g_fHeadless;
     
    184188}
    185189
    186 bool vboxSvcClipboardLock (void)
     190static bool vboxSvcClipboardLock (void)
    187191{
    188192    return RT_SUCCESS(RTCritSectEnter (&critsect));
    189193}
    190194
    191 void vboxSvcClipboardUnlock (void)
     195static void vboxSvcClipboardUnlock(void)
    192196{
    193197    RTCritSectLeave (&critsect);
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette