Fix OS X memory leak prints when starting blender:
[blender-staging.git] / intern / ghost / intern / GHOST_WindowCocoa.mm
index 5dcc949ed4590ab85499116854dda757247e2f3e..83f86840eb4b0b61f978ef69ac4e95478a9bc707 100644 (file)
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
@@ -167,7 +167,7 @@ extern "C" {
        else if ([[draggingPBoard types] containsObject:NSStringPboardType]) m_draggedObjectType = GHOST_kDragnDropTypeString;
        else return NSDragOperationNone;
        
-       associatedWindow->setAcceptDragOperation(FALSE); //Drag operation needs to be accepted explicitly by the event manager
+       associatedWindow->setAcceptDragOperation(TRUE); //Drag operation is accepted by default
        systemCocoa->handleDraggingEvent(GHOST_kEventDraggingEntered, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil);
        return NSDragOperationCopy;
 }
@@ -182,7 +182,7 @@ extern "C" {
        NSPoint mouseLocation = [sender draggingLocation];
        
        systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil);
-       return NSDragOperationCopy;
+       return associatedWindow->canAcceptDragOperation()?NSDragOperationCopy:NSDragOperationNone;
 }
 
 - (void)draggingExited:(id < NSDraggingInfo >)sender
@@ -203,11 +203,16 @@ extern "C" {
 {
        NSPoint mouseLocation = [sender draggingLocation];
        NSPasteboard *draggingPBoard = [sender draggingPasteboard];
+       NSImage *droppedImg;
        id data;
        
        switch (m_draggedObjectType) {
                case GHOST_kDragnDropTypeBitmap:
-                       data = [draggingPBoard dataForType:NSTIFFPboardType];
+                       if([NSImage canInitWithPasteboard:draggingPBoard]) {
+                               droppedImg = [[NSImage alloc]initWithPasteboard:draggingPBoard];
+                               data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType];
+                       }
+                       else return NO;
                        break;
                case GHOST_kDragnDropTypeFilenames:
                        data = [draggingPBoard propertyListForType:NSFilenamesPboardType];
@@ -343,10 +348,11 @@ GHOST_WindowCocoa::GHOST_WindowCocoa(
        
        pixelFormatAttrsWindow[i++] = NSOpenGLPFAAccelerated;
        //pixelFormatAttrsWindow[i++] = NSOpenGLPFAAllowOfflineRenderers,;   // Removed to allow 10.4 builds, and 2 GPUs rendering is not used anyway
-       
+
        pixelFormatAttrsWindow[i++] = NSOpenGLPFADepthSize;
        pixelFormatAttrsWindow[i++] = (NSOpenGLPixelFormatAttribute) 32;
        
+       
        if (stereoVisual) pixelFormatAttrsWindow[i++] = NSOpenGLPFAStereo;
        
        if (numOfAASamples>0) {
@@ -588,6 +594,7 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
 GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
 {
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid")
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        GHOST_Rect cBnds, wBnds;
        getClientBounds(cBnds);
        if (((GHOST_TUns32)cBnds.getWidth()) != width) {
@@ -596,6 +603,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
                size.height=cBnds.getHeight();
                [m_window setContentSize:size];
        }
+       [pool drain];
        return GHOST_kSuccess;
 }
 
@@ -603,6 +611,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
 GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
 {
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        GHOST_Rect cBnds, wBnds;
        getClientBounds(cBnds);
        if (((GHOST_TUns32)cBnds.getHeight()) != height) {
@@ -611,6 +620,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
                size.height=height;
                [m_window setContentSize:size];
        }
+       [pool drain];
        return GHOST_kSuccess;
 }
 
@@ -618,6 +628,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
 GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
 {
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        GHOST_Rect cBnds, wBnds;
        getClientBounds(cBnds);
        if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
@@ -627,6 +638,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32
                size.height=height;
                [m_window setContentSize:size];
        }
+       [pool drain];
        return GHOST_kSuccess;
 }
 
@@ -721,7 +733,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
 #ifdef MAC_OS_X_VERSION_10_6
                                //10.6 provides Cocoa functions to autoshow menu bar, and to change a window style
                                //Hide menu & dock if needed
-                               if ([[m_window screen] isEqual:[NSScreen mainScreen]])
+                               if ([[m_window screen] isEqual:[[NSScreen screens] objectAtIndex:0]])
                                {
                                        [NSApp setPresentationOptions:(NSApplicationPresentationHideDock | NSApplicationPresentationAutoHideMenuBar)];
                                }
@@ -732,7 +744,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
 #else
                                //With 10.5, we need to create a new window to change its style to borderless
                                //Hide menu & dock if needed
-                               if ([[m_window screen] isEqual:[NSScreen mainScreen]])
+                               if ([[m_window screen] isEqual:[[NSScreen screens] objectAtIndex:0]])
                                {
                                        //Cocoa function in 10.5 does not allow to set the menu bar in auto-show mode [NSMenu setMenuBarVisible:NO];
                                        //One of the very few 64bit compatible Carbon function
@@ -771,9 +783,9 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
                        break;
                case GHOST_kWindowStateNormal:
         default:
+                       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
                        if (m_fullScreen)
                        {
-                               NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
                                m_fullScreen = false;
 
                                //Exit fullscreen
@@ -823,15 +835,15 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
                        
                                //Tell WM of view new size
                                m_systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, this);
-                               
-                               [pool drain];
                        }
             else if ([m_window isMiniaturized])
                                [m_window deminiaturize:nil];
                        else if ([m_window isZoomed])
                                [m_window zoom:nil];
+                       [pool drain];
             break;
     }
+
     return GHOST_kSuccess;
 }
 
@@ -849,6 +861,8 @@ GHOST_TSuccess GHOST_WindowCocoa::setModifiedState(bool isUnsavedChanges)
 
 GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
 {
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       
        GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
     if (order == GHOST_kWindowOrderTop) {
                [m_window makeKeyAndOrderFront:nil];
@@ -864,6 +878,8 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
                        [[windowsList objectAtIndex:0] makeKeyAndOrderFront:nil];
                }
     }
+       
+       [pool drain];
     return GHOST_kSuccess;
 }
 
@@ -1005,14 +1021,72 @@ GHOST_TSuccess GHOST_WindowCocoa::invalidate()
        return GHOST_kSuccess;
 }
 
+#pragma mark Progress bar
+
+GHOST_TSuccess GHOST_WindowCocoa::setProgressBar(float progress)
+{
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       
+       if ((progress >=0.0) && (progress <=1.0)) {
+               NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
+               
+               [dockIcon lockFocus];
+        NSRect progressBox = {{4, 4}, {120, 16}};
+
+        [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0];
+        
+        // Track & Outline
+        [[NSColor blackColor] setFill];
+        NSRectFill(progressBox);
+        
+        [[NSColor whiteColor] set];
+        NSFrameRect(progressBox);
+        
+        // Progress fill
+        progressBox = NSInsetRect(progressBox, 1, 1);
+        [[NSColor knobColor] setFill];
+        progressBox.size.width = progressBox.size.width * progress;
+               NSRectFill(progressBox);
+               
+               [dockIcon unlockFocus];
+               
+               [NSApp setApplicationIconImage:dockIcon];
+               [dockIcon release];
+               
+               m_progressBarVisible = true;
+       }
+       
+       [pool drain];
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::endProgressBar()
+{
+       if (!m_progressBarVisible) return GHOST_kFailure;
+       m_progressBarVisible = false;
+       
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+       
+       NSImage* dockIcon = [[NSImage alloc] initWithSize:NSMakeSize(128,128)];
+       [dockIcon lockFocus];
+       [[NSImage imageNamed:@"NSApplicationIcon"] dissolveToPoint:NSZeroPoint fraction:1.0];
+       [dockIcon unlockFocus];
+       [NSApp setApplicationIconImage:dockIcon];
+       [dockIcon release];
+       
+       [pool drain];
+       return GHOST_kSuccess;
+}
+
+
+
 #pragma mark Cursor handling
 
 void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
 {
        static bool systemCursorVisible = true;
        
-       NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init];
-
        NSCursor *tmpCursor =nil;
        
        if (visible != systemCursorVisible) {
@@ -1076,17 +1150,19 @@ void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) c
                };
        }
        [tmpCursor set];
-       [pool drain];
 }
 
 
 
 GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
 {
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
+       
        if ([m_window isVisible]) {
                loadCursor(visible, getCursorShape());
        }
        
+       [pool drain];
        return GHOST_kSuccess;
 }
 
@@ -1100,6 +1176,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
                //No need to perform grab without warp as it is always on in OS X
                if(mode != GHOST_kGrabNormal) {
                        GHOST_TInt32 x_old,y_old;
+                       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
                        m_systemCocoa->getCursorPosition(x_old,y_old);
                        screenToClient(x_old, y_old, m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
@@ -1110,8 +1187,13 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
                                setWindowCursorVisibility(false);
                        }
                        
+                       //Make window key if it wasn't to get the mouse move events
+                       [m_window makeKeyWindow];
+                       
                        //Dissociate cursor position even for warp mode, to allow mouse acceleration to work even when warping the cursor
                        err = CGAssociateMouseAndMouseCursorPosition(false) == kCGErrorSuccess ? GHOST_kSuccess : GHOST_kFailure;
+                       
+                       [pool drain];
                }
        }
        else {
@@ -1131,6 +1213,8 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorGrab(GHOST_TGrabCursorMode mode
        
 GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
 {
+       NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
        if (m_customCursor) {
                [m_customCursor release];
                m_customCursor = nil;
@@ -1140,6 +1224,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor sha
                loadCursor(getCursorVisibility(), shape);
        }
        
+       [pool drain];
        return GHOST_kSuccess;
 }