diff --git a/CMakeLists.txt b/CMakeLists.txt index 63494490..66dd6a37 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,12 +31,9 @@ set(BUILD_EXAMPLES FALSE CACHE BOOL "TRUE to build the SFML examples, FALSE to i set(BUILD_DOC FALSE CACHE BOOL "TRUE to generate the API documentation, FALSE to ignore it") # Mac OS X specific options -if (MACOSX) - # (Not supported anymore by extlibs) add an option to compile ppc/ppc64 - #set(BUILD_PPC FALSE CACHE BOOL "TRUE to build SFML for ppc and ppc64, too, FALSE to only compile i386 and x86_64") - - # add an option to build against 10.5 SDK - set(BUILD_LEOPARD FALSE CACHE BOOL "TRUE to build SFML for OS X 10.5, FALSE to compile for default SDK") +if (MACOSX AND MACOSX_VERSION GREATER 5) + # add an option to build against 10.5 SDK if current OS X version is greater than 10.5 + set(BUILD_LEOPARD FALSE CACHE BOOL "TRUE to build SFML for OS X 10.5, FALSE to compile with default SDK") endif() # define SFML_STATIC if the build type is not set to 'shared' @@ -70,26 +67,14 @@ set(CMAKE_SKIP_BUILD_RPATH TRUE) # Setup Mac OS X multi arch/SDK support. if (MACOSX) -# # compile for PPC ? -# if (BUILD_PPC) -# if (NOT CMAKE_OSX_ARCHITECTURES) -# # Custom : ppc, ppc64, i386 and x86_64 -# set(CMAKE_OSX_ARCHITECTURES "ppc;i386;ppc64;x86_64") -# else() -# # We got some conflict with custom user settings ; let him know his on his own. -# message("You set BUILD_PPC to TRUE but CMAKE_OSX_ARCHITECTURES is not empty.") -# message("You're on your own : I won't change your settings.") -# endif() -# else() -# if (NOT CMAKE_OSX_ARCHITECTURES) -# # Default : i386 and x86_64 -# set(CMAKE_OSX_ARCHITECTURES "i386;x86_64") -# else() -# # We got some conflict with custom user settings ; let him know his on his own. -# message("CMAKE_OSX_ARCHITECTURES is not empty.") -# message("You're on your own : I won't change your settings.") -# endif() -# endif() + if (NOT CMAKE_OSX_ARCHITECTURES) + # Default : i386 and x86_64 + set(CMAKE_OSX_ARCHITECTURES "i386;x86_64") + else() + # We got some conflict with custom user settings ; let him know his on his own. + message("CMAKE_OSX_ARCHITECTURES is not empty.") + message("You're on your own : I won't change your settings.") + endif() # use 10.5 SDK ? if (BUILD_LEOPARD) diff --git a/bindings/c/include/SFML/System.h b/bindings/c/include/SFML/System.h index 428627e3..4e8e3aa5 100644 --- a/bindings/c/include/SFML/System.h +++ b/bindings/c/include/SFML/System.h @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/cmake/Config.cmake b/cmake/Config.cmake index 23668365..4b80e57e 100644 --- a/cmake/Config.cmake +++ b/cmake/Config.cmake @@ -5,7 +5,16 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") set(LINUX 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - set(MACOSX 1) + set(MACOSX 1) + + # detect OS X version. (use '/usr/bin/sw_vers -productVersion' to extract V from '10.V.x'.) + EXEC_PROGRAM(/usr/bin/sw_vers ARGS -productVersion OUTPUT_VARIABLE MACOSX_VERSION_RAW) + STRING(REGEX REPLACE "10\\.([0-9]).*" "\\1" MACOSX_VERSION "${MACOSX_VERSION_RAW}") + if(${MACOSX_VERSION} LESS 5) + message(WARNING "Unsupported version of OS X : ${MACOSX_VERSION_RAW}") + return() + endif() + else() message(WARNING "Unsupported operating system") return() diff --git a/src/SFML/Graphics/RenderImageImplDefault.cpp b/src/SFML/Graphics/RenderImageImplDefault.cpp index cb0f47b2..016a4314 100644 --- a/src/SFML/Graphics/RenderImageImplDefault.cpp +++ b/src/SFML/Graphics/RenderImageImplDefault.cpp @@ -37,9 +37,9 @@ namespace priv { //////////////////////////////////////////////////////////// RenderImageImplDefault::RenderImageImplDefault() : +myContext(0), myWidth (0), -myHeight (0), -myContext(0) +myHeight (0) { } diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt index 88ded956..419f044d 100644 --- a/src/SFML/Window/CMakeLists.txt +++ b/src/SFML/Window/CMakeLists.txt @@ -85,6 +85,8 @@ else() # MACOSX ${SRCROOT}/OSX/WindowImplCocoa.hpp ${SRCROOT}/OSX/WindowImplCocoa.mm ${SRCROOT}/OSX/WindowImplDelegateProtocol.h + ${SRCROOT}/OSX/AutoreleasePoolWrapper.h + ${SRCROOT}/OSX/AutoreleasePoolWrapper.mm ) endif() diff --git a/src/SFML/Window/OSX/AutoreleasePoolWrapper.h b/src/SFML/Window/OSX/AutoreleasePoolWrapper.h new file mode 100644 index 00000000..2a67f1b7 --- /dev/null +++ b/src/SFML/Window/OSX/AutoreleasePoolWrapper.h @@ -0,0 +1,28 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), +// 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. +// +//////////////////////////////////////////////////////////// + +void RetainPool(void); +void ReleasePool(void); + diff --git a/src/SFML/Window/OSX/AutoreleasePoolWrapper.mm b/src/SFML/Window/OSX/AutoreleasePoolWrapper.mm new file mode 100644 index 00000000..3391562c --- /dev/null +++ b/src/SFML/Window/OSX/AutoreleasePoolWrapper.mm @@ -0,0 +1,138 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com), +// 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. +// +//////////////////////////////////////////////////////////// + +#include +#include +#import "AutoreleasePoolWrapper.h" +#import + +// Here we manage one and only one pool by thread. This prevents draining one +// pool and making other pools invalid which can lead to a crash on 10.5 and an +// annoying message on 10.6 (*** attempt to pop an unknown autorelease pool). + +// Because NSAutoreleasePool cannot be retain we have to do it ourself. +// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread. + +// This implies that if RetainPool is called X times in a thread Y then +// ReleasePool must be called X times too in the same thread Y. + +class PoolWrapper { +public: + PoolWrapper() + : count(0) + , pool(0) + { + /* Nothing else */ + } + + ~PoolWrapper() + { +#ifdef SFML_DEBUG + if (count < 0) { + sf::Err() << "~PoolWrapper : count is less than zero! " + "You called ReleasePool from a thread too many times." + << std::endl; + } else if (count > 0) { + sf::Err() << "~PoolWrapper : count is greater than zero! " + "You called ReleasePool from a thread to few times." + << std::endl; + } else { // count == 0 + sf::Err() << "~PoolWrapper is HAPPY!" << std::endl; + } +#endif + } + + void Retain() + { + // Increase counter. + ++count; + + // Allocate pool if required. + if (pool == 0) { + pool = [[NSAutoreleasePool alloc] init]; + } + +#ifdef SFML_DEBUG + if (count <= 0) { + sf::Err() << "PoolWrapper::Retain : count <= 0! " << std::endl; + } +#endif + } + + void Release() + { + // Decrease counter. + --count; + + // Drain pool if required. + if (count == 0) { + [pool drain]; + pool = 0; + } + +#ifdef SFML_DEBUG + if (count < 0) { + sf::Err() << "PoolWrapper::Release : count < 0! " << std::endl; + } +#endif + } + + +private: + int count; ///< How many times the pool was retained ? + NSAutoreleasePool* pool; ///< Our pool. +}; + +// Thread shared variable but with local-only shared content. +sf::ThreadLocalPtr localPool; + +void RetainPool(void) +{ + // First, Check that we have a valid PoolWrapper object in our local pool. + if (localPool == NULL) { + localPool = new PoolWrapper(); + } + + // Then retains! + localPool->Retain(); +} + +void ReleasePool(void) +{ +#ifdef SFML_DEBUG + if (localPool == NULL) { + sf::Err() << "ReleasePool : You must call RetainPool at least once " + "in this thread before calling ReleasePool." + << std::endl; + } else { +#endif + + // Releases, that's all. + localPool->Release(); + +#ifdef SFML_DEBUG + } +#endif +} diff --git a/src/SFML/Window/OSX/Joystick.cpp b/src/SFML/Window/OSX/Joystick.cpp index 8b0e203b..6cec8a92 100644 --- a/src/SFML/Window/OSX/Joystick.cpp +++ b/src/SFML/Window/OSX/Joystick.cpp @@ -69,7 +69,7 @@ void Joystick::Initialize(unsigned int Index) // Is there enough joystick ? CFIndex joysticksCount = CFSetGetCount(devices); - if (joysticksCount <= Index) { + if (joysticksCount <= CFIndex(Index)) { FreeUp(); return; } @@ -303,6 +303,9 @@ bool Joystick::RetriveElements(IOHIDDeviceRef device) // Too many buttons. We ignore this one. } break; + + default: // Make compiler happy. + break; } } diff --git a/src/SFML/Window/OSX/SFContext.hpp b/src/SFML/Window/OSX/SFContext.hpp index c49e482f..f3f1f6ec 100644 --- a/src/SFML/Window/OSX/SFContext.hpp +++ b/src/SFML/Window/OSX/SFContext.hpp @@ -39,9 +39,6 @@ @class NSOpenGLContext; typedef NSOpenGLContext* NSOpenGLContextRef; -@class NSAutoreleasePool; -typedef NSAutoreleasePool* NSAutoreleasePoolRef; - @class NSOpenGLView; typedef NSOpenGLView* NSOpenGLViewRef; @@ -51,7 +48,6 @@ typedef NSWindow* NSWindowRef; #else // If C++ typedef void* NSOpenGLContextRef; -typedef void* NSAutoreleasePoolRef; typedef void* NSOpenGLViewRef; typedef void* NSWindowRef; @@ -154,7 +150,6 @@ private: // Member data //////////////////////////////////////////////////////////// NSOpenGLContextRef myContext; ///< OpenGL context. - NSAutoreleasePoolRef myPool; ///< Memory manager for this class. NSOpenGLViewRef myView; ///< Only for offscreen context. NSWindowRef myWindow; ///< Only for offscreen context. }; diff --git a/src/SFML/Window/OSX/SFContext.mm b/src/SFML/Window/OSX/SFContext.mm index 4f05b0df..e542e172 100644 --- a/src/SFML/Window/OSX/SFContext.mm +++ b/src/SFML/Window/OSX/SFContext.mm @@ -30,6 +30,8 @@ #include #include +#import + /* * DISCUSSION : * ============ @@ -53,7 +55,8 @@ namespace priv SFContext::SFContext(SFContext* shared) : myView(0), myWindow(0) { - myPool = [[NSAutoreleasePool alloc] init]; + // Ask for a pool. + RetainPool(); // Create the context CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, ContextSettings(0, 0, 0)); @@ -65,7 +68,8 @@ SFContext::SFContext(SFContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) : myView(0), myWindow(0) { - myPool = [[NSAutoreleasePool alloc] init]; + // Ask for a pool. + RetainPool(); // Create the context. CreateContext(shared, bitsPerPixel, settings); @@ -83,7 +87,8 @@ SFContext::SFContext(SFContext* shared, const ContextSettings& settings, // Ensure the process is setup in order to create a valid window. WindowImplCocoa::SetUpProcess(); - myPool = [[NSAutoreleasePool alloc] init]; + // Ask for a pool. + RetainPool(); // Create the context. CreateContext(shared, VideoMode::GetDesktopMode().BitsPerPixel, settings); @@ -109,8 +114,7 @@ SFContext::~SFContext() [myView release]; // Might be nil but we don't care. [myWindow release]; // Idem. - [myPool drain]; // Produce sometimes "*** attempt to pop an unknown autorelease pool" - // This is not a real issue : http://stackoverflow.com/questions/3484888/nsautoreleasepool-question + ReleasePool(); } diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h index be2903ef..c6021a66 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.h +++ b/src/SFML/Window/OSX/SFOpenGLView.h @@ -87,6 +87,12 @@ namespace sf { //////////////////////////////////////////////////////////// -(void)setRealSize:(NSSize)newSize; +//////////////////////////////////////////////////////////// +/// Move the mouse cursor to (x,y) (SFML Coordinates). +/// +//////////////////////////////////////////////////////////// +-(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y; + //////////////////////////////////////////////////////////// /// Adjust key repeat configuration. /// diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm index bd9c8477..87fd8df1 100644 --- a/src/SFML/Window/OSX/SFOpenGLView.mm +++ b/src/SFML/Window/OSX/SFOpenGLView.mm @@ -103,6 +103,18 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); //////////////////////////////////////////////////////////// -(void)initModifiersState; +//////////////////////////////////////////////////////////// +/// Compute the position of the cursor. +/// +//////////////////////////////////////////////////////////// +-(NSPoint)cursorPositionFromEvent:(NSEvent *)event; + +//////////////////////////////////////////////////////////// +/// Converte the NSEvent mouse button type to SFML type. +/// +//////////////////////////////////////////////////////////// +-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent *)event; + //////////////////////////////////////////////////////////// /// Convert a key down/up NSEvent into an SFML key event. /// Based on LocalizedKeys and NonLocalizedKeys function. @@ -161,6 +173,39 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); } +//////////////////////////////////////////////////////// +-(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y +{ + // Flip for SFML window coordinate system + y = NSHeight([[self window] frame]) - y; + + // Adjust for view reference instead of window + y -= NSHeight([[self window] frame]) - NSHeight([self frame]); + + // Convert to screen coordinates + NSPoint screenCoord = [[self window] convertBaseToScreen:NSMakePoint(x, y)]; + + // Flip screen coodinates + float const screenHeight = NSHeight([[[self window] screen] frame]); + screenCoord.y = screenHeight - screenCoord.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + screenCoord.x = screenCoord.x / myRealSize.width * [self frame].size.width; + screenCoord.y = screenCoord.y / myRealSize.height * [self frame].size.height; + } + + // Place the cursor. + CGEventRef event = CGEventCreateMouseEvent(NULL, + kCGEventMouseMoved, + CGPointMake(screenCoord.x, screenCoord.y), + /*we don't care about this : */0); + CGEventPost(kCGHIDEventTap, event); + CFRelease(event); + // This is a workaround to deprecated CGSetLocalEventsSuppressionInterval. +} + + //////////////////////////////////////////////////////// -(void)enableKeyRepeat { @@ -260,58 +305,24 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); //////////////////////////////////////////////////////// -(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 = [self frame].size.height; - myRequester->MouseDownAt(sf::Mouse::Left, loc.x, h - loc.y); + // Forward to... + [self otherMouseDown:theEvent]; } //////////////////////////////////////////////////////// -(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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } - - myRequester->MouseUpAt(sf::Mouse::Left, loc.x, loc.y); + // Forward to... + [self otherMouseUp:theEvent]; } //////////////////////////////////////////////////////// -(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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } - - myRequester->MouseMovedAt(loc.x, loc.y); + // Forward to... + [self otherMouseDragged:theEvent]; } @@ -320,17 +331,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); { if (myRequester == 0) return; - NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; - - // Don't forget to change to SFML coord system. - float h = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } + NSPoint loc = [self cursorPositionFromEvent:theEvent]; myRequester->MouseWheelScrolledAt([theEvent deltaY], loc.x, loc.y); } @@ -361,42 +362,16 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); //////////////////////////////////////////////////////// -(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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } - - myRequester->MouseDownAt(sf::Mouse::Right, loc.x, loc.y); + // Forward to... + [self otherMouseDown:theEvent]; } //////////////////////////////////////////////////////// -(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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } - - myRequester->MouseUpAt(sf::Mouse::Right, loc.x, loc.y); + // Forward to... + [self otherMouseUp:theEvent]; } @@ -405,32 +380,9 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); { if (myRequester == 0) return; - NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + NSPoint loc = [self cursorPositionFromEvent:theEvent]; - 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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } + sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent]; myRequester->MouseDownAt(button, loc.x, loc.y); } @@ -441,32 +393,9 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); { if (myRequester == 0) return; - NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil]; + NSPoint loc = [self cursorPositionFromEvent:theEvent]; - 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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } + sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent]; myRequester->MouseUpAt(button, loc.x, loc.y); } @@ -475,48 +404,16 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); //////////////////////////////////////////////////////// -(void)rightMouseDragged:(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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } - - myRequester->MouseMovedAt(loc.x, loc.y); + // Forward to... + [self otherMouseDragged:theEvent]; } //////////////////////////////////////////////////////// -(void)mouseDragged:(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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } - - myRequester->MouseMovedAt(loc.x, loc.y); + // Forward to... + [self otherMouseDragged:theEvent]; } @@ -528,17 +425,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); // 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 = [self frame].size.height; - loc.y = h - loc.y; - - // Recompute the mouse pos if required. - if (!NSEqualSizes(myRealSize, NSZeroSize)) { - loc.x = loc.x * myRealSize.width / [self frame].size.width; - loc.y = loc.y * myRealSize.height / [self frame].size.height; - } + NSPoint loc = [self cursorPositionFromEvent:theEvent]; myRequester->MouseMovedAt(loc.x, loc.y); } @@ -561,17 +448,24 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); } } - if (myUseKeyRepeat || ![theEvent isARepeat]) { - // Let's see if its a valid text. - NSText* text = [[self window] fieldEditor:YES forObject:self]; - [text interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; + if ((myUseKeyRepeat || ![theEvent isARepeat]) && [[theEvent characters] length] > 0) { - NSString* string = [text string]; - if ([string length] > 0) { - // It's a valid TextEntered event. - myRequester->TextEntered([string characterAtIndex:0]); + // Ignore escape key and non text keycode. (See NSEvent.h) + // They produce a sound alert. + unichar code = [[theEvent characters] characterAtIndex:0]; + if ([theEvent keyCode] != 0x35 && (code < 0xF700 || code > 0xF8FF)) { - [text setString:@""]; + // Let's see if its a valid text. + NSText* text = [[self window] fieldEditor:YES forObject:self]; + [text interpretKeyEvents:[NSArray arrayWithObject:theEvent]]; + + NSString* string = [text string]; + if ([string length] > 0) { + // It's a valid TextEntered event. + myRequester->TextEntered([string characterAtIndex:0]); + + [text setString:@""]; + } } } } @@ -1009,6 +903,39 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode); } +//////////////////////////////////////////////////////// +-(NSPoint)cursorPositionFromEvent:(NSEvent *)event +{ + NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; + + // Don't forget to change to SFML coord system. + float h = [self frame].size.height; + loc.y = h - loc.y; + + // Recompute the mouse pos if required. + if (!NSEqualSizes(myRealSize, NSZeroSize)) { + loc.x = loc.x * myRealSize.width / [self frame].size.width; + loc.y = loc.y * myRealSize.height / [self frame].size.height; + } + + return loc; +} + + +//////////////////////////////////////////////////////// +-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent *)event +{ + switch ([event buttonNumber]) { + case 0: return sf::Mouse::Left; + case 1: return sf::Mouse::Right; + case 2: return sf::Mouse::Middle; + case 3: return sf::Mouse::XButton1; + case 4: return sf::Mouse::XButton2; + default: return sf::Mouse::ButtonCount; // Never happens! (hopefully) + } +} + + //////////////////////////////////////////////////////// +(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent { diff --git a/src/SFML/Window/OSX/SFWindowController.h b/src/SFML/Window/OSX/SFWindowController.h index 642a25b0..5c72694c 100644 --- a/src/SFML/Window/OSX/SFWindowController.h +++ b/src/SFML/Window/OSX/SFWindowController.h @@ -61,7 +61,7 @@ namespace sf { NSWindow* myWindow; SFOpenGLView* myOGLView; sf::priv::WindowImplCocoa* myRequester; - sf::VideoMode myFullscreenMode; + sf::VideoMode* myFullscreenMode; // Note : C++ ctor/dtor are not called for Obj-C fields. } //////////////////////////////////////////////////////////// diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm index 09e3dc8b..1f5a1fa7 100644 --- a/src/SFML/Window/OSX/SFWindowController.mm +++ b/src/SFML/Window/OSX/SFWindowController.mm @@ -69,6 +69,7 @@ { if ((self = [super init])) { myRequester = 0; + myFullscreenMode = new sf::VideoMode(); // Retain the window for our own use. myWindow = [window retain]; @@ -121,6 +122,7 @@ if ((self = [super init])) { myRequester = 0; + myFullscreenMode = new sf::VideoMode(); // Create our window size. NSRect rect = NSZeroRect; @@ -128,7 +130,7 @@ // We use desktop mode to size the window // but we set the back buffer size to 'mode' in applyContext method. - myFullscreenMode = mode; + *myFullscreenMode = mode; sf::VideoMode dm = sf::VideoMode::GetDesktopMode(); rect = NSMakeRect(0, 0, dm.Width, dm.Height); @@ -211,7 +213,7 @@ // If a fullscreen window was requested... if (style & sf::Style::Fullscreen && mode != sf::VideoMode::GetDesktopMode()) { /// ... we set the "read size" of the view (that is the back buffer size). - [myOGLView setRealSize:NSMakeSize(myFullscreenMode.Width, myFullscreenMode.Height)]; + [myOGLView setRealSize:NSMakeSize(myFullscreenMode->Width, myFullscreenMode->Height)]; } // Set the view to the window as its content view. @@ -238,6 +240,8 @@ [myWindow release]; [myOGLView release]; + delete myFullscreenMode; + [super dealloc]; } @@ -279,30 +283,8 @@ //////////////////////////////////////////////////////// -(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y { - if (myRequester == 0) return; - - // 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; - - // Place the cursor. - CGEventRef event = CGEventCreateMouseEvent(NULL, - kCGEventMouseMoved, - CGPointMake(screenCoord.x, screenCoord.y), - /*we don't care about this : */0); - CGEventPost(kCGHIDEventTap, event); - CFRelease(event); - // This is a workaround to deprecated CGSetLocalEventsSuppressionInterval. - // The event produced will be catched by SFML in sf::Window::FilterEvent. + // Forward to... + [myOGLView setCursorPositionToX:x Y:y]; } @@ -453,10 +435,10 @@ // If fullscreen was requested and the mode used to create the window // was not the desktop mode, we change the back buffer size of the // context. - if (myFullscreenMode != sf::VideoMode()) { + if (*myFullscreenMode != sf::VideoMode()) { CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj]; - GLint dim[2] = {myFullscreenMode.Width, myFullscreenMode.Height}; + GLint dim[2] = {myFullscreenMode->Width, myFullscreenMode->Height}; CGLSetParameter(cgcontext, kCGLCPSurfaceBackingSize, dim); CGLEnable(cgcontext, kCGLCESurfaceBackingSize); diff --git a/src/SFML/Window/OSX/WindowImplCocoa.hpp b/src/SFML/Window/OSX/WindowImplCocoa.hpp index 3fff8a6a..6013abfa 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.hpp +++ b/src/SFML/Window/OSX/WindowImplCocoa.hpp @@ -40,9 +40,6 @@ #import typedef id WindowImplDelegateRef; -@class NSAutoreleasePool; -typedef NSAutoreleasePool* NSAutoreleasePoolRef; - @class NSOpenGLContext; typedef NSOpenGLContext* NSOpenGLContextRef; @@ -51,7 +48,6 @@ typedef NSOpenGLContext* NSOpenGLContextRef; typedef unsigned short unichar; // See NSString.h typedef void* WindowImplDelegateRef; -typedef void* NSAutoreleasePoolRef; typedef void* NSOpenGLContextRef; #endif @@ -333,7 +329,6 @@ private: // Member data //////////////////////////////////////////////////////////// WindowImplDelegateRef myDelegate; ///< Implementation in Obj-C. - NSAutoreleasePoolRef myPool; ///< Memory manager for this class. }; } // namespace priv diff --git a/src/SFML/Window/OSX/WindowImplCocoa.mm b/src/SFML/Window/OSX/WindowImplCocoa.mm index 22821f11..57866623 100644 --- a/src/SFML/Window/OSX/WindowImplCocoa.mm +++ b/src/SFML/Window/OSX/WindowImplCocoa.mm @@ -32,6 +32,7 @@ #import #import #import +#import namespace sf { @@ -44,8 +45,8 @@ namespace priv //////////////////////////////////////////////////////////// WindowImplCocoa::WindowImplCocoa(WindowHandle handle) { - // Create the pool. - myPool = [[NSAutoreleasePool alloc] init]; + // Ask for a pool. + RetainPool(); // Treat the handle as it real type id nsHandle = (id)handle; @@ -94,8 +95,8 @@ WindowImplCocoa::WindowImplCocoa(VideoMode mode, // Transform the app process. SetUpProcess(); - // Create the pool. - myPool = [[NSAutoreleasePool alloc] init]; + // Ask for a pool. + RetainPool(); // Don't forget to update our parent (that is, WindowImpl) size : myWidth = mode.Width; @@ -113,7 +114,8 @@ WindowImplCocoa::~WindowImplCocoa() [myDelegate closeWindow]; [myDelegate release]; - [myPool drain]; + + ReleasePool(); }