Cocoa port start:

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)
This commit is contained in:
Damien Plisson 2009-09-30 08:47:39 +00:00
parent 2a21c1acbe
commit 570c187ba1
9 changed files with 2940 additions and 4 deletions

@ -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 ")

@ -26,9 +26,18 @@
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)

@ -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_

@ -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;
}

@ -44,7 +44,11 @@
# 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

@ -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_

File diff suppressed because it is too large Load Diff

@ -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_

@ -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;
}