This is a big commit for os x port!

> remove old OSX version
> add new sources (Window and Graphics modules)
> add extlibs static binaries/headers/frameworks
> update cmake for OSX




git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/branches/sfml2@1711 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
mantognini 2010-11-25 16:45:03 +00:00
parent bb55254fe3
commit de8712fa5f
112 changed files with 42514 additions and 4588 deletions

View file

@ -28,9 +28,12 @@ set(SRC
${INCROOT}/SoundStream.hpp
)
# let CMake know about our additional audio libraries paths (on Windows)
# let CMake know about our additional audio libraries paths (on Windows and OSX)
if(WINDOWS)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/AL")
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/AL")
elseif (MACOSX)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/Frameworks")
endif()
# find external libraries

View file

@ -57,19 +57,47 @@ if(WINDOWS)
${SRCROOT}/Win32/RenderImageImplPBuffer.cpp
${SRCROOT}/Win32/RenderImageImplPBuffer.hpp
)
else()
elseif(LINUX)
set(SRC
${SRC}
${SRCROOT}/Linux/RenderImageImplPBuffer.cpp
${SRCROOT}/Linux/RenderImageImplPBuffer.hpp
)
elseif(MACOSX)
set(SRC
${SRC}
${SRCROOT}/OSX/RenderImageImplPBuffer.cpp
${SRCROOT}/OSX/RenderImageImplPBuffer.hpp
)
endif()
# let CMake know about our additional graphics libraries paths (on Windows)
# let CMake know about our additional graphics libraries paths (on Windows and OSX)
if (WINDOWS)
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/freetype")
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/GL")
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/jpeg")
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/headers/jpeg")
elseif (MACOSX)
# Add freetype search path
#if (${CMAKE_OSX_SYSROOT} STREQUAL "/Developer/SDKs/MacOSX10.4u.sdk")
# set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11R6/include/")
# set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11R6/lib/")
#else ()
# set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11/include/")
# set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_OSX_SYSROOT}/usr/X11/lib/")
#endif ()
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include/")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/lib/")
# Add GLEW search path
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include/")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/lib/")
# Add jpeg search path
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/include/jpeg")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${CMAKE_SOURCE_DIR}/extlibs/libs-osx/lib/")
endif()
# find external libraries
@ -91,6 +119,10 @@ if(BUILD_SHARED_LIBS)
set(GRAPHICS_EXT_LIBS ${GRAPHICS_EXT_LIBS} ${OPENGL_gl_LIBRARY})
if(LINUX)
set(GRAPHICS_EXT_LIBS ${GRAPHICS_EXT_LIBS} ${X11_LIBRARIES})
endif()
if(MACOSX)
# We use static version of freetype so we need to link against zlib.
set(GRAPHICS_EXT_LIBS ${GRAPHICS_EXT_LIBS} z)
endif()
endif()

View file

@ -0,0 +1,97 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/OSX/RenderImageImplPBuffer.hpp>
#include <SFML/Graphics/GLCheck.hpp>
#include <SFML/Window/Context.hpp>
#include <SFML/System/Err.hpp>
#warning RenderImageImplPBuffer not yet implemented
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
RenderImageImplPBuffer::RenderImageImplPBuffer()
{
/* TODO */
}
////////////////////////////////////////////////////////////
RenderImageImplPBuffer::~RenderImageImplPBuffer()
{
/* TODO */
// This is to make sure that another valid context is made
// active after we destroy the P-Buffer's one
Context::SetReferenceActive();
}
////////////////////////////////////////////////////////////
bool RenderImageImplPBuffer::IsSupported()
{
/* TODO */
return false;
}
////////////////////////////////////////////////////////////
bool RenderImageImplPBuffer::Create(unsigned int width, unsigned int height, unsigned int, bool depthBuffer)
{
// Store the dimensions
myWidth = width;
myHeight = height;
/* TODO */
return true;
}
////////////////////////////////////////////////////////////
bool RenderImageImplPBuffer::Activate(bool active)
{
if (active)
{
if (false/*myPBuffer && myContext*/)
{
// try to activate
}
else
{
return false;
}
}
else
{
// To deactivate the P-Buffer's context, we actually activate
// another one so that we make sure that there is always an
// active context for subsequent graphics operations
return Context::SetReferenceActive();
}
}
////////////////////////////////////////////////////////////
void RenderImageImplPBuffer::UpdateTexture(unsigned int textureId)
{
if (Activate(true))
{
GLint previous;
GLCheck(glGetIntegerv(GL_TEXTURE_BINDING_2D, &previous));
// Copy the rendered pixels to the image
GLCheck(glBindTexture(GL_TEXTURE_2D, textureId));
GLCheck(glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, myWidth, myHeight));
GLCheck(glBindTexture(GL_TEXTURE_2D, previous));
}
}
} // namespace priv
} // namespace sf

View file

@ -0,0 +1,89 @@
#ifndef SFML_RENDERIMAGEIMPLPBUFFER_HPP
#define SFML_RENDERIMAGEIMPLPBUFFER_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Graphics/RenderImageImpl.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Specialization of RenderImageImpl using ****** P-Buffers
///
////////////////////////////////////////////////////////////
class RenderImageImplPBuffer : public RenderImageImpl
{
public :
////////////////////////////////////////////////////////////
/// \brief Default constructor
///
////////////////////////////////////////////////////////////
RenderImageImplPBuffer();
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~RenderImageImplPBuffer();
////////////////////////////////////////////////////////////
/// \brief Check whether the system supports P-Buffer or not
///
/// \return True if P-Buffer render images are supported
///
////////////////////////////////////////////////////////////
static bool IsSupported();
private :
////////////////////////////////////////////////////////////
/// \brief Create the render image implementation
///
/// \param width Width of the image to render to
/// \param height Height of the image to render to
/// \param textureId OpenGL texture identifier of the target image
/// \param depthBuffer Is a depth buffer requested?
///
/// \return True if creation has been successful
///
////////////////////////////////////////////////////////////
virtual bool Create(unsigned int width, unsigned int height, unsigned int textureId, bool depthBuffer);
////////////////////////////////////////////////////////////
/// \brief Activate or deactivate the render image for rendering
///
/// \param active True to activate, false to deactivate
///
/// \return True on success, false on failure
///
////////////////////////////////////////////////////////////
virtual bool Activate(bool active);
////////////////////////////////////////////////////////////
/// \brief Update the pixels of the target texture
///
/// \param textureId OpenGL identifier of the target texture
///
////////////////////////////////////////////////////////////
virtual void UpdateTexture(unsigned textureId);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
unsigned int myWidth; ///< Width of the P-Buffer
unsigned int myHeight; ///< Height of the P-Buffer
};
} // namespace priv
} // namespace sf
#endif // SFML_RENDERIMAGEIMPLPBUFFER_HPP

View file

@ -39,6 +39,6 @@
#elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Graphics/MacOSX/RenderImageImplPBuffer.hpp>
#include <SFML/Graphics/OSX/RenderImageImplPBuffer.hpp>
#endif

View file

@ -47,18 +47,25 @@ elseif(LINUX)
${SRCROOT}/Linux/WindowImplX11.cpp
${SRCROOT}/Linux/WindowImplX11.hpp
)
else()
else() # MACOSX
set(SRC
${SRC}
${SRCROOT}/Cocoa/AppController.h
${SRCROOT}/Cocoa/AppController.mm
${SRCROOT}/Cocoa/GLKit.h
${SRCROOT}/Cocoa/GLKit.mm
${SRCROOT}/Cocoa/Joystick.cpp
${SRCROOT}/Cocoa/Joystick.hpp
${SRCROOT}/Cocoa/VideoModeImpl.cpp
${SRCROOT}/Cocoa/WindowImplCocoa.cpp
${SRCROOT}/Cocoa/WindowImplCocoa.mm
${SRCROOT}/OSX/cpp_objc_conversion.h
${SRCROOT}/OSX/cpp_objc_conversion.mm
${SRCROOT}/OSX/Joystick.cpp
${SRCROOT}/OSX/Joystick.hpp
${SRCROOT}/OSX/SFApplication.h
${SRCROOT}/OSX/SFApplication.m
${SRCROOT}/OSX/SFContext.hpp
${SRCROOT}/OSX/SFContext.mm
${SRCROOT}/OSX/SFOpenGLView.h
${SRCROOT}/OSX/SFOpenGLView.mm
${SRCROOT}/OSX/SFWindowController.h
${SRCROOT}/OSX/SFWindowController.mm
${SRCROOT}/OSX/VideoModeImpl.cpp
${SRCROOT}/OSX/WindowImplCocoa.hpp
${SRCROOT}/OSX/WindowImplCocoa.mm
${SRCROOT}/OSX/WindowImplDelegateProtocol.h
)
endif()
@ -72,8 +79,10 @@ endif()
set(WINDOW_EXT_LIBS ${OPENGL_gl_LIBRARY})
if(WINDOWS)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} winmm gdi32)
else(LINUX)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
elseif(LINUX)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
elseif(MACOSX)
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} "-framework Foundation -framework AppKit")
endif()
# define the sfml-window target

View file

@ -1,95 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/VideoMode.hpp>
#import <Cocoa/Cocoa.h>
// Fade operations
enum {
FillScreen,
CleanScreen
};
@class sfPrivWindow;
@interface sfPrivAppController : NSObject {
BOOL myOwningEventLoop;
sfPrivWindow *myFullscreenWrapper;
NSAutoreleasePool *myMainPool;
sf::VideoMode myDesktopMode;
sf::VideoMode myPrevMode;
}
////////////////////////////////////////////////////////////
/// Return the shared AppController instance. Make one if needed.
////////////////////////////////////////////////////////////
+ (sfPrivAppController *)sharedController;
////////////////////////////////////////////////////////////
/// Returns the primay computer's screen
////////////////////////////////////////////////////////////
+ (CGDirectDisplayID)primaryScreen;
////////////////////////////////////////////////////////////
/// Reset notifictions about application focus
////////////////////////////////////////////////////////////
- (void)setNotifications;
////////////////////////////////////////////////////////////
/// Make the menu bar
////////////////////////////////////////////////////////////
- (void)makeMenuBar;
////////////////////////////////////////////////////////////
/// Process all the events and send them to the application
/// No event is processed if the AppController instance is
/// not the owner of the event loop (ie: user made his own loop)
////////////////////////////////////////////////////////////
- (void)processEvents;
////////////////////////////////////////////////////////////
/// Set @window as the current fullscreen window
/// Change the screen resolution if needed according to @window and @fullscreenMode
////////////////////////////////////////////////////////////
- (void)setFullscreenWindow:(sfPrivWindow *)window mode:(sf::VideoMode *)fullscreenMode;
////////////////////////////////////////////////////////////
/// Perform fade operation where 'operation' is one of { FillScreen, CleanScreen}
/// and 'time' is the time during which you wish the operation to be performed.
/// Set 'sync' to true if you do not want the method to end before the end
/// of the fade operation.
////////////////////////////////////////////////////////////
- (void)doFadeOperation:(int)operation time:(float)time sync:(bool)sync;
////////////////////////////////////////////////////////////
/// Return the desktop video mode (made at the instance initialization)
////////////////////////////////////////////////////////////
- (const sf::VideoMode&)desktopMode;
@end

View file

@ -1,578 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/Cocoa/AppController.h>
#import <SFML/Window/Cocoa/GLKit.h>
#import <SFML/System.hpp>
#import <ApplicationServices/ApplicationServices.h>
#import <iostream>
/* setAppleMenu disappeared from the headers in 10.4 */
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
@interface NSApplication (SFML)
- (void)setAppleMenu:(NSMenu *)menu;
@end
#endif
#define ENABLE_FADE_OPERATIONS 1
@implementation NSApplication (SFML)
- (void)setRunning:(BOOL)flag
{
// Note: _running is a short, not a BOOL
if (flag)
_running = 1;
else
_running = 0;
}
@end
@implementation sfPrivAppController
////////////////////////////////////////////////////////////
/// Return an initialized AppController instance
/// Save the desktop mode
/// Make the main autorelease pool
/// Set the application observer
////////////////////////////////////////////////////////////
- (id)init
{
self = [super init];
if (self != nil) {
myOwningEventLoop = NO;
// Save the desktop mode
myDesktopMode = sf::VideoMode::GetDesktopMode();
myPrevMode = myDesktopMode;
// Make the app autorelease pool
myMainPool = [[NSAutoreleasePool alloc] init];
if (!myMainPool) {
[self release];
throw std::bad_alloc();
}
// Don't go on if the user handles the app
if (![NSApp isRunning])
{
// Force our application to appear in the Dock and make it able
// to get focus (even when it's a raw executable)
ProcessSerialNumber psn;
if (!GetCurrentProcess(&psn)) {
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
}
// Make the app
if (![NSApplication sharedApplication]) {
[self release];
throw std::bad_alloc();
}
[self setNotifications];
if ([NSApp mainMenu] == nil) {
[self makeMenuBar];
}
}
}
return self;
}
////////////////////////////////////////////////////////////
/// Clean the controller
////////////////////////////////////////////////////////////
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[myMainPool release];
[super dealloc];
}
////////////////////////////////////////////////////////////
/// Return the shared AppController instance. Make one if needed.
////////////////////////////////////////////////////////////
+ (sfPrivAppController *)sharedController
{
// AppController singleton object
static sfPrivAppController *shared = [[sfPrivAppController alloc] init];
return shared;
}
////////////////////////////////////////////////////////////
/// Returns the primay computer's screen
////////////////////////////////////////////////////////////
+ (CGDirectDisplayID)primaryScreen
{
static BOOL firstTime = YES;
static CGDirectDisplayID screen = kCGNullDirectDisplay;
if (firstTime) {
CGDisplayCount numScr;
CGDisplayErr err = CGGetDisplaysWithPoint(CGPointMake(0, 0), 1, &screen, &numScr);
if (err != kCGErrorSuccess || numScr < 1) {
std::cerr << "Unable to get primary screen (error code " << err
<< " ). Using the main screen.";
screen = CGMainDisplayID();
}
firstTime = NO;
}
return screen;
}
////////////////////////////////////////////////////////////
/// Reset notifictions about application focus
////////////////////////////////////////////////////////////
- (void)setNotifications
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(applicationWillDeactivate:)
name:NSApplicationWillResignActiveNotification
object:NSApp];
[nc addObserver:self
selector:@selector(applicationWillActivate:)
name:NSApplicationWillBecomeActiveNotification
object:NSApp];
[nc addObserver:self
selector:@selector(applicationWillTerminate:)
name:NSApplicationWillTerminateNotification
object:NSApp];
}
////////////////////////////////////////////////////////////
/// Hide all the fullscreen windows and switch back to the desktop display mode
////////////////////////////////////////////////////////////
- (void)applicationWillDeactivate:(NSNotification *)aNotification
{
// Note: not using fading because it produces reactivation issues
if (myFullscreenWrapper) {
myPrevMode = sf::VideoMode::GetDesktopMode();
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
myDesktopMode.BitsPerPixel,
myDesktopMode.Width,
myDesktopMode.Height,
NULL);
// Make the full screen window unvisible
[[myFullscreenWrapper window] setAlphaValue:0.0f];
// Switch to the wished display mode
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
}
}
////////////////////////////////////////////////////////////
/// Unhide all the fullscreen windows and switch to full screen display mode
////////////////////////////////////////////////////////////
- (void)applicationWillActivate:(NSNotification *)aNotification
{
if (myFullscreenWrapper) {
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
myPrevMode.BitsPerPixel,
myPrevMode.Width,
myPrevMode.Height,
NULL);
[NSMenu setMenuBarVisible:NO];
// Switch to the wished display mode
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
// Show the fullscreen window if existing
if (myFullscreenWrapper)
{
[[myFullscreenWrapper window] setAlphaValue:1.0f];
[[myFullscreenWrapper window] center];
[[myFullscreenWrapper window] makeKeyAndOrderFront:self];
}
}
}
- (void)applicationWillTerminate:(NSNotification *)aNotification
{
if (myFullscreenWrapper)
[self setFullscreenWindow:nil mode:NULL];
}
////////////////////////////////////////////////////////////
/// Make menu bar
////////////////////////////////////////////////////////////
- (void)makeMenuBar
{
// Source taken from SDL 1.3
NSString *appName = nil;
NSString *title = nil;
NSMenu *appleMenu = nil;
NSMenu *fileMenu = nil;
NSMenu *windowMenu = nil;
NSMenuItem *menuItem = nil;
NSMenuItem *quitMenuItem = nil;
// Determine the application name
appName = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"CFBundleName"];
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
// Create the main menu bar
[NSApp setMainMenu:[[NSMenu alloc] init]];
// Create the application menu
appleMenu = [[NSMenu alloc] initWithTitle:@""];
// Put menu items
// + 'About' menu item
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title
action:@selector(orderFrontStandardAboutPanel:)
keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
// + 'Hide' menu item
title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title
action:@selector(hide:)
keyEquivalent:@"h"];
// + 'Hide other' menu item
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask];
// + 'Show all' menu item
[appleMenu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:)
keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
// + 'Quit' menu item
title = [@"Quit " stringByAppendingString:appName];
quitMenuItem = [[[NSMenuItem alloc]
initWithTitle:title
action:@selector(terminate:)
keyEquivalent:@"q"] autorelease];
//[quitMenuItem setTarget:self];
[appleMenu addItem:quitMenuItem];
// Put the menu into the menubar
menuItem = [[NSMenuItem alloc]
initWithTitle:@""
action:nil
keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];
[menuItem release];
// Tell the application object that this is now the application menu
[NSApp setAppleMenu:appleMenu];
[appleMenu release];
// 'File' menu
fileMenu = [[NSMenu alloc]
initWithTitle:@"File"];
// + 'Close' menu item
menuItem = [[NSMenuItem alloc]
initWithTitle:@"Close"
action:@selector(performClose:)
keyEquivalent:@"w"];
[fileMenu addItem:menuItem];
[menuItem release];
// + 'File' menu item (head)
menuItem = [[NSMenuItem alloc]
initWithTitle:@"File"
action:nil
keyEquivalent:@""];
[menuItem setSubmenu:fileMenu];
[[NSApp mainMenu] addItem:menuItem];
[menuItem release];
// 'Window' menu
windowMenu = [[NSMenu alloc]
initWithTitle:@"Window"];
// + 'Minimize' menu item
menuItem = [[NSMenuItem alloc]
initWithTitle:@"Minimize"
action:@selector(performMiniaturize:)
keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
// + 'Window' menu item (head)
menuItem = [[NSMenuItem alloc]
initWithTitle:@"Window"
action:nil keyEquivalent:@""];
[menuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:menuItem];
[menuItem release];
// Tell the application object that this is now the window menu
[NSApp setWindowsMenu:windowMenu];
[windowMenu release];
}
////////////////////////////////////////////////////////////
/// Process all the events and send them to the application
/// No event is processed if the AppController instance is
/// not the owner of the event loop (ie: user made his own loop)
////////////////////////////////////////////////////////////
- (void)processEvents
{
// Check there is a run loop
if (![NSApp isRunning])
{
// Get the ownershipt of event handling if not and run
[NSApp finishLaunching];
[NSApp setRunning:YES];
myOwningEventLoop = YES;
}
NSEvent *event = nil;
if (myOwningEventLoop)
{
// Clean the autorelease pool
[myMainPool release];
myMainPool = [[NSAutoreleasePool alloc] init];
// Minimal event loop
while (nil != (event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:nil
inMode:NSDefaultRunLoopMode
dequeue:YES]))
{
[NSApp sendEvent:event];
}
}
}
////////////////////////////////////////////////////////////
/// Set @window as the current fullscreen window
/// Change the screen resolution if needed according to @window and @fullscreenMode
////////////////////////////////////////////////////////////
- (void)setFullscreenWindow:(sfPrivWindow *)aWindow mode:(sf::VideoMode *)fullscreenMode
{
// If we have a fullscreen window and want to remove it
if (aWindow == nil && myFullscreenWrapper)
{
// Get the CoreGraphics display mode according to the desktop mode
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
myDesktopMode.BitsPerPixel,
myDesktopMode.Width,
myDesktopMode.Height,
NULL);
#if ENABLE_FADE_OPERATIONS
// Fade to black screen
[self doFadeOperation:FillScreen time:0.2f sync:true];
#endif
// Switch to the desktop display mode
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
// Close the window
[[myFullscreenWrapper window] close];
// Show the menu bar
[NSMenu setMenuBarVisible:YES];
#if ENABLE_FADE_OPERATIONS
// Fade to normal screen
[self doFadeOperation:CleanScreen time:0.5f sync:true];
#endif
// Release the saved window wrapper
myFullscreenWrapper = nil;
}
else if (aWindow)
{
// else if we want to SET fullscreen
assert(fullscreenMode != NULL);
// Get the CoreGraphics display mode according to the given sf mode
CFDictionaryRef displayMode = CGDisplayBestModeForParameters ([sfPrivAppController primaryScreen],
fullscreenMode->BitsPerPixel,
fullscreenMode->Width,
fullscreenMode->Height,
NULL);
#if ENABLE_FADE_OPERATIONS
// Fade to a black screen
[self doFadeOperation:FillScreen time:0.5f sync:true];
#endif
if (!myFullscreenWrapper)
{
// Hide the main menu bar
[NSMenu setMenuBarVisible:NO];
}
if (myPrevMode != *fullscreenMode)
{
// Switch to the wished display mode
myPrevMode = *fullscreenMode;
CGDisplaySwitchToMode([sfPrivAppController primaryScreen], displayMode);
}
if (myFullscreenWrapper)
{
[[myFullscreenWrapper window] close];
}
// Open and center the window
[[aWindow window] makeKeyAndOrderFront:nil];
[[aWindow window] center];
#if ENABLE_FADE_OPERATIONS
// Fade to normal screen
[self doFadeOperation:CleanScreen time:0.2f sync:false];
#endif
// Save the fullscreen wrapper
myFullscreenWrapper = aWindow;
}
else
{
std::cerr << "Inconcistency error for arguments given to -[sfPrivAppController setFullscreenWindow:mode:]" << std::endl;
}
}
////////////////////////////////////////////////////////////
/// Perform fade operation where 'operation' is one of {FillScreen, CleanScreen}
/// and 'time' is the time during which you wish the operation to be performed.
/// Set 'sync' to true if you do not want the method to end before the end
/// of the fade operation. Pass the last used token or a new one if you are
/// using this method for the first time. This lets the method release some
/// resources when doing CleanScreen operation.
////////////////////////////////////////////////////////////
- (void) doFadeOperation:(int)operation time:(float)time sync:(bool)sync
{
static CGDisplayFadeReservationToken prevToken = kCGDisplayFadeReservationInvalidToken;
CGDisplayFadeReservationToken token = prevToken;
CGError result = 0, capture = 0;
if (operation == FillScreen) {
// Get access for the fade operation
result = CGAcquireDisplayFadeReservation((int)(3 + time), &token);
if (!result) {
// Capture display but do not fill the screen with black
// so that we can see the fade operation
capture = CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoFill);
if (!capture) {
// Do the increasing fade operation
CGDisplayFade(token, time,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
0.0f, 0.0f, 0.0f, sync);
// Now, release the non black-filling capture
CGDisplayRelease([sfPrivAppController primaryScreen]);
// And capture with filling
// so that we don't see the switching in the meantime
CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoOptions);
}
prevToken = token;
}
} else if (operation == CleanScreen) {
// Get access for the fade operation
if (token == kCGDisplayFadeReservationInvalidToken)
result = CGAcquireDisplayFadeReservation((int)(3 + time), &token);
if (!result) {
if (!capture) {
// Release the black-filling capture
CGDisplayRelease([sfPrivAppController primaryScreen]);
// Capture the display but do not fill with black (still for the fade operation)
CGDisplayCaptureWithOptions([sfPrivAppController primaryScreen], kCGCaptureNoFill);
// Do the decreasing fading
CGDisplayFade(token, time,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0f, 0.0f, 0.0f, sync);
// Release the fade operation token
CGReleaseDisplayFadeReservation(token);
// Invalidate the given token
prevToken = kCGDisplayFadeReservationInvalidToken;
}
// Release the captured display
CGDisplayRelease([sfPrivAppController primaryScreen]);
}
}
}
////////////////////////////////////////////////////////////
/// Return the desktop video mode (made at the instance initialization)
////////////////////////////////////////////////////////////
- (const sf::VideoMode&)desktopMode
{
return myDesktopMode;
}
@end

View file

@ -1,232 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <Cocoa/Cocoa.h>
#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
////////////////////////////////////////////////////////////
/// Window independant OpenGL context class
////////////////////////////////////////////////////////////
@interface sfPrivGLContext : NSOpenGLContext
////////////////////////////////////////////////////////////
/// Return the shared OpenGL context instance (making one if needed)
////////////////////////////////////////////////////////////
+ (id)sharedContext;
////////////////////////////////////////////////////////////
/// Make a new OpenGL context according to the @attribs settings
/// and the shared context @context
////////////////////////////////////////////////////////////
- (id)initWithAttributes:(sf::WindowSettings&)attribs
sharedContext:(sfPrivGLContext *)context;
@end
////////////////////////////////////////////////////////////
/// Customized Cocoa OpenGL view
////////////////////////////////////////////////////////////
@interface sfPrivGLView : NSOpenGLView
{
sf::priv::WindowImplCocoa *myDelegate;
sfPrivGLContext *myGLContext;
}
////////////////////////////////////////////////////////////
/// Make a new view according the the rect @frame,
/// the video mode @mode, the window settings @settings
/// @delegate must not be null
////////////////////////////////////////////////////////////
- (id)initWithFrame:(NSRect)frame
mode:(const sf::VideoMode&)mode
settings:(sf::WindowSettings&)settings;
////////////////////////////////////////////////////////////
/// Sets @aDelegate as the view delegate
////////////////////////////////////////////////////////////
- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate;
////////////////////////////////////////////////////////////
/// Returns the view delegate
////////////////////////////////////////////////////////////
- (sf::priv::WindowImplCocoa *)delegate;
////////////////////////////////////////////////////////////
/// Finish view setting (after having added it to the window)
////////////////////////////////////////////////////////////
- (void)finishInitialization;
////////////////////////////////////////////////////////////
/// Forward call to en/disable vertical synchronization
////////////////////////////////////////////////////////////
- (void)enableVerticalSync:(bool)flag;
////////////////////////////////////////////////////////////
/// Forward call to set the OpenGL context as active according to @flag
////////////////////////////////////////////////////////////
- (void)setActive:(bool)flag;
////////////////////////////////////////////////////////////
/// Forward call to flush the OpenGL context
////////////////////////////////////////////////////////////
- (void)flushBuffer;
@end
////////////////////////////////////////////////////////////
/// Parent class for handling general SFML window stuff
////////////////////////////////////////////////////////////
@interface sfPrivWindow : NSObject
{
@private
NSWindow *myWindow;
sfPrivGLView *myView;
}
////////////////////////////////////////////////////////////
/// Return a reference to the internal Cocoa window
////////////////////////////////////////////////////////////
- (NSWindow *)window;
////////////////////////////////////////////////////////////
/// Return a reference to the internal Cocoa OpenGL view
////////////////////////////////////////////////////////////
- (sfPrivGLView *)view;
////////////////////////////////////////////////////////////
/// Sets @aDelegate as the window delegate
////////////////////////////////////////////////////////////
- (void)setDelegate:(sf::priv::WindowImplCocoa *)aDelegate;
////////////////////////////////////////////////////////////
/// Returns the window delegate
////////////////////////////////////////////////////////////
- (sf::priv::WindowImplCocoa *)delegate;
////////////////////////////////////////////////////////////
/// Forward call to set the window position on screen
////////////////////////////////////////////////////////////
- (void)setPosition:(NSPoint)pos;
////////////////////////////////////////////////////////////
/// Forward call to set the window size
////////////////////////////////////////////////////////////
- (void)setSize:(NSSize)size;
////////////////////////////////////////////////////////////
/// Return the mouse location relative to the internal window
////////////////////////////////////////////////////////////
- (NSPoint)mouseLocation;
////////////////////////////////////////////////////////////
/// Return whether the mouse is on our window
////////////////////////////////////////////////////////////
- (BOOL)mouseInside;
////////////////////////////////////////////////////////////
/// Close or open the window
////////////////////////////////////////////////////////////
- (void)show:(bool)flag;
////////////////////////////////////////////////////////////
/// Forward call to en/disable the OpenGL view vertical synchronization
////////////////////////////////////////////////////////////
- (void)enableVerticalSync:(bool)flag;
////////////////////////////////////////////////////////////
/// Forward 'setActive' call the the OpenGL view
////////////////////////////////////////////////////////////
- (void)setActive:(bool)flag;
////////////////////////////////////////////////////////////
/// Forward call to flush the OpenGL view
////////////////////////////////////////////////////////////
- (void)flushBuffer;
@end
////////////////////////////////////////////////////////////
/// Class for creating new SFML windows from informations
////////////////////////////////////////////////////////////
@interface sfPrivOwnedWindow : sfPrivWindow
{
@private
sf::VideoMode myFullscreenMode;
bool myIsFullscreen;
}
////////////////////////////////////////////////////////////
/// Creates and returns a new SFML window handler with
/// the given parameters
////////////////////////////////////////////////////////////
- (id)initWithVideoMode:(sf::VideoMode&)aMode
settings:(sf::WindowSettings&)someSettings
style:(unsigned long)aStyle
title:(NSString *)aTitle;
////////////////////////////////////////////////////////////
/// Returns the window's fullscreen state
////////////////////////////////////////////////////////////
- (BOOL)isFullscreen;
@end
////////////////////////////////////////////////////////////
/// Class for creating SFML windows from Cocoa windows
////////////////////////////////////////////////////////////
@interface sfPrivImportedWindow : sfPrivWindow
////////////////////////////////////////////////////////////
/// Returns a new SFML window handler with the given window
/// and parameters
////////////////////////////////////////////////////////////
- (id)initWithWindow:(NSWindow *)aWindow
settings:(sf::WindowSettings&)someSettings;
@end
////////////////////////////////////////////////////////////
/// Class for creating SFML windows from Cocoa views
////////////////////////////////////////////////////////////
@interface sfPrivImportedView : sfPrivWindow
{
NSView *parentView;
}
////////////////////////////////////////////////////////////
/// Returns a new SFML window handler with the given view
/// and parameters
////////////////////////////////////////////////////////////
- (id)initWithView:(NSView *)aView
settings:(sf::WindowSettings&)someSettings;
@end

File diff suppressed because it is too large Load diff

View file

@ -1,77 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Joystick.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Initialize the instance and bind it to a physical joystick
////////////////////////////////////////////////////////////
void Joystick::Initialize(unsigned int Index)
{
// Reset the joystick state
// Initialize the Index-th available joystick
}
////////////////////////////////////////////////////////////
/// Update the current joystick and return its new state
////////////////////////////////////////////////////////////
JoystickState Joystick::UpdateState()
{
// Fill a JoystickState instance with the current joystick state
JoystickState s;
return s;
}
////////////////////////////////////////////////////////////
/// Check if the joystick supports the given axis
////////////////////////////////////////////////////////////
bool Joystick::HasAxis(Joy::Axis Axis) const
{
return false;
}
////////////////////////////////////////////////////////////
/// Get the number of buttons supported by the joystick
////////////////////////////////////////////////////////////
unsigned int Joystick::GetButtonsCount() const
{
// Return number of supported buttons
return 0;
}
} // namespace priv
} // namespace sf

View file

@ -1,84 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_JOYSTICKCARBON_HPP
#define SFML_JOYSTICKCARBON_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// ****** implementation of Joystick (unknown implementation kind for now)
////////////////////////////////////////////////////////////
class Joystick
{
public :
////////////////////////////////////////////////////////////
/// Initialize the instance and bind it to a physical joystick
///
/// \param Index : Index of the physical joystick to bind to
///
////////////////////////////////////////////////////////////
void Initialize(unsigned int Index);
////////////////////////////////////////////////////////////
/// Update the current joystick and return its new state
///
/// \return Current state of the joystick
///
////////////////////////////////////////////////////////////
JoystickState UpdateState();
////////////////////////////////////////////////////////////
/// Check if the joystick supports the given axis
///
/// \param Axis : Axis to check
///
/// \return True of the axis is supported, false otherwise
///
////////////////////////////////////////////////////////////
bool HasAxis(Joy::Axis Axis) const;
////////////////////////////////////////////////////////////
/// Get the number of buttons supported by the joystick
///
/// \return Number of buttons
///
////////////////////////////////////////////////////////////
unsigned int GetButtonsCount() const;
};
} // namespace priv
} // namespace sf
#endif // SFML_JOYSTICKCARBON_HPP

View file

@ -1,101 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/VideoModeImpl.hpp>
#include <ApplicationServices/ApplicationServices.h>
#include <algorithm>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// Get supported video modes
////////////////////////////////////////////////////////////
void VideoModeSupport::GetSupportedVideoModes(std::vector<VideoMode>& Modes)
{
// Ceylo -- using same implementation as in OSXCarbon
// First, clear array to fill
Modes.clear();
// Enumerate all available video modes for primary display adapter
CFArrayRef DisplayModes = CGDisplayAvailableModes( kCGDirectMainDisplay );
CFIndex DisplayModeCount = CFArrayGetCount( DisplayModes );
CFDictionaryRef CurrentMode;
for (int Count = 0; Count < DisplayModeCount; ++Count)
{
CurrentMode = (CFDictionaryRef)CFArrayGetValueAtIndex( DisplayModes, Count );
VideoMode Mode;
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayWidth), kCFNumberIntType, &(Mode.Width));
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayHeight), kCFNumberIntType, &(Mode.Height));
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentMode, kCGDisplayBitsPerPixel), kCFNumberIntType, &(Mode.BitsPerPixel));
// Add it only if it is not already in the array
if (std::find(Modes.begin(), Modes.end(), Mode) == Modes.end())
Modes.push_back(Mode);
}
}
////////////////////////////////////////////////////////////
/// Get current desktop video mode
////////////////////////////////////////////////////////////
VideoMode VideoModeSupport::GetDesktopVideoMode()
{
// Ceylo -- using same implementation as in OSXCarbon
CFDictionaryRef CurrentVideoMode = CGDisplayCurrentMode(kCGDirectMainDisplay);
VideoMode DesktopMode;
// Get video mode width
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentVideoMode, kCGDisplayWidth),
kCFNumberIntType,
&(DesktopMode.Width));
// Get video mode height
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentVideoMode, kCGDisplayHeight),
kCFNumberIntType,
&(DesktopMode.Height));
// Get video mode depth
CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(CurrentVideoMode, kCGDisplayBitsPerPixel),
kCFNumberIntType,
&(DesktopMode.BitsPerPixel));
return DesktopMode;
}
} // namespace priv
} // namespace sf

View file

@ -1,205 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
#ifndef SFML_WINDOWIMPLCOCOA_HPP
#define SFML_WINDOWIMPLCOCOA_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Event.hpp>
#include <SFML/Window/WindowImpl.hpp>
#include <string>
#ifdef __OBJC__
@class sfPrivWindow;
typedef sfPrivWindow* sfPrivWindowRef;
#else
typedef void* sfPrivWindowRef;
#endif
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// WindowImplCocoa is the Cocoa implementation of WindowImpl
////////////////////////////////////////////////////////////
class WindowImplCocoa : public WindowImpl
{
public :
////////////////////////////////////////////////////////////
/// Default constructor
/// (creates a dummy window to provide a valid OpenGL context)
///
////////////////////////////////////////////////////////////
WindowImplCocoa();
////////////////////////////////////////////////////////////
/// Construct the window implementation from an existing control
///
/// \param Handle : Platform-specific handle of the control
/// \param Params : Creation parameters
///
/// Note: the NSWindow object must not be defered !
////////////////////////////////////////////////////////////
WindowImplCocoa(WindowHandle Handle, WindowSettings& params);
////////////////////////////////////////////////////////////
/// Create the window implementation
///
/// \param Mode : Video mode to use
/// \param Title : Title of the window
/// \param WindowStyle : Window style
/// \param Params : Creation parameters
///
////////////////////////////////////////////////////////////
WindowImplCocoa(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& params);
////////////////////////////////////////////////////////////
/// Destructor
///
////////////////////////////////////////////////////////////
~WindowImplCocoa();
////////////////////////////////////////////////////////////
/// Check if there's an active context on the current thread
///
/// \return True if there's a context bound to the current thread
///
////////////////////////////////////////////////////////////
static bool IsContextActive();
////////////////////////////////////////////////////////////
/// Handle an event sent by the default NSNotificationCenter
////////////////////////////////////////////////////////////
void HandleNotifiedEvent(Event& eventRef);
////////////////////////////////////////////////////////////
/// Event handling for every event type.
/// 'eventRef' is a NSEvent.
////////////////////////////////////////////////////////////
void HandleKeyDown(void *eventRef);
void HandleKeyUp(void *eventRef);
void HandleModifierKey(void *eventRef);
void HandleMouseDown(void *eventRef);
void HandleMouseUp(void *eventRef);
void HandleMouseMove(void *eventRef);
void HandleMouseWheel(void *eventRef);
////////////////////////////////////////////////////////////
/// Return whether 'ev' must be considered as a TextEntered event
////////////////////////////////////////////////////////////
static bool IsTextEvent(void *event);
private :
////////////////////////////////////////////////////////////
/// see WindowImpl::Display
///
////////////////////////////////////////////////////////////
virtual void Display();
////////////////////////////////////////////////////////////
/// see WindowImpl::ProcessEvents
///
////////////////////////////////////////////////////////////
virtual void ProcessEvents();
////////////////////////////////////////////////////////////
/// see WindowImpl::MakeActive
///
////////////////////////////////////////////////////////////
virtual void SetActive(bool Active = true) const;
////////////////////////////////////////////////////////////
/// see WindowImpl::UseVerticalSync
///
////////////////////////////////////////////////////////////
virtual void UseVerticalSync(bool Enabled);
////////////////////////////////////////////////////////////
/// see WindowImpl::ShowMouseCursor
///
////////////////////////////////////////////////////////////
virtual void ShowMouseCursor(bool Show);
////////////////////////////////////////////////////////////
/// see WindowImpl::SetCursorPosition
///
////////////////////////////////////////////////////////////
virtual void SetCursorPosition(unsigned int Left, unsigned int Top);
////////////////////////////////////////////////////////////
/// see WindowImpl::SetPosition
///
////////////////////////////////////////////////////////////
virtual void SetPosition(int Left, int Top);
////////////////////////////////////////////////////////////
/// /see WindowImpl::SetSize
///
////////////////////////////////////////////////////////////
virtual void SetSize(unsigned int Width, unsigned int Height);
////////////////////////////////////////////////////////////
/// see WindowImpl::Show
///
////////////////////////////////////////////////////////////
virtual void Show(bool State);
////////////////////////////////////////////////////////////
/// see WindowImpl::EnableKeyRepeat
///
////////////////////////////////////////////////////////////
virtual void EnableKeyRepeat(bool Enabled);
////////////////////////////////////////////////////////////
/// see WindowImpl::SetIcon
///
////////////////////////////////////////////////////////////
virtual void SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels);
////////////////////////////////////////////////////////////
/// My own part starts here !
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
sfPrivWindowRef myWrapper;
bool myUseKeyRepeat;
bool myMouseIn;
float myWheelStatus;
};
} // namespace priv
} // namespace sf
#endif // SFML_WINDOWIMPLCOCOA_HPP

View file

@ -1,844 +0,0 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
// Copyright (C) 2007-2009 Lucas Soltic (ceylow@gmail.com) and Laurent Gomila (laurent.gom@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/Cocoa/WindowImplCocoa.hpp>
#import <SFML/Window/Cocoa/AppController.h>
#import <SFML/Window/Cocoa/GLKit.h>
#import <SFML/Window/WindowStyle.hpp>
#import <SFML/System.hpp>
#import <iostream>
namespace sf
{
namespace priv
{
// Do something only once (useful in loops)
#define ONCE(make) \
{ static int __done = 0;\
if (!__done) {\
make;\
__done = 1;\
} }
////////////////////////////////////////////////////////////
/// Private function declarations
////////////////////////////////////////////////////////////
namespace {
Key::Code KeyForVirtualCode(unsigned short vCode);
Key::Code KeyForUnicode(unsigned short uniCode);
} // anonymous namespace
////////////////////////////////////////////////////////////
/// Default constructor
/// (creates a dummy window to provide a valid OpenGL context)
////////////////////////////////////////////////////////////
WindowImplCocoa::WindowImplCocoa() :
myWrapper(nil),
myUseKeyRepeat(false),
myMouseIn(false),
myWheelStatus(0.0f)
{
[sfPrivAppController sharedController];
// Create the shared OpenGL context
if ([sfPrivGLContext sharedContext]) {
// Then we make it the current active OpenGL context
SetActive();
} else {
std::cerr << "Unable to make the main shared OpenGL context" << std::endl;
}
}
////////////////////////////////////////////////////////////
/// Create the window implementation from an existing control
////////////////////////////////////////////////////////////
WindowImplCocoa::WindowImplCocoa(WindowHandle Handle, WindowSettings& params) :
myWrapper(NULL),
myUseKeyRepeat(false),
myMouseIn(false),
myWheelStatus(0.0f)
{
if (Handle) {
// Classical window import
if ([(id)Handle isKindOfClass:[NSWindow class]]) {
myWrapper = [[sfPrivImportedWindow alloc]
initWithWindow:(NSWindow *)Handle
settings:params];
}
// Qt "window" import
else if ([(id)Handle isKindOfClass:[NSView class]]) {
myWrapper = [[sfPrivImportedView alloc]
initWithView:(NSView *)Handle
settings:params];
} else {
std::cerr
<< "Cannot import this Window Handle because it is neither"
<< "a <NSWindow *> nor <NSView *> object"
<< "(or any of its subclasses). You gave a <"
<< [[(id)Handle className] UTF8String]
<< "> object."
<< std::endl;
}
if (myWrapper) {
[myWrapper setDelegate:this];
// initial mouse state
myMouseIn = [myWrapper mouseInside];
// We set the myWidth and myHeight members to the correct values
myWidth = (int) [[myWrapper view] frame].size.width;
myHeight = (int) [[myWrapper view] frame].size.height;
} else {
std::cerr << "Failed to make the public window" << std::endl;
}
} else {
std::cerr
<< "Invalid null handle given to "
<< "Window::Window(WindowHandle Handle, const WindowSettings& Params)"
<< std::endl;
}
}
////////////////////////////////////////////////////////////
/// Create the window implementation
////////////////////////////////////////////////////////////
WindowImplCocoa::WindowImplCocoa(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& params) :
myWrapper(NULL),
myUseKeyRepeat(false),
myMouseIn(false),
myWheelStatus(0.0f)
{
// Create a new window with given size, title and style
// First we define some objects used for our window
NSString *title = [NSString stringWithCString:(Title.c_str()) ? (Title.c_str()) : ""
encoding:NSASCIIStringEncoding];
// We create the window
myWrapper = [[sfPrivOwnedWindow alloc]
initWithVideoMode:Mode
settings:params
style:WindowStyle
title:title];
if (myWrapper)
{
[myWrapper setDelegate:this];
// initial mouse state
myMouseIn = [myWrapper mouseInside];
// We set the myWidth and myHeight members to the correct values
myWidth = Mode.Width;
myHeight = Mode.Height;
} else {
std::cerr << "Failed to make the public window" << std::endl;
}
}
////////////////////////////////////////////////////////////
/// Destructor
////////////////////////////////////////////////////////////
WindowImplCocoa::~WindowImplCocoa()
{
// Release the window wrapper
[myWrapper release];
}
////////////////////////////////////////////////////////////
/// Check if there's an active context on the current thread
////////////////////////////////////////////////////////////
bool WindowImplCocoa::IsContextActive()
{
return ([NSOpenGLContext currentContext] != NULL);
}
////////////////////////////////////////////////////////////
/// Handle event sent by the default NSNotificationCenter
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleNotifiedEvent(Event& event)
{
// Set myWidth and myHeight to correct value if
// window size changed
switch (event.Type) {
case Event::Resized:
myWidth = event.Size.Width;
myHeight = event.Size.Height;
break;
default:
break;
}
// And send the event
SendEvent(event);
}
////////////////////////////////////////////////////////////
/// Handle a key down event (NSEvent)
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleKeyDown(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
unichar chr = 0, rawchr = 0;
unsigned long length = [[event characters] length];
unsigned mods = [event modifierFlags];
if (length) {
chr = [[event characters] characterAtIndex:0];
// Note : I got a crash (out of bounds exception) while typing so now I test...
if ([[event charactersIgnoringModifiers] length])
rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0];
// Don't handle repeated events if we chose not to send them
if (!myUseKeyRepeat && [event isARepeat])
return;
// Is it also a text event ?
if (IsTextEvent(event)) {
// buffer for the UTF-32 characters
Uint32 utf32Characters[2] = {0};
// convert the characters
// note: using CFString in order to keep compatibility with Mac OS X 10.4
// (as NSUTF32StringEncoding is only being defined in Mac OS X 10.5 and later)
if (!CFStringGetCString ((CFStringRef)[event characters],
(char *)utf32Characters,
sizeof(utf32Characters),
kCFStringEncodingUTF32))
{
char asciiChar[3] = {0};
if ([[event characters] lengthOfBytesUsingEncoding:NSASCIIStringEncoding])
[[event characters] getCString:asciiChar
maxLength:3
encoding:NSASCIIStringEncoding];
std::cerr << "Error while converting character to UTF32 : \""
<< asciiChar << "\"" << std::endl;
}
else
{
sfEvent.Type = Event::TextEntered;
sfEvent.Text.Unicode = utf32Characters[0];
SendEvent(sfEvent);
}
}
// Anyway it's also a KeyPressed event
sfEvent.Type = Event::KeyPressed;
// Get the keys
if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) {
sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
}
// Get the modifiers
sfEvent.Key.Alt = mods & NSAlternateKeyMask;
sfEvent.Key.Control = mods & NSControlKeyMask;
sfEvent.Key.Shift = mods & NSShiftKeyMask;
// Send the event
SendEvent(sfEvent);
}
}
////////////////////////////////////////////////////////////
/// Handle a key up event (NSEvent)
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleKeyUp(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
unsigned mods = [event modifierFlags];
unichar chr = 0, rawchr = 0;
if ([[event characters] length]) {
chr = [[event characters] characterAtIndex:0];
if ([[event charactersIgnoringModifiers] length])
rawchr = [[event charactersIgnoringModifiers] characterAtIndex:0];
sfEvent.Type = Event::KeyReleased;
// Get the code
if (Key::Code(0) == (sfEvent.Key.Code = KeyForUnicode(rawchr))) {
sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
}
// Get the modifiers
sfEvent.Key.Alt = mods & NSAlternateKeyMask;
sfEvent.Key.Control = mods & NSControlKeyMask;
sfEvent.Key.Shift = mods & NSShiftKeyMask;
// Send the event
SendEvent(sfEvent);
}
}
////////////////////////////////////////////////////////////
/// Handle a key modifier event [Command, Option, Control, Shift]
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleModifierKey(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
unsigned mods = [event modifierFlags];
sfEvent.Type = Event::KeyPressed;
// Get the code
sfEvent.Key.Code = KeyForVirtualCode([event keyCode]);
// Get the modifiers
sfEvent.Key.Alt = mods & NSAlternateKeyMask;
sfEvent.Key.Control = mods & NSControlKeyMask;
sfEvent.Key.Shift = mods & NSShiftKeyMask;
// Guess whether it's a pressed or released event
// Note: this does not work fine is both left and right modifiers are pressed
// I did not find any way to fix this.
// TODO: fix handling of modifier flags for use of left and right key at the same time
if (!(mods & NSAlternateKeyMask) &&
(sfEvent.Key.Code == Key::LAlt || sfEvent.Key.Code == Key::RAlt)) {
sfEvent.Type = Event::KeyReleased;
}
if (!(mods & NSControlKeyMask) &&
(sfEvent.Key.Code == Key::LControl || sfEvent.Key.Code == Key::RControl)) {
sfEvent.Type = Event::KeyReleased;
}
if (!(mods & NSShiftKeyMask) &&
(sfEvent.Key.Code == Key::LShift || sfEvent.Key.Code == Key::RShift)) {
sfEvent.Type = Event::KeyReleased;
}
if (!(mods & NSCommandKeyMask) &&
(sfEvent.Key.Code == Key::LSystem || sfEvent.Key.Code == Key::RSystem)) {
sfEvent.Type = Event::KeyReleased;
}
// Send the event
SendEvent(sfEvent);
}
////////////////////////////////////////////////////////////
/// Handle a mouse down event (NSEvent)
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleMouseDown(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
// Get mouse position relative to the window
NSPoint loc = [myWrapper mouseLocation];
unsigned mods = [event modifierFlags];
switch ([event type]) {
case NSLeftMouseDown:
sfEvent.Type = Event::MouseButtonPressed;
// Guess whether it's a mouse left or mouse right event
if (mods & NSControlKeyMask) {
sfEvent.MouseButton.Button = Mouse::Right;
} else {
sfEvent.MouseButton.Button = Mouse::Left;
}
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
// Send the event
SendEvent(sfEvent);
break;
case NSRightMouseDown:
sfEvent.Type = Event::MouseButtonPressed;
sfEvent.MouseButton.Button = Mouse::Right;
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
// Send the event
SendEvent(sfEvent);
break;
default:
break;
}
}
////////////////////////////////////////////////////////////
/// Handle a mouse up event (NSEvent)
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleMouseUp(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
Event sfEvent;
// Get mouse position relative to the window
NSPoint loc = [myWrapper mouseLocation];
unsigned mods = [event modifierFlags];
switch ([event type]) {
case NSLeftMouseUp:
sfEvent.Type = Event::MouseButtonReleased;
// Guess whether it's a mouse left or mouse right event
if (mods & NSControlKeyMask) {
sfEvent.MouseButton.Button = Mouse::Right;
} else {
sfEvent.MouseButton.Button = Mouse::Left;
}
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
// Send the event
SendEvent(sfEvent);
break;
case NSRightMouseUp:
sfEvent.Type = Event::MouseButtonReleased;
sfEvent.MouseButton.Button = Mouse::Right;
sfEvent.MouseButton.X = (int) loc.x;
sfEvent.MouseButton.Y = (int) loc.y;
// Send the event
SendEvent(sfEvent);
break;
default:
break;
}
}
////////////////////////////////////////////////////////////
/// Handle a mouse move event (NSEvent)
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleMouseMove(void *eventRef)
{
Event sfEvent;
NSPoint loc = [myWrapper mouseLocation];
sfEvent.Type = Event::MouseMoved;
sfEvent.MouseMove.X = (int) loc.x;
sfEvent.MouseMove.Y = (int) loc.y;
SendEvent(sfEvent);
if ([myWrapper mouseInside] && !myMouseIn) {
// If mouse IS inside but WAS not inside last time
sfEvent.Type = Event::MouseEntered;
myMouseIn = true;
SendEvent(sfEvent);
} else if (![myWrapper mouseInside] && myMouseIn) {
// Is mouse WAS not inside but IS now inside
sfEvent.Type = Event::MouseLeft;
myMouseIn = false;
SendEvent(sfEvent);
}
}
////////////////////////////////////////////////////////////
/// Handle a mouse wheel event (NSEvent)
////////////////////////////////////////////////////////////
void WindowImplCocoa::HandleMouseWheel(void *eventRef)
{
NSEvent *event = reinterpret_cast <NSEvent *> (eventRef);
// SFML uses integer values for delta but Cocoa uses float and it is mostly fewer than 1.0
// Therefore I chose to add the float value to a 'wheel status' and
// send a sf event only when it's greater than 1.0
myWheelStatus += [event deltaY];
if (fabs(myWheelStatus) > 1.0f) {
// Make the event and send it
Event sfEvent;
sfEvent.Type = Event::MouseWheelMoved;
sfEvent.MouseWheel.Delta = (int) myWheelStatus;
SendEvent(sfEvent);
// Remove as much integer units as the one that have been put in the event
// (was a mistake to set this to 0)
myWheelStatus -= (int) myWheelStatus;
}
}
////////////////////////////////////////////////////////////
/// Return whether 'ev' must be considered as a TextEntered event
////////////////////////////////////////////////////////////
bool WindowImplCocoa::IsTextEvent(void *eventRef)
{
NSEvent *event = (NSEvent *)eventRef;
bool res = false;
if (event && [event type] == NSKeyDown && [[event characters] length]) {
unichar code = [[event characters] characterAtIndex:0];
// Codes from 0xF700 to 0xF8FF are non text keys (see NSEvent.h)
// 0x35 is the Escape key
if ([event keyCode] != 0x35 && (code < 0xF700 || code > 0xF8FF))
res = true;
}
return res;
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::Display
////////////////////////////////////////////////////////////
void WindowImplCocoa::Display()
{
// Forward flush call to the window
[myWrapper flushBuffer];
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::ProcessEvents
////////////////////////////////////////////////////////////
void WindowImplCocoa::ProcessEvents()
{
// Forward event handling call to the application controller
[[sfPrivAppController sharedController] processEvents];
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::MakeActive
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetActive(bool Active) const
{
// Forward the call to the window
if (myWrapper)
[myWrapper setActive:Active];
else {
// Or directly activate the shared OpenGL context if we're not using a window
if (Active) {
if ([NSOpenGLContext currentContext] != [sfPrivGLContext sharedContext])
[[sfPrivGLContext sharedContext] makeCurrentContext];
} else {
if ([NSOpenGLContext currentContext] == [sfPrivGLContext sharedContext])
[NSOpenGLContext clearCurrentContext];
}
}
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::UseVerticalSync
////////////////////////////////////////////////////////////
void WindowImplCocoa::UseVerticalSync(bool Enabled)
{
// Forward the call to the window
[myWrapper enableVerticalSync:Enabled];
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::ShowMouseCursor
////////////////////////////////////////////////////////////
void WindowImplCocoa::ShowMouseCursor(bool flag)
{
if (flag) {
[NSCursor unhide];
} else {
[NSCursor hide];
}
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::SetCursorPosition
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetCursorPosition(unsigned int Left, unsigned int Top)
{
NSPoint pos = NSMakePoint ((float) Left, (float) Top);
if (myWrapper) {
// Flip for SFML window coordinate system
pos.y = [[myWrapper window] frame].size.height - pos.y;
// Adjust for view reference instead of window
pos.y -= [[myWrapper window] frame].size.height - [[myWrapper view] frame].size.height;
// Convert to screen coordinates
NSPoint absolute = [[myWrapper window] convertBaseToScreen:pos];
// Flip screen coodinates
absolute.y = [[NSScreen mainScreen] frame].size.height - absolute.y;
// Move cursor
CGDisplayMoveCursorToPoint([sfPrivAppController primaryScreen],
CGPointMake(absolute.x, absolute.y));
}
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::SetPosition
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetPosition(int Left, int Top)
{
[myWrapper setPosition:NSMakePoint(Left, Top)];
}
////////////////////////////////////////////////////////////
/// /see WindowImpl::SetSize
///
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetSize(unsigned int Width, unsigned int Height)
{
[myWrapper setSize:NSMakeSize(Width, Height)];
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::Show
////////////////////////////////////////////////////////////
void WindowImplCocoa::Show(bool State)
{
[myWrapper show:State];
}
////////////////////////////////////////////////////////////
/// /see sfWindowImpl::EnableKeyRepeat
////////////////////////////////////////////////////////////
void WindowImplCocoa::EnableKeyRepeat(bool Enabled)
{
myUseKeyRepeat = Enabled;
}
////////////////////////////////////////////////////////////
/// see WindowImpl::SetIcon
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels)
{
// Nothing to do
}
namespace {
////////////////////////////////////////////////////////////
/// Return the SFML key corresponding to a key code
////////////////////////////////////////////////////////////
Key::Code KeyForVirtualCode(unsigned short vCode)
{
static struct {
unsigned short code;
Key::Code sfKey;
} virtualTable[] =
{
{0x35, Key::Escape},
{0x31, Key::Space},
{0x24, Key::Return}, // main Return key
{0x4C, Key::Return}, // pav Return key
{0x33, Key::Back},
{0x30, Key::Tab},
{0x74, Key::PageUp},
{0x79, Key::PageDown},
{0x77, Key::End},
{0x73, Key::Home},
{0x72, Key::Insert},
{0x75, Key::Delete},
{0x45, Key::Add},
{0x4E, Key::Subtract},
{0x43, Key::Multiply},
{0x4B, Key::Divide},
{0x7A, Key::F1}, {0x78, Key::F2}, {0x63, Key::F3},
{0x76, Key::F4}, {0x60, Key::F5}, {0x61, Key::F6},
{0x62, Key::F7}, {0x64, Key::F8}, {0x65, Key::F9},
{0x6D, Key::F10}, {0x67, Key::F11}, {0x6F, Key::F12},
{0x69, Key::F13}, {0x6B, Key::F14}, {0x71, Key::F15},
{0x7B, Key::Left},
{0x7C, Key::Right},
{0x7E, Key::Up},
{0x7D, Key::Down},
{0x52, Key::Numpad0}, {0x53, Key::Numpad1}, {0x54, Key::Numpad2},
{0x55, Key::Numpad3}, {0x56, Key::Numpad4}, {0x57, Key::Numpad5},
{0x58, Key::Numpad6}, {0x59, Key::Numpad7}, {0x5B, Key::Numpad8},
{0x5C, Key::Numpad9},
{0x1D, Key::Num0}, {0x12, Key::Num1}, {0x13, Key::Num2},
{0x14, Key::Num3}, {0x15, Key::Num4}, {0x17, Key::Num5},
{0x16, Key::Num6}, {0x1A, Key::Num7}, {0x1C, Key::Num8},
{0x19, Key::Num9},
{0x3B, Key::LControl}, //< Left Ctrl
{0x3A, Key::LAlt}, //< Left Option/Alt
{0x37, Key::LSystem}, //< Left Command
{0x38, Key::LShift}, //< Left Shift
{0x3E, Key::RControl}, //< Right Ctrl
{0x3D, Key::RAlt}, //< Right Option/Alt
{0x36, Key::RSystem}, //< Right Command
{0x3C, Key::RShift}, //< Right Shift
{0x39, Key::Code(0)} //< Caps Lock (not handled by SFML for now)
};
Key::Code result = Key::Code(0);
for (unsigned i = 0;virtualTable[i].code;i++) {
if (virtualTable[i].code == vCode) {
result = virtualTable[i].sfKey;
break;
}
}
return result;
}
////////////////////////////////////////////////////////////
/// Return the SFML key corresponding to a unicode code
////////////////////////////////////////////////////////////
Key::Code KeyForUnicode(unsigned short uniCode)
{
// TODO: find a better way to get the language independant key
static struct {
unsigned short character;
Key::Code sfKey;
} unicodeTable[] =
{
{'!', Key::Code(0)}, //< No Key for this code
{'"', Key::Code(0)}, //< No Key for this code
{'#', Key::Code(0)}, //< No Key for this code
{'$', Key::Code(0)}, //< No Key for this code
{'%', Key::Code(0)}, //< No Key for this code
{'&', Key::Code(0)}, //< No Key for this code
{'\'', Key::Quote},
{'(', Key::Code(0)}, //< No Key for this code
{')', Key::Code(0)}, //< No Key for this code
{'*', Key::Multiply},
{'+', Key::Add},
{',', Key::Comma},
{'-', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'.', Key::Period},
{'/', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'0', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'1', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'2', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'3', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'4', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'5', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'6', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'7', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'8', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{'9', Key::Code(0)}, //< Handled by KeyForVirtualCode()
{':', Key::Code(0)}, //< No Key for this code
{';', Key::SemiColon},
{'<', Key::Code(0)}, //< No Key for this code
{'=', Key::Equal},
{'>', Key::Code(0)}, //< No Key for this code
{'?', Key::Code(0)}, //< No Key for this code
{'@', Key::Code(0)}, //< No Key for this code
{'A', Key::A}, {'B', Key::B}, {'C', Key::C},
{'D', Key::D}, {'E', Key::E}, {'F', Key::F},
{'G', Key::G}, {'H', Key::H}, {'I', Key::I},
{'J', Key::J}, {'K', Key::K}, {'L', Key::L},
{'M', Key::M}, {'N', Key::N}, {'O', Key::O},
{'P', Key::P}, {'Q', Key::Q}, {'R', Key::R},
{'S', Key::S}, {'T', Key::T}, {'U', Key::U},
{'V', Key::V}, {'W', Key::W}, {'X', Key::X},
{'Y', Key::Y}, {'Z', Key::Z},
{'[', Key::LBracket},
{'\\', Key::BackSlash},
{']', Key::RBracket},
{'^', Key::Code(0)}, //< No Key for this code
{'_', Key::Code(0)}, //< No Key for this code
{'`', Key::Code(0)}, //< No Key for this code
{'a', Key::A}, {'b', Key::B}, {'c', Key::C},
{'d', Key::D}, {'e', Key::E}, {'f', Key::F},
{'g', Key::G}, {'h', Key::H}, {'i', Key::I},
{'j', Key::J}, {'k', Key::K}, {'l', Key::L},
{'m', Key::M}, {'n', Key::N}, {'o', Key::O},
{'p', Key::P}, {'q', Key::Q}, {'r', Key::R},
{'s', Key::S}, {'t', Key::T}, {'u', Key::U},
{'v', Key::V}, {'w', Key::W}, {'x', Key::X},
{'y', Key::Y}, {'z', Key::Z},
{'{', Key::Code(0)}, //< No Key for this code
{'|', Key::Code(0)}, //< No Key for this code
{'}', Key::Code(0)}, //< No Key for this code
{'~', Key::Tilde},
{0, Key::Code(0)}
};
Key::Code result = Key::Code(0);
for (unsigned i = 0;unicodeTable[i].character;i++) {
if (unicodeTable[i].character == uniCode) {
result = unicodeTable[i].sfKey;
break;
}
}
return result;
}
} // anonymous namespace
} // namespace priv
} // namespace sf

View file

@ -44,8 +44,8 @@
#elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Window/Cocoa/AglContext.hpp>
typedef sf::priv::AglContext ContextType;
#include <SFML/Window/OSX/SFContext.hpp>
typedef sf::priv::SFContext ContextType;
#endif

View file

@ -73,7 +73,7 @@ struct JoystickState
#elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Window/Cocoa/Joystick.hpp>
#include <SFML/Window/OSX/Joystick.hpp>
#endif

View file

@ -0,0 +1,48 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Joystick.hpp>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
void Joystick::Initialize(unsigned int Index)
{
// Reset the joystick state
// Initialize the Index-th available joystick
}
////////////////////////////////////////////////////////////
JoystickState Joystick::UpdateState()
{
// Fill a JoystickState instance with the current joystick state
JoystickState s;
return s;
}
////////////////////////////////////////////////////////////
bool Joystick::HasAxis(Joy::Axis Axis) const
{
return false;
}
////////////////////////////////////////////////////////////
unsigned int Joystick::GetButtonsCount() const
{
// Return number of supported buttons
return 0;
}
} // namespace priv
} // namespace sf

View file

@ -0,0 +1,72 @@
#ifndef SFML_JOYSTICKOSX_HPP
#define SFML_JOYSTICKOSX_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#if USE_OS_X_VERSION_10_6
#include <IOKit/hid/IOHIDDevice.h>
#endif
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief OSX implementation of Joystick
///
////////////////////////////////////////////////////////////
class Joystick
{
public :
////////////////////////////////////////////////////////////
/// \brief Initialize the instance and bind it to a physical joystick
///
/// \param index Index of the physical joystick to bind to
///
////////////////////////////////////////////////////////////
void Initialize(unsigned int index);
////////////////////////////////////////////////////////////
/// \brief Update the current joystick and return its new state
///
/// \return Current state of the joystick
///
////////////////////////////////////////////////////////////
JoystickState UpdateState();
////////////////////////////////////////////////////////////
/// \brief Check if the joystick supports the given axis
///
/// \param axis Axis to check
///
/// \return True of the axis is supported, false otherwise
///
////////////////////////////////////////////////////////////
bool HasAxis(Joy::Axis Axis) const;
////////////////////////////////////////////////////////////
/// \brief Get the number of buttons supported by the joystick
///
/// \return Number of buttons
///
////////////////////////////////////////////////////////////
unsigned int GetButtonsCount() const;
private :
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
};
} // namespace priv
} // namespace sf
#endif // SFML_JOYSTICKOSX_HPP

View file

@ -0,0 +1,20 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <Foundation/Foundation.h>
////////////////////////////////////////////////////////////
/// \brief Event processing
////////////////////////////////////////////////////////////
@interface SFApplication : NSObject
////////////////////////////////////////////////////////////
/// \brief Event processing
///
/// \param block blocking mode means at least one event is proccessed.
////////////////////////////////////////////////////////////
+(void)processEventWithBlockingMode:(BOOL)block;
@end

View file

@ -0,0 +1,40 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/OSX/SFApplication.h>
#import <AppKit/AppKit.h>
////////////////////////////////////////////////////////////
@implementation SFApplication
////////////////////////////////////////////////////////////
+(void)processEventWithBlockingMode:(BOOL)block
{
[NSApplication sharedApplication]; // Make sure NSApp exists
NSEvent* event = nil;
if (block) { // At least one event is read.
event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantFuture]
inMode:NSDefaultRunLoopMode
dequeue:YES]; // Remove the event from the dequeue
[NSApp sendEvent:event];
}
// If there are some other event read them.
while (event = [NSApp nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES]) // Remove the event from the dequeue
{
[NSApp sendEvent:event];
}
}
@end

View file

@ -0,0 +1,121 @@
#ifndef SFML_SFCONTEXT_HPP
#define SFML_SFCONTEXT_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/GlContext.hpp>
////////////////////////////////////////////////////////////
/// Predefine OBJC classes
////////////////////////////////////////////////////////////
#ifdef __OBJC__
@class NSOpenGLContext;
typedef NSOpenGLContext* NSOpenGLContextRef;
@class NSAutoreleasePool;
typedef NSAutoreleasePool* NSAutoreleasePoolRef;
#else // If C++
typedef void* NSOpenGLContextRef;
typedef void* NSAutoreleasePoolRef;
#endif
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief OSX (Cocoa) implementation of OpenGL contexts
///
////////////////////////////////////////////////////////////
class SFContext : public GlContext
{
public:
////////////////////////////////////////////////////////////
/// \brief Create a new context, not associated to a window
///
/// \param shared Context to share the new one with (can be NULL)
///
////////////////////////////////////////////////////////////
SFContext(SFContext* shared);
////////////////////////////////////////////////////////////
/// \brief Create a new context attached to a window
///
/// \param shared Context to share the new one with (can be NULL)
/// \param owner Pointer to the owner window
/// \param bitsPerPixel Pixel depth (in bits per pixel)
/// \param settings Creation parameters
///
////////////////////////////////////////////////////////////
SFContext(SFContext* shared, const WindowImpl* owner,
unsigned int bitsPerPixel, const ContextSettings& settings);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~SFContext();
////////////////////////////////////////////////////////////
/// \brief Display what has been rendered to the context so far
///
////////////////////////////////////////////////////////////
virtual void Display();
////////////////////////////////////////////////////////////
/// \brief Enable or disable vertical synchronization
///
/// Activating vertical synchronization will limit the number
/// of frames displayed to the refresh rate of the monitor.
/// This can avoid some visual artifacts, and limit the framerate
/// to a good value (but not constant across different computers).
///
/// \param enabled : True to enable v-sync, false to deactivate
///
////////////////////////////////////////////////////////////
virtual void UseVerticalSync(bool enabled);
protected:
////////////////////////////////////////////////////////////
/// \brief Activate the context as the current target
/// for rendering
///
/// \return True on success, false if any error happened
///
////////////////////////////////////////////////////////////
virtual bool MakeCurrent();
private:
////////////////////////////////////////////////////////////
/// \brief Create the context
/// \note Must only be called from Ctor.
///
/// \param shared Context to share the new one with (can be NULL)
/// \param settings Creation parameters
/// \param bitsPerPixel bpp
///
////////////////////////////////////////////////////////////
void CreateContext(SFContext* shared,
const ContextSettings& settings,
unsigned int bitsPerPixel);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
NSOpenGLContextRef myContext; ///< OpenGL context
NSAutoreleasePoolRef myPool; ///< Memory manager for this class.
};
} // namespace priv
} // namespace sf
#endif // SFML_AGLCONTEXT_HPP

View file

@ -0,0 +1,156 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/SFContext.hpp>
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/System/Err.hpp>
/*
* DISCUSSION :
* ============
*
* [1] (2010_07)
* should AA-related NSOpenGLPixelFormatAttribute not be in the array
* if AA is not enable (settings.AntialiasingLevel == 0) ?
* => will not be present in attributs array if 0.
*
* [2] (2010_07)
* how many buffer should be used for AA ?
* => «1» was choosen.
*/
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
SFContext::SFContext(SFContext* shared)
{
myPool = [[NSAutoreleasePool alloc] init];
// Create the context
CreateContext(shared, ContextSettings(0, 0, 0), 0);
}
////////////////////////////////////////////////////////////
SFContext::SFContext(SFContext* shared, const WindowImpl* owner,
unsigned int bitsPerPixel, const ContextSettings& settings)
{
myPool = [[NSAutoreleasePool alloc] init];
// Create the context.
CreateContext(shared, settings, bitsPerPixel);
// Apply context.
WindowImplCocoa const * ownerCocoa = static_cast<WindowImplCocoa const *>(owner);
ownerCocoa->ApplyContext(myContext);
}
////////////////////////////////////////////////////////////
SFContext::~SFContext()
{
[myContext release];
[myPool release];
}
////////////////////////////////////////////////////////////
bool SFContext::MakeCurrent()
{
[myContext makeCurrentContext];
}
////////////////////////////////////////////////////////////
void SFContext::Display()
{
[myContext flushBuffer];
}
////////////////////////////////////////////////////////////
void SFContext::UseVerticalSync(bool enabled)
{
// Make compiler happy
#ifdef USE_OS_X_VERSION_10_4
long int swapInterval = enabled ? 1 : 0;
#else /* USE_OS_X_VERSION_10_6 */
GLint swapInterval = enabled ? 1 : 0;
#endif
[myContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
}
////////////////////////////////////////////////////////////
void SFContext::CreateContext(SFContext* shared,
const ContextSettings& settings,
unsigned int bitsPerPixel)
{
// Choose the attributs of OGL context.
std::vector<NSOpenGLPixelFormatAttribute> attrs;
attrs.reserve(20); // max attributs (estimation).
// These casts are safe. C++ is much more stric than Obj-C.
attrs.push_back(NSOpenGLPFAClosestPolicy);
attrs.push_back(NSOpenGLPFADoubleBuffer);
if (bitsPerPixel > 24) {
attrs.push_back(NSOpenGLPFAAlphaSize);
attrs.push_back((NSOpenGLPixelFormatAttribute)8);
}
attrs.push_back(NSOpenGLPFADepthSize);
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.DepthBits);
attrs.push_back(NSOpenGLPFAStencilSize);
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.StencilBits);
if (settings.AntialiasingLevel > 0) { // [1]
attrs.push_back(NSOpenGLPFAMultisample);
attrs.push_back(NSOpenGLPFASampleBuffers);
attrs.push_back((NSOpenGLPixelFormatAttribute)1); // [2]
attrs.push_back(NSOpenGLPFASamples);
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.AntialiasingLevel);
}
attrs.push_back((NSOpenGLPixelFormatAttribute)0); // end of array
// Create the pixel pormat.
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attrs[0]];
if(pixFmt == nil) {
sf::Err() << "Error. Unable to find a suitable pixel format." << std::endl;
return;
}
// Use the shared context if one is given.
NSOpenGLContext* sharedContext = shared != NULL ? shared->myContext : nil;
// Create the context.
myContext = [[NSOpenGLContext alloc] initWithFormat:pixFmt
shareContext:sharedContext];
// Free up.
[pixFmt release];
#warning update settings with ogl version not yet implemented
// Save the creation settings
mySettings = settings;
}
} // namespace priv
} // namespace sf

View file

@ -0,0 +1,36 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <AppKit/AppKit.h>
namespace sf {
namespace priv {
class WindowImplCocoa;
}
}
////////////////////////////////////////////////////////////
/// \brief Spesialized NSOpenGLView
///
/// Handle event and send them back to the requester.
////////////////////////////////////////////////////////////
@interface SFOpenGLView : NSOpenGLView {
sf::priv::WindowImplCocoa* myRequester;
BOOL myUseKeyRepeat;
NSTrackingRectTag myTrackingTag;
BOOL myMouseIsIn;
}
-(id)initWithFrame:(NSRect)frameRect;
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester;
-(void)enableKeyRepeat;
-(void)disableKeyRepeat;
-(void)frameDidChange:(NSNotification*)notification;
-(BOOL)isMouseInside;
@end

View file

@ -0,0 +1,306 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#import <SFML/Window/OSX/SFOpenGLView.h>
@implementation SFOpenGLView
#pragma mark
#pragma mark SFOpenGLView's methods
////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect
{
if (self = [super initWithFrame:frameRect]) {
[self setRequesterTo:0];
[self enableKeyRepeat];
// Register for mouse-move event
myMouseIsIn = [self isMouseInside];
myTrackingTag = [self addTrackingRect:[self frame]
owner:self
userData:nil
assumeInside:myMouseIsIn];
// Register for resize event
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
[center addObserver:self
selector:@selector(frameDidChange:)
name:NSViewFrameDidChangeNotification
object:nil];
}
return self;
}
////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
{
myRequester = requester;
}
////////////////////////////////////////////////////////
-(void)enableKeyRepeat
{
myUseKeyRepeat = YES;
}
////////////////////////////////////////////////////////
-(void)disableKeyRepeat
{
myUseKeyRepeat = NO;
}
////////////////////////////////////////////////////////
-(void)frameDidChange:(NSNotification*)notification
{
// Adapt tracking area for mouse mouse event.
[self removeTrackingRect:myTrackingTag];
myTrackingTag = [self addTrackingRect:[self frame]
owner:self
userData:nil
assumeInside:myMouseIsIn];
// Update the OGL view to fit the new size.
[self update];
// Send an event
if (myRequester == 0) return;
// The new size
NSSize newSize = [self frame].size;
myRequester->WindowResized(newSize.width, newSize.height);
}
////////////////////////////////////////////////////////
-(BOOL)isMouseInside
{
NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
if (NSPointInRect(relativeToView, [self frame])) {
return YES;
}
return NO;
}
#pragma mark
#pragma mark Subclassing methods
////////////////////////////////////////////////////////
-(void)dealloc
{
// Unregister
[[NSNotificationCenter defaultCenter] removeObserver:self];
[self removeTrackingRect:myTrackingTag];
[super dealloc];
}
////////////////////////////////////////////////////////
-(BOOL)acceptsFirstResponder
{
// Accepts key event.
return YES;
}
////////////////////////////////////////////////////////
-(BOOL)canBecomeKeyView
{
// Accepts key event.
return YES;
}
#pragma mark
#pragma mark Mouse-event methods
////////////////////////////////////////////////////////
-(void)mouseDown:(NSEvent*)theEvent
{
if (myRequester == 0) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseDownAt(sf::Mouse::Left, loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)mouseUp:(NSEvent*)theEvent
{
if (myRequester == 0) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseUpAt(sf::Mouse::Left, loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)mouseMoved:(NSEvent*)theEvent
{
if (myRequester == 0) return;
// If the event is not useful.
if (!myMouseIsIn) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseMovedAt(loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)rightMouseDown:(NSEvent*)theEvent
{
if (myRequester == 0) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseDownAt(sf::Mouse::Right, loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)rightMouseUp:(NSEvent*)theEvent
{
if (myRequester == 0) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseUpAt(sf::Mouse::Right, loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)otherMouseDown:(NSEvent*)theEvent
{
if (myRequester == 0) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
sf::Mouse::Button button;
switch ([theEvent buttonNumber]) {
case 2:
button = sf::Mouse::Middle;
break;
case 3:
button = sf::Mouse::XButton1;
break;
case 4:
button = sf::Mouse::XButton2;
break;
default:
break;
}
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseDownAt(button, loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)otherMouseUp:(NSEvent*)theEvent
{
if (myRequester == 0) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
sf::Mouse::Button button;
switch ([theEvent buttonNumber]) {
case 2:
button = sf::Mouse::Middle;
break;
case 3:
button = sf::Mouse::XButton1;
break;
case 4:
button = sf::Mouse::XButton2;
break;
default:
break;
}
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseUpAt(button, loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)scrollWheel:(NSEvent*)theEvent
{
if (myRequester == 0) return;
NSPoint loc = [self convertPoint:[theEvent locationInWindow] fromView:nil];
// Don't forget to change to SFML coord system.
float h = [[theEvent window] frame].size.height;
myRequester->MouseWheelScrolledAt([theEvent deltaY], loc.x, h - loc.y);
}
////////////////////////////////////////////////////////
-(void)mouseEntered:(NSEvent*)theEvent
{
myMouseIsIn = YES;
if (myRequester == 0) return;
myRequester->MouseMovedIn();
}
////////////////////////////////////////////////////////
-(void)mouseExited:(NSEvent*)theEvent
{
myMouseIsIn = NO;
if (myRequester == 0) return;
myRequester->MouseMovedOut();
}
#pragma mark
#pragma mark Key-event methods
////////////////////////////////////////////////////////
-(void)keyDown:(NSEvent*)theEvent
{
if (myRequester == 0) return;
if (myUseKeyRepeat || ![theEvent isARepeat])
myRequester->KeyDown([theEvent keyCode], [theEvent modifierFlags]);
if ([[theEvent characters] length] > 0)
myRequester->TextEntred([[theEvent characters] characterAtIndex:0]);
}
////////////////////////////////////////////////////////
-(void)keyUp:(NSEvent*)theEvent
{
if (myRequester == 0) return;
myRequester->KeyUp([theEvent keyCode], [theEvent modifierFlags]);
}
@end

View file

@ -0,0 +1,46 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
////////////////////////////////////////////////////////////
/// Predefine some classes
////////////////////////////////////////////////////////////
namespace sf {
namespace priv {
class WindowImplCocoa;
}
class VideoMode;
}
@class SFOpenGLView;
////////////////////////////////////////////////////////////
/// Implementation of WindowImplDelegateProtocol for window managment.
///
/// Key and mouse events are delegated to its view.
/// Window events are managed by this class.
///
/// Used when SFML handle everything and when a NSWindow* is given
/// as handle to WindowImpl.
////////////////////////////////////////////////////////////
#ifdef USE_OS_X_VERSION_10_4
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol> {
#else /* USE_OS_X_VERSION_10_6 */
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate> {
#endif
NSWindow* myWindow;
SFOpenGLView* myOGLView;
sf::priv::WindowImplCocoa* myRequester;
}
-(id)initWithWindow:(NSWindow*)window;
-(id)initWithMode:(sf::VideoMode const*)mode andStyle:(unsigned long)style;
-(void)dealloc;
-(float)titlebarHeight;
@end

View file

@ -0,0 +1,396 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/WindowHandle.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <SFML/System/Err.hpp>
#import <SFML/Window/OSX/SFWindowController.h>
#import <SFML/Window/OSX/SFApplication.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
@implementation SFWindowController
#pragma mark
#pragma mark SFWindowController's methods
////////////////////////////////////////////////////////
-(id)initWithWindow:(NSWindow*)window
{
if (self = [super init]) {
myRequester = 0;
// Retain the window for our own use.
myWindow = [window retain];
if (myWindow == nil) {
sf::Err()
<< "No window was given to initWithWindow:."
<< std::endl;
return self;
}
// Create the view.
myOGLView = [[SFOpenGLView alloc] initWithFrame:[[myWindow contentView] frame]];
if (myOGLView == nil) {
sf::Err()
<< "Could not create an instance of NSOpenGLView "
<< "in (SFWindowController -initWithMode:andStyle:)."
<< std::endl;
return self;
}
// Set the view to the window as its content view.
[myWindow setContentView:myOGLView];
}
return self;
}
////////////////////////////////////////////////////////
-(id)initWithMode:(sf::VideoMode const*)mode andStyle:(unsigned long)style
{
if (self = [super init]) {
myRequester = 0;
// Create our window size.
NSRect rect = NSMakeRect(0, 0, mode->Width, mode->Height);
// Convert the SFML window style to Cocoa window style.
unsigned int nsStyle = NSBorderlessWindowMask;
if (!(style & sf::Style::Fullscreen)) { // if fullscrean we keep our NSBorderlessWindowMask.
if (style & sf::Style::Titlebar) nsStyle |= NSTitledWindowMask | NSMiniaturizableWindowMask;
if (style & sf::Style::Resize) nsStyle |= NSResizableWindowMask;
if (style & sf::Style::Close) nsStyle |= NSClosableWindowMask;
}
// Create the window.
myWindow = [[NSWindow alloc] initWithContentRect:rect
styleMask:nsStyle
backing:NSBackingStoreBuffered
defer:NO];
/*
"YES" make some "invalid drawable".
See http://www.cocoabuilder.com/archive/cocoa/152482-nsviews-and-nsopenglcontext-invalid-drawable-error.html
[...]
As best as I can figure, this is happening because the NSWindow (and
hence my view) are not visible onscreen yet, and the system doesn't like that.
[...]
*/
if (myWindow == nil) {
sf::Err()
<< "Could not create an instance of NSWindow "
<< "in (SFWindowController -initWithMode:andStyle:)."
<< std::endl;
return self;
}
// Create the view.
myOGLView = [[SFOpenGLView alloc] initWithFrame:[[myWindow contentView] frame]];
if (myOGLView == nil) {
sf::Err()
<< "Could not create an instance of NSOpenGLView "
<< "in (SFWindowController -initWithMode:andStyle:)."
<< std::endl;
return self;
}
// Set the view to the window as its content view.
[myWindow setContentView:myOGLView];
// Register for event.
[myWindow setDelegate:self];
[myWindow setAcceptsMouseMovedEvents:YES];
[myWindow setIgnoresMouseEvents:NO];
// And some other things...
[myWindow setAutodisplay:YES];
[myWindow setReleasedWhenClosed:NO];
// Apply special feature for fullscreen window.
if (style & sf::Style::Fullscreen) {
// We place the window above everything else.
[myWindow setLevel:NSMainMenuWindowLevel+1];
[myWindow setOpaque:YES];
[myWindow setHidesOnDeactivate:YES];
/* ---------------------------
* | Note for future version |
* ---------------------------
*
* starting with OS 10.5 NSView provides
* a new method -enterFullScreenMode:withOptions:
* which could be a good alternative.
*/
}
// Center the window to be cool =)
[myWindow center];
} // if super init ok
return self;
}
////////////////////////////////////////////////////////
-(void)dealloc
{
[self closeWindow];
[myWindow release];
[myOGLView release];
[super dealloc];
}
#pragma mark
#pragma mark WindowImplDelegateProtocol's methods
////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
{
// Forward to the view.
[myOGLView setRequesterTo:requester];
myRequester = requester;
}
////////////////////////////////////////////////////////
-(sf::WindowHandle)getSystemHandle
{
return myWindow;
}
////////////////////////////////////////////////////////
-(void)hideMouseCursor
{
[NSCursor hide];
}
////////////////////////////////////////////////////////
-(void)showMouseCursor
{
[NSCursor unhide];
}
////////////////////////////////////////////////////////
-(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y
{
// Flip for SFML window coordinate system
y = NSHeight([myWindow frame]) - y;
// Adjust for view reference instead of window
y -= NSHeight([myWindow frame]) - NSHeight([myOGLView frame]);
// Convert to screen coordinates
NSPoint screenCoord = [myWindow convertBaseToScreen:NSMakePoint(x, y)];
// Flip screen coodinates
float const screenHeight = NSHeight([[myWindow screen] frame]);
screenCoord.y = screenHeight - screenCoord.y;
CGDirectDisplayID screenNumber = (CGDirectDisplayID)[[[[myWindow screen] deviceDescription] valueForKey:@"NSScreenNumber"] intValue];
// Place the cursor.
CGDisplayMoveCursorToPoint(screenNumber, CGPointMake(screenCoord.x, screenCoord.y));
}
////////////////////////////////////////////////////////.
-(void)setWindowPositionToX:(unsigned int)x Y:(unsigned int)y
{
NSPoint point = NSMakePoint(x, y);
// Flip for SFML window coordinate system.
point.y = NSHeight([[myWindow screen] visibleFrame]) - point.y;
// Place the window.
[myWindow setFrameTopLeftPoint:point];
}
////////////////////////////////////////////////////////
-(void)resizeTo:(unsigned int)width by:(unsigned int)height
{
// Add titlebar height.
NSRect frame = NSMakeRect([myWindow frame].origin.x,
[myWindow frame].origin.y,
width,
height + [self titlebarHeight]);
[myWindow setFrame:frame display:YES];
}
////////////////////////////////////////////////////////
-(void)changeTitle:(NSString*)title
{
[myWindow setTitle:title];
}
////////////////////////////////////////////////////////
-(void)hideWindow
{
[myWindow orderOut:nil];
}
////////////////////////////////////////////////////////
-(void)showWindow
{
[myWindow makeKeyAndOrderFront:nil];
}
////////////////////////////////////////////////////////
-(void)closeWindow
{
[myWindow close];
}
////////////////////////////////////////////////////////
-(void)enableKeyRepeat
{
[myOGLView enableKeyRepeat];
}
////////////////////////////////////////////////////////
-(void)disableKeyRepeat
{
[myOGLView disableKeyRepeat];
}
////////////////////////////////////////////////////////
-(void)setIconTo:(unsigned int)width
by:(unsigned int)height
with:(sf::Uint8 const*)pixels
{
// Create an empty image representation.
NSBitmapImageRep* bitmap =
[[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 // if 0 : only allocate memory
pixelsWide:width
pixelsHigh:height
bitsPerSample:8 // The number of bits used to specify
// one pixel in a single component of the data.
samplesPerPixel:4 // 3 if no alpha, 4 with it
hasAlpha:YES
isPlanar:NO // I don't know what it is but it works
colorSpaceName:NSCalibratedRGBColorSpace
bytesPerRow:0 // 0 == determine automatically
bitsPerPixel:0]; // 0 == determine automatically
// Load data pixels.
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 // We may need to define NSUInteger.
#define NSUInteger unsigned int
#endif
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width; ++x, pixels+=4) {
NSUInteger pixel[4] = { pixels[0], pixels[1], pixels[2], pixels[3] };
[bitmap setPixel:pixel
atX:x
y:y];
}
}
// Create an image from the representation.
NSImage* icon = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
[icon addRepresentation:bitmap];
// Set app icon.
[[NSApplication sharedApplication] setApplicationIconImage:icon];
// Free up.
[icon release];
[bitmap release];
}
////////////////////////////////////////////////////////
-(void)processEventWithBlockingMode:(BOOL)block
{
// If we don't have a requester we don't fetch event.
if (myRequester != 0) {
[SFApplication processEventWithBlockingMode:block];
}
}
////////////////////////////////////////////////////////
-(void)applyContext:(NSOpenGLContext*)context
{
[myOGLView setOpenGLContext:context];
[context setView:myOGLView];
}
#pragma mark
#pragma mark NSWindowDelegate's methods
////////////////////////////////////////////////////////
-(BOOL)windowShouldClose:(id)sender
{
if (myRequester == 0) return YES;
myRequester->WindowClosed();
return NO;
}
////////////////////////////////////////////////////////
-(void)windowDidBecomeKey:(NSNotification*)notification {
if (myRequester == 0) return;
myRequester->WindowGainedFocus();
}
////////////////////////////////////////////////////////
-(void)windowDidResignKey:(NSNotification*)notification {
if (myRequester == 0) return;
myRequester->WindowLostFocus();
}
#pragma mark
#pragma mark Other methods
////////////////////////////////////////////////////////
-(float)titlebarHeight {
return NSHeight([myWindow frame]) - NSHeight([[myWindow contentView] frame]);
}
@end

View file

@ -0,0 +1,101 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/VideoModeImpl.hpp>
#include <SFML/System/Err.hpp>
#include <algorithm>
#import <ApplicationServices/ApplicationServices.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Get bpp for all OS X version
///
/// This function use only non-deprecated way to get the
/// display bits per pixel information. It depends
/// on these macros :
///
/// - USE_OS_X_VERSION_10_4
/// - USE_OS_X_VERSION_10_6
///
#warning This may be improved by removing these dummy macros.
/// Maybe MAC_OS_X_VERSION_MAX_ALLOWED ?
////////////////////////////////////////////////////////////
size_t DisplayBitsPerPixel(CGDirectDisplayID displayId)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
return CGDisplayBitsPerPixel(displayId);
#else // MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 32;
else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 16;
else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
return 8;
return 0; // no match
#endif
}
////////////////////////////////////////////////////////////
std::vector<VideoMode> VideoModeImpl::GetFullscreenModes()
{
std::vector<VideoMode> modes;
CGDisplayCount count = 0;
int err = CGGetActiveDisplayList(0, NULL, &count);
if (err != 0) {
sf::Err() << "Error when retrieving displays count";
return modes;
}
CGDirectDisplayID* displays = new CGDirectDisplayID[count];
err = CGGetActiveDisplayList(count, displays, &count);
if (err != 0) {
sf::Err() << "Error when retrieving displays array";
return modes;
}
for (int i = 0; i < count; ++i) {
VideoMode mode(CGDisplayPixelsWide(displays[i]),
CGDisplayPixelsHigh(displays[i]),
DisplayBitsPerPixel(displays[i]));
// Add it only if it isn't already in the array.
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
modes.push_back(mode);
}
delete[] displays;
return modes;
}
////////////////////////////////////////////////////////////
VideoMode VideoModeImpl::GetDesktopMode()
{
CGDirectDisplayID display = CGMainDisplayID();
return VideoMode(CGDisplayPixelsWide(display),
CGDisplayPixelsHigh(display),
DisplayBitsPerPixel(display));
}
} // namespace priv
} // namespace sf

View file

@ -0,0 +1,199 @@
#ifndef SFML_WINDOWIMPLCOCOA_HPP
#define SFML_WINDOWIMPLCOCOA_HPP
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/Event.hpp>
#include <SFML/Window/WindowImpl.hpp>
////////////////////////////////////////////////////////////
/// Predefine OBJC classes
////////////////////////////////////////////////////////////
#ifdef __OBJC__
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
typedef id<WindowImplDelegateProtocol,NSObject> WindowImplDelegateRef;
@class NSAutoreleasePool;
typedef NSAutoreleasePool* NSAutoreleasePoolRef;
@class NSOpenGLContext;
typedef NSOpenGLContext* NSOpenGLContextRef;
#else // If C++
typedef void* WindowImplDelegateRef;
typedef void* NSAutoreleasePoolRef;
typedef void* NSOpenGLContextRef;
#endif
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Mac OS X (Cocoa) implementation of WindowImpl
///
////////////////////////////////////////////////////////////
class WindowImplCocoa : public WindowImpl
{
public:
////////////////////////////////////////////////////////////
/// \brief Construct the window implementation from an existing control
///
/// \param handle Platform-specific handle of the control
///
////////////////////////////////////////////////////////////
WindowImplCocoa(WindowHandle handle);
////////////////////////////////////////////////////////////
/// \brief Create the window implementation
///
/// \param mode Video mode to use
/// \param title Title of the window
/// \param style Window style (resizable, fixed, or fullscren)
///
////////////////////////////////////////////////////////////
WindowImplCocoa(VideoMode mode, const std::string& title, unsigned long style);
////////////////////////////////////////////////////////////
/// \brief Destructor
///
////////////////////////////////////////////////////////////
~WindowImplCocoa();
/// Events
void WindowClosed(void);
void WindowResized(unsigned int width, unsigned int height);
void WindowLostFocus(void);
void WindowGainedFocus(void);
void MouseDownAt(Mouse::Button button, int x, int y);
void MouseUpAt(Mouse::Button button, int x, int y);
void MouseMovedAt(int x, int y);
void MouseWheelScrolledAt(float delta, int x, int y);
void MouseMovedIn(void);
void MouseMovedOut(void);
void KeyDown(unsigned short keycode, unsigned int modifierFlags);
void KeyUp(unsigned short keycode, unsigned int modifierFlags);
void TextEntred(Uint32 charcode);
static Key::Code NSKeyCodeToSFMLKeyCode(unsigned short rawchar);
////////////////////////////////////////////////////////////
///
////////////////////////////////////////////////////////////
void ApplyContext(NSOpenGLContextRef context) const;
private:
////////////////////////////////////////////////////////////
/// \brief Process incoming events from the operating system
///
/// \param block Use true to block the thread until an event arrives
///
////////////////////////////////////////////////////////////
virtual void ProcessEvents(bool block);
////////////////////////////////////////////////////////////
/// \brief Get the OS-specific handle of the window
///
/// \return Handle of the window
///
////////////////////////////////////////////////////////////
virtual WindowHandle GetSystemHandle() const;
////////////////////////////////////////////////////////////
/// \brief Show or hide the mouse cursor
///
/// \param show True to show, false to hide
///
////////////////////////////////////////////////////////////
virtual void ShowMouseCursor(bool show);
////////////////////////////////////////////////////////////
/// \brief Change the position of the mouse cursor
///
/// \param x Left coordinate of the cursor, relative to the window
/// \param y Top coordinate of the cursor, relative to the window
///
////////////////////////////////////////////////////////////
virtual void SetCursorPosition(unsigned int x, unsigned int y);
////////////////////////////////////////////////////////////
/// \brief Change the position of the window on screen
///
/// \param x Left position
/// \param y Top position
///
////////////////////////////////////////////////////////////
virtual void SetPosition(int x, int y);
////////////////////////////////////////////////////////////
/// \brief Change the size of the rendering region of the window
///
/// \param width New width
/// \param height New height
///
////////////////////////////////////////////////////////////
virtual void SetSize(unsigned int width, unsigned int height);
////////////////////////////////////////////////////////////
/// \brief Change the title of the window
///
/// \param title New title
///
////////////////////////////////////////////////////////////
virtual void SetTitle(const std::string& title);
////////////////////////////////////////////////////////////
/// \brief Show or hide the window
///
/// \param show True to show, false to hide
///
////////////////////////////////////////////////////////////
virtual void Show(bool show);
////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat
///
/// \param enabled True to enable, false to disable
///
////////////////////////////////////////////////////////////
virtual void EnableKeyRepeat(bool enabled);
////////////////////////////////////////////////////////////
/// \brief Change the window's icon
///
/// \param width Icon's width, in pixels
/// \param height Icon's height, in pixels
/// \param pixels Pointer to the pixels in memory, format must be RGBA 32 bits
///
////////////////////////////////////////////////////////////
virtual void SetIcon(unsigned int width, unsigned int height, const Uint8* pixels);
////////////////////////////////////////////////////////////
/// \brief Construct the pool after ensuring NSApp is valid.
////////////////////////////////////////////////////////////
void SetUpPoolAndApplication(void);
////////////////////////////////////////////////////////////
/// \brief Change the type of the current process to become a full GUI app.
////////////////////////////////////////////////////////////
static void SetUpProcessAsApplication(void);
////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
WindowImplDelegateRef myDelegate; ///< Implementation in Obj-C.
NSAutoreleasePoolRef myPool; ///< Memory manager for this class.
};
} // namespace priv
} // namespace sf
#endif // SFML_WINDOWIMPLCOCOA_HPP

View file

@ -0,0 +1,518 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/System/Err.hpp>
#import <SFML/Window/OSX/SFWindowController.h>
//#import <SFML/Window/OSX/SFViewController.h>
#warning SFViewController not yet implemented.
#import <SFML/Window/OSX/cpp_objc_conversion.h>
namespace sf
{
namespace priv
{
#pragma mark
#pragma mark WindowImplCocoa's ctor/dtor
////////////////////////////////////////////////////////////
WindowImplCocoa::WindowImplCocoa(WindowHandle handle)
{
sf::Err() << "Not yet fully supported." << std::endl;
#warning WindowImplCocoa(WindowHandle handle) not yet fully implemented
SetUpPoolAndApplication();
// Treat the handle as it real type
id nsHandle = (id)handle;
if ([nsHandle isKindOfClass:[NSWindow class]]) {
// We have a window.
myDelegate = [[SFWindowController alloc] initWithWindow:nsHandle];
} /*else if ([nsHandle isKindOfClass:[NSView class]]) {
// We have a view.
myDelegate = [[SFViewController alloc] initWithView:nsHandle];
} */ else {
sf::Err()
<< "Cannot import this Window Handle because it is neither "
<< "a <NSWindow*> nor <NSView*> object "
<< "(or any of their subclasses). You gave a <"
<< [[nsHandle className] UTF8String]
<< "> object."
<< std::endl;
return;
}
// NO :
// [myDelegate setRequesterTo:this];
// because we don't handle event.
}
////////////////////////////////////////////////////////////
WindowImplCocoa::WindowImplCocoa(VideoMode mode,
const std::string& title,
unsigned long style)
{
SetUpPoolAndApplication();
// Don't forget to update our parent (that is, WindowImpl) size :
myWidth = mode.Width;
myHeight = mode.Height;
myDelegate = [[SFWindowController alloc] initWithMode:&mode andStyle:style];
[myDelegate changeTitle:stringToNSString(title)];
[myDelegate setRequesterTo:this];
}
////////////////////////////////////////////////////////////
WindowImplCocoa::~WindowImplCocoa()
{
[myDelegate closeWindow];
[myDelegate release];
[myPool release];
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::ApplyContext(NSOpenGLContextRef context) const
{
[myDelegate applyContext:context];
}
#pragma mark
#pragma mark WindowImplCocoa's window-event methods
////////////////////////////////////////////////////////////
void WindowImplCocoa::WindowClosed(void)
{
Event event;
event.Type = Event::Closed;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::WindowResized(unsigned int width, unsigned int height)
{
// Don't forget to update our parent (that is, WindowImpl) size :
myWidth = width;
myHeight = height;
Event event;
event.Type = Event::Resized;
event.Size.Width = myWidth;
event.Size.Height = myHeight;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::WindowLostFocus(void)
{
Event event;
event.Type = Event::LostFocus;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::WindowGainedFocus(void)
{
Event event;
event.Type = Event::GainedFocus;
PushEvent(event);
}
#pragma mark
#pragma mark WindowImplCocoa's mouse-event methods
////////////////////////////////////////////////////////////
void WindowImplCocoa::MouseDownAt(Mouse::Button button, int x, int y)
{
Event event;
event.Type = Event::MouseButtonPressed;
event.MouseButton.Button = button;
event.MouseButton.X = x;
event.MouseButton.Y = y;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::MouseUpAt(Mouse::Button button, int x, int y)
{
Event event;
event.Type = Event::MouseButtonReleased;
event.MouseButton.Button = button;
event.MouseButton.X = x;
event.MouseButton.Y = y;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::MouseMovedAt(int x, int y)
{
Event event;
event.Type = Event::MouseMoved;
event.MouseMove.X = x;
event.MouseMove.Y = y;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::MouseWheelScrolledAt(float delta, int x, int y)
{
Event event;
event.Type = Event::MouseWheelMoved;
event.MouseWheel.Delta = delta;
event.MouseWheel.X = x;
event.MouseWheel.Y = y;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::MouseMovedIn(void)
{
Event event;
event.Type = Event::MouseEntered;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::MouseMovedOut(void)
{
Event event;
event.Type = Event::MouseLeft;
PushEvent(event);
}
#pragma mark
#pragma mark WindowImplCocoa's key-event methods
////////////////////////////////////////////////////////////
void WindowImplCocoa::KeyDown(unsigned short keycode, unsigned int modifierFlags)
{
Event event;
event.Type = Event::KeyPressed;
event.Key.Code = NSKeyCodeToSFMLKeyCode(keycode);
if (event.Key.Code == Key::Count) {
sf::Err() << "Unknown key (pressed)" << std::endl;
return; // Not a valid/supported key.
}
event.Key.Alt = modifierFlags & NSAlternateKeyMask;
event.Key.Control = modifierFlags & NSControlKeyMask;
event.Key.Shift = modifierFlags & NSShiftKeyMask;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::KeyUp(unsigned short keycode, unsigned int modifierFlags)
{
Event event;
event.Type = Event::KeyReleased;
event.Key.Code = NSKeyCodeToSFMLKeyCode(keycode);
if (event.Key.Code == Key::Count) {
sf::Err() << "Unknown key (released)" << std::endl;
return; // Not a valid/supported key.
}
event.Key.Alt = modifierFlags & NSAlternateKeyMask;
event.Key.Control = modifierFlags & NSControlKeyMask;
event.Key.Shift = modifierFlags & NSShiftKeyMask;
PushEvent(event);
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::TextEntred(Uint32 charcode)
{
Event event;
event.Type = Event::TextEntered;
event.Text.Unicode = charcode;
PushEvent(event);
}
////////////////////////////////////////////////////////////
Key::Code WindowImplCocoa::NSKeyCodeToSFMLKeyCode(unsigned short keycode) {
/* Based on http://forums.macrumors.com/showthread.php?t=780577 */
switch (keycode) {
case 0x00: return Key::A;
case 0x0b: return Key::B;
case 0x08: return Key::C;
case 0x02: return Key::D;
case 0x0e: return Key::E;
case 0x03: return Key::F;
case 0x05: return Key::G;
case 0x04: return Key::H;
case 0x22: return Key::I;
case 0x26: return Key::J;
case 0x28: return Key::K;
case 0x25: return Key::L;
case 0x2e: return Key::M;
case 0x2d: return Key::N;
case 0x1f: return Key::O;
case 0x23: return Key::P;
case 0x0c: return Key::Q;
case 0x0f: return Key::R;
case 0x01: return Key::S;
case 0x11: return Key::T;
case 0x20: return Key::U;
case 0x09: return Key::V;
case 0x0d: return Key::W;
case 0x07: return Key::X;
case 0x10: return Key::Y;
case 0x06: return Key::Z;
case 0x1d: return Key::Num0;
case 0x12: return Key::Num1;
case 0x13: return Key::Num2;
case 0x14: return Key::Num3;
case 0x15: return Key::Num4;
case 0x17: return Key::Num5;
case 0x16: return Key::Num6;
case 0x1a: return Key::Num7;
case 0x1c: return Key::Num8;
case 0x19: return Key::Num9;
case 0x35: return Key::Escape;
case 0x3b: return Key::LControl;
case 0x38: return Key::LShift;
case 0x3a: return Key::LAlt;
case 0x37: return Key::LSystem;
case 0x3e: return Key::RControl;
case 0x3c: return Key::RShift;
case 0x3d: return Key::RAlt;
case 0x36: return Key::RSystem;
#warning unknown key code for Menu
// case 0x: return Key::Menu;
case 0x21: return Key::LBracket;
case 0x1e: return Key::RBracket;
case 0x29: return Key::SemiColon;
case 0x2b: return Key::Comma;
case 0x2f: return Key::Period;
case 0x27: return Key::Quote;
case 0x2c: return Key::Slash;
case 0x2a: return Key::BackSlash;
#warning 0x0a is for "Non-US Backslash" (from HID Calibrator, a sample provided by Apple).
case 0x0a: return Key::Tilde;
case 0x18: return Key::Equal;
case 0x32: return Key::Dash;
case 0x31: return Key::Space;
case 0x24: return Key::Return;
#warning unknown key code for Back
// case 0x: return Key::Back;
case 0x30: return Key::Tab;
case 0x74: return Key::PageUp;
case 0x79: return Key::PageDown;
case 0x77: return Key::End;
case 0x73: return Key::Home;
#warning unknown key code for Insert
// case 0x: return Key::Insert;
case 0x33: return Key::Delete;
case 0x45: return Key::Add;
case 0x4e: return Key::Subtract;
case 0x43: return Key::Multiply;
case 0x4b: return Key::Divide;
case 0x7b: return Key::Left;
case 0x7c: return Key::Right;
case 0x7e: return Key::Up;
case 0x7d: return Key::Down;
case 0x52: return Key::Numpad0;
case 0x53: return Key::Numpad1;
case 0x54: return Key::Numpad2;
case 0x55: return Key::Numpad3;
case 0x56: return Key::Numpad4;
case 0x57: return Key::Numpad5;
case 0x58: return Key::Numpad6;
case 0x59: return Key::Numpad7;
case 0x5b: return Key::Numpad8;
case 0x5c: return Key::Numpad9;
case 0x7a: return Key::F1;
case 0x78: return Key::F2;
case 0x63: return Key::F3;
case 0x76: return Key::F4;
case 0x60: return Key::F5;
case 0x61: return Key::F6;
case 0x62: return Key::F7;
case 0x64: return Key::F8;
case 0x65: return Key::F9;
case 0x6d: return Key::F10;
case 0x67: return Key::F11;
case 0x6f: return Key::F12;
case 0x69: return Key::F13;
case 0x6b: return Key::F14;
case 0x71: return Key::F15;
#warning unknown key code for PAUSE
// case 0x: return Key::PAUSE;
default: return Key::Count; // An unknown key.
}
}
#pragma mark
#pragma mark WindowImplCocoa's event-related methods
////////////////////////////////////////////////////////////
void WindowImplCocoa::ProcessEvents(bool block)
{
[myDelegate processEventWithBlockingMode:(block ? YES : NO)];
}
#pragma mark
#pragma mark WindowImplCocoa's private methods
////////////////////////////////////////////////////////////
WindowHandle WindowImplCocoa::GetSystemHandle() const
{
return [myDelegate getSystemHandle];
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::ShowMouseCursor(bool show)
{
if (show) {
[myDelegate showMouseCursor];
} else {
[myDelegate hideMouseCursor];
}
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetCursorPosition(unsigned int x, unsigned int y)
{
[myDelegate setCursorPositionToX:x Y:y];
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetPosition(int x, int y)
{
[myDelegate setWindowPositionToX:x Y:y];
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetSize(unsigned int width, unsigned int height)
{
// Don't forget to update our parent (that is, WindowImpl) size :
myWidth = width;
myHeight = height;
[myDelegate resizeTo:width by:height];
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetTitle(const std::string& title)
{
[myDelegate changeTitle:stringToNSString(title)];
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::Show(bool show)
{
if (show) {
[myDelegate showWindow];
} else {
[myDelegate hideWindow];
}
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::EnableKeyRepeat(bool enabled)
{
if (enabled) {
[myDelegate enableKeyRepeat];
} else {
[myDelegate disableKeyRepeat];
}
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetIcon(unsigned int width, unsigned int height,
const Uint8* pixels)
{
[myDelegate setIconTo:width by:height with:pixels];
}
#pragma mark
#pragma mark WindowImplCocoa's init methods
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetUpPoolAndApplication(void)
{
// Ensure NSApp exists.
[NSApplication sharedApplication];
// Create the pool.
myPool = [[NSAutoreleasePool alloc] init];
// Transform the app process.
SetUpProcessAsApplication();
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::SetUpProcessAsApplication(void)
{
static bool isTheProcessSetAsApplication = false;
if (!isTheProcessSetAsApplication) {
// Do it only once !
isTheProcessSetAsApplication = true;
// Set the process as a normal application so it can get focus.
ProcessSerialNumber psn;
if (!GetCurrentProcess(&psn)) {
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
}
// Tell the application to stop bouncing in the Dock.
[[NSApplication sharedApplication] finishLaunching];
// NOTE : This last call won't harm anything even if SFML window was
// created with an external handle.
}
}
} // namespace priv
} // namespace sf

View file

@ -0,0 +1,85 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/WindowHandle.hpp>
#include <SFML/Config.hpp> // for sf::Uint8
#import <AppKit/AppKit.h>
namespace sf {
namespace priv {
class WindowImplCocoa;
}
}
////////////////////////////////////////////////////////////
/// This protocol defines the interface of the delegate of
/// the window implementation.
///
/// Everything is done via a class that implement this protocol.
/// There are two of these classes :
///
/// SFViewController and SFWindowController
///
/// The requester is a WindowImplCocoa. It's used to send back
/// event via these functions :
///
/// WindowClosed, WindowResized, WindowLostFocus, WindowGainedFocus
///
/// MouseDownAt, MouseUpAt, MouseMovedAt, MouseWheelScrolledAt,
/// MouseMovedIn, MouseMovedOut
///
/// KeyDown, KeyUp, TextEntred
///
/// Note : Joystick are not bound to a view or window
/// thus they're not managed by a class implementing this protocol.
////////////////////////////////////////////////////////////
@protocol WindowImplDelegateProtocol
/// Set the WindowImpl who requested this delegate
/// (This would be a ctor in C++ or Java where we can prohibit the
/// construction of an object.)
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester;
/// Return the main view or window.
-(sf::WindowHandle)getSystemHandle;
/// Hide or show the mouse cursor.
-(void)hideMouseCursor;
-(void)showMouseCursor;
/// Move the mouse cursor to (x,y) (SFML Coordinates).
-(void)setCursorPositionToX:(unsigned int)x Y:(unsigned int)y;
/// Move the window (not the view if we handle not a window) (SFML Coordinates).
-(void)setWindowPositionToX:(unsigned int)x Y:(unsigned int)y;
/// Resize the window/view.
-(void)resizeTo:(unsigned int)width by:(unsigned int)height;
/// Set the title (does nothing if we manage a view).
-(void)changeTitle:(NSString*)title;
/// Hide or show the window (does nothing if we manage a view).
-(void)hideWindow;
-(void)showWindow;
/// Close the window (does nothing if we manage a view).
-(void)closeWindow;
/// Enable or disable key repeat.
-(void)enableKeyRepeat;
-(void)disableKeyRepeat;
/// Set an icon to the application.
-(void)setIconTo:(unsigned int)width by:(unsigned int)height with:(sf::Uint8 const*)pixels;
/// Fetch new event
-(void)processEventWithBlockingMode:(BOOL)block;
/// Apply a given context to an OpenGL view.
-(void)applyContext:(NSOpenGLContext*)context;
@end

View file

@ -0,0 +1,14 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <string>
#import <Foundation/Foundation.h>
////////////////////////////////////////////////////////////
/// \brief Returns a NSString construct with +stringWithCString:encoding:.
////////////////////////////////////////////////////////////
NSString* stringToNSString(std::string const& string);

View file

@ -0,0 +1,19 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/Utf.hpp>
#import <SFML/Window/OSX/cpp_objc_conversion.h>
////////////////////////////////////////////////////////////
NSString* stringToNSString(std::string const& string)
{
std::string utf8; utf8.reserve(string.size() + 1);
sf::Utf8::FromAnsi(string.begin(), string.end(), std::back_inserter(utf8));
NSString* str = [NSString stringWithCString:utf8.c_str() encoding:NSUTF8StringEncoding];
return str;
}

View file

@ -42,7 +42,7 @@
#elif defined(SFML_SYSTEM_MACOS)
#include <SFML/Window/Cocoa/WindowImplCocoa.hpp>
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
typedef sf::priv::WindowImplCocoa WindowImplType;
#endif