Changeset 46255 in vbox for trunk/src/VBox/Frontends
- Timestamp:
- May 24, 2013 12:44:24 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 85987
- Location:
- trunk/src/VBox/Frontends/VirtualBox/src/runtime
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBuffer.h
r46129 r46255 216 216 virtual void resizeEvent(UIResizeEvent *pEvent) = 0; 217 217 virtual void paintEvent(QPaintEvent *pEvent) = 0; 218 virtual void applyVisibleRegionEvent(UISetRegionEvent *pEvent) = 0; 218 219 219 220 #ifdef VBOX_WITH_VIDEOHWACCEL … … 236 237 ulong m_width; 237 238 ulong m_height; 239 QRegion m_visibleRegion; 238 240 QSize m_scaledSize; 239 241 int64_t m_WinId; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.cpp
r46120 r46255 34 34 # include "VBoxGlobal.h" 35 35 # include "UISession.h" 36 # include "UIMachineLogic.h" 37 # ifdef Q_WS_X11 38 # include "UIMachineWindow.h" 39 # endif /* Q_WS_X11 */ 36 40 37 41 /* COM includes: */ … … 51 55 void UIFrameBufferQImage::resizeEvent(UIResizeEvent *pEvent) 52 56 { 53 #if 0 54 LogFlowFunc (("fmt=%d, vram=%p, bpp=%d, bpl=%d, width=%d, height=%d\n", 55 pEvent->pixelFormat(), pEvent->VRAM(), 56 pEvent->bitsPerPixel(), pEvent->bytesPerLine(), 57 pEvent->width(), pEvent->height())); 58 #endif 57 /* Invalidate visible-region if necessary: */ 58 if (m_width != pEvent->width() || 59 m_height != pEvent->height()) 60 m_visibleRegion = QRegion(); 59 61 60 62 /* Remember new width/height: */ … … 156 158 goFallback(); 157 159 158 /* Scaled image by default is empty: */ 160 /* Depending on visual-state type: */ 161 switch (m_pMachineView->machineLogic()->visualStateType()) 162 { 163 case UIVisualStateType_Seamless: 164 paintSeamless(pEvent); 165 break; 166 case UIVisualStateType_Scale: 167 paintScale(pEvent); 168 break; 169 default: 170 paintDefault(pEvent); 171 break; 172 } 173 } 174 175 void UIFrameBufferQImage::applyVisibleRegionEvent(UISetRegionEvent *pEvent) 176 { 177 /* Make sure visible-region changed: */ 178 if (m_visibleRegion == pEvent->region()) 179 return; 180 181 /* Compose viewport region to update: */ 182 QRegion toUpdate = pEvent->region() + m_visibleRegion; 183 /* Remember new visible-region: */ 184 m_visibleRegion = pEvent->region(); 185 /* Update viewport region finally: */ 186 m_pMachineView->viewport()->update(toUpdate); 187 #ifdef Q_WS_X11 188 /* Qt 4.8.3 under X11 has Qt::WA_TranslucentBackground window attribute broken, 189 * so we are still have to use old one known Xshape extension wrapped by the widget setMask API: */ 190 m_pMachineView->machineWindow()->setMask(m_visibleRegion); 191 #endif /* Q_WS_X11 */ 192 } 193 194 void UIFrameBufferQImage::paintDefault(QPaintEvent *pEvent) 195 { 196 /* Get rectangle to paint: */ 197 QRect paintRect = pEvent->rect().intersected(m_img.rect()); 198 if (paintRect.isEmpty()) 199 return; 200 201 /* Create painter: */ 202 QPainter painter(m_pMachineView->viewport()); 203 204 /* Draw image rectangle depending on rectangle width: */ 205 if ((ulong)paintRect.width() < m_width * 2 / 3) 206 drawImageRectNarrow(painter, m_img, 207 paintRect, m_pMachineView->contentsX(), m_pMachineView->contentsY()); 208 else 209 drawImageRectWide(painter, m_img, 210 paintRect, m_pMachineView->contentsX(), m_pMachineView->contentsY()); 211 } 212 213 void UIFrameBufferQImage::paintSeamless(QPaintEvent *pEvent) 214 { 215 /* Get rectangle to paint: */ 216 QRect paintRect = pEvent->rect().intersected(m_img.rect()); 217 if (paintRect.isEmpty()) 218 return; 219 220 /* Create painter: */ 221 QPainter painter(m_pMachineView->viewport()); 222 223 /* Clear paint rectangle first: */ 224 painter.setCompositionMode(QPainter::CompositionMode_Clear); 225 painter.eraseRect(paintRect); 226 painter.setCompositionMode(QPainter::CompositionMode_SourceOver); 227 228 /* Repaint all the rectangles of visible-region: */ 229 QRegion visiblePaintRegion = m_visibleRegion & paintRect; 230 foreach (const QRect &rect, visiblePaintRegion.rects()) 231 { 232 #ifdef Q_WS_WIN 233 /* Replace translucent background with black one, 234 * that is necessary for window with Qt::WA_TranslucentBackground: */ 235 painter.setCompositionMode(QPainter::CompositionMode_Source); 236 painter.fillRect(rect, QColor(Qt::black)); 237 painter.setCompositionMode(QPainter::CompositionMode_SourceAtop); 238 #endif /* Q_WS_WIN */ 239 240 /* Draw image rectangle depending on rectangle width: */ 241 if ((ulong)rect.width() < m_width * 2 / 3) 242 drawImageRectNarrow(painter, m_img, 243 rect, m_pMachineView->contentsX(), m_pMachineView->contentsY()); 244 else 245 drawImageRectWide(painter, m_img, 246 rect, m_pMachineView->contentsX(), m_pMachineView->contentsY()); 247 } 248 } 249 250 void UIFrameBufferQImage::paintScale(QPaintEvent *pEvent) 251 { 252 /* Scaled image is NULL by default: */ 159 253 QImage scaledImage; 160 /* If scaled-factor is set and current image is NOT null: */254 /* But if scaled-factor is set and current image is NOT null: */ 161 255 if (m_scaledSize.isValid() && !m_img.isNull()) 162 256 { 163 /* We are doing a deep copy of image to make sure it will not be257 /* We are doing a deep copy of the image to make sure it will not be 164 258 * detached during scale process, otherwise we can get a frozen frame-buffer. */ 165 259 scaledImage = m_img.copy(); 166 /* Scale image toscaled-factor: */260 /* And scaling the image to predefined scaled-factor: */ 167 261 scaledImage = scaledImage.scaled(m_scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); 168 262 } 169 /* Choose required image: */ 170 QImage *pSourceImage = scaledImage.isNull() ? &m_img : &scaledImage; 171 172 /* Get clipping rectangle: */ 173 const QRect &r = pEvent->rect().intersected(pSourceImage->rect()); 174 if (r.isEmpty()) 175 return; 176 177 #if 0 178 LogFlowFunc (("%dx%d-%dx%d (img=%dx%d)\n", r.x(), r.y(), r.width(), r.height(), img.width(), img.height())); 179 #endif 263 /* Finally we are choosing image to paint from: */ 264 QImage &sourceImage = scaledImage.isNull() ? m_img : scaledImage; 265 266 /* Get rectangle to paint: */ 267 QRect paintRect = pEvent->rect().intersected(sourceImage.rect()); 268 if (paintRect.isEmpty()) 269 return; 180 270 181 271 /* Create painter: */ 182 272 QPainter painter(m_pMachineView->viewport()); 183 if ((ulong)r.width() < m_width * 2 / 3) 184 { 185 /* This method is faster for narrow updates: */ 186 m_PM = QPixmap::fromImage(pSourceImage->copy(r.x() + m_pMachineView->contentsX(), 187 r.y() + m_pMachineView->contentsY(), 188 r.width(), r.height())); 189 painter.drawPixmap(r.x(), r.y(), m_PM); 190 } 273 274 /* Draw image rectangle depending on rectangle width: */ 275 if ((ulong)paintRect.width() < m_width * 2 / 3) 276 drawImageRectNarrow(painter, sourceImage, 277 paintRect, m_pMachineView->contentsX(), m_pMachineView->contentsY()); 191 278 else 192 { 193 /* This method is faster for wide updates: */ 194 m_PM = QPixmap::fromImage(QImage(pSourceImage->scanLine(r.y() + m_pMachineView->contentsY()), 195 pSourceImage->width(), r.height(), pSourceImage->bytesPerLine(), 196 QImage::Format_RGB32)); 197 painter.drawPixmap(r.x(), r.y(), m_PM, r.x() + m_pMachineView->contentsX(), 0, 0, 0); 198 } 279 drawImageRectWide(painter, sourceImage, 280 paintRect, m_pMachineView->contentsX(), m_pMachineView->contentsY()); 281 } 282 283 /* static */ 284 void UIFrameBufferQImage::drawImageRectNarrow(QPainter &painter, const QImage &image, 285 const QRect &rect, int iContentsShiftX, int iContentsShiftY) 286 { 287 /* This method is faster for narrow updates: */ 288 QPixmap pm = QPixmap::fromImage(image.copy(rect.x() + iContentsShiftX, 289 rect.y() + iContentsShiftY, 290 rect.width(), rect.height())); 291 painter.drawPixmap(rect.x(), rect.y(), pm); 292 } 293 294 /* static */ 295 void UIFrameBufferQImage::drawImageRectWide(QPainter &painter, const QImage &image, 296 const QRect &rect, int iContentsShiftX, int /*iContentsShiftY*/) 297 { 298 /* This method is faster for wide updates: */ 299 QPixmap pm = QPixmap::fromImage(QImage(image.scanLine(rect.y() + iContentsShiftX), 300 image.width(), rect.height(), image.bytesPerLine(), 301 QImage::Format_RGB32)); 302 painter.drawPixmap(rect.x(), rect.y(), pm, rect.x() + iContentsShiftX, 0, 0, 0); 199 303 } 200 304 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQImage.h
r46064 r46255 47 47 void resizeEvent(UIResizeEvent *pEvent); 48 48 void paintEvent(QPaintEvent *pEvent); 49 void applyVisibleRegionEvent(UISetRegionEvent *pEvent); 49 50 50 51 private: 52 53 /* Helpers: Visual-mode paint stuff: */ 54 void paintDefault(QPaintEvent *pEvent); 55 void paintSeamless(QPaintEvent *pEvent); 56 void paintScale(QPaintEvent *pEvent); 57 58 /* Static helpers: Drawing stuff: */ 59 static void drawImageRectNarrow(QPainter &painter, const QImage &image, 60 const QRect &rect, int iContentsShiftX, int iContentsShiftY); 61 static void drawImageRectWide(QPainter &painter, const QImage &image, 62 const QRect &rect, int iContentsShiftX, int iContentsShiftY); 51 63 52 64 /* Helper: Fallback stuff: */ … … 54 66 55 67 /* Variables: */ 56 QPixmap m_PM;57 68 QImage m_img; 58 69 ulong m_uPixelFormat; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.cpp
r46120 r46255 7 7 8 8 /* 9 * Copyright (C) 2006-201 2Oracle Corporation9 * Copyright (C) 2006-2013 Oracle Corporation 10 10 * 11 11 * This file is part of VirtualBox Open Source Edition (OSE), as … … 463 463 } 464 464 465 void UIFrameBufferQuartz2D::applyVisibleRegionEvent(UISetRegionEvent *pEvent) 466 { 467 /* Make sure visible-region changed: */ 468 if (m_visibleRegion == pEvent->region()) 469 return; 470 471 /* Remember new visible-region: */ 472 m_visibleRegion = pEvent->region(); 473 /* Invalidate whole the viewport: */ 474 ::darwinWindowInvalidateShape(m_pMachineView->viewport()); 475 } 476 465 477 void UIFrameBufferQuartz2D::clean(bool fPreserveRegions) 466 478 { -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/UIFrameBufferQuartz2D.h
r46120 r46255 50 50 void resizeEvent(UIResizeEvent *pEvent); 51 51 void paintEvent(QPaintEvent *pEvent); 52 void applyVisibleRegionEvent(UISetRegionEvent *pEvent); 52 53 53 54 #ifdef VBOX_WITH_VIDEOHWACCEL -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.cpp
r46225 r46255 85 85 { 86 86 /* Apply new seamless-region: */ 87 UISetRegionEvent *pSetRegionEvent = static_cast<UISetRegionEvent*>(pEvent); 88 m_lastVisibleRegion = pSetRegionEvent->region(); 89 machineWindow()->setMask(m_lastVisibleRegion); 87 m_pFrameBuffer->applyVisibleRegionEvent(static_cast<UISetRegionEvent*>(pEvent)); 90 88 return true; 91 89 } -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineViewSeamless.h
r46020 r46255 6 6 7 7 /* 8 * Copyright (C) 2010-201 1Oracle Corporation8 * Copyright (C) 2010-2013 Oracle Corporation 9 9 * 10 10 * This file is part of VirtualBox Open Source Edition (OSE), as … … 26 26 { 27 27 Q_OBJECT; 28 29 public:30 31 /* Public getters: */32 QRegion lastVisibleRegion() const { return m_lastVisibleRegion; }33 28 34 29 protected: … … 72 67 QSize calculateMaxGuestSize() const; 73 68 74 /* Private variables: */75 QRegion m_lastVisibleRegion;76 77 69 /* Friend classes: */ 78 70 friend class UIMachineView; -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.cpp
r46244 r46255 87 87 UIMachineWindow::prepareVisualState(); 88 88 89 /* This might be required to correctly mask: */ 90 centralWidget()->setAutoFillBackground(false); 89 #ifdef Q_WS_WIN 90 /* Enable translucent background for Win host, 91 * Mac host has it native, Qt 4.8.3 under x11 host has is broken: */ 92 setAttribute(Qt::WA_TranslucentBackground); 93 #endif /* Q_WS_WIN */ 91 94 92 95 #ifdef Q_WS_MAC … … 270 273 #endif /* Q_WS_MAC */ 271 274 272 void UIMachineWindowSeamless::setMask(const QRegion &incomingRegion) 273 { 274 /* Copy region: */ 275 QRegion region(incomingRegion); 276 277 #ifndef Q_WS_MAC 275 #ifdef Q_WS_WIN 276 void UIMachineWindowSeamless::showEvent(QShowEvent*) 277 { 278 /* Following workaround allows to fix the next Qt BUG: 279 * https://bugreports.qt-project.org/browse/QTBUG-17548 280 * https://bugreports.qt-project.org/browse/QTBUG-30974 281 * Widgets with Qt::WA_TranslucentBackground attribute 282 * stops repainting after minimizing/restoring, we have to call for single update. */ 283 QApplication::postEvent(this, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority); 284 } 285 #endif /* Q_WS_WIN */ 286 287 #ifdef Q_WS_X11 288 void UIMachineWindowSeamless::setMask(const QRegion ®ion) 289 { 290 /* Prepare mask-region: */ 291 QRegion maskRegion(region); 292 278 293 /* Shift region if left spacer width is NOT zero or top spacer height is NOT zero: */ 279 294 if (m_pLeftSpacer->geometry().width() || m_pTopSpacer->geometry().height()) 280 region.translate(m_pLeftSpacer->geometry().width(), m_pTopSpacer->geometry().height()); 281 #endif /* !Q_WS_MAC */ 282 283 #ifdef VBOX_GUI_USE_QUARTZ2D 284 if (vboxGlobal().vmRenderMode() == Quartz2DMode) 285 { 286 /* If we are using the Quartz2D backend we have to trigger a repaint only. 287 * All the magic clipping stuff is done in the paint engine. */ 288 ::darwinWindowInvalidateShape(m_pMachineView->viewport()); 289 } 290 #else /* VBOX_GUI_USE_QUARTZ2D */ 295 maskRegion.translate(m_pLeftSpacer->geometry().width(), m_pTopSpacer->geometry().height()); 296 291 297 /* Seamless-window for empty region should be empty too, 292 * but native API wrapped by the QWidget::setMask()doesn't allow this.298 * but the QWidget::setMask() wrapper doesn't allow this. 293 299 * Instead, we have a full painted screen of seamless-geometry size visible. 294 300 * Moreover, we can't just hide the empty seamless-window as 'hiding' 295 301 * 1. will collide with the multi-screen layout behavior and 296 302 * 2. will cause a task-bar flicker on moving window from one screen to another. 297 * As a temporarythough quite a dirty workaround we have to make sure303 * As a *temporary* though quite a dirty workaround we have to make sure 298 304 * region have at least one pixel. */ 299 if (region.isEmpty()) 300 region += QRect(0, 0, 1, 1); 301 /* Make sure region had changed: */ 302 if (m_previousRegion != region) 303 { 304 /* Remember new region: */ 305 m_previousRegion = region; 306 /* Assign new region: */ 307 UIMachineWindow::setMask(m_previousRegion); 308 /* Update viewport contents: */ 309 m_pMachineView->viewport()->update(); 310 } 311 #endif /* !VBOX_GUI_USE_QUARTZ2D */ 312 } 313 305 if (maskRegion.isEmpty()) 306 maskRegion += QRect(0, 0, 1, 1); 307 /* Make sure mask-region had changed: */ 308 if (m_maskRegion != maskRegion) 309 { 310 /* Compose viewport region to update: */ 311 QRegion toUpdate = m_maskRegion + maskRegion; 312 /* Remember new mask-region: */ 313 m_maskRegion = maskRegion; 314 /* Assign new mask-region: */ 315 UIMachineWindow::setMask(m_maskRegion); 316 /* Update viewport region finally: */ 317 m_pMachineView->viewport()->update(toUpdate); 318 } 319 } 320 #endif /* Q_WS_X11 */ 321 -
trunk/src/VBox/Frontends/VirtualBox/src/runtime/seamless/UIMachineWindowSeamless.h
r46244 r46255 79 79 #endif /* Q_WS_MAC */ 80 80 81 /* Helpers: */ 81 #ifdef Q_WS_WIN 82 /* Handler: Translucency stuff: */ 83 void showEvent(QShowEvent *pEvent); 84 #endif /* Q_WS_WIN */ 85 86 #ifdef Q_WS_X11 87 /* Helper: Masking stuff: */ 82 88 void setMask(const QRegion ®ion); 89 #endif /* Q_WS_X11 */ 83 90 84 91 /* Widgets: */ … … 88 95 #endif /* !Q_WS_MAC */ 89 96 90 /* Variables: */ 91 QRegion m_previousRegion; 97 #ifdef Q_WS_X11 98 /* Variable: Masking stuff: */ 99 QRegion m_maskRegion; 100 #endif /* Q_WS_X11 */ 92 101 93 102 /* Factory support: */
Note:
See TracChangeset
for help on using the changeset viewer.