Merge branch 'master' of github.com:LaurentGomila/SFML

This commit is contained in:
Laurent Gomila 2011-07-04 13:27:29 +02:00
commit 39780549ea
16 changed files with 342 additions and 267 deletions

View File

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

View File

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

View File

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

View File

@ -37,9 +37,9 @@ namespace priv
{
////////////////////////////////////////////////////////////
RenderImageImplDefault::RenderImageImplDefault() :
myContext(0),
myWidth (0),
myHeight (0),
myContext(0)
myHeight (0)
{
}

View File

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

View 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);

View 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
}

View File

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

View File

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

View File

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

View File

@ -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.
///

View File

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

View File

@ -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.
}
////////////////////////////////////////////////////////////

View File

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

View File

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

View File

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