VirtualBox

Ignore:
Timestamp:
Nov 5, 2009 11:18:52 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
54404
Message:

crOpenGL-OSX: add support for realtime dock tile preview of OpenGL content in Cocoa

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
4 added
2 edited
1 copied
2 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r24108 r24377  
    464464        src/darwin/DarwinKeyboard.cpp \
    465465        src/darwin/VBoxUtils-darwin.cpp \
    466         src/darwin/VBoxDockIconPreview.cpp \
     466        src/darwin/AbstractDockIconPreview.cpp \
    467467        src/VBoxFBQuartz2D.cpp
    468468
     
    478478        src/darwin/VBoxUtils-darwin-cocoa.mm \
    479479        src/darwin/VBoxCocoaSpecialControls.mm \
    480         src/darwin/VBoxDockIconPreview-cocoa.mm
     480        src/darwin/CocoaDockIconPreview.mm
    481481 VirtualBox_QT_MOCHDRS.darwin = \
    482482        include/VBoxCocoaSpecialControls.h
     
    484484else
    485485 VirtualBox_SOURCES.darwin += \
    486         src/darwin/VBoxUtils-darwin-carbon.cpp
     486        src/darwin/VBoxUtils-darwin-carbon.cpp \
     487        src/darwin/CarbonDockIconPreview.cpp
    487488endif
    488489
  • trunk/src/VBox/Frontends/VirtualBox/include/DockIconPreview.h

    r23589 r24377  
     1/* $Id$ */
    12/** @file
    23 *
     
    2425#define ___VBoxDockIconPreview_h___
    2526
    26 #include "VBoxUtils-darwin.h"
     27#ifdef QT_MAC_USE_COCOA
    2728
    28 RT_C_DECLS_BEGIN
    29 void darwinCreateVBoxDockIconTileView (void);
    30 void darwinDestroyVBoxDockIconTileView (void);
    31 
    32 CGContextRef darwinBeginCGContextForApplicationDockTile (void);
    33 void darwinEndCGContextForApplicationDockTile (CGContextRef aContext);
    34 
    35 void darwinOverlayApplicationDockTileImage (CGImageRef pImage);
    36 void darwinRestoreApplicationDockTileImage (void);
    37 RT_C_DECLS_END
    38 
    39 #ifndef __OBJC__
    40 class VBoxConsoleWnd;
    41 class VBoxFrameBuffer;
    42 
    43 class QPixmap;
    44 
    45 class VBoxDockIconPreview
     29#include "CocoaDockIconPreview.h"
     30class VBoxDockIconPreview: public CocoaDockIconPreview
    4631{
    4732public:
    48     VBoxDockIconPreview (VBoxConsoleWnd *aMainWnd, const QPixmap& aOverlayImage);
    49     ~VBoxDockIconPreview();
     33    VBoxDockIconPreview (VBoxConsoleWnd *aMainWnd, const QPixmap& aOverlayImage)
     34      : CocoaDockIconPreview (aMainWnd, aOverlayImage) {}
     35};
    5036
    51     void updateDockOverlay();
    52     void updateDockPreview (CGImageRef aVMImage);
    53     void updateDockPreview (VBoxFrameBuffer *aFrameBuffer);
     37#else /* QT_MAC_USE_COCOA */
    5438
    55 private:
    56     inline void initPreviewImages();
    57     inline void initOverlayData (int aBitmapByteCount);
    58     inline CGImageRef stateImage() const;
    59     void drawOverlayIcons (CGContextRef aContext);
     39#include "CarbonDockIconPreview.h"
     40class VBoxDockIconPreview: public CarbonDockIconPreview
     41{
     42public:
     43    VBoxDockIconPreview (VBoxConsoleWnd *aMainWnd, const QPixmap& aOverlayImage)
     44      : CarbonDockIconPreview (aMainWnd, aOverlayImage) {}
     45};
    6046
    61     /* Flipping is necessary cause the drawing context in Carbon is flipped by 180 degree */
    62     inline CGRect flipRect (CGRect aRect) const { return ::darwinFlipCGRect (aRect, mDockIconRect); }
    63     inline CGRect centerRect (CGRect aRect) const { return ::darwinCenterRectTo (aRect, mDockIconRect); }
    64     inline CGRect centerRectTo (CGRect aRect, const CGRect& aToRect) const { return ::darwinCenterRectTo (aRect, aToRect); }
    65 
    66     void updateDockPreviewImpl (CGContextRef aContext, CGImageRef aVMImage);
    67 
    68     /* Private member vars */
    69     VBoxConsoleWnd *mMainWnd;
    70     const CGRect mDockIconRect;
    71 
    72     CGImageRef mOverlayImage;
    73     CGImageRef mDockMonitor;
    74     CGImageRef mDockMonitorGlossy;
    75 
    76     void *mBitmapData;
    77 
    78     CGImageRef mStatePaused;
    79     CGImageRef mStateSaving;
    80     CGImageRef mStateRestoring;
    81 
    82     CGRect mUpdateRect;
    83     CGRect mMonitorRect;
    84 };
    85 #endif /* !__OBJC__ */
     47#endif /* QT_MAC_USE_COCOA */
    8648
    8749#endif /* !___VBoxDockIconPreview_h___ */
  • trunk/src/VBox/Frontends/VirtualBox/src/VBoxConsoleView.cpp

    r24301 r24377  
    8282
    8383#if defined (Q_WS_MAC)
    84 # include "VBoxDockIconPreview.h"
     84# include "DockIconPreview.h"
    8585# include "DarwinKeyboard.h"
    8686# ifdef QT_MAC_USE_COCOA
     
    12831283                    viewport()->unsetCursor();
    12841284#endif
     1285
     1286#ifdef Q_WS_MAC
     1287                mDockIconPreview->setOriginalSize (re->width(), re->height());
     1288#endif /* Q_WS_MAC */
    12851289
    12861290                /* This event appears in case of guest video was changed
  • trunk/src/VBox/Frontends/VirtualBox/src/darwin/AbstractDockIconPreview.cpp

    r24376 r24377  
    2020 */
    2121
    22 #include "VBoxDockIconPreview.h"
    23 #include "VBoxUtils.h"
     22/* VBox includes */
     23#include "AbstractDockIconPreview.h"
    2424#include "VBoxConsoleWnd.h"
    2525#include "VBoxFrameBuffer.h"
    2626
    27 #include "iprt/assert.h"
     27AbstractDockIconPreview::AbstractDockIconPreview (VBoxConsoleWnd * /* aMainWnd */, const QPixmap& /* aOverlayImage */)
     28{
     29}
    2830
    29 #include <QPixmap>
     31void AbstractDockIconPreview::updateDockPreview (VBoxFrameBuffer *aFrameBuffer)
     32{
     33    CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
     34    Assert (cs);
     35    /* Create the image copy of the framebuffer */
     36    CGDataProviderRef dp = CGDataProviderCreateWithData (aFrameBuffer, aFrameBuffer->address(), aFrameBuffer->bitsPerPixel() / 8 * aFrameBuffer->width() * aFrameBuffer->height(), NULL);
     37    Assert (dp);
     38    CGImageRef ir = CGImageCreate (aFrameBuffer->width(), aFrameBuffer->height(), 8, 32, aFrameBuffer->bytesPerLine(), cs,
     39                                   kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
     40                                   kCGRenderingIntentDefault);
     41    Assert (ir);
    3042
    31 #ifndef QT_MAC_USE_COCOA
    32 /* Import private function to capture the window content of any given window. */
    33 CG_EXTERN_C_BEGIN
    34 typedef int CGSWindowID;
    35 typedef void *CGSConnectionID;
    36 CG_EXTERN CGSWindowID GetNativeWindowFromWindowRef(WindowRef ref);
    37 CG_EXTERN CGSConnectionID CGSMainConnectionID(void);
    38 CG_EXTERN void CGContextCopyWindowCaptureContentsToRect(CGContextRef c, CGRect dstRect, CGSConnectionID connection, CGSWindowID window, int zero);
    39 CG_EXTERN_C_END
    40 #endif /* !QT_MAC_USE_COCOA */
     43    /* Update the dock preview icon */
     44    updateDockPreview (ir);
    4145
    42 VBoxDockIconPreview::VBoxDockIconPreview (VBoxConsoleWnd *aMainWnd, const QPixmap& aOverlayImage)
     46    /* Release the temp data and image */
     47    CGImageRelease (ir);
     48    CGDataProviderRelease (dp);
     49    CGColorSpaceRelease (cs);
     50}
     51
     52AbstractDockIconPreviewHelper::AbstractDockIconPreviewHelper (VBoxConsoleWnd *aMainWnd, const QPixmap& aOverlayImage)
    4353    :  mMainWnd (aMainWnd)
    4454     , mDockIconRect (CGRectMake (0, 0, 128, 128))
    4555     , mDockMonitor (NULL)
    4656     , mDockMonitorGlossy (NULL)
    47      , mBitmapData (NULL)
    4857     , mUpdateRect (CGRectMake (0, 0, 0, 0))
    4958     , mMonitorRect (CGRectMake (0, 0, 0, 0))
     
    5867    mStateRestoring = ::darwinToCGImageRef ("state_restoring_16px.png");
    5968    Assert (mStateRestoring);
    60 
    61 #ifdef QT_MAC_USE_COCOA
    62     ::darwinCreateVBoxDockIconTileView();
    63 #endif /* QT_MAC_USE_COCOA */
    6469}
    6570
    66 VBoxDockIconPreview::~VBoxDockIconPreview()
     71AbstractDockIconPreviewHelper::~AbstractDockIconPreviewHelper()
    6772{
    68 #ifdef QT_MAC_USE_COCOA
    69     ::darwinDestroyVBoxDockIconTileView();
    70 #endif /* QT_MAC_USE_COCOA */
    71 
    7273    CGImageRelease (mOverlayImage);
    7374    if (mDockMonitor)
     
    7677        CGImageRelease (mDockMonitorGlossy);
    7778
    78     if (mBitmapData)
    79         RTMemFree (mBitmapData);
    80 
    8179    CGImageRelease (mStatePaused);
    8280    CGImageRelease (mStateSaving);
     
    8482}
    8583
    86 void VBoxDockIconPreview::initPreviewImages()
     84void AbstractDockIconPreviewHelper::initPreviewImages()
    8785{
    8886    if (!mDockMonitor)
     
    108106}
    109107
    110 void VBoxDockIconPreview::initOverlayData (int aBitmapByteCount)
    111 {
    112     if (!mBitmapData)
    113         mBitmapData = RTMemAlloc (aBitmapByteCount);
    114 }
    115 
    116 CGImageRef VBoxDockIconPreview::stateImage() const
     108CGImageRef AbstractDockIconPreviewHelper::stateImage() const
    117109{
    118110    CGImageRef img;
     
    131123}
    132124
    133 void VBoxDockIconPreview::drawOverlayIcons (CGContextRef aContext)
     125void AbstractDockIconPreviewHelper::drawOverlayIcons (CGContextRef aContext)
    134126{
    135127    CGRect overlayRect = CGRectMake (0, 0, 0, 0);
     
    155147}
    156148
    157 void VBoxDockIconPreview::updateDockOverlay()
    158 {
    159     /* Remove all previously set tile images */
    160 #ifdef QT_MAC_USE_COCOA
    161     ::darwinRestoreApplicationDockTileImage();
    162 #else /* QT_MAC_USE_COCOA */
    163     ::RestoreApplicationDockTileImage();
    164 #endif /* QT_MAC_USE_COCOA */
    165 
    166     CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    167     Assert (cs);
    168 
    169     /* Four bytes per color */
    170     int bitmapBytesPerRow = mDockIconRect.size.width * 4;
    171     int bitmapByteCount = bitmapBytesPerRow * mDockIconRect.size.height;
    172 
    173     initOverlayData (bitmapByteCount);
    174     Assert (mBitmapData);
    175 
    176     CGContextRef context = CGBitmapContextCreate (mBitmapData,
    177                                                   mDockIconRect.size.width,
    178                                                   mDockIconRect.size.height,
    179                                                   8,
    180                                                   bitmapBytesPerRow,
    181                                                   cs,
    182                                                   kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
    183     /* Clear the background to be transparent */
    184     CGContextSetBlendMode (context, kCGBlendModeNormal);
    185     CGContextClearRect (context, (mDockIconRect));
    186 
    187     /* Draw the state image & the overlay image */
    188     drawOverlayIcons (context);
    189 
    190     /* Flush the content */
    191     CGContextFlush (context);
    192 
    193     /* Create a image out of the bitmap context */
    194     CGImageRef overlayImage = CGBitmapContextCreateImage (context);
    195     Assert (overlayImage);
    196 
    197     /* Update the dock overlay icon */
    198 #ifdef QT_MAC_USE_COCOA
    199     ::darwinOverlayApplicationDockTileImage (overlayImage);
    200 #else /* QT_MAC_USE_COCOA */
    201     ::OverlayApplicationDockTileImage (overlayImage);
    202 #endif /* QT_MAC_USE_COCOA */
    203 
    204     /* Release the temp image */
    205     CGImageRelease (overlayImage);
    206     CGColorSpaceRelease (cs);
    207 }
    208 
    209 void VBoxDockIconPreview::updateDockPreview (CGImageRef aVMImage)
    210 {
    211     Assert (aVMImage);
    212 
    213 #ifdef QT_MAC_USE_COCOA
    214     /* Create the context to draw on */
    215     CGContextRef context = ::darwinBeginCGContextForApplicationDockTile();
    216     updateDockPreviewImpl (context, aVMImage);
    217     /* This flush updates the dock icon */
    218     CGContextFlush (context);
    219     ::darwinEndCGContextForApplicationDockTile (context);
    220 #else /* QT_MAC_USE_COCOA */
    221     /* Create the context to draw on */
    222     CGContextRef context = BeginCGContextForApplicationDockTile ();
    223     updateDockPreviewImpl (context, aVMImage);
    224     /* This flush updates the dock icon */
    225     CGContextFlush (context);
    226     EndCGContextForApplicationDockTile (context);
    227 #endif /* QT_MAC_USE_COCOA */
    228 }
    229 
    230 void VBoxDockIconPreview::updateDockPreviewImpl (CGContextRef aContext, CGImageRef aVMImage)
    231 {
    232     Assert (aContext);
    233 
    234     /* Init all dependend images in the case it wasn't done already */
    235     initPreviewImages();
    236 
    237     CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    238     Assert (cs);
    239 
    240     /* Clear the background to be transparent */
    241     CGContextSetBlendMode (aContext, kCGBlendModeNormal);
    242     CGContextClearRect (aContext, flipRect (mDockIconRect));
    243 
    244     /* Draw the monitor as the background */
    245     CGContextDrawImage (aContext, flipRect (mMonitorRect), mDockMonitor);
    246 
    247     /* Calc the size of the dock icon image and fit it into 128x128 */
    248     int scaledWidth;
    249     int scaledHeight;
    250     float aspect = static_cast <float> (CGImageGetWidth (aVMImage)) / CGImageGetHeight (aVMImage);
    251     if (aspect > 1.0)
    252     {
    253         scaledWidth = mUpdateRect.size.width;
    254         scaledHeight = mUpdateRect.size.height / aspect;
    255     }
    256     else
    257     {
    258         scaledWidth = mUpdateRect.size.width * aspect;
    259         scaledHeight = mUpdateRect.size.height;
    260     }
    261 
    262     CGRect iconRect = centerRectTo (CGRectMake (0, 0,
    263                                                 scaledWidth, scaledHeight),
    264                                     mUpdateRect);
    265     /* Draw the VM content */
    266     CGContextDrawImage (aContext, flipRect (iconRect), aVMImage);
    267 
    268 #if 0 // ndef QT_MAC_USE_COCOA
    269     /* Process the content of any external OpenGL window. */
    270     WindowRef w = darwinToNativeWindow (mMainWnd);
    271     WindowGroupRef g = GetWindowGroup (w);
    272     WindowGroupContentOptions wgco = kWindowGroupContentsReturnWindows | kWindowGroupContentsRecurse | kWindowGroupContentsVisible;
    273     ItemCount c = CountWindowGroupContents (g, wgco);
    274     float a1 = iconRect.size.width / static_cast <float> (CGImageGetWidth (aVMImage));
    275     float a2 = iconRect.size.height / static_cast <float> (CGImageGetHeight (aVMImage));
    276     Rect tmpR;
    277     GetWindowBounds (w, kWindowContentRgn, &tmpR);
    278     HIRect mainRect = CGRectMake (tmpR.left, tmpR.top, tmpR.right-tmpR.left, tmpR.bottom-tmpR.top);
    279     /* Iterate over every window in the returned window group. */
    280     for (ItemCount i = 0; i <= c; ++i)
    281     {
    282         WindowRef wc;
    283         OSStatus status = GetIndexedWindow (g, i, wgco, &wc);
    284         /* Skip the main window */
    285         if (status == noErr &&
    286             wc != w)
    287         {
    288             WindowClass winClass;
    289             status = GetWindowClass (wc, &winClass);
    290             /* Check that the class is of type overlay window */
    291             if (status == noErr &&
    292                 winClass == kOverlayWindowClass)
    293             {
    294                 Rect tmpR1;
    295                 GetWindowBounds (wc, kWindowContentRgn, &tmpR1);
    296                 HIRect rect;
    297                 rect.size.width = (tmpR1.right-tmpR1.left) * a1;
    298                 rect.size.height = (tmpR1.bottom-tmpR1.top) * a2;
    299                 rect.origin.x = iconRect.origin.x + (tmpR1.left - mainRect.origin.x) * a1;
    300                 rect.origin.y = iconRect.origin.y + (tmpR1.top  - mainRect.origin.y) * a2;
    301                 /* This is a big, bad hack. The following functions aren't
    302                  * documented nor official supported by apple. But its the only way
    303                  * to capture the OpenGL content of a window without fiddling
    304                  * around with gPixelRead or something like that. */
    305                 CGSWindowID wid = GetNativeWindowFromWindowRef (wc);
    306                 CGContextCopyWindowCaptureContentsToRect(aContext, flipRect (rect), CGSMainConnectionID(), wid, 0);
    307             }
    308         }
    309     }
    310 #endif /* QT_MAC_USE_COCOA */
    311 
    312     /* Draw the glossy overlay */
    313     CGContextDrawImage (aContext, flipRect (mMonitorRect), mDockMonitorGlossy);
    314 
    315     /* Draw the state image & the overlay image */
    316     drawOverlayIcons (aContext);
    317 
    318     CGColorSpaceRelease (cs);
    319 }
    320 
    321 void VBoxDockIconPreview::updateDockPreview (VBoxFrameBuffer *aFrameBuffer)
    322 {
    323     CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
    324     Assert (cs);
    325     /* Create the image copy of the framebuffer */
    326     CGDataProviderRef dp = CGDataProviderCreateWithData (aFrameBuffer, aFrameBuffer->address(), aFrameBuffer->bitsPerPixel() / 8 * aFrameBuffer->width() * aFrameBuffer->height(), NULL);
    327     Assert (dp);
    328     CGImageRef ir = CGImageCreate (aFrameBuffer->width(), aFrameBuffer->height(), 8, 32, aFrameBuffer->bytesPerLine(), cs,
    329                                    kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host, dp, 0, false,
    330                                    kCGRenderingIntentDefault);
    331     Assert (ir);
    332 
    333     /* Update the dock preview icon */
    334     updateDockPreview (ir);
    335 
    336     /* Release the temp data and image */
    337     CGImageRelease (ir);
    338     CGDataProviderRelease (dp);
    339     CGColorSpaceRelease (cs);
    340 }
    341 
  • trunk/src/VBox/Frontends/VirtualBox/src/darwin/CocoaDockIconPreview.mm

    r23589 r24377  
     1/* $Id$ */
    12/** @file
    23 *
     
    2122 */
    2223
    23 #import "VBoxDockIconPreview.h"
    24 
    25 #import <AppKit/NSView.h>
    26 #import <AppKit/NSDockTile.h>
    27 #import <AppKit/NSApplication.h>
    28 #import <AppKit/NSGraphicsContext.h>
    29 #import <AppKit/NSImage.h>
    30 
    31 static NSImage *gDockIconImage = NULL;
    32 
    33 /********************************************************************************
    34  *
    35  * C-Helper: This is the external interface to the Cocoa dock tile handling.
    36  *
    37  ********************************************************************************/
    38 
    39 void darwinCreateVBoxDockIconTileView (void)
    40 {
    41     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    42 
    43     if (gDockIconImage == NULL)
    44         gDockIconImage = [[NSImage imageNamed:@"NSApplicationIcon"] copy];
    45 
    46     [pool release];
    47 }
    48 
    49 void darwinDestroyVBoxDockIconTileView (void)
    50 {
    51     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    52 
    53     if (gDockIconImage != NULL)
    54     {
    55         [gDockIconImage release];
    56         gDockIconImage = NULL;
    57     }
    58 
    59     [pool release];
    60 }
    61 
    62 CGContextRef darwinBeginCGContextForApplicationDockTile (void)
    63 {
    64     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    65 
    66     [gDockIconImage lockFocus];
    67 
     24/* VBox includes */
     25#include "CocoaDockIconPreview.h"
     26#include "VBoxCocoaHelper.h"
     27
     28/* System includes */
     29#import <Cocoa/Cocoa.h>
     30
     31@interface DockTileMonitor: NSView
     32{
     33    CocoaDockIconPreviewPrivate *p;
     34
     35    NSImageView *mScreenContent;
     36    NSImageView *mMonitorGlossy;
     37}
     38- (id)initWithFrame:(NSRect)frame parent:(CocoaDockIconPreviewPrivate*)parent;
     39- (NSImageView*)screenContent;
     40- (void)resize:(NSSize)size;
     41@end
     42
     43@interface DockTileOverlay: NSView
     44{
     45    CocoaDockIconPreviewPrivate *p;
     46}
     47- (id)initWithFrame:(NSRect)frame parent:(CocoaDockIconPreviewPrivate*)parent;
     48@end
     49
     50@interface DockTile: NSView
     51{
     52    CocoaDockIconPreviewPrivate *p;
     53
     54    DockTileMonitor *mMonitor;
     55    NSImageView     *mAppIcon;
     56
     57    DockTileOverlay *mOverlay;
     58}
     59- (id)initWithParent:(CocoaDockIconPreviewPrivate*)parent;
     60- (NSView*)screenContent;
     61- (void)cleanup;
     62- (void)restoreAppIcon;
     63- (void)updateAppIcon;
     64- (void)restoreMonitor;
     65- (void)updateMonitorWithImage:(CGImageRef)image;
     66- (void)resizeMonitor:(NSSize)size;
     67@end
     68
     69/*
     70 * Helper class which allow us to access all members/methods of AbstractDockIconPreviewHelper
     71 * from any Cocoa class.
     72 */
     73class CocoaDockIconPreviewPrivate: public AbstractDockIconPreviewHelper
     74{
     75public:
     76    inline CocoaDockIconPreviewPrivate (VBoxConsoleWnd *aMainWnd, const QPixmap& aOverlayImage)
     77      :AbstractDockIconPreviewHelper (aMainWnd, aOverlayImage)
     78    {
     79        mDockTile = [[DockTile alloc] initWithParent:this];
     80    }
     81
     82    inline ~CocoaDockIconPreviewPrivate()
     83    {
     84        [mDockTile release];
     85    }
     86     
     87    DockTile *mDockTile;
     88};
     89
     90/*
     91 * Cocoa wrapper for the abstract dock icon preview class
     92 */
     93CocoaDockIconPreview::CocoaDockIconPreview (VBoxConsoleWnd *aMainWnd, const QPixmap& aOverlayImage)
     94  : AbstractDockIconPreview (aMainWnd, aOverlayImage)
     95{
     96    CocoaAutoreleasePool pool;
     97
     98    d = new CocoaDockIconPreviewPrivate (aMainWnd, aOverlayImage);
     99}
     100
     101CocoaDockIconPreview::~CocoaDockIconPreview()
     102{
     103    CocoaAutoreleasePool pool;
     104
     105    delete d;
     106}
     107
     108void CocoaDockIconPreview::updateDockOverlay()
     109{
     110    CocoaAutoreleasePool pool;
     111
     112    [d->mDockTile updateAppIcon];
     113}
     114
     115void CocoaDockIconPreview::updateDockPreview (CGImageRef aVMImage)
     116{
     117    CocoaAutoreleasePool pool;
     118
     119    [d->mDockTile updateMonitorWithImage:aVMImage];
     120}
     121
     122void CocoaDockIconPreview::updateDockPreview (VBoxFrameBuffer *aFrameBuffer)
     123{
     124    CocoaAutoreleasePool pool;
     125
     126    AbstractDockIconPreview::updateDockPreview (aFrameBuffer);
     127}
     128
     129
     130void CocoaDockIconPreview::setOriginalSize (int aWidth, int aHeight)
     131{
     132    CocoaAutoreleasePool pool;
     133
     134    [d->mDockTile resizeMonitor:NSMakeSize (aWidth, aHeight)];
     135}
     136
     137/*
     138 * Class for arranging/updating the layers for the glossy monitor preview.
     139 */
     140@implementation DockTileMonitor;
     141- (id)initWithFrame:(NSRect)frame parent:(CocoaDockIconPreviewPrivate*)parent
     142{
     143    self = [super initWithFrame:frame];
     144
     145    if (self != nil)
     146    {
     147        p = parent;
     148        /* The screen content view */
     149        mScreenContent = [[NSImageView alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->mUpdateRect))];
     150//        [mScreenContent setImageAlignment: NSImageAlignCenter];
     151        [mScreenContent setImageAlignment: NSImageAlignTop| NSImageAlignLeft];
     152        [mScreenContent setImageScaling: NSScaleToFit];
     153        [self addSubview: mScreenContent];
     154        /* The state view */
     155        mMonitorGlossy = [[NSImageView alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->mMonitorRect))];
     156        [mMonitorGlossy setImage: darwinCGImageToNSImage (p->mDockMonitorGlossy)];
     157        [self addSubview: mMonitorGlossy];
     158    }
     159
     160    return self;
     161}
     162
     163- (void)drawRect:(NSRect)aRect;
     164{
     165    NSImage *dockMonitor = darwinCGImageToNSImage (p->mDockMonitor);
     166    [dockMonitor drawInRect:NSRectFromCGRect (p->flipRect (p->mMonitorRect)) fromRect:aRect operation:NSCompositeSourceOver fraction:1.0];
     167    [dockMonitor release];
     168}
     169
     170- (NSImageView*)screenContent
     171{
     172    return mScreenContent;
     173}
     174
     175- (void)resize:(NSSize)size;
     176{
     177    /* Calculate the new size based on the aspect ratio of the original screen
     178       size */
     179    float w, h;
     180    if (size.width > size.height)
     181    {
     182        w = p->mUpdateRect.size.width;
     183        h = ((float)size.height / size.width * p->mUpdateRect.size.height);
     184    }
     185    else
     186    {
     187        w = ((float)size.width / size.height * p->mUpdateRect.size.width);
     188        h = p->mUpdateRect.size.height;
     189    }
     190    CGRect r = (p->flipRect (p->centerRectTo (CGRectMake (0, 0, (int)w, (int)h), p->mUpdateRect)));
     191    r.origin.x = (int)r.origin.x;
     192    r.origin.y = (int)r.origin.y;
     193    r.size.width = (int)r.size.width;
     194    r.size.height = (int)r.size.height;
     195//    printf("gui %f %f %f %f\n", r.origin.x, r.origin.y, r.size.width, r.size.height);
     196    /* Center within the update rect */
     197    [mScreenContent setFrame:NSRectFromCGRect (r)];
     198}
     199@end
     200
     201/*
     202 * Simple implementation for the overlay of the OS & the state icon. Is used both
     203 * in the application icon & preview mode.
     204 */
     205@implementation DockTileOverlay
     206- (id)initWithFrame:(NSRect)frame parent:(CocoaDockIconPreviewPrivate*)parent
     207{
     208    self = [super initWithFrame:frame];
     209
     210    if (self != nil)
     211        p = parent;
     212
     213    return self;
     214}
     215
     216- (void)drawRect:(NSRect)aRect;
     217{
    68218    NSGraphicsContext *nsContext = [NSGraphicsContext currentContext];
    69     CGContextRef pCGContext = [nsContext graphicsPort];
    70 
    71     [pool release];
    72     return pCGContext;
    73 }
    74 
    75 void darwinEndCGContextForApplicationDockTile (CGContextRef aContext)
    76 {
    77     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    78 
    79     [gDockIconImage unlockFocus];
    80 
    81     [NSApp setApplicationIconImage:gDockIconImage];
    82 
    83     [pool release];
    84 }
    85 
    86 void darwinOverlayApplicationDockTileImage (CGImageRef pImage)
    87 {
    88     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    89 
    90     /* Convert the CGImage to an NSImage */
    91     NSBitmapImageRep *bitmapImageRep = [[NSBitmapImageRep alloc] initWithCGImage:pImage];
    92     if (bitmapImageRep)
    93     {
    94         NSImage *badgeImage = [[NSImage alloc] initWithSize:[bitmapImageRep size]];
    95         [badgeImage addRepresentation:bitmapImageRep];
    96         [bitmapImageRep release];
    97         /* Make subsequent drawing operations on the icon */
    98         [gDockIconImage lockFocus];
    99         /* Draw the overlay bottom left */
    100         [badgeImage drawAtPoint:NSZeroPoint fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
    101         [gDockIconImage unlockFocus];
    102         [badgeImage release];
    103     }
    104     /* Set the new application icon */
    105     [NSApp setApplicationIconImage:gDockIconImage];
    106    
    107     [pool release];
    108 }
    109 
    110 void darwinRestoreApplicationDockTileImage (void)
    111 {
    112     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    113 
    114     /* Reset all */
    115     darwinDestroyVBoxDockIconTileView();
    116     darwinCreateVBoxDockIconTileView();
    117 
    118     [pool release];
    119 }
    120 
     219    CGContextRef pCGContext = (CGContextRef)[nsContext graphicsPort];
     220    p->drawOverlayIcons (pCGContext);
     221}
     222@end
     223
     224/*
     225 * VirtualBox Dock Tile implementation. Manage the switching between the icon
     226 * and preview mode & forwards all update request to the appropriate methods.
     227 */
     228@implementation DockTile
     229- (id)initWithParent:(CocoaDockIconPreviewPrivate*)parent
     230{
     231    self = [super init];
     232
     233    if (self != nil)
     234    {
     235        p = parent;
     236        /* Add self as the content view of the dock tile */
     237        NSDockTile *dock = [[NSApplication sharedApplication] dockTile];
     238        [dock setContentView: self];
     239        /* App icon is default */
     240        [self restoreAppIcon];
     241        /* The overlay */
     242        mOverlay = [[DockTileOverlay alloc] initWithFrame:NSRectFromCGRect(p->flipRect (p->mDockIconRect)) parent:p];
     243        [self addSubview: mOverlay];
     244    }
     245
     246    return self;
     247}
     248
     249- (NSView*)screenContent
     250{
     251    return [mMonitor screenContent];
     252}
     253
     254- (void)cleanup
     255{
     256    if (mAppIcon != nil)
     257    {
     258        [mAppIcon removeFromSuperview];
     259        [mAppIcon release];
     260        mAppIcon = nil;
     261    }
     262    if (mMonitor != nil)
     263    {
     264        [mMonitor removeFromSuperview];
     265        [mMonitor release];
     266        mMonitor = nil;
     267    }
     268}
     269
     270- (void)restoreAppIcon
     271{
     272    if (mAppIcon == nil)
     273    {
     274        [self cleanup];
     275        mAppIcon = [[NSImageView alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->mDockIconRect))];
     276        [mAppIcon setImage: [NSImage imageNamed:@"NSApplicationIcon"]];
     277        [self addSubview: mAppIcon positioned:NSWindowBelow relativeTo:mOverlay];
     278    }
     279}
     280
     281- (void)updateAppIcon
     282{
     283    [self restoreAppIcon];
     284    [[[NSApplication sharedApplication] dockTile] display];
     285}
     286
     287- (void)restoreMonitor
     288{
     289    if (mMonitor == nil)
     290    {
     291        p->initPreviewImages();
     292        [self cleanup];
     293        mMonitor = [[DockTileMonitor alloc] initWithFrame:NSRectFromCGRect (p->flipRect (p->mDockIconRect)) parent:p];
     294        [self addSubview: mMonitor positioned:NSWindowBelow relativeTo:mOverlay];
     295    }
     296}
     297
     298- (void)updateMonitorWithImage:(CGImageRef)image
     299{
     300    [self restoreMonitor];
     301    NSImage *nsimage = darwinCGImageToNSImage (image);
     302    [[mMonitor screenContent] setImage: nsimage];
     303    [nsimage release];
     304    [[[NSApplication sharedApplication] dockTile] display];
     305}
     306
     307- (void)resizeMonitor:(NSSize)size;
     308{
     309    [mMonitor resize:size];
     310}
     311@end
     312
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette