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())); } }
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(); } }
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); }
UIMachineLogic* UIMachineView::machineLogic() const { return machineWindowWrapper()->machineLogic(); }
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); } }