Index: trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk	(revision 6645)
@@ -251,5 +251,6 @@
 	src/darwin/DarwinCursor.cpp \
 	src/darwin/VBoxAquaStyle.cpp \
-	src/darwin/VBoxUtils-darwin.cpp
+	src/darwin/VBoxUtils-darwin.cpp \
+	src/VBoxFBQuartz2D.cpp
 
 ifneq ($(BUILD_TARGET),win)
@@ -269,5 +270,5 @@
 VirtualBox_DEFS           = VBOX_GUI_SEPARATE_VM_PROCESS
 VirtualBox_DEFS.debug     = VBOX_GUI_DEBUG VBOX_CHECK_STATE # QT_FATAL_ASSERT
-VirtualBox_DEFS.darwin    = VBOX_GUI_USE_QIMAGE VBOX_WITHOUT_QHTTP
+VirtualBox_DEFS.darwin    = VBOX_GUI_USE_QUARTZ2D VBOX_GUI_USE_QIMAGE VBOX_WITHOUT_QHTTP
 VirtualBox_DEFS.freebsd   = VBOX_GUI_USE_QIMAGE VBOX_GUI_USE_SDL
 VirtualBox_DEFS.linux     = VBOX_GUI_USE_SDL
Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxDefs.h	(revision 6645)
@@ -115,5 +115,5 @@
     enum RenderMode
     {
-        InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode
+        InvalidRenderMode, TimerMode, QImageMode, SDLMode, DDRAWMode, Quartz2DMode
     };
 
Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxFrameBuffer.h	(revision 6645)
@@ -459,3 +459,54 @@
 #endif
 
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined(Q_WS_MAC) && defined (VBOX_GUI_USE_QUARTZ2D)
+
+#include <Carbon/Carbon.h>
+class VBoxQuartz2DFrameBuffer : public VBoxFrameBuffer
+{
+public:
+
+    VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView);
+    virtual ~VBoxQuartz2DFrameBuffer ();
+
+    STDMETHOD (NotifyUpdate) (ULONG aX, ULONG aY,
+                              ULONG aW, ULONG aH,
+                              BOOL *aFinished);
+    STDMETHOD (SetVisibleRegion) (BYTE *aRectangles, ULONG aCount);
+
+    uchar *address () { return mDataAddress; }
+    ulong bitsPerPixel () { return CGImageGetBitsPerPixel (mImage); }
+    ulong bytesPerLine () { return CGImageGetBytesPerRow (mImage); }
+    ulong pixelFormat () { return mPixelFormat; };
+    bool usesGuestVRAM () { return mBitmapData == NULL; }
+
+    const CGImageRef imageRef () const { return mImage; }
+
+    void paintEvent (QPaintEvent *pe);
+    void resizeEvent (VBoxResizeEvent *re);
+
+private:
+    inline CGRect QRectToCGRect (const QRect &aRect) const
+    {
+        return CGRectMake (aRect.x (), aRect.y (), aRect.width (), aRect.height ());
+    } 
+    inline QRect mapYOrigin (const QRect &aRect, int aHeight) const
+    {
+        /* The cgcontext has a fliped y-coord relative to the 
+         * qt coord system. So we need some mapping here */
+        return QRect (aRect.x (), aHeight - (aRect.y () + aRect.height ()), aRect.width (), aRect.height ());
+    }
+    void clean ();
+
+    uchar *mDataAddress; 
+    void *mBitmapData;
+    ulong mPixelFormat;
+    CGImageRef mImage;
+    CGRect *mRegionRects;
+    ULONG mRegionCount;
+};
+
+#endif
+
 #endif // __VBoxFrameBuffer_h__
Index: trunk/src/VBox/Frontends/VirtualBox/include/VBoxUtils.h
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/include/VBoxUtils.h	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/include/VBoxUtils.h	(revision 6645)
@@ -255,4 +255,5 @@
 CGImageRef DarwinQPixmapFromMimeSourceToCGImage (const char *aSource);
 CGImageRef DarwinCreateDockBadge (const char *aSource);
+CGImageRef DarwinCreateDockPreview (CGImageRef aVMImage, CGImageRef aOverlayImage);
 CGImageRef DarwinCreateDockPreview (VBoxFrameBuffer *aFrameBuffer, CGImageRef aOverlayImage);
 OSStatus DarwinRegionHandler (EventHandlerCallRef aInHandlerCallRef, EventRef aInEvent, void *aInUserData);
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp	(revision 6645)
@@ -706,4 +706,9 @@
         case VBoxDefs::DDRAWMode:
             mFrameBuf = new VBoxDDRAWFrameBuffer (this);
+            break;
+#endif
+#if defined (VBOX_GUI_USE_QUARTZ2D)
+        case VBoxDefs::Quartz2DMode:
+            mFrameBuf = new VBoxQuartz2DFrameBuffer (this);
             break;
 #endif
@@ -2807,6 +2812,17 @@
 #ifdef Q_WS_MAC
             /* Update the dock icon if we are in the running state */
-            if (isRunning())
-                SetApplicationDockTileImage (::DarwinCreateDockPreview(mFrameBuf, mMainWnd->dockImageState ()));
+            if (isRunning ())
+            {
+# if defined (VBOX_GUI_USE_QUARTZ2D)
+                if (mode == VBoxDefs::Quartz2DMode)
+                {
+                    /* If the render mode is Quartz2D we could use the CGImageRef of the framebuffer 
+                     * for the dock icon creation. This saves some conversation time. */
+                    CGImageRef ir = static_cast<VBoxQuartz2DFrameBuffer*>(mFrameBuf)->imageRef ();
+                    SetApplicationDockTileImage (::DarwinCreateDockPreview (ir, mMainWnd->dockImageState ()));
+                }else
+# endif
+                    SetApplicationDockTileImage (::DarwinCreateDockPreview (mFrameBuf, mMainWnd->dockImageState ()));
+            }
 #endif
             return;
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleWnd.cpp	(revision 6645)
@@ -2102,4 +2102,9 @@
             status = SetWindowAlpha(WindowRef, 0.999);
             Assert (status == noErr);
+            /* For now disable the shadow of the window. This feature cause errors
+             * if a window in vbox looses focus, is reselected and than moved. 
+             * todo: Search for an option to enable this again. A shadow on every
+             * window has a big coolness factor. */
+            ChangeWindowAttributes (WindowRef, kWindowNoShadowAttribute, 0);
         }
 #else
@@ -2666,20 +2671,33 @@
     mPrevRegion = region;
 #elif defined(Q_WS_MAC)
-    /* This is necessary to avoid the flicker by an mask update. 
-     * See http://lists.apple.com/archives/Carbon-development/2001/Apr/msg01651.html
-     * for the hint.
-     * There *must* be a better solution. */
-    if (!region.isEmpty ())
-        region |= QRect (0, 0, 1, 1);
-    /* Save the current region for later processing in the darwin event handler. */
-    mCurrRegion = region;
-    /* We repaint the screen before the ReshapeCustomWindow command. Unfortunately
-     * this command flushes a copy of the backbuffer to the screen after the new
-     * mask is set. This leads into a missplaced drawing of the content. Currently
-     * no alternative to this and also this is not 100% perfect. */
-    repaint ();
-    qApp->processEvents ();
-    /* Now force the reshaping of the window. This is definitly necessary. */
-    ReshapeCustomWindow (reinterpret_cast<WindowPtr>(winId()));
+# if defined(VBOX_GUI_USE_QUARTZ2D)
+    if (vboxGlobal().vmRenderMode() == VBoxDefs::Quartz2DMode)
+    {
+        /* If we are using the Quartz2D backend we have to trigger 
+         * an repaint only. All the magic clipping stuff is done 
+         * in the paint engine. */
+        repaint ();
+//        qApp->processEvents ();
+    }
+    else
+# endif
+    {
+        /* This is necessary to avoid the flicker by an mask update. 
+         * See http://lists.apple.com/archives/Carbon-development/2001/Apr/msg01651.html
+         * for the hint.
+         * There *must* be a better solution. */
+        if (!region.isEmpty ())
+            region |= QRect (0, 0, 1, 1);
+        /* Save the current region for later processing in the darwin event handler. */
+        mCurrRegion = region;
+        /* We repaint the screen before the ReshapeCustomWindow command. Unfortunately
+         * this command flushes a copy of the backbuffer to the screen after the new
+         * mask is set. This leads into a missplaced drawing of the content. Currently
+         * no alternative to this and also this is not 100% perfect. */
+        repaint ();
+        qApp->processEvents ();
+        /* Now force the reshaping of the window. This is definitly necessary. */
+        ReshapeCustomWindow (reinterpret_cast<WindowPtr>(winId()));
+    }
 #else
     QMainWindow::setMask (region);
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp	(revision 6645)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxFBQuartz2D.cpp	(revision 6645)
@@ -0,0 +1,330 @@
+/** @file
+ *
+ * VBox frontends: Qt GUI ("VirtualBox"):
+ * Quartz2D framebuffer implementation
+ */
+
+/*
+ * Copyright (C) 2006-2007 innotek GmbH
+ *
+ * This file is part of VirtualBox Open Source Edition (OSE), as
+ * available from http://www.virtualbox.org. This file is free software;
+ * you can redistribute it and/or modify it under the terms of the GNU
+ * General Public License (GPL) as published by the Free Software
+ * Foundation, in version 2 as it comes in the "COPYING" file of the
+ * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
+ * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
+ */
+
+#if defined (VBOX_GUI_USE_QUARTZ2D)
+
+/* VBox includes */
+#include "VBoxFrameBuffer.h"
+#include "VBoxConsoleView.h"
+/* Needed for checking against seamless mode */
+#include "VBoxConsoleWnd.h"
+
+/* Qt includes */
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qstatusbar.h>
+
+/** @class VBoxQuartz2DFrameBuffer
+ *
+ *  The VBoxQuartz2dFrameBuffer class is a class that implements the IFrameBuffer
+ *  interface and uses Apples Quartz2D to store and render VM display data.
+ */
+
+VBoxQuartz2DFrameBuffer::VBoxQuartz2DFrameBuffer (VBoxConsoleView *aView) :
+    VBoxFrameBuffer(aView),
+    mDataAddress(NULL),
+    mBitmapData(NULL),
+    mPixelFormat(FramebufferPixelFormat_FOURCC_RGB),
+    mImage(NULL),
+    mRegionRects(NULL),
+    mRegionCount(0)
+{
+    Log (("Quartz2D: Creating\n"));
+    resizeEvent (new VBoxResizeEvent (FramebufferPixelFormat_PixelFormatOpaque,
+                                      NULL, 0, 0, 640, 480));
+}
+
+VBoxQuartz2DFrameBuffer::~VBoxQuartz2DFrameBuffer ()
+{
+    Log (("Quartz2D: Deleting\n"));
+    clean ();
+}
+
+/** @note This method is called on EMT from under this object's lock */
+STDMETHODIMP VBoxQuartz2DFrameBuffer::NotifyUpdate (ULONG aX, ULONG aY,
+                                                 ULONG aW, ULONG aH,
+                                                 BOOL *aFinished)
+{
+/*    Log (("Quartz2D: NotifyUpdate %d,%d %dx%d\n", aX, aY, aW, aH));*/
+
+    QApplication::postEvent (mView,
+                             new VBoxRepaintEvent (aX, aY, aW, aH));
+    /* the update has been finished, return TRUE */
+    *aFinished = TRUE;
+
+    return S_OK;
+}
+
+STDMETHODIMP VBoxQuartz2DFrameBuffer::SetVisibleRegion (BYTE *aRectangles, ULONG aCount)
+{
+    PRTRECT rects = (PRTRECT)aRectangles;
+
+    if (!rects)
+        return E_POINTER;
+
+    RTMemFree (mRegionRects);
+    mRegionCount = 0;
+    mRegionRects = static_cast<CGRect*>(RTMemAlloc (sizeof (CGRect) * aCount));
+
+    QRegion reg;
+//    printf ("Region rects follow...\n");
+    QRect vmScreenRect (0, 0, width (), height ());
+    for (ULONG ind = 0; ind < aCount; ++ ind)
+    {
+        QRect rect;
+        rect.setLeft (rects->xLeft);
+        rect.setTop (rects->yTop);
+        /* QRect are inclusive */
+        rect.setRight (rects->xRight - 1);
+        rect.setBottom (rects->yBottom - 1);
+
+        /* The rect should intersect with the vm screen. */
+        rect = vmScreenRect.intersect (rect);
+        ++ rects;
+        /* Make sure only valid rects are distributed */
+        /* todo: Test if the other framebuffer implementation have the same
+         * problem with invalid rects (In Linux/Windows) */
+        if (rect.isValid () && 
+           rect.width () > 0 && rect.height () > 0)
+            reg += rect;
+        else
+            continue;
+
+        mRegionRects[mRegionCount].origin.x = rect.x ();
+        mRegionRects[mRegionCount].origin.y = rect.y ();
+        mRegionRects[mRegionCount].size.width = rect.width ();
+        mRegionRects[mRegionCount].size.height = rect.height ();
+//        printf ("Region rect[%d - %d]: %d %d %d %d\n", mRegionCount, aCount, rect.x (), rect.y (), rect.height (), rect.width ());
+        ++mRegionCount;
+    }
+//    printf ("..................................\n");
+    QApplication::postEvent (mView, new VBoxSetRegionEvent (reg));
+
+    return S_OK;
+}
+
+/* Saved for later optimization */
+//#define BEST_BYTE_ALIGNMENT 16
+//#define COMPUTE_BEST_BYTES_PER_ROW (bpr)    ( ( (bpr) + (BEST_BYTE_ALIGNMENT-1) ) & ~(BEST_BYTE_ALIGNMENT-1) )
+//CGImageRef createImageFromImageInRect(CGImageRef* img, const QRect& rect)
+//{
+//    const int sx = qRound(sr.x()), sy = qRound(sr.y()), sw = qRound(sr.width()), sh = qRound(sr.height());
+//    const QMacPixmapData *pmData = static_cast<const QMacPixmapData*>(pm.data);
+//    quint32 *pantherData = pmData->pixels + (sy * pm.width() + sx);
+//
+//    QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(0, pantherData, sw*sh*sizeof(uint), 0);
+//
+//
+//    CGDataProviderRef dp = CGDataProviderCreateWithData(NULL, mBitmapData, bitmapByteCount, NULL);
+//    mImage = CGImageCreate(mWdt, mHgt, 8, 32, bitmapBytesPerRow, cs,
+//                           kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, 0,
+//                           kCGRenderingIntentDefault);
+//
+//    CGDataProviderRef dp = CGDataProviderCreateWithData(aFrameBuffer, aFrameBuffer->address(), aFrameBuffer->bitsPerPixel() / 8 * aFrameBuffer->width() * aFrameBuffer->height() , NULL);
+//    image = CGImageCreate(sw, sh, 8, 32, pm.width() * sizeof(uint),
+//                          macGenericColorSpace(),
+//                          kCGImageAlphaPremultipliedFirst, provider, 0, 0,
+//                          kCGRenderingIntentDefault);
+//}
+
+void VBoxQuartz2DFrameBuffer::paintEvent (QPaintEvent *pe)
+{
+    /* Some general hints at the beginning:
+     * The console is not a real sub window of the main window. There is 
+     * one real mac window only. This means all the drawing on the context has
+     * to pay attention to the statusbar, the scrollbars, the shifting spacers 
+     * and any frame borders.
+     * Secondly the origin of the coordinate system is differently defined in 
+     * Qt and Quartz2D. In Qt the point (0, 0) means top/left where this is 
+     * bottom/left in Quartz2D. Use mapYOrigin to map from Qt to Quartz2D. 
+     *
+     * For debugging /Developer/Applications/Performance Tools/Quartz Debug.app
+     * is a nice tool to see which parts of the screen are updated. */
+
+    Assert (mImage);
+
+    QWidget *pMain = qApp->mainWidget ();
+    Assert (pMain);
+    /* Calculate the view rect to draw in */
+    QPoint p = mView->viewport()->mapTo (pMain, QPoint (0, 0));
+    QRect Q2DViewRect = mapYOrigin (QRect (p.x (), p.y (), mView->width (), mView->height ()), pMain->height ());
+    /* We have to pay special attention to the scrollbars */
+    if (mView->horizontalScrollBar ()->isVisible ())
+        Q2DViewRect.setY (Q2DViewRect.y () + (mView->horizontalScrollBar ()->frameSize ().height () + 2));
+    if (mView->verticalScrollBar ()->isVisible ())
+        Q2DViewRect.setWidth (Q2DViewRect.width () - (mView->verticalScrollBar ()->frameSize ().width () + 2));
+
+    /* Create the context to draw on */
+    WindowPtr window = static_cast<WindowPtr>(mView->viewport ()->handle ());
+    SetPortWindowPort (window);
+    CGContextRef ctx;
+    QDBeginCGContext (GetWindowPort (window), &ctx);
+    /* We handle the seamless mode as a special case. */
+    if (static_cast<VBoxConsoleWnd*>(pMain)->isTrueSeamless ())
+    {
+        /* Here we paint the windows without any wallpaper. 
+         * So the background would be set transparently. */
+
+        /* Create a subimage of the current view.
+         * Currently this subimage is the whole screen. */
+        CGImageRef subImage = CGImageCreateWithImageInRect (mImage, CGRectMake (mView->contentsX (), mView->contentsY (), mView->visibleWidth (), mView->visibleHeight ()));
+        Assert (subImage);
+        /* Clear the background (Make the rect fully transparent) */
+        Rect winRect;
+        GetPortBounds (GetWindowPort (window), &winRect);
+        CGContextClearRect (ctx, CGRectMake (winRect.left, winRect.top, winRect.right - winRect.left, winRect.bottom - winRect.top));
+        if (mRegionRects && mRegionCount > 0)
+        {
+            /* Save state for display fliping */
+            CGContextSaveGState (ctx);
+            /* Flip the y-coord */
+            CGContextScaleCTM (ctx, 1.0, -1.0);
+            CGContextTranslateCTM (ctx, Q2DViewRect.x (), -Q2DViewRect.height () - Q2DViewRect.y ());
+            /* Add the clipping rects all at once. They are defined in
+             * SetVisibleRegion. */
+            CGContextBeginPath (ctx);
+            CGContextAddRects (ctx, mRegionRects, mRegionCount);
+            /* Restore the context state. Note that the
+             * current path isn't destroyed. */
+            CGContextRestoreGState (ctx);
+            /* Now convert the path to a clipping path. */
+            CGContextClip (ctx);
+        }
+        /* In any case clip the drawing to the view window */
+        CGContextClipToRect (ctx, QRectToCGRect (Q2DViewRect));
+        /* At this point draw the real vm image */
+        CGContextDrawImage (ctx, QRectToCGRect (Q2DViewRect), subImage);
+    }else
+    {
+        /* Here we paint if we didn't care about any masks */
+
+        /* Create a subimage of the current view in the size
+         * of the bounding box of the current paint event */
+        QRect ir = pe->rect ();
+        QRect is = QRect (ir.x () + mView->contentsX (), ir.y () + mView->contentsY (), ir.width (), ir.height ());
+        CGImageRef subImage = CGImageCreateWithImageInRect (mImage, QRectToCGRect (is));
+        Assert (subImage);
+
+        /* Ok, for more performance we set a clipping path of the
+         * regions given by this paint event. */
+        QMemArray<QRect> a = pe->region ().rects ();
+        if (a.size () > 0)
+        {
+            /* Save state for display fliping */
+            CGContextSaveGState (ctx);
+            /* Flip the y-coord */
+            CGContextScaleCTM (ctx, 1.0, -1.0);
+            CGContextTranslateCTM (ctx, Q2DViewRect.x (), -Q2DViewRect.height () - Q2DViewRect.y ());
+            CGContextBeginPath (ctx);
+            /* Add all region rects to the current context as path components */
+            for (unsigned int i = 0; i < a.size (); ++i)
+                CGContextAddRect (ctx, QRectToCGRect (a[i]));
+            CGContextRestoreGState (ctx);
+            /* Now convert the path to a clipping path. */
+            CGContextClip (ctx);
+        }
+
+        /* In any case clip the drawing to the view window */
+        CGContextClipToRect (ctx, QRectToCGRect (Q2DViewRect));
+        /* Draw the sub image to the right position */
+        QPoint p = mView->viewport ()->mapTo (pMain, QPoint (ir.x (), ir.y ()));
+        QRect cr = mapYOrigin (QRect (p.x (), p.y (), ir.width (), ir.height ()), pMain->height ());
+        CGContextDrawImage (ctx, QRectToCGRect (cr), subImage);
+    }
+    QDEndCGContext (GetWindowPort (window), &ctx);
+}
+/* Save for later shadow stuff ... */
+//        CGContextSetShadow (myContext, myShadowOffset, 10);
+//        CGContextBeginTransparencyLayer (myContext, NULL);
+//        CGContextSetShadow (myContext, CGSizeMake (10, 5), 1);
+//        CGContextClipToRect (myContext, rect);
+//        QRect ir = pe->rect ();
+//        CGContextClipToRect (myContext, CGRectMake (ir.y (), ir.x (), ir.width (), ir.height ()));
+//        CGContextEndTransparencyLayer (myContext);
+
+void VBoxQuartz2DFrameBuffer::resizeEvent (VBoxResizeEvent *re)
+{
+#if 0
+    printf ("fmt=%lu, vram=%X, bpp=%lu, bpl=%lu, width=%lu, height=%lu\n",
+           re->pixelFormat (), (unsigned int)re->VRAM (),
+           re->bitsPerPixel (), re->bytesPerLine (),
+           re->width (), re->height ());
+#endif
+
+    /* Clean out old stuff */
+    clean ();
+
+    mWdt = re->width ();
+    mHgt = re->height ();
+
+    /* We need a color space in any case */
+    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
+    /* Check if we support the pixel format/colordepth and can use the guest VRAM directly. 
+     * Mac OS X supports 16 bit also but not in the 565 mode. So we could use
+     * 32 bit only. */
+    if (re->pixelFormat () == FramebufferPixelFormat_FOURCC_RGB &&
+        re->bitsPerPixel () == 32)
+    {
+//        printf ("VRAM\n");
+        CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
+        /* Create the image copy of the framebuffer */
+        CGDataProviderRef dp = CGDataProviderCreateWithData (NULL, re->VRAM (), re->bitsPerPixel () / 8 * mWdt * mHgt, NULL);
+        mImage = CGImageCreate (mWdt, mHgt, 8, re->bitsPerPixel (), re->bytesPerLine (), cs,
+                                kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, dp, 0, false, 
+                                kCGRenderingIntentDefault);
+        mDataAddress = re->VRAM ();
+        CGDataProviderRelease (dp);
+    }
+    else
+    {
+//        printf ("No VRAM\n");
+        /* Create the memory we need for our image copy */
+        int bitmapBytesPerRow = (mWdt * 4);
+        int bitmapByteCount = (bitmapBytesPerRow * mHgt);
+        mBitmapData = RTMemAlloc (bitmapByteCount);
+        CGDataProviderRef dp = CGDataProviderCreateWithData (NULL, mBitmapData, bitmapByteCount, NULL);
+        mImage = CGImageCreate (mWdt, mHgt, 8, 32, bitmapBytesPerRow, cs,
+                               kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Little, dp, 0, false, 
+                               kCGRenderingIntentDefault);
+        mDataAddress = static_cast<uchar*>(mBitmapData);
+        CGDataProviderRelease (dp);
+    }
+    CGColorSpaceRelease (cs);
+}
+
+void VBoxQuartz2DFrameBuffer::clean ()
+{
+    if (mImage)
+    {
+        CGImageRelease (mImage);
+        mImage = NULL;
+    }
+    if (mBitmapData)
+    {
+        RTMemFree (mBitmapData);
+        mBitmapData = NULL;
+    }
+    if (mRegionRects)
+    {
+        RTMemFree (mRegionRects);
+        mRegionRects = NULL;
+        mRegionCount = 0;
+    }
+}
+
+#endif /* defined (VBOX_GUI_USE_QUARTZ2D) */
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxFrameBuffer.cpp	(revision 6645)
@@ -632,2 +632,12 @@
 
 #endif
+
+//
+// VBoxQuartz2DFrameBuffer class
+/////////////////////////////////////////////////////////////////////////////
+
+#if defined (VBOX_GUI_USE_QUARTZ2D)
+
+/* The class is defined in VBoxQuartz2D.cpp */
+
+#endif
Index: trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp	(revision 6645)
@@ -678,5 +678,7 @@
     VBoxDefs::RenderMode mode = VBoxDefs::InvalidRenderMode;
 
-#if (defined (Q_WS_WIN32) || defined (Q_WS_PM)) && defined (VBOX_GUI_USE_QIMAGE)
+#if defined (Q_WS_MAC) && defined(VBOX_GUI_USE_QUARTZ2D)
+    mode = VBoxDefs::Quartz2DMode;
+#elif (defined (Q_WS_WIN32) || defined (Q_WS_PM)) && defined (VBOX_GUI_USE_QIMAGE)
     mode = VBoxDefs::QImageMode;
 #elif defined (Q_WS_X11) && defined (VBOX_GUI_USE_SDL)
@@ -706,4 +708,8 @@
         else if (::strcmp (aModeStr, "ddraw") == 0)
             mode = VBoxDefs::DDRAWMode;
+#endif
+#if defined (VBOX_GUI_USE_QUARTZ2D)
+        else if (::strcmp (aModeStr, "quartz2d") == 0)
+            mode = VBoxDefs::Quartz2DMode;
 #endif
     }
Index: trunk/src/VBox/Frontends/VirtualBox/src/darwin/VBoxUtils-darwin.cpp
===================================================================
--- trunk/src/VBox/Frontends/VirtualBox/src/darwin/VBoxUtils-darwin.cpp	(revision 6644)
+++ trunk/src/VBox/Frontends/VirtualBox/src/darwin/VBoxUtils-darwin.cpp	(revision 6645)
@@ -33,5 +33,5 @@
  * @param   info        Pointer to the QImage.
  */
-static void darwinDataProviderReleaseQImage(void *info, const void *, size_t)
+static void darwinDataProviderReleaseQImage (void *info, const void *, size_t)
 {
     QImage *qimg = (QImage *)info;
@@ -45,18 +45,18 @@
  * @param   aPixmap     Pointer to the QPixmap instance to convert.
  */
-CGImageRef DarwinQImageToCGImage(const QImage *aImage)
-{
-    QImage *imageCopy = new QImage(*aImage);
+CGImageRef DarwinQImageToCGImage (const QImage *aImage)
+{
+    QImage *imageCopy = new QImage (*aImage);
     /** @todo this code assumes 32-bit image input, the lazy bird convert image to 32-bit method is anything but optimal... */
-    if (imageCopy->depth() != 32)
+    if (imageCopy->depth () != 32)
         *imageCopy = imageCopy->convertDepth (32);
-    Assert (!imageCopy->isNull());
-
-    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
-    CGDataProviderRef dp = CGDataProviderCreateWithData (imageCopy, aImage->bits(), aImage->numBytes(), darwinDataProviderReleaseQImage);
-
-    CGBitmapInfo bmpInfo = imageCopy->hasAlphaBuffer() ? kCGImageAlphaFirst : kCGImageAlphaNoneSkipFirst;
+    Assert (!imageCopy->isNull ());
+
+    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
+    CGDataProviderRef dp = CGDataProviderCreateWithData (imageCopy, aImage->bits (), aImage->numBytes (), darwinDataProviderReleaseQImage);
+
+    CGBitmapInfo bmpInfo = imageCopy->hasAlphaBuffer () ? kCGImageAlphaFirst : kCGImageAlphaNoneSkipFirst;
     bmpInfo |= kCGBitmapByteOrder32Host;
-    CGImageRef ir = CGImageCreate (imageCopy->width(), imageCopy->height(), 8, 32, imageCopy->bytesPerLine(), cs,
+    CGImageRef ir = CGImageCreate (imageCopy->width (), imageCopy->height (), 8, 32, imageCopy->bytesPerLine (), cs,
                                    bmpInfo, dp, 0 /*decode */, 0 /* shouldInterpolate */,
                                    kCGRenderingIntentDefault);
@@ -74,9 +74,9 @@
  * @param   aPixmap     Pointer to the QPixmap instance to convert.
  */
-CGImageRef DarwinQPixmapToCGImage(const QPixmap *aPixmap)
-{
-    QImage qimg = aPixmap->convertToImage();
-    Assert (!qimg.isNull());
-    return DarwinQImageToCGImage(&qimg);
+CGImageRef DarwinQPixmapToCGImage (const QPixmap *aPixmap)
+{
+    QImage qimg = aPixmap->convertToImage ();
+    Assert (!qimg.isNull ());
+    return DarwinQImageToCGImage (&qimg);
 }
 
@@ -90,5 +90,5 @@
 {
     QPixmap qpm = QPixmap::fromMimeSource (aSource);
-    Assert (!qpm.isNull());
+    Assert (!qpm.isNull ());
     return DarwinQPixmapToCGImage (&qpm);
 }
@@ -108,19 +108,19 @@
        just created one that I can load. The Qt gurus can fix this if they like :-) */
     QPixmap back (QPixmap::fromMimeSource ("dock_128x128_transparent.png"));
-    Assert (!back.isNull());
-    Assert (back.width() == 128 && back.height() == 128);
+    Assert (!back.isNull ());
+    Assert (back.width () == 128 && back.height () == 128);
 
     /* load the badge */
     QPixmap badge = QPixmap::fromMimeSource (aSource);
-    Assert (!badge.isNull());
+    Assert (!badge.isNull ());
 
     /* resize it and copy it onto the background. */
-    if (badge.width() < 32)
-        badge = badge.convertToImage().smoothScale (32, 32);
-    copyBlt (&back, back.width() - badge.width(), back.height() - badge.height(),
+    if (badge.width () < 32)
+        badge = badge.convertToImage ().smoothScale (32, 32);
+    copyBlt (&back, back.width () - badge.width (), back.height () - badge.height (),
              &badge, 0, 0,
-             badge.width(), badge.height());
-    Assert (!back.isNull());
-    Assert (back.width() == 128 && back.height() == 128);
+             badge.width (), badge.height ());
+    Assert (!back.isNull ());
+    Assert (back.width () == 128 && back.height () == 128);
 
     /* Convert it to a CGImage. */
@@ -128,4 +128,5 @@
 }
 
+
 /**
  * Creates a dock preview image.
@@ -134,19 +135,13 @@
  *
  * @returns CGImageRef for the new image. (Remember to release it when finished with it.)
- * @param   aFrameBuffer    The guest frame buffer.
- */
-CGImageRef DarwinCreateDockPreview (VBoxFrameBuffer *aFrameBuffer, CGImageRef aOverlayImage)
-{
-    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
-
-    /* Create the image copy of the framebuffer */
-    CGDataProviderRef dp = CGDataProviderCreateWithData (aFrameBuffer, aFrameBuffer->address(), aFrameBuffer->bitsPerPixel() / 8 * aFrameBuffer->width() * aFrameBuffer->height() , NULL);
-    CGImageRef ir = CGImageCreate (aFrameBuffer->width(), aFrameBuffer->height(), 8, 32, aFrameBuffer->bytesPerLine(), cs,
-                                   kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
-                                   kCGRenderingIntentDefault);
-
+ * @param   aVMImage   the vm screen as a CGImageRef
+ * @param   aOverlayImage   an optional overlay image to add at the bottom right of the icon
+ */
+CGImageRef DarwinCreateDockPreview (CGImageRef aVMImage, CGImageRef aOverlayImage)
+{
+    Assert (aVMImage);
+
+    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
     Assert (cs);
-    Assert (dp);
-    Assert (ir);
 
     /* Calc the size of the dock icon image and fit it into 128x128 */
@@ -155,5 +150,5 @@
     int scaledWidth;
     int scaledHeight;
-    float aspect = static_cast<float>(aFrameBuffer->width()) / aFrameBuffer->height();
+    float aspect = static_cast<float>(CGImageGetWidth (aVMImage)) / CGImageGetHeight (aVMImage);
     if (aspect > 1.0)
     {
@@ -179,5 +174,5 @@
         /* rounded corners */
 //        CGContextSetLineJoin (context, kCGLineJoinRound);
-//        CGContextSetShadow (context, CGSizeMake(10, 5), 1);
+//        CGContextSetShadow (context, CGSizeMake (10, 5), 1);
 //        CGContextSetAllowsAntialiasing (context, true);
         /* some little boarder */
@@ -193,5 +188,5 @@
         /* vm content */
         iconRect = CGRectInset (iconRect, 1, 1);
-        CGContextDrawImage (context, iconRect, ir);
+        CGContextDrawImage (context, iconRect, aVMImage);
         /* the overlay image */
         if (aOverlayImage)
@@ -207,8 +202,35 @@
 
     CGColorSpaceRelease (cs);
+
+    Assert (dockImage);
+    return dockImage;
+}
+
+/**
+ * Creates a dock preview image.
+ *
+ * This method is a callback that creates a 128x128 preview image of the VM window.
+ *
+ * @returns CGImageRef for the new image. (Remember to release it when finished with it.)
+ * @param   aFrameBuffer    The guest frame buffer.
+ * @param   aOverlayImage   an optional overlay image to add at the bottom right of the icon
+ */
+CGImageRef DarwinCreateDockPreview (VBoxFrameBuffer *aFrameBuffer, CGImageRef aOverlayImage)
+{
+    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB ();
+    Assert (cs);
+    /* Create the image copy of the framebuffer */
+    CGDataProviderRef dp = CGDataProviderCreateWithData (aFrameBuffer, aFrameBuffer->address (), aFrameBuffer->bitsPerPixel () / 8 * aFrameBuffer->width () * aFrameBuffer->height (), NULL);
+    Assert (dp);
+    CGImageRef ir = CGImageCreate (aFrameBuffer->width (), aFrameBuffer->height (), 8, 32, aFrameBuffer->bytesPerLine (), cs,
+                                   kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
+                                   kCGRenderingIntentDefault);
+    /* Create the preview icon */
+    CGImageRef dockImage = DarwinCreateDockPreview (ir, aOverlayImage);
+    /* Release the temp data and image */
     CGDataProviderRelease (dp);
     CGImageRelease (ir);
-
-    Assert (dockImage);
+    CGColorSpaceRelease (cs);
+
     return dockImage;
 }
@@ -216,5 +238,5 @@
 OSStatus DarwinRegionHandler (EventHandlerCallRef aInHandlerCallRef, EventRef aInEvent, void *aInUserData)
 {
-    NOREF(aInHandlerCallRef);
+    NOREF (aInHandlerCallRef);
 
     OSStatus status = eventNotHandledErr;
@@ -241,8 +263,8 @@
             {
                 GetEventParameter (aInEvent, kEventParamRgnHandle, typeQDRgnHandle, NULL, sizeof (rgn), NULL, &rgn);
-                QRegion *pRegion = static_cast <QRegion*>(aInUserData);
-                if(!pRegion->isNull () && pRegion)
+                QRegion *pRegion = static_cast <QRegion*> (aInUserData);
+                if (!pRegion->isNull () && pRegion)
                 {
-                    CopyRgn (pRegion->handle(), rgn);
+                    CopyRgn (pRegion->handle (), rgn);
                     status = noErr;
                 }
