* src/vbox/vbox_tmpl.c: New vboxDomainScreenshot() function --- src/vbox/vbox_tmpl.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 113 insertions(+), 0 deletions(-) diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index a87c6a5..53a3a88 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -36,6 +36,9 @@ #include <sys/utsname.h> #include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include "internal.h" #include "datatypes.h" @@ -51,6 +54,9 @@ #include "nodeinfo.h" #include "logging.h" #include "vbox_driver.h" +#include "configmake.h" +#include "files.h" +#include "fdstream.h" /* This one changes from version to version. */ #if VBOX_API_VERSION == 2002 @@ -8522,6 +8528,109 @@ static char *vboxStorageVolGetPath(virStorageVolPtr vol) { return ret; } +#if VBOX_API_VERSION == 4000 +static char * +vboxDomainScreenshot(virDomainPtr dom, virStreamPtr st, + unsigned int flags ATTRIBUTE_UNUSED) +{ + VBOX_OBJECT_CHECK(dom->conn, char *, NULL); + IConsole *console = NULL; + vboxIID iid = VBOX_IID_INITIALIZER; + IMachine *machine = NULL; + nsresult rc; + char *tmp; + int tmp_fd = -1; + + vboxIIDFromUUID(&iid, dom->uuid); + rc = VBOX_OBJECT_GET_MACHINE(iid.value, &machine); + if (NS_FAILED(rc)) { + vboxError(VIR_ERR_NO_DOMAIN, "%s", + _("no domain with matching uuid")); + return NULL; + } + + if (virAsprintf(&tmp, "%s/cache/libvirt/vbox.screendump.XXXXXX", LOCALSTATEDIR) < 0) { + virReportOOMError(); + return NULL; + } + + if ((tmp_fd = mkstemp(tmp)) == -1) { + virReportSystemError(errno, _("mkstemp(\"%s\") failed"), tmp); + VIR_FREE(tmp); + return NULL; + } + + + rc = VBOX_SESSION_OPEN_EXISTING(iid.value, machine); + if (NS_SUCCEEDED(rc)) { + rc = data->vboxSession->vtbl->GetConsole(data->vboxSession, &console); + if (NS_SUCCEEDED(rc) && console) { + IDisplay *display = NULL; + + console->vtbl->GetDisplay(console, &display); + + if (display) { + PRUint32 width, height, bitsPerPixel; + PRUint32 screenDataSize; + PRUint8 *screenData; + + rc = display->vtbl->GetScreenResolution(display, 0, + &width, &height, + &bitsPerPixel); + + if (NS_FAILED(rc) || !width || !height) { + vboxError(VIR_ERR_OPERATION_FAILED, "%s", + _("unable to get screen resolution")); + goto endjob; + } + + rc = display->vtbl->TakeScreenShotPNGToArray(display, 0, + width, height, + &screenDataSize, + &screenData); + if (NS_FAILED(rc)) { + vboxError(VIR_ERR_OPERATION_FAILED, "%s", + _("failed to take screenshot")); + goto endjob; + } + + if (safewrite(tmp_fd, (char *) screenData, + screenDataSize) < 0) { + virReportSystemError(errno, _("unable to write data " + "to '%s'"), tmp); + goto endjob; + } + + if (VIR_CLOSE(tmp_fd) < 0) { + virReportSystemError(errno, _("unable to close %s"), tmp); + goto endjob; + } + + if (virFDStreamOpenFile(st, tmp, 0, 0, O_RDONLY, true) < 0) { + vboxError(VIR_ERR_OPERATION_FAILED, "%s", + _("unable to open stream")); + goto endjob; + } + + ret = strdup("image/png; charset=binary"); + +endjob: + VIR_FREE(screenData); + VBOX_RELEASE(display); + } + VBOX_RELEASE(console); + } + VBOX_SESSION_CLOSE(); + } + + VIR_FORCE_CLOSE(tmp_fd); + VIR_FREE(tmp); + VBOX_RELEASE(machine); + vboxIIDUnalloc(&iid); + return ret; +} +#endif /* VBOX_API_VERSION == 4000 */ + /** * Function Tables */ @@ -8564,7 +8673,11 @@ virDriver NAME(Driver) = { vboxDomainSave, /* domainSave */ NULL, /* domainRestore */ NULL, /* domainCoreDump */ +#if VBOX_API_VERSION == 4000 + vboxDomainScreenshot, /* domainScreenshot */ +#else NULL, /* domainScreenshot */ +#endif vboxDomainSetVcpus, /* domainSetVcpus */ vboxDomainSetVcpusFlags, /* domainSetVcpusFlags */ vboxDomainGetVcpusFlags, /* domainGetVcpusFlags */ -- 1.7.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list