void UIMachineViewFullscreen::sltPerformGuestResize(const QSize &toSize)
{
    if (m_bIsGuestAutoresizeEnabled && uisession()->isGuestSupportsGraphics())
    {
        /* Get machine window: */
        QMainWindow *pMachineWindow = machineWindowWrapper() && machineWindowWrapper()->machineWindow() ?
                                      qobject_cast<QMainWindow*>(machineWindowWrapper()->machineWindow()) : 0;

        /* If this slot is invoked directly then use the passed size otherwise get
         * the available size for the guest display. We assume here that centralWidget()
         * contains this view only and gives it all available space: */
        QSize newSize(toSize.isValid() ? toSize : pMachineWindow ? pMachineWindow->centralWidget()->size() : QSize());
        AssertMsg(newSize.isValid(), ("Size should be valid!\n"));

        /* Do not send the same hints as we already have: */
        if ((newSize.width() == storedConsoleSize().width()) && (newSize.height() == storedConsoleSize().height()))
            return;

        /* We only actually send the hint if either an explicit new size was given
         * (e.g. if the request was triggered directly by a console resize event) or
         * if no explicit size was specified but a resize is flagged as being needed
         * (e.g. the autoresize was just enabled and the console was resized while it was disabled). */
        if (toSize.isValid() || m_fShouldWeDoResize)
        {
            /* Remember the new size: */
            storeConsoleSize(newSize.width(), newSize.height());

            /* Send new size-hint to the guest: */
            session().GetConsole().GetDisplay().SetVideoModeHint(newSize.width(), newSize.height(), 0, screenId());
        }

        /* We had requested resize now, rejecting other accident requests: */
        m_fShouldWeDoResize = false;
    }
}
bool UIMachineViewFullscreen::eventFilter(QObject *pWatched, QEvent *pEvent)
{
    /* Who are we watching? */
    QMainWindow *pMainDialog = machineWindowWrapper() && machineWindowWrapper()->machineWindow() ?
                               qobject_cast<QMainWindow*>(machineWindowWrapper()->machineWindow()) : 0;

    if (pWatched != 0 && pWatched == pMainDialog)
    {
        switch (pEvent->type())
        {
            case QEvent::Resize:
            {
                /* Send guest-resize hint only if top window resizing to required dimension: */
                QResizeEvent *pResizeEvent = static_cast<QResizeEvent*>(pEvent);
                if (pResizeEvent->size() != workingArea().size())
                    break;

                /* Set the "guest needs to resize" hint.
                 * This hint is acted upon when (and only when) the autoresize property is "true": */
                m_fShouldWeDoResize = uisession()->isGuestSupportsGraphics();
                if (m_bIsGuestAutoresizeEnabled && m_fShouldWeDoResize)
                    QTimer::singleShot(0, this, SLOT(sltPerformGuestResize()));
                break;
            }
            default:
                break;
        }
    }

    return UIMachineView::eventFilter(pWatched, pEvent);
}
bool UIMachineViewScale::eventFilter(QObject *pWatched, QEvent *pEvent)
{
    /* Who are we watching? */
    QMainWindow *pMainDialog = machineWindowWrapper() && machineWindowWrapper()->machineWindow() ?
                               qobject_cast<QMainWindow*>(machineWindowWrapper()->machineWindow()) : 0;

    if (pWatched != 0 && pWatched == viewport())
    {
        switch (pEvent->type())
        {
            case QEvent::Resize:
            {
                /* Perform the actually resize */
                sltPerformGuestScale();
                break;
            }
            default:
                break;
        }
    }
    else if (pWatched != 0 && pWatched == pMainDialog)
    {
        switch (pEvent->type())
        {
#if defined (Q_WS_WIN32)
# if defined (VBOX_GUI_USE_DDRAW)
            case QEvent::Move:
            {
                /* Notification from our parent that it has moved. We need this in order
                 * to possibly adjust the direct screen blitting: */
                if (frameBuffer())
                    frameBuffer()->moveEvent(static_cast<QMoveEvent*>(pEvent));
                break;
            }
# else
            case 0: /* Fixes compiler warning, fall through. */
# endif /* defined (VBOX_GUI_USE_DDRAW) */

#else
            case 0: /* Fixes compiler warning, fall through. */
#endif /* defined (Q_WS_WIN32) */
            default:
                break;
        }
    }

    return UIMachineView::eventFilter(pWatched, pEvent);
}
void UIMachineViewFullscreen::prepareFilters()
{
    /* Base class filters: */
    UIMachineView::prepareFilters();

#ifdef Q_WS_MAC // TODO: Is it really needed? See UIMachineViewSeamless::eventFilter(...);
    /* Menu bar filter: */
    qobject_cast<QMainWindow*>(machineWindowWrapper()->machineWindow())->menuBar()->installEventFilter(this);
#endif
}
void UIMachineViewScale::calculateDesktopGeometry()
{
    /* This method should not get called until we have initially set up the desktop geometry type: */
    Assert((desktopGeometryType() != DesktopGeo_Invalid));
    /* If we are not doing automatic geometry calculation then there is nothing to do: */
    if (desktopGeometryType() == DesktopGeo_Automatic)
    {
        /* The area taken up by the machine window on the desktop,
         * including window frame, title, menu bar and status bar: */
        QRect windowGeo = machineWindowWrapper()->machineWindow()->frameGeometry();
        /* The area taken up by the machine central widget, so excluding all decorations: */
        QRect centralWidgetGeo = static_cast<QMainWindow*>(machineWindowWrapper()->machineWindow())->centralWidget()->geometry();
        /* To work out how big we can make the console window while still fitting on the desktop,
         * we calculate workingArea() - (windowGeo - centralWidgetGeo).
         * This works because the difference between machine window and machine central widget
         * (or at least its width and height) is a constant. */
        m_desktopGeometry = QSize(workingArea().width() - (windowGeo.width() - centralWidgetGeo.width()),
                                  workingArea().height() - (windowGeo.height() - centralWidgetGeo.height()));
    }
}
Example #6
0
void UIMachineView::prepareFilters()
{
    /* Enable MouseMove events: */
    viewport()->setMouseTracking(true);

    /* QScrollView does the below on its own, but let's
     * do it anyway for the case it will not do it in the future: */
    viewport()->installEventFilter(this);

    /* We want to be notified on some parent's events: */
    machineWindowWrapper()->machineWindow()->installEventFilter(this);
}
void UIMachineViewSeamless::cleanupSeamless()
{
    /* If machine still running: */
    if (uisession()->isRunning())
    {
        /* Reset seamless feature flag of the guest: */
        session().GetConsole().GetDisplay().SetSeamlessMode(false);

        /* Rollback seamless frame-buffer size to normal: */
        machineWindowWrapper()->machineWindow()->hide();
        sltPerformGuestResize(guestSizeHint());
        m_pSyncBlocker->exec();

        /* Delete sync-blocker: */
        m_pSyncBlocker->deleteLater();
    }
}
Example #8
0
bool UIMachineView::eventFilter(QObject *pWatched, QEvent *pEvent)
{
#ifdef VBOX_WITH_VIDEOHWACCEL
    if (pWatched == viewport())
    {
        switch (pEvent->type())
        {
            case QEvent::Resize:
            {
                if (m_pFrameBuffer)
                    m_pFrameBuffer->viewportResized(static_cast<QResizeEvent*>(pEvent));
                break;
            }
            default:
                break;
        }
    }
#endif /* VBOX_WITH_VIDEOHWACCEL */
    if (pWatched == machineWindowWrapper()->machineWindow())
    {
        switch (pEvent->type())
        {
            case QEvent::WindowStateChange:
            {
                /* During minimizing and state restoring machineWindowWrapper() gets
                 * the focus which belongs to console view window, so returning it properly. */
                QWindowStateChangeEvent *pWindowEvent = static_cast<QWindowStateChangeEvent*>(pEvent);
                if (pWindowEvent->oldState() & Qt::WindowMinimized)
                {
                    if (QApplication::focusWidget())
                    {
                        QApplication::focusWidget()->clearFocus();
                        qApp->processEvents();
                    }
                    QTimer::singleShot(0, this, SLOT(setFocus()));
                }
                break;
            }
            default:
                break;
        }
    }

    return QAbstractScrollArea::eventFilter(pWatched, pEvent);
}
void UIMachineViewFullscreen::cleanupFullscreen()
{
    /* If machine still running: */
    if (uisession()->isRunning())
    {
        /* And guest supports advanced graphics management which is enabled: */
        if (m_bIsGuestAutoresizeEnabled && uisession()->isGuestSupportsGraphics())
        {
            /* Rollback seamless frame-buffer size to normal: */
            machineWindowWrapper()->machineWindow()->hide();
            sltPerformGuestResize(guestSizeHint());
            m_pSyncBlocker->exec();

            /* Request to delete sync-blocker: */
            m_pSyncBlocker->deleteLater();
        }
    }
}
bool UIMachineViewSeamless::event(QEvent *pEvent)
{
    switch (pEvent->type())
    {
        case VBoxDefs::SetRegionEventType:
        {
            /* Get region-update event: */
            UISetRegionEvent *pSetRegionEvent = static_cast<UISetRegionEvent*>(pEvent);

            /* Apply new region: */
            if (pSetRegionEvent->region() != m_lastVisibleRegion)
            {
                m_lastVisibleRegion = pSetRegionEvent->region();
                machineWindowWrapper()->setMask(m_lastVisibleRegion);
            }
            return true;
        }

        case VBoxDefs::ResizeEventType:
        {
            /* Some situations require framebuffer resize events to be ignored at all,
             * leaving machine-window, machine-view and framebuffer sizes preserved: */
            if (uisession()->isGuestResizeIgnored())
                return true;

            /* We are starting to perform machine-view resize,
             * we should temporary ignore other if they are trying to be: */
            bool fWasMachineWindowResizeIgnored = isMachineWindowResizeIgnored();
            setMachineWindowResizeIgnored(true);

            /* Get guest resize-event: */
            UIResizeEvent *pResizeEvent = static_cast<UIResizeEvent*>(pEvent);

            /* Perform framebuffer resize: */
            frameBuffer()->resizeEvent(pResizeEvent);

            /* Reapply maximum size restriction for machine-view: */
            setMaximumSize(sizeHint());

            /* Store the new size to prevent unwanted resize hints being sent back: */
            storeConsoleSize(pResizeEvent->width(), pResizeEvent->height());

            /* Perform machine-view resize: */
            resize(pResizeEvent->width(), pResizeEvent->height());

            /* Let our toplevel widget calculate its sizeHint properly: */
            QCoreApplication::sendPostedEvents(0, QEvent::LayoutRequest);

#ifdef Q_WS_MAC
            machineLogic()->updateDockIconSize(screenId(), pResizeEvent->width(), pResizeEvent->height());
#endif /* Q_WS_MAC */

            /* Update machine-view sliders: */
            updateSliders();

            /* Report to the VM thread that we finished resizing: */
            session().GetConsole().GetDisplay().ResizeCompleted(screenId());

            /* We are finishing to perform machine-view resize: */
            setMachineWindowResizeIgnored(fWasMachineWindowResizeIgnored);

            /* We also recalculate the desktop geometry if this is determined
             * automatically.  In fact, we only need this on the first resize,
             * but it is done every time to keep the code simpler. */
            calculateDesktopGeometry();

            /* Emit a signal about guest was resized: */
            emit resizeHintDone();

            /* Unlock after processing guest resize event: */
            if (m_pSyncBlocker && m_pSyncBlocker->isRunning())
                m_pSyncBlocker->quit();

            pEvent->accept();
            return true;
        }

        default:
            break;
    }
    return UIMachineView::event(pEvent);
}
Example #11
0
UIMachineLogic* UIMachineView::machineLogic() const
{
    return machineWindowWrapper()->machineLogic();
}
Example #12
0
void UIMachineView::prepareFrameBuffer()
{
    /* Prepare frame-buffer depending on render-mode: */
    switch (vboxGlobal().vmRenderMode())
    {
#ifdef VBOX_GUI_USE_QIMAGE
        case VBoxDefs::QImageMode:
# ifdef VBOX_WITH_VIDEOHWACCEL
            if (m_fAccelerate2DVideo)
            {
                UIFrameBuffer* pFramebuffer = uisession()->frameBuffer(screenId());
                if (pFramebuffer)
                    pFramebuffer->setView(this);
                else
                {
                    /* these two additional template args is a workaround to this [VBox|UI] duplication
                     * @todo: they are to be removed once VBox stuff is gone */
                    pFramebuffer = new VBoxOverlayFrameBuffer<UIFrameBufferQImage, UIMachineView, UIResizeEvent>(this, &machineWindowWrapper()->session(), (uint32_t)screenId());
                    uisession()->setFrameBuffer(screenId(), pFramebuffer);
                }
                m_pFrameBuffer = pFramebuffer;
            }
            else
                m_pFrameBuffer = new UIFrameBufferQImage(this);
# else /* VBOX_WITH_VIDEOHWACCEL */
            m_pFrameBuffer = new UIFrameBufferQImage(this);
# endif /* !VBOX_WITH_VIDEOHWACCEL */
            break;
#endif /* VBOX_GUI_USE_QIMAGE */
#ifdef VBOX_GUI_USE_QGLFB
        case VBoxDefs::QGLMode:
            m_pFrameBuffer = new UIFrameBufferQGL(this);
            break;
//        case VBoxDefs::QGLOverlayMode:
//            m_pFrameBuffer = new UIQGLOverlayFrameBuffer(this);
//            break;
#endif /* VBOX_GUI_USE_QGLFB */
#ifdef VBOX_GUI_USE_SDL
        case VBoxDefs::SDLMode:
            /* Indicate that we are doing all drawing stuff ourself: */
            // TODO_NEW_CORE
            viewport()->setAttribute(Qt::WA_PaintOnScreen);
# ifdef Q_WS_X11
            /* This is somehow necessary to prevent strange X11 warnings on i386 and segfaults on x86_64: */
            XFlush(QX11Info::display());
# endif /* Q_WS_X11 */
# if defined(VBOX_WITH_VIDEOHWACCEL) && defined(DEBUG_misha) /* not tested yet */
            if (m_fAccelerate2DVideo)
            {
                class UIFrameBuffer* pFramebuffer = uisession()->frameBuffer(screenId());
                if (pFramebuffer)
                    pFramebuffer->setView(this);
                else
                {
                    /* these two additional template args is a workaround to this [VBox|UI] duplication
                     * @todo: they are to be removed once VBox stuff is gone */
                    pFramebuffer = new VBoxOverlayFrameBuffer<UIFrameBufferSDL, UIMachineView, UIResizeEvent>(this, &machineWindowWrapper()->session(), (uint32_t)screenId());
                    uisession()->setFrameBuffer(screenId(), pFramebuffer);
                }
                m_pFrameBuffer = pFramebuffer;
            }
            else
                m_pFrameBuffer = new UIFrameBufferSDL(this);
# else
            m_pFrameBuffer = new UIFrameBufferSDL(this);
# endif
            /* Disable scrollbars because we cannot correctly draw in a scrolled window using SDL: */
            horizontalScrollBar()->setEnabled(false);
            verticalScrollBar()->setEnabled(false);
            break;
#endif /* VBOX_GUI_USE_SDL */
#if 0 // TODO: Enable DDraw frame buffer!
#ifdef VBOX_GUI_USE_DDRAW
        case VBoxDefs::DDRAWMode:
            m_pFrameBuffer = new UIDDRAWFrameBuffer(this);
            if (!m_pFrameBuffer || m_pFrameBuffer->address() == NULL)
            {
                if (m_pFrameBuffer)
                    delete m_pFrameBuffer;
                m_mode = VBoxDefs::QImageMode;
                m_pFrameBuffer = new UIFrameBufferQImage(this);
            }
            break;
#endif /* VBOX_GUI_USE_DDRAW */
#endif
#ifdef VBOX_GUI_USE_QUARTZ2D
        case VBoxDefs::Quartz2DMode:
            /* Indicate that we are doing all drawing stuff ourself: */
            viewport()->setAttribute(Qt::WA_PaintOnScreen);
# ifdef VBOX_WITH_VIDEOHWACCEL
            if (m_fAccelerate2DVideo)
            {
                UIFrameBuffer* pFramebuffer = uisession()->frameBuffer(screenId());
                if (pFramebuffer)
                    pFramebuffer->setView(this);
                else
                {
                    /* these two additional template args is a workaround to this [VBox|UI] duplication
                     * @todo: they are to be removed once VBox stuff is gone */
                    pFramebuffer = new VBoxOverlayFrameBuffer<UIFrameBufferQuartz2D, UIMachineView, UIResizeEvent>(this, &machineWindowWrapper()->session(), (uint32_t)screenId());
                    uisession()->setFrameBuffer(screenId(), pFramebuffer);
                }
                m_pFrameBuffer = pFramebuffer;
            }
            else
                m_pFrameBuffer = new UIFrameBufferQuartz2D(this);
# else /* VBOX_WITH_VIDEOHWACCEL */
            m_pFrameBuffer = new UIFrameBufferQuartz2D(this);
# endif /* !VBOX_WITH_VIDEOHWACCEL */
            break;
#endif /* VBOX_GUI_USE_QUARTZ2D */
        default:
            AssertReleaseMsgFailed(("Render mode must be valid: %d\n", vboxGlobal().vmRenderMode()));
            LogRel(("Invalid render mode: %d\n", vboxGlobal().vmRenderMode()));
            qApp->exit(1);
            break;
    }

    /* If frame-buffer was prepared: */
    if (m_pFrameBuffer)
    {
        /* Prepare display: */
        CDisplay display = session().GetConsole().GetDisplay();
        Assert(!display.isNull());
#ifdef VBOX_WITH_VIDEOHWACCEL
        CFramebuffer fb(NULL);
        if (m_fAccelerate2DVideo)
        {
            LONG XOrigin, YOrigin;
            /* Check if the framebuffer is already assigned;
             * in this case we do not need to re-assign it neither do we need to AddRef. */
            display.GetFramebuffer(m_uScreenId, fb, XOrigin, YOrigin);
        }
        if (fb.raw() != m_pFrameBuffer) /* <-this will evaluate to true iff m_fAccelerate2DVideo is disabled or iff no framebuffer is yet assigned */
#endif /* VBOX_WITH_VIDEOHWACCEL */
        {
            m_pFrameBuffer->AddRef();
        }
        /* Always perform SetFramebuffer to ensure 3D gets notified: */
        display.SetFramebuffer(m_uScreenId, CFramebuffer(m_pFrameBuffer));
    }

    QSize size;
#ifdef Q_WS_X11
    /* Processing pseudo resize-event to synchronize frame-buffer with stored
     * framebuffer size. On X11 this will be additional done when the machine
     * state was 'saved'. */
    if (session().GetMachine().GetState() == KMachineState_Saved)
        size = guestSizeHint();
#endif /* Q_WS_X11 */
    /* If there is a preview image saved, we will resize the framebuffer to the
     * size of that image. */
    ULONG buffer = 0, width = 0, height = 0;
    CMachine machine = session().GetMachine();
    machine.QuerySavedScreenshotPNGSize(0, buffer, width, height);
    if (buffer > 0)
    {
        /* Init with the screenshot size */
        size = QSize(width, height);
        /* Try to get the real guest dimensions from the save state */
        ULONG guestWidth = 0, guestHeight = 0;
        machine.QuerySavedGuestSize(0, guestWidth, guestHeight);
        if (   guestWidth  > 0
            && guestHeight > 0)
            size = QSize(guestWidth, guestHeight);
    }
    /* If we have a valid size, resize the framebuffer. */
    if (   size.width() > 0
        && size.height() > 0)
    {
        UIResizeEvent event(FramebufferPixelFormat_Opaque, NULL, 0, 0, size.width(), size.height());
        frameBuffer()->resizeEvent(&event);
    }
}