VBoxClipboard.cpp revision b357df727b216b85d4517efecf466a7b14c2e80c
/** @file
*
* VBoxClipboard - Shared clipboard
*
*/
/*
* Copyright (C) 2006-2007 Sun Microsystems, Inc.
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
* Clara, CA 95054 USA or visit http://www.sun.com if you need
* additional information or have any questions.
*/
#include "VBoxTray.h"
#include "helpers.h"
typedef struct _VBOXCLIPBOARDCONTEXT
{
const VBOXSERVICEENV *pEnv;
// bool fOperational;
// uint32_t u32LastSentFormat;
// uint64_t u64LastSentCRC64;
static char gachWindowClassName[] = "VBoxSharedClipboardClass";
} while (0)
//static bool vboxClipboardIsSameAsLastSent (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format,
// void *pv, uint32_t cb)
//{
// uint64_t u64CRC = RTCrc64 (pv, cb);
//
// if ( pCtx->u32LastSentFormat == u32Format
// && pCtx->u64LastSentCRC64 == u64CRC)
// {
// return true;
// }
//
// pCtx->u64LastSentCRC64 = u64CRC;
// pCtx->u32LastSentFormat = u32Format;
//
// return false;
//}
{
NULL))
{
{
}
}
else
{
}
}
{
if (pCtx->u32ClientID == 0)
{
return;
}
NULL);
return;
}
{
}
{
{
return VINF_SUCCESS;
}
return VERR_INVALID_PARAMETER;
}
{
}
{
if (DeviceIoControl (hDriver,
NULL))
{
return VINF_SUCCESS;
}
return VERR_NOT_SUPPORTED;
}
{
if (VBOX_SUCCESS (rc))
{
}
return rc;
}
static int vboxClipboardReadData (VBOXCLIPBOARDCONTEXT *pCtx, uint32_t u32Format, void *pv, uint32_t cb, uint32_t *pcbActual)
{
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
if (pcbActual)
{
}
}
}
}
return rc;
}
{
// if (vboxClipboardIsSameAsLastSent (pCtx, u32Format, pv, cb))
// {
// dprintf (("vboxClipboardWriteData: The data to be sent are the same as the last sent.\n"));
// return VINF_SUCCESS;
// }
if (VBOX_SUCCESS (rc))
{
}
return rc;
}
{
/* Query list of available formats and report to host. */
{
uint32_t u32Formats = 0;
{
switch (format)
{
case CF_UNICODETEXT:
case CF_TEXT:
break;
case CF_DIB:
case CF_BITMAP:
break;
default:
if (format >= 0xC000)
{
if (cActual)
{
{
}
}
}
break;
}
}
CloseClipboard ();
}
}
static LRESULT vboxClipboardProcessMsg(VBOXCLIPBOARDCONTEXT *pCtx, HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CHANGECBCHAIN:
{
dprintf (("vboxClipboardProcessMsg: WM_CHANGECBCHAIN: hwndRemoved %p, hwndNext %p, hwnd %p\n", hwndRemoved, hwndNext, pCtx->hwnd));
{
/* The window that was next to our in the chain is being removed.
* Relink to the new next window.
*/
}
else
{
if (pCtx->hwndNextInChain)
{
/* Pass the message further. */
}
}
} break;
case WM_DRAWCLIPBOARD:
{
if (GetClipboardOwner () != hwnd)
{
/* Clipboard was updated by another application. */
}
/* Pass the message to next windows in the clipboard chain. */
} break;
case WM_CLOSE:
{
/* Do nothing. Ignore the message. */
} break;
case WM_RENDERFORMAT:
{
/* Insert the requested clipboard format data into the clipboard. */
switch (format)
{
case CF_UNICODETEXT:
break;
case CF_DIB:
break;
default:
if (format >= 0xC000)
{
if (cActual)
{
{
}
}
}
break;
}
if (u32Format == 0)
{
/* Unsupported clipboard format is requested. */
EmptyClipboard ();
}
else
{
/* Preallocate a buffer, most of small text transfers will fit into it. */
if (hMem)
{
if (pMem)
{
/* Read the host data to the preallocated buffer. */
if (VBOX_SUCCESS (rc))
{
if (cb > cbPrealloc)
{
GlobalUnlock (hMem);
/* The preallocated buffer is too small, adjust the size. */
if (hMem)
{
if (pMem)
{
/* Read the host data to the preallocated buffer. */
{
}
else
{
GlobalUnlock (pMem);
GlobalFree (hMem);
}
}
else
{
GlobalFree (hMem);
}
}
}
if (hMem)
{
/* pMem is the address of the data. cb is the size of returned data. */
/* Verify the size of returned text. */
{
}
GlobalUnlock (hMem);
if (hMem)
{
/* 'hMem' contains the host clipboard data.
* size is 'cb' and format is 'format'.
*/
if (hClip)
{
/* The hMem ownership has gone to the system. Finish the processing. */
break;
}
/* Cleanup follows. */
}
}
}
if (hMem)
{
GlobalUnlock (hMem);
}
}
if (hMem)
{
GlobalFree (hMem);
}
}
/* Something went wrong. */
EmptyClipboard ();
}
} break;
case WM_RENDERALLFORMATS:
{
/* Do nothing. The clipboard formats will be unavailable now, because the
* windows is to be destroyed and therefore the guest side becomes inactive.
*/
if (OpenClipboard (hwnd))
{
}
} break;
case WM_USER:
{
/* Announce available formats. Do not insert data, they will be inserted in WM_RENDER*. */
if (OpenClipboard (hwnd))
{
{
dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT\n"));
}
{
dprintf(("window proc WM_USER: VBOX_SHARED_CLIPBOARD_FMT_BITMAP\n"));
}
{
if (format != 0)
{
}
}
}
else
{
dprintf(("window proc WM_USER: failed to open clipboard\n"));
}
} break;
case WM_USER + 1:
{
/* Send data in the specified format to the host. */
if (OpenClipboard (hwnd))
{
{
{
{
dprintf(("CF_DIB\n"));
}
else
{
}
}
}
else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
{
{
{
dprintf(("CF_UNICODETEXT\n"));
}
else
{
}
}
}
else if (u32Formats & VBOX_SHARED_CLIPBOARD_FMT_HTML)
{
if (format != 0)
{
{
{
dprintf(("CF_HTML\n"));
}
else
{
}
}
}
}
CloseClipboard ();
}
{
/* Requested clipboard format is not available, send empty data. */
}
} break;
default:
{
}
}
return rc;
}
{
int rc = VINF_SUCCESS;
/* Register the Window Class. */
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
if (pCtx->atomWindowClass == 0)
{
}
else
{
/* Create the window. */
{
}
else
{
}
}
return rc;
}
{
{
}
if (pCtx->atomWindowClass != 0)
{
pCtx->atomWindowClass = 0;
}
}
/* Static since it is the single instance. Directly used in the windows proc. */
{
/* Forward with proper context. */
}
{
int rc = VINF_SUCCESS;
dprintf (("VboxClipboardInit\n"));
{
/* Clipboard was already initialized. 2 or more instances are not supported. */
return VERR_NOT_SUPPORTED;
}
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
/* Always start the thread for host messages. */
*pfStartThread = true;
}
}
if (VBOX_SUCCESS (rc))
{
*ppInstance = &gCtx;
}
else
{
}
return rc;
}
{
dprintf(("VBoxClipboardThread\n"));
/* Open the new driver instance to not interfere with other callers. */
NULL,
NULL);
/* The thread waits for incoming messages from the host. */
for (;;)
{
if (!DeviceIoControl (hDriver,
NULL))
{
dprintf(("Failed to call the driver for host message.\n"));
/* Wait a bit before retrying. */
{
break;
}
continue;
}
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
if (VBOX_SUCCESS (rc))
{
switch (u32Msg)
{
{
/* The host has announced available clipboard formats.
* Forward the information to the window, so it can later
* respond to WM_RENDERFORMAT message.
*/
} break;
{
/* The host needs data in the specified format.
*/
} break;
{
/* The host is terminating.
*/
} break;
default:
{
dprintf(("Unsupported message from host!!!"));
}
}
}
}
}
if (rc == VERR_INTERRUPTED)
{
/* Wait for termination event. */
break;
}
if (VBOX_FAILURE (rc))
{
/* Wait a bit before retrying. */
{
break;
}
continue;
}
}
return 0;
}
{
{
}
return;
}