Merge branch 'master' of github.com:LaurentGomila/SFML
This commit is contained in:
commit
39780549ea
@ -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)
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <SFML/Config.h>
|
||||
#include <SFML/System/Clock.h>
|
||||
#include <SFML/System/Mutex.h>
|
||||
#include <SFML/System/Randomizer.h>
|
||||
#include <SFML/System/Sleep.h>
|
||||
#include <SFML/System/Thread.h>
|
||||
|
||||
|
@ -6,6 +6,15 @@ elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(LINUX 1)
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
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()
|
||||
|
@ -37,9 +37,9 @@ namespace priv
|
||||
{
|
||||
////////////////////////////////////////////////////////////
|
||||
RenderImageImplDefault::RenderImageImplDefault() :
|
||||
myContext(0),
|
||||
myWidth (0),
|
||||
myHeight (0),
|
||||
myContext(0)
|
||||
myHeight (0)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -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()
|
||||
|
||||
|
28
src/SFML/Window/OSX/AutoreleasePoolWrapper.h
Normal file
28
src/SFML/Window/OSX/AutoreleasePoolWrapper.h
Normal file
@ -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);
|
||||
|
138
src/SFML/Window/OSX/AutoreleasePoolWrapper.mm
Normal file
138
src/SFML/Window/OSX/AutoreleasePoolWrapper.mm
Normal file
@ -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 <SFML/System/ThreadLocalPtr.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
#import "AutoreleasePoolWrapper.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
// 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<PoolWrapper> 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
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
};
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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,7 +448,13 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
||||
}
|
||||
}
|
||||
|
||||
if (myUseKeyRepeat || ![theEvent isARepeat]) {
|
||||
if ((myUseKeyRepeat || ![theEvent isARepeat]) && [[theEvent characters] length] > 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)) {
|
||||
|
||||
// Let's see if its a valid text.
|
||||
NSText* text = [[self window] fieldEditor:YES forObject:self];
|
||||
[text interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
||||
@ -574,6 +467,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
||||
[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
|
||||
{
|
||||
|
@ -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.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
@ -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);
|
||||
|
@ -40,9 +40,6 @@
|
||||
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
|
||||
typedef id<WindowImplDelegateProtocol,NSObject> 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
|
||||
|
@ -32,6 +32,7 @@
|
||||
#import <SFML/Window/OSX/SFWindowController.h>
|
||||
#import <SFML/Window/OSX/SFViewController.h>
|
||||
#import <SFML/Window/OSX/cpp_objc_conversion.h>
|
||||
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user