void UIMachineView::takePauseShotLive() { /* Take a screen snapshot. Note that TakeScreenShot() always needs a 32bpp image: */ QImage shot = QImage(m_pFrameBuffer->width(), m_pFrameBuffer->height(), QImage::Format_RGB32); /* If TakeScreenShot fails or returns no image, just show a black image. */ shot.fill(0); CDisplay dsp = session().GetConsole().GetDisplay(); dsp.TakeScreenShot(screenId(), shot.bits(), shot.width(), shot.height()); /* TakeScreenShot() may fail if, e.g. the Paused notification was delivered * after the machine execution was resumed. It's not fatal: */ if (dsp.isOk()) dimImage(shot); m_pauseShot = QPixmap::fromImage(shot); }
void UIVMPreviewWindow::sltRecreatePreview() { /* Only do this if we are visible: */ if (!isVisible()) return; /* Remove preview if any: */ if (m_pPreviewImg) { delete m_pPreviewImg; m_pPreviewImg = 0; } /* We are not creating preview for inaccessible VMs: */ if (m_machineState == KMachineState_Null) return; if (!m_machine.isNull() && m_vRect.width() > 0 && m_vRect.height() > 0) { QImage image(size(), QImage::Format_ARGB32); image.fill(Qt::transparent); QPainter painter(&image); bool fDone = false; /* Preview enabled? */ if (m_pUpdateTimer->interval() > 0) { /* Use the image which may be included in the save state. */ if ( m_machineState == KMachineState_Saved || m_machineState == KMachineState_Restoring) { ULONG width = 0, height = 0; QVector<BYTE> screenData = m_machine.ReadSavedScreenshotPNGToArray(0, width, height); if (screenData.size() != 0) { QImage shot = QImage::fromData(screenData.data(), screenData.size(), "PNG").scaled(m_vRect.size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); dimImage(shot); painter.drawImage(m_vRect.x(), m_vRect.y(), shot); fDone = true; } } /* Use the current VM output. */ else if ( m_machineState == KMachineState_Running // || m_machineState == KMachineState_Saving /* Not sure if this is valid */ || m_machineState == KMachineState_Paused) { if (m_session.GetState() == KSessionState_Locked) { CVirtualBox vbox = vboxGlobal().virtualBox(); if (vbox.isOk()) { const CConsole& console = m_session.GetConsole(); if (!console.isNull()) { CDisplay display = console.GetDisplay(); /* Todo: correct aspect radio */ // ULONG w, h, bpp; // display.GetScreenResolution(0, w, h, bpp); // QImage shot = QImage(w, h, QImage::Format_RGB32); // shot.fill(Qt::black); // display.TakeScreenShot(0, shot.bits(), shot.width(), shot.height()); QVector<BYTE> screenData = display.TakeScreenShotToArray(0, m_vRect.width(), m_vRect.height()); if ( display.isOk() && screenData.size() != 0) { /* Unfortunately we have to reorder the pixel * data, cause the VBox API returns RGBA data, * which is not a format QImage understand. * Todo: check for 32bit alignment, for both * the data and the scanlines. Maybe we need to * copy the data in any case. */ uint32_t *d = (uint32_t*)screenData.data(); for (int i = 0; i < screenData.size() / 4; ++i) { uint32_t e = d[i]; d[i] = RT_MAKE_U32_FROM_U8(RT_BYTE3(e), RT_BYTE2(e), RT_BYTE1(e), RT_BYTE4(e)); } QImage shot = QImage((uchar*)d, m_vRect.width(), m_vRect.height(), QImage::Format_RGB32); if (m_machineState == KMachineState_Paused) dimImage(shot); painter.drawImage(m_vRect.x(), m_vRect.y(), shot); fDone = true; } } } } } } if (fDone) m_pPreviewImg = new QImage(image); } update(); }