On 05/13/2011 11:21 AM, Daniel P. Berrange wrote: > On Thu, May 12, 2011 at 06:29:15PM +0200, Michal Privoznik wrote: >> * src/vbox/vbox_tmpl.c: New vboxDomainScreenshot() function >> --- >> src/vbox/vbox_tmpl.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 files changed, 133 insertions(+), 0 deletions(-) >> >> diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c >> index dc91240..d598bcf 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 >> @@ -8527,6 +8533,129 @@ static char *vboxStorageVolGetPath(virStorageVolPtr vol) { >> return ret; >> } >> >> +#if VBOX_API_VERSION == 4000 >> +static char * >> +vboxDomainScreenshot(virDomainPtr dom, >> + virStreamPtr st, >> + unsigned int screen, >> + 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; >> + unsigned int max_screen; >> + >> + 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; >> + } >> + >> + rc = machine->vtbl->GetMonitorCount(machine, &max_screen); >> + if (NS_FAILED(rc)) { >> + vboxError(VIR_ERR_OPERATION_FAILED, "%s", >> + _("unable to get monitor count")); >> + VBOX_RELEASE(machine); >> + return NULL; >> + } >> + >> + if (screen >= max_screen) { >> + vboxError(VIR_ERR_INVALID_ARG, _("screen ID higher than monitor " >> + "count (%d)"), max_screen); >> + VBOX_RELEASE(machine); >> + return NULL; >> + } >> + >> + if (virAsprintf(&tmp, "%s/cache/libvirt/vbox.screendump.XXXXXX", LOCALSTATEDIR) < 0) { >> + virReportOOMError(); >> + VBOX_RELEASE(machine); >> + return NULL; >> + } >> + >> + if ((tmp_fd = mkstemp(tmp)) == -1) { >> + virReportSystemError(errno, _("mkstemp(\"%s\") failed"), tmp); >> + VIR_FREE(tmp); >> + VBOX_RELEASE(machine); >> + 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, screen, >> + &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, screen, >> + 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"); > > > Likewise, drop the '; charset=binary' here > > ACK with that change > > Daniel Thanks, pushed the whole series. Michal -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list