Improved coding style of OS X implementation

And fixed some typos.
This commit is contained in:
Marco Antognini 2014-04-11 10:40:00 +02:00
parent 2204838384
commit b868833191
33 changed files with 876 additions and 750 deletions

View File

@ -24,7 +24,7 @@
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// \brief Ensure at least one autorelease pool is available on this thread.
/// \brief Ensure at least one autorelease pool is available on this thread
///
/// Increment a retain count.
/// See SPECIAL CONSIDERATION in implementation file.
@ -35,14 +35,14 @@ void retainPool(void);
////////////////////////////////////////////////////////////
/// \brief Release the pool.
///
/// Drain the pool if it is no more needed (retain count is zero).
/// Drain the pool if it is no more needed (retain count is zero)
/// See SPECIAL CONSIDERATION in implementation file.
///
////////////////////////////////////////////////////////////
void releasePool(void);
////////////////////////////////////////////////////////////
/// \brief Drain the pool.
/// \brief Drain the pool
///
/// releasePool must be called at least once before drainPool.
///

View File

@ -26,12 +26,12 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/ThreadLocalPtr.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/System/Err.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <SFML/System/ThreadLocalPtr.hpp>
#import <Foundation/Foundation.h>
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
#import <Foundation/Foundation.h>
////////////////////////////////////////////////////////////
@ -43,7 +43,7 @@
/// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread.
///
/// SPECIAL CONSIDERATION:
/// =======================
/// ======================
/// This implies that if retainPool is called X times in a thread Y then
/// releasePool must be called X times too in the same thread Y.
///
@ -54,10 +54,11 @@ namespace sf
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief C++ Wrapper of Obj-C Autorelease Pool.
/// \brief C++ Wrapper of Obj-C Autorelease Pool
///
////////////////////////////////////////////////////////////
class PoolWrapper : NonCopyable {
class PoolWrapper : NonCopyable
{
public :
////////////////////////////////////////////////////////////
@ -101,9 +102,9 @@ private:
////////////////////////////////////////////////////////////
PoolWrapper::PoolWrapper()
: m_count(0)
, m_pool(0)
PoolWrapper::PoolWrapper() :
m_count(0),
m_pool(0)
{
/* Nothing else */
}
@ -113,17 +114,16 @@ PoolWrapper::PoolWrapper()
PoolWrapper::~PoolWrapper()
{
#ifdef SFML_DEBUG
if (m_count < 0) {
if (m_count < 0)
sf::err() << "~PoolWrapper : m_count is less than zero! "
"You called releasePool from a thread too many times."
<< std::endl;
} else if (m_count > 0) {
else if (m_count > 0)
sf::err() << "~PoolWrapper : m_count is greater than zero! "
"You called releasePool from a thread to few times."
<< std::endl;
} else { // m_count == 0
else // m_count == 0
sf::err() << "~PoolWrapper is HAPPY!" << std::endl;
}
#endif
}
@ -135,14 +135,12 @@ void PoolWrapper::retain()
++m_count;
// Allocate pool if required.
if (m_pool == 0) {
if (m_pool == 0)
m_pool = [[NSAutoreleasePool alloc] init];
}
#ifdef SFML_DEBUG
if (m_count <= 0) {
if (m_count <= 0)
sf::err() << "PoolWrapper::retain : m_count <= 0! " << std::endl;
}
#endif
}
@ -154,14 +152,12 @@ void PoolWrapper::release()
--m_count;
// Drain pool if required.
if (m_count == 0) {
if (m_count == 0)
drain();
}
#ifdef SFML_DEBUG
if (m_count < 0) {
if (m_count < 0)
sf::err() << "PoolWrapper::release : m_count < 0! " << std::endl;
}
#endif
}
@ -170,10 +166,9 @@ void PoolWrapper::drain()
[m_pool drain];
m_pool = 0;
if (m_count != 0) {
if (m_count != 0)
m_pool = [[NSAutoreleasePool alloc] init];
}
}
} // namespace priv
@ -194,9 +189,8 @@ namespace
void retainPool(void)
{
// First, Check that we have a valid PoolWrapper object in our local pool.
if (localPool == NULL) {
if (localPool == NULL)
localPool = new sf::priv::PoolWrapper();
}
// Then retains!
localPool->retain();
@ -206,19 +200,13 @@ void retainPool(void)
////////////////////////////////////////////////////////////
void releasePool(void)
{
if (localPool != NULL)
localPool->release();
#ifdef SFML_DEBUG
if (localPool == NULL) {
else
sf::err() << "releasePool : You must call retainPool at least once "
"in this thread before calling releasePool."
<< std::endl;
} else {
#endif
// Releases, that's all.
localPool->release();
#ifdef SFML_DEBUG
}
#endif
}
@ -226,14 +214,12 @@ void releasePool(void)
////////////////////////////////////////////////////////////
void drainPool()
{
if (localPool != NULL) {
if (localPool != NULL)
localPool->drain();
}
#ifdef SFML_DEBUG
else {
else
sf::err() << "releasePool must be called at least one before drainPool"
<< std::endl;
}
#endif
}

View File

@ -29,13 +29,13 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <SFML/Window/JoystickImpl.hpp>
#include <SFML/Window/Keyboard.hpp>
#include <SFML/Window/Mouse.hpp>
#include <SFML/System/NonCopyable.hpp>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDDevice.h>
#include <IOKit/hid/IOHIDManager.h>
#include <vector>
namespace sf
@ -46,9 +46,10 @@ namespace priv
typedef std::vector<IOHIDElementRef> IOHIDElements;
////////////////////////////////////////////////////////////
/// \brief This class manage as a singleton instance the
/// keyboard and mouse states. It's only purpose is
/// to help sf::priv::InputImpl class.
/// \brief sf::priv::InputImpl helper
///
/// This class manage as a singleton instance the keyboard and mouse states.
/// It's only purpose is to help sf::priv::InputImpl class.
///
////////////////////////////////////////////////////////////
class HIDInputManager : NonCopyable
@ -211,7 +212,7 @@ private :
void freeUp();
////////////////////////////////////////////////////////////
/// \brief Filter the devices and return them.
/// \brief Filter the devices and return them
///
/// freeUp is _not_ called by this function.
///

View File

@ -63,15 +63,13 @@ long HIDInputManager::getLocationID(IOHIDDeviceRef device)
// Get a unique ID: its usb location ID
CFTypeRef typeRef = IOHIDDeviceGetProperty(device,
CFSTR(kIOHIDLocationIDKey));
if (!typeRef || CFGetTypeID(typeRef) != CFNumberGetTypeID()) {
if (!typeRef || (CFGetTypeID(typeRef) != CFNumberGetTypeID()))
return 0;
}
CFNumberRef locRef = (CFNumberRef)typeRef;
if (!CFNumberGetValue(locRef, kCFNumberLongType, &loc)) {
if (!CFNumberGetValue(locRef, kCFNumberLongType, &loc))
return 0;
}
return loc;
}
@ -100,18 +98,19 @@ CFDictionaryRef HIDInputManager::copyDevicesMask(UInt32 page, UInt32 usage)
////////////////////////////////////////////////////////////
HIDInputManager::HIDInputManager()
: m_isValid(true)
, m_layoutData(0)
, m_layout(0)
, m_manager(0)
HIDInputManager::HIDInputManager() :
m_isValid(true),
m_layoutData(0),
m_layout(0),
m_manager(0)
{
// Get the current keyboard layout
TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource();
m_layoutData = (CFDataRef)TISGetInputSourceProperty(tis,
kTISPropertyUnicodeKeyLayoutData);
if (m_layoutData == 0) {
if (m_layoutData == 0)
{
sf::err() << "Cannot get the keyboard layout" << std::endl;
freeUp();
return;
@ -130,9 +129,9 @@ HIDInputManager::HIDInputManager()
// Open the HID Manager reference
IOReturn openStatus = IOHIDManagerOpen(m_manager, kIOHIDOptionsTypeNone);
if (openStatus != kIOReturnSuccess) {
if (openStatus != kIOReturnSuccess)
{
sf::err() << "Error when opening the HID manager" << std::endl;
freeUp();
return;
}
@ -168,7 +167,8 @@ void HIDInputManager::initializeKeyboard()
// Get only keyboards
CFSetRef keyboards = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
if (keyboards == NULL) {
if (keyboards == NULL)
{
freeUp();
return;
}
@ -179,10 +179,9 @@ void HIDInputManager::initializeKeyboard()
CFTypeRef devicesArray[keyboardCount];
CFSetGetValues(keyboards, devicesArray);
for (CFIndex i = 0; i < keyboardCount; ++i) {
for (CFIndex i = 0; i < keyboardCount; ++i)
{
IOHIDDeviceRef keyboard = (IOHIDDeviceRef)devicesArray[i];
loadKeyboard(keyboard);
}
@ -203,7 +202,8 @@ void HIDInputManager::initializeMouse()
// Get only mouses
CFSetRef mouses = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse);
if (mouses == NULL) {
if (mouses == NULL)
{
freeUp();
return;
}
@ -214,10 +214,9 @@ void HIDInputManager::initializeMouse()
CFTypeRef devicesArray[mouseCount];
CFSetGetValues(mouses, devicesArray);
for (CFIndex i = 0; i < mouseCount; ++i) {
for (CFIndex i = 0; i < mouseCount; ++i)
{
IOHIDDeviceRef mouse = (IOHIDDeviceRef)devicesArray[i];
loadMouse(mouse);
}
@ -235,7 +234,8 @@ void HIDInputManager::loadKeyboard(IOHIDDeviceRef keyboard)
CFArrayRef keys = IOHIDDeviceCopyMatchingElements(keyboard,
NULL,
kIOHIDOptionsTypeNone);
if (keys == NULL) {
if (keys == NULL)
{
sf::err() << "We got a keyboard without any keys (1)" << std::endl;
return;
}
@ -243,24 +243,23 @@ void HIDInputManager::loadKeyboard(IOHIDDeviceRef keyboard)
// How many elements are there?
CFIndex keysCount = CFArrayGetCount(keys);
if (keysCount == 0) {
if (keysCount == 0)
{
sf::err() << "We got a keyboard without any keys (2)" << std::endl;
CFRelease(keys);
return;
}
// Go through all connected elements.
for (CFIndex i = 0; i < keysCount; ++i) {
for (CFIndex i = 0; i < keysCount; ++i)
{
IOHIDElementRef aKey = (IOHIDElementRef) CFArrayGetValueAtIndex(keys, i);
// Skip non-matching keys elements
if (IOHIDElementGetUsagePage(aKey) != kHIDPage_KeyboardOrKeypad) {
if (IOHIDElementGetUsagePage(aKey) != kHIDPage_KeyboardOrKeypad)
continue;
}
loadKey(aKey);
}
// Release unused stuff
@ -274,7 +273,8 @@ void HIDInputManager::loadMouse(IOHIDDeviceRef mouse)
CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(mouse,
NULL,
kIOHIDOptionsTypeNone);
if (buttons == NULL) {
if (buttons == NULL)
{
sf::err() << "We got a mouse without any buttons (1)" << std::endl;
return;
}
@ -282,21 +282,21 @@ void HIDInputManager::loadMouse(IOHIDDeviceRef mouse)
// How many elements are there?
CFIndex buttonCount = CFArrayGetCount(buttons);
if (buttonCount == 0) {
if (buttonCount == 0)
{
sf::err() << "We got a mouse without any buttons (2)" << std::endl;
CFRelease(buttons);
return;
}
// Go through all connected elements.
for (CFIndex i = 0; i < buttonCount; ++i) {
for (CFIndex i = 0; i < buttonCount; ++i)
{
IOHIDElementRef aButton = (IOHIDElementRef) CFArrayGetValueAtIndex(buttons, i);
// Skip non-matching keys elements
if (IOHIDElementGetUsagePage(aButton) != kHIDPage_Button) {
if (IOHIDElementGetUsagePage(aButton) != kHIDPage_Button)
continue;
}
loadButton(aButton);
}
@ -313,9 +313,8 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
UInt32 usageCode = IOHIDElementGetUsage(key);
UInt8 virtualCode = usageToVirtualCode(usageCode);
if (virtualCode == 0xff) {
if (virtualCode == 0xff)
return; // no corresponding virtual code -> skip
}
// Now translate the virtual code to unicode according to
// the current keyboard layout
@ -339,7 +338,8 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
&actualStringLength, // length of what we get
unicodeString); // what we get
if (error == noErr) {
if (error == noErr)
{
// Translation went fine
// The corresponding SFML key code
@ -347,27 +347,23 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
// First we look if the key down is from a list of characters
// that depend on keyboard localization
if (actualStringLength > 0) {
if (actualStringLength > 0)
code = localizedKeys(unicodeString[0]);
}
// The key is not a localized one so we try to find a
// corresponding code through virtual key code
if (code == Keyboard::Unknown) {
if (code == Keyboard::Unknown)
code = nonLocalizedKeys(virtualCode);
}
// A code was found, wonderful!
if (code != Keyboard::Unknown) {
if (code != Keyboard::Unknown)
{
// Ok, everything went fine. Now we have a unique
// corresponding sf::Keyboard::Key to one IOHIDElementRef
m_keys[code].push_back(key);
// And don't forget to keep the reference alive for our usage
CFRetain(m_keys[code].back());
}
////////////////////////////////////////////////////////////
@ -392,8 +388,8 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
//}
} /* if (error == noErr) */
else {
else
{
sf::err() << "Cannot translate the virtual key code, error : "
<< error
<< std::endl;
@ -411,7 +407,8 @@ void HIDInputManager::loadButton(IOHIDElementRef button)
// Extends kHIDUsage_Button_* enum with:
#define kHIDUsage_Button_5 0x05
switch (usage) {
switch (usage)
{
case kHIDUsage_Button_1: dest = Mouse::Left; break;
case kHIDUsage_Button_2: dest = Mouse::Right; break;
case kHIDUsage_Button_3: dest = Mouse::Middle; break;
@ -420,9 +417,9 @@ void HIDInputManager::loadButton(IOHIDElementRef button)
default: dest = Mouse::ButtonCount; break;
}
if (dest != Mouse::ButtonCount) {
if (dest != Mouse::ButtonCount)
{
// We know what kind of button it is!
m_buttons[dest].push_back(button);
// And don't forget to keep the reference alive for our usage
@ -436,21 +433,25 @@ void HIDInputManager::freeUp()
{
m_isValid = false;
if (m_layoutData != 0) CFRelease(m_layoutData);
if (m_layoutData != 0)
CFRelease(m_layoutData);
// Do not release m_layout! It is owned by m_layoutData.
if (m_manager != 0) CFRelease(m_manager);
if (m_manager != 0)
CFRelease(m_manager);
for (unsigned int i = 0; i < Keyboard::KeyCount; ++i) {
for (IOHIDElements::iterator it = m_keys[i].begin(); it != m_keys[i].end(); ++it) {
for (unsigned int i = 0; i < Keyboard::KeyCount; ++i)
{
for (IOHIDElements::iterator it = m_keys[i].begin(); it != m_keys[i].end(); ++it)
CFRelease(*it);
}
m_keys[i].clear();
}
for (unsigned int i = 0; i < Mouse::ButtonCount; ++i) {
for (IOHIDElements::iterator it = m_buttons[i].begin(); it != m_buttons[i].end(); ++it) {
for (unsigned int i = 0; i < Mouse::ButtonCount; ++i)
{
for (IOHIDElements::iterator it = m_buttons[i].begin(); it != m_buttons[i].end(); ++it)
CFRelease(*it);
}
m_buttons[i].clear();
}
}
@ -468,13 +469,13 @@ CFSetRef HIDInputManager::copyDevices(UInt32 page, UInt32 usage)
mask = 0;
CFSetRef devices = IOHIDManagerCopyDevices(m_manager);
if (devices == NULL) {
if (devices == NULL)
return NULL;
}
// Is there at least one device?
CFIndex deviceCount = CFSetGetCount(devices);
if (deviceCount < 1) {
if (deviceCount < 1)
{
CFRelease(devices);
return NULL;
}
@ -484,7 +485,8 @@ CFSetRef HIDInputManager::copyDevices(UInt32 page, UInt32 usage)
bool HIDInputManager::isPressed(IOHIDElements& elements)
{
if (!m_isValid) {
if (!m_isValid)
{
sf::err() << "HIDInputManager is invalid." << std::endl;
return false;
}
@ -492,33 +494,31 @@ bool HIDInputManager::isPressed(IOHIDElements& elements)
// state = true if at least one corresponding HID button is pressed
bool state = false;
for (IOHIDElements::iterator it = elements.begin(); it != elements.end();) {
for (IOHIDElements::iterator it = elements.begin(); it != elements.end(); /* noop */)
{
IOHIDValueRef value = 0;
IOHIDDeviceRef device = IOHIDElementGetDevice(*it);
IOHIDDeviceGetValue(device, *it, &value);
if (!value) {
if (!value)
{
// This means some kind of error / disconnection so we remove this
// element from our buttons
CFRelease(*it);
it = elements.erase(it);
} else if (IOHIDValueGetIntegerValue(value) == 1) {
}
else if (IOHIDValueGetIntegerValue(value) == 1)
{
// This means the button is pressed
state = true;
break; // Stop here
} else {
}
else
{
// This means the button is released
++it;
}
}
return state;
@ -530,7 +530,8 @@ UInt8 HIDInputManager::usageToVirtualCode(UInt32 usage)
{
// Some usage key doesn't have any corresponding virtual
// code or it was not found (return 0xff).
switch (usage) {
switch (usage)
{
case kHIDUsage_KeyboardErrorRollOver: return 0xff;
case kHIDUsage_KeyboardPOSTFail: return 0xff;
case kHIDUsage_KeyboardErrorUndefined: return 0xff;
@ -734,7 +735,8 @@ UInt8 HIDInputManager::usageToVirtualCode(UInt32 usage)
////////////////////////////////////////////////////////
Keyboard::Key HIDInputManager::localizedKeys(UniChar ch)
{
switch (ch) {
switch (ch)
{
case 'a':
case 'A': return sf::Keyboard::A;
@ -824,7 +826,8 @@ Keyboard::Key HIDInputManager::nonLocalizedKeys(UniChar virtualKeycode)
{
// (Some) 0x code based on http://forums.macrumors.com/showthread.php?t=780577
// Some sf::Keyboard::Key are present twice.
switch (virtualKeycode) {
switch (virtualKeycode)
{
// These cases should not be used but anyway...
case 0x00: return sf::Keyboard::A;
case 0x0b: return sf::Keyboard::B;

View File

@ -26,8 +26,8 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/HIDJoystickManager.hpp>
#include <SFML/Window/OSX/HIDInputManager.hpp>
#include <SFML/Window/OSX/HIDJoystickManager.hpp>
////////////////////////////////////////////////////////////
// Private data
@ -36,7 +36,7 @@ namespace
{
// Using a custom run loop mode solve some issues that appears when SFML
// is used with Cocoa.
CFStringRef const RunLoopMode = CFSTR("SFML_RUN_LOOP_MODE");
const CFStringRef RunLoopMode = CFSTR("SFML_RUN_LOOP_MODE");
}
@ -69,9 +69,9 @@ CFSetRef HIDJoystickManager::copyJoysticks()
////////////////////////////////////////////////////////////
HIDJoystickManager::HIDJoystickManager()
: m_manager(0)
, m_joystickCount(0)
HIDJoystickManager::HIDJoystickManager() :
m_manager(0),
m_joystickCount(0)
{
m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
@ -123,7 +123,8 @@ void HIDJoystickManager::update()
{
SInt32 status = kCFRunLoopRunHandledSource;
while (status == kCFRunLoopRunHandledSource) {
while (status == kCFRunLoopRunHandledSource)
{
status = CFRunLoopRunInMode(RunLoopMode, 0, true);
}
}

View File

@ -30,17 +30,18 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/System/NonCopyable.hpp>
#include <IOKit/hid/IOHIDManager.h>
#include <IOKit/hid/IOHIDDevice.h>
#include <IOKit/hid/IOHIDManager.h>
namespace sf
{
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief This class manage as a singleton instance the
/// joysticks. It's only purpose is
/// to help sf::priv::JoystickImpl class.
/// \brief sf::priv::InputImpl helper
///
/// This class manage as a singleton instance the joysticks.
/// It's only purpose is to help sf::priv::JoystickImpl class.
///
////////////////////////////////////////////////////////////
class HIDJoystickManager : NonCopyable
@ -66,7 +67,7 @@ public :
unsigned int getJoystickCount();
////////////////////////////////////////////////////////////
/// \brief Copy the devices assosiated with this HID manager
/// \brief Copy the devices associated with this HID manager
///
/// \return a retained CFSetRef of IOHIDDeviceRef or NULL
///
@ -88,7 +89,7 @@ private :
~HIDJoystickManager();
////////////////////////////////////////////////////////////
/// \brief Make sur all event have been processed in the run loop
/// \brief Make sure all event have been processed in the run loop
///
////////////////////////////////////////////////////////////
void update();
@ -97,7 +98,7 @@ private :
////////////////////////////////////////////////////////////
/// \brief Private "plug-in" callback
/// \note Only 'context' parametre is used.
/// \note Only 'context' parameter is used.
/// \see IOHIDDeviceCallback
///
////////////////////////////////////////////////////////////
@ -105,7 +106,7 @@ private :
////////////////////////////////////////////////////////////
/// \brief Private "plug-out" callback
/// \note Only 'context' parametre is used.
/// \note Only 'context' parameter is used.
/// \see IOHIDDeviceCallback
///
////////////////////////////////////////////////////////////

View File

@ -26,14 +26,14 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/InputImpl.hpp>
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/Window.hpp>
#include <SFML/System/Err.hpp>
#include <SFML/Window/OSX/InputImpl.hpp>
#include <SFML/Window/OSX/HIDInputManager.hpp>
#include <SFML/System/Err.hpp>
#import <AppKit/AppKit.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
#import <AppKit/AppKit.h>
////////////////////////////////////////////////////////////
/// In order to keep track of the keyboard's state and mouse buttons' state
@ -62,42 +62,44 @@ SFOpenGLView* getSFOpenGLViewFromSFMLWindow(const Window& window)
// Get our SFOpenGLView from ...
SFOpenGLView* view = nil;
if ([nsHandle isKindOfClass:[NSWindow class]]) {
if ([nsHandle isKindOfClass:[NSWindow class]])
{
// If system handle is a window then from its content view.
view = [nsHandle contentView];
// Subview doesn't match ?
if (![view isKindOfClass:[SFOpenGLView class]]) {
if (![view isKindOfClass:[SFOpenGLView class]])
{
sf::err() << "The content view is not a valid SFOpenGLView"
<< std::endl;
view = nil;
}
} else if ([nsHandle isKindOfClass:[NSView class]]) {
}
else if ([nsHandle isKindOfClass:[NSView class]])
{
// If system handle is a view then from a subview of kind SFOpenGLView.
NSArray* subviews = [nsHandle subviews];
for (NSView* subview in subviews) {
if ([subview isKindOfClass:[SFOpenGLView class]]) {
for (NSView* subview in subviews)
{
if ([subview isKindOfClass:[SFOpenGLView class]])
{
view = (SFOpenGLView*)subview;
break;
}
}
// No matching subview ?
if (view == nil) {
if (view == nil)
sf::err() << "Cannot find a valid SFOpenGLView subview." << std::endl;
}
} else {
if (nsHandle != 0) {
else
{
if (nsHandle != 0)
sf::err() << "The system handle is neither a <NSWindow*> nor <NSView*>"
<< "object. This shouldn't happen."
<< std::endl;
} else {
// This probably means the SFML window was previously closed.
}
// Else: this probably means the SFML window was previously closed.
}
return view;
@ -134,9 +136,8 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
// No view ?
if (view == nil) {
if (view == nil)
return Vector2i();
}
// Use -cursorPositionFromEvent: with nil.
NSPoint pos = [view cursorPositionFromEvent:nil];
@ -168,9 +169,8 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
// No view ?
if (view == nil) {
if (view == nil)
return;
}
// Let SFOpenGLView compute the position in global coordinate
NSPoint p = NSMakePoint(position.x, position.y);

View File

@ -69,57 +69,60 @@ bool JoystickImpl::isConnected(unsigned int index)
bool state = false; // Is the index-th joystick connected?
// First, let's check if the device was previously detected:
if (m_locationIDs[index] != 0) {
if (m_locationIDs[index] != 0)
{
state = true;
}
// Otherwise, let's check if it is now connected :
else { // i.e., m_locationIDs[index] == 0
else
{
// Otherwise, let's check if it is now connected
// i.e., m_locationIDs[index] == 0
// if there is more connected joystick to the HID manager than
// opened joystick devices then we find the new one.
unsigned int openedCount = 0;
for (unsigned int i(0); i < sf::Joystick::Count; ++i) {
if (m_locationIDs[i] != 0) openedCount++;
for (unsigned int i(0); i < sf::Joystick::Count; ++i)
{
if (m_locationIDs[i] != 0)
openedCount++;
}
unsigned int connectedCount = HIDJoystickManager::getInstance().getJoystickCount();
if (connectedCount > openedCount) {
if (connectedCount > openedCount)
{
// Get all devices
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
if (devices != NULL) {
if (devices != NULL)
{
CFIndex size = CFSetGetCount(devices);
if (size > 0) {
if (size > 0)
{
CFTypeRef array[size]; // array of IOHIDDeviceRef
CFSetGetValues(devices, array);
// If there exists a device d s.t. there is no j s.t.
// m_locationIDs[j] == d's location then we have a new device.
for (CFIndex didx(0); didx < size; ++didx) {
for (CFIndex didx(0); didx < size; ++didx)
{
IOHIDDeviceRef d = (IOHIDDeviceRef)array[didx];
Location dloc = HIDInputManager::getLocationID(d);
bool foundJ = false;
for (unsigned int j(0); j < Joystick::Count; ++j) {
if (m_locationIDs[j] == dloc) {
for (unsigned int j(0); j < Joystick::Count; ++j)
{
if (m_locationIDs[j] == dloc)
{
foundJ = true;
break; // no need to loop again
}
}
if (foundJ) {
// This is a known device
// Nothing else to do
} else {
if (!foundJ) {
// This is a new device
// We set it up for Open(..)
m_locationIDs[index] = dloc;
@ -127,7 +130,6 @@ bool JoystickImpl::isConnected(unsigned int index)
break; // We stop looking for a new device
}
}
}
CFRelease(devices);
@ -147,9 +149,8 @@ bool JoystickImpl::open(unsigned int index)
// Get all devices
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
if (devices == NULL) {
if (devices == NULL)
return false;
}
// Get a usable copy of the joysticks devices.
CFIndex joysticksCount = CFSetGetCount(devices);
@ -158,15 +159,18 @@ bool JoystickImpl::open(unsigned int index)
// Get the desired joystick.
IOHIDDeviceRef self = 0;
for (CFIndex i(0); i < joysticksCount; ++i) {
for (CFIndex i(0); i < joysticksCount; ++i)
{
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
if (deviceLoc == HIDInputManager::getLocationID(d)) {
if (deviceLoc == HIDInputManager::getLocationID(d))
{
self = d;
break; // We found it so we stop looping.
}
}
if (self == 0) {
if (self == 0)
{
// This shouldn't happen!
CFRelease(devices);
return false;
@ -177,11 +181,10 @@ bool JoystickImpl::open(unsigned int index)
m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey));
// Get a list of all elements attached to the device.
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self,
NULL,
kIOHIDOptionsTypeNone);
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, NULL, kIOHIDOptionsTypeNone);
if (elements == NULL) {
if (elements == NULL)
{
CFRelease(devices);
return false;
}
@ -189,7 +192,8 @@ bool JoystickImpl::open(unsigned int index)
// How many elements are there?
CFIndex elementsCount = CFArrayGetCount(elements);
if (elementsCount == 0) {
if (elementsCount == 0)
{
// What is a joystick with no element?
CFRelease(elements);
CFRelease(devices);
@ -197,48 +201,28 @@ bool JoystickImpl::open(unsigned int index)
}
// Go through all connected elements.
for (int i = 0; i < elementsCount; ++i) {
for (int i = 0; i < elementsCount; ++i)
{
IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
switch (IOHIDElementGetType(element)) {
switch (IOHIDElementGetType(element))
{
case kIOHIDElementTypeInput_Misc:
switch (IOHIDElementGetUsage(element)) {
case kHIDUsage_GD_X:
m_axis[Joystick::X] = element;
break;
case kHIDUsage_GD_Y:
m_axis[Joystick::Y] = element;
break;
case kHIDUsage_GD_Z:
m_axis[Joystick::Z] = element;
break;
case kHIDUsage_GD_Rx:
m_axis[Joystick::U] = element;
break;
case kHIDUsage_GD_Ry:
m_axis[Joystick::V] = element;
break;
case kHIDUsage_GD_Rz:
m_axis[Joystick::R] = element;
break;
switch (IOHIDElementGetUsage(element))
{
case kHIDUsage_GD_X: m_axis[Joystick::X] = element; break;
case kHIDUsage_GD_Y: m_axis[Joystick::Y] = element; break;
case kHIDUsage_GD_Z: m_axis[Joystick::Z] = element; break;
case kHIDUsage_GD_Rx: m_axis[Joystick::U] = element; break;
case kHIDUsage_GD_Ry: m_axis[Joystick::V] = element; break;
case kHIDUsage_GD_Rz: m_axis[Joystick::R] = element; break;
// kHIDUsage_GD_Vx, kHIDUsage_GD_Vy, kHIDUsage_GD_Vz are ignored.
}
break;
case kIOHIDElementTypeInput_Button:
if (m_buttons.size() < Joystick::ButtonCount) { // If we have free slot...
if (m_buttons.size() < Joystick::ButtonCount) // If we have free slot...
m_buttons.push_back(element); // ...we add this element to the list
} else {
// Too many buttons. We ignore this one.
}
// Else: too many buttons. We ignore this one.
break;
default: // Make compiler happy
@ -253,13 +237,11 @@ bool JoystickImpl::open(unsigned int index)
// Note : Joy::AxisPovX/Y are not supported (yet).
// Maybe kIOHIDElementTypeInput_Axis is the corresponding type but I can't test.
// Retain all these objets for personal use
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it) {
// Retain all these objects for personal use
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it)
CFRetain(*it);
}
for (AxisMap::iterator it(m_axis.begin()); it != m_axis.end(); ++it) {
for (AxisMap::iterator it(m_axis.begin()); it != m_axis.end(); ++it)
CFRetain(it->second);
}
// Note : we didn't retain element in the switch because we might have multiple
// Axis X (for example) and we want to keep only the last one. So to prevent
@ -275,14 +257,12 @@ bool JoystickImpl::open(unsigned int index)
////////////////////////////////////////////////////////////
void JoystickImpl::close()
{
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it) {
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it)
CFRelease(*it);
}
m_buttons.clear();
for (AxisMap::iterator it(m_axis.begin()); it != m_axis.end(); ++it) {
for (AxisMap::iterator it(m_axis.begin()); it != m_axis.end(); ++it)
CFRelease(it->second);
}
m_axis.clear();
// And we unregister this joystick
@ -329,9 +309,8 @@ JoystickState JoystickImpl::update()
// Get all devices
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
if (devices == NULL) {
if (devices == NULL)
return disconnectedState;
}
// Get a usable copy of the joysticks devices.
CFIndex joysticksCount = CFSetGetCount(devices);
@ -340,9 +319,11 @@ JoystickState JoystickImpl::update()
// Search for it
bool found = false;
for (CFIndex i(0); i < joysticksCount; ++i) {
for (CFIndex i(0); i < joysticksCount; ++i)
{
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
if (selfLoc == HIDInputManager::getLocationID(d)) {
if (selfLoc == HIDInputManager::getLocationID(d))
{
found = true;
break; // Stop looping
}
@ -351,22 +332,20 @@ JoystickState JoystickImpl::update()
// Release unused stuff
CFRelease(devices);
// Was it found ?
if (found) {
// Yes, so we can continue.
} else {
// No, so we stop here
// If not found we consider it disconnected
if (!found)
return disconnectedState;
}
// Update buttons' state
unsigned int i = 0;
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it, ++i) {
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it, ++i)
{
IOHIDValueRef value = 0;
IOHIDDeviceGetValue(IOHIDElementGetDevice(*it), *it, &value);
// Check for plug out.
if (!value) {
if (!value)
{
// No value? Hum... Seems like the joystick is gone
return disconnectedState;
}
@ -376,12 +355,14 @@ JoystickState JoystickImpl::update()
}
// Update axes' state
for (AxisMap::iterator it = m_axis.begin(); it != m_axis.end(); ++it) {
for (AxisMap::iterator it = m_axis.begin(); it != m_axis.end(); ++it)
{
IOHIDValueRef value = 0;
IOHIDDeviceGetValue(IOHIDElementGetDevice(it->second), it->second, &value);
// Check for plug out.
if (!value) {
if (!value)
{
// No value? Hum... Seems like the joystick is gone
return disconnectedState;
}
@ -401,11 +382,10 @@ JoystickState JoystickImpl::update()
double scaledMin = -100;
double scaledMax = 100;
double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
float scaledValue = ((physicalValue - physicalMin) * (scaledMax - scaledMin) / (physicalMax - physicalMin)) + scaledMin;
float scaledValue = (((physicalValue - physicalMin) * (scaledMax - scaledMin)) / (physicalMax - physicalMin)) + scaledMin;
state.axes[it->first] = scaledValue;
}
return state;
}
@ -414,13 +394,13 @@ JoystickState JoystickImpl::update()
std::string JoystickImpl::getDeviceString(IOHIDDeviceRef ref, CFStringRef prop)
{
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
if (ref && CFGetTypeID(typeRef) == CFStringGetTypeID())
if (ref && (CFGetTypeID(typeRef) == CFStringGetTypeID()))
{
CFStringRef str = static_cast<CFStringRef>(typeRef);
return stringFromCFString(str);
}
err() << "Unable to read string value for property '" << stringFromCFString(prop) << "' for joystick at index " << m_index << std::endl;
sf::err() << "Unable to read string value for property '" << stringFromCFString(prop) << "' for joystick at index " << m_index << std::endl;
return "Unknown Joystick";
}
@ -429,14 +409,14 @@ std::string JoystickImpl::getDeviceString(IOHIDDeviceRef ref, CFStringRef prop)
unsigned int JoystickImpl::getDeviceUint(IOHIDDeviceRef ref, CFStringRef prop)
{
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
if (ref && CFGetTypeID(typeRef) == CFNumberGetTypeID())
if (ref && (CFGetTypeID(typeRef) == CFNumberGetTypeID()))
{
SInt32 value;
CFNumberGetValue((CFNumberRef)typeRef, kCFNumberSInt32Type, &value);
return value;
}
err() << "Unable to read uint value for property '" << stringFromCFString(prop) << "' for joystick at index " << m_index << std::endl;
sf::err() << "Unable to read uint value for property '" << stringFromCFString(prop) << "' for joystick at index " << m_index << std::endl;
return 0;
}

View File

@ -119,7 +119,7 @@ private :
/// \param ref HID device
/// \param prop Property to retrieve from the device
///
/// \return Value for the property as a string
/// \return Value of the property
///
////////////////////////////////////////////////////////////
std::string getDeviceString(IOHIDDeviceRef ref, CFStringRef prop);
@ -130,7 +130,7 @@ private :
/// \param ref HID device
/// \param prop Property to retrieve from the device
///
/// \return Value for the propery as an unsigned int
/// \return Value of the property
///
////////////////////////////////////////////////////////////
unsigned int getDeviceUint(IOHIDDeviceRef ref, CFStringRef prop);
@ -141,6 +141,7 @@ private :
/// \param cfString CFStringRef to convert
///
/// \return std::string
///
////////////////////////////////////////////////////////////
std::string stringFromCFString(CFStringRef cfString);

View File

@ -26,8 +26,8 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
////////////////////////////////////////////////////////////
/// \brief Event processing & Menu bar initialisation
@ -55,6 +55,7 @@
///
/// This overload of -[NSApplication sendEvent:] is used to
/// fix KeyRelease events when the command key is down.
///
////////////////////////////////////////////////////////////
-(void)sendEvent:(NSEvent*)anEvent;

View File

@ -56,7 +56,8 @@
// Set the main menu bar
NSMenu* mainMenu = [NSApp mainMenu];
if (mainMenu != nil) return;
if (mainMenu != nil)
return;
mainMenu = [[NSMenu alloc] initWithTitle:@""];
[NSApp setMainMenu:mainMenu];
@ -224,14 +225,12 @@
NSString* appName = [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"];
// Then, try non-localized name
if (appName == nil || [appName length] == 0) {
if ((appName == nil) || ([appName length] == 0))
appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
}
// Finally, fallback to the process info
if (appName == nil || [appName length] == 0) {
if ((appName == nil) || ([appName length] == 0))
appName = [[NSProcessInfo processInfo] processName];
}
return appName;
}
@ -252,8 +251,7 @@
// custom OpenGL view. See -[SFOpenGLView sfKeyUp:] for more details.
id firstResponder = [[anEvent window] firstResponder];
if ([anEvent type] != NSKeyUp
|| ![firstResponder tryToPerform:@selector(sfKeyUp:) with:anEvent]) {
if (([anEvent type] != NSKeyUp) || (![firstResponder tryToPerform:@selector(sfKeyUp:) with:anEvent])) {
// It's either not a key up event or no responder has a sfKeyUp
// message implemented.
[super sendEvent:anEvent];

View File

@ -26,8 +26,8 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <Foundation/Foundation.h>
#import <AppKit/AppKit.h>
#import <Foundation/Foundation.h>
////////////////////////////////////////////////////////////
@ -36,7 +36,18 @@
////////////////////////////////////////////////////////////
@interface SFApplicationDelegate : NSObject <NSApplicationDelegate>
////////////////////////////////////////////////////////////
/// \brief React to a termination notification
///
/// Send a close message to all windows and cancel the termination.
///
////////////////////////////////////////////////////////////
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
////////////////////////////////////////////////////////////
/// \brief Exit the app when all windows are closed
///
////////////////////////////////////////////////////////////
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication;
@end

View File

@ -39,8 +39,9 @@ namespace priv
////////////////////////////////////////////////////////////
SFContext::SFContext(SFContext* shared)
: m_view(0), m_window(0)
SFContext::SFContext(SFContext* shared) :
m_view(0),
m_window(0)
{
// Ask for a pool.
retainPool();
@ -54,8 +55,9 @@ SFContext::SFContext(SFContext* shared)
////////////////////////////////////////////////////////////
SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
const WindowImpl* owner, unsigned int bitsPerPixel)
: m_view(0), m_window(0)
const WindowImpl* owner, unsigned int bitsPerPixel) :
m_view(0),
m_window(0)
{
// Ask for a pool.
retainPool();
@ -64,15 +66,16 @@ SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
createContext(shared, bitsPerPixel, settings);
// Apply context.
WindowImplCocoa const * ownerCocoa = static_cast<WindowImplCocoa const *>(owner);
const WindowImplCocoa* ownerCocoa = static_cast<const WindowImplCocoa*>(owner);
ownerCocoa->applyContext(m_context);
}
////////////////////////////////////////////////////////////
SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
unsigned int width, unsigned int height)
: m_view(0), m_window(0)
unsigned int width, unsigned int height) :
m_view(0),
m_window(0)
{
// Ensure the process is setup in order to create a valid window.
WindowImplCocoa::setUpProcess();
@ -142,16 +145,17 @@ void SFContext::createContext(SFContext* shared,
unsigned int bitsPerPixel,
const ContextSettings& settings)
{
// Choose the attributs of OGL context.
// Choose the attributes of OGL context.
std::vector<NSOpenGLPixelFormatAttribute> attrs;
attrs.reserve(20); // max attributs (estimation).
attrs.reserve(20); // max attributes (estimation).
// These casts are safe. C++ is much more strict than Obj-C.
attrs.push_back(NSOpenGLPFAClosestPolicy);
attrs.push_back(NSOpenGLPFADoubleBuffer);
if (bitsPerPixel > 24) {
if (bitsPerPixel > 24)
{
attrs.push_back(NSOpenGLPFAAlphaSize);
attrs.push_back((NSOpenGLPixelFormatAttribute)8);
}
@ -162,7 +166,8 @@ void SFContext::createContext(SFContext* shared,
attrs.push_back(NSOpenGLPFAStencilSize);
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.stencilBits);
if (settings.antialiasingLevel > 0) {
if (settings.antialiasingLevel > 0)
{
/*
* Antialiasing techniques are described in the
* "OpenGL Programming Guide for Mac OS X" document.
@ -191,10 +196,11 @@ void SFContext::createContext(SFContext* shared,
attrs.push_back((NSOpenGLPixelFormatAttribute)0); // end of array
// Create the pixel pormat.
// Create the pixel format.
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attrs[0]];
if (pixFmt == nil) {
if (pixFmt == nil)
{
sf::err() << "Error. Unable to find a suitable pixel format." << std::endl;
return;
}
@ -206,9 +212,8 @@ void SFContext::createContext(SFContext* shared,
m_context = [[NSOpenGLContext alloc] initWithFormat:pixFmt
shareContext:sharedContext];
if (m_context == nil) {
if (m_context == nil)
sf::err() << "Error. Unable to create the context." << std::endl;
}
// Free up.
[pixFmt release];

View File

@ -44,24 +44,25 @@ namespace sf {
////////////////////////////////////////////////////////////
/// Init the global state (only if needed). It needs to be
/// Called before any event, e.g. in the window constructor.
/// \brief Initialize the global state (only if needed)
///
/// It needs to be called before any event, e.g. in the window constructor.
///
////////////////////////////////////////////////////////////
void initialiseKeyboardHelper();
void initialiseKeyboardHelper(void);
////////////////////////////////////////////////////////////
/// Set up a SFML key event based on the given modifiers
/// flags and key code.
/// \brief Set up a SFML key event based on the given modifiers flags and key code
///
////////////////////////////////////////////////////////////
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key);
////////////////////////////////////////////////////////////
/// Handle the state of modifiers keys and send key
/// release & pressed events to the requester.
/// \brief Handle the state of modifiers keys
///
/// Send key released & pressed events to the requester.
///
////////////////////////////////////////////////////////////
void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& requester);

View File

@ -78,15 +78,16 @@ static BOOL isStateInitialized = NO;
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// Carefully observe if the key mask is on in the modifiers
/// \brief Carefully observe if the key mask is on in the modifiers
///
////////////////////////////////////////////////////////////
BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask);
////////////////////////////////////////////////////////////
/// Handle one modifier key mask, update the key state and
/// send events to the requester
/// \brief Handle one modifier key mask
///
/// Update the key state and send events to the requester
///
////////////////////////////////////////////////////////////
void processOneModifier(NSUInteger modifiers, NSUInteger mask,
@ -95,8 +96,9 @@ void processOneModifier(NSUInteger modifiers, NSUInteger mask,
////////////////////////////////////////////////////////////
/// Handle left & right modifier keys, update the keys state and
/// send events to the requester
/// \brief Handle left & right modifier keys
///
/// Update the keys state and send events to the requester
///
////////////////////////////////////////////////////////////
void processLeftRightModifiers(NSUInteger modifiers,
@ -113,7 +115,7 @@ void processLeftRightModifiers(NSUInteger modifiers,
////////////////////////////////////////////////////////
void initialiseKeyboardHelper()
void initialiseKeyboardHelper(void)
{
if (isStateInitialized) return;
@ -210,13 +212,13 @@ void processOneModifier(NSUInteger modifiers, NSUInteger mask,
BOOL isDown = isKeyMaskActive(modifiers, mask);
// Check for key pressed event
if (isDown && !wasDown) {
if (isDown && !wasDown)
requester.keyDown(event);
}
// And check for key released event
else if (!isDown && wasDown) {
else if (!isDown && wasDown)
requester.keyUp(event);
}
// else isDown == wasDown, so no change
// Update state

View File

@ -46,7 +46,7 @@ namespace sf {
/// The SFWindowController should call -[SFOpenGLView exitFullscreen]
/// and -[SFOpenGLView enterFullscreen] when appropriate.
///
/// In order to send correct mouse coordonate to the requester when
/// In order to send correct mouse coordinate to the requester when
/// the window is in fullscreen we use m_realSize to represent the
/// back buffer size (see SFWindowController). If 'm_realSize' is
/// bound to its default value we don't recompute the mouse position
@ -56,12 +56,13 @@ namespace sf {
/// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm).
///
////////////////////////////////////////////////////////////
@interface SFOpenGLView : NSOpenGLView {
sf::priv::WindowImplCocoa* m_requester;
BOOL m_useKeyRepeat;
BOOL m_mouseIsIn;
NSTrackingArea* m_trackingArea;
NSSize m_realSize;
@interface SFOpenGLView : NSOpenGLView
{
sf::priv::WindowImplCocoa* m_requester; ///< View's requester
BOOL m_useKeyRepeat; ///< Key repeat setting
BOOL m_mouseIsIn; ///< Mouse positional state
NSTrackingArea* m_trackingArea; ///< Mouse tracking area
NSSize m_realSize; ///< Actual size of the view
// Hidden text view used to convert key event to actual chars.
// We use a silent responder to prevent sound alerts.
@ -70,49 +71,73 @@ namespace sf {
}
////////////////////////////////////////////////////////////
/// Create the SFML opengl view to fit the given area.
/// \brief Create the SFML OpenGL view
///
/// \param frameRect dimension of the view
///
/// \return an initialized view
///
////////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect;
////////////////////////////////////////////////////////////
/// Handle going in and out of fullscreen mode.
/// \brief Handle going in fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)enterFullscreen;
////////////////////////////////////////////////////////////
/// \brief Handle exiting fullscreen mode
///
////////////////////////////////////////////////////////////
-(void)exitFullscreen;
////////////////////////////////////////////////////////////
/// Apply the given resquester to the view.
/// \brief Apply the given requester to the view
///
/// \param requester new 'requester' of the view
///
////////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester;
////////////////////////////////////////////////////////////
/// Set the real size of view (it should be the back buffer size).
/// \brief Set the real size of view (it should be the back buffer size)
///
/// If not set, or set to its default value NSZeroSize, the view
/// won't recompute the mouse coordinates before sending them
/// to the requester.
///
/// \param newSize actual size of the view
///
////////////////////////////////////////////////////////////
-(void)setRealSize:(NSSize)newSize;
////////////////////////////////////////////////////////////
/// Compute the position in global coordinate
/// of the given point in SFML coordinate.
/// \brief Compute the position in global coordinate
///
/// \param point a point in SFML coordinate
///
/// \return the global coordinates of the point
///
////////////////////////////////////////////////////////////
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point;
////////////////////////////////////////////////////////////
/// Adjust key repeat configuration.
/// \brief Enable key repeat
///
////////////////////////////////////////////////////////////
-(void)enableKeyRepeat;
////////////////////////////////////////////////////////////
/// \brief Disable key repeat
///
////////////////////////////////////////////////////////////
-(void)disableKeyRepeat;
////////////////////////////////////////////////////////////
/// Compute the position of the cursor.
/// \brief Compute the position of the cursor
///
/// \param eventOrNil
///
////////////////////////////////////////////////////////////
-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil;

View File

@ -30,16 +30,20 @@
#include <SFML/Window/OSX/HIDInputManager.hpp> // For localizedKeys and nonLocalizedKeys
#include <SFML/System/Err.hpp>
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
#import <SFML/Window/OSX/SFSilentResponder.h>
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
////////////////////////////////////////////////////////////
/// Returns true if `event` represents a representable character.
/// \brief Check if the event represent some Unicode text
///
/// The event is assumed to be a key down event.
/// False is returned if the event is either escape or a non text unicode.
/// False is returned if the event is either escape or a non text Unicode.
///
/// \param event a key down event
///
/// \return true if event represents a Unicode character, false otherwise
///
////////////////////////////////////////////////////////////
BOOL isValidTextUnicode(NSEvent* event);
@ -52,40 +56,48 @@ BOOL isValidTextUnicode(NSEvent* event);
@interface SFOpenGLView ()
////////////////////////////////////////////////////////////
/// Handle view resized event.
/// \brief Handle view resized event
///
////////////////////////////////////////////////////////////
-(void)viewDidEndLiveResize;
////////////////////////////////////////////////////////////
/// Establish if the mouse is inside or outside the OpenGL view.
/// \brief Determine where the mouse is
///
/// \return true when the mouse is inside the OpenGL view, false otherwise
///
////////////////////////////////////////////////////////////
-(BOOL)isMouseInside;
////////////////////////////////////////////////////////////
/// Update the mouse state (in or out) and fire an event
/// if its state has changed.
/// \brief Update the mouse state (in or out)
///
/// Fire an event if its state has changed.
///
////////////////////////////////////////////////////////////
-(void)updateMouseState;
////////////////////////////////////////////////////////////
/// Convert the NSEvent mouse button type to SFML type.
/// \brief Convert the NSEvent mouse button type to SFML type
///
/// Returns ButtonCount if the button is unknown
/// \param event a mouse button event
///
/// \return Left, Right, ..., or ButtonCount if the button is unknown
///
////////////////////////////////////////////////////////////
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event;
////////////////////////////////////////////////////////////
/// Convert a key down/up NSEvent into an SFML key event.
/// Based on localizedKeys and nonLocalizedKeys function.
/// \brief Convert a key down/up NSEvent into an SFML key event
///
/// Return sf::Keyboard::Unknown as Code if the key is unknown.
/// The conversion is based on localizedKeys and nonLocalizedKeys functions.
///
/// \param event a key event
///
/// \return sf::Keyboard::Unknown as Code if the key is unknown
///
////////////////////////////////////////////////////////////
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent;
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event;
@end
@ -97,7 +109,8 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
-(id)initWithFrame:(NSRect)frameRect
{
if ((self = [super initWithFrame:frameRect])) {
if ((self = [super initWithFrame:frameRect]))
{
[self setRequesterTo:0];
[self enableKeyRepeat];
m_realSize = NSZeroSize;
@ -130,9 +143,8 @@ BOOL isValidTextUnicode(NSEvent* event);
[self addTrackingArea:m_trackingArea];
// Fire an mouse entered event if needed
if (!m_mouseIsIn && m_requester != 0) {
if (!m_mouseIsIn && (m_requester != 0))
m_requester->mouseMovedIn();
}
// Update status
m_mouseIsIn = YES;
@ -145,9 +157,8 @@ BOOL isValidTextUnicode(NSEvent* event);
[self removeTrackingArea:m_trackingArea];
// Fire an mouse left event if needed
if (m_mouseIsIn && m_requester != 0) {
if (m_mouseIsIn && (m_requester != 0))
m_requester->mouseMovedOut();
}
// Update status
m_mouseIsIn = NO;
@ -172,9 +183,10 @@ BOOL isValidTextUnicode(NSEvent* event);
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point
{
// Recompute the mouse pos if required.
if (!NSEqualSizes(m_realSize, NSZeroSize)) {
point.x = point.x / m_realSize.width * [self frame].size.width;
point.y = point.y / m_realSize.height * [self frame].size.height;
if (!NSEqualSizes(m_realSize, NSZeroSize))
{
point.x = (point.x / m_realSize.width) * [self frame].size.width;
point.y = (point.y / m_realSize.height) * [self frame].size.height;
}
// Note : -[NSWindow convertBaseToScreen:] is deprecated on 10.7
@ -194,8 +206,8 @@ BOOL isValidTextUnicode(NSEvent* event);
// Convert it to screen coordinates
point = [[self window] convertBaseToScreen:point];
// Flip screen coodinates to match CGDisplayMoveCursorToPoint referential.
float const screenHeight = [[[self window] screen] frame].size.height;
// Flip screen coordinates to match CGDisplayMoveCursorToPoint referential.
const float screenHeight = [[[self window] screen] frame].size.height;
point.y = screenHeight - point.y;
return point;
@ -237,7 +249,8 @@ BOOL isValidTextUnicode(NSEvent* event);
[self update];
// Send an event
if (m_requester == 0) return;
if (m_requester == 0)
return;
// The new size
NSSize newSize = [self frame].size;
@ -251,11 +264,7 @@ BOOL isValidTextUnicode(NSEvent* event);
NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
if (NSPointInRect(relativeToView, [self frame])) {
return YES;
}
return NO;
return NSPointInRect(relativeToView, [self frame]);
}
@ -266,12 +275,11 @@ BOOL isValidTextUnicode(NSEvent* event);
m_mouseIsIn = [self isMouseInside];
// Send event if needed.
if (mouseWasIn && !m_mouseIsIn) {
if (mouseWasIn && !m_mouseIsIn)
[self mouseExited:nil];
} else if (!mouseWasIn && m_mouseIsIn) {
else if (!mouseWasIn && m_mouseIsIn)
[self mouseEntered:nil];
}
}
#pragma mark
@ -351,9 +359,9 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
-(void)scrollWheel:(NSEvent*)theEvent
{
if (m_requester != 0) {
if (m_requester != 0)
{
NSPoint loc = [self cursorPositionFromEvent:theEvent];
m_requester->mouseWheelScrolledAt([theEvent deltaY], loc.x, loc.y);
}
@ -369,36 +377,36 @@ BOOL isValidTextUnicode(NSEvent* event);
// a) the event is nil, meaning that the method was
// called from our code (e.g. updateMouseState)
// b) the mouse was outside the view.
BOOL shouldFire = (theEvent == nil || m_mouseIsIn == NO);
BOOL shouldFire = ((theEvent == nil) || (m_mouseIsIn == NO));
// Update status
m_mouseIsIn = YES;
if (m_requester == 0) return;
if (m_requester == 0)
return;
// Fire (or not) an event
if (shouldFire) {
if (shouldFire)
m_requester->mouseMovedIn();
}
}
////////////////////////////////////////////////////////
-(void)mouseExited:(NSEvent*)theEvent
{
// Similarly to mouseEntered:
BOOL shouldFire = (theEvent == nil || m_mouseIsIn == YES);
BOOL shouldFire = ((theEvent == nil) || (m_mouseIsIn == YES));
// Update status
m_mouseIsIn = NO;
if (m_requester == 0) return;
if (m_requester == 0)
return;
// Fire (or not) an event
if (shouldFire) {
if (shouldFire)
m_requester->mouseMovedOut();
}
}
////////////////////////////////////////////////////////
@ -428,16 +436,17 @@ BOOL isValidTextUnicode(NSEvent* event);
{
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
if (m_requester != 0) {
if (m_requester != 0)
{
NSPoint loc = [self cursorPositionFromEvent:theEvent];
if (button != sf::Mouse::ButtonCount) {
if (button != sf::Mouse::ButtonCount)
m_requester->mouseDownAt(button, loc.x, loc.y);
}
}
// If the event is not forwarded by mouseDown or rightMouseDown...
if (button != sf::Mouse::Left && button != sf::Mouse::Right) {
if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
{
// ... transmit to non-SFML responder
[[self nextResponder] otherMouseDown:theEvent];
}
@ -449,16 +458,17 @@ BOOL isValidTextUnicode(NSEvent* event);
{
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
if (m_requester != 0) {
if (m_requester != 0)
{
NSPoint loc = [self cursorPositionFromEvent:theEvent];
if (button != sf::Mouse::ButtonCount) {
if (button != sf::Mouse::ButtonCount)
m_requester->mouseUpAt(button, loc.x, loc.y);
}
}
// If the event is not forwarded by mouseUp or rightMouseUp...
if (button != sf::Mouse::Left && button != sf::Mouse::Right) {
if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
{
// ... transmit to non-SFML responder
[[self nextResponder] otherMouseUp:theEvent];
}
@ -490,21 +500,22 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
-(void)otherMouseDragged:(NSEvent*)theEvent
{
if (m_requester != 0) {
if (m_requester != 0)
{
NSPoint loc = [self cursorPositionFromEvent:theEvent];
// Make sure the point is inside the view.
// (mouseEntered: and mouseExited: are not immediately called
// when the mouse is dragged. That would be too easy!)
[self updateMouseState];
if (m_mouseIsIn) {
if (m_mouseIsIn)
m_requester->mouseMovedAt(loc.x, loc.y);
}
}
// If the event is not forwarded by mouseDragged or rightMouseDragged...
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
if (button != sf::Mouse::Left && button != sf::Mouse::Right) {
if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
{
// ... transmit to non-SFML responder
[[self nextResponder] otherMouseUp:theEvent];
}
@ -516,10 +527,13 @@ BOOL isValidTextUnicode(NSEvent* event);
{
NSPoint loc;
// If no event given then get current mouse pos.
if (eventOrNil == nil) {
if (eventOrNil == nil)
{
NSPoint rawPos = [[self window] mouseLocationOutsideOfEventStream];
loc = [self convertPoint:rawPos fromView:nil];
} else {
}
else
{
loc = [self convertPoint:[eventOrNil locationInWindow] fromView:nil];
}
@ -528,9 +542,10 @@ BOOL isValidTextUnicode(NSEvent* event);
loc.y = h - loc.y;
// Recompute the mouse pos if required.
if (!NSEqualSizes(m_realSize, NSZeroSize)) {
loc.x = loc.x * m_realSize.width / [self frame].size.width;
loc.y = loc.y * m_realSize.height / [self frame].size.height;
if (!NSEqualSizes(m_realSize, NSZeroSize))
{
loc.x = (loc.x * m_realSize.width) / [self frame].size.width;
loc.y = (loc.y * m_realSize.height) / [self frame].size.height;
}
return loc;
@ -540,7 +555,8 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event
{
switch ([event buttonNumber]) {
switch ([event buttonNumber])
{
case 0: return sf::Mouse::Left;
case 1: return sf::Mouse::Right;
case 2: return sf::Mouse::Middle;
@ -561,24 +577,27 @@ BOOL isValidTextUnicode(NSEvent* event);
// Transmit to non-SFML responder
[[self nextResponder] keyDown:theEvent];
if (m_requester == 0) return;
if (m_requester == 0)
return;
// Handle key down event
if (m_useKeyRepeat || ![theEvent isARepeat]) {
if (m_useKeyRepeat || ![theEvent isARepeat])
{
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
if (key.code != sf::Keyboard::Unknown) { // The key is recognized.
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
m_requester->keyDown(key);
}
}
// Handle text entred event:
// Ignore event if we don't want repeated keystrokes
if (m_useKeyRepeat || ![theEvent isARepeat]) {
if (m_useKeyRepeat || ![theEvent isARepeat])
{
// Ignore escape key and other non text keycode (See NSEvent.h)
// because they produce a sound alert.
if (isValidTextUnicode(theEvent)) {
if (isValidTextUnicode(theEvent))
{
// Send the event to the hidden text view for processing
[m_hiddenTextView interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
}
@ -591,25 +610,27 @@ BOOL isValidTextUnicode(NSEvent* event);
unsigned short keycode = [theEvent keyCode];
// Backspace
if (keycode == 0x33) {
if (keycode == 0x33)
{
// Send the correct unicode value (i.e. 8) instead of 127 (which is 'delete')
m_requester->textEntered(8);
}
// Delete
else if (keycode == 0x75 || keycode == NSDeleteFunctionKey) {
else if ((keycode == 0x75) || (keycode == NSDeleteFunctionKey))
{
// Instead of the value 63272 we send 127.
m_requester->textEntered(127);
}
// Otherwise, let's see what our hidden field has computed
else {
else
{
NSString* string = [m_hiddenTextView string];
// Send each character to SFML event requester
for (NSUInteger index = 0; index < [string length]; ++index) {
for (NSUInteger index = 0; index < [string length]; ++index)
m_requester->textEntered([string characterAtIndex:index]);
}
// Empty our hidden cache
[m_hiddenTextView setString:@""];
@ -631,14 +652,14 @@ BOOL isValidTextUnicode(NSEvent* event);
// Transmit to non-SFML responder
[[self nextResponder] keyUp:theEvent];
if (m_requester == 0) return;
if (m_requester == 0)
return;
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
if (key.code != sf::Keyboard::Unknown) { // The key is recognized.
if (key.code != sf::Keyboard::Unknown) // The key is recognized.
m_requester->keyUp(key);
}
}
////////////////////////////////////////////////////////
@ -647,7 +668,8 @@ BOOL isValidTextUnicode(NSEvent* event);
// Transmit to non-SFML responder
[[self nextResponder] flagsChanged:theEvent];
if (m_requester == 0) return;
if (m_requester == 0)
return;
NSUInteger modifiers = [theEvent modifierFlags];
handleModifiersChanged(modifiers, *m_requester);
@ -655,35 +677,33 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
{
// Key code
sf::Keyboard::Key key = sf::Keyboard::Unknown;
// First we look if the key down is from a list of characters
// that depend on keyboard localization.
NSString* string = [anEvent charactersIgnoringModifiers];
if ([string length] > 0) {
NSString* string = [event charactersIgnoringModifiers];
if ([string length] > 0)
key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
}
// If the key is not a localized one, we try to find a corresponding code
// through virtual key code.
if (key == sf::Keyboard::Unknown) {
key = sf::priv::HIDInputManager::nonLocalizedKeys([anEvent keyCode]);
}
if (key == sf::Keyboard::Unknown)
key = sf::priv::HIDInputManager::nonLocalizedKeys([event keyCode]);
//#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages.
// if (key.code == sf::Keyboard::Unknown) { // The key is unknown.
// sf::err() << "This is an unknow key. Virtual key code is 0x"
// << std::hex
// << [anEvent keyCode]
// << [event keyCode]
// << "."
// << std::endl;
// }
//#endif
return keyEventWithModifiers([anEvent modifierFlags], key);
return keyEventWithModifiers([event modifierFlags], key);
}
@end
@ -693,12 +713,17 @@ BOOL isValidTextUnicode(NSEvent* event);
BOOL isValidTextUnicode(NSEvent* event)
{
if ([event keyCode] == 0x35) { // Escape
if ([event keyCode] == 0x35) // Escape
{
return false;
} else if ([[event characters] length] > 0) {
}
else if ([[event characters] length] > 0)
{
unichar code = [[event characters] characterAtIndex:0];
return code < 0xF700 || code > 0xF8FF;
} else {
return ((code < 0xF700) || (code > 0xF8FF));
}
else
{
return true;
}
}

View File

@ -32,6 +32,7 @@
/// \brief Silent Responder used to prevent sound alert with key event
///
/// Mainly used by SFOpenGLView and its hidden text view.
///
////////////////////////////////////////////////////////////
@interface SFSilentResponder : NSResponder

View File

@ -34,16 +34,25 @@
@class SFOpenGLView;
////////////////////////////////////////////////////////////
/// Implementation of WindowImplDelegateProtocol for view managment.
/// \brief Implementation of WindowImplDelegateProtocol for view management
///
////////////////////////////////////////////////////////////
@interface SFViewController : NSObject <WindowImplDelegateProtocol> {
NSView* m_view;
SFOpenGLView* m_oglView;
sf::priv::WindowImplCocoa* m_requester;
@interface SFViewController : NSObject <WindowImplDelegateProtocol>
{
NSView* m_view; ///< Underlying Cocoa view
SFOpenGLView* m_oglView; ///< OpenGL view
sf::priv::WindowImplCocoa* m_requester; ///< View's requester
}
////////////////////////////////////////////////////////////
/// \brief Initialize the view controller
///
/// \param view view to be controlled
///
/// \return an initialized view controller
///
////////////////////////////////////////////////////////////
-(id)initWithView:(NSView*)view;
@end

View File

@ -26,30 +26,29 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/OSX/SFViewController.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
#import <SFML/Window/OSX/SFApplication.h>
#include <SFML/System/Err.hpp>
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#import <SFML/Window/OSX/SFApplication.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
#import <SFML/Window/OSX/SFViewController.h>
@implementation SFViewController
////////////////////////////////////////////////////////
-(id)initWithView:(NSView *)view
{
if ((self = [super init])) {
if ((self = [super init]))
{
m_requester = 0;
// Retain the view for our own use.
m_view = [view retain];
if (m_view == nil) {
sf::err()
<< "No view was given to initWithWindow:."
<< std::endl;
if (m_view == nil)
{
sf::err() << "No view was given to initWithWindow:." << std::endl;
return self;
}
@ -59,10 +58,9 @@
frame.origin.y = 0;
m_oglView = [[SFOpenGLView alloc] initWithFrame:frame];
if (m_oglView == nil) {
sf::err()
<< "Could not create an instance of NSOpenGLView "
if (m_oglView == nil)
{
sf::err() << "Could not create an instance of NSOpenGLView "
<< "in (SFViewController -initWithView:)."
<< std::endl;
@ -132,7 +130,7 @@
////////////////////////////////////////////////////////.
-(void)setWindowPositionToX:(int)x Y:(int)y
{
sf::err() << "Cannot move SFML area when SFML is integrated in a NSView. Use the view hanlder directly instead." << std::endl;
sf::err() << "Cannot move SFML area when SFML is integrated in a NSView. Use the view handler directly instead." << std::endl;
}
@ -201,7 +199,7 @@
////////////////////////////////////////////////////////
-(void)setIconTo:(unsigned int)width
by:(unsigned int)height
with:(sf::Uint8 const *)pixels
with:(const sf::Uint8*)pixels
{
sf::err() << "Cannot set an icon when SFML is integrated in a NSView." << std::endl;
}
@ -211,23 +209,21 @@
-(void)processEvent
{
// If we are not on the main thread we stop here and advice the user.
if ([NSThread currentThread] != [NSThread mainThread]) {
if ([NSThread currentThread] != [NSThread mainThread])
{
/*
* See http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00460.html
* for more information.
*/
sf::err()
<< "Cannot fetch event from a worker thread. (OS X restriction)"
<< std::endl;
sf::err() << "Cannot fetch event from a worker thread. (OS X restriction)" << std::endl;
return;
}
// If we don't have a requester we don't fetch event.
if (m_requester != 0) {
if (m_requester != 0)
[SFApplication processEvent];
}
}
////////////////////////////////////////////////////////

View File

@ -29,23 +29,38 @@
#import <AppKit/AppKit.h>
////////////////////////////////////////////////////////////
/// \brief Here we redefine some methods to allow grabing fullscreen events.
/// \brief Here we redefine some methods to allow grabbing fullscreen events
///
////////////////////////////////////////////////////////////
@interface SFWindow : NSWindow
////////////////////////////////////////////////////////////
/// These two methods must return YES to grab fullscreen events.
/// \brief Allow to grab fullscreen events
///
/// acceptsFirstResponder and canBecomeKeyWindow messages must
/// return YES to grab fullscreen events.
///
/// See http://stackoverflow.com/questions/999464/fullscreen-key-down-actions
/// for more informations
///
/// \return YES
///
////////////////////////////////////////////////////////////
-(BOOL)acceptsFirstResponder;
////////////////////////////////////////////////////////////
/// \brief Allow to grab fullscreen events
///
/// See acceptsFirstResponder documentation above.
///
/// \return YES
///
////////////////////////////////////////////////////////////
-(BOOL)canBecomeKeyWindow;
////////////////////////////////////////////////////////////
/// Override default implementation of keyDown: to prevent
/// system alert
/// \brief Prevent system alert
///
/// \param theEvent a Cocoa event
///
////////////////////////////////////////////////////////////
-(void)keyDown:(NSEvent*)theEvent;
@ -53,12 +68,18 @@
@end
////////////////////////////////////////////////////////////
/// \brief Extension of NSWindow
///
/// Add some extra messages for SFML internal usage.
///
////////////////////////////////////////////////////////////
@interface NSWindow (SFML)
////////////////////////////////////////////////////////////
/// Proxy for performClose: for the app delegate
///
/// Always return nil
/// \return nil
///
////////////////////////////////////////////////////////////
-(id)sfClose;

View File

@ -26,7 +26,7 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import "SFWindow.h"
#import <SFML/Window/OSX/SFWindow.h>
@implementation SFWindow

View File

@ -26,9 +26,10 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
#include <SFML/Window/VideoMode.hpp>
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
////////////////////////////////////////////////////////////
/// Predefine some classes
////////////////////////////////////////////////////////////
@ -41,7 +42,7 @@ namespace sf {
@class SFOpenGLView;
////////////////////////////////////////////////////////////
/// Implementation of WindowImplDelegateProtocol for window managment.
/// \brief Implementation of WindowImplDelegateProtocol for window management
///
/// Key and mouse events are delegated to its view.
/// Window events are managed by this class.
@ -54,26 +55,38 @@ namespace sf {
////////////////////////////////////////////////////////////
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 // NSWindowDelegate is only define since 10.6
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol> {
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol>
#else
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate> {
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate>
#endif
NSWindow* m_window;
SFOpenGLView* m_oglView;
sf::priv::WindowImplCocoa* m_requester;
sf::VideoMode* m_fullscreenMode; // Note : C++ ctor/dtor are not called for Obj-C fields.
{
NSWindow* m_window; ///< Underlying Cocoa window to be controlled
SFOpenGLView* m_oglView; ///< OpenGL view for rendering
sf::priv::WindowImplCocoa* m_requester; ///< Requester
sf::VideoMode* m_fullscreenMode; ///< Fullscreen mode
/// Note: C++ ctor/dtor are not called for Obj-C fields! Use manual allocation instead.
}
////////////////////////////////////////////////////////////
/// Create the SFML window with an external Cocoa window.
/// \brief Create the SFML window with an external Cocoa window
///
/// \param window Cocoa window to be controlled
///
/// \return an initialized controller
///
////////////////////////////////////////////////////////////
-(id)initWithWindow:(NSWindow*)window;
////////////////////////////////////////////////////////////
/// Create the SFML window "from scratch" (full SFML handling).
/// \brief Create the SFML window "from scratch" (SFML handle everything)
///
/// \param mode Video mode
/// \param style Window's style, as described by sf::Style
///
/// \return an initialized controller
///
////////////////////////////////////////////////////////////
-(id)initWithMode:(sf::VideoMode const &)mode andStyle:(unsigned long)style;
-(id)initWithMode:(const sf::VideoMode&)mode andStyle:(unsigned long)style;
@end

View File

@ -26,33 +26,37 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/Window/VideoMode.hpp>
#include <SFML/Window/WindowHandle.hpp>
#include <SFML/Window/WindowStyle.hpp>
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/System/Err.hpp>
#include <ApplicationServices/ApplicationServices.h>
#import <SFML/Window/OSX/SFWindowController.h>
#import <SFML/Window/OSX/SFApplication.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
#import <SFML/Window/OSX/SFWindow.h>
#import <SFML/Window/OSX/SFWindowController.h>
#import <OpenGL/OpenGL.h>
////////////////////////////////////////////////////////////
/// SFWindowController class : Privates Methods Declaration
/// SFWindowController class: private interface
///
////////////////////////////////////////////////////////////
@interface SFWindowController ()
////////////////////////////////////////////////////////////
/// Retrieves the screen height.
/// \brief Retrieves the screen height
///
/// \return screen height
///
////////////////////////////////////////////////////////////
-(float)screenHeight;
////////////////////////////////////////////////////////////
/// Retrives the title bar height.
/// \brief Retrieves the title bar height
///
/// \return title bar height
///
////////////////////////////////////////////////////////////
-(float)titlebarHeight;
@ -67,32 +71,28 @@
////////////////////////////////////////////////////////
-(id)initWithWindow:(NSWindow*)window
{
if ((self = [super init])) {
if ((self = [super init]))
{
m_requester = 0;
m_fullscreenMode = new sf::VideoMode();
// Retain the window for our own use.
m_window = [window retain];
if (m_window == nil) {
sf::err()
<< "No window was given to initWithWindow:."
<< std::endl;
if (m_window == nil)
{
sf::err() << "No window was given to initWithWindow:." << std::endl;
return self;
}
// Create the view.
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]];
if (m_oglView == nil) {
sf::err()
<< "Could not create an instance of NSOpenGLView "
if (m_oglView == nil)
{
sf::err() << "Could not create an instance of NSOpenGLView "
<< "in (SFWindowController -initWithWindow:)."
<< std::endl;
return self;
}
@ -105,49 +105,56 @@
////////////////////////////////////////////////////////
-(id)initWithMode:(sf::VideoMode const &)mode andStyle:(unsigned long)style
-(id)initWithMode:(const sf::VideoMode&)mode andStyle:(unsigned long)style
{
// If we are not on the main thread we stop here and advice the user.
if ([NSThread currentThread] != [NSThread mainThread]) {
if ([NSThread currentThread] != [NSThread mainThread])
{
/*
* See http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00460.html
* for more information.
*/
sf::err()
<< "Cannot create a window from a worker thread. (OS X limitation)"
<< std::endl;
sf::err() << "Cannot create a window from a worker thread. (OS X limitation)" << std::endl;
return nil;
}
if ((self = [super init])) {
if ((self = [super init]))
{
m_requester = 0;
m_fullscreenMode = new sf::VideoMode();
// Create our window size.
NSRect rect = NSZeroRect;
if (style & sf::Style::Fullscreen && mode != sf::VideoMode::getDesktopMode()) {
if ((style & sf::Style::Fullscreen) && (mode != sf::VideoMode::getDesktopMode()))
{
// We use desktop mode to size the window
// but we set the back buffer size to 'mode' in applyContext method.
*m_fullscreenMode = mode;
sf::VideoMode dm = sf::VideoMode::getDesktopMode();
rect = NSMakeRect(0, 0, dm.width, dm.height);
} else { // no fullscreen requested.
}
else
{
// no fullscreen requested.
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 fullscrean we keep our NSBorderlessWindowMask.
if (!(style & sf::Style::Fullscreen))
{
if (style & sf::Style::Titlebar)
nsStyle |= NSTitledWindowMask | NSMiniaturizableWindowMask;
if (style & sf::Style::Resize) nsStyle |= NSResizableWindowMask;
if (style & sf::Style::Resize)
nsStyle |= NSResizableWindowMask;
if (style & sf::Style::Close) nsStyle |= NSClosableWindowMask;
if (style & sf::Style::Close)
nsStyle |= NSClosableWindowMask;
}
@ -166,9 +173,9 @@
[...]
*/
if (m_window == nil) {
sf::err()
<< "Could not create an instance of NSWindow "
if (m_window == nil)
{
sf::err() << "Could not create an instance of NSWindow "
<< "in (SFWindowController -initWithMode:andStyle:)."
<< std::endl;
@ -176,7 +183,8 @@
}
// Apply special feature for fullscreen window.
if (style & sf::Style::Fullscreen) {
if (style & sf::Style::Fullscreen)
{
// We place the window above everything else.
[m_window setOpaque:YES];
[m_window setHidesOnDeactivate:YES];
@ -195,15 +203,15 @@
*/
}
// Center the window to be cool =)
// Centre the window to be cool =)
[m_window center];
// Create the view.
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]];
if (m_oglView == nil) {
sf::err()
<< "Could not create an instance of NSOpenGLView "
if (m_oglView == nil)
{
sf::err() << "Could not create an instance of NSOpenGLView "
<< "in (SFWindowController -initWithMode:andStyle:)."
<< std::endl;
@ -211,12 +219,14 @@
}
// If a fullscreen window was requested...
if (style & sf::Style::Fullscreen) {
if (style & sf::Style::Fullscreen)
{
/// ... we tell the OpenGL view
[m_oglView enterFullscreen];
// ... and if the resolution is not the default one...
if (mode != sf::VideoMode::getDesktopMode()) {
if (mode != sf::VideoMode::getDesktopMode())
{
// ... we set the "real size" of the view (that is the back buffer size).
[m_oglView setRealSize:NSMakeSize(m_fullscreenMode->width, m_fullscreenMode->height)];
}
@ -291,21 +301,21 @@
-(NSPoint)position
{
// First, get the top left corner of the view in its own base system
NSPoint const origin = [m_oglView frame].origin;
NSSize const size = [m_oglView frame].size;
NSPoint const topLeftCornerOfView = NSMakePoint(origin.x, origin.y + size.height);
NSPoint const positionInView = [m_oglView convertPointToBase:topLeftCornerOfView];
const NSPoint origin = [m_oglView frame].origin;
const NSSize size = [m_oglView frame].size;
const NSPoint topLeftCornerOfView = NSMakePoint(origin.x, origin.y + size.height);
const NSPoint positionInView = [m_oglView convertPointToBase:topLeftCornerOfView];
// Then, convert it to window base system
NSPoint const positionInWindow = [m_oglView convertPoint:positionInView toView:nil];
const NSPoint positionInWindow = [m_oglView convertPoint:positionInView toView:nil];
// here nil denotes the window containing the view
// Next, convert it to the screen base system
NSPoint const positionInScreen = [[m_oglView window] convertBaseToScreen:positionInWindow];
const NSPoint positionInScreen = [[m_oglView window] convertBaseToScreen:positionInWindow];
// Finally, flip for SFML window coordinate system
// Don't forget to discard the title bar !
NSPoint const positionInSFML = NSMakePoint(positionInScreen.x,
const NSPoint positionInSFML = NSMakePoint(positionInScreen.x,
([self screenHeight] - [self titlebarHeight]) - positionInScreen.y);
return positionInSFML;
@ -328,12 +338,11 @@
////////////////////////////////////////////////////////
-(NSSize)size
{
if (*m_fullscreenMode == sf::VideoMode()) {
if (*m_fullscreenMode == sf::VideoMode())
return [m_oglView frame].size;
} else {
else
return NSMakeSize(m_fullscreenMode->width, m_fullscreenMode->height);
}
}
////////////////////////////////////////////////////////
@ -405,7 +414,7 @@
////////////////////////////////////////////////////////
-(void)setIconTo:(unsigned int)width
by:(unsigned int)height
with:(sf::Uint8 const *)pixels
with:(const sf::Uint8*)pixels
{
// Create an empty image representation.
NSBitmapImageRep* bitmap =
@ -425,12 +434,12 @@
#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) {
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];
[bitmap setPixel:pixel atX:x y:y];
}
}
@ -451,23 +460,21 @@
-(void)processEvent
{
// If we are not on the main thread we stop here and advice the user.
if ([NSThread currentThread] != [NSThread mainThread]) {
if ([NSThread currentThread] != [NSThread mainThread])
{
/*
* See http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00460.html
* for more information.
*/
sf::err()
<< "Cannot fetch event from a worker thread. (OS X restriction)"
<< std::endl;
sf::err() << "Cannot fetch event from a worker thread. (OS X restriction)" << std::endl;
return;
}
// If we don't have a requester we don't fetch event.
if (m_requester != 0) {
if (m_requester != 0)
[SFApplication processEvent];
}
}
////////////////////////////////////////////////////////
@ -479,7 +486,8 @@
// If fullscreen was requested and the mode used to create the window
// was not the desktop mode, we change the back buffer size of the
// context.
if (*m_fullscreenMode != sf::VideoMode()) {
if (*m_fullscreenMode != sf::VideoMode())
{
CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj];
GLint dim[2] = {m_fullscreenMode->width, m_fullscreenMode->height};
@ -497,7 +505,8 @@
////////////////////////////////////////////////////////
-(BOOL)windowShouldClose:(id)sender
{
if (m_requester == 0) return YES;
if (m_requester == 0)
return YES;
m_requester->windowClosed();
return NO;
@ -508,28 +517,28 @@
-(void)windowDidBecomeKey:(NSNotification*)notification
{
// Send event.
if (m_requester == 0) return;
if (m_requester == 0)
return;
m_requester->windowGainedFocus();
if (*m_fullscreenMode != sf::VideoMode()) {
if (*m_fullscreenMode != sf::VideoMode())
[m_oglView enterFullscreen];
}
}
////////////////////////////////////////////////////////
-(void)windowDidResignKey:(NSNotification*)notification
{
// Send event.
if (m_requester == 0) return;
if (m_requester == 0)
return;
m_requester->windowLostFocus();
if (*m_fullscreenMode != sf::VideoMode()) {
if (*m_fullscreenMode != sf::VideoMode())
[m_oglView exitFullscreen];
}
}
#pragma mark

View File

@ -50,23 +50,24 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
// Retrieve array of dictionaries representing display modes.
CFArrayRef displayModes = CGDisplayAvailableModes(CGMainDisplayID());
if (displayModes == NULL) {
sf::err() << "Couldn't get VideoMode for main display.";
if (displayModes == NULL)
{
sf::err() << "Couldn't get VideoMode for main display." << std::endl;
return modes;
}
// Loop on each mode and convert it into a sf::VideoMode object.
CFIndex const modesCount = CFArrayGetCount(displayModes);
for (CFIndex i = 0; i < modesCount; i++) {
const CFIndex modesCount = CFArrayGetCount(displayModes);
for (CFIndex i = 0; i < modesCount; i++)
{
CFDictionaryRef dictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(displayModes, i);
VideoMode mode = convertCGModeToSFMode(dictionary);
// If not yet listed we add it to our modes array.
if (std::find(modes.begin(), modes.end(), mode) == modes.end()) {
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
modes.push_back(mode);
}
}
return modes;
@ -77,23 +78,24 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
// Retrieve all modes available for main screen only.
CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
if (cgmodes == NULL) {
sf::err() << "Couldn't get VideoMode for main display.";
if (cgmodes == NULL)
{
sf::err() << "Couldn't get VideoMode for main display." << std::endl;
return modes;
}
// Loop on each mode and convert it into a sf::VideoMode object.
CFIndex const modesCount = CFArrayGetCount(cgmodes);
for (CFIndex i = 0; i < modesCount; i++) {
const CFIndex modesCount = CFArrayGetCount(cgmodes);
for (CFIndex i = 0; i < modesCount; i++)
{
CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
VideoMode mode = convertCGModeToSFMode(cgmode);
// If not yet listed we add it to our modes array.
if (std::find(modes.begin(), modes.end(), mode) == modes.end()) {
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
modes.push_back(mode);
}
}
// Clean up memory.
CFRelease(cgmodes);

View File

@ -34,7 +34,7 @@
#include <SFML/System/String.hpp>
////////////////////////////////////////////////////////////
/// Predefine OBJC classes
/// Predefine OBJ-C classes
////////////////////////////////////////////////////////////
#ifdef __OBJC__
@ -77,7 +77,7 @@ public :
///
/// \param mode Video mode to use
/// \param title Title of the window
/// \param style Window style (resizable, fixed, or fullscren)
/// \param style Window style (resizeable, fixed, or fullscren)
/// \param settings Additional settings for the underlying OpenGL context
///
////////////////////////////////////////////////////////////
@ -90,7 +90,7 @@ public :
~WindowImplCocoa();
////////////////////////////////////////////////////////////
/// \brief Window Closed Event called by the cocoa window object.
/// \brief Window Closed Event called by the cocoa window object
///
/// Send the event to SFML WindowImpl class.
///
@ -98,18 +98,18 @@ public :
void windowClosed(void);
////////////////////////////////////////////////////////////
/// \brief Window Resized Event called by the cocoa window object.
/// \brief Window Resized Event called by the cocoa window object
///
/// Send the event to SFML WindowImpl class.
///
/// \param width
/// \param height
/// \param width new width
/// \param height new height
///
////////////////////////////////////////////////////////////
void windowResized(unsigned int width, unsigned int height);
////////////////////////////////////////////////////////////
/// \brief Window Lost Focus Event called by the cocoa window object.
/// \brief Window Lost Focus Event called by the cocoa window object
///
/// Send the event to SFML WindowImpl class.
///
@ -117,7 +117,7 @@ public :
void windowLostFocus(void);
////////////////////////////////////////////////////////////
/// \brief Window Get Focus Event called by the cocoa window object.
/// \brief Window Get Focus Event called by the cocoa window object
///
/// Send the event to SFML WindowImpl class.
///
@ -125,54 +125,54 @@ public :
void windowGainedFocus(void);
////////////////////////////////////////////////////////////
/// \brief Mouse Down Event called by the cocoa view object.
/// \brief Mouse Down Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param button
/// \param x
/// \param y
/// \param button active button
/// \param x mouse x position
/// \param y mouse y position
///
////////////////////////////////////////////////////////////
void mouseDownAt(Mouse::Button button, int x, int y);
////////////////////////////////////////////////////////////
/// \brief Mouse Up Event called by the cocoa view object.
/// \brief Mouse Up Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param button
/// \param x
/// \param y
/// \param button active button
/// \param x mouse x position
/// \param y mouse y position
///
////////////////////////////////////////////////////////////
void mouseUpAt(Mouse::Button button, int x, int y);
////////////////////////////////////////////////////////////
/// \brief Mouse Moved Event called by the cocoa view object.
/// \brief Mouse Moved Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param x
/// \param y
/// \param x mouse x position
/// \param y mouse y position
///
////////////////////////////////////////////////////////////
void mouseMovedAt(int x, int y);
////////////////////////////////////////////////////////////
/// \brief Mouse Wheel Scrolled Event called by the cocoa view object.
/// \brief Mouse Wheel Scrolled Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param delta
/// \param x
/// \param y
/// \param delta scrolling delta
/// \param x mouse x position
/// \param y mouse y position
///
////////////////////////////////////////////////////////////
void mouseWheelScrolledAt(float delta, int x, int y);
////////////////////////////////////////////////////////////
/// \brief Mouse In Event called by the cocoa view object.
/// \brief Mouse In Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
@ -180,7 +180,7 @@ public :
void mouseMovedIn(void);
////////////////////////////////////////////////////////////
/// \brief Mouse Out Event called by the cocoa view object.
/// \brief Mouse Out Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
@ -188,37 +188,37 @@ public :
void mouseMovedOut(void);
////////////////////////////////////////////////////////////
/// \brief Key Down Event called by the cocoa view object.
/// \brief Key Down Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param key
/// \param key active key
///
////////////////////////////////////////////////////////////
void keyDown(Event::KeyEvent key);
////////////////////////////////////////////////////////////
/// \brief Key Up Event called by the cocoa view object.
/// \brief Key Up Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param key
/// \param key active key
///
////////////////////////////////////////////////////////////
void keyUp(Event::KeyEvent key);
////////////////////////////////////////////////////////////
/// \brief Text Entred Event called by the cocoa view object.
/// \brief Text Entred Event called by the cocoa view object
///
/// Send the event to SFML WindowImpl class.
///
/// \param charcode Input unicode
/// \param charcode Unicode input
///
////////////////////////////////////////////////////////////
void textEntered(unichar charcode);
////////////////////////////////////////////////////////////
/// \brief Apply the context to the view.
/// \brief Apply the context to the view
///
/// Called by the SFML context object to finalize its creation.
///
@ -228,7 +228,9 @@ public :
void applyContext(NSOpenGLContextRef context) const;
////////////////////////////////////////////////////////////
/// \brief Change the type of the current process to become a full GUI app.
/// \brief Change the type of the current process
///
/// The type of the process is changed to become a full GUI app.
/// Also ensure NSApp is constructed.
///
////////////////////////////////////////////////////////////

View File

@ -30,13 +30,13 @@
#include <SFML/System/Err.hpp>
#include <SFML/System/String.hpp>
#import <SFML/Window/OSX/SFWindowController.h>
#import <SFML/Window/OSX/SFViewController.h>
#import <SFML/Window/OSX/cpp_objc_conversion.h>
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
#import <SFML/Window/OSX/cpp_objc_conversion.h>
#import <SFML/Window/OSX/SFApplication.h>
#import <SFML/Window/OSX/SFApplicationDelegate.h>
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
#import <SFML/Window/OSX/SFViewController.h>
#import <SFML/Window/OSX/SFWindowController.h>
namespace sf
{
@ -47,28 +47,28 @@ namespace priv
#pragma mark WindowImplCocoa's ctor/dtor
////////////////////////////////////////////////////////////
WindowImplCocoa::WindowImplCocoa(WindowHandle handle)
: m_showCursor(true)
WindowImplCocoa::WindowImplCocoa(WindowHandle handle) :
m_showCursor(true)
{
// Ask for a pool.
retainPool();
// Treat the handle as it real type
id nsHandle = (id)handle;
if ([nsHandle isKindOfClass:[NSWindow class]]) {
if ([nsHandle isKindOfClass:[NSWindow class]])
{
// We have a window.
m_delegate = [[SFWindowController alloc] initWithWindow:nsHandle];
} else if ([nsHandle isKindOfClass:[NSView class]]) {
}
else if ([nsHandle isKindOfClass:[NSView class]])
{
// We have a view.
m_delegate = [[SFViewController alloc] initWithView:nsHandle];
}
else
{
} else {
sf::err()
<< "Cannot import this Window Handle because it is neither "
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]
@ -89,8 +89,8 @@ WindowImplCocoa::WindowImplCocoa(WindowHandle handle)
WindowImplCocoa::WindowImplCocoa(VideoMode mode,
const String& title,
unsigned long style,
const ContextSettings& /*settings*/)
: m_showCursor(true)
const ContextSettings& /*settings*/) :
m_showCursor(true)
{
// Transform the app process.
setUpProcess();
@ -116,9 +116,8 @@ WindowImplCocoa::~WindowImplCocoa()
// Put the next window in front, if any.
NSArray* windows = [NSApp orderedWindows];
if ([windows count] > 0) {
if ([windows count] > 0)
[[windows objectAtIndex:0] makeKeyAndOrderFront:nil];
}
releasePool();
@ -140,21 +139,22 @@ void WindowImplCocoa::setUpProcess(void)
{
static bool isTheProcessSetAsApplication = false;
if (!isTheProcessSetAsApplication) {
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)) {
if (!GetCurrentProcess(&psn))
{
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
}
// Register an application delegate if there is none
if (![[SFApplication sharedApplication] delegate]) {
if (![[SFApplication sharedApplication] delegate])
[NSApp setDelegate:[[SFApplicationDelegate alloc] init]];
}
// Create menus for the application (before finishing launching!)
[SFApplication setUpMenuBar];
@ -196,9 +196,8 @@ void WindowImplCocoa::windowResized(unsigned int width, unsigned int height)
////////////////////////////////////////////////////////////
void WindowImplCocoa::windowLostFocus(void)
{
if (!m_showCursor) {
[m_delegate showMouseCursor]; // Make sur the cursor is visible
}
if (!m_showCursor)
[m_delegate showMouseCursor]; // Make sure the cursor is visible
Event event;
event.type = Event::LostFocus;
@ -210,9 +209,8 @@ void WindowImplCocoa::windowLostFocus(void)
////////////////////////////////////////////////////////////
void WindowImplCocoa::windowGainedFocus(void)
{
if (!m_showCursor) {
if (!m_showCursor)
[m_delegate hideMouseCursor]; // Restore user's setting
}
Event event;
event.type = Event::GainedFocus;
@ -276,9 +274,8 @@ void WindowImplCocoa::mouseWheelScrolledAt(float delta, int x, int y)
////////////////////////////////////////////////////////////
void WindowImplCocoa::mouseMovedIn(void)
{
if (!m_showCursor) {
if (!m_showCursor)
[m_delegate hideMouseCursor]; // Restore user's setting
}
Event event;
event.type = Event::MouseEntered;
@ -289,9 +286,8 @@ void WindowImplCocoa::mouseMovedIn(void)
////////////////////////////////////////////////////////////
void WindowImplCocoa::mouseMovedOut(void)
{
if (!m_showCursor) {
[m_delegate showMouseCursor]; // Make sur the cursor is visible
}
if (!m_showCursor)
[m_delegate showMouseCursor]; // Make sure the cursor is visible
Event event;
event.type = Event::MouseLeft;
@ -403,12 +399,11 @@ void WindowImplCocoa::setIcon(unsigned int width, unsigned int height, const Uin
////////////////////////////////////////////////////////////
void WindowImplCocoa::setVisible(bool visible)
{
if (visible) {
if (visible)
[m_delegate showWindow];
} else {
else
[m_delegate hideWindow];
}
}
////////////////////////////////////////////////////////////
@ -416,23 +411,21 @@ void WindowImplCocoa::setMouseCursorVisible(bool visible)
{
m_showCursor = visible;
if (m_showCursor) {
if (m_showCursor)
[m_delegate showMouseCursor];
} else {
else
[m_delegate hideMouseCursor];
}
}
////////////////////////////////////////////////////////////
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
{
if (enabled) {
if (enabled)
[m_delegate enableKeyRepeat];
} else {
else
[m_delegate disableKeyRepeat];
}
}
} // namespace priv

View File

@ -26,8 +26,8 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/WindowHandle.hpp>
#include <SFML/Config.hpp> // for sf::Uint8
#include <SFML/Window/WindowHandle.hpp>
#import <AppKit/AppKit.h>
@ -38,8 +38,7 @@ namespace sf {
}
////////////////////////////////////////////////////////////
/// This protocol defines the interface of the delegate of
/// the window implementation.
/// \brief Interface of the delegate of the window implementation
///
/// We don't create an interface here because Obj-C doesn't allow
/// multiple inheritance (SFViewController and SFWindowController
@ -68,90 +67,133 @@ namespace sf {
@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.)
/// \brief Set the WindowImpl who requested this delegate
///
////////////////////////////////////////////////////////////
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester;
////////////////////////////////////////////////////////////
/// Return the main view or window.
/// \brief Get the underlying OS specific handle
///
/// \return Return the main view or window.
///
////////////////////////////////////////////////////////////
-(sf::WindowHandle)getSystemHandle;
////////////////////////////////////////////////////////////
/// Hide or show the mouse cursor.
/// \brief Hide the mouse cursor
///
////////////////////////////////////////////////////////////
-(void)hideMouseCursor;
////////////////////////////////////////////////////////////
/// \brief Show the mouse cursor
///
////////////////////////////////////////////////////////////
-(void)showMouseCursor;
////////////////////////////////////////////////////////////
/// Get window's position.
/// \brief Get window position
///
/// \return Top left corner of the window or view
///
////////////////////////////////////////////////////////////
-(NSPoint)position;
////////////////////////////////////////////////////////////
/// Move the window (not the view if we handle not a window) (SFML Coordinates).
/// \brief Move the window
///
/// Doesn't apply if the implementation is 'only' a view.
///
/// \param x x position in SFML coordinates
/// \param y y position in SFML coordinates
///
////////////////////////////////////////////////////////////
-(void)setWindowPositionToX:(int)x Y:(int)y;
////////////////////////////////////////////////////////////
/// Get window's size.
/// \brief Get window/view's size
///
/// \return the size of the rendering area
///
////////////////////////////////////////////////////////////
-(NSSize)size;
////////////////////////////////////////////////////////////
/// Resize the window/view.
/// \brief Resize the window/view
///
/// \param width new width
/// \param height new height
///
////////////////////////////////////////////////////////////
-(void)resizeTo:(unsigned int)width by:(unsigned int)height;
////////////////////////////////////////////////////////////
/// Set the title (does nothing if we manage a view).
/// \brief Set the window's title
///
/// Doesn't apply if the implementation is 'only' a view.
///
/// \param title new title
///
////////////////////////////////////////////////////////////
-(void)changeTitle:(NSString*)title;
////////////////////////////////////////////////////////////
/// Hide or show the window (does nothing if we manage a view).
/// \brief Hide the window
///
/// Doesn't apply if the implementation is 'only' a view.
///
////////////////////////////////////////////////////////////
-(void)hideWindow;
////////////////////////////////////////////////////////////
/// \brief Show the window
///
/// Doesn't apply if the implementation is 'only' a view.
///
////////////////////////////////////////////////////////////
-(void)showWindow;
////////////////////////////////////////////////////////////
/// Close the window (does nothing if we manage a view).
/// \brief Close the window
///
/// Doesn't apply if the implementation is 'only' a view.
///
////////////////////////////////////////////////////////////
-(void)closeWindow;
////////////////////////////////////////////////////////////
/// Enable or disable key repeat.
/// \brief Enable key repeat
///
////////////////////////////////////////////////////////////
-(void)enableKeyRepeat;
////////////////////////////////////////////////////////////
/// \brief Disable key repeat
///
////////////////////////////////////////////////////////////
-(void)disableKeyRepeat;
////////////////////////////////////////////////////////////
/// Set an icon to the application.
/// \brief Set an icon to the application
///
/// \param width icon's width
/// \param height icon's height
/// \param pixels icon's data
///
////////////////////////////////////////////////////////////
-(void)setIconTo:(unsigned int)width by:(unsigned int)height with:(sf::Uint8 const*)pixels;
-(void)setIconTo:(unsigned int)width by:(unsigned int)height with:(const sf::Uint8*)pixels;
////////////////////////////////////////////////////////////
/// Fetch new event
/// \brief Fetch new event
///
////////////////////////////////////////////////////////////
-(void)processEvent;
////////////////////////////////////////////////////////////
/// Apply a given context to an OpenGL view.
/// \brief Apply a given context to an OpenGL view
///
/// \param context OpenGL context to attach to the OpenGL view
///
////////////////////////////////////////////////////////////
-(void)applyContext:(NSOpenGLContext*)context;

View File

@ -42,20 +42,13 @@ size_t modeBitsPerPixel(CGDisplayModeRef mode)
// Compare encoding.
CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
bpp = 32;
} else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
bpp = 16;
} else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
bpp = 8;
}
// Clean up memory.
CFRelease(pixEnc);
@ -78,7 +71,7 @@ size_t displayBitsPerPixel(CGDirectDisplayID displayId)
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
// Get bpp for the mode.
size_t const bpp = modeBitsPerPixel(mode);
const size_t bpp = modeBitsPerPixel(mode);
// Clean up Memory.
CGDisplayModeRelease(mode);
@ -146,31 +139,30 @@ CGDisplayModeRef convertSFModeToCGMode(VideoMode sfmode)
// Retrieve all modes available for main screen only.
CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
if (cgmodes == NULL) { // Should not happen but anyway...
if (cgmodes == NULL) // Should not happen but anyway...
{
sf::err() << "Couldn't get VideoMode for main display.";
return NULL;
}
// Loop on each mode and convert it into a sf::VideoMode object.
CFIndex const modesCount = CFArrayGetCount(cgmodes);
for (CFIndex i = 0; i < modesCount; i++) {
const CFIndex modesCount = CFArrayGetCount(cgmodes);
for (CFIndex i = 0; i < modesCount; i++)
{
CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
VideoMode mode = convertCGModeToSFMode(cgmode);
if (mode == sfmode) {
if (mode == sfmode)
cgbestMode = cgmode;
}
}
// Clean up memory.
CFRelease(cgmodes);
if (cgbestMode == NULL) {
sf::err()
<< "Couldn't convert the given sf:VideoMode into a CGDisplayMode."
if (cgbestMode == NULL)
sf::err() << "Couldn't convert the given sf:VideoMode into a CGDisplayMode."
<< std::endl;
}
return cgbestMode;
}

View File

@ -37,7 +37,7 @@ namespace sf
namespace priv
{
////////////////////////////////////////////////////////////
/// \brief Get bpp of a video mode for OS 10.6 or later.
/// \brief Get bpp of a video mode for OS 10.6 or later
///
/// With OS 10.6 and later, Quartz doesn't use anymore dictionaries
/// to represent video mode. Instead it uses a CGDisplayMode opaque type.
@ -48,7 +48,7 @@ size_t modeBitsPerPixel(CGDisplayModeRef mode);
#endif
////////////////////////////////////////////////////////////
/// \brief Get bpp for all OS X version.
/// \brief Get bpp for all OS X version
///
/// This function use only non-deprecated way to get the
/// display bits per pixel information for a given display id.
@ -57,7 +57,7 @@ size_t modeBitsPerPixel(CGDisplayModeRef mode);
size_t displayBitsPerPixel(CGDirectDisplayID displayId);
////////////////////////////////////////////////////////////
/// \brief Convert a Quartz video mode into a sf::VideoMode object.
/// \brief Convert a Quartz video mode into a sf::VideoMode object
///
////////////////////////////////////////////////////////////
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
@ -67,7 +67,7 @@ VideoMode convertCGModeToSFMode(CGDisplayModeRef cgmode);
#endif
////////////////////////////////////////////////////////////
/// \brief Convert a sf::VideoMode object into a Quartz video mode.
/// \brief Convert a sf::VideoMode object into a Quartz video mode
///
////////////////////////////////////////////////////////////
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060

View File

@ -26,14 +26,19 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
#include <string>
#include <SFML/System/String.hpp>
#include <string>
#import <Foundation/Foundation.h>
////////////////////////////////////////////////////////////
/// \brief Returns a NSString construct with +stringWithCString:encoding:.
/// \brief Returns a NSString construct with +stringWithCString:encoding:
///
////////////////////////////////////////////////////////////
NSString* stringToNSString(std::string const& string);
NSString* sfStringToNSString(sf::String const& string);
NSString* stringToNSString(const std::string& string);
////////////////////////////////////////////////////////////
/// \brief Returns a NSString construct with +stringWithCString:encoding:
///
////////////////////////////////////////////////////////////
NSString* sfStringToNSString(const sf::String& string);

View File

@ -28,11 +28,11 @@
////////////////////////////////////////////////////////////
#include <SFML/System/Utf.hpp>
#import <Foundation/Foundation.h>
#import <SFML/Window/OSX/cpp_objc_conversion.h>
#import <Foundation/Foundation.h>
////////////////////////////////////////////////////////////
NSString* stringToNSString(std::string const& string)
NSString* stringToNSString(const std::string& string)
{
std::string utf8; utf8.reserve(string.size() + 1);
sf::Utf8::fromAnsi(string.begin(), string.end(), std::back_inserter(utf8));
@ -42,7 +42,7 @@ NSString* stringToNSString(std::string const& string)
}
////////////////////////////////////////////////////////////
NSString* sfStringToNSString(sf::String const& string)
NSString* sfStringToNSString(const sf::String& string)
{
sf::Uint32 length = string.getSize() * sizeof(sf::Uint32);
const void* data = reinterpret_cast<const void*>(string.getData());