Cocoa port start:
authorDamien Plisson <damien.plisson@yahoo.fr>
Wed, 30 Sep 2009 08:47:39 +0000 (08:47 +0000)
committerDamien Plisson <damien.plisson@yahoo.fr>
Wed, 30 Sep 2009 08:47:39 +0000 (08:47 +0000)
GHOST*Cocoa.mm & .h files creation
First Cocoa version of GHOST_SystemCocoa.mm
CMake files update to allow optional (WITH_COCOA option) Cocoa version build - disabled by default
SCons files are not updated to allow Cocoa build (the ghost .mm files)

CMakeLists.txt
intern/ghost/CMakeLists.txt
intern/ghost/intern/GHOST_DisplayManagerCocoa.h [new file with mode: 0644]
intern/ghost/intern/GHOST_DisplayManagerCocoa.mm [new file with mode: 0644]
intern/ghost/intern/GHOST_ISystem.cpp
intern/ghost/intern/GHOST_SystemCocoa.h [new file with mode: 0644]
intern/ghost/intern/GHOST_SystemCocoa.mm [new file with mode: 0644]
intern/ghost/intern/GHOST_WindowCocoa.h [new file with mode: 0644]
intern/ghost/intern/GHOST_WindowCocoa.mm [new file with mode: 0644]

index d8c5a13..d53f4ed 100644 (file)
@@ -81,6 +81,10 @@ OPTION(WITH_CXX_GUARDEDALLOC "Enable GuardedAlloc for C++ memory allocation" OFF
 OPTION(WITH_BUILDINFO     "Include extra build details" ON)
 OPTION(WITH_INSTALL       "Install accompanying scripts and language files needed to run blender" ON)
 
+IF (APPLE)
+OPTION(WITH_COCOA        "Use Cocoa framework instead of deprecated Carbon" OFF)
+ENDIF (APPLE)
+
 IF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
        MESSAGE("WARNING: WITH_PLAYER needs WITH_GAMEENGINE")
 ENDIF(NOT WITH_GAMEENGINE AND WITH_PLAYER)
@@ -402,6 +406,7 @@ IF(APPLE)
                FIND_PACKAGE(OpenAL)
                IF(OPENAL_FOUND)
                        SET(WITH_OPENAL ON)
+                       SET(OPENAL_INCLUDE_DIR "${OPENAL_INCLUDE_DIR};${LIBDIR}/openal/include")
                ELSE(OPENAL_FOUND)
                        SET(WITH_OPENAL OFF)
                ENDIF(OPENAL_FOUND)
@@ -485,9 +490,13 @@ IF(APPLE)
 
        SET(LLIBS stdc++ SystemStubs)
 
+       IF (WITH_COCOA)
+       SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing -DGHOST_COCOA")
+       SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Cocoa -framework Carbon -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
+       ELSE (WITH_COCOA)
        SET(PLATFORM_CFLAGS "-pipe -fPIC -funsigned-char -fno-strict-aliasing")
        SET(PLATFORM_LINKFLAGS "-fexceptions -framework CoreServices -framework Foundation -framework IOKit -framework AppKit -framework Carbon -framework AGL -framework AudioUnit -framework AudioToolbox -framework CoreAudio -framework QuickTime")
-
+       ENDIF (WITH_COCOA)
        IF(WITH_OPENMP)
                SET(LLIBS "${LLIBS} -lgomp ")
                SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fopenmp ")
index 9128e92..33af61b 100644 (file)
 
 SET(INC . ../string)
 
-FILE(GLOB SRC intern/*.cpp)
+FILE(GLOB SRC intern/*.cpp intern/*.mm)
 
 IF(APPLE)
+       IF(WITH_COCOA)
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+       ELSE(WITH_COCOA)
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
+       ENDIF(WITH_COCOA)
        LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp")
        LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp")
        LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp")
@@ -41,6 +50,9 @@ ELSE(APPLE)
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp")
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp")
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp")
@@ -52,6 +64,9 @@ ELSE(APPLE)
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
                LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCocoa.mm")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCocoa.mm")
+               LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCocoa.mm")
        ENDIF(WIN32)
 ENDIF(APPLE)
 
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.h b/intern/ghost/intern/GHOST_DisplayManagerCocoa.h
new file mode 100644 (file)
index 0000000..1483f62
--- /dev/null
@@ -0,0 +1,113 @@
+/**
+ * $Id: GHOST_DisplayManagerCocoa.h 13161 2008-01-07 19:13:47Z hos $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/**
+ * @file       GHOST_DisplayManagerCocoa.h
+ * Declaration of GHOST_DisplayManagerCocoa class.
+ */
+
+#ifndef _GHOST_DISPLAY_MANAGER_COCOA_H_
+#define _GHOST_DISPLAY_MANAGER_COCOA_H_
+
+#ifndef __APPLE__
+#error Apple only!
+#endif // __APPLE__
+
+#include "GHOST_DisplayManager.h"
+
+/**
+ * Manages system displays  (Mac OSX/Cocoa implementation).
+ * @see GHOST_DisplayManager
+ * @author     Maarten Gribnau
+ * @date       September 21, 2001
+ */
+class GHOST_DisplayManagerCocoa : public GHOST_DisplayManager
+{
+public:
+       /**
+        * Constructor.
+        */
+       GHOST_DisplayManagerCocoa(void);
+
+       /**
+        * Returns the number of display devices on this system.
+        * @param numDisplays The number of displays on this system.
+        * @return Indication of success.
+        */
+       virtual GHOST_TSuccess getNumDisplays(GHOST_TUns8& numDisplays) const;
+
+       /**
+        * Returns the number of display settings for this display device.
+        * @param display The index of the display to query with 0 <= display < getNumDisplays().
+        * @param setting The number of settings of the display device with this index.
+        * @return Indication of success.
+        */
+       virtual GHOST_TSuccess getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const;
+
+       /**
+        * Returns the current setting for this display device. 
+        * @param display The index of the display to query with 0 <= display < getNumDisplays().
+        * @param index   The setting index to be returned.
+        * @param setting The setting of the display device with this index.
+        * @return Indication of success.
+        */
+       virtual GHOST_TSuccess getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const;
+
+       /**
+        * Returns the current setting for this display device. 
+        * @param display The index of the display to query with 0 <= display < getNumDisplays().
+        * @param setting The current setting of the display device with this index.
+        * @return Indication of success.
+        */
+       virtual GHOST_TSuccess getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const;
+
+       /**
+        * Changes the current setting for this display device. 
+        * @param display The index of the display to query with 0 <= display < getNumDisplays().
+        * @param setting The current setting of the display device with this index.
+        * @return Indication of success.
+        */
+       virtual GHOST_TSuccess setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting);
+
+protected:
+       /**
+        * Returns a value from a dictionary.
+        * @param       values  Dictionary to return value from.
+        * @param       key     Key to return value for.
+        * @return The value for this key.
+        */
+       long getValue(CFDictionaryRef values, CFStringRef key) const;
+       
+       /** Cached number of displays. */
+       CGDisplayCount m_numDisplays;
+       /** Cached display id's for each display. */
+       CGDirectDisplayID* m_displayIDs;
+};
+
+
+#endif // _GHOST_DISPLAY_MANAGER_COCOA_H_
+
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
new file mode 100644 (file)
index 0000000..298baa5
--- /dev/null
@@ -0,0 +1,180 @@
+/**
+ * $Id: GHOST_DisplayManagerCocoa.mm 13161 2008-01-07 19:13:47Z hos $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id: GHOST_DisplayManagerCocoa.mm 13161 2008-01-07 19:13:47Z hos $
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author     Maarten Gribnau
+ * @date       September 21, 2001
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Carbon/Carbon.h>
+
+#include "GHOST_DisplayManagerCocoa.h"
+#include "GHOST_Debug.h"
+
+// We do not support multiple monitors at the moment
+
+
+GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(void)
+{
+       if (::CGGetActiveDisplayList(0, NULL, &m_numDisplays) != CGDisplayNoErr)
+       {
+               m_numDisplays = 0;
+               m_displayIDs = NULL;
+       }
+       if (m_numDisplays > 0)
+       {
+               m_displayIDs = new CGDirectDisplayID [m_numDisplays];
+               GHOST_ASSERT((m_displayIDs!=NULL), "GHOST_DisplayManagerCocoa::GHOST_DisplayManagerCocoa(): memory allocation failed");
+               ::CGGetActiveDisplayList(m_numDisplays, m_displayIDs, &m_numDisplays);
+       }
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplays(GHOST_TUns8& numDisplays) const
+{
+       numDisplays = (GHOST_TUns8) m_numDisplays;
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getNumDisplaySettings(GHOST_TUns8 display, GHOST_TInt32& numSettings) const
+{
+       GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getNumDisplaySettings(): only main display is supported");
+       
+       CFArrayRef displayModes;
+       displayModes = ::CGDisplayAvailableModes(m_displayIDs[display]);
+       CFIndex numModes = ::CFArrayGetCount(displayModes);
+       numSettings = (GHOST_TInt32)numModes;
+       
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getDisplaySetting(GHOST_TUns8 display, GHOST_TInt32 index, GHOST_DisplaySetting& setting) const
+{
+       GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getDisplaySetting(): only main display is supported");
+       
+       CFArrayRef displayModes;
+       CGDirectDisplayID d = m_displayIDs[display];
+       displayModes = ::CGDisplayAvailableModes(d);
+       //CFIndex numModes = ::CFArrayGetCount(displayModes);/*unused*/
+       //GHOST_TInt32 numSettings = (GHOST_TInt32)numModes; /*unused*/
+        CFDictionaryRef displayModeValues = (CFDictionaryRef)::CFArrayGetValueAtIndex(displayModes, index);
+                       
+       setting.xPixels         = getValue(displayModeValues, kCGDisplayWidth);
+       setting.yPixels         = getValue(displayModeValues, kCGDisplayHeight);
+       setting.bpp                     = getValue(displayModeValues, kCGDisplayBitsPerPixel);
+       setting.frequency       = getValue(displayModeValues, kCGDisplayRefreshRate);
+                       
+#ifdef GHOST_DEBUG
+       printf("display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
+#endif // GHOST_DEBUG
+
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 display, GHOST_DisplaySetting& setting) const
+{
+       GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(): only main display is supported");
+        
+       CFDictionaryRef displayModeValues = ::CGDisplayCurrentMode(m_displayIDs[display]);
+       
+       setting.xPixels         = getValue(displayModeValues, kCGDisplayWidth);
+       setting.yPixels         = getValue(displayModeValues, kCGDisplayHeight);
+       setting.bpp                     = getValue(displayModeValues, kCGDisplayBitsPerPixel);
+       setting.frequency       = getValue(displayModeValues, kCGDisplayRefreshRate);
+
+#ifdef GHOST_DEBUG
+       printf("current display mode: width=%d, height=%d, bpp=%d, frequency=%d\n", setting.xPixels, setting.yPixels, setting.bpp, setting.frequency);
+#endif // GHOST_DEBUG
+
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(GHOST_TUns8 display, const GHOST_DisplaySetting& setting)
+{
+       GHOST_ASSERT((display==kMainDisplay), "GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): only main display is supported");
+
+#ifdef GHOST_DEBUG
+       printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): requested settings:\n");
+       printf("  setting.xPixels=%d\n", setting.xPixels);
+       printf("  setting.yPixels=%d\n", setting.yPixels);
+       printf("  setting.bpp=%d\n", setting.bpp);
+       printf("  setting.frequency=%d\n", setting.frequency);
+#endif // GHOST_DEBUG
+
+       CFDictionaryRef displayModeValues = ::CGDisplayBestModeForParametersAndRefreshRate(
+               m_displayIDs[display],
+               (size_t)setting.bpp,
+               (size_t)setting.xPixels,
+               (size_t)setting.yPixels,
+               (CGRefreshRate)setting.frequency,
+               NULL);
+
+#ifdef GHOST_DEBUG
+       printf("GHOST_DisplayManagerCocoa::setCurrentDisplaySetting(): switching to:\n");
+       printf("  setting.xPixels=%d\n", getValue(displayModeValues, kCGDisplayWidth));
+       printf("  setting.yPixels=%d\n", getValue(displayModeValues, kCGDisplayHeight));
+       printf("  setting.bpp=%d\n", getValue(displayModeValues, kCGDisplayBitsPerPixel));
+       printf("  setting.frequency=%d\n", getValue(displayModeValues, kCGDisplayRefreshRate));
+#endif // GHOST_DEBUG
+
+       CGDisplayErr err = ::CGDisplaySwitchToMode(m_displayIDs[display], displayModeValues);
+        
+       return err == CGDisplayNoErr ? GHOST_kSuccess : GHOST_kFailure;
+}
+
+
+long GHOST_DisplayManagerCocoa::getValue(CFDictionaryRef values, CFStringRef key) const
+{
+    CFNumberRef numberValue = (CFNumberRef) CFDictionaryGetValue(values, key);
+    
+    if (!numberValue)
+    {
+        return -1;
+    }
+    
+    long intValue;
+    
+    if (!CFNumberGetValue(numberValue, kCFNumberLongType, &intValue))
+    {
+        return -1;
+    }
+    
+    return intValue;
+}
+
index 9329e68..fc338c1 100644 (file)
 #      include "GHOST_SystemWin32.h"
 #else
 #      ifdef __APPLE__
-#              include "GHOST_SystemCarbon.h"
+#              ifdef GHOST_COCOA
+#                      include "GHOST_SystemCocoa.h"
+#              else
+#                      include "GHOST_SystemCarbon.h"
+#              endif
 #      else
 #              include "GHOST_SystemX11.h"
 #      endif
@@ -62,7 +66,11 @@ GHOST_TSuccess GHOST_ISystem::createSystem()
                m_system = new GHOST_SystemWin32 ();
 #else
 #      ifdef __APPLE__
-        m_system = new GHOST_SystemCarbon ();
+#              ifdef GHOST_COCOA
+                       m_system = new GHOST_SystemCocoa ();
+#              else
+                       m_system = new GHOST_SystemCarbon ();
+#              endif
 #      else 
                m_system = new GHOST_SystemX11 ();
 #      endif
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.h b/intern/ghost/intern/GHOST_SystemCocoa.h
new file mode 100644 (file)
index 0000000..3093118
--- /dev/null
@@ -0,0 +1,274 @@
+/**
+ * $Id: GHOST_SystemCocoa.h 20741 2009-06-08 20:08:19Z blendix $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s):     Maarten Gribnau 05/2001
+ *                                     Damien Plisson 09/2009
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/**
+ * @file       GHOST_SystemCocoa.h
+ * Declaration of GHOST_SystemCocoa class.
+ */
+
+#ifndef _GHOST_SYSTEM_COCOA_H_
+#define _GHOST_SYSTEM_COCOA_H_
+
+#ifndef __APPLE__
+#error Apple OSX only!
+#endif // __APPLE__
+
+//#define __CARBONSOUND__
+
+
+#include "GHOST_System.h"
+
+class GHOST_EventCursor;
+class GHOST_EventKey;
+class GHOST_EventWindow;
+
+
+class GHOST_SystemCocoa : public GHOST_System {
+public:
+    /**
+     * Constructor.
+     */
+    GHOST_SystemCocoa();
+    
+    /** 
+     * Destructor.
+     */
+    ~GHOST_SystemCocoa();
+    
+       /***************************************************************************************
+        ** Time(r) functionality
+        ***************************************************************************************/
+
+       /**
+        * Returns the system time.
+        * Returns the number of milliseconds since the start of the system process.
+        * Based on ANSI clock() routine.
+        * @return The number of milliseconds.
+        */
+       virtual GHOST_TUns64 getMilliSeconds() const;
+
+       /***************************************************************************************
+        ** Display/window management functionality
+        ***************************************************************************************/
+
+       /**
+        * Returns the number of displays on this system.
+        * @return The number of displays.
+        */
+       virtual GHOST_TUns8 getNumDisplays() const;
+
+       /**
+        * Returns the dimensions of the main display on this system.
+        * @return The dimension of the main display.
+        */
+       virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const;
+       
+       /**
+        * Create a new window.
+        * The new window is added to the list of windows managed. 
+        * Never explicitly delete the window, use disposeWindow() instead.
+        * @param       title   The name of the window (displayed in the title bar of the window if the OS supports it).
+        * @param       left    The coordinate of the left edge of the window.
+        * @param       top             The coordinate of the top edge of the window.
+        * @param       width   The width the window.
+        * @param       height  The height the window.
+        * @param       state   The state of the window when opened.
+        * @param       type    The type of drawing context installed in this window.
+        * @param       parentWindow    Parent (embedder) window
+        * @return      The new window (or 0 if creation failed).
+        */
+       virtual GHOST_IWindow* createWindow(
+               const STR_String& title,
+               GHOST_TInt32 left,
+               GHOST_TInt32 top,
+               GHOST_TUns32 width,
+               GHOST_TUns32 height,
+               GHOST_TWindowState state,
+               GHOST_TDrawingContextType type,
+               const bool stereoVisual,
+               const GHOST_TEmbedderWindowID parentWindow = 0 
+       );
+       
+       virtual GHOST_TSuccess beginFullScreen(
+               const GHOST_DisplaySetting& setting, 
+               GHOST_IWindow** window,
+               const bool stereoVisual
+       );
+       
+       virtual GHOST_TSuccess endFullScreen( void );
+       
+       /***************************************************************************************
+        ** Event management functionality
+        ***************************************************************************************/
+
+       /**
+        * Gets events from the system and stores them in the queue.
+        * @param waitForEvent Flag to wait for an event (or return immediately).
+        * @return Indication of the presence of events.
+        */
+       virtual bool processEvents(bool waitForEvent);
+       
+       /***************************************************************************************
+        ** Cursor management functionality
+        ***************************************************************************************/
+
+       /**
+        * Returns the current location of the cursor (location in screen coordinates)
+        * @param x                     The x-coordinate of the cursor.
+        * @param y                     The y-coordinate of the cursor.
+        * @return                      Indication of success.
+        */
+       virtual GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const;
+
+       /**
+        * Updates the location of the cursor (location in screen coordinates).
+        * @param x                     The x-coordinate of the cursor.
+        * @param y                     The y-coordinate of the cursor.
+        * @return                      Indication of success.
+        */
+       virtual GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const;
+
+       /***************************************************************************************
+        ** Access to mouse button and keyboard states.
+        ***************************************************************************************/
+
+       /**
+        * Returns the state of all modifier keys.
+        * @param keys  The state of all modifier keys (true == pressed).
+        * @return              Indication of success.
+        */
+       virtual GHOST_TSuccess getModifierKeys(GHOST_ModifierKeys& keys) const;
+
+       /**
+        * Returns the state of the mouse buttons (ouside the message queue).
+        * @param buttons       The state of the buttons.
+        * @return                      Indication of success.
+        */
+       virtual GHOST_TSuccess getButtons(GHOST_Buttons& buttons) const;
+
+       /**
+        * Returns Clipboard data
+        * @param selection             Indicate which buffer to return
+        * @return                              Returns the selected buffer
+        */
+       virtual GHOST_TUns8* getClipboard(bool selection) const;
+       
+       /**
+        * Puts buffer to system clipboard
+        * @param buffer        The buffer to be copied
+        * @param selection     Indicates which buffer to copy too, only used on X11
+        */
+       virtual void putClipboard(GHOST_TInt8 *buffer, bool selection) const;
+
+protected:
+       /**
+        * Initializes the system.
+        * For now, it justs registers the window class (WNDCLASS).
+        * @return A success value.
+        */
+       virtual GHOST_TSuccess init();
+
+       /**
+        * Closes the system down.
+        * @return A success value.
+        */
+       virtual GHOST_TSuccess exit();
+
+       
+    /**
+     * Handles a tablet event.
+     * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+     * @return Indication whether the event was handled. 
+     */
+    int handleTabletEvent(void *eventPtr);
+    /**
+     * Handles a mouse event.
+     * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+     * @return Indication whether the event was handled. 
+     */
+    int handleMouseEvent(void *eventPtr);
+
+    /**
+     * Handles a key event.
+     * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+     * @return Indication whether the event was handled. 
+     */
+    int handleKeyEvent(void *eventPtr);
+
+   /**
+     * Handles a window event.
+     * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+     * @return Indication whether the event was handled. 
+     */
+    int handleWindowEvent(void *eventPtr);
+
+    /**
+     * Handles all basic Mac application stuff for a mouse down event.
+     * @param eventPtr An NSEvent pointer (casted to void* to enable compilation in standard C++)
+     * @return Indication whether the event was handled. 
+     */
+   // bool handleMouseDown(void *eventPtr);
+
+    /**
+     * Handles a Mac menu command.
+     * @param menuResult A Mac menu/item identifier.
+     * @return Indication whether the event was handled. 
+     */
+   // bool handleMenuCommand(GHOST_TInt32 menuResult);
+    
+    /* callback for blender generated events */
+//     static OSStatus blendEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData);
+
+
+    /**
+     * Callback for Mac Timer tasks that expire.
+     * @param tmTask Pointer to the timer task that expired.
+     */
+    //static void s_timerCallback(TMTaskPtr tmTask);
+    
+       /** Cocoa autoReleasePool (void*) used for enablign standard C++ compilation */
+       void* autoReleasePool;
+       
+    /** Event handler reference. */
+    //EventHandlerRef m_handler;
+       
+       /** Start time at initialization. */
+       GHOST_TUns64 m_start_time;
+       
+       /** Mouse buttons state */
+       GHOST_TUns32 m_pressedMouseButtons;
+       
+    /** State of the modifiers. */
+    GHOST_TUns32 m_modifierMask;
+
+    /** Ignores window size messages (when window is dragged). */
+    bool m_ignoreWindowSizedMessages;    
+};
+
+#endif // _GHOST_SYSTEM_COCOA_H_
+
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
new file mode 100644 (file)
index 0000000..7495284
--- /dev/null
@@ -0,0 +1,1282 @@
+/**
+ * $Id: GHOST_SystemCocoa.cpp 23296 2009-09-16 22:27:27Z broken $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s):     Maarten Gribnau 05/2001
+ *                                     Damien Plisson 09/2009
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#import <Cocoa/Cocoa.h>
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include "GHOST_SystemCocoa.h"
+
+#include "GHOST_DisplayManagerCocoa.h"
+#include "GHOST_EventKey.h"
+#include "GHOST_EventButton.h"
+#include "GHOST_EventCursor.h"
+#include "GHOST_EventWheel.h"
+#include "GHOST_EventNDOF.h"
+
+#include "GHOST_TimerManager.h"
+#include "GHOST_TimerTask.h"
+#include "GHOST_WindowManager.h"
+#include "GHOST_WindowCocoa.h"
+#include "GHOST_NDOFManager.h"
+#include "AssertMacros.h"
+
+#define GHOST_KEY_SWITCH(mac, ghost) { case (mac): ghostKey = (ghost); break; }
+
+/* blender class and types events */
+enum {
+  kEventClassBlender              = 'blnd'
+};
+
+enum {
+       kEventBlenderNdofAxis                   = 1,
+       kEventBlenderNdofButtons                = 2
+};
+
+#pragma mark KeyMap, mouse converters
+
+const EventTypeSpec    kEvents[] =
+{
+       { kEventClassAppleEvent, kEventAppleEvent },
+/*
+       { kEventClassApplication, kEventAppActivated },
+       { kEventClassApplication, kEventAppDeactivated },
+*/     
+       { kEventClassKeyboard, kEventRawKeyDown },
+       { kEventClassKeyboard, kEventRawKeyRepeat },
+       { kEventClassKeyboard, kEventRawKeyUp },
+       { kEventClassKeyboard, kEventRawKeyModifiersChanged },
+       
+       { kEventClassMouse, kEventMouseDown },
+       { kEventClassMouse, kEventMouseUp },
+       { kEventClassMouse, kEventMouseMoved },
+       { kEventClassMouse, kEventMouseDragged },
+       { kEventClassMouse, kEventMouseWheelMoved },
+       
+       { kEventClassWindow, kEventWindowClickZoomRgn } ,  /* for new zoom behaviour */ 
+       { kEventClassWindow, kEventWindowZoom },  /* for new zoom behaviour */ 
+       { kEventClassWindow, kEventWindowExpand } ,  /* for new zoom behaviour */ 
+       { kEventClassWindow, kEventWindowExpandAll },  /* for new zoom behaviour */ 
+
+       { kEventClassWindow, kEventWindowClose },
+       { kEventClassWindow, kEventWindowActivated },
+       { kEventClassWindow, kEventWindowDeactivated },
+       { kEventClassWindow, kEventWindowUpdate },
+       { kEventClassWindow, kEventWindowBoundsChanged },
+       
+       { kEventClassBlender, kEventBlenderNdofAxis },
+       { kEventClassBlender, kEventBlenderNdofButtons }
+       
+       
+       
+};
+
+static GHOST_TButtonMask convertButton(EventMouseButton button)
+{
+       switch (button) {
+               case 0:
+                       return GHOST_kButtonMaskLeft;
+               case 1:
+                       return GHOST_kButtonMaskRight;
+               case 2:
+                       return GHOST_kButtonMaskMiddle;
+               case 3:
+                       return GHOST_kButtonMaskButton4;
+               case 4:
+                       return GHOST_kButtonMaskButton5;
+               default:
+                       return GHOST_kButtonMaskLeft;
+       }
+}
+
+static GHOST_TKey convertKey(int rawCode, unsigned char asciiCharacter) 
+{      
+               /* This bit of magic converts the rawCode into a virtual
+                * Mac key based on the current keyboard mapping, but
+                * without regard to the modifiers (so we don't get 'a' 
+                * and 'A' for example.
+                */
+               /* Map numpad based on rawcodes first, otherwise they
+                * look like non-numpad events.
+                * Added too: mapping the number keys, for french keyboards etc (ton)
+                */
+       // printf("GHOST: vk: %d %c raw: %d\n", asciiCharacter, asciiCharacter, rawCode);
+       //FIXME : check rawcodes         
+       switch (rawCode) {
+       case 18:        return GHOST_kKey1;
+       case 19:        return GHOST_kKey2;
+       case 20:        return GHOST_kKey3;
+       case 21:        return GHOST_kKey4;
+       case 23:        return GHOST_kKey5;
+       case 22:        return GHOST_kKey6;
+       case 26:        return GHOST_kKey7;
+       case 28:        return GHOST_kKey8;
+       case 25:        return GHOST_kKey9;
+       case 29:        return GHOST_kKey0;
+       
+       case 82:        return GHOST_kKeyNumpad0;
+       case 83:        return GHOST_kKeyNumpad1;
+       case 84:        return GHOST_kKeyNumpad2;
+       case 85:        return GHOST_kKeyNumpad3;
+       case 86:        return GHOST_kKeyNumpad4;
+       case 87:        return GHOST_kKeyNumpad5;
+       case 88:        return GHOST_kKeyNumpad6;
+       case 89:        return GHOST_kKeyNumpad7;
+       case 91:        return GHOST_kKeyNumpad8;
+       case 92:        return GHOST_kKeyNumpad9;
+       case 65:        return GHOST_kKeyNumpadPeriod;
+       case 76:        return GHOST_kKeyNumpadEnter;
+       case 69:        return GHOST_kKeyNumpadPlus;
+       case 78:        return GHOST_kKeyNumpadMinus;
+       case 67:        return GHOST_kKeyNumpadAsterisk;
+       case 75:        return GHOST_kKeyNumpadSlash;
+       }
+       
+       if ((asciiCharacter >= 'a') && (asciiCharacter <= 'z')) {
+               return (GHOST_TKey) (asciiCharacter - 'a' + GHOST_kKeyA);
+       } else if ((asciiCharacter >= '0') && (asciiCharacter <= '9')) {
+               return (GHOST_TKey) (asciiCharacter - '0' + GHOST_kKey0);
+       } else if (asciiCharacter==16) {
+               switch (rawCode) {
+               case 122:       return GHOST_kKeyF1;
+               case 120:       return GHOST_kKeyF2;
+               case 99:        return GHOST_kKeyF3;
+               case 118:       return GHOST_kKeyF4;
+               case 96:        return GHOST_kKeyF5;
+               case 97:        return GHOST_kKeyF6;
+               case 98:        return GHOST_kKeyF7;
+               case 100:       return GHOST_kKeyF8;
+               case 101:       return GHOST_kKeyF9;
+               case 109:       return GHOST_kKeyF10;
+               case 103:       return GHOST_kKeyF11;
+               case 111:       return GHOST_kKeyF12;  // FIXME : Never get, is used for ejecting the CD! 
+               }
+       } else {
+               switch (asciiCharacter) {
+               case kUpArrowCharCode:          return GHOST_kKeyUpArrow;
+               case kDownArrowCharCode:        return GHOST_kKeyDownArrow;
+               case kLeftArrowCharCode:        return GHOST_kKeyLeftArrow;
+               case kRightArrowCharCode:       return GHOST_kKeyRightArrow;
+
+               case kReturnCharCode:           return GHOST_kKeyEnter;
+               case kBackspaceCharCode:        return GHOST_kKeyBackSpace;
+               case kDeleteCharCode:           return GHOST_kKeyDelete;
+               case kEscapeCharCode:           return GHOST_kKeyEsc;
+               case kTabCharCode:                      return GHOST_kKeyTab;
+               case kSpaceCharCode:            return GHOST_kKeySpace;
+
+               case kHomeCharCode:             return GHOST_kKeyHome;
+               case kEndCharCode:                      return GHOST_kKeyEnd;
+               case kPageUpCharCode:           return GHOST_kKeyUpPage;
+               case kPageDownCharCode:         return GHOST_kKeyDownPage;
+
+               case '-':       return GHOST_kKeyMinus;
+               case '=':       return GHOST_kKeyEqual;
+               case ',':       return GHOST_kKeyComma;
+               case '.':       return GHOST_kKeyPeriod;
+               case '/':       return GHOST_kKeySlash;
+               case ';':       return GHOST_kKeySemicolon;
+               case '\'':      return GHOST_kKeyQuote;
+               case '\\':      return GHOST_kKeyBackslash;
+               case '[':       return GHOST_kKeyLeftBracket;
+               case ']':       return GHOST_kKeyRightBracket;
+               case '`':       return GHOST_kKeyAccentGrave;
+               }
+       }
+       
+       // printf("GHOST: unknown key: %d %d\n", vk, rawCode);
+       
+       return GHOST_kKeyUnknown;
+}
+
+/* MacOSX returns a Roman charset with kEventParamKeyMacCharCodes
+ * as defined here: http://developer.apple.com/documentation/mac/Text/Text-516.html
+ * I am not sure how international this works...
+ * For cross-platform convention, we'll use the Latin ascii set instead.
+ * As defined at: http://www.ramsch.org/martin/uni/fmi-hp/iso8859-1.html
+ * 
+ */
+static unsigned char convertRomanToLatin(unsigned char ascii)
+{
+
+       if(ascii<128) return ascii;
+       
+       switch(ascii) {
+       case 128:       return 142;
+       case 129:       return 143;
+       case 130:       return 128;
+       case 131:       return 201;
+       case 132:       return 209;
+       case 133:       return 214;
+       case 134:       return 220;
+       case 135:       return 225;
+       case 136:       return 224;
+       case 137:       return 226;
+       case 138:       return 228;
+       case 139:       return 227;
+       case 140:       return 229;
+       case 141:       return 231;
+       case 142:       return 233;
+       case 143:       return 232;
+       case 144:       return 234;
+       case 145:       return 235;
+       case 146:       return 237;
+       case 147:       return 236;
+       case 148:       return 238;
+       case 149:       return 239;
+       case 150:       return 241;
+       case 151:       return 243;
+       case 152:       return 242;
+       case 153:       return 244;
+       case 154:       return 246;
+       case 155:       return 245;
+       case 156:       return 250;
+       case 157:       return 249;
+       case 158:       return 251;
+       case 159:       return 252;
+       case 160:       return 0;
+       case 161:       return 176;
+       case 162:       return 162;
+       case 163:       return 163;
+       case 164:       return 167;
+       case 165:       return 183;
+       case 166:       return 182;
+       case 167:       return 223;
+       case 168:       return 174;
+       case 169:       return 169;
+       case 170:       return 174;
+       case 171:       return 180;
+       case 172:       return 168;
+       case 173:       return 0;
+       case 174:       return 198;
+       case 175:       return 216;
+       case 176:       return 0;
+       case 177:       return 177;
+       case 178:       return 0;
+       case 179:       return 0;
+       case 180:       return 165;
+       case 181:       return 181;
+       case 182:       return 0;
+       case 183:       return 0;
+       case 184:       return 215;
+       case 185:       return 0;
+       case 186:       return 0;
+       case 187:       return 170;
+       case 188:       return 186;
+       case 189:       return 0;
+       case 190:       return 230;
+       case 191:       return 248;
+       case 192:       return 191;
+       case 193:       return 161;
+       case 194:       return 172;
+       case 195:       return 0;
+       case 196:       return 0;
+       case 197:       return 0;
+       case 198:       return 0;
+       case 199:       return 171;
+       case 200:       return 187;
+       case 201:       return 201;
+       case 202:       return 0;
+       case 203:       return 192;
+       case 204:       return 195;
+       case 205:       return 213;
+       case 206:       return 0;
+       case 207:       return 0;
+       case 208:       return 0;
+       case 209:       return 0;
+       case 210:       return 0;
+       
+       case 214:       return 247;
+
+       case 229:       return 194;
+       case 230:       return 202;
+       case 231:       return 193;
+       case 232:       return 203;
+       case 233:       return 200;
+       case 234:       return 205;
+       case 235:       return 206;
+       case 236:       return 207;
+       case 237:       return 204;
+       case 238:       return 211;
+       case 239:       return 212;
+       case 240:       return 0;
+       case 241:       return 210;
+       case 242:       return 218;
+       case 243:       return 219;
+       case 244:       return 217;
+       case 245:       return 0;
+       case 246:       return 0;
+       case 247:       return 0;
+       case 248:       return 0;
+       case 249:       return 0;
+       case 250:       return 0;
+
+       
+               default: return 0;
+       }
+
+}
+
+#define FIRSTFILEBUFLG 512
+static bool g_hasFirstFile = false;
+static char g_firstFileBuf[512];
+
+extern "C" int GHOST_HACK_getFirstFile(char buf[FIRSTFILEBUFLG]) { 
+       if (g_hasFirstFile) {
+               strncpy(buf, g_firstFileBuf, FIRSTFILEBUFLG - 1);
+               buf[FIRSTFILEBUFLG - 1] = '\0';
+               return 1;
+       } else {
+               return 0; 
+       }
+}
+
+
+#pragma mark Cocoa objects
+
+/**
+ * CocoaAppDelegate
+ * ObjC object to capture applicationShouldTerminate, and send quit event
+ **/
+@interface CocoaAppDelegate : NSObject
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
+@end
+
+@implementation CocoaAppDelegate : NSObject
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
+{
+       //Note that Cmd+Q is already handled by keyhandler
+    //FIXME: Cocoa_SendQuit();
+    return NSTerminateCancel;
+}
+@end
+
+
+
+#pragma mark initialization/finalization
+
+/***/
+
+GHOST_SystemCocoa::GHOST_SystemCocoa()
+{
+       m_modifierMask =0;
+       m_pressedMouseButtons =0;
+       m_displayManager = new GHOST_DisplayManagerCocoa ();
+       GHOST_ASSERT(m_displayManager, "GHOST_SystemCocoa::GHOST_SystemCocoa(): m_displayManager==0\n");
+       m_displayManager->initialize();
+
+       //NSEvent timeStamp is given in system uptime, state start date is boot time
+       //FIXME : replace by Cocoa equivalent
+       int mib[2];
+       struct timeval boottime;
+       size_t len;
+       
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_BOOTTIME;
+       len = sizeof(struct timeval);
+       
+       sysctl(mib, 2, &boottime, &len, NULL, 0);
+       m_start_time = ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
+       
+       m_ignoreWindowSizedMessages = false;
+}
+
+GHOST_SystemCocoa::~GHOST_SystemCocoa()
+{
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::init()
+{
+       
+    GHOST_TSuccess success = GHOST_System::init();
+    if (success) {
+               //ProcessSerialNumber psn;
+               
+               //FIXME: Carbon stuff to move window & menu to foreground
+               /*if (!GetCurrentProcess(&psn)) {
+                       TransformProcessType(&psn, kProcessTransformToForegroundApplication);
+                       SetFrontProcess(&psn);
+               }*/
+               
+               autoReleasePool = [[NSAutoreleasePool alloc] init];
+               if (NSApp == nil) {
+                       [NSApplication sharedApplication];
+                       
+                       if ([NSApp mainMenu] == nil) {
+                               //FIXME: CreateApplicationMenus();
+                               printf("Creating main menu");
+                       }
+                       [NSApp finishLaunching];
+               }
+               if ([NSApp delegate] == nil) {
+                       [NSApp setDelegate:[[CocoaAppDelegate alloc] init]];
+               }
+               
+               
+               /*
+         * Initialize the cursor to the standard arrow shape (so that we can change it later on).
+         * This initializes the cursor's visibility counter to 0.
+         */
+        /*::InitCursor();
+               
+               MenuRef windMenu;
+               ::CreateStandardWindowMenu(0, &windMenu);
+               ::InsertMenu(windMenu, 0);
+               ::DrawMenuBar();
+               
+        ::InstallApplicationEventHandler(sEventHandlerProc, GetEventTypeCount(kEvents), kEvents, this, &m_handler);
+               
+               ::AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, sAEHandlerLaunch, (SInt32) this, false);
+               ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, sAEHandlerOpenDocs, (SInt32) this, false);
+               ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, sAEHandlerPrintDocs, (SInt32) this, false);
+               ::AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, sAEHandlerQuit, (SInt32) this, false);
+               */
+    }
+    return success;
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::exit()
+{
+       NSAutoreleasePool* pool = (NSAutoreleasePool *)autoReleasePool;
+       [pool release];
+    return GHOST_System::exit();
+}
+
+#pragma mark window management
+
+GHOST_TUns64 GHOST_SystemCocoa::getMilliSeconds() const
+{
+       //FIXME : replace by Cocoa equivalent
+       int mib[2];
+       struct timeval boottime;
+       size_t len;
+       
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_BOOTTIME;
+       len = sizeof(struct timeval);
+       
+       sysctl(mib, 2, &boottime, &len, NULL, 0);
+
+       return ((boottime.tv_sec*1000)+(boottime.tv_usec/1000));
+}
+
+
+GHOST_TUns8 GHOST_SystemCocoa::getNumDisplays() const
+{
+       //Note that OS X supports monitor hot plug
+       // We do not support multiple monitors at the moment
+       return [[NSScreen screens] count];
+}
+
+
+void GHOST_SystemCocoa::getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const
+{
+       //TODO: Provide visible frame or total frame, check for consistency with rest of code
+       NSRect frame = [[NSScreen mainScreen] visibleFrame];
+       
+       width = frame.size.width;
+       height = frame.size.height;
+}
+
+
+GHOST_IWindow* GHOST_SystemCocoa::createWindow(
+       const STR_String& title, 
+       GHOST_TInt32 left,
+       GHOST_TInt32 top,
+       GHOST_TUns32 width,
+       GHOST_TUns32 height,
+       GHOST_TWindowState state,
+       GHOST_TDrawingContextType type,
+       bool stereoVisual,
+       const GHOST_TEmbedderWindowID parentWindow
+)
+{
+    GHOST_IWindow* window = 0;
+
+       window = new GHOST_WindowCocoa (title, left, top, width, height, state, type);
+
+    if (window) {
+        if (window->getValid()) {
+            // Store the pointer to the window 
+            GHOST_ASSERT(m_windowManager, "m_windowManager not initialized");
+            m_windowManager->addWindow(window);
+            m_windowManager->setActiveWindow(window);
+            pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window));
+        }
+        else {
+                       GHOST_PRINT("GHOST_SystemCocoa::createWindow(): window invalid\n");
+            delete window;
+            window = 0;
+        }
+    }
+       else {
+               GHOST_PRINT("GHOST_SystemCocoa::createWindow(): could not create window\n");
+       }
+    return window;
+}
+
+GHOST_TSuccess GHOST_SystemCocoa::beginFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow** window, const bool stereoVisual)
+{      
+       GHOST_TSuccess success = GHOST_kFailure;
+
+       //TODO: update this method
+       // need yo make this Carbon all on 10.5 for fullscreen to work correctly
+       CGCaptureAllDisplays();
+       
+       success = GHOST_System::beginFullScreen( setting, window, stereoVisual);
+       
+       if( success != GHOST_kSuccess ) {
+                       // fullscreen failed for other reasons, release
+                       CGReleaseAllDisplays(); 
+       }
+
+       return success;
+}
+
+GHOST_TSuccess GHOST_SystemCocoa::endFullScreen(void)
+{      
+       //TODO: update this method
+       CGReleaseAllDisplays();
+       return GHOST_System::endFullScreen();
+}
+
+
+       
+
+GHOST_TSuccess GHOST_SystemCocoa::getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const
+{
+    NSPoint mouseLoc = [NSEvent mouseLocation];
+       
+    // Convert the coordinates to screen coordinates
+    x = (GHOST_TInt32)mouseLoc.x;
+    y = (GHOST_TInt32)mouseLoc.y;
+    return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y) const
+{
+       float xf=(float)x, yf=(float)y;
+       //TODO:cocoatize this
+       CGAssociateMouseAndMouseCursorPosition(false);
+       CGSetLocalEventsSuppressionInterval(0);
+       CGWarpMouseCursorPosition(CGPointMake(xf, yf));
+       CGAssociateMouseAndMouseCursorPosition(true);
+
+//this doesn't work properly, see game engine mouse-look scripts
+//     CGWarpMouseCursorPosition(CGPointMake(xf, yf));
+       // this call below sends event, but empties other events (like shift)
+       // CGPostMouseEvent(CGPointMake(xf, yf), TRUE, 1, FALSE, 0);
+
+    return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_SystemCocoa::getModifierKeys(GHOST_ModifierKeys& keys) const
+{
+    NSUInteger modifiers = [[NSApp currentEvent] modifierFlags];
+       //Direct query to modifierFlags can be used in 10.6
+
+    keys.set(GHOST_kModifierKeyCommand, (modifiers & NSCommandKeyMask) ? true : false);
+    keys.set(GHOST_kModifierKeyLeftAlt, (modifiers & NSAlternateKeyMask) ? true : false);
+    keys.set(GHOST_kModifierKeyLeftShift, (modifiers & NSShiftKeyMask) ? true : false);
+    keys.set(GHOST_kModifierKeyLeftControl, (modifiers & NSControlKeyMask) ? true : false);
+       
+    return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons& buttons) const
+{
+       buttons.clear();
+    buttons.set(GHOST_kButtonMaskLeft, m_pressedMouseButtons & GHOST_kButtonMaskLeft);
+       buttons.set(GHOST_kButtonMaskRight, m_pressedMouseButtons & GHOST_kButtonMaskRight);
+       buttons.set(GHOST_kButtonMaskMiddle, m_pressedMouseButtons & GHOST_kButtonMaskMiddle);
+       buttons.set(GHOST_kButtonMaskButton4, m_pressedMouseButtons & GHOST_kButtonMaskButton4);
+       buttons.set(GHOST_kButtonMaskButton5, m_pressedMouseButtons & GHOST_kButtonMaskButton5);
+    return GHOST_kSuccess;
+}
+
+
+
+#pragma mark Event handlers
+
+/**
+ * The event queue polling function
+ */
+bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
+{
+       bool anyProcessed = false;
+       NSEvent *event;
+       
+       //      SetMouseCoalescingEnabled(false, NULL);
+       //TODO : implement timer ??
+       
+       do {
+               //GHOST_TimerManager* timerMgr = getTimerManager();
+               /*
+                if (waitForEvent) {
+                GHOST_TUns64 next = timerMgr->nextFireTime();
+                double timeOut;
+                
+                if (next == GHOST_kFireTimeNever) {
+                timeOut = kEventDurationForever;
+                } else {
+                timeOut = (double)(next - getMilliSeconds())/1000.0;
+                if (timeOut < 0.0)
+                timeOut = 0.0;
+                }
+                
+                ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
+                }
+                
+                if (timerMgr->fireTimers(getMilliSeconds())) {
+                anyProcessed = true;
+                }
+                
+                //TODO: check fullscreen redrawing issues
+                if (getFullScreen()) {
+                // Check if the full-screen window is dirty
+                GHOST_IWindow* window = m_windowManager->getFullScreenWindow();
+                if (((GHOST_WindowCarbon*)window)->getFullScreenDirty()) {
+                pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
+                anyProcessed = true;
+                }
+                }*/
+               
+               do {
+                       event = [NSApp nextEventMatchingMask:NSAnyEventMask
+                                                                          untilDate:[NSDate distantPast]
+                                                                                 inMode:NSDefaultRunLoopMode
+                                                                                dequeue:YES];
+                       if (event==nil)
+                               break;
+                       
+                       anyProcessed = true;
+                       
+                       switch ([event type]) {
+                               case NSKeyDown:
+                               case NSKeyUp:
+                               case NSFlagsChanged:
+                                       handleKeyEvent(event);
+                                       
+                                       /* Support system-wide keyboard shortcuts, like Exposé, ...) */
+                                       /*              if (([event modifierFlags] & NSCommandKeyMask) || [event type] == NSFlagsChanged) {
+                                        [NSApp sendEvent:event];
+                                        }*/
+                                       break;
+                                       
+                               case NSLeftMouseDown:
+                               case NSLeftMouseUp:
+                               case NSRightMouseDown:
+                               case NSRightMouseUp:
+                               case NSMouseMoved:
+                               case NSLeftMouseDragged:
+                               case NSRightMouseDragged:
+                               case NSScrollWheel:
+                               case NSOtherMouseDown:
+                               case NSOtherMouseUp:
+                               case NSOtherMouseDragged:                               
+                                       handleMouseEvent(event);
+                                       break;
+                                       
+                               case NSTabletPoint:
+                               case NSTabletProximity:
+                                       handleTabletEvent(event);
+                                       break;
+                                       
+                                       /* Trackpad features, will need OS X 10.6 for implementation
+                                        case NSEventTypeGesture:
+                                        case NSEventTypeMagnify:
+                                        case NSEventTypeSwipe:
+                                        case NSEventTypeRotate:
+                                        case NSEventTypeBeginGesture:
+                                        case NSEventTypeEndGesture:
+                                        break; */
+                                       
+                                       /*Unused events
+                                        NSMouseEntered       = 8,
+                                        NSMouseExited        = 9,
+                                        NSAppKitDefined      = 13,
+                                        NSSystemDefined      = 14,
+                                        NSApplicationDefined = 15,
+                                        NSPeriodic           = 16,
+                                        NSCursorUpdate       = 17,*/
+                                       
+                               default:
+                                       break;
+                       }
+                       //Resend event to NSApp to ensure Mac wide events are handled
+                       [NSApp sendEvent:event];
+               } while (event!= nil);          
+       } while (waitForEvent && !anyProcessed);
+       
+    return anyProcessed;
+}
+
+//TODO: To be called from NSWindow delegate
+int GHOST_SystemCocoa::handleWindowEvent(void *eventPtr)
+{
+       int err = eventNotHandledErr;
+       /*WindowRef windowRef;
+       GHOST_WindowCocoa *window;
+       
+       // Check if the event was send to a GHOST window
+       ::GetEventParameter(event, kEventParamDirectObject, typeWindowRef, NULL, sizeof(WindowRef), NULL, &windowRef);
+       window = (GHOST_WindowCarbon*) ::GetWRefCon(windowRef);
+       if (!validWindow(window)) {
+               return err;
+       }
+
+       //if (!getFullScreen()) {
+               err = noErr;
+               switch([event ]) 
+               {
+                       case kEventWindowClose:
+                               pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window) );
+                               break;
+                       case kEventWindowActivated:
+                               m_windowManager->setActiveWindow(window);
+                               window->loadCursor(window->getCursorVisibility(), window->getCursorShape());
+                               pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window) );
+                               break;
+                       case kEventWindowDeactivated:
+                               m_windowManager->setWindowInactive(window);
+                               pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window) );
+                               break;
+                       case kEventWindowUpdate:
+                               //if (getFullScreen()) GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen update event\n");
+                               pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window) );
+                               break;
+                       case kEventWindowBoundsChanged:
+                               if (!m_ignoreWindowSizedMessages)
+                               {
+                                       window->updateDrawingContext();
+                                       pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window) );
+                               }
+                               break;
+                       default:
+                               err = eventNotHandledErr;
+                               break;
+               }
+//     }
+       //else {
+               //window = (GHOST_WindowCarbon*) m_windowManager->getFullScreenWindow();
+               //GHOST_PRINT("GHOST_SystemCarbon::handleWindowEvent(): full-screen window event, " << window << "\n");
+               //::RemoveEventFromQueue(::GetMainEventQueue(), event);
+       //}
+       */
+       return err;
+}
+
+int GHOST_SystemCocoa::handleTabletEvent(void *eventPtr)
+{
+       NSEvent *event = (NSEvent *)eventPtr;
+       GHOST_IWindow* window = m_windowManager->getActiveWindow();
+       GHOST_TabletData& ct=((GHOST_WindowCocoa*)window)->GetCocoaTabletData();
+       
+       ct.Pressure = 0;
+       ct.Xtilt = 0;
+       ct.Ytilt = 0;
+       
+       
+       switch ([event type]) {
+               case NSTabletPoint:
+                       ct.Pressure = [event tangentialPressure];
+                       ct.Xtilt = [event tilt].x;
+                       ct.Ytilt = [event tilt].y;
+                       break;
+               
+               case NSTabletProximity:
+                       if ([event isEnteringProximity])
+                       {
+                               //pointer is entering tablet area proximity
+                               switch ([event pointingDeviceType]) {
+                                       case NSPenPointingDevice:
+                                               ct.Active = GHOST_kTabletModeStylus;
+                                               break;
+                                       case NSEraserPointingDevice:
+                                               ct.Active = GHOST_kTabletModeEraser;
+                                               break;
+                                       case NSCursorPointingDevice:
+                                       case NSUnknownPointingDevice:
+                                       default:
+                                               ct.Active = GHOST_kTabletModeNone;
+                                               break;
+                               }
+                       } else {
+                               // pointer is leaving - return to mouse
+                               ct.Active = GHOST_kTabletModeNone;
+                       }
+                       break;
+               
+               default:
+                       GHOST_ASSERT(FALSE,"GHOST_SystemCocoa::handleTabletEvent : unknown event received");
+                       break;
+       }
+       return noErr;
+}
+
+
+int GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
+{
+       NSEvent *event = (NSEvent *)eventPtr;
+    GHOST_IWindow* window = m_windowManager->getActiveWindow();
+                       
+       switch ([event type])
+    {
+                       //TODO: check for tablet subtype events
+               case NSLeftMouseDown:
+               case NSRightMouseDown:
+               case NSOtherMouseDown:
+                       if (m_windowManager->getActiveWindow()) {
+                               pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
+                       }
+                       break;
+                                               
+               case NSLeftMouseUp:
+               case NSRightMouseUp:
+               case NSOtherMouseUp:
+                       if (m_windowManager->getActiveWindow()) {
+                               pushEvent(new GHOST_EventButton([event timestamp], GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
+                       }
+                       break;
+                       
+               case NSMouseMoved:
+               case NSLeftMouseDragged:
+               case NSRightMouseDragged:
+               case NSOtherMouseDragged:                               
+                       {
+                               NSPoint mousePos = [event locationInWindow];
+                               pushEvent(new GHOST_EventCursor([event timestamp], GHOST_kEventCursorMove, window, mousePos.x, mousePos.y));
+                               break;
+                       }
+                       
+               case NSScrollWheel:
+                       {
+                               GHOST_TInt32 delta;
+                               delta = [event deltaY] > 0 ? 1 : -1;
+                               pushEvent(new GHOST_EventWheel(getMilliSeconds(), window, delta));
+
+                       }
+                       break;
+               }
+       
+       return noErr;
+}
+
+
+int GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
+{
+       NSEvent *event = (NSEvent *)eventPtr;
+       OSStatus err = eventNotHandledErr;
+       GHOST_IWindow* window = m_windowManager->getActiveWindow();
+       NSUInteger modifiers;
+       unsigned short rawCode;
+       GHOST_TKey key;
+       unsigned char ascii;
+
+       /* Can happen, very rarely - seems to only be when command-H makes
+        * the window go away and we still get an HKey up. 
+        */
+       if (!window) {
+               //::GetEventParameter(event, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &rawCode);
+               //key = convertKey(rawCode);
+               return err;
+       }
+       
+       err = noErr;
+       switch ([event type]) {
+               case NSKeyDown:
+               case NSKeyUp:
+                       rawCode = [event keyCode];
+                       ascii = [[event characters] characterAtIndex:0];
+       
+                       key = convertKey(rawCode,ascii);
+                       ascii= convertRomanToLatin(ascii);
+                       
+                       if ([event type] == NSKeyDown) {
+                               pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyDown, window, key, ascii) );
+                               } else {
+                                       pushEvent( new GHOST_EventKey([event timestamp], GHOST_kEventKeyUp, window, key, ascii) );
+                               }
+                       break;
+       
+               case NSFlagsChanged: 
+                       modifiers = [event modifierFlags];
+                       if ((modifiers & NSShiftKeyMask) != (m_modifierMask & NSShiftKeyMask)) {
+                               pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSShiftKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftShift) );
+                       }
+                       if ((modifiers & NSControlKeyMask) != (m_modifierMask & NSControlKeyMask)) {
+                               pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSControlKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftControl) );
+                       }
+                       if ((modifiers & NSAlternateKeyMask) != (m_modifierMask & NSAlternateKeyMask)) {
+                               pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSAlternateKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyLeftAlt) );
+                       }
+                       if ((modifiers & NSCommandKeyMask) != (m_modifierMask & NSCommandKeyMask)) {
+                               pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSCommandKeyMask)?GHOST_kEventKeyDown:GHOST_kEventKeyUp, window, GHOST_kKeyCommand) );
+                       }
+                       
+                       m_modifierMask = modifiers;
+                       break;
+                       
+               default:
+                       err = eventNotHandledErr;
+                       break;
+       }
+       
+       return err;
+}
+
+
+/* System wide mouse clicks are handled directly through systematic event forwarding to Cocoa
+bool GHOST_SystemCarbon::handleMouseDown(void *eventPtr)
+{
+       NSEvent *event = (NSEvent *)eventPtr;
+       WindowPtr                       window;
+       short                           part;
+       BitMap                          screenBits;
+    bool                               handled = true;
+    GHOST_WindowCarbon* ghostWindow;
+    Point                              mousePos = {0 , 0};
+       
+       ::GetEventParameter(event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &mousePos);
+       
+       part = ::FindWindow(mousePos, &window);
+       ghostWindow = (GHOST_WindowCarbon*) ::GetWRefCon(window);
+       
+       switch (part) {
+               case inMenuBar:
+                       handleMenuCommand(::MenuSelect(mousePos));
+                       break;
+                       
+               case inDrag:
+                       // *
+                       // * The DragWindow() routine creates a lot of kEventWindowBoundsChanged
+                       // * events. By setting m_ignoreWindowSizedMessages these are suppressed.
+                       // * @see GHOST_SystemCarbon::handleWindowEvent(EventRef event)
+                       // *
+                       // even worse: scale window also generates a load of events, and nothing 
+                        //  is handled (read: client's event proc called) until you release mouse (ton) 
+                       
+                       GHOST_ASSERT(validWindow(ghostWindow), "GHOST_SystemCarbon::handleMouseDown: invalid window");
+                       m_ignoreWindowSizedMessages = true;
+                       ::DragWindow(window, mousePos, &GetQDGlobalsScreenBits(&screenBits)->bounds);
+                       m_ignoreWindowSizedMessages = false;
+                       
+                       pushEvent( new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, ghostWindow) );
+
+                       break;
+               
+               case inContent:
+                       if (window != ::FrontWindow()) {
+                               ::SelectWindow(window);
+                               //
+                               // * We add a mouse down event on the newly actived window
+                               // *            
+                               //GHOST_PRINT("GHOST_SystemCarbon::handleMouseDown(): adding mouse down event, " << ghostWindow << "\n");
+                               EventMouseButton button;
+                               ::GetEventParameter(event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(button), NULL, &button);
+                               pushEvent(new GHOST_EventButton(getMilliSeconds(), GHOST_kEventButtonDown, ghostWindow, convertButton(button)));
+                       } else {
+                               handled = false;
+                       }
+                       break;
+                       
+               case inGoAway:
+                       GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+                       if (::TrackGoAway(window, mousePos))
+                       {
+                               // todo: add option-close, because itÿs in the HIG
+                               // if (event.modifiers & optionKey) {
+                                       // Close the clean documents, others will be confirmed one by one.
+                               //}
+                               // else {
+                               pushEvent(new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, ghostWindow));
+                               //}
+                       }
+                       break;
+                       
+               case inGrow:
+                       GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+                       ::ResizeWindow(window, mousePos, NULL, NULL);
+                       break;
+                       
+               case inZoomIn:
+               case inZoomOut:
+                       GHOST_ASSERT(ghostWindow, "GHOST_SystemCarbon::handleMouseEvent: ghostWindow==0");
+                       if (::TrackBox(window, mousePos, part)) {
+                               int macState;
+                               
+                               macState = ghostWindow->getMac_windowState();
+                               if ( macState== 0)
+                                       ::ZoomWindow(window, part, true);
+                               else 
+                                       if (macState == 2) { // always ok
+                                                       ::ZoomWindow(window, part, true);
+                                                       ghostWindow->setMac_windowState(1);
+                                       } else { // need to force size again
+                                       //      GHOST_TUns32 scr_x,scr_y; //unused
+                                               Rect outAvailableRect;
+                                               
+                                               ghostWindow->setMac_windowState(2);
+                                               ::GetAvailableWindowPositioningBounds ( GetMainDevice(), &outAvailableRect);
+                                               
+                                               //this->getMainDisplayDimensions(scr_x,scr_y);
+                                               ::SizeWindow (window, outAvailableRect.right-outAvailableRect.left,outAvailableRect.bottom-outAvailableRect.top-1,false);
+                                               ::MoveWindow (window, outAvailableRect.left, outAvailableRect.top,true);
+                                       }
+                               
+                       }
+                       break;
+
+               default:
+                       handled = false;
+                       break;
+       }
+       
+       return handled;
+}
+
+
+bool GHOST_SystemCarbon::handleMenuCommand(GHOST_TInt32 menuResult)
+{
+       short           menuID;
+       short           menuItem;
+       UInt32          command;
+       bool            handled;
+       OSErr           err;
+       
+       menuID = HiWord(menuResult);
+       menuItem = LoWord(menuResult);
+
+       err = ::GetMenuItemCommandID(::GetMenuHandle(menuID), menuItem, &command);
+
+       handled = false;
+       
+       if (err || command == 0) {
+       }
+       else {
+               switch(command) {
+               }
+       }
+
+       ::HiliteMenu(0);
+    return handled;
+}*/
+
+
+
+#pragma mark Clipboard get/set
+
+GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const
+{
+       GHOST_TUns8 * temp_buff;
+       size_t pastedTextSize;  
+       
+       NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
+       
+       if (pasteBoard = nil) {
+               return NULL;
+       }
+       
+       NSArray *supportedTypes =
+               [NSArray arrayWithObjects: @"public.utf8-plain-text", nil];
+       
+       NSString *bestType = [[NSPasteboard generalPasteboard]
+                                                 availableTypeFromArray:supportedTypes];
+       
+       if (bestType == nil) { return NULL; }
+       
+       NSString * textPasted = [pasteBoard stringForType:@"public.utf8-plain-text"];
+
+       pastedTextSize = [textPasted lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+       
+       temp_buff = (GHOST_TUns8*) malloc(pastedTextSize+1); 
+
+       if (temp_buff == NULL) return NULL;
+       
+       strncpy((char*)temp_buff, [textPasted UTF8String], pastedTextSize);
+       
+       temp_buff[pastedTextSize] = '\0';
+       
+       if(temp_buff) {
+               return temp_buff;
+       } else {
+               return NULL;
+       }
+}
+
+void GHOST_SystemCocoa::putClipboard(GHOST_TInt8 *buffer, bool selection) const
+{
+       NSString *textToCopy;
+       
+       if(selection) {return;} // for copying the selection, used on X11
+
+       
+       NSPasteboard *pasteBoard = [NSPasteboard generalPasteboard];
+       
+       if (pasteBoard = nil) {
+               return;
+       }
+       
+       NSArray *supportedTypes = [NSArray arrayWithObjects: @"public.utf8-plain-text",nil];
+       
+       [pasteBoard declareTypes:supportedTypes owner:nil];
+       
+       textToCopy = [NSString stringWithUTF8String:buffer];
+       
+       [pasteBoard setString:textToCopy forType:@"public.utf8-plain-text"];
+       
+}
+
+#pragma mark Carbon stuff to remove
+
+#ifdef WITH_CARBON
+
+
+OSErr GHOST_SystemCarbon::sAEHandlerLaunch(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+       //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+       
+       return noErr;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerOpenDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+       //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+       AEDescList docs;
+       SInt32 ndocs;
+       OSErr err;
+       
+       err = AEGetParamDesc(event, keyDirectObject, typeAEList, &docs);
+       if (err != noErr)  return err;
+       
+       err = AECountItems(&docs, &ndocs);
+       if (err==noErr) {
+               int i;
+               
+               for (i=0; i<ndocs; i++) {
+                       FSSpec fss;
+                       AEKeyword kwd;
+                       DescType actType;
+                       Size actSize;
+                       
+                       err = AEGetNthPtr(&docs, i+1, typeFSS, &kwd, &actType, &fss, sizeof(fss), &actSize);
+                       if (err!=noErr)
+                               break;
+                       
+                       if (i==0) {
+                               FSRef fsref;
+                               
+                               if (FSpMakeFSRef(&fss, &fsref)!=noErr)
+                                       break;
+                               if (FSRefMakePath(&fsref, (UInt8*) g_firstFileBuf, sizeof(g_firstFileBuf))!=noErr)
+                                       break;
+                               
+                               g_hasFirstFile = true;
+                       }
+               }
+       }
+       
+       AEDisposeDesc(&docs);
+       
+       return err;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerPrintDocs(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+       //GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+       
+       return noErr;
+}
+
+OSErr GHOST_SystemCarbon::sAEHandlerQuit(const AppleEvent *event, AppleEvent *reply, SInt32 refCon)
+{
+       GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) refCon;
+       
+       sys->pushEvent( new GHOST_Event(sys->getMilliSeconds(), GHOST_kEventQuit, NULL) );
+       
+       return noErr;
+}
+
+OSStatus GHOST_SystemCarbon::sEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData)
+{
+       GHOST_SystemCarbon* sys = (GHOST_SystemCarbon*) userData;
+    OSStatus err = eventNotHandledErr;
+       GHOST_IWindow* window;
+       GHOST_TEventNDOFData data;
+       UInt32 kind;
+       
+    switch (::GetEventClass(event))
+    {
+               case kEventClassAppleEvent:
+                       EventRecord eventrec;
+                       if (ConvertEventRefToEventRecord(event, &eventrec)) {
+                               err = AEProcessAppleEvent(&eventrec);
+                       }
+                       break;
+        case kEventClassMouse:
+            err = sys->handleMouseEvent(event);
+            break;
+               case kEventClassWindow:
+                       err = sys->handleWindowEvent(event);
+                       break;
+               case kEventClassKeyboard:
+                       err = sys->handleKeyEvent(event);
+                       break;
+               case kEventClassBlender :
+                       window = sys->m_windowManager->getActiveWindow();
+                       sys->m_ndofManager->GHOST_NDOFGetDatas(data);
+                       kind = ::GetEventKind(event);
+                       
+                       switch (kind)
+               {
+                       case 1:
+                               sys->m_eventManager->pushEvent(new GHOST_EventNDOF(sys->getMilliSeconds(), GHOST_kEventNDOFMotion, window, data));
+                               //                              printf("motion\n");
+                               break;
+                       case 2:
+                               sys->m_eventManager->pushEvent(new GHOST_EventNDOF(sys->getMilliSeconds(), GHOST_kEventNDOFButton, window, data));
+                               //                                      printf("button\n");
+                               break;
+               }
+                       err = noErr;
+                       break;
+               default : 
+                       ;
+                       break;
+       }
+       
+    return err;
+}
+#endif
\ No newline at end of file
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
new file mode 100644 (file)
index 0000000..1a00385
--- /dev/null
@@ -0,0 +1,308 @@
+/**
+ * $Id: GHOST_WindowCocoa.h 13161 2008-01-07 19:13:47Z hos $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+/**
+ * @file       GHOST_WindowCocoa.h
+ * Declaration of GHOST_WindowCocoa class.
+ */
+
+#ifndef _GHOST_WINDOW_COCOA_H_
+#define _GHOST_WINDOW_COCOA_H_
+
+#ifndef __APPLE__
+#error Apple OSX only!
+#endif // __APPLE__
+
+#include "GHOST_Window.h"
+#include "STR_String.h"
+
+#include <AGL/agl.h>
+
+
+/**
+ * Window on Mac OSX/Cocoa.
+ * Carbon windows have a size widget in the lower right corner of the window.
+ * To force it to be visible, the height of the client rectangle is reduced so
+ * that applications do not draw in that area. GHOST will manage that area
+ * which is called the gutter.
+ * When OpenGL contexts are active, GHOST will use AGL_BUFFER_RECT to prevent
+ * OpenGL drawing outside the reduced client rectangle.
+ * @author     Maarten Gribnau
+ * @date       May 23, 2001
+ */
+class GHOST_WindowCocoa : public GHOST_Window {
+public:
+       /**
+        * Constructor.
+        * Creates a new window and opens it.
+        * To check if the window was created properly, use the getValid() method.
+        * @param title         The text shown in the title bar of the window.
+        * @param left          The coordinate of the left edge of the window.
+        * @param top           The coordinate of the top edge of the window.
+        * @param width         The width the window.
+        * @param height        The height the window.
+        * @param state         The state the window is initially opened with.
+        * @param type          The type of drawing context installed in this window.
+        * @param stereoVisual  Stereo visual for quad buffered stereo.
+        */
+       GHOST_WindowCocoa(
+               const STR_String& title,
+               GHOST_TInt32 left,
+               GHOST_TInt32 top,
+               GHOST_TUns32 width,
+               GHOST_TUns32 height,
+               GHOST_TWindowState state,
+               GHOST_TDrawingContextType type = GHOST_kDrawingContextTypeNone,
+               const bool stereoVisual = false
+       );
+
+       /**
+        * Destructor.
+        * Closes the window and disposes resources allocated.
+        */
+       virtual ~GHOST_WindowCocoa();
+
+       /**
+        * Returns indication as to whether the window is valid.
+        * @return The validity of the window.
+        */
+       virtual bool getValid() const;
+
+       /**
+        * Sets the title displayed in the title bar.
+        * @param title The title to display in the title bar.
+        */
+       virtual void setTitle(const STR_String& title);
+
+       /**
+        * Returns the title displayed in the title bar.
+        * @param title The title displayed in the title bar.
+        */
+       virtual void getTitle(STR_String& title) const;
+
+       /**
+        * Returns the window rectangle dimensions.
+        * The dimensions are given in screen coordinates that are relative to the upper-left corner of the screen. 
+        * @param bounds The bounding rectangle of the window.
+        */
+       virtual void getWindowBounds(GHOST_Rect& bounds) const;
+       
+       /**
+        * Returns the client rectangle dimensions.
+        * The left and top members of the rectangle are always zero.
+        * @param bounds The bounding rectangle of the cleient area of the window.
+        */
+       virtual void getClientBounds(GHOST_Rect& bounds) const;
+
+       /**
+        * Resizes client rectangle width.
+        * @param width The new width of the client area of the window.
+        */
+       virtual GHOST_TSuccess setClientWidth(GHOST_TUns32 width);
+
+       /**
+        * Resizes client rectangle height.
+        * @param height The new height of the client area of the window.
+        */
+       virtual GHOST_TSuccess setClientHeight(GHOST_TUns32 height);
+
+       /**
+        * Resizes client rectangle.
+        * @param width         The new width of the client area of the window.
+        * @param height        The new height of the client area of the window.
+        */
+       virtual GHOST_TSuccess setClientSize(GHOST_TUns32 width, GHOST_TUns32 height);
+
+       /**
+        * Returns the state of the window (normal, minimized, maximized).
+        * @return The state of the window.
+        */
+       virtual GHOST_TWindowState getState() const;
+
+       /**
+        * Converts a point in screen coordinates to client rectangle coordinates
+        * @param inX   The x-coordinate on the screen.
+        * @param inY   The y-coordinate on the screen.
+        * @param outX  The x-coordinate in the client rectangle.
+        * @param outY  The y-coordinate in the client rectangle.
+        */
+       virtual void screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+       /**
+        * Converts a point in screen coordinates to client rectangle coordinates
+        * @param inX   The x-coordinate in the client rectangle.
+        * @param inY   The y-coordinate in the client rectangle.
+        * @param outX  The x-coordinate on the screen.
+        * @param outY  The y-coordinate on the screen.
+        */
+       virtual void clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const;
+
+       /**
+        * Sets the state of the window (normal, minimized, maximized).
+        * @param state The state of the window.
+        * @return Indication of success.
+        */
+       virtual GHOST_TSuccess setState(GHOST_TWindowState state);
+
+       /**
+        * Sets the order of the window (bottom, top).
+        * @param order The order of the window.
+        * @return Indication of success.
+        */
+       virtual GHOST_TSuccess setOrder(GHOST_TWindowOrder order);
+
+       /**
+        * Swaps front and back buffers of a window.
+        * @return      A boolean success indicator.
+        */
+       virtual GHOST_TSuccess swapBuffers();
+
+       /**
+        * Updates the drawing context of this window. Needed
+        * whenever the window is changed.
+        * @return Indication of success.
+        */
+       GHOST_TSuccess updateDrawingContext();
+
+       /**
+        * Activates the drawing context of this window.
+        * @return      A boolean success indicator.
+        */
+       virtual GHOST_TSuccess activateDrawingContext();
+
+       virtual void loadCursor(bool visible, GHOST_TStandardCursor cursor) const;
+    
+    /**
+     * Returns the dirty state of the window when in full-screen mode.
+     * @return Whether it is dirty.
+     */
+    virtual bool getFullScreenDirty();
+
+               /* accessor for fullscreen window */
+       virtual void setMac_windowState(short value);
+       virtual short getMac_windowState();
+
+
+       const GHOST_TabletData* GetTabletData()
+       { return &m_tablet; }
+
+       GHOST_TabletData& GetCocoaTabletData()
+       { return m_tablet; }
+protected:
+       /**
+        * Tries to install a rendering context in this window.
+        * @param type  The type of rendering context installed.
+        * @return Indication as to whether installation has succeeded.
+        */
+       virtual GHOST_TSuccess installDrawingContext(GHOST_TDrawingContextType type);
+
+       /**
+        * Removes the current drawing context.
+        * @return Indication as to whether removal has succeeded.
+        */
+       virtual GHOST_TSuccess removeDrawingContext();
+    
+       /**
+        * Invalidates the contents of this window.
+         * @return Indication of success.
+        */
+       virtual GHOST_TSuccess invalidate();
+
+       /**
+        * Sets the cursor visibility on the window using
+        * native window system calls.
+        */
+       virtual GHOST_TSuccess setWindowCursorVisibility(bool visible);
+       
+       /**
+        * Sets the cursor shape on the window using
+        * native window system calls.
+        */
+       virtual GHOST_TSuccess setWindowCursorShape(GHOST_TStandardCursor shape);
+
+       /**
+        * Sets the cursor shape on the window using
+        * native window system calls.
+        */
+       virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
+                                       int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color);
+                                       
+       virtual GHOST_TSuccess setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], GHOST_TUns8 mask[16][2], int hotX, int hotY);
+    
+    /**
+     * Converts a string object to a Mac Pascal string.
+     * @param in       The string object to be converted.
+     * @param out      The converted string.
+     */
+    virtual void gen2mac(const STR_String& in, Str255 out) const;
+
+    /**
+     * Converts a Mac Pascal string to a string object.
+     * @param in       The string to be converted.
+     * @param out      The converted string object.
+     */
+    virtual void mac2gen(const Str255 in, STR_String& out) const;
+       
+    WindowRef m_windowRef;
+    CGrafPtr m_grafPtr;
+    AGLContext m_aglCtx;
+
+       /** The first created OpenGL context (for sharing display lists) */
+       static AGLContext s_firstaglCtx;
+               
+       Cursor* m_customCursor;
+
+       GHOST_TabletData m_tablet;
+    
+    /** When running in full-screen this tells whether to refresh the window. */
+    bool m_fullScreenDirty;
+       
+       /** specific MacOs X full screen window setting as we use partially system mechanism 
+           values :      0       not maximizable default
+                             1       normal state
+                                         2               maximized state
+       
+            this will be reworked when rebuilding GHOST carbon to use new OS X apis 
+               in order to be unified with GHOST fullscreen/maximised settings
+                
+                (lukep)
+    **/
+                
+       short mac_windowState;
+       
+
+    /**
+     * The width/height of the size rectangle in the lower right corner of a 
+     * Mac/Carbon window. This is also the height of the gutter area.
+     */
+#ifdef GHOST_DRAW_CARBON_GUTTER
+    static const GHOST_TInt32 s_sizeRectSize;
+#endif // GHOST_DRAW_CARBON_GUTTER
+};
+
+#endif // _GHOST_WINDOW_COCOA_H_
+
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
new file mode 100644 (file)
index 0000000..8318fd5
--- /dev/null
@@ -0,0 +1,747 @@
+/**
+ * $Id: GHOST_WindowCocoa.mm 23275 2009-09-16 15:55:00Z campbellbarton $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id: GHOST_WindowCocoa.mm 23275 2009-09-16 15:55:00Z campbellbarton $
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * @author     Maarten Gribnau
+ * @date       May 10, 2001
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <Carbon/Carbon.h>
+
+#include "GHOST_WindowCocoa.h"
+#include "GHOST_Debug.h"
+
+AGLContext GHOST_WindowCocoa::s_firstaglCtx = NULL;
+#ifdef GHOST_DRAW_CARBON_GUTTER
+const GHOST_TInt32 GHOST_WindowCocoa::s_sizeRectSize = 16;
+#endif //GHOST_DRAW_CARBON_GUTTER
+
+static const GLint sPreferredFormatWindow[8] = {
+AGL_RGBA,
+AGL_DOUBLEBUFFER,      
+AGL_ACCELERATED,
+AGL_DEPTH_SIZE,                32,
+AGL_NONE,
+};
+
+static const GLint sPreferredFormatFullScreen[9] = {
+AGL_RGBA,
+AGL_DOUBLEBUFFER,
+AGL_ACCELERATED,
+AGL_FULLSCREEN,
+AGL_DEPTH_SIZE,                32,
+AGL_NONE,
+};
+
+
+
+WindowRef ugly_hack=NULL;
+
+const EventTypeSpec    kWEvents[] = {
+       { kEventClassWindow, kEventWindowZoom },  /* for new zoom behaviour */ 
+};
+
+static OSStatus myWEventHandlerProc(EventHandlerCallRef handler, EventRef event, void* userData) {
+       WindowRef mywindow;
+       GHOST_WindowCocoa *ghost_window;
+       OSStatus err;
+       int theState;
+       
+       if (::GetEventKind(event) == kEventWindowZoom) {
+               err =  ::GetEventParameter (event,kEventParamDirectObject,typeWindowRef,NULL,sizeof(mywindow),NULL, &mywindow);
+               ghost_window = (GHOST_WindowCocoa *) GetWRefCon(mywindow);
+               theState = ghost_window->getMac_windowState();
+               if (theState == 1) 
+                       ghost_window->setMac_windowState(2);
+               else if (theState == 2)
+                       ghost_window->setMac_windowState(1);
+
+       }
+       return eventNotHandledErr;
+}
+
+GHOST_WindowCocoa::GHOST_WindowCocoa(
+       const STR_String& title,
+       GHOST_TInt32 left,
+       GHOST_TInt32 top,
+       GHOST_TUns32 width,
+       GHOST_TUns32 height,
+       GHOST_TWindowState state,
+       GHOST_TDrawingContextType type,
+       const bool stereoVisual
+) :
+       GHOST_Window(title, left, top, width, height, state, GHOST_kDrawingContextTypeNone),
+       m_windowRef(0),
+       m_grafPtr(0),
+       m_aglCtx(0),
+       m_customCursor(0),
+       m_fullScreenDirty(false)
+{
+    Str255 title255;
+       OSStatus err;
+       
+       //fprintf(stderr," main screen top %i left %i height %i width %i\n", top, left, height, width);
+       
+       if (state >= GHOST_kWindowState8Normal ) {
+               if(state == GHOST_kWindowState8Normal) state= GHOST_kWindowStateNormal;
+               else if(state == GHOST_kWindowState8Maximized) state= GHOST_kWindowStateMaximized;
+               else if(state == GHOST_kWindowState8Minimized) state= GHOST_kWindowStateMinimized;
+               else if(state == GHOST_kWindowState8FullScreen) state= GHOST_kWindowStateFullScreen;
+               
+               // state = state - 8;   this was the simple version of above code, doesnt work in gcc 4.0
+               
+               setMac_windowState(1);
+       } else 
+               setMac_windowState(0);
+
+       if (state != GHOST_kWindowStateFullScreen) {
+        Rect bnds = { top, left, top+height, left+width };
+        // Boolean visible = (state == GHOST_kWindowStateNormal) || (state == GHOST_kWindowStateMaximized); /*unused*/
+        gen2mac(title, title255);
+        
+               err =  ::CreateNewWindow( kDocumentWindowClass,
+                                                                kWindowStandardDocumentAttributes+kWindowLiveResizeAttribute,
+                                                                &bnds,
+                                                                &m_windowRef);
+               
+               if ( err != noErr) {
+                       fprintf(stderr," error creating window %i \n",err);
+               } else {
+                       
+                       ::SetWRefCon(m_windowRef,(SInt32)this);
+                       setTitle(title);
+                       err = InstallWindowEventHandler (m_windowRef, myWEventHandlerProc, GetEventTypeCount(kWEvents), kWEvents,NULL,NULL); 
+                       if ( err != noErr) {
+                               fprintf(stderr," error creating handler %i \n",err);
+                       } else {
+                               //      ::TransitionWindow (m_windowRef,kWindowZoomTransitionEffect,kWindowShowTransitionAction,NULL);
+                               ::ShowWindow(m_windowRef);
+                               ::MoveWindow (m_windowRef, left, top,true);
+                               
+                       }
+               }
+        if (m_windowRef) {
+            m_grafPtr = ::GetWindowPort(m_windowRef);
+            setDrawingContextType(type);
+            updateDrawingContext();
+            activateDrawingContext();
+        }
+               if(ugly_hack==NULL) {
+                       ugly_hack= m_windowRef;
+                       // when started from commandline, window remains in the back... also for play anim
+                       ProcessSerialNumber psn;
+                       GetCurrentProcess(&psn);
+                       SetFrontProcess(&psn);
+               }
+    }
+    else {
+    /*
+        Rect bnds = { top, left, top+height, left+width };
+        gen2mac("", title255);
+        m_windowRef = ::NewCWindow(
+            nil,                                                       // Storage 
+            &bnds,                                                     // Bounding rectangle of the window
+            title255,                                          // Title of the window
+            0,                                                         // Window initially visible
+            plainDBox,                                                 // procID
+            (WindowRef)-1L,                                    // Put window before all other windows
+            0,                                                         // Window has minimize box
+            (SInt32)this);                                     // Store a pointer to the class in the refCon
+    */
+        //GHOST_PRINT("GHOST_WindowCocoa::GHOST_WindowCocoa(): creating full-screen OpenGL context\n");
+        setDrawingContextType(GHOST_kDrawingContextTypeOpenGL);;installDrawingContext(GHOST_kDrawingContextTypeOpenGL);
+        updateDrawingContext();
+        activateDrawingContext();        
+
+       m_tablet.Active = GHOST_kTabletModeNone;
+    }
+}
+
+
+GHOST_WindowCocoa::~GHOST_WindowCocoa()
+{
+       if (m_customCursor) delete m_customCursor;
+
+       if(ugly_hack==m_windowRef) ugly_hack= NULL;
+       
+       // printf("GHOST_WindowCocoa::~GHOST_WindowCocoa(): removing drawing context\n");
+       if(ugly_hack==NULL) setDrawingContextType(GHOST_kDrawingContextTypeNone);
+    if (m_windowRef) {
+        ::DisposeWindow(m_windowRef);
+               m_windowRef = 0;
+       }
+}
+
+bool GHOST_WindowCocoa::getValid() const
+{
+    bool valid;
+    if (!m_fullScreen) {
+        valid = (m_windowRef != 0) && (m_grafPtr != 0) && ::IsValidWindowPtr(m_windowRef);
+    }
+    else {
+        valid = true;
+    }
+    return valid;
+}
+
+
+void GHOST_WindowCocoa::setTitle(const STR_String& title)
+{
+    GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
+    Str255 title255;
+    gen2mac(title, title255);
+       ::SetWTitle(m_windowRef, title255);
+}
+
+
+void GHOST_WindowCocoa::getTitle(STR_String& title) const
+{
+    GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getTitle(): window invalid")
+    Str255 title255;
+    ::GetWTitle(m_windowRef, title255);
+    mac2gen(title255, title);
+}
+
+
+void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
+{
+       OSStatus success;
+       Rect rect;
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid")
+       success = ::GetWindowBounds(m_windowRef, kWindowStructureRgn, &rect);
+       bounds.m_b = rect.bottom;
+       bounds.m_l = rect.left;
+       bounds.m_r = rect.right;
+       bounds.m_t = rect.top;
+}
+
+
+void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
+{
+       Rect rect;
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
+       //::GetPortBounds(m_grafPtr, &rect);
+       ::GetWindowBounds(m_windowRef, kWindowContentRgn, &rect);
+
+       bounds.m_b = rect.bottom;
+       bounds.m_l = rect.left;
+       bounds.m_r = rect.right;
+       bounds.m_t = rect.top;
+
+       // Subtract gutter height from bottom
+#ifdef GHOST_DRAW_CARBON_GUTTER
+       if ((bounds.m_b - bounds.m_t) > s_sizeRectSize)
+       {
+               bounds.m_b -= s_sizeRectSize;
+       }
+       else
+       {
+               bounds.m_t = bounds.m_b;
+       }
+#endif //GHOST_DRAW_CARBON_GUTTER
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid")
+       GHOST_Rect cBnds, wBnds;
+       getClientBounds(cBnds);
+       if (((GHOST_TUns32)cBnds.getWidth()) != width) {
+               ::SizeWindow(m_windowRef, width, cBnds.getHeight(), true);
+       }
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
+       GHOST_Rect cBnds, wBnds;
+       getClientBounds(cBnds);
+#ifdef GHOST_DRAW_CARBON_GUTTER
+       if (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize) {
+               ::SizeWindow(m_windowRef, cBnds.getWidth(), height+s_sizeRectSize, true);
+       }
+#else //GHOST_DRAW_CARBON_GUTTER
+       if (((GHOST_TUns32)cBnds.getHeight()) != height) {
+               ::SizeWindow(m_windowRef, cBnds.getWidth(), height, true);
+       }
+#endif //GHOST_DRAW_CARBON_GUTTER
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
+       GHOST_Rect cBnds, wBnds;
+       getClientBounds(cBnds);
+#ifdef GHOST_DRAW_CARBON_GUTTER
+       if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
+           (((GHOST_TUns32)cBnds.getHeight()) != height+s_sizeRectSize)) {
+               ::SizeWindow(m_windowRef, width, height+s_sizeRectSize, true);
+       }
+#else //GHOST_DRAW_CARBON_GUTTER
+       if ((((GHOST_TUns32)cBnds.getWidth()) != width) ||
+           (((GHOST_TUns32)cBnds.getHeight()) != height)) {
+               ::SizeWindow(m_windowRef, width, height, true);
+       }
+#endif //GHOST_DRAW_CARBON_GUTTER
+       return GHOST_kSuccess;
+}
+
+
+GHOST_TWindowState GHOST_WindowCocoa::getState() const
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
+       GHOST_TWindowState state;
+       if (::IsWindowVisible(m_windowRef) == false) {
+               state = GHOST_kWindowStateMinimized;
+       }
+       else if (::IsWindowInStandardState(m_windowRef, nil, nil)) {
+               state = GHOST_kWindowStateMaximized;
+       }
+       else {
+               state = GHOST_kWindowStateNormal;
+       }
+       return state;
+}
+
+
+void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::screenToClient(): window invalid")
+       Point point;
+       point.h = inX;
+       point.v = inY;
+    GrafPtr oldPort;
+    ::GetPort(&oldPort);
+    ::SetPort(m_grafPtr);
+       ::GlobalToLocal(&point);
+    ::SetPort(oldPort);
+       outX = point.h;
+       outY = point.v;
+}
+
+
+void GHOST_WindowCocoa::clientToScreen(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST_TInt32& outX, GHOST_TInt32& outY) const
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::clientToScreen(): window invalid")
+       Point point;
+       point.h = inX;
+       point.v = inY;
+    GrafPtr oldPort;
+    ::GetPort(&oldPort);
+    ::SetPort(m_grafPtr);
+       ::LocalToGlobal(&point);
+    ::SetPort(oldPort);
+       outX = point.h;
+       outY = point.v;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
+    switch (state) {
+       case GHOST_kWindowStateMinimized:
+            ::HideWindow(m_windowRef);
+            break;
+       case GHOST_kWindowStateModified:
+               SetWindowModified(m_windowRef, 1);
+               break;
+       case GHOST_kWindowStateUnModified:
+               SetWindowModified(m_windowRef, 0);
+               break;
+       case GHOST_kWindowStateMaximized:
+       case GHOST_kWindowStateNormal:
+        default:
+            ::ShowWindow(m_windowRef);
+            break;
+    }
+    return GHOST_kSuccess;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
+    if (order == GHOST_kWindowOrderTop) {
+        //::BringToFront(m_windowRef); is wrong, front window should be active for input too
+               ::SelectWindow(m_windowRef);
+    }
+    else {
+               /* doesnt work if you do this with a mouseclick */
+        ::SendBehind(m_windowRef, nil);
+    }
+    return GHOST_kSuccess;
+}
+
+/*#define  WAIT_FOR_VSYNC 1*/
+#ifdef WAIT_FOR_VSYNC
+#include <OpenGL/OpenGL.h>
+#endif
+
+GHOST_TSuccess GHOST_WindowCocoa::swapBuffers()
+{
+#ifdef WAIT_FOR_VSYNC
+/* wait for vsync, to avoid tearing artifacts */
+long VBL = 1;
+CGLSetParameter(CGLGetCurrentContext(), kCGLCPSwapInterval, &VBL);
+#endif
+
+    GHOST_TSuccess succeeded = GHOST_kSuccess;
+    if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+        if (m_aglCtx) {
+            ::aglSwapBuffers(m_aglCtx);
+        }
+        else {
+            succeeded = GHOST_kFailure;
+        }
+    }
+    return succeeded;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::updateDrawingContext()
+{
+       GHOST_TSuccess succeeded = GHOST_kSuccess;
+       if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+               if (m_aglCtx) {
+                       ::aglUpdateContext(m_aglCtx);
+               }
+               else {
+                       succeeded = GHOST_kFailure;
+               }
+       }
+       return succeeded;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::activateDrawingContext()
+{
+       GHOST_TSuccess succeeded = GHOST_kSuccess;
+       if (m_drawingContextType == GHOST_kDrawingContextTypeOpenGL) {
+               if (m_aglCtx) {
+                       ::aglSetCurrentContext(m_aglCtx);
+#ifdef GHOST_DRAW_CARBON_GUTTER
+                       // Restrict drawing to non-gutter area
+                       ::aglEnable(m_aglCtx, AGL_BUFFER_RECT);
+                       GHOST_Rect bnds;
+                       getClientBounds(bnds);
+                       GLint b[4] =
+                       {
+                               bnds.m_l,
+                               bnds.m_t+s_sizeRectSize,
+                               bnds.m_r-bnds.m_l,
+                               bnds.m_b-bnds.m_t
+                       };
+                       GLboolean result = ::aglSetInteger(m_aglCtx, AGL_BUFFER_RECT, b);
+#endif //GHOST_DRAW_CARBON_GUTTER
+               }
+               else {
+                       succeeded = GHOST_kFailure;
+               }
+       }
+       return succeeded;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::installDrawingContext(GHOST_TDrawingContextType type)
+{
+       GHOST_TSuccess success = GHOST_kFailure;
+       switch (type) {
+               case GHOST_kDrawingContextTypeOpenGL:
+                       {
+                       if (!getValid()) break;
+            
+            AGLPixelFormat pixelFormat;
+            if (!m_fullScreen) {
+                pixelFormat = ::aglChoosePixelFormat(0, 0, sPreferredFormatWindow);
+                m_aglCtx = ::aglCreateContext(pixelFormat, s_firstaglCtx);
+                if (!m_aglCtx) break;
+                               if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
+                 success = ::aglSetDrawable(m_aglCtx, m_grafPtr) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+            }
+            else {
+                //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL\n");
+GDHandle device=::GetMainDevice();pixelFormat=::aglChoosePixelFormat(&device,1,sPreferredFormatFullScreen);
+                m_aglCtx = ::aglCreateContext(pixelFormat, 0);
+                if (!m_aglCtx) break;
+                               if (!s_firstaglCtx) s_firstaglCtx = m_aglCtx;
+                //GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): created OpenGL context\n");
+                //::CGGetActiveDisplayList(0, NULL, &m_numDisplays)
+                success = ::aglSetFullScreen(m_aglCtx, m_fullScreenWidth, m_fullScreenHeight, 75, 0) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+                /*
+                if (success == GHOST_kSuccess) {
+                    GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL succeeded\n");
+                }
+                else {
+                    GHOST_PRINT("GHOST_WindowCocoa::installDrawingContext(): init full-screen OpenGL failed\n");
+                }
+                */
+            }
+            ::aglDestroyPixelFormat(pixelFormat);
+                       }
+                       break;
+               
+               case GHOST_kDrawingContextTypeNone:
+                       success = GHOST_kSuccess;
+                       break;
+               
+               default:
+                       break;
+       }
+       return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
+{
+       GHOST_TSuccess success = GHOST_kFailure;
+       switch (m_drawingContextType) {
+               case GHOST_kDrawingContextTypeOpenGL:
+                       if (m_aglCtx) {
+                aglSetCurrentContext(NULL);
+                aglSetDrawable(m_aglCtx, NULL);
+                //aglDestroyContext(m_aglCtx);
+                               if (s_firstaglCtx == m_aglCtx) s_firstaglCtx = NULL;
+                               success = ::aglDestroyContext(m_aglCtx) == GL_TRUE ? GHOST_kSuccess : GHOST_kFailure;
+                               m_aglCtx = 0;
+                       }
+                       break;
+               case GHOST_kDrawingContextTypeNone:
+                       success = GHOST_kSuccess;
+                       break;
+               default:
+                       break;
+       }
+       return success;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::invalidate()
+{
+       GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
+    if (!m_fullScreen) {
+        Rect rect;
+        ::GetPortBounds(m_grafPtr, &rect);
+        ::InvalWindowRect(m_windowRef, &rect);
+    }
+    else {
+        //EventRef event;
+        //OSStatus status = ::CreateEvent(NULL, kEventClassWindow, kEventWindowUpdate, 0, 0, &event);
+        //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): created event " << status << " \n");
+        //status = ::SetEventParameter(event, kEventParamDirectObject, typeWindowRef, sizeof(WindowRef), this);
+        //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): set event parameter " << status << " \n");
+        //status = ::PostEventToQueue(::GetMainEventQueue(), event, kEventPriorityStandard);
+        //status = ::SendEventToEventTarget(event, ::GetApplicationEventTarget());
+        //GHOST_PRINT("GHOST_WindowCocoa::invalidate(): added event to queue " << status << " \n");
+        m_fullScreenDirty = true;
+    }
+       return GHOST_kSuccess;
+}
+
+
+void GHOST_WindowCocoa::gen2mac(const STR_String& in, Str255 out) const
+{
+       STR_String tempStr  = in;
+       int num = tempStr.Length();
+       if (num > 255) num = 255;
+       ::memcpy(out+1, tempStr.Ptr(), num);
+       out[0] = num;
+}
+
+
+void GHOST_WindowCocoa::mac2gen(const Str255 in, STR_String& out) const
+{
+       char tmp[256];
+       ::memcpy(tmp, in+1, in[0]);
+       tmp[in[0]] = '\0';
+       out = tmp;
+}
+
+void GHOST_WindowCocoa::loadCursor(bool visible, GHOST_TStandardCursor cursor) const
+{
+       static bool systemCursorVisible = true;
+       
+       if (visible != systemCursorVisible) {
+               if (visible) {
+                       ::ShowCursor();
+                       systemCursorVisible = true;
+               }
+               else {
+                       ::HideCursor();
+                       systemCursorVisible = false;
+               }
+       }
+
+       if (cursor == GHOST_kStandardCursorCustom && m_customCursor) {
+               ::SetCursor( m_customCursor );
+       } else {
+               int carbon_cursor;
+       
+#define GCMAP(ghostCursor, carbonCursor)       case ghostCursor: carbon_cursor = carbonCursor; break
+               switch (cursor) {
+               default:
+               GCMAP( GHOST_kStandardCursorDefault,                            kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorRightArrow,                         kThemeAliasArrowCursor);
+               GCMAP( GHOST_kStandardCursorLeftArrow,                          kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorInfo,                                       kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorDestroy,                            kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorHelp,                               kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorCycle,                                      kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorSpray,                                      kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorWait,                                       kThemeWatchCursor);
+               GCMAP( GHOST_kStandardCursorText,                                       kThemeIBeamCursor);
+               GCMAP( GHOST_kStandardCursorCrosshair,                          kThemeCrossCursor);
+               GCMAP( GHOST_kStandardCursorUpDown,                                     kThemeClosedHandCursor);
+               GCMAP( GHOST_kStandardCursorLeftRight,                          kThemeClosedHandCursor);
+               GCMAP( GHOST_kStandardCursorTopSide,                            kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorBottomSide,                         kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorLeftSide,                           kThemeResizeLeftCursor);
+               GCMAP( GHOST_kStandardCursorRightSide,                          kThemeResizeRightCursor);
+               GCMAP( GHOST_kStandardCursorTopLeftCorner,                      kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorTopRightCorner,                     kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorBottomRightCorner,          kThemeArrowCursor);
+               GCMAP( GHOST_kStandardCursorBottomLeftCorner,           kThemeArrowCursor);
+               };
+#undef GCMAP
+
+               ::SetThemeCursor(carbon_cursor);
+       }
+}
+
+
+bool GHOST_WindowCocoa::getFullScreenDirty()
+{
+    return m_fullScreen && m_fullScreenDirty;
+}
+
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorVisibility(bool visible)
+{
+       if (::FrontWindow() == m_windowRef) {
+               loadCursor(visible, getCursorShape());
+       }
+       
+       return GHOST_kSuccess;
+}
+       
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCursorShape(GHOST_TStandardCursor shape)
+{
+       if (m_customCursor) {
+               delete m_customCursor;
+               m_customCursor = 0;
+       }
+
+       if (::FrontWindow() == m_windowRef) {
+               loadCursor(getCursorVisibility(), shape);
+       }
+       
+       return GHOST_kSuccess;
+}
+
+#if 0
+/** Reverse the bits in a GHOST_TUns8 */
+static GHOST_TUns8 uns8ReverseBits(GHOST_TUns8 ch)
+{
+       ch= ((ch>>1)&0x55) | ((ch<<1)&0xAA);
+       ch= ((ch>>2)&0x33) | ((ch<<2)&0xCC);
+       ch= ((ch>>4)&0x0F) | ((ch<<4)&0xF0);
+       return ch;
+}
+#endif
+
+
+/** Reverse the bits in a GHOST_TUns16 */
+static GHOST_TUns16 uns16ReverseBits(GHOST_TUns16 shrt)
+{
+       shrt= ((shrt>>1)&0x5555) | ((shrt<<1)&0xAAAA);
+       shrt= ((shrt>>2)&0x3333) | ((shrt<<2)&0xCCCC);
+       shrt= ((shrt>>4)&0x0F0F) | ((shrt<<4)&0xF0F0);
+       shrt= ((shrt>>8)&0x00FF) | ((shrt<<8)&0xFF00);
+       return shrt;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 *bitmap, GHOST_TUns8 *mask,
+                                       int sizex, int sizey, int hotX, int hotY, int fg_color, int bg_color)
+{
+       int y;
+       
+       if (m_customCursor) {
+               delete m_customCursor;
+               m_customCursor = 0;
+       }
+       
+       m_customCursor = new Cursor;
+       if (!m_customCursor) return GHOST_kFailure;
+       
+       for (y=0; y<16; y++) {
+#if !defined(__LITTLE_ENDIAN__)
+               m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y]<<0) | (bitmap[2*y+1]<<8));
+               m_customCursor->mask[y] = uns16ReverseBits((mask[2*y]<<0) | (mask[2*y+1]<<8));
+#else
+               m_customCursor->data[y] = uns16ReverseBits((bitmap[2*y+1]<<0) | (bitmap[2*y]<<8));
+               m_customCursor->mask[y] = uns16ReverseBits((mask[2*y+1]<<0) | (mask[2*y]<<8));
+#endif
+                       
+       }
+       
+       m_customCursor->hotSpot.h = hotX;
+       m_customCursor->hotSpot.v = hotY;
+       
+       if (::FrontWindow() == m_windowRef) {
+               loadCursor(getCursorVisibility(), GHOST_kStandardCursorCustom);
+       }
+       
+       return GHOST_kSuccess;
+}
+
+GHOST_TSuccess GHOST_WindowCocoa::setWindowCustomCursorShape(GHOST_TUns8 bitmap[16][2], 
+                                                                                               GHOST_TUns8 mask[16][2], int hotX, int hotY)
+{
+       return setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*) mask, 16, 16, hotX, hotY, 0, 1);
+}
+
+
+void GHOST_WindowCocoa::setMac_windowState(short value)
+{
+       mac_windowState = value;
+}
+
+short GHOST_WindowCocoa::getMac_windowState()
+{
+       return mac_windowState;
+}