Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h	(revision 3671)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleView.h	(revision 3674)
@@ -95,4 +95,6 @@
     void fixModifierState (LONG *codes, uint *count);
 
+    bool isInSeamlessMode();
+
 signals:
 
@@ -100,5 +102,5 @@
     void mouseStateChanged (int state);
     void machineStateChanged (CEnums::MachineState state);
-    void additionsStateChanged (const QString &, bool);
+    void additionsStateChanged (const QString &, bool, bool);
 
 protected:
Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h	(revision 3671)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxConsoleWnd.h	(revision 3674)
@@ -73,4 +73,6 @@
     bool isTrueFullscreen() const { return full_screen; }
 
+    bool isTrueSeamless() const { return mIsInSeamlessMode; }
+
     void setMouseIntegrationLocked (bool);
 
@@ -120,4 +122,5 @@
 
     void vmFullscreen (bool on);
+    void vmSeamless (bool on);
     void vmAutoresizeGuest (bool on);
     void vmAdjustWindow();
@@ -162,5 +165,5 @@
     void updateMouseState (int state);
 
-    void updateAdditionsState (const QString&, bool);
+    void updateAdditionsState (const QString&, bool, bool);
 
     void tryClose();
@@ -177,4 +180,5 @@
     // VM actions
     QAction *vmFullscreenAction;
+    QAction *vmSeamlessAction;
     QAction *vmAutoresizeGuestAction;
     QAction *vmAdjustWindowAction;
@@ -279,4 +283,5 @@
     // variables for dealing with true fullscreen
     bool full_screen : 1;
+    bool mIsInSeamlessMode : 1;
     int normal_wflags;
     bool was_max : 1;
Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 3671)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 3674)
@@ -125,4 +125,5 @@
         ResizeEventType = QEvent::User,
         RepaintEventType,
+        SetRegionEventType,
         MouseCapabilityEventType,
         MousePointerChangeEventType,
@@ -143,5 +144,5 @@
 #if defined (Q_WS_MAC)
         ShowWindowEventType,
-#endif 
+#endif
     };
 };
Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 3671)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 3674)
@@ -104,4 +104,18 @@
 private:
     int ex, ey, ew, eh;
+};
+
+/**
+ *  Frame buffer set region event.
+ */
+class VBoxSetRegionEvent : public QEvent
+{
+public:
+    VBoxSetRegionEvent (const QRegion &aReg)
+        : QEvent ((QEvent::Type) VBoxDefs::SetRegionEventType)
+        , mReg (aReg) {}
+    QRegion region() { return mReg; }
+private:
+    QRegion mReg;
 };
 
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 3671)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 3674)
@@ -231,14 +231,18 @@
     GuestAdditionsEvent (const QString &aOsTypeId,
                          const QString &aAddVersion,
-                         bool aAddActive) :
+                         bool aAddActive,
+                         bool aSeamlessActive) :
         QEvent ((QEvent::Type) VBoxDefs::AdditionsStateChangeEventType),
-        mOsTypeId (aOsTypeId), mAddVersion (aAddVersion), mAddActive (aAddActive) {}
+        mOsTypeId (aOsTypeId), mAddVersion (aAddVersion),
+        mAddActive (aAddActive), mSeamlessActive (aSeamlessActive) {}
     const QString &osTypeId() const { return mOsTypeId; }
     const QString &additionVersion() const { return mAddVersion; }
     bool additionActive() const { return mAddActive; }
+    bool seamlessActive() const { return mSeamlessActive; }
 private:
     QString mOsTypeId;
     QString mAddVersion;
     bool mAddActive;
+    bool mSeamlessActive;
 };
 
@@ -391,5 +395,6 @@
                                      guest.GetOSTypeId(),
                                      guest.GetAdditionsVersion(),
-                                     guest.GetAdditionsActive()));
+                                     guest.GetAdditionsActive(),
+                                     guest.GetSeamlessSupport()));
         return S_OK;
     }
@@ -935,4 +940,5 @@
                  * full screen */
                 if (!mainwnd->isTrueFullscreen() &&
+                    !mainwnd->isTrueSeamless() &&
                     !topLevelWidget()->isMaximized())
                     normalizeGeometry (true /* adjustPosition */);
@@ -955,4 +961,11 @@
             }
 #endif /* Q_WS_MAC */
+
+            case VBoxDefs::SetRegionEventType:
+            {
+                VBoxSetRegionEvent *sre = (VBoxSetRegionEvent*) e;
+                mainwnd->setMask (sre->region());
+                return true;
+            }
 
             case VBoxDefs::MousePointerChangeEventType:
@@ -1022,5 +1035,7 @@
                 maybeRestrictMinimumSize();
 
-                emit additionsStateChanged (ge->additionVersion(), ge->additionActive());
+                emit additionsStateChanged (ge->additionVersion(),
+                                            ge->additionActive(),
+                                            ge->seamlessActive());
                 return true;
             }
@@ -1261,5 +1276,6 @@
                      * variable should be set to true here in case of mainwnd is
                      * maximized or in fullscreen state. */
-                    if (mainwnd->isMaximized() || mainwnd->isTrueFullscreen())
+                    if (mainwnd->isMaximized() || mainwnd->isTrueFullscreen()
+                                               || mainwnd->isTrueSeamless())
                         ignore_mainwnd_resize = true;
                 }
@@ -1273,5 +1289,6 @@
                 if (!mainwnd->isMinimized() &&
                     !mainwnd->isMaximized() &&
-                    !mainwnd->isTrueFullscreen())
+                    !mainwnd->isTrueFullscreen() &&
+                    !mainwnd->isTrueSeamless())
                     QTimer::singleShot (0, this, SLOT (exitFullScreen()));
             }
@@ -1824,4 +1841,9 @@
 }
 
+bool VBoxConsoleView::isInSeamlessMode()
+{
+    return mainwnd->isTrueSeamless();
+}
+
 /**
  *  Called on exit from fullscreen or from maximized mode.
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 3671)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 3674)
@@ -225,4 +225,5 @@
     , no_auto_close (false)
     , full_screen (false)
+    , mIsInSeamlessMode (false)
     , normal_wflags (getWFlags())
     , was_max (false)
@@ -271,4 +272,9 @@
     vmFullscreenAction->setToggleAction (true);
 
+    vmSeamlessAction = new QAction (this, "vmSeamlessAction");
+    vmSeamlessAction->setIconSet (
+        VBoxGlobal::iconSet ("nw_16px.png", "nw_disabled_16px.png"));
+    vmSeamlessAction->setToggleAction (true);
+
     vmAutoresizeGuestAction = new QAction (runningActions, "vmAutoresizeGuestAction");
     vmAutoresizeGuestAction->setIconSet (
@@ -372,4 +378,5 @@
     QPopupMenu *vmMenu = new QPopupMenu (this, "vmMenu");
     vmFullscreenAction->addTo (vmMenu);
+    vmSeamlessAction->addTo (vmMenu);
     vmAdjustWindowAction->addTo (vmMenu);
     vmAutoresizeGuestAction->addTo (vmMenu);
@@ -536,4 +543,6 @@
     connect (vmFullscreenAction, SIGNAL (toggled (bool)),
              this, SLOT (vmFullscreen (bool)));
+    connect (vmSeamlessAction, SIGNAL (toggled (bool)),
+             this, SLOT (vmSeamless (bool)));
     connect (vmAutoresizeGuestAction, SIGNAL (toggled (bool)),
              this, SLOT (vmAutoresizeGuest (bool)));
@@ -679,4 +688,5 @@
 
 static const char *GUI_Fullscreen = "GUI/Fullscreen";
+static const char *GUI_Seamless = "GUI/Seamless";
 static const char *GUI_AutoresizeGuest = "GUI/AutoresizeGuest";
 extern const char *GUI_FirstRun = "GUI/FirstRun";
@@ -729,4 +739,9 @@
         if (str == "on")
             vmFullscreenAction->setOn (true);
+
+        vmSeamlessAction->setEnabled (false);
+        str = cmachine.GetExtraData (GUI_Seamless);
+        if (str == "on")
+            vmSeamlessAction->setOn (true);
 
         str = cmachine.GetExtraData (GUI_AutoresizeGuest);
@@ -762,5 +777,5 @@
             normal_pos = QPoint (x, y);
             normal_size = QSize (w, h);
-            if (!full_screen)
+            if (!full_screen && !vmSeamlessAction->isOn())
             {
                 move (normal_pos);
@@ -779,5 +794,5 @@
             normal_pos = QPoint();
             normal_size = QSize();
-            if (!full_screen)
+            if (!full_screen && !vmSeamlessAction->isOn())
             {
                 console->normalizeGeometry (true /* adjustPosition */);
@@ -845,6 +860,6 @@
     connect (console, SIGNAL (machineStateChanged (CEnums::MachineState)),
              this, SLOT (updateMachineState (CEnums::MachineState)));
-    connect (console, SIGNAL (additionsStateChanged (const QString&, bool)),
-             this, SLOT (updateAdditionsState (const QString &, bool)));
+    connect (console, SIGNAL (additionsStateChanged (const QString&, bool, bool)),
+             this, SLOT (updateAdditionsState (const QString &, bool, bool)));
 
 #ifdef Q_WS_MAC
@@ -1015,5 +1030,6 @@
                                  .arg (normal_size.width())
                                  .arg (normal_size.height());
-        if (isMaximized() || (full_screen && was_max))
+        if (isMaximized() || (full_screen && was_max)
+                          || (mIsInSeamlessMode && was_max))
             winPos += QString (",%1").arg (GUI_LastWindowPosition_Max);
 
@@ -1022,4 +1038,6 @@
         machine.SetExtraData (GUI_Fullscreen,
                               vmFullscreenAction->isOn() ? "on" : "off");
+        machine.SetExtraData (GUI_Seamless,
+                              vmSeamlessAction->isOn() ? "on" : "off");
         machine.SetExtraData (GUI_AutoresizeGuest,
                               vmAutoresizeGuestAction->isOn() ? "on" : "off");
@@ -1070,5 +1088,5 @@
         {
             QResizeEvent *re = (QResizeEvent *) e;
-            if (!full_screen &&
+            if (!full_screen && !mIsInSeamlessMode &&
                 (windowState() & (WindowMaximized | WindowMinimized |
                                   WindowFullScreen)) == 0)
@@ -1083,5 +1101,5 @@
         case QEvent::Move:
         {
-            if (!full_screen &&
+            if (!full_screen && !mIsInSeamlessMode &&
                 (windowState() & (WindowMaximized | WindowMinimized |
                                   WindowFullScreen)) == 0)
@@ -1354,4 +1372,7 @@
     vmFullscreenAction->setStatusTip (tr ("Switch to fullscreen mode" ));
 
+    vmSeamlessAction->setMenuText (tr ("&Seamless Mode") + "\tHost+S");
+    vmSeamlessAction->setStatusTip (tr ("Switch to seamless mode"));
+
     vmDisMouseIntegrMenu->setToolTip (tr ("Mouse Integration",
                                           "enable/disable..."));
@@ -1764,4 +1785,5 @@
 
     vmAdjustWindowAction->setEnabled (!on);
+    vmSeamlessAction->setEnabled (!on);
 
     bool wasHidden = isHidden();
@@ -1856,5 +1878,116 @@
         if (was_max)
             setWindowState (windowState() | WindowMaximized);
-        QTimer::singleShot (0, console, SLOT (exitFullScreen()));
+        else
+            QTimer::singleShot (0, console, SLOT (exitFullScreen()));
+    }
+
+    /* VBoxConsoleView loses focus for some reason after reparenting,
+     * restore it */
+    console->setFocus();
+
+    if (!wasHidden)
+        show();
+}
+
+void VBoxConsoleWnd::vmSeamless (bool on)
+{
+    if (on && !vmSeamlessAction->isEnabled() ||
+        !on && !mIsInSeamlessMode ||
+        on && full_screen)
+        return;
+
+    AssertReturnVoid (console);
+    AssertReturnVoid (mIsInSeamlessMode != on);
+    AssertReturnVoid ((hidden_children.isEmpty() == on));
+
+    /* activate the auto-resize feature required for the seamless mode */
+    if (!vmAutoresizeGuestAction->isOn())
+        vmAutoresizeGuestAction->setOn (true);
+    mIsInSeamlessMode = on;
+
+    vmAdjustWindowAction->setEnabled (!on);
+    vmFullscreenAction->setEnabled (!on);
+    vmAutoresizeGuestAction->setEnabled (!on);
+
+    bool wasHidden = isHidden();
+
+    if (on)
+    {
+        /* Save the previous scroll-view minimum size before entering
+         * fullscreen state to restore this minimum size before the exiting
+         * fullscreen. Required for correct scroll-view and guest display
+         * update in SDL mode. */
+        prev_min_size = console->minimumSize();
+        console->setMinimumSize (0, 0);
+
+        /* memorize the maximized state */
+        was_max = isMaximized();
+        /* set the correct flags to disable unnecessary frame controls */
+        int flags = WType_TopLevel | WStyle_Customize | WStyle_NoBorder;
+        QRect scrGeo = QApplication::desktop()->availableGeometry (this);
+        /* hide early to avoid extra flicker */
+        hide();
+        /* hide all but the central widget containing the console view */
+        QObjectList *list = queryList (NULL, NULL, false, false);
+        for (QObject *obj = list->first(); obj != NULL; obj = list->next())
+        {
+            if (obj->isWidgetType() && obj != centralWidget())
+            {
+                QWidget *w = (QWidget *) obj;
+                if (!w->isHidden())
+                {
+                    w->hide();
+                    hidden_children.append (w);
+                }
+            }
+        }
+        delete list;
+        /* reparent to apply new flags and place to the top left corner of the
+         * current desktop */
+        reparent (parentWidget(), flags, QPoint (scrGeo.x(), scrGeo.y()), false);
+        /* adjust colors and appearance */
+        console_style = console->frameStyle();
+        console->setFrameStyle (QFrame::NoFrame);
+        console->setMaximumSize (console->sizeHint());
+        console->setVScrollBarMode (QScrollView::AlwaysOff);
+        console->setHScrollBarMode (QScrollView::AlwaysOff);
+        /* go full available screen */
+        resize (scrGeo.size());
+        setMinimumSize (size());
+        setMaximumSize (size());
+    }
+    else
+    {
+        /* Restore the previous scroll-view minimum size before the exiting
+         * fullscreen. Required for correct scroll-view and guest display
+         * update in SDL mode. */
+        console->setMinimumSize (prev_min_size);
+
+        /* hide early to avoid extra flicker */
+        hide();
+        /* reparent to restore normal flags */
+        reparent (parentWidget(), normal_wflags, QPoint (0, 0), false);
+        /* adjust colors and appearance */
+        console->setFrameStyle (console_style);
+        console->setMaximumSize (console->sizeHint());
+        console->setVScrollBarMode (QScrollView::Auto);
+        console->setHScrollBarMode (QScrollView::Auto);
+        /* show everything hidden when going fullscreen */
+        for (QObject *obj = hidden_children.first(); obj != NULL;
+             obj = hidden_children.next())
+            ((QWidget *) obj)->show();
+        hidden_children.clear();
+        /* restore normal values */
+        setMinimumSize (QSize(0, 0));
+        setMaximumSize (QSize (QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
+        move (normal_pos);
+        resize (normal_size);
+        /* let our toplevel widget calculate its sizeHint properly */
+        QApplication::sendPostedEvents (0, QEvent::LayoutHint);
+        /* restore the maximized state */
+        if (was_max)
+            setWindowState (windowState() | WindowMaximized);
+        else
+            QTimer::singleShot (0, console, SLOT (exitFullScreen()));
     }
 
@@ -2613,7 +2746,12 @@
 
 
-void VBoxConsoleWnd::updateAdditionsState (const QString &aVersion, bool aActive)
+void VBoxConsoleWnd::updateAdditionsState (const QString &aVersion,
+                                           bool aActive,
+                                           bool aSeamless)
 {
     vmAutoresizeGuestAction->setEnabled (aActive);
+    vmSeamlessAction->setEnabled (aSeamless);
+    if (aSeamless && vmSeamlessAction->isOn())
+        vmSeamless (true);
 
     /* Check the Guest Additions version and warn the user about possible
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 3671)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 3674)
@@ -267,13 +267,13 @@
         return E_POINTER;
 
-	/// @todo
-
-	NOREF(aCount);
-	NOREF(aCountCopied);
-
-    return S_OK;
-}
-
-STDMETHODIMP VBoxFrameBuffer::SetVisibleRegion(BYTE *aRectangles, ULONG aCount)
+    /// @todo what and why?
+
+    NOREF(aCount);
+    NOREF(aCountCopied);
+
+    return S_OK;
+}
+
+STDMETHODIMP VBoxFrameBuffer::SetVisibleRegion (BYTE *aRectangles, ULONG aCount)
 {
     PRTRECT rects = (PRTRECT)aRectangles;
@@ -282,7 +282,19 @@
         return E_POINTER;
 
-	/// @todo
-
-	NOREF(aCount);
+    if (!mView->isInSeamlessMode())
+        return S_OK;
+
+    QRegion reg;
+    for (ULONG ind = 0; ind < aCount; ++ ind)
+    {
+        QRect rect;
+        rect.setLeft (rects->xLeft);
+        rect.setBottom (rects->yBottom);
+        rect.setRight (rects->xRight);
+        rect.setTop (rects->yTop);
+        reg += rect;
+        ++ rects;
+    }
+    QApplication::postEvent (mView, new VBoxSetRegionEvent (reg));
 
     return S_OK;
