vbox: enable clipboard support"

Fixes #1696
This commit is contained in:
Alexander Boettcher 2015-09-15 14:08:35 +02:00 committed by Christian Helmuth
parent 2426c58b9f
commit 5aec67d5bb
11 changed files with 267 additions and 25 deletions

View File

@ -1 +1 @@
2fc156a977246088b14dc9acad72ea3013c9e596
d0f14330729a8ef3234c8a569e183e230c28e100

View File

@ -65,6 +65,7 @@ VBOX_MAIN_INC += USBDeviceImpl HostUSBDeviceImpl Matching Wrapper
VBOX_SRC_VBOX := VMM Devices Runtime GuestHost/HGSMI Storage Disassembler
VBOX_SRC_VBOX += HostDrivers/VBoxUSB/USBFilter.cpp
VBOX_SRC_VBOX += HostServices/SharedFolders Main/xml/Settings.cpp
VBOX_SRC_VBOX += HostServices/SharedClipboard
VBOX_SRC_VBOX += Main/xml/VirtualBox-settings.xsd Main/xml/SchemaDefs.xsl
VBOX_SRC_VBOX += $(addsuffix .h, $(addprefix Main/include/, $(VBOX_MAIN_INC)))
VBOX_SRC_VBOX += $(addsuffix .cpp, $(addprefix Main/src-client/, $(VBOX_MAIN_CLI)))
@ -83,9 +84,12 @@ VBOX_INC += usb.h usbfilter.h
VBOX_INC_COM := array.h assert.h AutoLock.h ErrorInfo.h EventQueue.h Guid.h
VBOX_INC_COM += list.h MultiResult.h string.h
VBOX_CONTENT += $(addprefix src/VBox/, $(VBOX_SRC_VBOX))
VBOX_CONTENT += $(addprefix include/VBox/, $(VBOX_INC))
VBOX_INC_HOST := VBoxClipboardExt.h VBoxClipboardSvc.h
VBOX_CONTENT += $(addprefix src/VBox/,$(VBOX_SRC_VBOX))
VBOX_CONTENT += $(addprefix include/VBox/, $(VBOX_INC))
VBOX_CONTENT += $(addprefix include/VBox/com/, $(VBOX_INC_COM))
VBOX_CONTENT += $(addprefix include/VBox/HostServices/, $(VBOX_INC_HOST))
VBOX_CONTENT += src/libs/zlib-1.2.6 src/libs/liblzf-3.4 src/libs/libxml2-2.6.31
VBOX_CONTENT += src/recompiler include/VBox/vmm include/iprt Config.kmk

View File

@ -22,14 +22,18 @@
extern "C" {
DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable);
DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad_sf (VBOXHGCMSVCFNTABLE *ptable);
DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad_cb (VBOXHGCMSVCFNTABLE *ptable);
static struct shared {
const char * name;
const char * symbol;
void * func;
} shared[] = {{ "VBoxSharedFolders", VBOX_HGCM_SVCLOAD_NAME, (void *)VBoxHGCMSvcLoad }};
} shared[] = {
{ "VBoxSharedFolders", VBOX_HGCM_SVCLOAD_NAME, (void *)VBoxHGCMSvcLoad_sf },
{ "VBoxSharedClipboard", VBOX_HGCM_SVCLOAD_NAME, (void *)VBoxHGCMSvcLoad_cb }
};
int RTLdrLoad(const char *pszFilename, PRTLDRMOD phLdrMod)

View File

@ -1,6 +1,22 @@
/*
* \brief Port of VirtualBox to Genode
* \author Norman Feske
* \author Alexander Boettcher
*/
/*
* Copyright (C) 2013-2015 Genode Labs GmbH
*
* This file is distributed under the terms of the GNU General Public License
* version 2.
*/
#include <base/printf.h>
#include <util/xml_node.h>
#include <VBox/settings.h>
#include <SharedClipboard/VBoxClipboard.h>
#include <VBox/HostServices/VBoxClipboardSvc.h>
#include "ConsoleImpl.h"
#include "MachineImpl.h"
@ -15,11 +31,13 @@
static const bool debug = false;
static Genode::Attached_rom_dataspace *clipboard_rom = nullptr;
static Genode::Reporter *clipboard_reporter = nullptr;
void Console::uninit() DUMMY()
HRESULT Console::resume(Reason_T aReason) DUMMY(E_FAIL)
HRESULT Console::pause(Reason_T aReason) DUMMY(E_FAIL)
void Console::enableVMMStatistics(BOOL aEnable) DUMMY()
void Console::changeClipboardMode(ClipboardMode_T aClipboardMode) DUMMY()
HRESULT Console::updateMachineState(MachineState_T aMachineState) DUMMY(E_FAIL)
HRESULT Console::attachToTapInterface(INetworkAdapter *networkAdapter)
@ -314,6 +332,41 @@ void GenodeConsole::handle_mode_change(unsigned)
update_video_mode();
}
void GenodeConsole::init_clipboard()
{
if (!&*machine())
return;
ClipboardMode_T mode;
machine()->COMGETTER(ClipboardMode)(&mode);
if (mode == ClipboardMode_Bidirectional ||
mode == ClipboardMode_HostToGuest) {
_clipboard_rom = new Genode::Attached_rom_dataspace("clipboard");
_clipboard_rom->sigh(_clipboard_signal_dispatcher);
clipboard_rom = _clipboard_rom;
}
if (mode == ClipboardMode_Bidirectional ||
mode == ClipboardMode_GuestToHost) {
_clipboard_reporter = new Genode::Reporter("clipboard");
_clipboard_reporter->enabled(true);
clipboard_reporter = _clipboard_reporter;
}
}
void GenodeConsole::handle_cb_rom_change(unsigned)
{
if (!_clipboard_rom)
return;
vboxClipboardSync(nullptr);
}
void GenodeConsole::event_loop(IKeyboard * gKeyboard, IMouse * gMouse)
{
_vbox_keyboard = gKeyboard;
@ -345,3 +398,151 @@ void GenodeConsole::onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supports
gMouse->PutMouseEventAbsolute(-1, -1, 0, 0, 0);
}
}
/**********************
* Clipboard handling *
**********************/
struct _VBOXCLIPBOARDCONTEXT
{
VBOXCLIPBOARDCLIENTDATA *pClient;
};
static VBOXCLIPBOARDCONTEXT context;
int vboxClipboardInit (void) { return VINF_SUCCESS; }
void vboxClipboardDestroy (void)
{
clipboard_rom = nullptr;
}
int vboxClipboardConnect (VBOXCLIPBOARDCLIENTDATA *pClient, bool fHeadless)
{
if (!pClient || context.pClient != NULL)
return VERR_NOT_SUPPORTED;
vboxSvcClipboardLock();
pClient->pCtx = &context;
pClient->pCtx->pClient = pClient;
vboxSvcClipboardUnlock();
int rc = vboxClipboardSync (pClient);
return rc;
}
void vboxClipboardDisconnect (VBOXCLIPBOARDCLIENTDATA *pClient)
{
if (!pClient || !pClient->pCtx)
return;
vboxSvcClipboardLock();
pClient->pCtx->pClient = NULL;
vboxSvcClipboardUnlock();
}
void vboxClipboardFormatAnnounce (VBOXCLIPBOARDCLIENTDATA *pClient,
uint32_t formats)
{
if (!pClient)
return;
vboxSvcClipboardReportMsg (pClient,
VBOX_SHARED_CLIPBOARD_HOST_MSG_READ_DATA,
formats);
}
int vboxClipboardReadData (VBOXCLIPBOARDCLIENTDATA *pClient, uint32_t format,
void *pv, uint32_t const cb, uint32_t *pcbActual)
{
if (!clipboard_rom || format != VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT)
return VERR_NOT_SUPPORTED;
if (!pv || !pcbActual || cb == 0)
return VERR_INVALID_PARAMETER;
clipboard_rom->update();
if (!clipboard_rom->is_valid()) {
PERR("invalid clipboard dataspace");
return VERR_NOT_SUPPORTED;
}
char * data = clipboard_rom->local_addr<char>();
try {
Genode::Xml_node node(data);
if (!node.has_type("clipboard")) {
PERR("invalid clipboard xml syntax");
return VERR_INVALID_PARAMETER;
}
size_t const len = node.content_size();
size_t written = 0;
PRTUTF16 utf16_string = reinterpret_cast<PRTUTF16>(pv);
int rc = RTStrToUtf16Ex(node.content_base(), len, &utf16_string, cb, &written);
if (RT_SUCCESS(rc)) {
if ((written * 2) + 2 > cb)
written = (cb - 2) / 2;
/* +1 stuff required for Windows guests ... linux guest doesn't care */
*pcbActual = (written + 1) * 2;
utf16_string[written] = 0;
} else
*pcbActual = 0;
} catch (Genode::Xml_node::Invalid_syntax) {
PERR("invalid clipboard xml syntax");
return VERR_INVALID_PARAMETER;
}
return VINF_SUCCESS;
}
void vboxClipboardWriteData (VBOXCLIPBOARDCLIENTDATA *pClient, void *pv,
uint32_t cb, uint32_t format)
{
if (format != VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT || !pv || !pClient ||
!clipboard_reporter)
return;
PCRTUTF16 utf16str = reinterpret_cast<PCRTUTF16>(pv);
char * message = 0;
int rc = RTUtf16ToUtf8(utf16str, &message);
if (!RT_SUCCESS(rc) || !message)
return;
try {
Genode::Reporter::Xml_generator xml(*clipboard_reporter, [&] () {
xml.append_sanitized(message, strlen(message)); });
} catch (...) {
PERR("could not write clipboard data");
}
RTStrFree(message);
}
int vboxClipboardSync (VBOXCLIPBOARDCLIENTDATA *pClient)
{
if (!pClient)
pClient = context.pClient;
if (!pClient)
return VERR_NOT_SUPPORTED;
vboxSvcClipboardReportMsg (pClient, VBOX_SHARED_CLIPBOARD_HOST_MSG_FORMATS,
VBOX_SHARED_CLIPBOARD_FMT_UNICODETEXT);
return VINF_SUCCESS;
}

View File

@ -13,20 +13,24 @@
*/
/* Genode includes */
#include <base/printf.h>
#include <input/event.h>
#include <input/keycodes.h>
#include <input_session/connection.h>
#include <os/attached_dataspace.h>
#include <os/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <report_session/connection.h>
#include <timer_session/connection.h>
/* included from os/src/drivers/input/spec/ps2 */
#include <scan_code_set_1.h>
/* repos/ports includes */
#include <vbox_pointer/shape_report.h>
/* VirtualBox includes */
#include "ConsoleImpl.h"
#include <base/printf.h>
#include <os/attached_dataspace.h>
#include <report_session/connection.h>
#include <vbox_pointer/shape_report.h>
class Scan_code
@ -115,10 +119,13 @@ class GenodeConsole : public Console {
Report::Connection _shape_report_connection;
Genode::Attached_dataspace _shape_report_ds;
Vbox_pointer::Shape_report *_shape_report;
Genode::Reporter *_clipboard_reporter;
Genode::Attached_rom_dataspace *_clipboard_rom;
IKeyboard *_vbox_keyboard;
IMouse *_vbox_mouse;
Genode::Signal_dispatcher<GenodeConsole> _input_signal_dispatcher;
Genode::Signal_dispatcher<GenodeConsole> _mode_change_signal_dispatcher;
Genode::Signal_dispatcher<GenodeConsole> _clipboard_signal_dispatcher;
bool _key_status[Input::KEY_MAX + 1];
@ -140,10 +147,13 @@ class GenodeConsole : public Console {
_shape_report_connection("shape", sizeof(Vbox_pointer::Shape_report)),
_shape_report_ds(_shape_report_connection.dataspace()),
_shape_report(_shape_report_ds.local_addr<Vbox_pointer::Shape_report>()),
_clipboard_reporter(nullptr),
_clipboard_rom(nullptr),
_vbox_keyboard(0),
_vbox_mouse(0),
_input_signal_dispatcher(_receiver, *this, &GenodeConsole::handle_input),
_mode_change_signal_dispatcher(_receiver, *this, &GenodeConsole::handle_mode_change)
_mode_change_signal_dispatcher(_receiver, *this, &GenodeConsole::handle_mode_change),
_clipboard_signal_dispatcher(_receiver, *this, &GenodeConsole::handle_cb_rom_change)
{
for (unsigned i = 0; i <= Input::KEY_MAX; i++)
_key_status[i] = 0;
@ -151,6 +161,8 @@ class GenodeConsole : public Console {
_input.sigh(_input_signal_dispatcher);
}
void init_clipboard();
void event_loop(IKeyboard * gKeyboard, IMouse * gMouse);
void onMouseCapabilityChange(BOOL supportsAbsolute, BOOL supportsRelative,
@ -219,4 +231,5 @@ class GenodeConsole : public Console {
void handle_input(unsigned);
void handle_mode_change(unsigned);
void handle_cb_rom_change(unsigned);
};

View File

@ -145,6 +145,12 @@ HRESULT setupmachine()
ComPtr<IConsole> gConsole;
rc = session->COMGETTER(Console)(gConsole.asOutParam());
/* handle input of Genode and forward it to VMM layer */
ComPtr<GenodeConsole> genodeConsole = gConsole;
RTLogPrintf("genodeConsole = %p\n", genodeConsole);
genodeConsole->init_clipboard();
/* Display object */
ComPtr<IDisplay> display;
rc = gConsole->COMGETTER(Display)(display.asOutParam());
@ -194,10 +200,6 @@ HRESULT setupmachine()
return rc;
Assert (&*gKeyboard);
/* handle input of Genode and forward it to VMM layer */
ComPtr<GenodeConsole> genodeConsole = gConsole;
RTLogPrintf("genodeConsole = %p\n", genodeConsole);
genodeConsole->event_loop(gKeyboard, gMouse);
Assert(!"return not expected");

View File

@ -1,6 +0,0 @@
#ifndef ___VBox_HostService_VBoxClipboardSvc_h
#define ___VBox_HostService_VBoxClipboardSvc_h
#define VBOX_SHARED_CLIPBOARD_HOST_FN_SET_HEADLESS 2
#endif

View File

@ -0,0 +1,20 @@
+++ a/src/app/virtualbox/src/VBox/HostServices/SharedFolders/service.cpp
@@ -1445,7 +1489,7 @@
return rc;
}
-extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
+extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad_sf (VBOXHGCMSVCFNTABLE *ptable)
{
int rc = VINF_SUCCESS;
+++ a/src/app/virtualbox/src/VBox/HostServices/SharedClipboard/service.cpp
@@ -966,7 +966,7 @@
return VINF_SUCCESS;
}
-extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad (VBOXHGCMSVCFNTABLE *ptable)
+extern "C" DECLCALLBACK(DECLEXPORT(int)) VBoxHGCMSvcLoad_cb (VBOXHGCMSVCFNTABLE *ptable)
{
int rc = VINF_SUCCESS;

View File

@ -22,3 +22,4 @@ rem_irq.patch
usb.patch
tm_smp.patch
posix.patch
hostservice.patch

View File

@ -772,14 +772,14 @@ index 69e3109..141bb98 100644
/**
* Fetches the list of global or machine shared folders from the server.
*
@@ -8353,6 +8437,8 @@ DECLCALLBACK(void) Console::vmstateChangeCallback(PUVM pUVM, VMSTATE enmState, V
}
@@ -8390,6 +8474,8 @@
pVMMDev->hgcmHostCall("VBoxSharedClipboard", VBOX_SHARED_CLIPBOARD_HOST_FN_SET_MODE, 1, &parm);
}
+#if 0
+
/**
* Changes the clipboard mode.
* Changes the drag'n_drop mode.
*
@@ -8426,7 +8512,7 @@ void Console::changeDragAndDropMode(DragAndDropMode_T aDragAndDropMode)

View File

@ -13,7 +13,7 @@ SRC_CC = frontend/main.cc frontend/console.cc \
frontend/USBProxyDevice-genode.cpp \
devices.cc drivers.cc dummies.cc libc.cc \
logger.cc mm.cc pdm.cc pgm.cc rt.cc sup.cc iommio.cc ioport.cc \
hm.cc thread.cc dynlib.cc unimpl.cc
hm.cc thread.cc dynlib.cc unimpl.cc
LIBS += base
LIBS += config_args
@ -38,6 +38,8 @@ SRC_CC += HostServices/SharedFolders/mappings.cpp
SRC_CC += HostServices/SharedFolders/vbsf.cpp
SRC_CC += HostServices/SharedFolders/shflhandle.cpp
SRC_CC += HostServices/SharedClipboard/service.cpp
SRC_CC += frontend/dummy/errorinfo.cc frontend/dummy/virtualboxbase.cc
SRC_CC += frontend/dummy/autostart.cc frontend/dummy/rest.cc
SRC_CC += frontend/dummy/host.cc
@ -50,6 +52,7 @@ INC_DIR += $(REP_DIR)/src/virtualbox/frontend/VBoxAPIWrap
INC_DIR += $(VBOX_DIR)/Main/xml
INC_DIR += $(VBOX_DIR)/Devices/USB
INC_DIR += $(VBOX_DIR)/HostServices
# search path to 'scan_code_set_2.h'
INC_DIR += $(call select_from_repositories,src/drivers/input/spec/ps2)