Improved coding style of OS X implementation
And fixed some typos.
This commit is contained in:
parent
2204838384
commit
b868833191
@ -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.
|
||||
///
|
||||
|
@ -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>
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -42,8 +42,8 @@
|
||||
/// Because NSAutoreleasePool cannot be retain we have to do it ourself.
|
||||
/// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread.
|
||||
///
|
||||
/// SPECIAL CONSIDERATION :
|
||||
/// =======================
|
||||
/// 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 :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -95,15 +96,15 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
int m_count; ///< How many times was the pool retained ?
|
||||
int m_count; ///< How many times was the pool retained?
|
||||
NSAutoreleasePool* m_pool; ///< Our dedicated pool
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
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,9 +166,8 @@ void PoolWrapper::drain()
|
||||
[m_pool drain];
|
||||
m_pool = 0;
|
||||
|
||||
if (m_count != 0) {
|
||||
if (m_count != 0)
|
||||
m_pool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -60,18 +60,16 @@ long HIDInputManager::getLocationID(IOHIDDeviceRef device)
|
||||
{
|
||||
long loc = 0;
|
||||
|
||||
// Get a unique ID : its usb location ID
|
||||
// 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,32 +234,32 @@ 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;
|
||||
}
|
||||
|
||||
// How many elements are there ?
|
||||
// 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,29 +273,30 @@ 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;
|
||||
}
|
||||
|
||||
// How many elements are there ?
|
||||
// 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;
|
||||
@ -408,10 +404,11 @@ void HIDInputManager::loadButton(IOHIDElementRef button)
|
||||
UInt32 usage = IOHIDElementGetUsage(button);
|
||||
Mouse::Button dest = Mouse::ButtonCount;
|
||||
|
||||
// Extends kHIDUsage_Button_* enum with :
|
||||
// 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);
|
||||
// Do not release m_layout ! It is owned by m_layoutData.
|
||||
if (m_manager != 0) CFRelease(m_manager);
|
||||
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);
|
||||
|
||||
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 ?
|
||||
// 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;
|
||||
|
@ -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,14 +123,15 @@ void HIDJoystickManager::update()
|
||||
{
|
||||
SInt32 status = kCFRunLoopRunHandledSource;
|
||||
|
||||
while (status == kCFRunLoopRunHandledSource) {
|
||||
while (status == kCFRunLoopRunHandledSource)
|
||||
{
|
||||
status = CFRunLoopRunInMode(RunLoopMode, 0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void HIDJoystickManager::pluggedIn(void * context, IOReturn, void *, IOHIDDeviceRef)
|
||||
void HIDJoystickManager::pluggedIn(void* context, IOReturn, void*, IOHIDDeviceRef)
|
||||
{
|
||||
HIDJoystickManager* manager = (HIDJoystickManager*)context;
|
||||
manager->m_joystickCount++;
|
||||
@ -138,7 +139,7 @@ void HIDJoystickManager::pluggedIn(void * context, IOReturn, void *, IOHIDDevice
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void HIDJoystickManager::pluggedOut(void * context, IOReturn, void *, IOHIDDeviceRef)
|
||||
void HIDJoystickManager::pluggedOut(void* context, IOReturn, void*, IOHIDDeviceRef)
|
||||
{
|
||||
HIDJoystickManager* manager = (HIDJoystickManager*)context;
|
||||
manager->m_joystickCount--;
|
||||
|
@ -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,19 +98,19 @@ private :
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Private "plug-in" callback
|
||||
/// \note Only 'context' parametre is used.
|
||||
/// \note Only 'context' parameter is used.
|
||||
/// \see IOHIDDeviceCallback
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void pluggedIn(void * context, IOReturn, void *, IOHIDDeviceRef);
|
||||
static void pluggedIn(void* context, IOReturn, void*, IOHIDDeviceRef);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Private "plug-out" callback
|
||||
/// \note Only 'context' parametre is used.
|
||||
/// \note Only 'context' parameter is used.
|
||||
/// \see IOHIDDeviceCallback
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void pluggedOut(void * context, IOReturn, void *, IOHIDDeviceRef);
|
||||
static void pluggedOut(void* context, IOReturn, void*, IOHIDDeviceRef);
|
||||
|
||||
private :
|
||||
|
||||
|
@ -26,20 +26,20 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
/// we use the HID manager. Mouse position is handled differently.
|
||||
///
|
||||
/// NB : we probably could use
|
||||
/// NB: we probably could use
|
||||
/// NSEvent +addGlobalMonitorForEventsMatchingMask:handler: for mouse only.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -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]]) {
|
||||
view = (SFOpenGLView *)subview;
|
||||
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);
|
||||
|
@ -66,60 +66,63 @@ void JoystickImpl::cleanup()
|
||||
////////////////////////////////////////////////////////////
|
||||
bool JoystickImpl::isConnected(unsigned int index)
|
||||
{
|
||||
bool state = false; // Is the index-th joystick connected ?
|
||||
bool state = false; // Is the index-th joystick connected?
|
||||
|
||||
// First, let's check if the device was previously detected :
|
||||
|
||||
if (m_locationIDs[index] != 0) {
|
||||
// First, let's check if the device was previously detected:
|
||||
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,68 +181,48 @@ 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;
|
||||
}
|
||||
|
||||
// How many elements are there ?
|
||||
// How many elements are there?
|
||||
CFIndex elementsCount = CFArrayGetCount(elements);
|
||||
|
||||
if (elementsCount == 0) {
|
||||
// What is a joystick with no element ?
|
||||
if (elementsCount == 0)
|
||||
{
|
||||
// What is a joystick with no element?
|
||||
CFRelease(elements);
|
||||
CFRelease(devices);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
// kHIDUsage_GD_Vx, kHIDUsage_GD_Vy, kHIDUsage_GD_Vz are ignored.
|
||||
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
|
||||
@ -295,10 +275,10 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
||||
{
|
||||
JoystickCaps caps;
|
||||
|
||||
// Buttons :
|
||||
// Buttons:
|
||||
caps.buttonCount = m_buttons.size();
|
||||
|
||||
// Axis :
|
||||
// Axis:
|
||||
for (AxisMap::const_iterator it(m_axis.begin()); it != m_axis.end(); ++it) {
|
||||
caps.axes[it->first] = true;
|
||||
}
|
||||
@ -321,17 +301,16 @@ JoystickState JoystickImpl::update()
|
||||
JoystickState state; // otherwise return that
|
||||
state.connected = true;
|
||||
|
||||
// Note : free up is done in close() which is called, if required,
|
||||
// by the joystick manager. So we don't release buttons nor axes here.
|
||||
// Note: free up is done in close() which is called, if required,
|
||||
// by the joystick manager. So we don't release buttons nor axes here.
|
||||
|
||||
// First, let's determine if the joystick is still connected
|
||||
Location selfLoc = m_locationIDs[m_index];
|
||||
|
||||
// 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,23 +332,21 @@ 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) {
|
||||
// No value ? Hum... Seems like the joystick is gone
|
||||
if (!value)
|
||||
{
|
||||
// No value? Hum... Seems like the joystick is gone
|
||||
return disconnectedState;
|
||||
}
|
||||
|
||||
@ -376,19 +355,21 @@ 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) {
|
||||
// No value ? Hum... Seems like the joystick is gone
|
||||
if (!value)
|
||||
{
|
||||
// No value? Hum... Seems like the joystick is gone
|
||||
return disconnectedState;
|
||||
}
|
||||
|
||||
// We want to bind [physicalMin,physicalMax] to [-100=min,100=max].
|
||||
//
|
||||
// General formula to bind [a,b] to [c,d] with a linear progression :
|
||||
// General formula to bind [a,b] to [c,d] with a linear progression:
|
||||
//
|
||||
// f : [a, b] -> [c, d]
|
||||
// x |-> (x-a)(d-c)/(b-a)+c
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -26,8 +26,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Event processing & Menu bar initialisation
|
||||
@ -55,8 +55,9 @@
|
||||
///
|
||||
/// This overload of -[NSApplication sendEvent:] is used to
|
||||
/// fix KeyRelease events when the command key is down.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
-(void)sendEvent:(NSEvent *)anEvent;
|
||||
-(void)sendEvent:(NSEvent*)anEvent;
|
||||
|
||||
|
||||
@end
|
||||
|
@ -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];
|
||||
|
||||
@ -79,7 +80,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
+(NSMenu *)createAppleMenu
|
||||
+(NSMenu*)createAppleMenu
|
||||
{
|
||||
// Apple menu is as follow:
|
||||
//
|
||||
@ -158,7 +159,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
+(NSMenu *)createFileMenu
|
||||
+(NSMenu*)createFileMenu
|
||||
{
|
||||
// The File menu is as follow:
|
||||
//
|
||||
@ -180,7 +181,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
+(NSMenu *)createWindowMenu
|
||||
+(NSMenu*)createWindowMenu
|
||||
{
|
||||
// The Window menu is as follow:
|
||||
//
|
||||
@ -218,20 +219,18 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
+(NSString *)applicationName
|
||||
+(NSString*)applicationName
|
||||
{
|
||||
// First, try localized name
|
||||
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];
|
||||
|
@ -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>
|
||||
|
||||
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
|
||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication;
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
|
@ -33,7 +33,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
||||
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
|
||||
{
|
||||
// TODO generate close event for each SFML window
|
||||
[NSApp makeWindowsPerform:@selector(sfClose) inOrder:NO];
|
||||
@ -42,7 +42,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
|
||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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,51 +71,75 @@ 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;
|
||||
-(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;
|
||||
-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil;
|
||||
|
||||
@end
|
||||
|
@ -30,62 +30,74 @@
|
||||
#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);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// SFOpenGLView class : Privates Methods Declaration
|
||||
/// SFOpenGLView class: Privates Methods Declaration
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
@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;
|
||||
-(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;
|
||||
@ -155,7 +166,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
|
||||
{
|
||||
m_requester = requester;
|
||||
}
|
||||
@ -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,11 +275,10 @@ 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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -316,7 +324,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseDown:(NSEvent *)theEvent
|
||||
-(void)mouseDown:(NSEvent*)theEvent
|
||||
{
|
||||
// Forward to...
|
||||
[self otherMouseDown:theEvent];
|
||||
@ -327,7 +335,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseUp:(NSEvent *)theEvent
|
||||
-(void)mouseUp:(NSEvent*)theEvent
|
||||
{
|
||||
// Forward to...
|
||||
[self otherMouseUp:theEvent];
|
||||
@ -338,7 +346,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseMoved:(NSEvent *)theEvent
|
||||
-(void)mouseMoved:(NSEvent*)theEvent
|
||||
{
|
||||
// Forward to...
|
||||
[self otherMouseDragged:theEvent];
|
||||
@ -349,11 +357,11 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)scrollWheel:(NSEvent *)theEvent
|
||||
-(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);
|
||||
}
|
||||
|
||||
@ -363,46 +371,46 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseEntered:(NSEvent *)theEvent
|
||||
-(void)mouseEntered:(NSEvent*)theEvent
|
||||
{
|
||||
// There are two cases when we need to fire an 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
|
||||
-(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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)rightMouseDown:(NSEvent *)theEvent
|
||||
-(void)rightMouseDown:(NSEvent*)theEvent
|
||||
{
|
||||
// Forward to...
|
||||
[self otherMouseDown:theEvent];
|
||||
@ -413,7 +421,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)rightMouseUp:(NSEvent *)theEvent
|
||||
-(void)rightMouseUp:(NSEvent*)theEvent
|
||||
{
|
||||
// Forward to...
|
||||
[self otherMouseUp:theEvent];
|
||||
@ -424,20 +432,21 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)otherMouseDown:(NSEvent *)theEvent
|
||||
-(void)otherMouseDown:(NSEvent*)theEvent
|
||||
{
|
||||
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];
|
||||
}
|
||||
@ -445,20 +454,21 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)otherMouseUp:(NSEvent *)theEvent
|
||||
-(void)otherMouseUp:(NSEvent*)theEvent
|
||||
{
|
||||
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];
|
||||
}
|
||||
@ -466,7 +476,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)rightMouseDragged:(NSEvent *)theEvent
|
||||
-(void)rightMouseDragged:(NSEvent*)theEvent
|
||||
{
|
||||
// Forward to...
|
||||
[self otherMouseDragged:theEvent];
|
||||
@ -477,7 +487,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)mouseDragged:(NSEvent *)theEvent
|
||||
-(void)mouseDragged:(NSEvent*)theEvent
|
||||
{
|
||||
// Forward to...
|
||||
[self otherMouseDragged:theEvent];
|
||||
@ -488,23 +498,24 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)otherMouseDragged:(NSEvent *)theEvent
|
||||
-(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];
|
||||
}
|
||||
@ -512,14 +523,17 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(NSPoint)cursorPositionFromEvent:(NSEvent *)eventOrNil
|
||||
-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil
|
||||
{
|
||||
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;
|
||||
@ -538,9 +553,10 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(sf::Mouse::Button)mouseButtonFromEvent:(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;
|
||||
@ -556,29 +572,32 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)keyDown:(NSEvent *)theEvent
|
||||
-(void)keyDown:(NSEvent*)theEvent
|
||||
{
|
||||
// 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:@""];
|
||||
@ -619,7 +640,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)sfKeyUp:(NSEvent *)theEvent
|
||||
-(void)sfKeyUp:(NSEvent*)theEvent
|
||||
{
|
||||
// For some mystic reasons, key released events don't work the same way
|
||||
// as key pressed events... We somewhat hijack the event chain of response
|
||||
@ -631,23 +652,24 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)flagsChanged:(NSEvent *)theEvent
|
||||
-(void)flagsChanged:(NSEvent*)theEvent
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
-(id)initWithView:(NSView *)view;
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Initialize the view controller
|
||||
///
|
||||
/// \param view view to be controlled
|
||||
///
|
||||
/// \return an initialized view controller
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
-(id)initWithView:(NSView*)view;
|
||||
|
||||
@end
|
||||
|
@ -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,12 +58,11 @@
|
||||
frame.origin.y = 0;
|
||||
m_oglView = [[SFOpenGLView alloc] initWithFrame:frame];
|
||||
|
||||
if (m_oglView == nil) {
|
||||
|
||||
sf::err()
|
||||
<< "Could not create an instance of NSOpenGLView "
|
||||
<< "in (SFViewController -initWithView:)."
|
||||
<< std::endl;
|
||||
if (m_oglView == nil)
|
||||
{
|
||||
sf::err() << "Could not create an instance of NSOpenGLView "
|
||||
<< "in (SFViewController -initWithView:)."
|
||||
<< std::endl;
|
||||
|
||||
return self;
|
||||
}
|
||||
@ -92,7 +90,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
|
||||
{
|
||||
// Forward to the view.
|
||||
[m_oglView setRequesterTo:requester];
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -157,7 +155,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)changeTitle:(NSString *)title
|
||||
-(void)changeTitle:(NSString*)title
|
||||
{
|
||||
sf::err() << "Cannot change the title of the SFML area when SFML is integrated in a NSView." << 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,27 +209,25 @@
|
||||
-(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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)applyContext:(NSOpenGLContext *)context
|
||||
-(void)applyContext:(NSOpenGLContext*)context
|
||||
{
|
||||
[m_oglView setOpenGLContext:context];
|
||||
[context setView:m_oglView];
|
||||
|
@ -29,36 +29,57 @@
|
||||
#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;
|
||||
-(void)keyDown:(NSEvent*)theEvent;
|
||||
|
||||
@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;
|
||||
|
@ -26,7 +26,7 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
// Headers
|
||||
////////////////////////////////////////////////////////////
|
||||
#import "SFWindow.h"
|
||||
#import <SFML/Window/OSX/SFWindow.h>
|
||||
|
||||
|
||||
@implementation SFWindow
|
||||
@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)keyDown:(NSEvent *)theEvent
|
||||
-(void)keyDown:(NSEvent*)theEvent
|
||||
{
|
||||
// Do nothing except preventing a system alert each time a key is pressed
|
||||
//
|
||||
@ -54,7 +54,7 @@
|
||||
// -----------------------
|
||||
// Consider overriding NSResponder -keyDown: message in a Cocoa view/window
|
||||
// that contains a SFML rendering area. Doing so will prevent a system
|
||||
// alert to be thrown everytime the user presses a key.
|
||||
// alert to be thrown every time the user presses a key.
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
-(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
|
||||
|
@ -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;
|
||||
@ -65,34 +69,30 @@
|
||||
#pragma mark SFWindowController's methods
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(id)initWithWindow:(NSWindow *)window
|
||||
-(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 "
|
||||
<< "in (SFWindowController -initWithWindow:)."
|
||||
<< std::endl;
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
@ -162,21 +169,22 @@
|
||||
|
||||
[...]
|
||||
As best as I can figure, this is happening because the NSWindow (and
|
||||
hence my view) are not visible onscreen yet, and the system doesn't like that.
|
||||
hence my view) are not visible on screen yet, and the system doesn't like that.
|
||||
[...]
|
||||
*/
|
||||
|
||||
if (m_window == nil) {
|
||||
sf::err()
|
||||
<< "Could not create an instance of NSWindow "
|
||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||
<< std::endl;
|
||||
if (m_window == nil)
|
||||
{
|
||||
sf::err() << "Could not create an instance of NSWindow "
|
||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||
<< std::endl;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// 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,28 +203,30 @@
|
||||
*/
|
||||
}
|
||||
|
||||
// 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 "
|
||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||
<< std::endl;
|
||||
if (m_oglView == nil)
|
||||
{
|
||||
sf::err() << "Could not create an instance of NSOpenGLView "
|
||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||
<< std::endl;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// 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)];
|
||||
}
|
||||
@ -258,7 +268,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
|
||||
{
|
||||
// Forward to the view.
|
||||
[m_oglView setRequesterTo:requester];
|
||||
@ -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,11 +338,10 @@
|
||||
////////////////////////////////////////////////////////
|
||||
-(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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -359,7 +368,7 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)changeTitle:(NSString *)title
|
||||
-(void)changeTitle:(NSString*)title
|
||||
{
|
||||
[m_window setTitle:title];
|
||||
}
|
||||
@ -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,27 +460,25 @@
|
||||
-(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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)applyContext:(NSOpenGLContext *)context
|
||||
-(void)applyContext:(NSOpenGLContext*)context
|
||||
{
|
||||
[m_oglView setOpenGLContext:context];
|
||||
[context setView:m_oglView];
|
||||
@ -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;
|
||||
@ -505,30 +514,30 @@
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
-(void)windowDidBecomeKey:(NSNotification *)notification
|
||||
-(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
|
||||
-(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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -538,8 +547,8 @@
|
||||
////////////////////////////////////////////////////////
|
||||
-(float)screenHeight
|
||||
{
|
||||
NSDictionary *deviceDescription = [[m_window screen] deviceDescription];
|
||||
NSNumber *screenNumber = [deviceDescription valueForKey:@"NSScreenNumber"];
|
||||
NSDictionary* deviceDescription = [[m_window screen] deviceDescription];
|
||||
NSNumber* screenNumber = [deviceDescription valueForKey:@"NSScreenNumber"];
|
||||
CGDirectDisplayID screenID = (CGDirectDisplayID)[screenNumber intValue];
|
||||
CGFloat height = CGDisplayPixelsHigh(screenID);
|
||||
return height;
|
||||
|
@ -50,22 +50,23 @@ 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,22 +78,23 @@ 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.
|
||||
|
@ -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,8 +228,10 @@ public :
|
||||
void applyContext(NSOpenGLContextRef context) const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Change the type of the current process to become a full GUI app.
|
||||
/// Also ensure NSApp is constructed.
|
||||
/// \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.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
static void setUpProcess(void);
|
||||
@ -332,7 +334,7 @@ private :
|
||||
// Member data
|
||||
////////////////////////////////////////////////////////////
|
||||
WindowImplDelegateRef m_delegate; ///< Implementation in Obj-C.
|
||||
bool m_showCursor; ///< Is the cursor displayed or hidden ?
|
||||
bool m_showCursor; ///< Is the cursor displayed or hidden?
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -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,33 +47,33 @@ 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 "
|
||||
<< "a <NSWindow*> nor <NSView*> object "
|
||||
<< "(or any of their subclasses). You gave a <"
|
||||
<< [[nsHandle className] UTF8String]
|
||||
<< "> object."
|
||||
<< std::endl;
|
||||
sf::err() << "Cannot import this Window Handle because it is neither "
|
||||
<< "a <NSWindow*> nor <NSView*> object "
|
||||
<< "(or any of their subclasses). You gave a <"
|
||||
<< [[nsHandle className] UTF8String]
|
||||
<< "> object."
|
||||
<< std::endl;
|
||||
return;
|
||||
|
||||
}
|
||||
@ -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,11 +399,10 @@ 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,22 +411,20 @@ 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];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
@ -47,12 +46,12 @@ namespace sf {
|
||||
/// we have to duplicate some code.
|
||||
///
|
||||
/// Everything is done via a class that implement this protocol.
|
||||
/// There are two of these classes :
|
||||
/// There are two of these classes:
|
||||
///
|
||||
/// SFViewController and SFWindowController
|
||||
///
|
||||
/// The requester is a WindowImplCocoa. It's used to send back
|
||||
/// event via these functions :
|
||||
/// event via these functions:
|
||||
///
|
||||
/// windowClosed, windowResized, windowLostFocus, windowGainedFocus
|
||||
///
|
||||
@ -61,99 +60,142 @@ namespace sf {
|
||||
///
|
||||
/// keyDown, keyUp, textEntered
|
||||
///
|
||||
/// Note : Joysticks are not bound to a view or window
|
||||
/// Note: Joysticks are not bound to a view or window
|
||||
/// thus they're not managed by a class implementing this protocol.
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
@protocol WindowImplDelegateProtocol
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// Set the WindowImpl who requested this delegate
|
||||
/// (This would be a ctor in C++ or Java where we can prohibit the
|
||||
/// construction of an object.)
|
||||
/// \brief Set the WindowImpl who requested this delegate
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester;
|
||||
-(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;
|
||||
-(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;
|
||||
-(void)applyContext:(NSOpenGLContext*)context;
|
||||
|
||||
@end
|
||||
|
@ -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."
|
||||
<< std::endl;
|
||||
}
|
||||
if (cgbestMode == NULL)
|
||||
sf::err() << "Couldn't convert the given sf:VideoMode into a CGDisplayMode."
|
||||
<< std::endl;
|
||||
|
||||
return cgbestMode;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user