This is a big commit for os x port!
> remove old OSX version > add new sources (Window and Graphics modules) > add extlibs static binaries/headers/frameworks > update cmake for OSX git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1711 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
bb55254fe3
commit
de8712fa5f
112 changed files with 42514 additions and 4588 deletions
|
@ -28,9 +28,12 @@ set(SRC
|
|||
${INCROOT}/SoundStream.hpp
|
||||
)
|
||||
|
||||
# let CMake know about our additional audio libraries paths (on Windows)
|
||||
# let CMake know about our additional audio libraries paths (on Windows and OSX)
|
||||
if(WINDOWS)
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/AL")
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/AL")
|
||||
elseif (MACOSX)
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include")
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/Frameworks")
|
||||
endif()
|
||||
|
||||
# find external libraries
|
||||
|
|
|
@ -57,19 +57,47 @@ if(WINDOWS)
|
|||
${SRCROOT}/Win32/RenderImageImplPBuffer.cpp
|
||||
${SRCROOT}/Win32/RenderImageImplPBuffer.hpp
|
||||
)
|
||||
else()
|
||||
elseif(LINUX)
|
||||
set(SRC
|
||||
${SRC}
|
||||
${SRCROOT}/Linux/RenderImageImplPBuffer.cpp
|
||||
${SRCROOT}/Linux/RenderImageImplPBuffer.hpp
|
||||
)
|
||||
elseif(MACOSX)
|
||||
set(SRC
|
||||
${SRC}
|
||||
${SRCROOT}/OSX/RenderImageImplPBuffer.cpp
|
||||
${SRCROOT}/OSX/RenderImageImplPBuffer.hpp
|
||||
)
|
||||
endif()
|
||||
|
||||
# let CMake know about our additional graphics libraries paths (on Windows)
|
||||
# let CMake know about our additional graphics libraries paths (on Windows and OSX)
|
||||
if (WINDOWS)
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/freetype")
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/GL")
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/jpeg")
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/jpeg")
|
||||
|
||||
elseif (MACOSX)
|
||||
|
||||
# Add freetype search path
|
||||
#if (${CMAKE_OSX_SYSROOT} STREQUAL "/Developer/SDKs/MacOSX10.4u.sdk")
|
||||
# set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11R6/include/")
|
||||
# set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11R6/lib/")
|
||||
#else ()
|
||||
# set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11/include/")
|
||||
# set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11/lib/")
|
||||
#endif ()
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include/")
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/lib/")
|
||||
|
||||
|
||||
# Add GLEW search path
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include/")
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/lib/")
|
||||
|
||||
# Add jpeg search path
|
||||
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include/jpeg")
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/lib/")
|
||||
endif()
|
||||
|
||||
# find external libraries
|
||||
|
@ -91,6 +119,10 @@ if(BUILD_SHARED_LIBS)
|
|||
set(GRAPHICS_EXT_LIBS ${GRAPHICS_EXT_LIBS} ${OPENGL_gl_LIBRARY})
|
||||
if(LINUX)
|
||||
set(GRAPHICS_EXT_LIBS ${GRAPHICS_EXT_LIBS} ${X11_LIBRARIES})
|
||||
endif()
|
||||
if(MACOSX)
|
||||
# We use static version of freetype so we need to link against zlib.
|
||||
set(GRAPHICS_EXT_LIBS ${GRAPHICS_EXT_LIBS} z)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
97
src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp
Normal file
97
src/SFML/Graphics/OSX/RenderImageImplPBuffer.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/OSX/RenderImageImplPBuffer.hpp>
|
||||
#include <SFML/Graphics/GLCheck.hpp>
|
||||
#include <SFML/Window/Context.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
#warning RenderImageImplPBuffer not yet implemented
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer::RenderImageImplPBuffer()
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer::~RenderImageImplPBuffer()
|
||||
{
|
||||
/* TODO */
|
||||
|
||||
// This is to make sure that another valid context is made
|
||||
// active after we destroy the P-Buffer's one
|
||||
Context::SetReferenceActive();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::IsSupported()
|
||||
{
|
||||
/* TODO */
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer)
|
||||
{
|
||||
// Store the dimensions
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
|
||||
/* TODO */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool RenderImageImplPBuffer::Activate(bool active)
|
||||
{
|
||||
if (active)
|
||||
{
|
||||
if (false/*myPBuffer && myContext*/)
|
||||
{
|
||||
// try to activate
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// To deactivate the P-Buffer's context, we actually activate
|
||||
// another one so that we make sure that there is always an
|
||||
// active context for subsequent graphics operations
|
||||
return Context::SetReferenceActive();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
|
||||
{
|
||||
if (Activate(true))
|
||||
{
|
||||
GLint previous;
|
||||
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
|
||||
|
||||
// Copy the rendered pixels to the image
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, textureId));
|
||||
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
|
||||
|
||||
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
89
src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp
Normal file
89
src/SFML/Graphics/OSX/RenderImageImplPBuffer.hpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
|
||||
|
||||
#ifndef SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
||||
#define SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Graphics/RenderImageImpl.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Specialization of RenderImageImpl using ****** P-Buffers
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class RenderImageImplPBuffer : public RenderImageImpl
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Default constructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplPBuffer();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~RenderImageImplPBuffer();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check whether the system supports P-Buffer or not
|
||||
///
|
||||
/// \return True if P-Buffer render images are supported
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool IsSupported();
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the render image implementation
|
||||
///
|
||||
/// \param width Width of the image to render to
|
||||
/// \param height Height of the image to render to
|
||||
/// \param textureId OpenGL texture identifier of the target image
|
||||
/// \param depthBuffer Is a depth buffer requested?
|
||||
///
|
||||
/// \return True if creation has been successful
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate or deactivate the render image for rendering
|
||||
///
|
||||
/// \param active True to activate, false to deactivate
|
||||
///
|
||||
/// \return True on success, false on failure
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool Activate(bool active);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update the pixels of the target texture
|
||||
///
|
||||
/// \param textureId OpenGL identifier of the target texture
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void UpdateTexture(unsigned textureId);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int myWidth; ///< Width of the P-Buffer
|
||||
unsigned int myHeight; ///< Height of the P-Buffer
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_RENDERIMAGEIMPLPBUFFER_HPP
|
|
@ -39,6 +39,6 @@
|
|||
|
||||
#elif defined(SFML_SYSTEM_MACOS)
|
||||
|
||||
#include <SFML/Graphics/MacOSX/RenderImageImplPBuffer.hpp>
|
||||
#include <SFML/Graphics/OSX/RenderImageImplPBuffer.hpp>
|
||||
|
||||
#endif
|
||||
|
|
|
@ -47,18 +47,25 @@ elseif(LINUX)
|
|||
${SRCROOT}/Linux/WindowImplX11.cpp
|
||||
${SRCROOT}/Linux/WindowImplX11.hpp
|
||||
)
|
||||
else()
|
||||
else() # MACOSX
|
||||
set(SRC
|
||||
${SRC}
|
||||
${SRCROOT}/Cocoa/AppController.h
|
||||
${SRCROOT}/Cocoa/AppController.mm
|
||||
${SRCROOT}/Cocoa/GLKit.h
|
||||
${SRCROOT}/Cocoa/GLKit.mm
|
||||
${SRCROOT}/Cocoa/Joystick.cpp
|
||||
${SRCROOT}/Cocoa/Joystick.hpp
|
||||
${SRCROOT}/Cocoa/VideoModeImpl.cpp
|
||||
${SRCROOT}/Cocoa/WindowImplCocoa.cpp
|
||||
${SRCROOT}/Cocoa/WindowImplCocoa.mm
|
||||
${SRCROOT}/OSX/cpp_objc_conversion.h
|
||||
${SRCROOT}/OSX/cpp_objc_conversion.mm
|
||||
${SRCROOT}/OSX/Joystick.cpp
|
||||
${SRCROOT}/OSX/Joystick.hpp
|
||||
${SRCROOT}/OSX/SFApplication.h
|
||||
${SRCROOT}/OSX/SFApplication.m
|
||||
${SRCROOT}/OSX/SFContext.hpp
|
||||
${SRCROOT}/OSX/SFContext.mm
|
||||
${SRCROOT}/OSX/SFOpenGLView.h
|
||||
${SRCROOT}/OSX/SFOpenGLView.mm
|
||||
${SRCROOT}/OSX/SFWindowController.h
|
||||
${SRCROOT}/OSX/SFWindowController.mm
|
||||
${SRCROOT}/OSX/VideoModeImpl.cpp
|
||||
${SRCROOT}/OSX/WindowImplCocoa.hpp
|
||||
${SRCROOT}/OSX/WindowImplCocoa.mm
|
||||
${SRCROOT}/OSX/WindowImplDelegateProtocol.h
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -72,8 +79,10 @@ endif()
|
|||
set(WINDOW_EXT_LIBS ${OPENGL_gl_LIBRARY})
|
||||
if(WINDOWS)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} winmm gdi32)
|
||||
else(LINUX)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
|
||||
elseif(LINUX)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
|
||||
elseif(MACOSX)
|
||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} "-framework Foundation -framework AppKit")
|
||||
endif()
|
||||
|
||||
# define the sfml-window target
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <SFML/Window/VideoMode.hpp>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
|
||||
// Fade operations
|
||||
enum {
|
||||
FillScreen,
|
||||
CleanScreen
|
||||
};
|
||||
|
||||
@class sfPrivWindow;
|
||||
@interface sfPrivAppController : NSObject {
|
||||
BOOL myOwningEventLoop;
|
||||
sfPrivWindow *myFullscreenWrapper;
|
||||
NSAutoreleasePool *myMainPool;
|
||||
sf::VideoMode myDesktopMode;
|
||||
sf::VideoMode myPrevMode;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the shared AppController instance. Make one if needed.
|
||||
////////////////////////////////////////////////////////////
|
||||
+ (sfPrivAppController *)sharedController;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Returns the primay computer's screen
|
||||
////////////////////////////////////////////////////////////
|
||||
+ (CGDirectDisplayID)primaryScreen;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Reset notifictions about application focus
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setNotifications;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Make the menu bar
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)makeMenuBar;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Process all the events and send them to the application
|
||||
/// No event is processed if the AppController instance is
|
||||
/// not the owner of the event loop (ie: user made his own loop)
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)processEvents;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Set @window as the current fullscreen window
|
||||
/// Change the screen resolution if needed according to @window and @fullscreenMode
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setFullscreenWindow:(sfPrivWindow *)window mode:(sf::VideoMode *)fullscreenMode;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Perform fade operation where 'operation' is one of { FillScreen, CleanScreen}
|
||||
/// and 'time' is the time during which you wish the operation to be performed.
|
||||
/// Set 'sync' to true if you do not want the method to end before the end
|
||||
/// of the fade operation.
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)doFadeOperation:(int)operation time:(float)time sync:(bool)sync;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the desktop video mode (made at the instance initialization)
|
||||
////////////////////////////////////////////////////////////
|
||||
- (const sf::VideoMode&)desktopMode;
|
||||
|
||||
@end
|
||||
|
|
@ -1,578 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <SFML/Window/Cocoa/AppController.h>
|
||||
#import <SFML/Window/Cocoa/GLKit.h>
|
||||
#import <SFML/System.hpp>
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#import <iostream>
|
||||
|
||||
|
||||
|
||||
/* setAppleMenu disappeared from the headers in 10.4 */
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
@interface NSApplication (SFML)
|
||||
- (void)setAppleMenu:(NSMenu *)menu;
|
||||
@end
|
||||
#endif
|
||||
|
||||
#define ENABLE_FADE_OPERATIONS 1
|
||||
|
||||
@implementation NSApplication (SFML)
|
||||
|
||||
- (void)setRunning:(BOOL)flag
|
||||
{
|
||||
// Note: _running is a short, not a BOOL
|
||||
if (flag)
|
||||
_running = 1;
|
||||
else
|
||||
_running = 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation sfPrivAppController
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return an initialized AppController instance
|
||||
/// Save the desktop mode
|
||||
/// Make the main autorelease pool
|
||||
/// Set the application observer
|
||||
////////////////////////////////////////////////////////////
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self != nil) {
|
||||
myOwningEventLoop = NO;
|
||||
|
||||
// Save the desktop mode
|
||||
myDesktopMode = sf::VideoMode::GetDesktopMode();
|
||||
myPrevMode = myDesktopMode;
|
||||
|
||||
// Make the app autorelease pool
|
||||
myMainPool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
if (!myMainPool) {
|
||||
[self release];
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
// Don't go on if the user handles the app
|
||||
if (![NSApp isRunning])
|
||||
{
|
||||
// Force our application to appear in the Dock and make it able
|
||||
// to get focus (even when it's a raw executable)
|
||||
ProcessSerialNumber psn;
|
||||
|
||||
if (!GetCurrentProcess(&psn)) {
|
||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
SetFrontProcess(&psn);
|
||||
}
|
||||
|
||||
// Make the app
|
||||
if (![NSApplication sharedApplication]) {
|
||||
[self release];
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
|
||||
[self setNotifications];
|
||||
|
||||
if ([NSApp mainMenu] == nil) {
|
||||
[self makeMenuBar];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Clean the controller
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)dealloc
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[myMainPool release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the shared AppController instance. Make one if needed.
|
||||
////////////////////////////////////////////////////////////
|
||||
+ (sfPrivAppController *)sharedController
|
||||
{
|
||||
// AppController singleton object
|
||||
static sfPrivAppController *shared = [[sfPrivAppController alloc] init];
|
||||
return shared;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Returns the primay computer's screen
|
||||
////////////////////////////////////////////////////////////
|
||||
+ (CGDirectDisplayID)primaryScreen
|
||||
{
|
||||
static BOOL firstTime = YES;
|
||||
static CGDirectDisplayID screen = kCGNullDirectDisplay;
|
||||
|
||||
if (firstTime) {
|
||||
CGDisplayCount numScr;
|
||||
CGDisplayErr err = CGGetDisplaysWithPoint(CGPointMake(0, 0), 1, &screen, &numScr);
|
||||
|
||||
if (err != kCGErrorSuccess || numScr < 1) {
|
||||
std::cerr << "Unable to get primary screen (error code " << err
|
||||
<< " ). Using the main screen.";
|
||||
screen = CGMainDisplayID();
|
||||
}
|
||||
firstTime = NO;
|
||||
}
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Reset notifictions about application focus
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setNotifications
|
||||
{
|
||||
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
||||
[nc addObserver:self
|
||||
selector:@selector(applicationWillDeactivate:)
|
||||
name:NSApplicationWillResignActiveNotification
|
||||
object:NSApp];
|
||||
[nc addObserver:self
|
||||
selector:@selector(applicationWillActivate:)
|
||||
name:NSApplicationWillBecomeActiveNotification
|
||||
object:NSApp];
|
||||
|
||||
[nc addObserver:self
|
||||
selector:@selector(applicationWillTerminate:)
|
||||
name:NSApplicationWillTerminateNotification
|
||||
object:NSApp];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Hide all the fullscreen windows and switch back to the desktop display mode
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)applicationWillDeactivate:(NSNotification *)aNotification
|
||||
{
|
||||
// Note: not using fading because it produces reactivation issues
|
||||
if (myFullscreenWrapper) {
|
||||
myPrevMode = sf::VideoMode::GetDesktopMode();
|
||||
|
||||
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
|
||||
myDesktopMode.BitsPerPixel,
|
||||
myDesktopMode.Width,
|
||||
myDesktopMode.Height,
|
||||
NULL);
|
||||
|
||||
// Make the full screen window unvisible
|
||||
[[myFullscreenWrapper window] setAlphaValue:0.0f];
|
||||
|
||||
// Switch to the wished display mode
|
||||
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Unhide all the fullscreen windows and switch to full screen display mode
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)applicationWillActivate:(NSNotification *)aNotification
|
||||
{
|
||||
if (myFullscreenWrapper) {
|
||||
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
|
||||
myPrevMode.BitsPerPixel,
|
||||
myPrevMode.Width,
|
||||
myPrevMode.Height,
|
||||
NULL);
|
||||
[NSMenu setMenuBarVisible:NO];
|
||||
|
||||
// Switch to the wished display mode
|
||||
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
|
||||
|
||||
// Show the fullscreen window if existing
|
||||
if (myFullscreenWrapper)
|
||||
{
|
||||
[[myFullscreenWrapper window] setAlphaValue:1.0f];
|
||||
[[myFullscreenWrapper window] center];
|
||||
[[myFullscreenWrapper window] makeKeyAndOrderFront:self];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification
|
||||
{
|
||||
if (myFullscreenWrapper)
|
||||
[self setFullscreenWindow:nil mode:NULL];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Make menu bar
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)makeMenuBar
|
||||
{
|
||||
// Source taken from SDL 1.3
|
||||
NSString *appName = nil;
|
||||
NSString *title = nil;
|
||||
NSMenu *appleMenu = nil;
|
||||
NSMenu *fileMenu = nil;
|
||||
NSMenu *windowMenu = nil;
|
||||
NSMenuItem *menuItem = nil;
|
||||
NSMenuItem *quitMenuItem = nil;
|
||||
|
||||
// Determine the application name
|
||||
appName = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleName"];
|
||||
|
||||
if (![appName length])
|
||||
appName = [[NSProcessInfo processInfo] processName];
|
||||
|
||||
|
||||
// Create the main menu bar
|
||||
[NSApp setMainMenu:[[NSMenu alloc] init]];
|
||||
|
||||
// Create the application menu
|
||||
appleMenu = [[NSMenu alloc] initWithTitle:@""];
|
||||
|
||||
// Put menu items
|
||||
// + 'About' menu item
|
||||
title = [@"About " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title
|
||||
action:@selector(orderFrontStandardAboutPanel:)
|
||||
keyEquivalent:@""];
|
||||
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// + 'Hide' menu item
|
||||
title = [@"Hide " stringByAppendingString:appName];
|
||||
[appleMenu addItemWithTitle:title
|
||||
action:@selector(hide:)
|
||||
keyEquivalent:@"h"];
|
||||
|
||||
// + 'Hide other' menu item
|
||||
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others"
|
||||
action:@selector(hideOtherApplications:)
|
||||
keyEquivalent:@"h"];
|
||||
[menuItem setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
|
||||
|
||||
// + 'Show all' menu item
|
||||
[appleMenu addItemWithTitle:@"Show All"
|
||||
action:@selector(unhideAllApplications:)
|
||||
keyEquivalent:@""];
|
||||
|
||||
[appleMenu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
// + 'Quit' menu item
|
||||
title = [@"Quit " stringByAppendingString:appName];
|
||||
quitMenuItem = [[[NSMenuItem alloc]
|
||||
initWithTitle:title
|
||||
action:@selector(terminate:)
|
||||
keyEquivalent:@"q"] autorelease];
|
||||
//[quitMenuItem setTarget:self];
|
||||
[appleMenu addItem:quitMenuItem];
|
||||
|
||||
// Put the menu into the menubar
|
||||
menuItem = [[NSMenuItem alloc]
|
||||
initWithTitle:@""
|
||||
action:nil
|
||||
keyEquivalent:@""];
|
||||
[menuItem setSubmenu:appleMenu];
|
||||
[[NSApp mainMenu] addItem:menuItem];
|
||||
[menuItem release];
|
||||
|
||||
// Tell the application object that this is now the application menu
|
||||
[NSApp setAppleMenu:appleMenu];
|
||||
[appleMenu release];
|
||||
|
||||
// 'File' menu
|
||||
fileMenu = [[NSMenu alloc]
|
||||
initWithTitle:@"File"];
|
||||
|
||||
// + 'Close' menu item
|
||||
menuItem = [[NSMenuItem alloc]
|
||||
initWithTitle:@"Close"
|
||||
action:@selector(performClose:)
|
||||
keyEquivalent:@"w"];
|
||||
[fileMenu addItem:menuItem];
|
||||
[menuItem release];
|
||||
|
||||
// + 'File' menu item (head)
|
||||
menuItem = [[NSMenuItem alloc]
|
||||
initWithTitle:@"File"
|
||||
action:nil
|
||||
keyEquivalent:@""];
|
||||
[menuItem setSubmenu:fileMenu];
|
||||
[[NSApp mainMenu] addItem:menuItem];
|
||||
[menuItem release];
|
||||
|
||||
// 'Window' menu
|
||||
windowMenu = [[NSMenu alloc]
|
||||
initWithTitle:@"Window"];
|
||||
|
||||
// + 'Minimize' menu item
|
||||
menuItem = [[NSMenuItem alloc]
|
||||
initWithTitle:@"Minimize"
|
||||
action:@selector(performMiniaturize:)
|
||||
keyEquivalent:@"m"];
|
||||
[windowMenu addItem:menuItem];
|
||||
[menuItem release];
|
||||
|
||||
// + 'Window' menu item (head)
|
||||
menuItem = [[NSMenuItem alloc]
|
||||
initWithTitle:@"Window"
|
||||
action:nil keyEquivalent:@""];
|
||||
[menuItem setSubmenu:windowMenu];
|
||||
[[NSApp mainMenu] addItem:menuItem];
|
||||
[menuItem release];
|
||||
|
||||
// Tell the application object that this is now the window menu
|
||||
[NSApp setWindowsMenu:windowMenu];
|
||||
[windowMenu release];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Process all the events and send them to the application
|
||||
/// No event is processed if the AppController instance is
|
||||
/// not the owner of the event loop (ie: user made his own loop)
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)processEvents
|
||||
{
|
||||
// Check there is a run loop
|
||||
if (![NSApp isRunning])
|
||||
{
|
||||
// Get the ownershipt of event handling if not and run
|
||||
[NSApp finishLaunching];
|
||||
[NSApp setRunning:YES];
|
||||
myOwningEventLoop = YES;
|
||||
}
|
||||
|
||||
NSEvent *event = nil;
|
||||
|
||||
if (myOwningEventLoop)
|
||||
{
|
||||
// Clean the autorelease pool
|
||||
[myMainPool release];
|
||||
myMainPool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Minimal event loop
|
||||
while (nil != (event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:nil
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES]))
|
||||
{
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Set @window as the current fullscreen window
|
||||
/// Change the screen resolution if needed according to @window and @fullscreenMode
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setFullscreenWindow:(sfPrivWindow *)aWindow mode:(sf::VideoMode *)fullscreenMode
|
||||
{
|
||||
// If we have a fullscreen window and want to remove it
|
||||
if (aWindow == nil && myFullscreenWrapper)
|
||||
{
|
||||
// Get the CoreGraphics display mode according to the desktop mode
|
||||
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
|
||||
myDesktopMode.BitsPerPixel,
|
||||
myDesktopMode.Width,
|
||||
myDesktopMode.Height,
|
||||
NULL);
|
||||
|
||||
#if ENABLE_FADE_OPERATIONS
|
||||
// Fade to black screen
|
||||
[self doFadeOperation:FillScreen time:0.2f sync:true];
|
||||
#endif
|
||||
|
||||
// Switch to the desktop display mode
|
||||
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
|
||||
|
||||
// Close the window
|
||||
[[myFullscreenWrapper window] close];
|
||||
|
||||
// Show the menu bar
|
||||
[NSMenu setMenuBarVisible:YES];
|
||||
|
||||
#if ENABLE_FADE_OPERATIONS
|
||||
// Fade to normal screen
|
||||
[self doFadeOperation:CleanScreen time:0.5f sync:true];
|
||||
#endif
|
||||
|
||||
// Release the saved window wrapper
|
||||
myFullscreenWrapper = nil;
|
||||
}
|
||||
else if (aWindow)
|
||||
{
|
||||
// else if we want to SET fullscreen
|
||||
assert(fullscreenMode != NULL);
|
||||
|
||||
// Get the CoreGraphics display mode according to the given sf mode
|
||||
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
|
||||
fullscreenMode->BitsPerPixel,
|
||||
fullscreenMode->Width,
|
||||
fullscreenMode->Height,
|
||||
NULL);
|
||||
|
||||
#if ENABLE_FADE_OPERATIONS
|
||||
// Fade to a black screen
|
||||
[self doFadeOperation:FillScreen time:0.5f sync:true];
|
||||
#endif
|
||||
|
||||
if (!myFullscreenWrapper)
|
||||
{
|
||||
// Hide the main menu bar
|
||||
[NSMenu setMenuBarVisible:NO];
|
||||
}
|
||||
|
||||
if (myPrevMode != *fullscreenMode)
|
||||
{
|
||||
// Switch to the wished display mode
|
||||
myPrevMode = *fullscreenMode;
|
||||
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
|
||||
}
|
||||
|
||||
if (myFullscreenWrapper)
|
||||
{
|
||||
[[myFullscreenWrapper window] close];
|
||||
}
|
||||
|
||||
// Open and center the window
|
||||
[[aWindow window] makeKeyAndOrderFront:nil];
|
||||
[[aWindow window] center];
|
||||
|
||||
#if ENABLE_FADE_OPERATIONS
|
||||
// Fade to normal screen
|
||||
[self doFadeOperation:CleanScreen time:0.2f sync:false];
|
||||
#endif
|
||||
|
||||
// Save the fullscreen wrapper
|
||||
myFullscreenWrapper = aWindow;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Inconcistency error for arguments given to -[sfPrivAppController setFullscreenWindow:mode:]" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Perform fade operation where 'operation' is one of {FillScreen, CleanScreen}
|
||||
/// and 'time' is the time during which you wish the operation to be performed.
|
||||
/// Set 'sync' to true if you do not want the method to end before the end
|
||||
/// of the fade operation. Pass the last used token or a new one if you are
|
||||
/// using this method for the first time. This lets the method release some
|
||||
/// resources when doing CleanScreen operation.
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void) doFadeOperation:(int)operation time:(float)time sync:(bool)sync
|
||||
{
|
||||
static CGDisplayFadeReservationToken prevToken = kCGDisplayFadeReservationInvalidToken;
|
||||
CGDisplayFadeReservationToken token = prevToken;
|
||||
|
||||
CGError result = 0, capture = 0;
|
||||
|
||||
if (operation == FillScreen) {
|
||||
// Get access for the fade operation
|
||||
result = CGAcquireDisplayFadeReservation((int)(3 + time), &token);
|
||||
|
||||
if (!result) {
|
||||
// Capture display but do not fill the screen with black
|
||||
// so that we can see the fade operation
|
||||
capture = CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoFill);
|
||||
|
||||
if (!capture) {
|
||||
// Do the increasing fade operation
|
||||
CGDisplayFade(token, time,
|
||||
kCGDisplayBlendNormal,
|
||||
kCGDisplayBlendSolidColor,
|
||||
0.0f, 0.0f, 0.0f, sync);
|
||||
|
||||
// Now, release the non black-filling capture
|
||||
CGDisplayRelease([sfPrivAppController primaryScreen]);
|
||||
|
||||
// And capture with filling
|
||||
// so that we don't see the switching in the meantime
|
||||
CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoOptions);
|
||||
}
|
||||
|
||||
prevToken = token;
|
||||
}
|
||||
} else if (operation == CleanScreen) {
|
||||
// Get access for the fade operation
|
||||
if (token == kCGDisplayFadeReservationInvalidToken)
|
||||
result = CGAcquireDisplayFadeReservation((int)(3 + time), &token);
|
||||
|
||||
if (!result) {
|
||||
if (!capture) {
|
||||
// Release the black-filling capture
|
||||
CGDisplayRelease([sfPrivAppController primaryScreen]);
|
||||
|
||||
// Capture the display but do not fill with black (still for the fade operation)
|
||||
CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoFill);
|
||||
|
||||
// Do the decreasing fading
|
||||
CGDisplayFade(token, time,
|
||||
kCGDisplayBlendSolidColor,
|
||||
kCGDisplayBlendNormal,
|
||||
0.0f, 0.0f, 0.0f, sync);
|
||||
|
||||
// Release the fade operation token
|
||||
CGReleaseDisplayFadeReservation(token);
|
||||
|
||||
// Invalidate the given token
|
||||
prevToken = kCGDisplayFadeReservationInvalidToken;
|
||||
}
|
||||
|
||||
// Release the captured display
|
||||
CGDisplayRelease([sfPrivAppController primaryScreen]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the desktop video mode (made at the instance initialization)
|
||||
////////////////////////////////////////////////////////////
|
||||
- (const sf::VideoMode&)desktopMode
|
||||
{
|
||||
return myDesktopMode;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Window independant OpenGL context class
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface sfPrivGLContext : NSOpenGLContext
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the shared OpenGL context instance (making one if needed)
|
||||
////////////////////////////////////////////////////////////
|
||||
+ (id)sharedContext;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Make a new OpenGL context according to the @attribs settings
|
||||
/// and the shared context @context
|
||||
////////////////////////////////////////////////////////////
|
||||
- (id)initWithAttributes:(sf::WindowSettings&)attribs
|
||||
sharedContext:(sfPrivGLContext *)context;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Customized Cocoa OpenGL view
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface sfPrivGLView : NSOpenGLView
|
||||
{
|
||||
sf::priv::WindowImplCocoa *myDelegate;
|
||||
sfPrivGLContext *myGLContext;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Make a new view according the the rect @frame,
|
||||
/// the video mode @mode, the window settings @settings
|
||||
/// @delegate must not be null
|
||||
////////////////////////////////////////////////////////////
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
mode:(const sf::VideoMode&)mode
|
||||
settings:(sf::WindowSettings&)settings;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Sets @aDelegate as the view delegate
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Returns the view delegate
|
||||
////////////////////////////////////////////////////////////
|
||||
- (sf::priv::WindowImplCocoa *)delegate;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Finish view setting (after having added it to the window)
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)finishInitialization;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward call to en/disable vertical synchronization
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)enableVerticalSync:(bool)flag;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward call to set the OpenGL context as active according to @flag
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setActive:(bool)flag;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward call to flush the OpenGL context
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)flushBuffer;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Parent class for handling general SFML window stuff
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface sfPrivWindow : NSObject
|
||||
{
|
||||
@private
|
||||
NSWindow *myWindow;
|
||||
sfPrivGLView *myView;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return a reference to the internal Cocoa window
|
||||
////////////////////////////////////////////////////////////
|
||||
- (NSWindow *)window;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return a reference to the internal Cocoa OpenGL view
|
||||
////////////////////////////////////////////////////////////
|
||||
- (sfPrivGLView *)view;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Sets @aDelegate as the window delegate
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Returns the window delegate
|
||||
////////////////////////////////////////////////////////////
|
||||
- (sf::priv::WindowImplCocoa *)delegate;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward call to set the window position on screen
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setPosition:(NSPoint)pos;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward call to set the window size
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setSize:(NSSize)size;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the mouse location relative to the internal window
|
||||
////////////////////////////////////////////////////////////
|
||||
- (NSPoint)mouseLocation;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return whether the mouse is on our window
|
||||
////////////////////////////////////////////////////////////
|
||||
- (BOOL)mouseInside;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Close or open the window
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)show:(bool)flag;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward call to en/disable the OpenGL view vertical synchronization
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)enableVerticalSync:(bool)flag;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward 'setActive' call the the OpenGL view
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)setActive:(bool)flag;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Forward call to flush the OpenGL view
|
||||
////////////////////////////////////////////////////////////
|
||||
- (void)flushBuffer;
|
||||
|
||||
@end
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Class for creating new SFML windows from informations
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface sfPrivOwnedWindow : sfPrivWindow
|
||||
{
|
||||
@private
|
||||
sf::VideoMode myFullscreenMode;
|
||||
bool myIsFullscreen;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Creates and returns a new SFML window handler with
|
||||
/// the given parameters
|
||||
////////////////////////////////////////////////////////////
|
||||
- (id)initWithVideoMode:(sf::VideoMode&)aMode
|
||||
settings:(sf::WindowSettings&)someSettings
|
||||
style:(unsigned long)aStyle
|
||||
title:(NSString *)aTitle;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Returns the window's fullscreen state
|
||||
////////////////////////////////////////////////////////////
|
||||
- (BOOL)isFullscreen;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Class for creating SFML windows from Cocoa windows
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface sfPrivImportedWindow : sfPrivWindow
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Returns a new SFML window handler with the given window
|
||||
/// and parameters
|
||||
////////////////////////////////////////////////////////////
|
||||
- (id)initWithWindow:(NSWindow *)aWindow
|
||||
settings:(sf::WindowSettings&)someSettings;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Class for creating SFML windows from Cocoa views
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface sfPrivImportedView : sfPrivWindow
|
||||
{
|
||||
NSView *parentView;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Returns a new SFML window handler with the given view
|
||||
/// and parameters
|
||||
////////////////////////////////////////////////////////////
|
||||
- (id)initWithView:(NSView *)aView
|
||||
settings:(sf::WindowSettings&)someSettings;
|
||||
|
||||
@end
|
File diff suppressed because it is too large
Load diff
|
@ -1,77 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Joystick.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Initialize the instance and bind it to a physical joystick
|
||||
////////////////////////////////////////////////////////////
|
||||
void Joystick::Initialize(unsigned int Index)
|
||||
{
|
||||
// Reset the joystick state
|
||||
|
||||
// Initialize the Index-th available joystick
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Update the current joystick and return its new state
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickState Joystick::UpdateState()
|
||||
{
|
||||
// Fill a JoystickState instance with the current joystick state
|
||||
JoystickState s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Check if the joystick supports the given axis
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Joystick::HasAxis(Joy::Axis Axis) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the number of buttons supported by the joystick
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Joystick::GetButtonsCount() const
|
||||
{
|
||||
// Return number of supported buttons
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
|
@ -1,84 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_JOYSTICKCARBON_HPP
|
||||
#define SFML_JOYSTICKCARBON_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// ****** implementation of Joystick (unknown implementation kind for now)
|
||||
////////////////////////////////////////////////////////////
|
||||
class Joystick
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Initialize the instance and bind it to a physical joystick
|
||||
///
|
||||
/// \param Index : Index of the physical joystick to bind to
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Initialize(unsigned int Index);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Update the current joystick and return its new state
|
||||
///
|
||||
/// \return Current state of the joystick
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickState UpdateState();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Check if the joystick supports the given axis
|
||||
///
|
||||
/// \param Axis : Axis to check
|
||||
///
|
||||
/// \return True of the axis is supported, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool HasAxis(Joy::Axis Axis) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get the number of buttons supported by the joystick
|
||||
///
|
||||
/// \return Number of buttons
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int GetButtonsCount() const;
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_JOYSTICKCARBON_HPP
|
|
@ -1,101 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/VideoModeImpl.hpp>
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get supported video modes
|
||||
////////////////////////////////////////////////////////////
|
||||
void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
|
||||
{
|
||||
// Ceylo -- using same implementation as in OSXCarbon
|
||||
|
||||
// First, clear array to fill
|
||||
Modes.clear();
|
||||
|
||||
// Enumerate all available video modes for primary display adapter
|
||||
CFArrayRef DisplayModes = CGDisplayAvailableModes( kCGDirectMainDisplay );
|
||||
CFIndex DisplayModeCount = CFArrayGetCount( DisplayModes );
|
||||
CFDictionaryRef CurrentMode;
|
||||
|
||||
for (int Count = 0; Count < DisplayModeCount; ++Count)
|
||||
{
|
||||
CurrentMode = (CFDictionaryRef)CFArrayGetValueAtIndex( DisplayModes, Count );
|
||||
|
||||
VideoMode Mode;
|
||||
|
||||
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayWidth), kCFNumberIntType, &(Mode.Width));
|
||||
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayHeight), kCFNumberIntType, &(Mode.Height));
|
||||
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayBitsPerPixel), kCFNumberIntType, &(Mode.BitsPerPixel));
|
||||
|
||||
// Add it only if it is not already in the array
|
||||
if (std::find(Modes.begin(), Modes.end(), Mode) == Modes.end())
|
||||
Modes.push_back(Mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Get current desktop video mode
|
||||
////////////////////////////////////////////////////////////
|
||||
VideoMode VideoModeSupport::GetDesktopVideoMode()
|
||||
{
|
||||
// Ceylo -- using same implementation as in OSXCarbon
|
||||
|
||||
CFDictionaryRef CurrentVideoMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
|
||||
|
||||
VideoMode DesktopMode;
|
||||
|
||||
|
||||
// Get video mode width
|
||||
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentVideoMode, kCGDisplayWidth),
|
||||
kCFNumberIntType,
|
||||
&(DesktopMode.Width));
|
||||
|
||||
// Get video mode height
|
||||
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentVideoMode, kCGDisplayHeight),
|
||||
kCFNumberIntType,
|
||||
&(DesktopMode.Height));
|
||||
|
||||
// Get video mode depth
|
||||
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentVideoMode, kCGDisplayBitsPerPixel),
|
||||
kCFNumberIntType,
|
||||
&(DesktopMode.BitsPerPixel));
|
||||
|
||||
|
||||
return DesktopMode;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
|
@ -1,205 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SFML_WINDOWIMPLCOCOA_HPP
|
||||
#define SFML_WINDOWIMPLCOCOA_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Event.hpp>
|
||||
#include <SFML/Window/WindowImpl.hpp>
|
||||
#include <string>
|
||||
|
||||
#ifdef __OBJC__
|
||||
@class sfPrivWindow;
|
||||
typedef sfPrivWindow* sfPrivWindowRef;
|
||||
#else
|
||||
typedef void* sfPrivWindowRef;
|
||||
#endif
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// WindowImplCocoa is the Cocoa implementation of WindowImpl
|
||||
////////////////////////////////////////////////////////////
|
||||
class WindowImplCocoa : public WindowImpl
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
/// (creates a dummy window to provide a valid OpenGL context)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Construct the window implementation from an existing control
|
||||
///
|
||||
/// \param Handle : Platform-specific handle of the control
|
||||
/// \param Params : Creation parameters
|
||||
///
|
||||
/// Note: the NSWindow object must not be defered !
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa(WindowHandle Handle, WindowSettings& params);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create the window implementation
|
||||
///
|
||||
/// \param Mode : Video mode to use
|
||||
/// \param Title : Title of the window
|
||||
/// \param WindowStyle : Window style
|
||||
/// \param Params : Creation parameters
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& params);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~WindowImplCocoa();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Check if there's an active context on the current thread
|
||||
///
|
||||
/// \return True if there's a context bound to the current thread
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool IsContextActive();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle an event sent by the default NSNotificationCenter
|
||||
////////////////////////////////////////////////////////////
|
||||
void HandleNotifiedEvent(Event& eventRef);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Event handling for every event type.
|
||||
/// 'eventRef' is a NSEvent.
|
||||
////////////////////////////////////////////////////////////
|
||||
void HandleKeyDown(void *eventRef);
|
||||
void HandleKeyUp(void *eventRef);
|
||||
void HandleModifierKey(void *eventRef);
|
||||
void HandleMouseDown(void *eventRef);
|
||||
void HandleMouseUp(void *eventRef);
|
||||
void HandleMouseMove(void *eventRef);
|
||||
void HandleMouseWheel(void *eventRef);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return whether 'ev' must be considered as a TextEntered event
|
||||
////////////////////////////////////////////////////////////
|
||||
static bool IsTextEvent(void *event);
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::Display
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void Display();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::ProcessEvents
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void ProcessEvents();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::MakeActive
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetActive(bool Active = true) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::UseVerticalSync
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void UseVerticalSync(bool Enabled);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::ShowMouseCursor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void ShowMouseCursor(bool Show);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::SetCursorPosition
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetCursorPosition(unsigned int Left, unsigned int Top);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::SetPosition
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetPosition(int Left, int Top);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see WindowImpl::SetSize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetSize(unsigned int Width, unsigned int Height);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::Show
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void Show(bool State);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::EnableKeyRepeat
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void EnableKeyRepeat(bool Enabled);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::SetIcon
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels);
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// My own part starts here !
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
sfPrivWindowRef myWrapper;
|
||||
bool myUseKeyRepeat;
|
||||
bool myMouseIn;
|
||||
float myWheelStatus;
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
#endif // SFML_WINDOWIMPLCOCOA_HPP
|
|
@ -1,844 +0,0 @@
|
|||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SFML - Simple and Fast Multimedia Library
|
||||
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied warranty.
|
||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it freely,
|
||||
// subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented;
|
||||
// you must not claim that you wrote the original software.
|
||||
// If you use this software in a product, an acknowledgment
|
||||
// in the product documentation would be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such,
|
||||
// and must not be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source distribution.
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
|
||||
#import <SFML/Window/Cocoa/AppController.h>
|
||||
#import <SFML/Window/Cocoa/GLKit.h>
|
||||
#import <SFML/Window/WindowStyle.hpp>
|
||||
#import <SFML/System.hpp>
|
||||
#import <iostream>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
|
||||
// Do something only once (useful in loops)
|
||||
#define ONCE(make) \
|
||||
{ static int __done = 0;\
|
||||
if (!__done) {\
|
||||
make;\
|
||||
__done = 1;\
|
||||
} }
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Private function declarations
|
||||
////////////////////////////////////////////////////////////
|
||||
namespace {
|
||||
Key::Code KeyForVirtualCode(unsigned short vCode);
|
||||
Key::Code KeyForUnicode(unsigned short uniCode);
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Default constructor
|
||||
/// (creates a dummy window to provide a valid OpenGL context)
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::WindowImplCocoa() :
|
||||
myWrapper(nil),
|
||||
myUseKeyRepeat(false),
|
||||
myMouseIn(false),
|
||||
myWheelStatus(0.0f)
|
||||
{
|
||||
[sfPrivAppController sharedController];
|
||||
|
||||
// Create the shared OpenGL context
|
||||
if ([sfPrivGLContext sharedContext]) {
|
||||
// Then we make it the current active OpenGL context
|
||||
SetActive();
|
||||
} else {
|
||||
std::cerr << "Unable to make the main shared OpenGL context" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create the window implementation from an existing control
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::WindowImplCocoa(WindowHandle Handle, WindowSettings& params) :
|
||||
myWrapper(NULL),
|
||||
myUseKeyRepeat(false),
|
||||
myMouseIn(false),
|
||||
myWheelStatus(0.0f)
|
||||
{
|
||||
if (Handle) {
|
||||
// Classical window import
|
||||
if ([(id)Handle isKindOfClass:[NSWindow class]]) {
|
||||
myWrapper = [[sfPrivImportedWindow alloc]
|
||||
initWithWindow:(NSWindow *)Handle
|
||||
settings:params];
|
||||
}
|
||||
// Qt "window" import
|
||||
else if ([(id)Handle isKindOfClass:[NSView class]]) {
|
||||
myWrapper = [[sfPrivImportedView alloc]
|
||||
initWithView:(NSView *)Handle
|
||||
settings:params];
|
||||
} else {
|
||||
std::cerr
|
||||
<< "Cannot import this Window Handle because it is neither"
|
||||
<< "a <NSWindow *> nor <NSView *> object"
|
||||
<< "(or any of its subclasses). You gave a <"
|
||||
<< [[(id)Handle className] UTF8String]
|
||||
<< "> object."
|
||||
<< std::endl;
|
||||
|
||||
}
|
||||
|
||||
if (myWrapper) {
|
||||
[myWrapper setDelegate:this];
|
||||
|
||||
// initial mouse state
|
||||
myMouseIn = [myWrapper mouseInside];
|
||||
|
||||
// We set the myWidth and myHeight members to the correct values
|
||||
myWidth = (int) [[myWrapper view] frame].size.width;
|
||||
myHeight = (int) [[myWrapper view] frame].size.height;
|
||||
} else {
|
||||
std::cerr << "Failed to make the public window" << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cerr
|
||||
<< "Invalid null handle given to "
|
||||
<< "Window::Window(WindowHandle Handle, const WindowSettings& Params)"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Create the window implementation
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::WindowImplCocoa(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& params) :
|
||||
myWrapper(NULL),
|
||||
myUseKeyRepeat(false),
|
||||
myMouseIn(false),
|
||||
myWheelStatus(0.0f)
|
||||
{
|
||||
// Create a new window with given size, title and style
|
||||
// First we define some objects used for our window
|
||||
NSString *title = [NSString stringWithCString:(Title.c_str()) ? (Title.c_str()) : ""
|
||||
encoding:NSASCIIStringEncoding];
|
||||
|
||||
// We create the window
|
||||
myWrapper = [[sfPrivOwnedWindow alloc]
|
||||
initWithVideoMode:Mode
|
||||
settings:params
|
||||
style:WindowStyle
|
||||
title:title];
|
||||
|
||||
|
||||
|
||||
if (myWrapper)
|
||||
{
|
||||
[myWrapper setDelegate:this];
|
||||
|
||||
// initial mouse state
|
||||
myMouseIn = [myWrapper mouseInside];
|
||||
|
||||
// We set the myWidth and myHeight members to the correct values
|
||||
myWidth = Mode.Width;
|
||||
myHeight = Mode.Height;
|
||||
} else {
|
||||
std::cerr << "Failed to make the public window" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Destructor
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::~WindowImplCocoa()
|
||||
{
|
||||
// Release the window wrapper
|
||||
[myWrapper release];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Check if there's an active context on the current thread
|
||||
////////////////////////////////////////////////////////////
|
||||
bool WindowImplCocoa::IsContextActive()
|
||||
{
|
||||
return ([NSOpenGLContext currentContext] != NULL);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle event sent by the default NSNotificationCenter
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleNotifiedEvent(Event& event)
|
||||
{
|
||||
// Set myWidth and myHeight to correct value if
|
||||
// window size changed
|
||||
switch (event.Type) {
|
||||
case Event::Resized:
|
||||
myWidth = event.Size.Width;
|
||||
myHeight = event.Size.Height;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// And send the event
|
||||
SendEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle a key down event (NSEvent)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleKeyDown(void *eventRef)
|
||||
{
|
||||
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
|
||||
|
||||
Event sfEvent;
|
||||
unichar chr = 0, rawchr = 0;
|
||||
unsigned long length = [[event characters] length];
|
||||
unsigned mods = [event modifierFlags];
|
||||
|
||||
if (length) {
|
||||
chr = [[event characters] characterAtIndex:0];
|
||||
|
||||
// Note : I got a crash (out of bounds exception) while typing so now I test...
|
||||
if ([[event charactersIgnoringModifiers] length])
|
||||
rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0];
|
||||
|
||||
|
||||
// Don't handle repeated events if we chose not to send them
|
||||
if (!myUseKeyRepeat && [event isARepeat])
|
||||
return;
|
||||
|
||||
// Is it also a text event ?
|
||||
if (IsTextEvent(event)) {
|
||||
// buffer for the UTF-32 characters
|
||||
Uint32 utf32Characters[2] = {0};
|
||||
|
||||
// convert the characters
|
||||
// note: using CFString in order to keep compatibility with Mac OS X 10.4
|
||||
// (as NSUTF32StringEncoding is only being defined in Mac OS X 10.5 and later)
|
||||
if (!CFStringGetCString ((CFStringRef)[event characters],
|
||||
(char *)utf32Characters,
|
||||
sizeof(utf32Characters),
|
||||
kCFStringEncodingUTF32))
|
||||
{
|
||||
char asciiChar[3] = {0};
|
||||
if ([[event characters] lengthOfBytesUsingEncoding:NSASCIIStringEncoding])
|
||||
[[event characters] getCString:asciiChar
|
||||
maxLength:3
|
||||
encoding:NSASCIIStringEncoding];
|
||||
|
||||
std::cerr << "Error while converting character to UTF32 : \""
|
||||
<< asciiChar << "\"" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
sfEvent.Type = Event::TextEntered;
|
||||
sfEvent.Text.Unicode = utf32Characters[0];
|
||||
|
||||
SendEvent(sfEvent);
|
||||
}
|
||||
}
|
||||
|
||||
// Anyway it's also a KeyPressed event
|
||||
sfEvent.Type = Event::KeyPressed;
|
||||
|
||||
// Get the keys
|
||||
if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) {
|
||||
sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
|
||||
}
|
||||
|
||||
// Get the modifiers
|
||||
sfEvent.Key.Alt = mods & NSAlternateKeyMask;
|
||||
sfEvent.Key.Control = mods & NSControlKeyMask;
|
||||
sfEvent.Key.Shift = mods & NSShiftKeyMask;
|
||||
|
||||
// Send the event
|
||||
SendEvent(sfEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle a key up event (NSEvent)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleKeyUp(void *eventRef)
|
||||
{
|
||||
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
|
||||
|
||||
Event sfEvent;
|
||||
unsigned mods = [event modifierFlags];
|
||||
unichar chr = 0, rawchr = 0;
|
||||
|
||||
if ([[event characters] length]) {
|
||||
chr = [[event characters] characterAtIndex:0];
|
||||
|
||||
if ([[event charactersIgnoringModifiers] length])
|
||||
rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0];
|
||||
|
||||
sfEvent.Type = Event::KeyReleased;
|
||||
|
||||
// Get the code
|
||||
if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) {
|
||||
sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
|
||||
}
|
||||
|
||||
// Get the modifiers
|
||||
sfEvent.Key.Alt = mods & NSAlternateKeyMask;
|
||||
sfEvent.Key.Control = mods & NSControlKeyMask;
|
||||
sfEvent.Key.Shift = mods & NSShiftKeyMask;
|
||||
|
||||
// Send the event
|
||||
SendEvent(sfEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle a key modifier event [Command, Option, Control, Shift]
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleModifierKey(void *eventRef)
|
||||
{
|
||||
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
|
||||
Event sfEvent;
|
||||
unsigned mods = [event modifierFlags];
|
||||
|
||||
sfEvent.Type = Event::KeyPressed;
|
||||
|
||||
// Get the code
|
||||
sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
|
||||
|
||||
// Get the modifiers
|
||||
sfEvent.Key.Alt = mods & NSAlternateKeyMask;
|
||||
sfEvent.Key.Control = mods & NSControlKeyMask;
|
||||
sfEvent.Key.Shift = mods & NSShiftKeyMask;
|
||||
|
||||
// Guess whether it's a pressed or released event
|
||||
// Note: this does not work fine is both left and right modifiers are pressed
|
||||
// I did not find any way to fix this.
|
||||
// TODO: fix handling of modifier flags for use of left and right key at the same time
|
||||
if (!(mods & NSAlternateKeyMask) &&
|
||||
(sfEvent.Key.Code == Key::LAlt || sfEvent.Key.Code == Key::RAlt)) {
|
||||
sfEvent.Type = Event::KeyReleased;
|
||||
}
|
||||
|
||||
if (!(mods & NSControlKeyMask) &&
|
||||
(sfEvent.Key.Code == Key::LControl || sfEvent.Key.Code == Key::RControl)) {
|
||||
sfEvent.Type = Event::KeyReleased;
|
||||
}
|
||||
|
||||
if (!(mods & NSShiftKeyMask) &&
|
||||
(sfEvent.Key.Code == Key::LShift || sfEvent.Key.Code == Key::RShift)) {
|
||||
sfEvent.Type = Event::KeyReleased;
|
||||
}
|
||||
|
||||
if (!(mods & NSCommandKeyMask) &&
|
||||
(sfEvent.Key.Code == Key::LSystem || sfEvent.Key.Code == Key::RSystem)) {
|
||||
sfEvent.Type = Event::KeyReleased;
|
||||
}
|
||||
|
||||
// Send the event
|
||||
SendEvent(sfEvent);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle a mouse down event (NSEvent)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleMouseDown(void *eventRef)
|
||||
{
|
||||
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
|
||||
Event sfEvent;
|
||||
|
||||
// Get mouse position relative to the window
|
||||
NSPoint loc = [myWrapper mouseLocation];
|
||||
unsigned mods = [event modifierFlags];
|
||||
|
||||
switch ([event type]) {
|
||||
case NSLeftMouseDown:
|
||||
sfEvent.Type = Event::MouseButtonPressed;
|
||||
|
||||
// Guess whether it's a mouse left or mouse right event
|
||||
if (mods & NSControlKeyMask) {
|
||||
sfEvent.MouseButton.Button = Mouse::Right;
|
||||
} else {
|
||||
sfEvent.MouseButton.Button = Mouse::Left;
|
||||
}
|
||||
|
||||
sfEvent.MouseButton.X = (int) loc.x;
|
||||
sfEvent.MouseButton.Y = (int) loc.y;
|
||||
|
||||
// Send the event
|
||||
SendEvent(sfEvent);
|
||||
break;
|
||||
|
||||
case NSRightMouseDown:
|
||||
sfEvent.Type = Event::MouseButtonPressed;
|
||||
sfEvent.MouseButton.Button = Mouse::Right;
|
||||
|
||||
sfEvent.MouseButton.X = (int) loc.x;
|
||||
sfEvent.MouseButton.Y = (int) loc.y;
|
||||
|
||||
// Send the event
|
||||
SendEvent(sfEvent);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle a mouse up event (NSEvent)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleMouseUp(void *eventRef)
|
||||
{
|
||||
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
|
||||
Event sfEvent;
|
||||
|
||||
// Get mouse position relative to the window
|
||||
NSPoint loc = [myWrapper mouseLocation];
|
||||
unsigned mods = [event modifierFlags];
|
||||
|
||||
switch ([event type]) {
|
||||
case NSLeftMouseUp:
|
||||
sfEvent.Type = Event::MouseButtonReleased;
|
||||
|
||||
// Guess whether it's a mouse left or mouse right event
|
||||
if (mods & NSControlKeyMask) {
|
||||
sfEvent.MouseButton.Button = Mouse::Right;
|
||||
} else {
|
||||
sfEvent.MouseButton.Button = Mouse::Left;
|
||||
}
|
||||
|
||||
sfEvent.MouseButton.X = (int) loc.x;
|
||||
sfEvent.MouseButton.Y = (int) loc.y;
|
||||
|
||||
// Send the event
|
||||
SendEvent(sfEvent);
|
||||
break;
|
||||
|
||||
case NSRightMouseUp:
|
||||
sfEvent.Type = Event::MouseButtonReleased;
|
||||
sfEvent.MouseButton.Button = Mouse::Right;
|
||||
|
||||
sfEvent.MouseButton.X = (int) loc.x;
|
||||
sfEvent.MouseButton.Y = (int) loc.y;
|
||||
|
||||
// Send the event
|
||||
SendEvent(sfEvent);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle a mouse move event (NSEvent)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleMouseMove(void *eventRef)
|
||||
{
|
||||
Event sfEvent;
|
||||
NSPoint loc = [myWrapper mouseLocation];
|
||||
sfEvent.Type = Event::MouseMoved;
|
||||
|
||||
sfEvent.MouseMove.X = (int) loc.x;
|
||||
sfEvent.MouseMove.Y = (int) loc.y;
|
||||
|
||||
SendEvent(sfEvent);
|
||||
|
||||
if ([myWrapper mouseInside] && !myMouseIn) {
|
||||
// If mouse IS inside but WAS not inside last time
|
||||
sfEvent.Type = Event::MouseEntered;
|
||||
myMouseIn = true;
|
||||
|
||||
SendEvent(sfEvent);
|
||||
} else if (![myWrapper mouseInside] && myMouseIn) {
|
||||
// Is mouse WAS not inside but IS now inside
|
||||
sfEvent.Type = Event::MouseLeft;
|
||||
myMouseIn = false;
|
||||
|
||||
SendEvent(sfEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Handle a mouse wheel event (NSEvent)
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::HandleMouseWheel(void *eventRef)
|
||||
{
|
||||
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
|
||||
|
||||
// SFML uses integer values for delta but Cocoa uses float and it is mostly fewer than 1.0
|
||||
// Therefore I chose to add the float value to a 'wheel status' and
|
||||
// send a sf event only when it's greater than 1.0
|
||||
myWheelStatus += [event deltaY];
|
||||
|
||||
if (fabs(myWheelStatus) > 1.0f) {
|
||||
// Make the event and send it
|
||||
Event sfEvent;
|
||||
sfEvent.Type = Event::MouseWheelMoved;
|
||||
sfEvent.MouseWheel.Delta = (int) myWheelStatus;
|
||||
SendEvent(sfEvent);
|
||||
|
||||
// Remove as much integer units as the one that have been put in the event
|
||||
// (was a mistake to set this to 0)
|
||||
myWheelStatus -= (int) myWheelStatus;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return whether 'ev' must be considered as a TextEntered event
|
||||
////////////////////////////////////////////////////////////
|
||||
bool WindowImplCocoa::IsTextEvent(void *eventRef)
|
||||
{
|
||||
NSEvent *event = (NSEvent *)eventRef;
|
||||
bool res = false;
|
||||
|
||||
if (event && [event type] == NSKeyDown && [[event characters] length]) {
|
||||
unichar code = [[event characters] characterAtIndex:0];
|
||||
|
||||
// Codes from 0xF700 to 0xF8FF are non text keys (see NSEvent.h)
|
||||
// 0x35 is the Escape key
|
||||
if ([event keyCode] != 0x35 && (code < 0xF700 || code > 0xF8FF))
|
||||
res = true;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::Display
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::Display()
|
||||
{
|
||||
// Forward flush call to the window
|
||||
[myWrapper flushBuffer];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::ProcessEvents
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::ProcessEvents()
|
||||
{
|
||||
// Forward event handling call to the application controller
|
||||
[[sfPrivAppController sharedController] processEvents];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::MakeActive
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetActive(bool Active) const
|
||||
{
|
||||
// Forward the call to the window
|
||||
if (myWrapper)
|
||||
[myWrapper setActive:Active];
|
||||
else {
|
||||
// Or directly activate the shared OpenGL context if we're not using a window
|
||||
if (Active) {
|
||||
if ([NSOpenGLContext currentContext] != [sfPrivGLContext sharedContext])
|
||||
[[sfPrivGLContext sharedContext] makeCurrentContext];
|
||||
} else {
|
||||
if ([NSOpenGLContext currentContext] == [sfPrivGLContext sharedContext])
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::UseVerticalSync
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::UseVerticalSync(bool Enabled)
|
||||
{
|
||||
// Forward the call to the window
|
||||
[myWrapper enableVerticalSync:Enabled];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::ShowMouseCursor
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::ShowMouseCursor(bool flag)
|
||||
{
|
||||
if (flag) {
|
||||
[NSCursor unhide];
|
||||
} else {
|
||||
[NSCursor hide];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::SetCursorPosition
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top)
|
||||
{
|
||||
NSPoint pos = NSMakePoint ((float) Left, (float) Top);
|
||||
|
||||
if (myWrapper) {
|
||||
// Flip for SFML window coordinate system
|
||||
pos.y = [[myWrapper window] frame].size.height - pos.y;
|
||||
|
||||
// Adjust for view reference instead of window
|
||||
pos.y -= [[myWrapper window] frame].size.height - [[myWrapper view] frame].size.height;
|
||||
|
||||
// Convert to screen coordinates
|
||||
NSPoint absolute = [[myWrapper window] convertBaseToScreen:pos];
|
||||
|
||||
// Flip screen coodinates
|
||||
absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y;
|
||||
|
||||
// Move cursor
|
||||
CGDisplayMoveCursorToPoint([sfPrivAppController primaryScreen],
|
||||
CGPointMake(absolute.x, absolute.y));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::SetPosition
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetPosition(int Left, int Top)
|
||||
{
|
||||
[myWrapper setPosition:NSMakePoint(Left, Top)];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see WindowImpl::SetSize
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetSize(unsigned int Width, unsigned int Height)
|
||||
{
|
||||
[myWrapper setSize:NSMakeSize(Width, Height)];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::Show
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::Show(bool State)
|
||||
{
|
||||
[myWrapper show:State];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// /see sfWindowImpl::EnableKeyRepeat
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::EnableKeyRepeat(bool Enabled)
|
||||
{
|
||||
myUseKeyRepeat = Enabled;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// see WindowImpl::SetIcon
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels)
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the SFML key corresponding to a key code
|
||||
////////////////////////////////////////////////////////////
|
||||
Key::Code KeyForVirtualCode(unsigned short vCode)
|
||||
{
|
||||
static struct {
|
||||
unsigned short code;
|
||||
Key::Code sfKey;
|
||||
} virtualTable[] =
|
||||
{
|
||||
{0x35, Key::Escape},
|
||||
{0x31, Key::Space},
|
||||
{0x24, Key::Return}, // main Return key
|
||||
{0x4C, Key::Return}, // pav Return key
|
||||
{0x33, Key::Back},
|
||||
{0x30, Key::Tab},
|
||||
{0x74, Key::PageUp},
|
||||
{0x79, Key::PageDown},
|
||||
{0x77, Key::End},
|
||||
{0x73, Key::Home},
|
||||
{0x72, Key::Insert},
|
||||
{0x75, Key::Delete},
|
||||
{0x45, Key::Add},
|
||||
{0x4E, Key::Subtract},
|
||||
{0x43, Key::Multiply},
|
||||
{0x4B, Key::Divide},
|
||||
|
||||
{0x7A, Key::F1}, {0x78, Key::F2}, {0x63, Key::F3},
|
||||
{0x76, Key::F4}, {0x60, Key::F5}, {0x61, Key::F6},
|
||||
{0x62, Key::F7}, {0x64, Key::F8}, {0x65, Key::F9},
|
||||
{0x6D, Key::F10}, {0x67, Key::F11}, {0x6F, Key::F12},
|
||||
{0x69, Key::F13}, {0x6B, Key::F14}, {0x71, Key::F15},
|
||||
|
||||
{0x7B, Key::Left},
|
||||
{0x7C, Key::Right},
|
||||
{0x7E, Key::Up},
|
||||
{0x7D, Key::Down},
|
||||
|
||||
{0x52, Key::Numpad0}, {0x53, Key::Numpad1}, {0x54, Key::Numpad2},
|
||||
{0x55, Key::Numpad3}, {0x56, Key::Numpad4}, {0x57, Key::Numpad5},
|
||||
{0x58, Key::Numpad6}, {0x59, Key::Numpad7}, {0x5B, Key::Numpad8},
|
||||
{0x5C, Key::Numpad9},
|
||||
|
||||
{0x1D, Key::Num0}, {0x12, Key::Num1}, {0x13, Key::Num2},
|
||||
{0x14, Key::Num3}, {0x15, Key::Num4}, {0x17, Key::Num5},
|
||||
{0x16, Key::Num6}, {0x1A, Key::Num7}, {0x1C, Key::Num8},
|
||||
{0x19, Key::Num9},
|
||||
|
||||
{0x3B, Key::LControl}, //< Left Ctrl
|
||||
{0x3A, Key::LAlt}, //< Left Option/Alt
|
||||
{0x37, Key::LSystem}, //< Left Command
|
||||
{0x38, Key::LShift}, //< Left Shift
|
||||
{0x3E, Key::RControl}, //< Right Ctrl
|
||||
{0x3D, Key::RAlt}, //< Right Option/Alt
|
||||
{0x36, Key::RSystem}, //< Right Command
|
||||
{0x3C, Key::RShift}, //< Right Shift
|
||||
|
||||
{0x39, Key::Code(0)} //< Caps Lock (not handled by SFML for now)
|
||||
};
|
||||
|
||||
Key::Code result = Key::Code(0);
|
||||
|
||||
for (unsigned i = 0;virtualTable[i].code;i++) {
|
||||
if (virtualTable[i].code == vCode) {
|
||||
result = virtualTable[i].sfKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Return the SFML key corresponding to a unicode code
|
||||
////////////////////////////////////////////////////////////
|
||||
Key::Code KeyForUnicode(unsigned short uniCode)
|
||||
{
|
||||
// TODO: find a better way to get the language independant key
|
||||
static struct {
|
||||
unsigned short character;
|
||||
Key::Code sfKey;
|
||||
} unicodeTable[] =
|
||||
{
|
||||
{'!', Key::Code(0)}, //< No Key for this code
|
||||
{'"', Key::Code(0)}, //< No Key for this code
|
||||
{'#', Key::Code(0)}, //< No Key for this code
|
||||
{'$', Key::Code(0)}, //< No Key for this code
|
||||
{'%', Key::Code(0)}, //< No Key for this code
|
||||
{'&', Key::Code(0)}, //< No Key for this code
|
||||
{'\'', Key::Quote},
|
||||
{'(', Key::Code(0)}, //< No Key for this code
|
||||
{')', Key::Code(0)}, //< No Key for this code
|
||||
{'*', Key::Multiply},
|
||||
{'+', Key::Add},
|
||||
{',', Key::Comma},
|
||||
{'-', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'.', Key::Period},
|
||||
{'/', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'0', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'1', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'2', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'3', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'4', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'5', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'6', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'7', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'8', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{'9', Key::Code(0)}, //< Handled by KeyForVirtualCode()
|
||||
{':', Key::Code(0)}, //< No Key for this code
|
||||
{';', Key::SemiColon},
|
||||
{'<', Key::Code(0)}, //< No Key for this code
|
||||
{'=', Key::Equal},
|
||||
{'>', Key::Code(0)}, //< No Key for this code
|
||||
{'?', Key::Code(0)}, //< No Key for this code
|
||||
{'@', Key::Code(0)}, //< No Key for this code
|
||||
{'A', Key::A}, {'B', Key::B}, {'C', Key::C},
|
||||
{'D', Key::D}, {'E', Key::E}, {'F', Key::F},
|
||||
{'G', Key::G}, {'H', Key::H}, {'I', Key::I},
|
||||
{'J', Key::J}, {'K', Key::K}, {'L', Key::L},
|
||||
{'M', Key::M}, {'N', Key::N}, {'O', Key::O},
|
||||
{'P', Key::P}, {'Q', Key::Q}, {'R', Key::R},
|
||||
{'S', Key::S}, {'T', Key::T}, {'U', Key::U},
|
||||
{'V', Key::V}, {'W', Key::W}, {'X', Key::X},
|
||||
{'Y', Key::Y}, {'Z', Key::Z},
|
||||
{'[', Key::LBracket},
|
||||
{'\\', Key::BackSlash},
|
||||
{']', Key::RBracket},
|
||||
{'^', Key::Code(0)}, //< No Key for this code
|
||||
{'_', Key::Code(0)}, //< No Key for this code
|
||||
{'`', Key::Code(0)}, //< No Key for this code
|
||||
{'a', Key::A}, {'b', Key::B}, {'c', Key::C},
|
||||
{'d', Key::D}, {'e', Key::E}, {'f', Key::F},
|
||||
{'g', Key::G}, {'h', Key::H}, {'i', Key::I},
|
||||
{'j', Key::J}, {'k', Key::K}, {'l', Key::L},
|
||||
{'m', Key::M}, {'n', Key::N}, {'o', Key::O},
|
||||
{'p', Key::P}, {'q', Key::Q}, {'r', Key::R},
|
||||
{'s', Key::S}, {'t', Key::T}, {'u', Key::U},
|
||||
{'v', Key::V}, {'w', Key::W}, {'x', Key::X},
|
||||
{'y', Key::Y}, {'z', Key::Z},
|
||||
{'{', Key::Code(0)}, //< No Key for this code
|
||||
{'|', Key::Code(0)}, //< No Key for this code
|
||||
{'}', Key::Code(0)}, //< No Key for this code
|
||||
{'~', Key::Tilde},
|
||||
{0, Key::Code(0)}
|
||||
};
|
||||
|
||||
Key::Code result = Key::Code(0);
|
||||
|
||||
for (unsigned i = 0;unicodeTable[i].character;i++) {
|
||||
if (unicodeTable[i].character == uniCode) {
|
||||
result = unicodeTable[i].sfKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
|
@ -44,8 +44,8 @@
|
|||
|
||||
#elif defined(SFML_SYSTEM_MACOS)
|
||||
|
||||
#include <SFML/Window/Cocoa/AglContext.hpp>
|
||||
typedef sf::priv::AglContext ContextType;
|
||||
#include <SFML/Window/OSX/SFContext.hpp>
|
||||
typedef sf::priv::SFContext ContextType;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ struct JoystickState
|
|||
|
||||
#elif defined(SFML_SYSTEM_MACOS)
|
||||
|
||||
#include <SFML/Window/Cocoa/Joystick.hpp>
|
||||
#include <SFML/Window/OSX/Joystick.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
|
|
48
src/SFML/Window/OSX/Joystick.cpp
Normal file
48
src/SFML/Window/OSX/Joystick.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Joystick.hpp>
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Joystick::Initialize(unsigned int Index)
|
||||
{
|
||||
// Reset the joystick state
|
||||
|
||||
// Initialize the Index-th available joystick
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickState Joystick::UpdateState()
|
||||
{
|
||||
// Fill a JoystickState instance with the current joystick state
|
||||
JoystickState s;
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool Joystick::HasAxis(Joy::Axis Axis) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int Joystick::GetButtonsCount() const
|
||||
{
|
||||
// Return number of supported buttons
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
72
src/SFML/Window/OSX/Joystick.hpp
Normal file
72
src/SFML/Window/OSX/Joystick.hpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
|
||||
|
||||
#ifndef SFML_JOYSTICKOSX_HPP
|
||||
#define SFML_JOYSTICKOSX_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#if USE_OS_X_VERSION_10_6
|
||||
#include <IOKit/hid/IOHIDDevice.h>
|
||||
#endif
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief OSX implementation of Joystick
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class Joystick
|
||||
{
|
||||
public :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Initialize the instance and bind it to a physical joystick
|
||||
///
|
||||
/// \param index Index of the physical joystick to bind to
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void Initialize(unsigned int index);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Update the current joystick and return its new state
|
||||
///
|
||||
/// \return Current state of the joystick
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
JoystickState UpdateState();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Check if the joystick supports the given axis
|
||||
///
|
||||
/// \param axis Axis to check
|
||||
///
|
||||
/// \return True of the axis is supported, false otherwise
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
bool HasAxis(Joy::Axis Axis) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the number of buttons supported by the joystick
|
||||
///
|
||||
/// \return Number of buttons
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
unsigned int GetButtonsCount() const;
|
||||
|
||||
private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_JOYSTICKOSX_HPP
|
20
src/SFML/Window/OSX/SFApplication.h
Normal file
20
src/SFML/Window/OSX/SFApplication.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Event processing
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface SFApplication : NSObject
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Event processing
|
||||
///
|
||||
/// \param block blocking mode means at least one event is proccessed.
|
||||
////////////////////////////////////////////////////////////
|
||||
+(void)processEventWithBlockingMode:(BOOL)block;
|
||||
|
||||
@end
|
40
src/SFML/Window/OSX/SFApplication.m
Normal file
40
src/SFML/Window/OSX/SFApplication.m
Normal file
|
@ -0,0 +1,40 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <SFML/Window/OSX/SFApplication.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@implementation SFApplication
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
+(void)processEventWithBlockingMode:(BOOL)block
|
||||
{
|
||||
[NSApplication sharedApplication]; // Make sure NSApp exists
|
||||
NSEvent* event = nil;
|
||||
|
||||
if (block) { // At least one event is read.
|
||||
event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate distantFuture]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES]; // Remove the event from the dequeue
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
|
||||
// If there are some other event read them.
|
||||
while (event = [NSApp nextEventMatchingMask:NSAnyEventMask
|
||||
untilDate:[NSDate distantPast]
|
||||
inMode:NSDefaultRunLoopMode
|
||||
dequeue:YES]) // Remove the event from the dequeue
|
||||
{
|
||||
[NSApp sendEvent:event];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
||||
|
121
src/SFML/Window/OSX/SFContext.hpp
Normal file
121
src/SFML/Window/OSX/SFContext.hpp
Normal file
|
@ -0,0 +1,121 @@
|
|||
|
||||
|
||||
#ifndef SFML_SFCONTEXT_HPP
|
||||
#define SFML_SFCONTEXT_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/GlContext.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Predefine OBJC classes
|
||||
////////////////////////////////////////////////////////////
|
||||
#ifdef __OBJC__
|
||||
|
||||
@class NSOpenGLContext;
|
||||
typedef NSOpenGLContext* NSOpenGLContextRef;
|
||||
|
||||
@class NSAutoreleasePool;
|
||||
typedef NSAutoreleasePool* NSAutoreleasePoolRef;
|
||||
|
||||
#else // If C++
|
||||
|
||||
typedef void* NSOpenGLContextRef;
|
||||
typedef void* NSAutoreleasePoolRef;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief OSX (Cocoa) implementation of OpenGL contexts
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class SFContext : public GlContext
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a new context, not associated to a window
|
||||
///
|
||||
/// \param shared Context to share the new one with (can be NULL)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
SFContext(SFContext* shared);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create a new context attached to a window
|
||||
///
|
||||
/// \param shared Context to share the new one with (can be NULL)
|
||||
/// \param owner Pointer to the owner window
|
||||
/// \param bitsPerPixel Pixel depth (in bits per pixel)
|
||||
/// \param settings Creation parameters
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
SFContext(SFContext* shared, const WindowImpl* owner,
|
||||
unsigned int bitsPerPixel, const ContextSettings& settings);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~SFContext();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Display what has been rendered to the context so far
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void Display();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable vertical synchronization
|
||||
///
|
||||
/// Activating vertical synchronization will limit the number
|
||||
/// of frames displayed to the refresh rate of the monitor.
|
||||
/// This can avoid some visual artifacts, and limit the framerate
|
||||
/// to a good value (but not constant across different computers).
|
||||
///
|
||||
/// \param enabled : True to enable v-sync, false to deactivate
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void UseVerticalSync(bool enabled);
|
||||
|
||||
protected:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Activate the context as the current target
|
||||
/// for rendering
|
||||
///
|
||||
/// \return True on success, false if any error happened
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool MakeCurrent();
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the context
|
||||
/// \note Must only be called from Ctor.
|
||||
///
|
||||
/// \param shared Context to share the new one with (can be NULL)
|
||||
/// \param settings Creation parameters
|
||||
/// \param bitsPerPixel bpp
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void CreateContext(SFContext* shared,
|
||||
const ContextSettings& settings,
|
||||
unsigned int bitsPerPixel);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
NSOpenGLContextRef myContext; ///< OpenGL context
|
||||
NSAutoreleasePoolRef myPool; ///< Memory manager for this class.
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
#endif // SFML_AGLCONTEXT_HPP
|
156
src/SFML/Window/OSX/SFContext.mm
Normal file
156
src/SFML/Window/OSX/SFContext.mm
Normal file
|
@ -0,0 +1,156 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/SFContext.hpp>
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
|
||||
/*
|
||||
* DISCUSSION :
|
||||
* ============
|
||||
*
|
||||
* [1] (2010_07)
|
||||
* should AA-related NSOpenGLPixelFormatAttribute not be in the array
|
||||
* if AA is not enable (settings.AntialiasingLevel == 0) ?
|
||||
* => will not be present in attributs array if 0.
|
||||
*
|
||||
* [2] (2010_07)
|
||||
* how many buffer should be used for AA ?
|
||||
* => «1» was choosen.
|
||||
*/
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
SFContext::SFContext(SFContext* shared)
|
||||
{
|
||||
myPool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Create the context
|
||||
CreateContext(shared, ContextSettings(0, 0, 0), 0);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
SFContext::SFContext(SFContext* shared, const WindowImpl* owner,
|
||||
unsigned int bitsPerPixel, const ContextSettings& settings)
|
||||
{
|
||||
myPool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Create the context.
|
||||
CreateContext(shared, settings, bitsPerPixel);
|
||||
|
||||
// Apply context.
|
||||
WindowImplCocoa const * ownerCocoa = static_cast<WindowImplCocoa const *>(owner);
|
||||
ownerCocoa->ApplyContext(myContext);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
SFContext::~SFContext()
|
||||
{
|
||||
[myContext release];
|
||||
[myPool release];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
bool SFContext::MakeCurrent()
|
||||
{
|
||||
[myContext makeCurrentContext];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void SFContext::Display()
|
||||
{
|
||||
[myContext flushBuffer];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void SFContext::UseVerticalSync(bool enabled)
|
||||
{
|
||||
// Make compiler happy
|
||||
#ifdef USE_OS_X_VERSION_10_4
|
||||
long int swapInterval = enabled ? 1 : 0;
|
||||
#else /* USE_OS_X_VERSION_10_6 */
|
||||
GLint swapInterval = enabled ? 1 : 0;
|
||||
#endif
|
||||
|
||||
[myContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void SFContext::CreateContext(SFContext* shared,
|
||||
const ContextSettings& settings,
|
||||
unsigned int bitsPerPixel)
|
||||
{
|
||||
// Choose the attributs of OGL context.
|
||||
std::vector<NSOpenGLPixelFormatAttribute> attrs;
|
||||
attrs.reserve(20); // max attributs (estimation).
|
||||
|
||||
// These casts are safe. C++ is much more stric than Obj-C.
|
||||
|
||||
attrs.push_back(NSOpenGLPFAClosestPolicy);
|
||||
|
||||
attrs.push_back(NSOpenGLPFADoubleBuffer);
|
||||
|
||||
if (bitsPerPixel > 24) {
|
||||
attrs.push_back(NSOpenGLPFAAlphaSize);
|
||||
attrs.push_back((NSOpenGLPixelFormatAttribute)8);
|
||||
}
|
||||
|
||||
attrs.push_back(NSOpenGLPFADepthSize);
|
||||
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.DepthBits);
|
||||
|
||||
attrs.push_back(NSOpenGLPFAStencilSize);
|
||||
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.StencilBits);
|
||||
|
||||
if (settings.AntialiasingLevel > 0) { // [1]
|
||||
attrs.push_back(NSOpenGLPFAMultisample);
|
||||
|
||||
attrs.push_back(NSOpenGLPFASampleBuffers);
|
||||
attrs.push_back((NSOpenGLPixelFormatAttribute)1); // [2]
|
||||
|
||||
attrs.push_back(NSOpenGLPFASamples);
|
||||
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.AntialiasingLevel);
|
||||
}
|
||||
|
||||
attrs.push_back((NSOpenGLPixelFormatAttribute)0); // end of array
|
||||
|
||||
// Create the pixel pormat.
|
||||
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attrs[0]];
|
||||
|
||||
if(pixFmt == nil) {
|
||||
sf::Err() << "Error. Unable to find a suitable pixel format." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the shared context if one is given.
|
||||
NSOpenGLContext* sharedContext = shared != NULL ? shared->myContext : nil;
|
||||
|
||||
// Create the context.
|
||||
myContext = [[NSOpenGLContext alloc] initWithFormat:pixFmt
|
||||
shareContext:sharedContext];
|
||||
|
||||
// Free up.
|
||||
[pixFmt release];
|
||||
|
||||
#warning update settings with ogl version not yet implemented
|
||||
|
||||
// Save the creation settings
|
||||
mySettings = settings;
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
36
src/SFML/Window/OSX/SFOpenGLView.h
Normal file
36
src/SFML/Window/OSX/SFOpenGLView.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
namespace sf {
|
||||
namespace priv {
|
||||
class WindowImplCocoa;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Spesialized NSOpenGLView
|
||||
///
|
||||
/// Handle event and send them back to the requester.
|
||||
////////////////////////////////////////////////////////////
|
||||
@interface SFOpenGLView : NSOpenGLView {
|
||||
sf::priv::WindowImplCocoa* myRequester;
|
||||
BOOL myUseKeyRepeat;
|
||||
NSTrackingRectTag myTrackingTag;
|
||||
BOOL myMouseIsIn;
|
||||
}
|
||||
|
||||
|
||||
-(id)initWithFrame:(NSRect)frameRect;
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester;
|
||||
|
||||
-(void)enableKeyRepeat;
|
||||
-(void)disableKeyRepeat;
|
||||
|
||||
-(void)frameDidChange:(NSNotification*)notification;
|
||||
|
||||
-(BOOL)isMouseInside;
|
||||
|
||||
@end
|
306
src/SFML/Window/OSX/SFOpenGLView.mm
Normal file
306
src/SFML/Window/OSX/SFOpenGLView.mm
Normal file
|
@ -0,0 +1,306 @@
|
|||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
|
||||
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||
|
||||
@implementation SFOpenGLView
|
||||
|
||||
#pragma mark
|
||||
#pragma mark SFOpenGLView's methods
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(id)initWithFrame:(NSRect)frameRect
|
||||
{
|
||||
if (self = [super initWithFrame:frameRect]) {
|
||||
[self setRequesterTo:0];
|
||||
[self enableKeyRepeat];
|
||||
|
||||
// Register for mouse-move event
|
||||
myMouseIsIn = [self isMouseInside];
|
||||
myTrackingTag = [self addTrackingRect:[self frame]
|
||||
owner:self
|
||||
userData:nil
|
||||
assumeInside:myMouseIsIn];
|
||||
|
||||
// Register for resize event
|
||||
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||
[center addObserver:self
|
||||
selector:@selector(frameDidChange:)
|
||||
name:NSViewFrameDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
|
||||
{
|
||||
myRequester = requester;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)enableKeyRepeat
|
||||
{
|
||||
myUseKeyRepeat = YES;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)disableKeyRepeat
|
||||
{
|
||||
myUseKeyRepeat = NO;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)frameDidChange:(NSNotification*)notification
|
||||
{
|
||||
// Adapt tracking area for mouse mouse event.
|
||||
[self removeTrackingRect:myTrackingTag];
|
||||
myTrackingTag = [self addTrackingRect:[self frame]
|
||||
owner:self
|
||||
userData:nil
|
||||
assumeInside:myMouseIsIn];
|
||||
|
||||
// Update the OGL view to fit the new size.
|
||||
[self update];
|
||||
|
||||
// Send an event
|
||||
if (myRequester == 0) return;
|
||||
|
||||
// The new size
|
||||
NSSize newSize = [self frame].size;
|
||||
myRequester->WindowResized(newSize.width, newSize.height);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(BOOL)isMouseInside
|
||||
{
|
||||
NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
|
||||
NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
|
||||
|
||||
if (NSPointInRect(relativeToView, [self frame])) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark Subclassing methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)dealloc
|
||||
{
|
||||
// Unregister
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
[self removeTrackingRect:myTrackingTag];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(BOOL)acceptsFirstResponder
|
||||
{
|
||||
// Accepts key event.
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(BOOL)canBecomeKeyView
|
||||
{
|
||||
// Accepts key event.
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark Mouse-event methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseDown:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseDownAt(sf::Mouse::Left, loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseUp:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseUpAt(sf::Mouse::Left, loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseMoved:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
// If the event is not useful.
|
||||
if (!myMouseIsIn) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseMovedAt(loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)rightMouseDown:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseDownAt(sf::Mouse::Right, loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)rightMouseUp:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseUpAt(sf::Mouse::Right, loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)otherMouseDown:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
sf::Mouse::Button button;
|
||||
switch ([theEvent buttonNumber]) {
|
||||
case 2:
|
||||
button = sf::Mouse::Middle;
|
||||
break;
|
||||
case 3:
|
||||
button = sf::Mouse::XButton1;
|
||||
break;
|
||||
case 4:
|
||||
button = sf::Mouse::XButton2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseDownAt(button, loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)otherMouseUp:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
sf::Mouse::Button button;
|
||||
switch ([theEvent buttonNumber]) {
|
||||
case 2:
|
||||
button = sf::Mouse::Middle;
|
||||
break;
|
||||
case 3:
|
||||
button = sf::Mouse::XButton1;
|
||||
break;
|
||||
case 4:
|
||||
button = sf::Mouse::XButton2;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseUpAt(button, loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)scrollWheel:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
|
||||
// Don't forget to change to SFML coord system.
|
||||
float h = [[theEvent window] frame].size.height;
|
||||
myRequester->MouseWheelScrolledAt([theEvent deltaY], loc.x, h - loc.y);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseEntered:(NSEvent*)theEvent
|
||||
{
|
||||
myMouseIsIn = YES;
|
||||
|
||||
if (myRequester == 0) return;
|
||||
|
||||
myRequester->MouseMovedIn();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseExited:(NSEvent*)theEvent
|
||||
{
|
||||
myMouseIsIn = NO;
|
||||
|
||||
if (myRequester == 0) return;
|
||||
|
||||
myRequester->MouseMovedOut();
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark Key-event methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)keyDown:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
if (myUseKeyRepeat || ![theEvent isARepeat])
|
||||
myRequester->KeyDown([theEvent keyCode], [theEvent modifierFlags]);
|
||||
|
||||
if ([[theEvent characters] length] > 0)
|
||||
myRequester->TextEntred([[theEvent characters] characterAtIndex:0]);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)keyUp:(NSEvent*)theEvent
|
||||
{
|
||||
if (myRequester == 0) return;
|
||||
|
||||
myRequester->KeyUp([theEvent keyCode], [theEvent modifierFlags]);
|
||||
}
|
||||
|
||||
@end
|
46
src/SFML/Window/OSX/SFWindowController.h
Normal file
46
src/SFML/Window/OSX/SFWindowController.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Predefine some classes
|
||||
////////////////////////////////////////////////////////////
|
||||
namespace sf {
|
||||
namespace priv {
|
||||
class WindowImplCocoa;
|
||||
}
|
||||
class VideoMode;
|
||||
}
|
||||
|
||||
@class SFOpenGLView;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Implementation of WindowImplDelegateProtocol for window managment.
|
||||
///
|
||||
/// Key and mouse events are delegated to its view.
|
||||
/// Window events are managed by this class.
|
||||
///
|
||||
/// Used when SFML handle everything and when a NSWindow* is given
|
||||
/// as handle to WindowImpl.
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef USE_OS_X_VERSION_10_4
|
||||
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol> {
|
||||
#else /* USE_OS_X_VERSION_10_6 */
|
||||
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate> {
|
||||
#endif
|
||||
NSWindow* myWindow;
|
||||
SFOpenGLView* myOGLView;
|
||||
sf::priv::WindowImplCocoa* myRequester;
|
||||
}
|
||||
|
||||
-(id)initWithWindow:(NSWindow*)window;
|
||||
-(id)initWithMode:(sf::VideoMode const*)mode andStyle:(unsigned long)style;
|
||||
-(void)dealloc;
|
||||
|
||||
-(float)titlebarHeight;
|
||||
|
||||
@end
|
396
src/SFML/Window/OSX/SFWindowController.mm
Normal file
396
src/SFML/Window/OSX/SFWindowController.mm
Normal file
|
@ -0,0 +1,396 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
#include <SFML/Window/VideoMode.hpp>
|
||||
#include <SFML/Window/WindowHandle.hpp>
|
||||
#include <SFML/Window/WindowStyle.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
#import <SFML/Window/OSX/SFWindowController.h>
|
||||
#import <SFML/Window/OSX/SFApplication.h>
|
||||
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||
|
||||
@implementation SFWindowController
|
||||
|
||||
#pragma mark
|
||||
#pragma mark SFWindowController's methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(id)initWithWindow:(NSWindow*)window
|
||||
{
|
||||
if (self = [super init]) {
|
||||
myRequester = 0;
|
||||
|
||||
// Retain the window for our own use.
|
||||
myWindow = [window retain];
|
||||
|
||||
if (myWindow == nil) {
|
||||
|
||||
sf::Err()
|
||||
<< "No window was given to initWithWindow:."
|
||||
<< std::endl;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// Create the view.
|
||||
myOGLView = [[SFOpenGLView alloc] initWithFrame:[[myWindow contentView] frame]];
|
||||
|
||||
if (myOGLView == nil) {
|
||||
|
||||
sf::Err()
|
||||
<< "Could not create an instance of NSOpenGLView "
|
||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||
<< std::endl;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// Set the view to the window as its content view.
|
||||
[myWindow setContentView:myOGLView];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(id)initWithMode:(sf::VideoMode const*)mode andStyle:(unsigned long)style
|
||||
{
|
||||
if (self = [super init]) {
|
||||
myRequester = 0;
|
||||
|
||||
// Create our window size.
|
||||
NSRect rect = NSMakeRect(0, 0, mode->Width, mode->Height);
|
||||
|
||||
// Convert the SFML window style to Cocoa window style.
|
||||
unsigned int nsStyle = NSBorderlessWindowMask;
|
||||
if (!(style & sf::Style::Fullscreen)) { // if fullscrean we keep our NSBorderlessWindowMask.
|
||||
|
||||
if (style & sf::Style::Titlebar) nsStyle |= NSTitledWindowMask | NSMiniaturizableWindowMask;
|
||||
|
||||
if (style & sf::Style::Resize) nsStyle |= NSResizableWindowMask;
|
||||
|
||||
if (style & sf::Style::Close) nsStyle |= NSClosableWindowMask;
|
||||
|
||||
}
|
||||
|
||||
// Create the window.
|
||||
myWindow = [[NSWindow alloc] initWithContentRect:rect
|
||||
styleMask:nsStyle
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
/*
|
||||
"YES" make some "invalid drawable".
|
||||
See http://www.cocoabuilder.com/archive/cocoa/152482-nsviews-and-nsopenglcontext-invalid-drawable-error.html
|
||||
|
||||
[...]
|
||||
As best as I can figure, this is happening because the NSWindow (and
|
||||
hence my view) are not visible onscreen yet, and the system doesn't like that.
|
||||
[...]
|
||||
*/
|
||||
|
||||
if (myWindow == nil) {
|
||||
|
||||
sf::Err()
|
||||
<< "Could not create an instance of NSWindow "
|
||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||
<< std::endl;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// Create the view.
|
||||
myOGLView = [[SFOpenGLView alloc] initWithFrame:[[myWindow contentView] frame]];
|
||||
|
||||
if (myOGLView == nil) {
|
||||
|
||||
sf::Err()
|
||||
<< "Could not create an instance of NSOpenGLView "
|
||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||
<< std::endl;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// Set the view to the window as its content view.
|
||||
[myWindow setContentView:myOGLView];
|
||||
|
||||
// Register for event.
|
||||
[myWindow setDelegate:self];
|
||||
[myWindow setAcceptsMouseMovedEvents:YES];
|
||||
[myWindow setIgnoresMouseEvents:NO];
|
||||
|
||||
// And some other things...
|
||||
[myWindow setAutodisplay:YES];
|
||||
[myWindow setReleasedWhenClosed:NO];
|
||||
|
||||
// Apply special feature for fullscreen window.
|
||||
if (style & sf::Style::Fullscreen) {
|
||||
|
||||
// We place the window above everything else.
|
||||
[myWindow setLevel:NSMainMenuWindowLevel+1];
|
||||
[myWindow setOpaque:YES];
|
||||
[myWindow setHidesOnDeactivate:YES];
|
||||
|
||||
/* ---------------------------
|
||||
* | Note for future version |
|
||||
* ---------------------------
|
||||
*
|
||||
* starting with OS 10.5 NSView provides
|
||||
* a new method -enterFullScreenMode:withOptions:
|
||||
* which could be a good alternative.
|
||||
*/
|
||||
}
|
||||
|
||||
// Center the window to be cool =)
|
||||
[myWindow center];
|
||||
|
||||
} // if super init ok
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)dealloc
|
||||
{
|
||||
[self closeWindow];
|
||||
|
||||
[myWindow release];
|
||||
[myOGLView release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplDelegateProtocol's methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
|
||||
{
|
||||
// Forward to the view.
|
||||
[myOGLView setRequesterTo:requester];
|
||||
myRequester = requester;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(sf::WindowHandle)getSystemHandle
|
||||
{
|
||||
return myWindow;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)hideMouseCursor
|
||||
{
|
||||
[NSCursor hide];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)showMouseCursor
|
||||
{
|
||||
[NSCursor unhide];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y
|
||||
{
|
||||
// Flip for SFML window coordinate system
|
||||
y = NSHeight([myWindow frame]) - y;
|
||||
|
||||
// Adjust for view reference instead of window
|
||||
y -= NSHeight([myWindow frame]) - NSHeight([myOGLView frame]);
|
||||
|
||||
// Convert to screen coordinates
|
||||
NSPoint screenCoord = [myWindow convertBaseToScreen:NSMakePoint(x, y)];
|
||||
|
||||
// Flip screen coodinates
|
||||
float const screenHeight = NSHeight([[myWindow screen] frame]);
|
||||
screenCoord.y = screenHeight - screenCoord.y;
|
||||
|
||||
CGDirectDisplayID screenNumber = (CGDirectDisplayID)[[[[myWindow screen] deviceDescription] valueForKey:@"NSScreenNumber"] intValue];
|
||||
|
||||
// Place the cursor.
|
||||
CGDisplayMoveCursorToPoint(screenNumber, CGPointMake(screenCoord.x, screenCoord.y));
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////.
|
||||
-(void)setWindowPositionToX:(unsigned int)x Y:(unsigned int)y
|
||||
{
|
||||
NSPoint point = NSMakePoint(x, y);
|
||||
|
||||
// Flip for SFML window coordinate system.
|
||||
point.y = NSHeight([[myWindow screen] visibleFrame]) - point.y;
|
||||
|
||||
// Place the window.
|
||||
[myWindow setFrameTopLeftPoint:point];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)resizeTo:(unsigned int)width by:(unsigned int)height
|
||||
{
|
||||
// Add titlebar height.
|
||||
NSRect frame = NSMakeRect([myWindow frame].origin.x,
|
||||
[myWindow frame].origin.y,
|
||||
width,
|
||||
height + [self titlebarHeight]);
|
||||
|
||||
[myWindow setFrame:frame display:YES];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)changeTitle:(NSString*)title
|
||||
{
|
||||
[myWindow setTitle:title];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)hideWindow
|
||||
{
|
||||
[myWindow orderOut:nil];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)showWindow
|
||||
{
|
||||
[myWindow makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)closeWindow
|
||||
{
|
||||
[myWindow close];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)enableKeyRepeat
|
||||
{
|
||||
[myOGLView enableKeyRepeat];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)disableKeyRepeat
|
||||
{
|
||||
[myOGLView disableKeyRepeat];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)setIconTo:(unsigned int)width
|
||||
by:(unsigned int)height
|
||||
with:(sf::Uint8 const*)pixels
|
||||
{
|
||||
// Create an empty image representation.
|
||||
NSBitmapImageRep* bitmap =
|
||||
[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 // if 0 : only allocate memory
|
||||
pixelsWide:width
|
||||
pixelsHigh:height
|
||||
bitsPerSample:8 // The number of bits used to specify
|
||||
// one pixel in a single component of the data.
|
||||
samplesPerPixel:4 // 3 if no alpha, 4 with it
|
||||
hasAlpha:YES
|
||||
isPlanar:NO // I don't know what it is but it works
|
||||
colorSpaceName:NSCalibratedRGBColorSpace
|
||||
bytesPerRow:0 // 0 == determine automatically
|
||||
bitsPerPixel:0]; // 0 == determine automatically
|
||||
|
||||
// Load data pixels.
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 // We may need to define NSUInteger.
|
||||
#define NSUInteger unsigned int
|
||||
#endif
|
||||
for (unsigned int y = 0; y < height; ++y) {
|
||||
for (unsigned int x = 0; x < width; ++x, pixels+=4) {
|
||||
NSUInteger pixel[4] = { pixels[0], pixels[1], pixels[2], pixels[3] };
|
||||
[bitmap setPixel:pixel
|
||||
atX:x
|
||||
y:y];
|
||||
}
|
||||
}
|
||||
|
||||
// Create an image from the representation.
|
||||
NSImage* icon = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
|
||||
[icon addRepresentation:bitmap];
|
||||
|
||||
// Set app icon.
|
||||
[[NSApplication sharedApplication] setApplicationIconImage:icon];
|
||||
|
||||
// Free up.
|
||||
[icon release];
|
||||
[bitmap release];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)processEventWithBlockingMode:(BOOL)block
|
||||
{
|
||||
// If we don't have a requester we don't fetch event.
|
||||
if (myRequester != 0) {
|
||||
[SFApplication processEventWithBlockingMode:block];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)applyContext:(NSOpenGLContext*)context
|
||||
{
|
||||
[myOGLView setOpenGLContext:context];
|
||||
[context setView:myOGLView];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark NSWindowDelegate's methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(BOOL)windowShouldClose:(id)sender
|
||||
{
|
||||
if (myRequester == 0) return YES;
|
||||
|
||||
myRequester->WindowClosed();
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)windowDidBecomeKey:(NSNotification*)notification {
|
||||
if (myRequester == 0) return;
|
||||
|
||||
myRequester->WindowGainedFocus();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)windowDidResignKey:(NSNotification*)notification {
|
||||
if (myRequester == 0) return;
|
||||
|
||||
myRequester->WindowLostFocus();
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark Other methods
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(float)titlebarHeight {
|
||||
return NSHeight([myWindow frame]) - NSHeight([[myWindow contentView] frame]);
|
||||
}
|
||||
|
||||
@end
|
101
src/SFML/Window/OSX/VideoModeImpl.cpp
Normal file
101
src/SFML/Window/OSX/VideoModeImpl.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/VideoModeImpl.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get bpp for all OS X version
|
||||
///
|
||||
/// This function use only non-deprecated way to get the
|
||||
/// display bits per pixel information. It depends
|
||||
/// on these macros :
|
||||
///
|
||||
/// - USE_OS_X_VERSION_10_4
|
||||
/// - USE_OS_X_VERSION_10_6
|
||||
///
|
||||
#warning This may be improved by removing these dummy macros.
|
||||
/// Maybe MAC_OS_X_VERSION_MAX_ALLOWED ?
|
||||
////////////////////////////////////////////////////////////
|
||||
size_t DisplayBitsPerPixel(CGDirectDisplayID displayId)
|
||||
{
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
|
||||
|
||||
return CGDisplayBitsPerPixel(displayId);
|
||||
|
||||
#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
|
||||
|
||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
|
||||
|
||||
CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
|
||||
if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
return 32;
|
||||
else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
return 16;
|
||||
else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||
return 8;
|
||||
|
||||
return 0; // no match
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
std::vector<VideoMode> VideoModeImpl::GetFullscreenModes()
|
||||
{
|
||||
std::vector<VideoMode> modes;
|
||||
|
||||
CGDisplayCount count = 0;
|
||||
int err = CGGetActiveDisplayList(0, NULL, &count);
|
||||
|
||||
if (err != 0) {
|
||||
sf::Err() << "Error when retrieving displays count";
|
||||
return modes;
|
||||
}
|
||||
|
||||
CGDirectDisplayID* displays = new CGDirectDisplayID[count];
|
||||
err = CGGetActiveDisplayList(count, displays, &count);
|
||||
|
||||
if (err != 0) {
|
||||
sf::Err() << "Error when retrieving displays array";
|
||||
return modes;
|
||||
}
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
VideoMode mode(CGDisplayPixelsWide(displays[i]),
|
||||
CGDisplayPixelsHigh(displays[i]),
|
||||
DisplayBitsPerPixel(displays[i]));
|
||||
|
||||
// Add it only if it isn't already in the array.
|
||||
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
|
||||
modes.push_back(mode);
|
||||
}
|
||||
|
||||
delete[] displays;
|
||||
|
||||
return modes;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
VideoMode VideoModeImpl::GetDesktopMode()
|
||||
{
|
||||
CGDirectDisplayID display = CGMainDisplayID();
|
||||
return VideoMode(CGDisplayPixelsWide(display),
|
||||
CGDisplayPixelsHigh(display),
|
||||
DisplayBitsPerPixel(display));
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
199
src/SFML/Window/OSX/WindowImplCocoa.hpp
Normal file
199
src/SFML/Window/OSX/WindowImplCocoa.hpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
|
||||
|
||||
#ifndef SFML_WINDOWIMPLCOCOA_HPP
|
||||
#define SFML_WINDOWIMPLCOCOA_HPP
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/Event.hpp>
|
||||
#include <SFML/Window/WindowImpl.hpp>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Predefine OBJC classes
|
||||
////////////////////////////////////////////////////////////
|
||||
#ifdef __OBJC__
|
||||
|
||||
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
|
||||
typedef id<WindowImplDelegateProtocol,NSObject> WindowImplDelegateRef;
|
||||
|
||||
@class NSAutoreleasePool;
|
||||
typedef NSAutoreleasePool* NSAutoreleasePoolRef;
|
||||
|
||||
@class NSOpenGLContext;
|
||||
typedef NSOpenGLContext* NSOpenGLContextRef;
|
||||
|
||||
#else // If C++
|
||||
|
||||
typedef void* WindowImplDelegateRef;
|
||||
typedef void* NSAutoreleasePoolRef;
|
||||
typedef void* NSOpenGLContextRef;
|
||||
|
||||
#endif
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Mac OS X (Cocoa) implementation of WindowImpl
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
class WindowImplCocoa : public WindowImpl
|
||||
{
|
||||
public:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the window implementation from an existing control
|
||||
///
|
||||
/// \param handle Platform-specific handle of the control
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa(WindowHandle handle);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Create the window implementation
|
||||
///
|
||||
/// \param mode Video mode to use
|
||||
/// \param title Title of the window
|
||||
/// \param style Window style (resizable, fixed, or fullscren)
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa(VideoMode mode, const std::string& title, unsigned long style);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Destructor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
~WindowImplCocoa();
|
||||
|
||||
/// Events
|
||||
void WindowClosed(void);
|
||||
void WindowResized(unsigned int width, unsigned int height);
|
||||
void WindowLostFocus(void);
|
||||
void WindowGainedFocus(void);
|
||||
void MouseDownAt(Mouse::Button button, int x, int y);
|
||||
void MouseUpAt(Mouse::Button button, int x, int y);
|
||||
void MouseMovedAt(int x, int y);
|
||||
void MouseWheelScrolledAt(float delta, int x, int y);
|
||||
void MouseMovedIn(void);
|
||||
void MouseMovedOut(void);
|
||||
void KeyDown(unsigned short keycode, unsigned int modifierFlags);
|
||||
void KeyUp(unsigned short keycode, unsigned int modifierFlags);
|
||||
void TextEntred(Uint32 charcode);
|
||||
|
||||
static Key::Code NSKeyCodeToSFMLKeyCode(unsigned short rawchar);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void ApplyContext(NSOpenGLContextRef context) const;
|
||||
|
||||
private:
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Process incoming events from the operating system
|
||||
///
|
||||
/// \param block Use true to block the thread until an event arrives
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void ProcessEvents(bool block);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the OS-specific handle of the window
|
||||
///
|
||||
/// \return Handle of the window
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual WindowHandle GetSystemHandle() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the mouse cursor
|
||||
///
|
||||
/// \param show True to show, false to hide
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void ShowMouseCursor(bool show);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the position of the mouse cursor
|
||||
///
|
||||
/// \param x Left coordinate of the cursor, relative to the window
|
||||
/// \param y Top coordinate of the cursor, relative to the window
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetCursorPosition(unsigned int x, unsigned int y);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the position of the window on screen
|
||||
///
|
||||
/// \param x Left position
|
||||
/// \param y Top position
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetPosition(int x, int y);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the size of the rendering region of the window
|
||||
///
|
||||
/// \param width New width
|
||||
/// \param height New height
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetSize(unsigned int width, unsigned int height);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the title of the window
|
||||
///
|
||||
/// \param title New title
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetTitle(const std::string& title);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Show or hide the window
|
||||
///
|
||||
/// \param show True to show, false to hide
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void Show(bool show);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable automatic key-repeat
|
||||
///
|
||||
/// \param enabled True to enable, false to disable
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void EnableKeyRepeat(bool enabled);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the window's icon
|
||||
///
|
||||
/// \param width Icon's width, in pixels
|
||||
/// \param height Icon's height, in pixels
|
||||
/// \param pixels Pointer to the pixels in memory, format must be RGBA 32 bits
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void SetIcon(unsigned int width, unsigned int height, const Uint8* pixels);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Construct the pool after ensuring NSApp is valid.
|
||||
////////////////////////////////////////////////////////////
|
||||
void SetUpPoolAndApplication(void);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the type of the current process to become a full GUI app.
|
||||
////////////////////////////////////////////////////////////
|
||||
static void SetUpProcessAsApplication(void);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplDelegateRef myDelegate; ///< Implementation in Obj-C.
|
||||
NSAutoreleasePoolRef myPool; ///< Memory manager for this class.
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
||||
|
||||
|
||||
#endif // SFML_WINDOWIMPLCOCOA_HPP
|
518
src/SFML/Window/OSX/WindowImplCocoa.mm
Normal file
518
src/SFML/Window/OSX/WindowImplCocoa.mm
Normal file
|
@ -0,0 +1,518 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
#import <SFML/Window/OSX/SFWindowController.h>
|
||||
//#import <SFML/Window/OSX/SFViewController.h>
|
||||
#warning SFViewController not yet implemented.
|
||||
#import <SFML/Window/OSX/cpp_objc_conversion.h>
|
||||
|
||||
namespace sf
|
||||
{
|
||||
namespace priv
|
||||
{
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplCocoa's ctor/dtor
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::WindowImplCocoa(WindowHandle handle)
|
||||
{
|
||||
sf::Err() << "Not yet fully supported." << std::endl;
|
||||
#warning WindowImplCocoa(WindowHandle handle) not yet fully implemented
|
||||
|
||||
SetUpPoolAndApplication();
|
||||
|
||||
// Treat the handle as it real type
|
||||
id nsHandle = (id)handle;
|
||||
if ([nsHandle isKindOfClass:[NSWindow class]]) {
|
||||
|
||||
// We have a window.
|
||||
myDelegate = [[SFWindowController alloc] initWithWindow:nsHandle];
|
||||
|
||||
} /*else if ([nsHandle isKindOfClass:[NSView class]]) {
|
||||
|
||||
// We have a view.
|
||||
myDelegate = [[SFViewController alloc] initWithView:nsHandle];
|
||||
|
||||
} */ else {
|
||||
|
||||
sf::Err()
|
||||
<< "Cannot import this Window Handle because it is neither "
|
||||
<< "a <NSWindow*> nor <NSView*> object "
|
||||
<< "(or any of their subclasses). You gave a <"
|
||||
<< [[nsHandle className] UTF8String]
|
||||
<< "> object."
|
||||
<< std::endl;
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
// NO :
|
||||
// [myDelegate setRequesterTo:this];
|
||||
// because we don't handle event.
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::WindowImplCocoa(VideoMode mode,
|
||||
const std::string& title,
|
||||
unsigned long style)
|
||||
{
|
||||
SetUpPoolAndApplication();
|
||||
|
||||
// Don't forget to update our parent (that is, WindowImpl) size :
|
||||
myWidth = mode.Width;
|
||||
myHeight = mode.Height;
|
||||
|
||||
myDelegate = [[SFWindowController alloc] initWithMode:&mode andStyle:style];
|
||||
[myDelegate changeTitle:stringToNSString(title)];
|
||||
[myDelegate setRequesterTo:this];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplCocoa::~WindowImplCocoa()
|
||||
{
|
||||
[myDelegate closeWindow];
|
||||
|
||||
[myDelegate release];
|
||||
[myPool release];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::ApplyContext(NSOpenGLContextRef context) const
|
||||
{
|
||||
[myDelegate applyContext:context];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplCocoa's window-event methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::WindowClosed(void)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::Closed;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::WindowResized(unsigned int width, unsigned int height)
|
||||
{
|
||||
// Don't forget to update our parent (that is, WindowImpl) size :
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
|
||||
Event event;
|
||||
event.Type = Event::Resized;
|
||||
event.Size.Width = myWidth;
|
||||
event.Size.Height = myHeight;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::WindowLostFocus(void)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::LostFocus;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::WindowGainedFocus(void)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::GainedFocus;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplCocoa's mouse-event methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::MouseDownAt(Mouse::Button button, int x, int y)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::MouseButtonPressed;
|
||||
event.MouseButton.Button = button;
|
||||
event.MouseButton.X = x;
|
||||
event.MouseButton.Y = y;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::MouseUpAt(Mouse::Button button, int x, int y)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::MouseButtonReleased;
|
||||
event.MouseButton.Button = button;
|
||||
event.MouseButton.X = x;
|
||||
event.MouseButton.Y = y;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::MouseMovedAt(int x, int y)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::MouseMoved;
|
||||
event.MouseMove.X = x;
|
||||
event.MouseMove.Y = y;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::MouseWheelScrolledAt(float delta, int x, int y)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::MouseWheelMoved;
|
||||
event.MouseWheel.Delta = delta;
|
||||
event.MouseWheel.X = x;
|
||||
event.MouseWheel.Y = y;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::MouseMovedIn(void)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::MouseEntered;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::MouseMovedOut(void)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::MouseLeft;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplCocoa's key-event methods
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::KeyDown(unsigned short keycode, unsigned int modifierFlags)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::KeyPressed;
|
||||
|
||||
event.Key.Code = NSKeyCodeToSFMLKeyCode(keycode);
|
||||
if (event.Key.Code == Key::Count) {
|
||||
sf::Err() << "Unknown key (pressed)" << std::endl;
|
||||
return; // Not a valid/supported key.
|
||||
}
|
||||
|
||||
event.Key.Alt = modifierFlags & NSAlternateKeyMask;
|
||||
event.Key.Control = modifierFlags & NSControlKeyMask;
|
||||
event.Key.Shift = modifierFlags & NSShiftKeyMask;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::KeyUp(unsigned short keycode, unsigned int modifierFlags)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::KeyReleased;
|
||||
|
||||
event.Key.Code = NSKeyCodeToSFMLKeyCode(keycode);
|
||||
if (event.Key.Code == Key::Count) {
|
||||
sf::Err() << "Unknown key (released)" << std::endl;
|
||||
return; // Not a valid/supported key.
|
||||
}
|
||||
|
||||
event.Key.Alt = modifierFlags & NSAlternateKeyMask;
|
||||
event.Key.Control = modifierFlags & NSControlKeyMask;
|
||||
event.Key.Shift = modifierFlags & NSShiftKeyMask;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::TextEntred(Uint32 charcode)
|
||||
{
|
||||
Event event;
|
||||
event.Type = Event::TextEntered;
|
||||
event.Text.Unicode = charcode;
|
||||
|
||||
PushEvent(event);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
Key::Code WindowImplCocoa::NSKeyCodeToSFMLKeyCode(unsigned short keycode) {
|
||||
/* Based on http://forums.macrumors.com/showthread.php?t=780577 */
|
||||
switch (keycode) {
|
||||
case 0x00: return Key::A;
|
||||
case 0x0b: return Key::B;
|
||||
case 0x08: return Key::C;
|
||||
case 0x02: return Key::D;
|
||||
case 0x0e: return Key::E;
|
||||
case 0x03: return Key::F;
|
||||
case 0x05: return Key::G;
|
||||
case 0x04: return Key::H;
|
||||
case 0x22: return Key::I;
|
||||
case 0x26: return Key::J;
|
||||
case 0x28: return Key::K;
|
||||
case 0x25: return Key::L;
|
||||
case 0x2e: return Key::M;
|
||||
case 0x2d: return Key::N;
|
||||
case 0x1f: return Key::O;
|
||||
case 0x23: return Key::P;
|
||||
case 0x0c: return Key::Q;
|
||||
case 0x0f: return Key::R;
|
||||
case 0x01: return Key::S;
|
||||
case 0x11: return Key::T;
|
||||
case 0x20: return Key::U;
|
||||
case 0x09: return Key::V;
|
||||
case 0x0d: return Key::W;
|
||||
case 0x07: return Key::X;
|
||||
case 0x10: return Key::Y;
|
||||
case 0x06: return Key::Z;
|
||||
case 0x1d: return Key::Num0;
|
||||
case 0x12: return Key::Num1;
|
||||
case 0x13: return Key::Num2;
|
||||
case 0x14: return Key::Num3;
|
||||
case 0x15: return Key::Num4;
|
||||
case 0x17: return Key::Num5;
|
||||
case 0x16: return Key::Num6;
|
||||
case 0x1a: return Key::Num7;
|
||||
case 0x1c: return Key::Num8;
|
||||
case 0x19: return Key::Num9;
|
||||
case 0x35: return Key::Escape;
|
||||
case 0x3b: return Key::LControl;
|
||||
case 0x38: return Key::LShift;
|
||||
case 0x3a: return Key::LAlt;
|
||||
case 0x37: return Key::LSystem;
|
||||
case 0x3e: return Key::RControl;
|
||||
case 0x3c: return Key::RShift;
|
||||
case 0x3d: return Key::RAlt;
|
||||
case 0x36: return Key::RSystem;
|
||||
#warning unknown key code for Menu
|
||||
// case 0x: return Key::Menu;
|
||||
case 0x21: return Key::LBracket;
|
||||
case 0x1e: return Key::RBracket;
|
||||
case 0x29: return Key::SemiColon;
|
||||
case 0x2b: return Key::Comma;
|
||||
case 0x2f: return Key::Period;
|
||||
case 0x27: return Key::Quote;
|
||||
case 0x2c: return Key::Slash;
|
||||
case 0x2a: return Key::BackSlash;
|
||||
#warning 0x0a is for "Non-US Backslash" (from HID Calibrator, a sample provided by Apple).
|
||||
case 0x0a: return Key::Tilde;
|
||||
case 0x18: return Key::Equal;
|
||||
case 0x32: return Key::Dash;
|
||||
case 0x31: return Key::Space;
|
||||
case 0x24: return Key::Return;
|
||||
#warning unknown key code for Back
|
||||
// case 0x: return Key::Back;
|
||||
case 0x30: return Key::Tab;
|
||||
case 0x74: return Key::PageUp;
|
||||
case 0x79: return Key::PageDown;
|
||||
case 0x77: return Key::End;
|
||||
case 0x73: return Key::Home;
|
||||
#warning unknown key code for Insert
|
||||
// case 0x: return Key::Insert;
|
||||
case 0x33: return Key::Delete;
|
||||
case 0x45: return Key::Add;
|
||||
case 0x4e: return Key::Subtract;
|
||||
case 0x43: return Key::Multiply;
|
||||
case 0x4b: return Key::Divide;
|
||||
case 0x7b: return Key::Left;
|
||||
case 0x7c: return Key::Right;
|
||||
case 0x7e: return Key::Up;
|
||||
case 0x7d: return Key::Down;
|
||||
case 0x52: return Key::Numpad0;
|
||||
case 0x53: return Key::Numpad1;
|
||||
case 0x54: return Key::Numpad2;
|
||||
case 0x55: return Key::Numpad3;
|
||||
case 0x56: return Key::Numpad4;
|
||||
case 0x57: return Key::Numpad5;
|
||||
case 0x58: return Key::Numpad6;
|
||||
case 0x59: return Key::Numpad7;
|
||||
case 0x5b: return Key::Numpad8;
|
||||
case 0x5c: return Key::Numpad9;
|
||||
case 0x7a: return Key::F1;
|
||||
case 0x78: return Key::F2;
|
||||
case 0x63: return Key::F3;
|
||||
case 0x76: return Key::F4;
|
||||
case 0x60: return Key::F5;
|
||||
case 0x61: return Key::F6;
|
||||
case 0x62: return Key::F7;
|
||||
case 0x64: return Key::F8;
|
||||
case 0x65: return Key::F9;
|
||||
case 0x6d: return Key::F10;
|
||||
case 0x67: return Key::F11;
|
||||
case 0x6f: return Key::F12;
|
||||
case 0x69: return Key::F13;
|
||||
case 0x6b: return Key::F14;
|
||||
case 0x71: return Key::F15;
|
||||
#warning unknown key code for PAUSE
|
||||
// case 0x: return Key::PAUSE;
|
||||
default: return Key::Count; // An unknown key.
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplCocoa's event-related methods
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::ProcessEvents(bool block)
|
||||
{
|
||||
[myDelegate processEventWithBlockingMode:(block ? YES : NO)];
|
||||
}
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplCocoa's private methods
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowHandle WindowImplCocoa::GetSystemHandle() const
|
||||
{
|
||||
return [myDelegate getSystemHandle];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::ShowMouseCursor(bool show)
|
||||
{
|
||||
if (show) {
|
||||
[myDelegate showMouseCursor];
|
||||
} else {
|
||||
[myDelegate hideMouseCursor];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetCursorPosition(unsigned int x, unsigned int y)
|
||||
{
|
||||
[myDelegate setCursorPositionToX:x Y:y];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetPosition(int x, int y)
|
||||
{
|
||||
[myDelegate setWindowPositionToX:x Y:y];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetSize(unsigned int width, unsigned int height)
|
||||
{
|
||||
// Don't forget to update our parent (that is, WindowImpl) size :
|
||||
myWidth = width;
|
||||
myHeight = height;
|
||||
|
||||
[myDelegate resizeTo:width by:height];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetTitle(const std::string& title)
|
||||
{
|
||||
[myDelegate changeTitle:stringToNSString(title)];
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::Show(bool show)
|
||||
{
|
||||
if (show) {
|
||||
[myDelegate showWindow];
|
||||
} else {
|
||||
[myDelegate hideWindow];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::EnableKeyRepeat(bool enabled)
|
||||
{
|
||||
if (enabled) {
|
||||
[myDelegate enableKeyRepeat];
|
||||
} else {
|
||||
[myDelegate disableKeyRepeat];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetIcon(unsigned int width, unsigned int height,
|
||||
const Uint8* pixels)
|
||||
{
|
||||
[myDelegate setIconTo:width by:height with:pixels];
|
||||
}
|
||||
|
||||
#pragma mark
|
||||
#pragma mark WindowImplCocoa's init methods
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetUpPoolAndApplication(void)
|
||||
{
|
||||
// Ensure NSApp exists.
|
||||
[NSApplication sharedApplication];
|
||||
|
||||
// Create the pool.
|
||||
myPool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Transform the app process.
|
||||
SetUpProcessAsApplication();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::SetUpProcessAsApplication(void)
|
||||
{
|
||||
static bool isTheProcessSetAsApplication = false;
|
||||
|
||||
if (!isTheProcessSetAsApplication) {
|
||||
// Do it only once !
|
||||
isTheProcessSetAsApplication = true;
|
||||
|
||||
// Set the process as a normal application so it can get focus.
|
||||
ProcessSerialNumber psn;
|
||||
if (!GetCurrentProcess(&psn)) {
|
||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||
SetFrontProcess(&psn);
|
||||
}
|
||||
|
||||
// Tell the application to stop bouncing in the Dock.
|
||||
[[NSApplication sharedApplication] finishLaunching];
|
||||
// NOTE : This last call won't harm anything even if SFML window was
|
||||
// created with an external handle.
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace priv
|
||||
|
||||
} // namespace sf
|
85
src/SFML/Window/OSX/WindowImplDelegateProtocol.h
Normal file
85
src/SFML/Window/OSX/WindowImplDelegateProtocol.h
Normal file
|
@ -0,0 +1,85 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/Window/WindowHandle.hpp>
|
||||
#include <SFML/Config.hpp> // for sf::Uint8
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
|
||||
namespace sf {
|
||||
namespace priv {
|
||||
class WindowImplCocoa;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// This protocol defines the interface of the delegate of
|
||||
/// the window implementation.
|
||||
///
|
||||
/// Everything is done via a class that implement this protocol.
|
||||
/// There are two of these classes :
|
||||
///
|
||||
/// SFViewController and SFWindowController
|
||||
///
|
||||
/// The requester is a WindowImplCocoa. It's used to send back
|
||||
/// event via these functions :
|
||||
///
|
||||
/// WindowClosed, WindowResized, WindowLostFocus, WindowGainedFocus
|
||||
///
|
||||
/// MouseDownAt, MouseUpAt, MouseMovedAt, MouseWheelScrolledAt,
|
||||
/// MouseMovedIn, MouseMovedOut
|
||||
///
|
||||
/// KeyDown, KeyUp, TextEntred
|
||||
///
|
||||
/// Note : Joystick are not bound to a view or window
|
||||
/// thus they're not managed by a class implementing this protocol.
|
||||
////////////////////////////////////////////////////////////
|
||||
@protocol WindowImplDelegateProtocol
|
||||
|
||||
/// Set the WindowImpl who requested this delegate
|
||||
/// (This would be a ctor in C++ or Java where we can prohibit the
|
||||
/// construction of an object.)
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester;
|
||||
|
||||
/// Return the main view or window.
|
||||
-(sf::WindowHandle)getSystemHandle;
|
||||
|
||||
/// Hide or show the mouse cursor.
|
||||
-(void)hideMouseCursor;
|
||||
-(void)showMouseCursor;
|
||||
|
||||
/// Move the mouse cursor to (x,y) (SFML Coordinates).
|
||||
-(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y;
|
||||
|
||||
/// Move the window (not the view if we handle not a window) (SFML Coordinates).
|
||||
-(void)setWindowPositionToX:(unsigned int)x Y:(unsigned int)y;
|
||||
|
||||
/// Resize the window/view.
|
||||
-(void)resizeTo:(unsigned int)width by:(unsigned int)height;
|
||||
|
||||
/// Set the title (does nothing if we manage a view).
|
||||
-(void)changeTitle:(NSString*)title;
|
||||
|
||||
/// Hide or show the window (does nothing if we manage a view).
|
||||
-(void)hideWindow;
|
||||
-(void)showWindow;
|
||||
|
||||
/// Close the window (does nothing if we manage a view).
|
||||
-(void)closeWindow;
|
||||
|
||||
/// Enable or disable key repeat.
|
||||
-(void)enableKeyRepeat;
|
||||
-(void)disableKeyRepeat;
|
||||
|
||||
/// Set an icon to the application.
|
||||
-(void)setIconTo:(unsigned int)width by:(unsigned int)height with:(sf::Uint8 const*)pixels;
|
||||
|
||||
/// Fetch new event
|
||||
-(void)processEventWithBlockingMode:(BOOL)block;
|
||||
|
||||
/// Apply a given context to an OpenGL view.
|
||||
-(void)applyContext:(NSOpenGLContext*)context;
|
||||
|
||||
@end
|
14
src/SFML/Window/OSX/cpp_objc_conversion.h
Normal file
14
src/SFML/Window/OSX/cpp_objc_conversion.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <string>
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Returns a NSString construct with +stringWithCString:encoding:.
|
||||
////////////////////////////////////////////////////////////
|
||||
NSString* stringToNSString(std::string const& string);
|
||||
|
19
src/SFML/Window/OSX/cpp_objc_conversion.mm
Normal file
19
src/SFML/Window/OSX/cpp_objc_conversion.mm
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#include <SFML/System/Utf.hpp>
|
||||
|
||||
#import <SFML/Window/OSX/cpp_objc_conversion.h>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
NSString* stringToNSString(std::string const& string)
|
||||
{
|
||||
std::string utf8; utf8.reserve(string.size() + 1);
|
||||
sf::Utf8::FromAnsi(string.begin(), string.end(), std::back_inserter(utf8));
|
||||
NSString* str = [NSString stringWithCString:utf8.c_str() encoding:NSUTF8StringEncoding];
|
||||
|
||||
return str;
|
||||
}
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
#elif defined(SFML_SYSTEM_MACOS)
|
||||
|
||||
#include <SFML/Window/Cocoa/WindowImplCocoa.hpp>
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
typedef sf::priv::WindowImplCocoa WindowImplType;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue