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.
|
/// Increment a retain count.
|
||||||
/// See SPECIAL CONSIDERATION in implementation file.
|
/// See SPECIAL CONSIDERATION in implementation file.
|
||||||
@ -35,14 +35,14 @@ void retainPool(void);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Release the pool.
|
/// \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.
|
/// See SPECIAL CONSIDERATION in implementation file.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void releasePool(void);
|
void releasePool(void);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Drain the pool.
|
/// \brief Drain the pool
|
||||||
///
|
///
|
||||||
/// releasePool must be called at least once before drainPool.
|
/// releasePool must be called at least once before drainPool.
|
||||||
///
|
///
|
||||||
|
@ -26,12 +26,12 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/ThreadLocalPtr.hpp>
|
|
||||||
#include <SFML/System/NonCopyable.hpp>
|
|
||||||
#include <SFML/System/Err.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 <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -42,8 +42,8 @@
|
|||||||
/// Because NSAutoreleasePool cannot be retain we have to do it ourself.
|
/// Because NSAutoreleasePool cannot be retain we have to do it ourself.
|
||||||
/// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread.
|
/// 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
|
/// 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.
|
/// releasePool must be called X times too in the same thread Y.
|
||||||
///
|
///
|
||||||
@ -54,10 +54,11 @@ namespace sf
|
|||||||
namespace priv
|
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 :
|
public :
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -95,15 +96,15 @@ private:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// 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
|
NSAutoreleasePool* m_pool; ///< Our dedicated pool
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
PoolWrapper::PoolWrapper()
|
PoolWrapper::PoolWrapper() :
|
||||||
: m_count(0)
|
m_count(0),
|
||||||
, m_pool(0)
|
m_pool(0)
|
||||||
{
|
{
|
||||||
/* Nothing else */
|
/* Nothing else */
|
||||||
}
|
}
|
||||||
@ -113,17 +114,16 @@ PoolWrapper::PoolWrapper()
|
|||||||
PoolWrapper::~PoolWrapper()
|
PoolWrapper::~PoolWrapper()
|
||||||
{
|
{
|
||||||
#ifdef SFML_DEBUG
|
#ifdef SFML_DEBUG
|
||||||
if (m_count < 0) {
|
if (m_count < 0)
|
||||||
sf::err() << "~PoolWrapper : m_count is less than zero! "
|
sf::err() << "~PoolWrapper : m_count is less than zero! "
|
||||||
"You called releasePool from a thread too many times."
|
"You called releasePool from a thread too many times."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
} else if (m_count > 0) {
|
else if (m_count > 0)
|
||||||
sf::err() << "~PoolWrapper : m_count is greater than zero! "
|
sf::err() << "~PoolWrapper : m_count is greater than zero! "
|
||||||
"You called releasePool from a thread to few times."
|
"You called releasePool from a thread to few times."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
} else { // m_count == 0
|
else // m_count == 0
|
||||||
sf::err() << "~PoolWrapper is HAPPY!" << std::endl;
|
sf::err() << "~PoolWrapper is HAPPY!" << std::endl;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,14 +135,12 @@ void PoolWrapper::retain()
|
|||||||
++m_count;
|
++m_count;
|
||||||
|
|
||||||
// Allocate pool if required.
|
// Allocate pool if required.
|
||||||
if (m_pool == 0) {
|
if (m_pool == 0)
|
||||||
m_pool = [[NSAutoreleasePool alloc] init];
|
m_pool = [[NSAutoreleasePool alloc] init];
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SFML_DEBUG
|
#ifdef SFML_DEBUG
|
||||||
if (m_count <= 0) {
|
if (m_count <= 0)
|
||||||
sf::err() << "PoolWrapper::retain : m_count <= 0! " << std::endl;
|
sf::err() << "PoolWrapper::retain : m_count <= 0! " << std::endl;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,14 +152,12 @@ void PoolWrapper::release()
|
|||||||
--m_count;
|
--m_count;
|
||||||
|
|
||||||
// Drain pool if required.
|
// Drain pool if required.
|
||||||
if (m_count == 0) {
|
if (m_count == 0)
|
||||||
drain();
|
drain();
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SFML_DEBUG
|
#ifdef SFML_DEBUG
|
||||||
if (m_count < 0) {
|
if (m_count < 0)
|
||||||
sf::err() << "PoolWrapper::release : m_count < 0! " << std::endl;
|
sf::err() << "PoolWrapper::release : m_count < 0! " << std::endl;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,9 +166,8 @@ void PoolWrapper::drain()
|
|||||||
[m_pool drain];
|
[m_pool drain];
|
||||||
m_pool = 0;
|
m_pool = 0;
|
||||||
|
|
||||||
if (m_count != 0) {
|
if (m_count != 0)
|
||||||
m_pool = [[NSAutoreleasePool alloc] init];
|
m_pool = [[NSAutoreleasePool alloc] init];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -194,9 +189,8 @@ namespace
|
|||||||
void retainPool(void)
|
void retainPool(void)
|
||||||
{
|
{
|
||||||
// First, Check that we have a valid PoolWrapper object in our local pool.
|
// First, Check that we have a valid PoolWrapper object in our local pool.
|
||||||
if (localPool == NULL) {
|
if (localPool == NULL)
|
||||||
localPool = new sf::priv::PoolWrapper();
|
localPool = new sf::priv::PoolWrapper();
|
||||||
}
|
|
||||||
|
|
||||||
// Then retains!
|
// Then retains!
|
||||||
localPool->retain();
|
localPool->retain();
|
||||||
@ -206,19 +200,13 @@ void retainPool(void)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void releasePool(void)
|
void releasePool(void)
|
||||||
{
|
{
|
||||||
|
if (localPool != NULL)
|
||||||
|
localPool->release();
|
||||||
#ifdef SFML_DEBUG
|
#ifdef SFML_DEBUG
|
||||||
if (localPool == NULL) {
|
else
|
||||||
sf::err() << "releasePool : You must call retainPool at least once "
|
sf::err() << "releasePool : You must call retainPool at least once "
|
||||||
"in this thread before calling releasePool."
|
"in this thread before calling releasePool."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Releases, that's all.
|
|
||||||
localPool->release();
|
|
||||||
|
|
||||||
#ifdef SFML_DEBUG
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,14 +214,12 @@ void releasePool(void)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void drainPool()
|
void drainPool()
|
||||||
{
|
{
|
||||||
if (localPool != NULL) {
|
if (localPool != NULL)
|
||||||
localPool->drain();
|
localPool->drain();
|
||||||
}
|
|
||||||
#ifdef SFML_DEBUG
|
#ifdef SFML_DEBUG
|
||||||
else {
|
else
|
||||||
sf::err() << "releasePool must be called at least one before drainPool"
|
sf::err() << "releasePool must be called at least one before drainPool"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/NonCopyable.hpp>
|
|
||||||
#include <SFML/Window/JoystickImpl.hpp>
|
#include <SFML/Window/JoystickImpl.hpp>
|
||||||
#include <SFML/Window/Keyboard.hpp>
|
#include <SFML/Window/Keyboard.hpp>
|
||||||
#include <SFML/Window/Mouse.hpp>
|
#include <SFML/Window/Mouse.hpp>
|
||||||
|
#include <SFML/System/NonCopyable.hpp>
|
||||||
#include <Carbon/Carbon.h>
|
#include <Carbon/Carbon.h>
|
||||||
#include <IOKit/hid/IOHIDManager.h>
|
|
||||||
#include <IOKit/hid/IOHIDDevice.h>
|
#include <IOKit/hid/IOHIDDevice.h>
|
||||||
|
#include <IOKit/hid/IOHIDManager.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
@ -46,9 +46,10 @@ namespace priv
|
|||||||
typedef std::vector<IOHIDElementRef> IOHIDElements;
|
typedef std::vector<IOHIDElementRef> IOHIDElements;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief This class manage as a singleton instance the
|
/// \brief sf::priv::InputImpl helper
|
||||||
/// keyboard and mouse states. It's only purpose is
|
///
|
||||||
/// to help sf::priv::InputImpl class.
|
/// 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
|
class HIDInputManager : NonCopyable
|
||||||
@ -211,7 +212,7 @@ private :
|
|||||||
void freeUp();
|
void freeUp();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Filter the devices and return them.
|
/// \brief Filter the devices and return them
|
||||||
///
|
///
|
||||||
/// freeUp is _not_ called by this function.
|
/// freeUp is _not_ called by this function.
|
||||||
///
|
///
|
||||||
|
@ -60,18 +60,16 @@ long HIDInputManager::getLocationID(IOHIDDeviceRef device)
|
|||||||
{
|
{
|
||||||
long loc = 0;
|
long loc = 0;
|
||||||
|
|
||||||
// Get a unique ID : its usb location ID
|
// Get a unique ID: its usb location ID
|
||||||
CFTypeRef typeRef = IOHIDDeviceGetProperty(device,
|
CFTypeRef typeRef = IOHIDDeviceGetProperty(device,
|
||||||
CFSTR(kIOHIDLocationIDKey));
|
CFSTR(kIOHIDLocationIDKey));
|
||||||
if (!typeRef || CFGetTypeID(typeRef) != CFNumberGetTypeID()) {
|
if (!typeRef || (CFGetTypeID(typeRef) != CFNumberGetTypeID()))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
CFNumberRef locRef = (CFNumberRef)typeRef;
|
CFNumberRef locRef = (CFNumberRef)typeRef;
|
||||||
|
|
||||||
if (!CFNumberGetValue(locRef, kCFNumberLongType, &loc)) {
|
if (!CFNumberGetValue(locRef, kCFNumberLongType, &loc))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
return loc;
|
return loc;
|
||||||
}
|
}
|
||||||
@ -100,18 +98,19 @@ CFDictionaryRef HIDInputManager::copyDevicesMask(UInt32 page, UInt32 usage)
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
HIDInputManager::HIDInputManager()
|
HIDInputManager::HIDInputManager() :
|
||||||
: m_isValid(true)
|
m_isValid(true),
|
||||||
, m_layoutData(0)
|
m_layoutData(0),
|
||||||
, m_layout(0)
|
m_layout(0),
|
||||||
, m_manager(0)
|
m_manager(0)
|
||||||
{
|
{
|
||||||
// Get the current keyboard layout
|
// Get the current keyboard layout
|
||||||
TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource();
|
TISInputSourceRef tis = TISCopyCurrentKeyboardLayoutInputSource();
|
||||||
m_layoutData = (CFDataRef)TISGetInputSourceProperty(tis,
|
m_layoutData = (CFDataRef)TISGetInputSourceProperty(tis,
|
||||||
kTISPropertyUnicodeKeyLayoutData);
|
kTISPropertyUnicodeKeyLayoutData);
|
||||||
|
|
||||||
if (m_layoutData == 0) {
|
if (m_layoutData == 0)
|
||||||
|
{
|
||||||
sf::err() << "Cannot get the keyboard layout" << std::endl;
|
sf::err() << "Cannot get the keyboard layout" << std::endl;
|
||||||
freeUp();
|
freeUp();
|
||||||
return;
|
return;
|
||||||
@ -130,9 +129,9 @@ HIDInputManager::HIDInputManager()
|
|||||||
// Open the HID Manager reference
|
// Open the HID Manager reference
|
||||||
IOReturn openStatus = IOHIDManagerOpen(m_manager, kIOHIDOptionsTypeNone);
|
IOReturn openStatus = IOHIDManagerOpen(m_manager, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
if (openStatus != kIOReturnSuccess) {
|
if (openStatus != kIOReturnSuccess)
|
||||||
|
{
|
||||||
sf::err() << "Error when opening the HID manager" << std::endl;
|
sf::err() << "Error when opening the HID manager" << std::endl;
|
||||||
|
|
||||||
freeUp();
|
freeUp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -168,7 +167,8 @@ void HIDInputManager::initializeKeyboard()
|
|||||||
|
|
||||||
// Get only keyboards
|
// Get only keyboards
|
||||||
CFSetRef keyboards = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
|
CFSetRef keyboards = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard);
|
||||||
if (keyboards == NULL) {
|
if (keyboards == NULL)
|
||||||
|
{
|
||||||
freeUp();
|
freeUp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -179,10 +179,9 @@ void HIDInputManager::initializeKeyboard()
|
|||||||
CFTypeRef devicesArray[keyboardCount];
|
CFTypeRef devicesArray[keyboardCount];
|
||||||
CFSetGetValues(keyboards, devicesArray);
|
CFSetGetValues(keyboards, devicesArray);
|
||||||
|
|
||||||
for (CFIndex i = 0; i < keyboardCount; ++i) {
|
for (CFIndex i = 0; i < keyboardCount; ++i)
|
||||||
|
{
|
||||||
IOHIDDeviceRef keyboard = (IOHIDDeviceRef)devicesArray[i];
|
IOHIDDeviceRef keyboard = (IOHIDDeviceRef)devicesArray[i];
|
||||||
|
|
||||||
loadKeyboard(keyboard);
|
loadKeyboard(keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,7 +202,8 @@ void HIDInputManager::initializeMouse()
|
|||||||
|
|
||||||
// Get only mouses
|
// Get only mouses
|
||||||
CFSetRef mouses = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse);
|
CFSetRef mouses = copyDevices(kHIDPage_GenericDesktop, kHIDUsage_GD_Mouse);
|
||||||
if (mouses == NULL) {
|
if (mouses == NULL)
|
||||||
|
{
|
||||||
freeUp();
|
freeUp();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -214,10 +214,9 @@ void HIDInputManager::initializeMouse()
|
|||||||
CFTypeRef devicesArray[mouseCount];
|
CFTypeRef devicesArray[mouseCount];
|
||||||
CFSetGetValues(mouses, devicesArray);
|
CFSetGetValues(mouses, devicesArray);
|
||||||
|
|
||||||
for (CFIndex i = 0; i < mouseCount; ++i) {
|
for (CFIndex i = 0; i < mouseCount; ++i)
|
||||||
|
{
|
||||||
IOHIDDeviceRef mouse = (IOHIDDeviceRef)devicesArray[i];
|
IOHIDDeviceRef mouse = (IOHIDDeviceRef)devicesArray[i];
|
||||||
|
|
||||||
loadMouse(mouse);
|
loadMouse(mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,32 +234,32 @@ void HIDInputManager::loadKeyboard(IOHIDDeviceRef keyboard)
|
|||||||
CFArrayRef keys = IOHIDDeviceCopyMatchingElements(keyboard,
|
CFArrayRef keys = IOHIDDeviceCopyMatchingElements(keyboard,
|
||||||
NULL,
|
NULL,
|
||||||
kIOHIDOptionsTypeNone);
|
kIOHIDOptionsTypeNone);
|
||||||
if (keys == NULL) {
|
if (keys == NULL)
|
||||||
|
{
|
||||||
sf::err() << "We got a keyboard without any keys (1)" << std::endl;
|
sf::err() << "We got a keyboard without any keys (1)" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// How many elements are there ?
|
// How many elements are there?
|
||||||
CFIndex keysCount = CFArrayGetCount(keys);
|
CFIndex keysCount = CFArrayGetCount(keys);
|
||||||
|
|
||||||
if (keysCount == 0) {
|
if (keysCount == 0)
|
||||||
|
{
|
||||||
sf::err() << "We got a keyboard without any keys (2)" << std::endl;
|
sf::err() << "We got a keyboard without any keys (2)" << std::endl;
|
||||||
CFRelease(keys);
|
CFRelease(keys);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through all connected elements.
|
// 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);
|
IOHIDElementRef aKey = (IOHIDElementRef) CFArrayGetValueAtIndex(keys, i);
|
||||||
|
|
||||||
// Skip non-matching keys elements
|
// Skip non-matching keys elements
|
||||||
if (IOHIDElementGetUsagePage(aKey) != kHIDPage_KeyboardOrKeypad) {
|
if (IOHIDElementGetUsagePage(aKey) != kHIDPage_KeyboardOrKeypad)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
loadKey(aKey);
|
loadKey(aKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Release unused stuff
|
// Release unused stuff
|
||||||
@ -274,29 +273,30 @@ void HIDInputManager::loadMouse(IOHIDDeviceRef mouse)
|
|||||||
CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(mouse,
|
CFArrayRef buttons = IOHIDDeviceCopyMatchingElements(mouse,
|
||||||
NULL,
|
NULL,
|
||||||
kIOHIDOptionsTypeNone);
|
kIOHIDOptionsTypeNone);
|
||||||
if (buttons == NULL) {
|
if (buttons == NULL)
|
||||||
|
{
|
||||||
sf::err() << "We got a mouse without any buttons (1)" << std::endl;
|
sf::err() << "We got a mouse without any buttons (1)" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// How many elements are there ?
|
// How many elements are there?
|
||||||
CFIndex buttonCount = CFArrayGetCount(buttons);
|
CFIndex buttonCount = CFArrayGetCount(buttons);
|
||||||
|
|
||||||
if (buttonCount == 0) {
|
if (buttonCount == 0)
|
||||||
|
{
|
||||||
sf::err() << "We got a mouse without any buttons (2)" << std::endl;
|
sf::err() << "We got a mouse without any buttons (2)" << std::endl;
|
||||||
CFRelease(buttons);
|
CFRelease(buttons);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through all connected elements.
|
// 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);
|
IOHIDElementRef aButton = (IOHIDElementRef) CFArrayGetValueAtIndex(buttons, i);
|
||||||
|
|
||||||
// Skip non-matching keys elements
|
// Skip non-matching keys elements
|
||||||
if (IOHIDElementGetUsagePage(aButton) != kHIDPage_Button) {
|
if (IOHIDElementGetUsagePage(aButton) != kHIDPage_Button)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
loadButton(aButton);
|
loadButton(aButton);
|
||||||
}
|
}
|
||||||
@ -313,9 +313,8 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
|
|||||||
UInt32 usageCode = IOHIDElementGetUsage(key);
|
UInt32 usageCode = IOHIDElementGetUsage(key);
|
||||||
UInt8 virtualCode = usageToVirtualCode(usageCode);
|
UInt8 virtualCode = usageToVirtualCode(usageCode);
|
||||||
|
|
||||||
if (virtualCode == 0xff) {
|
if (virtualCode == 0xff)
|
||||||
return; // no corresponding virtual code -> skip
|
return; // no corresponding virtual code -> skip
|
||||||
}
|
|
||||||
|
|
||||||
// Now translate the virtual code to unicode according to
|
// Now translate the virtual code to unicode according to
|
||||||
// the current keyboard layout
|
// the current keyboard layout
|
||||||
@ -339,7 +338,8 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
|
|||||||
&actualStringLength, // length of what we get
|
&actualStringLength, // length of what we get
|
||||||
unicodeString); // what we get
|
unicodeString); // what we get
|
||||||
|
|
||||||
if (error == noErr) {
|
if (error == noErr)
|
||||||
|
{
|
||||||
// Translation went fine
|
// Translation went fine
|
||||||
|
|
||||||
// The corresponding SFML key code
|
// 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
|
// First we look if the key down is from a list of characters
|
||||||
// that depend on keyboard localization
|
// that depend on keyboard localization
|
||||||
if (actualStringLength > 0) {
|
if (actualStringLength > 0)
|
||||||
code = localizedKeys(unicodeString[0]);
|
code = localizedKeys(unicodeString[0]);
|
||||||
}
|
|
||||||
|
|
||||||
// The key is not a localized one so we try to find a
|
// The key is not a localized one so we try to find a
|
||||||
// corresponding code through virtual key code
|
// corresponding code through virtual key code
|
||||||
if (code == Keyboard::Unknown) {
|
if (code == Keyboard::Unknown)
|
||||||
code = nonLocalizedKeys(virtualCode);
|
code = nonLocalizedKeys(virtualCode);
|
||||||
}
|
|
||||||
|
|
||||||
// A code was found, wonderful!
|
// A code was found, wonderful!
|
||||||
if (code != Keyboard::Unknown) {
|
if (code != Keyboard::Unknown)
|
||||||
|
{
|
||||||
// Ok, everything went fine. Now we have a unique
|
// Ok, everything went fine. Now we have a unique
|
||||||
// corresponding sf::Keyboard::Key to one IOHIDElementRef
|
// corresponding sf::Keyboard::Key to one IOHIDElementRef
|
||||||
|
|
||||||
m_keys[code].push_back(key);
|
m_keys[code].push_back(key);
|
||||||
|
|
||||||
// And don't forget to keep the reference alive for our usage
|
// And don't forget to keep the reference alive for our usage
|
||||||
CFRetain(m_keys[code].back());
|
CFRetain(m_keys[code].back());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -392,8 +388,8 @@ void HIDInputManager::loadKey(IOHIDElementRef key)
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
} /* if (error == noErr) */
|
} /* if (error == noErr) */
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
sf::err() << "Cannot translate the virtual key code, error : "
|
sf::err() << "Cannot translate the virtual key code, error : "
|
||||||
<< error
|
<< error
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
@ -408,10 +404,11 @@ void HIDInputManager::loadButton(IOHIDElementRef button)
|
|||||||
UInt32 usage = IOHIDElementGetUsage(button);
|
UInt32 usage = IOHIDElementGetUsage(button);
|
||||||
Mouse::Button dest = Mouse::ButtonCount;
|
Mouse::Button dest = Mouse::ButtonCount;
|
||||||
|
|
||||||
// Extends kHIDUsage_Button_* enum with :
|
// Extends kHIDUsage_Button_* enum with:
|
||||||
#define kHIDUsage_Button_5 0x05
|
#define kHIDUsage_Button_5 0x05
|
||||||
|
|
||||||
switch (usage) {
|
switch (usage)
|
||||||
|
{
|
||||||
case kHIDUsage_Button_1: dest = Mouse::Left; break;
|
case kHIDUsage_Button_1: dest = Mouse::Left; break;
|
||||||
case kHIDUsage_Button_2: dest = Mouse::Right; break;
|
case kHIDUsage_Button_2: dest = Mouse::Right; break;
|
||||||
case kHIDUsage_Button_3: dest = Mouse::Middle; break;
|
case kHIDUsage_Button_3: dest = Mouse::Middle; break;
|
||||||
@ -420,9 +417,9 @@ void HIDInputManager::loadButton(IOHIDElementRef button)
|
|||||||
default: dest = Mouse::ButtonCount; break;
|
default: dest = Mouse::ButtonCount; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest != Mouse::ButtonCount) {
|
if (dest != Mouse::ButtonCount)
|
||||||
|
{
|
||||||
// We know what kind of button it is!
|
// We know what kind of button it is!
|
||||||
|
|
||||||
m_buttons[dest].push_back(button);
|
m_buttons[dest].push_back(button);
|
||||||
|
|
||||||
// And don't forget to keep the reference alive for our usage
|
// And don't forget to keep the reference alive for our usage
|
||||||
@ -436,21 +433,25 @@ void HIDInputManager::freeUp()
|
|||||||
{
|
{
|
||||||
m_isValid = false;
|
m_isValid = false;
|
||||||
|
|
||||||
if (m_layoutData != 0) CFRelease(m_layoutData);
|
if (m_layoutData != 0)
|
||||||
// Do not release m_layout ! It is owned by m_layoutData.
|
CFRelease(m_layoutData);
|
||||||
if (m_manager != 0) CFRelease(m_manager);
|
// 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 (unsigned int i = 0; i < Keyboard::KeyCount; ++i)
|
||||||
for (IOHIDElements::iterator it = m_keys[i].begin(); it != m_keys[i].end(); ++it) {
|
{
|
||||||
|
for (IOHIDElements::iterator it = m_keys[i].begin(); it != m_keys[i].end(); ++it)
|
||||||
CFRelease(*it);
|
CFRelease(*it);
|
||||||
}
|
|
||||||
m_keys[i].clear();
|
m_keys[i].clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < Mouse::ButtonCount; ++i) {
|
for (unsigned int i = 0; i < Mouse::ButtonCount; ++i)
|
||||||
for (IOHIDElements::iterator it = m_buttons[i].begin(); it != m_buttons[i].end(); ++it) {
|
{
|
||||||
|
for (IOHIDElements::iterator it = m_buttons[i].begin(); it != m_buttons[i].end(); ++it)
|
||||||
CFRelease(*it);
|
CFRelease(*it);
|
||||||
}
|
|
||||||
m_buttons[i].clear();
|
m_buttons[i].clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -468,13 +469,13 @@ CFSetRef HIDInputManager::copyDevices(UInt32 page, UInt32 usage)
|
|||||||
mask = 0;
|
mask = 0;
|
||||||
|
|
||||||
CFSetRef devices = IOHIDManagerCopyDevices(m_manager);
|
CFSetRef devices = IOHIDManagerCopyDevices(m_manager);
|
||||||
if (devices == NULL) {
|
if (devices == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
// Is there at least one device ?
|
// Is there at least one device?
|
||||||
CFIndex deviceCount = CFSetGetCount(devices);
|
CFIndex deviceCount = CFSetGetCount(devices);
|
||||||
if (deviceCount < 1) {
|
if (deviceCount < 1)
|
||||||
|
{
|
||||||
CFRelease(devices);
|
CFRelease(devices);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -484,7 +485,8 @@ CFSetRef HIDInputManager::copyDevices(UInt32 page, UInt32 usage)
|
|||||||
|
|
||||||
bool HIDInputManager::isPressed(IOHIDElements& elements)
|
bool HIDInputManager::isPressed(IOHIDElements& elements)
|
||||||
{
|
{
|
||||||
if (!m_isValid) {
|
if (!m_isValid)
|
||||||
|
{
|
||||||
sf::err() << "HIDInputManager is invalid." << std::endl;
|
sf::err() << "HIDInputManager is invalid." << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -492,33 +494,31 @@ bool HIDInputManager::isPressed(IOHIDElements& elements)
|
|||||||
// state = true if at least one corresponding HID button is pressed
|
// state = true if at least one corresponding HID button is pressed
|
||||||
bool state = false;
|
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;
|
IOHIDValueRef value = 0;
|
||||||
|
|
||||||
IOHIDDeviceRef device = IOHIDElementGetDevice(*it);
|
IOHIDDeviceRef device = IOHIDElementGetDevice(*it);
|
||||||
IOHIDDeviceGetValue(device, *it, &value);
|
IOHIDDeviceGetValue(device, *it, &value);
|
||||||
|
|
||||||
if (!value) {
|
if (!value)
|
||||||
|
{
|
||||||
// This means some kind of error / disconnection so we remove this
|
// This means some kind of error / disconnection so we remove this
|
||||||
// element from our buttons
|
// element from our buttons
|
||||||
|
|
||||||
CFRelease(*it);
|
CFRelease(*it);
|
||||||
it = elements.erase(it);
|
it = elements.erase(it);
|
||||||
|
}
|
||||||
} else if (IOHIDValueGetIntegerValue(value) == 1) {
|
else if (IOHIDValueGetIntegerValue(value) == 1)
|
||||||
|
{
|
||||||
// This means the button is pressed
|
// This means the button is pressed
|
||||||
state = true;
|
state = true;
|
||||||
break; // Stop here
|
break; // Stop here
|
||||||
|
}
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
// This means the button is released
|
// This means the button is released
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
@ -530,7 +530,8 @@ UInt8 HIDInputManager::usageToVirtualCode(UInt32 usage)
|
|||||||
{
|
{
|
||||||
// Some usage key doesn't have any corresponding virtual
|
// Some usage key doesn't have any corresponding virtual
|
||||||
// code or it was not found (return 0xff).
|
// code or it was not found (return 0xff).
|
||||||
switch (usage) {
|
switch (usage)
|
||||||
|
{
|
||||||
case kHIDUsage_KeyboardErrorRollOver: return 0xff;
|
case kHIDUsage_KeyboardErrorRollOver: return 0xff;
|
||||||
case kHIDUsage_KeyboardPOSTFail: return 0xff;
|
case kHIDUsage_KeyboardPOSTFail: return 0xff;
|
||||||
case kHIDUsage_KeyboardErrorUndefined: return 0xff;
|
case kHIDUsage_KeyboardErrorUndefined: return 0xff;
|
||||||
@ -734,7 +735,8 @@ UInt8 HIDInputManager::usageToVirtualCode(UInt32 usage)
|
|||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
Keyboard::Key HIDInputManager::localizedKeys(UniChar ch)
|
Keyboard::Key HIDInputManager::localizedKeys(UniChar ch)
|
||||||
{
|
{
|
||||||
switch (ch) {
|
switch (ch)
|
||||||
|
{
|
||||||
case 'a':
|
case 'a':
|
||||||
case 'A': return sf::Keyboard::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) 0x code based on http://forums.macrumors.com/showthread.php?t=780577
|
||||||
// Some sf::Keyboard::Key are present twice.
|
// Some sf::Keyboard::Key are present twice.
|
||||||
switch (virtualKeycode) {
|
switch (virtualKeycode)
|
||||||
|
{
|
||||||
// These cases should not be used but anyway...
|
// These cases should not be used but anyway...
|
||||||
case 0x00: return sf::Keyboard::A;
|
case 0x00: return sf::Keyboard::A;
|
||||||
case 0x0b: return sf::Keyboard::B;
|
case 0x0b: return sf::Keyboard::B;
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/OSX/HIDJoystickManager.hpp>
|
|
||||||
#include <SFML/Window/OSX/HIDInputManager.hpp>
|
#include <SFML/Window/OSX/HIDInputManager.hpp>
|
||||||
|
#include <SFML/Window/OSX/HIDJoystickManager.hpp>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Private data
|
// Private data
|
||||||
@ -36,7 +36,7 @@ namespace
|
|||||||
{
|
{
|
||||||
// Using a custom run loop mode solve some issues that appears when SFML
|
// Using a custom run loop mode solve some issues that appears when SFML
|
||||||
// is used with Cocoa.
|
// 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()
|
HIDJoystickManager::HIDJoystickManager() :
|
||||||
: m_manager(0)
|
m_manager(0),
|
||||||
, m_joystickCount(0)
|
m_joystickCount(0)
|
||||||
{
|
{
|
||||||
m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
m_manager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
||||||
|
|
||||||
@ -123,14 +123,15 @@ void HIDJoystickManager::update()
|
|||||||
{
|
{
|
||||||
SInt32 status = kCFRunLoopRunHandledSource;
|
SInt32 status = kCFRunLoopRunHandledSource;
|
||||||
|
|
||||||
while (status == kCFRunLoopRunHandledSource) {
|
while (status == kCFRunLoopRunHandledSource)
|
||||||
|
{
|
||||||
status = CFRunLoopRunInMode(RunLoopMode, 0, true);
|
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;
|
HIDJoystickManager* manager = (HIDJoystickManager*)context;
|
||||||
manager->m_joystickCount++;
|
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;
|
HIDJoystickManager* manager = (HIDJoystickManager*)context;
|
||||||
manager->m_joystickCount--;
|
manager->m_joystickCount--;
|
||||||
|
@ -30,17 +30,18 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/NonCopyable.hpp>
|
#include <SFML/System/NonCopyable.hpp>
|
||||||
#include <IOKit/hid/IOHIDManager.h>
|
|
||||||
#include <IOKit/hid/IOHIDDevice.h>
|
#include <IOKit/hid/IOHIDDevice.h>
|
||||||
|
#include <IOKit/hid/IOHIDManager.h>
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief This class manage as a singleton instance the
|
/// \brief sf::priv::InputImpl helper
|
||||||
/// joysticks. It's only purpose is
|
///
|
||||||
/// to help sf::priv::JoystickImpl class.
|
/// This class manage as a singleton instance the joysticks.
|
||||||
|
/// It's only purpose is to help sf::priv::JoystickImpl class.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
class HIDJoystickManager : NonCopyable
|
class HIDJoystickManager : NonCopyable
|
||||||
@ -66,7 +67,7 @@ public :
|
|||||||
unsigned int getJoystickCount();
|
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
|
/// \return a retained CFSetRef of IOHIDDeviceRef or NULL
|
||||||
///
|
///
|
||||||
@ -88,7 +89,7 @@ private :
|
|||||||
~HIDJoystickManager();
|
~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();
|
void update();
|
||||||
@ -97,19 +98,19 @@ private :
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Private "plug-in" callback
|
/// \brief Private "plug-in" callback
|
||||||
/// \note Only 'context' parametre is used.
|
/// \note Only 'context' parameter is used.
|
||||||
/// \see IOHIDDeviceCallback
|
/// \see IOHIDDeviceCallback
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
static void pluggedIn(void * context, IOReturn, void *, IOHIDDeviceRef);
|
static void pluggedIn(void* context, IOReturn, void*, IOHIDDeviceRef);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Private "plug-out" callback
|
/// \brief Private "plug-out" callback
|
||||||
/// \note Only 'context' parametre is used.
|
/// \note Only 'context' parameter is used.
|
||||||
/// \see IOHIDDeviceCallback
|
/// \see IOHIDDeviceCallback
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
static void pluggedOut(void * context, IOReturn, void *, IOHIDDeviceRef);
|
static void pluggedOut(void* context, IOReturn, void*, IOHIDDeviceRef);
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
|
@ -26,20 +26,20 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/OSX/InputImpl.hpp>
|
|
||||||
#include <SFML/Window/VideoMode.hpp>
|
#include <SFML/Window/VideoMode.hpp>
|
||||||
#include <SFML/Window/Window.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/Window/OSX/HIDInputManager.hpp>
|
||||||
|
#include <SFML/System/Err.hpp>
|
||||||
|
|
||||||
#import <AppKit/AppKit.h>
|
|
||||||
#import <SFML/Window/OSX/SFOpenGLView.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
|
/// In order to keep track of the keyboard's state and mouse buttons' state
|
||||||
/// we use the HID manager. Mouse position is handled differently.
|
/// 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.
|
/// NSEvent +addGlobalMonitorForEventsMatchingMask:handler: for mouse only.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -62,42 +62,44 @@ SFOpenGLView* getSFOpenGLViewFromSFMLWindow(const Window& window)
|
|||||||
// Get our SFOpenGLView from ...
|
// Get our SFOpenGLView from ...
|
||||||
SFOpenGLView* view = nil;
|
SFOpenGLView* view = nil;
|
||||||
|
|
||||||
if ([nsHandle isKindOfClass:[NSWindow class]]) {
|
if ([nsHandle isKindOfClass:[NSWindow class]])
|
||||||
|
{
|
||||||
// If system handle is a window then from its content view.
|
// If system handle is a window then from its content view.
|
||||||
view = [nsHandle contentView];
|
view = [nsHandle contentView];
|
||||||
|
|
||||||
// Subview doesn't match ?
|
// Subview doesn't match ?
|
||||||
if (![view isKindOfClass:[SFOpenGLView class]]) {
|
if (![view isKindOfClass:[SFOpenGLView class]])
|
||||||
|
{
|
||||||
sf::err() << "The content view is not a valid SFOpenGLView"
|
sf::err() << "The content view is not a valid SFOpenGLView"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
view = nil;
|
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.
|
// If system handle is a view then from a subview of kind SFOpenGLView.
|
||||||
NSArray* subviews = [nsHandle subviews];
|
NSArray* subviews = [nsHandle subviews];
|
||||||
for (NSView* subview in subviews) {
|
for (NSView* subview in subviews)
|
||||||
if ([subview isKindOfClass:[SFOpenGLView class]]) {
|
{
|
||||||
view = (SFOpenGLView *)subview;
|
if ([subview isKindOfClass:[SFOpenGLView class]])
|
||||||
|
{
|
||||||
|
view = (SFOpenGLView*)subview;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No matching subview ?
|
// No matching subview ?
|
||||||
if (view == nil) {
|
if (view == nil)
|
||||||
sf::err() << "Cannot find a valid SFOpenGLView subview." << std::endl;
|
sf::err() << "Cannot find a valid SFOpenGLView subview." << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
} else {
|
{
|
||||||
if (nsHandle != 0) {
|
if (nsHandle != 0)
|
||||||
sf::err() << "The system handle is neither a <NSWindow*> nor <NSView*>"
|
sf::err() << "The system handle is neither a <NSWindow*> nor <NSView*>"
|
||||||
<< "object. This shouldn't happen."
|
<< "object. This shouldn't happen."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
} else {
|
// Else: this probably means the SFML window was previously closed.
|
||||||
// This probably means the SFML window was previously closed.
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
@ -134,9 +136,8 @@ Vector2i InputImpl::getMousePosition(const Window& relativeTo)
|
|||||||
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
|
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
|
||||||
|
|
||||||
// No view ?
|
// No view ?
|
||||||
if (view == nil) {
|
if (view == nil)
|
||||||
return Vector2i();
|
return Vector2i();
|
||||||
}
|
|
||||||
|
|
||||||
// Use -cursorPositionFromEvent: with nil.
|
// Use -cursorPositionFromEvent: with nil.
|
||||||
NSPoint pos = [view cursorPositionFromEvent:nil];
|
NSPoint pos = [view cursorPositionFromEvent:nil];
|
||||||
@ -168,9 +169,8 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ
|
|||||||
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
|
SFOpenGLView* view = getSFOpenGLViewFromSFMLWindow(relativeTo);
|
||||||
|
|
||||||
// No view ?
|
// No view ?
|
||||||
if (view == nil) {
|
if (view == nil)
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// Let SFOpenGLView compute the position in global coordinate
|
// Let SFOpenGLView compute the position in global coordinate
|
||||||
NSPoint p = NSMakePoint(position.x, position.y);
|
NSPoint p = NSMakePoint(position.x, position.y);
|
||||||
|
@ -66,60 +66,63 @@ void JoystickImpl::cleanup()
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool JoystickImpl::isConnected(unsigned int index)
|
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 :
|
// First, let's check if the device was previously detected:
|
||||||
|
if (m_locationIDs[index] != 0)
|
||||||
if (m_locationIDs[index] != 0) {
|
{
|
||||||
state = true;
|
state = true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
// Otherwise, let's check if it is now connected :
|
{
|
||||||
else { // i.e., m_locationIDs[index] == 0
|
// 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
|
// if there is more connected joystick to the HID manager than
|
||||||
// opened joystick devices then we find the new one.
|
// opened joystick devices then we find the new one.
|
||||||
|
|
||||||
unsigned int openedCount = 0;
|
unsigned int openedCount = 0;
|
||||||
for (unsigned int i(0); i < sf::Joystick::Count; ++i) {
|
for (unsigned int i(0); i < sf::Joystick::Count; ++i)
|
||||||
if (m_locationIDs[i] != 0) openedCount++;
|
{
|
||||||
|
if (m_locationIDs[i] != 0)
|
||||||
|
openedCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned int connectedCount = HIDJoystickManager::getInstance().getJoystickCount();
|
unsigned int connectedCount = HIDJoystickManager::getInstance().getJoystickCount();
|
||||||
|
|
||||||
if (connectedCount > openedCount) {
|
if (connectedCount > openedCount)
|
||||||
|
{
|
||||||
// Get all devices
|
// Get all devices
|
||||||
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
|
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
|
||||||
|
|
||||||
if (devices != NULL) {
|
if (devices != NULL)
|
||||||
|
{
|
||||||
CFIndex size = CFSetGetCount(devices);
|
CFIndex size = CFSetGetCount(devices);
|
||||||
|
if (size > 0)
|
||||||
if (size > 0) {
|
{
|
||||||
|
|
||||||
CFTypeRef array[size]; // array of IOHIDDeviceRef
|
CFTypeRef array[size]; // array of IOHIDDeviceRef
|
||||||
CFSetGetValues(devices, array);
|
CFSetGetValues(devices, array);
|
||||||
|
|
||||||
// If there exists a device d s.t. there is no j s.t.
|
// 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.
|
// 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];
|
IOHIDDeviceRef d = (IOHIDDeviceRef)array[didx];
|
||||||
Location dloc = HIDInputManager::getLocationID(d);
|
Location dloc = HIDInputManager::getLocationID(d);
|
||||||
|
|
||||||
bool foundJ = false;
|
bool foundJ = false;
|
||||||
for (unsigned int j(0); j < Joystick::Count; ++j) {
|
for (unsigned int j(0); j < Joystick::Count; ++j)
|
||||||
if (m_locationIDs[j] == dloc) {
|
{
|
||||||
|
if (m_locationIDs[j] == dloc)
|
||||||
|
{
|
||||||
foundJ = true;
|
foundJ = true;
|
||||||
break; // no need to loop again
|
break; // no need to loop again
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (foundJ) {
|
if (!foundJ) {
|
||||||
// This is a known device
|
|
||||||
// Nothing else to do
|
|
||||||
} else {
|
|
||||||
// This is a new device
|
// This is a new device
|
||||||
// We set it up for Open(..)
|
// We set it up for Open(..)
|
||||||
m_locationIDs[index] = dloc;
|
m_locationIDs[index] = dloc;
|
||||||
@ -127,7 +130,6 @@ bool JoystickImpl::isConnected(unsigned int index)
|
|||||||
break; // We stop looking for a new device
|
break; // We stop looking for a new device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CFRelease(devices);
|
CFRelease(devices);
|
||||||
@ -147,9 +149,8 @@ bool JoystickImpl::open(unsigned int index)
|
|||||||
|
|
||||||
// Get all devices
|
// Get all devices
|
||||||
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
|
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
|
||||||
if (devices == NULL) {
|
if (devices == NULL)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// Get a usable copy of the joysticks devices.
|
// Get a usable copy of the joysticks devices.
|
||||||
CFIndex joysticksCount = CFSetGetCount(devices);
|
CFIndex joysticksCount = CFSetGetCount(devices);
|
||||||
@ -158,15 +159,18 @@ bool JoystickImpl::open(unsigned int index)
|
|||||||
|
|
||||||
// Get the desired joystick.
|
// Get the desired joystick.
|
||||||
IOHIDDeviceRef self = 0;
|
IOHIDDeviceRef self = 0;
|
||||||
for (CFIndex i(0); i < joysticksCount; ++i) {
|
for (CFIndex i(0); i < joysticksCount; ++i)
|
||||||
|
{
|
||||||
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
|
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
|
||||||
if (deviceLoc == HIDInputManager::getLocationID(d)) {
|
if (deviceLoc == HIDInputManager::getLocationID(d))
|
||||||
|
{
|
||||||
self = d;
|
self = d;
|
||||||
break; // We found it so we stop looping.
|
break; // We found it so we stop looping.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self == 0) {
|
if (self == 0)
|
||||||
|
{
|
||||||
// This shouldn't happen!
|
// This shouldn't happen!
|
||||||
CFRelease(devices);
|
CFRelease(devices);
|
||||||
return false;
|
return false;
|
||||||
@ -177,68 +181,48 @@ bool JoystickImpl::open(unsigned int index)
|
|||||||
m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey));
|
m_identification.productId = getDeviceUint(self, CFSTR(kIOHIDProductIDKey));
|
||||||
|
|
||||||
// Get a list of all elements attached to the device.
|
// Get a list of all elements attached to the device.
|
||||||
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self,
|
CFArrayRef elements = IOHIDDeviceCopyMatchingElements(self, NULL, kIOHIDOptionsTypeNone);
|
||||||
NULL,
|
|
||||||
kIOHIDOptionsTypeNone);
|
|
||||||
|
|
||||||
if (elements == NULL) {
|
if (elements == NULL)
|
||||||
|
{
|
||||||
CFRelease(devices);
|
CFRelease(devices);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// How many elements are there ?
|
// How many elements are there?
|
||||||
CFIndex elementsCount = CFArrayGetCount(elements);
|
CFIndex elementsCount = CFArrayGetCount(elements);
|
||||||
|
|
||||||
if (elementsCount == 0) {
|
if (elementsCount == 0)
|
||||||
// What is a joystick with no element ?
|
{
|
||||||
|
// What is a joystick with no element?
|
||||||
CFRelease(elements);
|
CFRelease(elements);
|
||||||
CFRelease(devices);
|
CFRelease(devices);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Go through all connected elements.
|
// 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);
|
IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, i);
|
||||||
|
switch (IOHIDElementGetType(element))
|
||||||
switch (IOHIDElementGetType(element)) {
|
{
|
||||||
|
|
||||||
case kIOHIDElementTypeInput_Misc:
|
case kIOHIDElementTypeInput_Misc:
|
||||||
switch (IOHIDElementGetUsage(element)) {
|
switch (IOHIDElementGetUsage(element))
|
||||||
|
{
|
||||||
case kHIDUsage_GD_X:
|
case kHIDUsage_GD_X: m_axis[Joystick::X] = element; break;
|
||||||
m_axis[Joystick::X] = element;
|
case kHIDUsage_GD_Y: m_axis[Joystick::Y] = element; break;
|
||||||
break;
|
case kHIDUsage_GD_Z: m_axis[Joystick::Z] = element; break;
|
||||||
|
case kHIDUsage_GD_Rx: m_axis[Joystick::U] = element; break;
|
||||||
case kHIDUsage_GD_Y:
|
case kHIDUsage_GD_Ry: m_axis[Joystick::V] = element; break;
|
||||||
m_axis[Joystick::Y] = element;
|
case kHIDUsage_GD_Rz: m_axis[Joystick::R] = element; break;
|
||||||
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.
|
// kHIDUsage_GD_Vx, kHIDUsage_GD_Vy, kHIDUsage_GD_Vz are ignored.
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kIOHIDElementTypeInput_Button:
|
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
|
m_buttons.push_back(element); // ...we add this element to the list
|
||||||
} else {
|
// Else: too many buttons. We ignore this one.
|
||||||
// Too many buttons. We ignore this one.
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // Make compiler happy
|
default: // Make compiler happy
|
||||||
@ -253,13 +237,11 @@ bool JoystickImpl::open(unsigned int index)
|
|||||||
// Note : Joy::AxisPovX/Y are not supported (yet).
|
// Note : Joy::AxisPovX/Y are not supported (yet).
|
||||||
// Maybe kIOHIDElementTypeInput_Axis is the corresponding type but I can't test.
|
// Maybe kIOHIDElementTypeInput_Axis is the corresponding type but I can't test.
|
||||||
|
|
||||||
// Retain all these objets for personal use
|
// Retain all these objects for personal use
|
||||||
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it) {
|
for (ButtonsVector::iterator it(m_buttons.begin()); it != m_buttons.end(); ++it)
|
||||||
CFRetain(*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);
|
CFRetain(it->second);
|
||||||
}
|
|
||||||
|
|
||||||
// Note : we didn't retain element in the switch because we might have multiple
|
// 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
|
// 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()
|
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);
|
CFRelease(*it);
|
||||||
}
|
|
||||||
m_buttons.clear();
|
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);
|
CFRelease(it->second);
|
||||||
}
|
|
||||||
m_axis.clear();
|
m_axis.clear();
|
||||||
|
|
||||||
// And we unregister this joystick
|
// And we unregister this joystick
|
||||||
@ -295,10 +275,10 @@ JoystickCaps JoystickImpl::getCapabilities() const
|
|||||||
{
|
{
|
||||||
JoystickCaps caps;
|
JoystickCaps caps;
|
||||||
|
|
||||||
// Buttons :
|
// Buttons:
|
||||||
caps.buttonCount = m_buttons.size();
|
caps.buttonCount = m_buttons.size();
|
||||||
|
|
||||||
// Axis :
|
// Axis:
|
||||||
for (AxisMap::const_iterator it(m_axis.begin()); it != m_axis.end(); ++it) {
|
for (AxisMap::const_iterator it(m_axis.begin()); it != m_axis.end(); ++it) {
|
||||||
caps.axes[it->first] = true;
|
caps.axes[it->first] = true;
|
||||||
}
|
}
|
||||||
@ -321,7 +301,7 @@ JoystickState JoystickImpl::update()
|
|||||||
JoystickState state; // otherwise return that
|
JoystickState state; // otherwise return that
|
||||||
state.connected = true;
|
state.connected = true;
|
||||||
|
|
||||||
// Note : free up is done in close() which is called, if required,
|
// 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.
|
// by the joystick manager. So we don't release buttons nor axes here.
|
||||||
|
|
||||||
// First, let's determine if the joystick is still connected
|
// First, let's determine if the joystick is still connected
|
||||||
@ -329,9 +309,8 @@ JoystickState JoystickImpl::update()
|
|||||||
|
|
||||||
// Get all devices
|
// Get all devices
|
||||||
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
|
CFSetRef devices = HIDJoystickManager::getInstance().copyJoysticks();
|
||||||
if (devices == NULL) {
|
if (devices == NULL)
|
||||||
return disconnectedState;
|
return disconnectedState;
|
||||||
}
|
|
||||||
|
|
||||||
// Get a usable copy of the joysticks devices.
|
// Get a usable copy of the joysticks devices.
|
||||||
CFIndex joysticksCount = CFSetGetCount(devices);
|
CFIndex joysticksCount = CFSetGetCount(devices);
|
||||||
@ -340,9 +319,11 @@ JoystickState JoystickImpl::update()
|
|||||||
|
|
||||||
// Search for it
|
// Search for it
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (CFIndex i(0); i < joysticksCount; ++i) {
|
for (CFIndex i(0); i < joysticksCount; ++i)
|
||||||
|
{
|
||||||
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
|
IOHIDDeviceRef d = (IOHIDDeviceRef)devicesArray[i];
|
||||||
if (selfLoc == HIDInputManager::getLocationID(d)) {
|
if (selfLoc == HIDInputManager::getLocationID(d))
|
||||||
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break; // Stop looping
|
break; // Stop looping
|
||||||
}
|
}
|
||||||
@ -351,23 +332,21 @@ JoystickState JoystickImpl::update()
|
|||||||
// Release unused stuff
|
// Release unused stuff
|
||||||
CFRelease(devices);
|
CFRelease(devices);
|
||||||
|
|
||||||
// Was it found ?
|
// If not found we consider it disconnected
|
||||||
if (found) {
|
if (!found)
|
||||||
// Yes, so we can continue.
|
|
||||||
} else {
|
|
||||||
// No, so we stop here
|
|
||||||
return disconnectedState;
|
return disconnectedState;
|
||||||
}
|
|
||||||
|
|
||||||
// Update buttons' state
|
// Update buttons' state
|
||||||
unsigned int i = 0;
|
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;
|
IOHIDValueRef value = 0;
|
||||||
IOHIDDeviceGetValue(IOHIDElementGetDevice(*it), *it, &value);
|
IOHIDDeviceGetValue(IOHIDElementGetDevice(*it), *it, &value);
|
||||||
|
|
||||||
// Check for plug out.
|
// Check for plug out.
|
||||||
if (!value) {
|
if (!value)
|
||||||
// No value ? Hum... Seems like the joystick is gone
|
{
|
||||||
|
// No value? Hum... Seems like the joystick is gone
|
||||||
return disconnectedState;
|
return disconnectedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,19 +355,21 @@ JoystickState JoystickImpl::update()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update axes' state
|
// 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;
|
IOHIDValueRef value = 0;
|
||||||
IOHIDDeviceGetValue(IOHIDElementGetDevice(it->second), it->second, &value);
|
IOHIDDeviceGetValue(IOHIDElementGetDevice(it->second), it->second, &value);
|
||||||
|
|
||||||
// Check for plug out.
|
// Check for plug out.
|
||||||
if (!value) {
|
if (!value)
|
||||||
// No value ? Hum... Seems like the joystick is gone
|
{
|
||||||
|
// No value? Hum... Seems like the joystick is gone
|
||||||
return disconnectedState;
|
return disconnectedState;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want to bind [physicalMin,physicalMax] to [-100=min,100=max].
|
// 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]
|
// f : [a, b] -> [c, d]
|
||||||
// x |-> (x-a)(d-c)/(b-a)+c
|
// x |-> (x-a)(d-c)/(b-a)+c
|
||||||
@ -401,11 +382,10 @@ JoystickState JoystickImpl::update()
|
|||||||
double scaledMin = -100;
|
double scaledMin = -100;
|
||||||
double scaledMax = 100;
|
double scaledMax = 100;
|
||||||
double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
|
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;
|
state.axes[it->first] = scaledValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -414,13 +394,13 @@ JoystickState JoystickImpl::update()
|
|||||||
std::string JoystickImpl::getDeviceString(IOHIDDeviceRef ref, CFStringRef prop)
|
std::string JoystickImpl::getDeviceString(IOHIDDeviceRef ref, CFStringRef prop)
|
||||||
{
|
{
|
||||||
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
|
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
|
||||||
if (ref && CFGetTypeID(typeRef) == CFStringGetTypeID())
|
if (ref && (CFGetTypeID(typeRef) == CFStringGetTypeID()))
|
||||||
{
|
{
|
||||||
CFStringRef str = static_cast<CFStringRef>(typeRef);
|
CFStringRef str = static_cast<CFStringRef>(typeRef);
|
||||||
return stringFromCFString(str);
|
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";
|
return "Unknown Joystick";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,14 +409,14 @@ std::string JoystickImpl::getDeviceString(IOHIDDeviceRef ref, CFStringRef prop)
|
|||||||
unsigned int JoystickImpl::getDeviceUint(IOHIDDeviceRef ref, CFStringRef prop)
|
unsigned int JoystickImpl::getDeviceUint(IOHIDDeviceRef ref, CFStringRef prop)
|
||||||
{
|
{
|
||||||
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
|
CFTypeRef typeRef = IOHIDDeviceGetProperty(ref, prop);
|
||||||
if (ref && CFGetTypeID(typeRef) == CFNumberGetTypeID())
|
if (ref && (CFGetTypeID(typeRef) == CFNumberGetTypeID()))
|
||||||
{
|
{
|
||||||
SInt32 value;
|
SInt32 value;
|
||||||
CFNumberGetValue((CFNumberRef)typeRef, kCFNumberSInt32Type, &value);
|
CFNumberGetValue((CFNumberRef)typeRef, kCFNumberSInt32Type, &value);
|
||||||
return 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ private :
|
|||||||
/// \param ref HID device
|
/// \param ref HID device
|
||||||
/// \param prop Property to retrieve from the 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);
|
std::string getDeviceString(IOHIDDeviceRef ref, CFStringRef prop);
|
||||||
@ -130,7 +130,7 @@ private :
|
|||||||
/// \param ref HID device
|
/// \param ref HID device
|
||||||
/// \param prop Property to retrieve from the 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);
|
unsigned int getDeviceUint(IOHIDDeviceRef ref, CFStringRef prop);
|
||||||
@ -141,6 +141,7 @@ private :
|
|||||||
/// \param cfString CFStringRef to convert
|
/// \param cfString CFStringRef to convert
|
||||||
///
|
///
|
||||||
/// \return std::string
|
/// \return std::string
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
std::string stringFromCFString(CFStringRef cfString);
|
std::string stringFromCFString(CFStringRef cfString);
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Event processing & Menu bar initialisation
|
/// \brief Event processing & Menu bar initialisation
|
||||||
@ -55,8 +55,9 @@
|
|||||||
///
|
///
|
||||||
/// This overload of -[NSApplication sendEvent:] is used to
|
/// This overload of -[NSApplication sendEvent:] is used to
|
||||||
/// fix KeyRelease events when the command key is down.
|
/// fix KeyRelease events when the command key is down.
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)sendEvent:(NSEvent *)anEvent;
|
-(void)sendEvent:(NSEvent*)anEvent;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -56,7 +56,8 @@
|
|||||||
|
|
||||||
// Set the main menu bar
|
// Set the main menu bar
|
||||||
NSMenu* mainMenu = [NSApp mainMenu];
|
NSMenu* mainMenu = [NSApp mainMenu];
|
||||||
if (mainMenu != nil) return;
|
if (mainMenu != nil)
|
||||||
|
return;
|
||||||
mainMenu = [[NSMenu alloc] initWithTitle:@""];
|
mainMenu = [[NSMenu alloc] initWithTitle:@""];
|
||||||
[NSApp setMainMenu:mainMenu];
|
[NSApp setMainMenu:mainMenu];
|
||||||
|
|
||||||
@ -79,7 +80,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
+(NSMenu *)createAppleMenu
|
+(NSMenu*)createAppleMenu
|
||||||
{
|
{
|
||||||
// Apple menu is as follow:
|
// Apple menu is as follow:
|
||||||
//
|
//
|
||||||
@ -158,7 +159,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
+(NSMenu *)createFileMenu
|
+(NSMenu*)createFileMenu
|
||||||
{
|
{
|
||||||
// The File menu is as follow:
|
// The File menu is as follow:
|
||||||
//
|
//
|
||||||
@ -180,7 +181,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
+(NSMenu *)createWindowMenu
|
+(NSMenu*)createWindowMenu
|
||||||
{
|
{
|
||||||
// The Window menu is as follow:
|
// The Window menu is as follow:
|
||||||
//
|
//
|
||||||
@ -218,20 +219,18 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
+(NSString *)applicationName
|
+(NSString*)applicationName
|
||||||
{
|
{
|
||||||
// First, try localized name
|
// First, try localized name
|
||||||
NSString* appName = [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"];
|
NSString* appName = [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:@"CFBundleDisplayName"];
|
||||||
|
|
||||||
// Then, try non-localized name
|
// Then, try non-localized name
|
||||||
if (appName == nil || [appName length] == 0) {
|
if ((appName == nil) || ([appName length] == 0))
|
||||||
appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, fallback to the process info
|
// Finally, fallback to the process info
|
||||||
if (appName == nil || [appName length] == 0) {
|
if ((appName == nil) || ([appName length] == 0))
|
||||||
appName = [[NSProcessInfo processInfo] processName];
|
appName = [[NSProcessInfo processInfo] processName];
|
||||||
}
|
|
||||||
|
|
||||||
return appName;
|
return appName;
|
||||||
}
|
}
|
||||||
@ -252,8 +251,7 @@
|
|||||||
// custom OpenGL view. See -[SFOpenGLView sfKeyUp:] for more details.
|
// custom OpenGL view. See -[SFOpenGLView sfKeyUp:] for more details.
|
||||||
|
|
||||||
id firstResponder = [[anEvent window] firstResponder];
|
id firstResponder = [[anEvent window] firstResponder];
|
||||||
if ([anEvent type] != NSKeyUp
|
if (([anEvent type] != NSKeyUp) || (![firstResponder tryToPerform:@selector(sfKeyUp:) with:anEvent])) {
|
||||||
|| ![firstResponder tryToPerform:@selector(sfKeyUp:) with:anEvent]) {
|
|
||||||
// It's either not a key up event or no responder has a sfKeyUp
|
// It's either not a key up event or no responder has a sfKeyUp
|
||||||
// message implemented.
|
// message implemented.
|
||||||
[super sendEvent:anEvent];
|
[super sendEvent:anEvent];
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -36,7 +36,18 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@interface SFApplicationDelegate : NSObject <NSApplicationDelegate>
|
@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
|
@end
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
|
-(NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
|
||||||
{
|
{
|
||||||
// TODO generate close event for each SFML window
|
// TODO generate close event for each SFML window
|
||||||
[NSApp makeWindowsPerform:@selector(sfClose) inOrder:NO];
|
[NSApp makeWindowsPerform:@selector(sfClose) inOrder:NO];
|
||||||
@ -42,7 +42,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
|
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)theApplication
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,9 @@ namespace priv
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFContext::SFContext(SFContext* shared)
|
SFContext::SFContext(SFContext* shared) :
|
||||||
: m_view(0), m_window(0)
|
m_view(0),
|
||||||
|
m_window(0)
|
||||||
{
|
{
|
||||||
// Ask for a pool.
|
// Ask for a pool.
|
||||||
retainPool();
|
retainPool();
|
||||||
@ -54,8 +55,9 @@ SFContext::SFContext(SFContext* shared)
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
|
SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
|
||||||
const WindowImpl* owner, unsigned int bitsPerPixel)
|
const WindowImpl* owner, unsigned int bitsPerPixel) :
|
||||||
: m_view(0), m_window(0)
|
m_view(0),
|
||||||
|
m_window(0)
|
||||||
{
|
{
|
||||||
// Ask for a pool.
|
// Ask for a pool.
|
||||||
retainPool();
|
retainPool();
|
||||||
@ -64,15 +66,16 @@ SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
|
|||||||
createContext(shared, bitsPerPixel, settings);
|
createContext(shared, bitsPerPixel, settings);
|
||||||
|
|
||||||
// Apply context.
|
// Apply context.
|
||||||
WindowImplCocoa const * ownerCocoa = static_cast<WindowImplCocoa const *>(owner);
|
const WindowImplCocoa* ownerCocoa = static_cast<const WindowImplCocoa*>(owner);
|
||||||
ownerCocoa->applyContext(m_context);
|
ownerCocoa->applyContext(m_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
|
SFContext::SFContext(SFContext* shared, const ContextSettings& settings,
|
||||||
unsigned int width, unsigned int height)
|
unsigned int width, unsigned int height) :
|
||||||
: m_view(0), m_window(0)
|
m_view(0),
|
||||||
|
m_window(0)
|
||||||
{
|
{
|
||||||
// Ensure the process is setup in order to create a valid window.
|
// Ensure the process is setup in order to create a valid window.
|
||||||
WindowImplCocoa::setUpProcess();
|
WindowImplCocoa::setUpProcess();
|
||||||
@ -142,16 +145,17 @@ void SFContext::createContext(SFContext* shared,
|
|||||||
unsigned int bitsPerPixel,
|
unsigned int bitsPerPixel,
|
||||||
const ContextSettings& settings)
|
const ContextSettings& settings)
|
||||||
{
|
{
|
||||||
// Choose the attributs of OGL context.
|
// Choose the attributes of OGL context.
|
||||||
std::vector<NSOpenGLPixelFormatAttribute> attrs;
|
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.
|
// These casts are safe. C++ is much more strict than Obj-C.
|
||||||
|
|
||||||
attrs.push_back(NSOpenGLPFAClosestPolicy);
|
attrs.push_back(NSOpenGLPFAClosestPolicy);
|
||||||
attrs.push_back(NSOpenGLPFADoubleBuffer);
|
attrs.push_back(NSOpenGLPFADoubleBuffer);
|
||||||
|
|
||||||
if (bitsPerPixel > 24) {
|
if (bitsPerPixel > 24)
|
||||||
|
{
|
||||||
attrs.push_back(NSOpenGLPFAAlphaSize);
|
attrs.push_back(NSOpenGLPFAAlphaSize);
|
||||||
attrs.push_back((NSOpenGLPixelFormatAttribute)8);
|
attrs.push_back((NSOpenGLPixelFormatAttribute)8);
|
||||||
}
|
}
|
||||||
@ -162,7 +166,8 @@ void SFContext::createContext(SFContext* shared,
|
|||||||
attrs.push_back(NSOpenGLPFAStencilSize);
|
attrs.push_back(NSOpenGLPFAStencilSize);
|
||||||
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.stencilBits);
|
attrs.push_back((NSOpenGLPixelFormatAttribute)settings.stencilBits);
|
||||||
|
|
||||||
if (settings.antialiasingLevel > 0) {
|
if (settings.antialiasingLevel > 0)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Antialiasing techniques are described in the
|
* Antialiasing techniques are described in the
|
||||||
* "OpenGL Programming Guide for Mac OS X" document.
|
* "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
|
attrs.push_back((NSOpenGLPixelFormatAttribute)0); // end of array
|
||||||
|
|
||||||
// Create the pixel pormat.
|
// Create the pixel format.
|
||||||
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attrs[0]];
|
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;
|
sf::err() << "Error. Unable to find a suitable pixel format." << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -206,9 +212,8 @@ void SFContext::createContext(SFContext* shared,
|
|||||||
m_context = [[NSOpenGLContext alloc] initWithFormat:pixFmt
|
m_context = [[NSOpenGLContext alloc] initWithFormat:pixFmt
|
||||||
shareContext:sharedContext];
|
shareContext:sharedContext];
|
||||||
|
|
||||||
if (m_context == nil) {
|
if (m_context == nil)
|
||||||
sf::err() << "Error. Unable to create the context." << std::endl;
|
sf::err() << "Error. Unable to create the context." << std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
// Free up.
|
// Free up.
|
||||||
[pixFmt release];
|
[pixFmt release];
|
||||||
|
@ -44,24 +44,25 @@ namespace sf {
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Init the global state (only if needed). It needs to be
|
/// \brief Initialize the global state (only if needed)
|
||||||
/// Called before any event, e.g. in the window constructor.
|
///
|
||||||
|
/// 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
|
/// \brief Set up a SFML key event based on the given modifiers flags and key code
|
||||||
/// flags and key code.
|
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key);
|
sf::Event::KeyEvent keyEventWithModifiers(NSUInteger modifiers, sf::Keyboard::Key key);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Handle the state of modifiers keys and send key
|
/// \brief Handle the state of modifiers keys
|
||||||
/// release & pressed events to the requester.
|
///
|
||||||
|
/// Send key released & pressed events to the requester.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& 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);
|
BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Handle one modifier key mask, update the key state and
|
/// \brief Handle one modifier key mask
|
||||||
/// send events to the requester
|
///
|
||||||
|
/// Update the key state and send events to the requester
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void processOneModifier(NSUInteger modifiers, NSUInteger mask,
|
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
|
/// \brief Handle left & right modifier keys
|
||||||
/// send events to the requester
|
///
|
||||||
|
/// Update the keys state and send events to the requester
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void processLeftRightModifiers(NSUInteger modifiers,
|
void processLeftRightModifiers(NSUInteger modifiers,
|
||||||
@ -113,7 +115,7 @@ void processLeftRightModifiers(NSUInteger modifiers,
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
void initialiseKeyboardHelper()
|
void initialiseKeyboardHelper(void)
|
||||||
{
|
{
|
||||||
if (isStateInitialized) return;
|
if (isStateInitialized) return;
|
||||||
|
|
||||||
@ -210,13 +212,13 @@ void processOneModifier(NSUInteger modifiers, NSUInteger mask,
|
|||||||
BOOL isDown = isKeyMaskActive(modifiers, mask);
|
BOOL isDown = isKeyMaskActive(modifiers, mask);
|
||||||
|
|
||||||
// Check for key pressed event
|
// Check for key pressed event
|
||||||
if (isDown && !wasDown) {
|
if (isDown && !wasDown)
|
||||||
requester.keyDown(event);
|
requester.keyDown(event);
|
||||||
}
|
|
||||||
// And check for key released event
|
// And check for key released event
|
||||||
else if (!isDown && wasDown) {
|
else if (!isDown && wasDown)
|
||||||
requester.keyUp(event);
|
requester.keyUp(event);
|
||||||
}
|
|
||||||
// else isDown == wasDown, so no change
|
// else isDown == wasDown, so no change
|
||||||
|
|
||||||
// Update state
|
// Update state
|
||||||
|
@ -46,7 +46,7 @@ namespace sf {
|
|||||||
/// The SFWindowController should call -[SFOpenGLView exitFullscreen]
|
/// The SFWindowController should call -[SFOpenGLView exitFullscreen]
|
||||||
/// and -[SFOpenGLView enterFullscreen] when appropriate.
|
/// 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
|
/// the window is in fullscreen we use m_realSize to represent the
|
||||||
/// back buffer size (see SFWindowController). If 'm_realSize' is
|
/// back buffer size (see SFWindowController). If 'm_realSize' is
|
||||||
/// bound to its default value we don't recompute the mouse position
|
/// 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).
|
/// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm).
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@interface SFOpenGLView : NSOpenGLView {
|
@interface SFOpenGLView : NSOpenGLView
|
||||||
sf::priv::WindowImplCocoa* m_requester;
|
{
|
||||||
BOOL m_useKeyRepeat;
|
sf::priv::WindowImplCocoa* m_requester; ///< View's requester
|
||||||
BOOL m_mouseIsIn;
|
BOOL m_useKeyRepeat; ///< Key repeat setting
|
||||||
NSTrackingArea* m_trackingArea;
|
BOOL m_mouseIsIn; ///< Mouse positional state
|
||||||
NSSize m_realSize;
|
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.
|
// Hidden text view used to convert key event to actual chars.
|
||||||
// We use a silent responder to prevent sound alerts.
|
// 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;
|
-(id)initWithFrame:(NSRect)frameRect;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Handle going in and out of fullscreen mode.
|
/// \brief Handle going in fullscreen mode
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)enterFullscreen;
|
-(void)enterFullscreen;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Handle exiting fullscreen mode
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
-(void)exitFullscreen;
|
-(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
|
/// If not set, or set to its default value NSZeroSize, the view
|
||||||
/// won't recompute the mouse coordinates before sending them
|
/// won't recompute the mouse coordinates before sending them
|
||||||
/// to the requester.
|
/// to the requester.
|
||||||
///
|
///
|
||||||
|
/// \param newSize actual size of the view
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)setRealSize:(NSSize)newSize;
|
-(void)setRealSize:(NSSize)newSize;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Compute the position in global coordinate
|
/// \brief Compute the position in global coordinate
|
||||||
/// of the given point in SFML coordinate.
|
///
|
||||||
|
/// \param point a point in SFML coordinate
|
||||||
|
///
|
||||||
|
/// \return the global coordinates of the point
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point;
|
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Adjust key repeat configuration.
|
/// \brief Enable key repeat
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)enableKeyRepeat;
|
-(void)enableKeyRepeat;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Disable key repeat
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
-(void)disableKeyRepeat;
|
-(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
|
@end
|
||||||
|
@ -30,62 +30,74 @@
|
|||||||
#include <SFML/Window/OSX/HIDInputManager.hpp> // For localizedKeys and nonLocalizedKeys
|
#include <SFML/Window/OSX/HIDInputManager.hpp> // For localizedKeys and nonLocalizedKeys
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
|
||||||
|
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
|
||||||
#import <SFML/Window/OSX/SFOpenGLView.h>
|
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||||
#import <SFML/Window/OSX/SFSilentResponder.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.
|
/// 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);
|
BOOL isValidTextUnicode(NSEvent* event);
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// SFOpenGLView class : Privates Methods Declaration
|
/// SFOpenGLView class: Privates Methods Declaration
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@interface SFOpenGLView ()
|
@interface SFOpenGLView ()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Handle view resized event.
|
/// \brief Handle view resized event
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)viewDidEndLiveResize;
|
-(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;
|
-(BOOL)isMouseInside;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Update the mouse state (in or out) and fire an event
|
/// \brief Update the mouse state (in or out)
|
||||||
/// if its state has changed.
|
///
|
||||||
|
/// Fire an event if its state has changed.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)updateMouseState;
|
-(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.
|
/// \brief Convert a key down/up NSEvent into an SFML key event
|
||||||
/// Based on localizedKeys and nonLocalizedKeys function.
|
|
||||||
///
|
///
|
||||||
/// 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
|
@end
|
||||||
|
|
||||||
@ -97,7 +109,8 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(id)initWithFrame:(NSRect)frameRect
|
-(id)initWithFrame:(NSRect)frameRect
|
||||||
{
|
{
|
||||||
if ((self = [super initWithFrame:frameRect])) {
|
if ((self = [super initWithFrame:frameRect]))
|
||||||
|
{
|
||||||
[self setRequesterTo:0];
|
[self setRequesterTo:0];
|
||||||
[self enableKeyRepeat];
|
[self enableKeyRepeat];
|
||||||
m_realSize = NSZeroSize;
|
m_realSize = NSZeroSize;
|
||||||
@ -130,9 +143,8 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
[self addTrackingArea:m_trackingArea];
|
[self addTrackingArea:m_trackingArea];
|
||||||
|
|
||||||
// Fire an mouse entered event if needed
|
// Fire an mouse entered event if needed
|
||||||
if (!m_mouseIsIn && m_requester != 0) {
|
if (!m_mouseIsIn && (m_requester != 0))
|
||||||
m_requester->mouseMovedIn();
|
m_requester->mouseMovedIn();
|
||||||
}
|
|
||||||
|
|
||||||
// Update status
|
// Update status
|
||||||
m_mouseIsIn = YES;
|
m_mouseIsIn = YES;
|
||||||
@ -145,9 +157,8 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
[self removeTrackingArea:m_trackingArea];
|
[self removeTrackingArea:m_trackingArea];
|
||||||
|
|
||||||
// Fire an mouse left event if needed
|
// Fire an mouse left event if needed
|
||||||
if (m_mouseIsIn && m_requester != 0) {
|
if (m_mouseIsIn && (m_requester != 0))
|
||||||
m_requester->mouseMovedOut();
|
m_requester->mouseMovedOut();
|
||||||
}
|
|
||||||
|
|
||||||
// Update status
|
// Update status
|
||||||
m_mouseIsIn = NO;
|
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;
|
m_requester = requester;
|
||||||
}
|
}
|
||||||
@ -172,9 +183,10 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point
|
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point
|
||||||
{
|
{
|
||||||
// Recompute the mouse pos if required.
|
// Recompute the mouse pos if required.
|
||||||
if (!NSEqualSizes(m_realSize, NSZeroSize)) {
|
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;
|
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
|
// Note : -[NSWindow convertBaseToScreen:] is deprecated on 10.7
|
||||||
@ -194,8 +206,8 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
// Convert it to screen coordinates
|
// Convert it to screen coordinates
|
||||||
point = [[self window] convertBaseToScreen:point];
|
point = [[self window] convertBaseToScreen:point];
|
||||||
|
|
||||||
// Flip screen coodinates to match CGDisplayMoveCursorToPoint referential.
|
// Flip screen coordinates to match CGDisplayMoveCursorToPoint referential.
|
||||||
float const screenHeight = [[[self window] screen] frame].size.height;
|
const float screenHeight = [[[self window] screen] frame].size.height;
|
||||||
point.y = screenHeight - point.y;
|
point.y = screenHeight - point.y;
|
||||||
|
|
||||||
return point;
|
return point;
|
||||||
@ -237,7 +249,8 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
[self update];
|
[self update];
|
||||||
|
|
||||||
// Send an event
|
// Send an event
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// The new size
|
// The new size
|
||||||
NSSize newSize = [self frame].size;
|
NSSize newSize = [self frame].size;
|
||||||
@ -251,11 +264,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
|
NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
|
||||||
NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
|
NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
|
||||||
|
|
||||||
if (NSPointInRect(relativeToView, [self frame])) {
|
return NSPointInRect(relativeToView, [self frame]);
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -266,11 +275,10 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
m_mouseIsIn = [self isMouseInside];
|
m_mouseIsIn = [self isMouseInside];
|
||||||
|
|
||||||
// Send event if needed.
|
// Send event if needed.
|
||||||
if (mouseWasIn && !m_mouseIsIn) {
|
if (mouseWasIn && !m_mouseIsIn)
|
||||||
[self mouseExited:nil];
|
[self mouseExited:nil];
|
||||||
} else if (!mouseWasIn && m_mouseIsIn) {
|
else if (!mouseWasIn && m_mouseIsIn)
|
||||||
[self mouseEntered:nil];
|
[self mouseEntered:nil];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -316,7 +324,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)mouseDown:(NSEvent *)theEvent
|
-(void)mouseDown:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Forward to...
|
// Forward to...
|
||||||
[self otherMouseDown:theEvent];
|
[self otherMouseDown:theEvent];
|
||||||
@ -327,7 +335,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)mouseUp:(NSEvent *)theEvent
|
-(void)mouseUp:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Forward to...
|
// Forward to...
|
||||||
[self otherMouseUp:theEvent];
|
[self otherMouseUp:theEvent];
|
||||||
@ -338,7 +346,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)mouseMoved:(NSEvent *)theEvent
|
-(void)mouseMoved:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Forward to...
|
// Forward to...
|
||||||
[self otherMouseDragged:theEvent];
|
[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];
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
|
||||||
m_requester->mouseWheelScrolledAt([theEvent deltaY], loc.x, loc.y);
|
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:
|
// There are two cases when we need to fire an event:
|
||||||
// a) the event is nil, meaning that the method was
|
// a) the event is nil, meaning that the method was
|
||||||
// called from our code (e.g. updateMouseState)
|
// called from our code (e.g. updateMouseState)
|
||||||
// b) the mouse was outside the view.
|
// b) the mouse was outside the view.
|
||||||
BOOL shouldFire = (theEvent == nil || m_mouseIsIn == NO);
|
BOOL shouldFire = ((theEvent == nil) || (m_mouseIsIn == NO));
|
||||||
|
|
||||||
// Update status
|
// Update status
|
||||||
m_mouseIsIn = YES;
|
m_mouseIsIn = YES;
|
||||||
|
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// Fire (or not) an event
|
// Fire (or not) an event
|
||||||
if (shouldFire) {
|
if (shouldFire)
|
||||||
m_requester->mouseMovedIn();
|
m_requester->mouseMovedIn();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)mouseExited:(NSEvent *)theEvent
|
-(void)mouseExited:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Similarly to mouseEntered:
|
// Similarly to mouseEntered:
|
||||||
BOOL shouldFire = (theEvent == nil || m_mouseIsIn == YES);
|
BOOL shouldFire = ((theEvent == nil) || (m_mouseIsIn == YES));
|
||||||
|
|
||||||
// Update status
|
// Update status
|
||||||
m_mouseIsIn = NO;
|
m_mouseIsIn = NO;
|
||||||
|
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// Fire (or not) an event
|
// Fire (or not) an event
|
||||||
if (shouldFire) {
|
if (shouldFire)
|
||||||
m_requester->mouseMovedOut();
|
m_requester->mouseMovedOut();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)rightMouseDown:(NSEvent *)theEvent
|
-(void)rightMouseDown:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Forward to...
|
// Forward to...
|
||||||
[self otherMouseDown:theEvent];
|
[self otherMouseDown:theEvent];
|
||||||
@ -413,7 +421,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)rightMouseUp:(NSEvent *)theEvent
|
-(void)rightMouseUp:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Forward to...
|
// Forward to...
|
||||||
[self otherMouseUp:theEvent];
|
[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];
|
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
||||||
|
|
||||||
if (m_requester != 0) {
|
if (m_requester != 0)
|
||||||
|
{
|
||||||
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
|
||||||
if (button != sf::Mouse::ButtonCount) {
|
if (button != sf::Mouse::ButtonCount)
|
||||||
m_requester->mouseDownAt(button, loc.x, loc.y);
|
m_requester->mouseDownAt(button, loc.x, loc.y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the event is not forwarded by mouseDown or rightMouseDown...
|
// 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
|
// ... transmit to non-SFML responder
|
||||||
[[self nextResponder] otherMouseDown:theEvent];
|
[[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];
|
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
||||||
|
|
||||||
if (m_requester != 0) {
|
if (m_requester != 0)
|
||||||
|
{
|
||||||
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
|
||||||
if (button != sf::Mouse::ButtonCount) {
|
if (button != sf::Mouse::ButtonCount)
|
||||||
m_requester->mouseUpAt(button, loc.x, loc.y);
|
m_requester->mouseUpAt(button, loc.x, loc.y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the event is not forwarded by mouseUp or rightMouseUp...
|
// 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
|
// ... transmit to non-SFML responder
|
||||||
[[self nextResponder] otherMouseUp:theEvent];
|
[[self nextResponder] otherMouseUp:theEvent];
|
||||||
}
|
}
|
||||||
@ -466,7 +476,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)rightMouseDragged:(NSEvent *)theEvent
|
-(void)rightMouseDragged:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Forward to...
|
// Forward to...
|
||||||
[self otherMouseDragged:theEvent];
|
[self otherMouseDragged:theEvent];
|
||||||
@ -477,7 +487,7 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)mouseDragged:(NSEvent *)theEvent
|
-(void)mouseDragged:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Forward to...
|
// Forward to...
|
||||||
[self otherMouseDragged:theEvent];
|
[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];
|
NSPoint loc = [self cursorPositionFromEvent:theEvent];
|
||||||
|
|
||||||
// Make sure the point is inside the view.
|
// Make sure the point is inside the view.
|
||||||
// (mouseEntered: and mouseExited: are not immediately called
|
// (mouseEntered: and mouseExited: are not immediately called
|
||||||
// when the mouse is dragged. That would be too easy!)
|
// when the mouse is dragged. That would be too easy!)
|
||||||
[self updateMouseState];
|
[self updateMouseState];
|
||||||
if (m_mouseIsIn) {
|
if (m_mouseIsIn)
|
||||||
m_requester->mouseMovedAt(loc.x, loc.y);
|
m_requester->mouseMovedAt(loc.x, loc.y);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// If the event is not forwarded by mouseDragged or rightMouseDragged...
|
// If the event is not forwarded by mouseDragged or rightMouseDragged...
|
||||||
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
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
|
// ... transmit to non-SFML responder
|
||||||
[[self nextResponder] otherMouseUp:theEvent];
|
[[self nextResponder] otherMouseUp:theEvent];
|
||||||
}
|
}
|
||||||
@ -512,14 +523,17 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(NSPoint)cursorPositionFromEvent:(NSEvent *)eventOrNil
|
-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil
|
||||||
{
|
{
|
||||||
NSPoint loc;
|
NSPoint loc;
|
||||||
// If no event given then get current mouse pos.
|
// If no event given then get current mouse pos.
|
||||||
if (eventOrNil == nil) {
|
if (eventOrNil == nil)
|
||||||
|
{
|
||||||
NSPoint rawPos = [[self window] mouseLocationOutsideOfEventStream];
|
NSPoint rawPos = [[self window] mouseLocationOutsideOfEventStream];
|
||||||
loc = [self convertPoint:rawPos fromView:nil];
|
loc = [self convertPoint:rawPos fromView:nil];
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
loc = [self convertPoint:[eventOrNil locationInWindow] fromView:nil];
|
loc = [self convertPoint:[eventOrNil locationInWindow] fromView:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,9 +542,10 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
loc.y = h - loc.y;
|
loc.y = h - loc.y;
|
||||||
|
|
||||||
// Recompute the mouse pos if required.
|
// Recompute the mouse pos if required.
|
||||||
if (!NSEqualSizes(m_realSize, NSZeroSize)) {
|
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;
|
loc.x = (loc.x * m_realSize.width) / [self frame].size.width;
|
||||||
|
loc.y = (loc.y * m_realSize.height) / [self frame].size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
return loc;
|
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 0: return sf::Mouse::Left;
|
||||||
case 1: return sf::Mouse::Right;
|
case 1: return sf::Mouse::Right;
|
||||||
case 2: return sf::Mouse::Middle;
|
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
|
// Transmit to non-SFML responder
|
||||||
[[self nextResponder] keyDown:theEvent];
|
[[self nextResponder] keyDown:theEvent];
|
||||||
|
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
// Handle key down event
|
// Handle key down event
|
||||||
if (m_useKeyRepeat || ![theEvent isARepeat]) {
|
if (m_useKeyRepeat || ![theEvent isARepeat])
|
||||||
|
{
|
||||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
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);
|
m_requester->keyDown(key);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Handle text entred event:
|
// Handle text entred event:
|
||||||
// Ignore event if we don't want repeated keystrokes
|
// 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)
|
// Ignore escape key and other non text keycode (See NSEvent.h)
|
||||||
// because they produce a sound alert.
|
// because they produce a sound alert.
|
||||||
if (isValidTextUnicode(theEvent)) {
|
if (isValidTextUnicode(theEvent))
|
||||||
|
{
|
||||||
// Send the event to the hidden text view for processing
|
// Send the event to the hidden text view for processing
|
||||||
[m_hiddenTextView interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
[m_hiddenTextView interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
|
||||||
}
|
}
|
||||||
@ -591,25 +610,27 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
unsigned short keycode = [theEvent keyCode];
|
unsigned short keycode = [theEvent keyCode];
|
||||||
|
|
||||||
// Backspace
|
// Backspace
|
||||||
if (keycode == 0x33) {
|
if (keycode == 0x33)
|
||||||
|
{
|
||||||
// Send the correct unicode value (i.e. 8) instead of 127 (which is 'delete')
|
// Send the correct unicode value (i.e. 8) instead of 127 (which is 'delete')
|
||||||
m_requester->textEntered(8);
|
m_requester->textEntered(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete
|
// Delete
|
||||||
else if (keycode == 0x75 || keycode == NSDeleteFunctionKey) {
|
else if ((keycode == 0x75) || (keycode == NSDeleteFunctionKey))
|
||||||
|
{
|
||||||
// Instead of the value 63272 we send 127.
|
// Instead of the value 63272 we send 127.
|
||||||
m_requester->textEntered(127);
|
m_requester->textEntered(127);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, let's see what our hidden field has computed
|
// Otherwise, let's see what our hidden field has computed
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
NSString* string = [m_hiddenTextView string];
|
NSString* string = [m_hiddenTextView string];
|
||||||
|
|
||||||
// Send each character to SFML event requester
|
// 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]);
|
m_requester->textEntered([string characterAtIndex:index]);
|
||||||
}
|
|
||||||
|
|
||||||
// Empty our hidden cache
|
// Empty our hidden cache
|
||||||
[m_hiddenTextView setString:@""];
|
[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
|
// 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
|
// 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
|
// Transmit to non-SFML responder
|
||||||
[[self nextResponder] keyUp:theEvent];
|
[[self nextResponder] keyUp:theEvent];
|
||||||
|
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
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);
|
m_requester->keyUp(key);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)flagsChanged:(NSEvent *)theEvent
|
-(void)flagsChanged:(NSEvent*)theEvent
|
||||||
{
|
{
|
||||||
// Transmit to non-SFML responder
|
// Transmit to non-SFML responder
|
||||||
[[self nextResponder] flagsChanged:theEvent];
|
[[self nextResponder] flagsChanged:theEvent];
|
||||||
|
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
NSUInteger modifiers = [theEvent modifierFlags];
|
NSUInteger modifiers = [theEvent modifierFlags];
|
||||||
handleModifiersChanged(modifiers, *m_requester);
|
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
|
// Key code
|
||||||
sf::Keyboard::Key key = sf::Keyboard::Unknown;
|
sf::Keyboard::Key key = sf::Keyboard::Unknown;
|
||||||
|
|
||||||
// First we look if the key down is from a list of characters
|
// First we look if the key down is from a list of characters
|
||||||
// that depend on keyboard localization.
|
// that depend on keyboard localization.
|
||||||
NSString* string = [anEvent charactersIgnoringModifiers];
|
NSString* string = [event charactersIgnoringModifiers];
|
||||||
if ([string length] > 0) {
|
if ([string length] > 0)
|
||||||
key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
|
key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
|
||||||
}
|
|
||||||
|
|
||||||
// If the key is not a localized one, we try to find a corresponding code
|
// If the key is not a localized one, we try to find a corresponding code
|
||||||
// through virtual key code.
|
// through virtual key code.
|
||||||
if (key == sf::Keyboard::Unknown) {
|
if (key == sf::Keyboard::Unknown)
|
||||||
key = sf::priv::HIDInputManager::nonLocalizedKeys([anEvent keyCode]);
|
key = sf::priv::HIDInputManager::nonLocalizedKeys([event keyCode]);
|
||||||
}
|
|
||||||
|
|
||||||
//#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages.
|
//#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages.
|
||||||
// if (key.code == sf::Keyboard::Unknown) { // The key is unknown.
|
// if (key.code == sf::Keyboard::Unknown) { // The key is unknown.
|
||||||
// sf::err() << "This is an unknow key. Virtual key code is 0x"
|
// sf::err() << "This is an unknow key. Virtual key code is 0x"
|
||||||
// << std::hex
|
// << std::hex
|
||||||
// << [anEvent keyCode]
|
// << [event keyCode]
|
||||||
// << "."
|
// << "."
|
||||||
// << std::endl;
|
// << std::endl;
|
||||||
// }
|
// }
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
return keyEventWithModifiers([anEvent modifierFlags], key);
|
return keyEventWithModifiers([event modifierFlags], key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -693,12 +713,17 @@ BOOL isValidTextUnicode(NSEvent* event);
|
|||||||
|
|
||||||
BOOL isValidTextUnicode(NSEvent* event)
|
BOOL isValidTextUnicode(NSEvent* event)
|
||||||
{
|
{
|
||||||
if ([event keyCode] == 0x35) { // Escape
|
if ([event keyCode] == 0x35) // Escape
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
} else if ([[event characters] length] > 0) {
|
}
|
||||||
|
else if ([[event characters] length] > 0)
|
||||||
|
{
|
||||||
unichar code = [[event characters] characterAtIndex:0];
|
unichar code = [[event characters] characterAtIndex:0];
|
||||||
return code < 0xF700 || code > 0xF8FF;
|
return ((code < 0xF700) || (code > 0xF8FF));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
/// \brief Silent Responder used to prevent sound alert with key event
|
/// \brief Silent Responder used to prevent sound alert with key event
|
||||||
///
|
///
|
||||||
/// Mainly used by SFOpenGLView and its hidden text view.
|
/// Mainly used by SFOpenGLView and its hidden text view.
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@interface SFSilentResponder : NSResponder
|
@interface SFSilentResponder : NSResponder
|
||||||
|
|
||||||
|
@ -34,16 +34,25 @@
|
|||||||
@class SFOpenGLView;
|
@class SFOpenGLView;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Implementation of WindowImplDelegateProtocol for view managment.
|
/// \brief Implementation of WindowImplDelegateProtocol for view management
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@interface SFViewController : NSObject <WindowImplDelegateProtocol> {
|
@interface SFViewController : NSObject <WindowImplDelegateProtocol>
|
||||||
NSView* m_view;
|
{
|
||||||
SFOpenGLView* m_oglView;
|
NSView* m_view; ///< Underlying Cocoa view
|
||||||
sf::priv::WindowImplCocoa* m_requester;
|
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
|
@end
|
||||||
|
@ -26,30 +26,29 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// 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/System/Err.hpp>
|
||||||
#include <SFML/Window/OSX/WindowImplCocoa.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
|
@implementation SFViewController
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(id)initWithView:(NSView *)view
|
-(id)initWithView:(NSView *)view
|
||||||
{
|
{
|
||||||
if ((self = [super init])) {
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
m_requester = 0;
|
m_requester = 0;
|
||||||
|
|
||||||
// Retain the view for our own use.
|
// Retain the view for our own use.
|
||||||
m_view = [view retain];
|
m_view = [view retain];
|
||||||
|
|
||||||
if (m_view == nil) {
|
if (m_view == nil)
|
||||||
|
{
|
||||||
sf::err()
|
sf::err() << "No view was given to initWithWindow:." << std::endl;
|
||||||
<< "No view was given to initWithWindow:."
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,10 +58,9 @@
|
|||||||
frame.origin.y = 0;
|
frame.origin.y = 0;
|
||||||
m_oglView = [[SFOpenGLView alloc] initWithFrame:frame];
|
m_oglView = [[SFOpenGLView alloc] initWithFrame:frame];
|
||||||
|
|
||||||
if (m_oglView == nil) {
|
if (m_oglView == nil)
|
||||||
|
{
|
||||||
sf::err()
|
sf::err() << "Could not create an instance of NSOpenGLView "
|
||||||
<< "Could not create an instance of NSOpenGLView "
|
|
||||||
<< "in (SFViewController -initWithView:)."
|
<< "in (SFViewController -initWithView:)."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
@ -92,7 +90,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester
|
-(void)setRequesterTo:(sf::priv::WindowImplCocoa*)requester
|
||||||
{
|
{
|
||||||
// Forward to the view.
|
// Forward to the view.
|
||||||
[m_oglView setRequesterTo:requester];
|
[m_oglView setRequesterTo:requester];
|
||||||
@ -132,7 +130,7 @@
|
|||||||
////////////////////////////////////////////////////////.
|
////////////////////////////////////////////////////////.
|
||||||
-(void)setWindowPositionToX:(int)x Y:(int)y
|
-(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;
|
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
|
-(void)setIconTo:(unsigned int)width
|
||||||
by:(unsigned int)height
|
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;
|
sf::err() << "Cannot set an icon when SFML is integrated in a NSView." << std::endl;
|
||||||
}
|
}
|
||||||
@ -211,27 +209,25 @@
|
|||||||
-(void)processEvent
|
-(void)processEvent
|
||||||
{
|
{
|
||||||
// If we are not on the main thread we stop here and advice the user.
|
// 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
|
* See http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00460.html
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
sf::err()
|
sf::err() << "Cannot fetch event from a worker thread. (OS X restriction)" << std::endl;
|
||||||
<< "Cannot fetch event from a worker thread. (OS X restriction)"
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have a requester we don't fetch event.
|
// If we don't have a requester we don't fetch event.
|
||||||
if (m_requester != 0) {
|
if (m_requester != 0)
|
||||||
[SFApplication processEvent];
|
[SFApplication processEvent];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)applyContext:(NSOpenGLContext *)context
|
-(void)applyContext:(NSOpenGLContext*)context
|
||||||
{
|
{
|
||||||
[m_oglView setOpenGLContext:context];
|
[m_oglView setOpenGLContext:context];
|
||||||
[context setView:m_oglView];
|
[context setView:m_oglView];
|
||||||
|
@ -29,36 +29,57 @@
|
|||||||
#import <AppKit/AppKit.h>
|
#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
|
@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
|
/// See http://stackoverflow.com/questions/999464/fullscreen-key-down-actions
|
||||||
/// for more informations
|
///
|
||||||
|
/// \return YES
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(BOOL)acceptsFirstResponder;
|
-(BOOL)acceptsFirstResponder;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Allow to grab fullscreen events
|
||||||
|
///
|
||||||
|
/// See acceptsFirstResponder documentation above.
|
||||||
|
///
|
||||||
|
/// \return YES
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
-(BOOL)canBecomeKeyWindow;
|
-(BOOL)canBecomeKeyWindow;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Override default implementation of keyDown: to prevent
|
/// \brief Prevent system alert
|
||||||
/// system alert
|
///
|
||||||
|
/// \param theEvent a Cocoa event
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)keyDown:(NSEvent *)theEvent;
|
-(void)keyDown:(NSEvent*)theEvent;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Extension of NSWindow
|
||||||
|
///
|
||||||
|
/// Add some extra messages for SFML internal usage.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
@interface NSWindow (SFML)
|
@interface NSWindow (SFML)
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Proxy for performClose: for the app delegate
|
/// Proxy for performClose: for the app delegate
|
||||||
///
|
///
|
||||||
/// Always return nil
|
/// \return nil
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(id)sfClose;
|
-(id)sfClose;
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#import "SFWindow.h"
|
#import <SFML/Window/OSX/SFWindow.h>
|
||||||
|
|
||||||
|
|
||||||
@implementation SFWindow
|
@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
|
// 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
|
// Consider overriding NSResponder -keyDown: message in a Cocoa view/window
|
||||||
// that contains a SFML rendering area. Doing so will prevent a system
|
// 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
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
|
|
||||||
#include <SFML/Window/VideoMode.hpp>
|
#include <SFML/Window/VideoMode.hpp>
|
||||||
|
|
||||||
|
#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Predefine some classes
|
/// Predefine some classes
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -41,7 +42,7 @@ namespace sf {
|
|||||||
@class SFOpenGLView;
|
@class SFOpenGLView;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Implementation of WindowImplDelegateProtocol for window managment.
|
/// \brief Implementation of WindowImplDelegateProtocol for window management
|
||||||
///
|
///
|
||||||
/// Key and mouse events are delegated to its view.
|
/// Key and mouse events are delegated to its view.
|
||||||
/// Window events are managed by this class.
|
/// 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
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060 // NSWindowDelegate is only define since 10.6
|
||||||
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol> {
|
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol>
|
||||||
#else
|
#else
|
||||||
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate> {
|
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate>
|
||||||
#endif
|
#endif
|
||||||
NSWindow* m_window;
|
{
|
||||||
SFOpenGLView* m_oglView;
|
NSWindow* m_window; ///< Underlying Cocoa window to be controlled
|
||||||
sf::priv::WindowImplCocoa* m_requester;
|
SFOpenGLView* m_oglView; ///< OpenGL view for rendering
|
||||||
sf::VideoMode* m_fullscreenMode; // Note : C++ ctor/dtor are not called for Obj-C fields.
|
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
|
@end
|
||||||
|
@ -26,33 +26,37 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
|
||||||
#include <SFML/Window/VideoMode.hpp>
|
#include <SFML/Window/VideoMode.hpp>
|
||||||
#include <SFML/Window/WindowHandle.hpp>
|
#include <SFML/Window/WindowHandle.hpp>
|
||||||
#include <SFML/Window/WindowStyle.hpp>
|
#include <SFML/Window/WindowStyle.hpp>
|
||||||
|
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
#include <ApplicationServices/ApplicationServices.h>
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
|
||||||
#import <SFML/Window/OSX/SFWindowController.h>
|
|
||||||
#import <SFML/Window/OSX/SFApplication.h>
|
#import <SFML/Window/OSX/SFApplication.h>
|
||||||
#import <SFML/Window/OSX/SFOpenGLView.h>
|
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||||
#import <SFML/Window/OSX/SFWindow.h>
|
#import <SFML/Window/OSX/SFWindow.h>
|
||||||
|
#import <SFML/Window/OSX/SFWindowController.h>
|
||||||
#import <OpenGL/OpenGL.h>
|
#import <OpenGL/OpenGL.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// SFWindowController class : Privates Methods Declaration
|
/// SFWindowController class: private interface
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@interface SFWindowController ()
|
@interface SFWindowController ()
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Retrieves the screen height.
|
/// \brief Retrieves the screen height
|
||||||
|
///
|
||||||
|
/// \return screen height
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(float)screenHeight;
|
-(float)screenHeight;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Retrives the title bar height.
|
/// \brief Retrieves the title bar height
|
||||||
|
///
|
||||||
|
/// \return title bar height
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(float)titlebarHeight;
|
-(float)titlebarHeight;
|
||||||
@ -65,34 +69,30 @@
|
|||||||
#pragma mark SFWindowController's methods
|
#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_requester = 0;
|
||||||
m_fullscreenMode = new sf::VideoMode();
|
m_fullscreenMode = new sf::VideoMode();
|
||||||
|
|
||||||
// Retain the window for our own use.
|
// Retain the window for our own use.
|
||||||
m_window = [window retain];
|
m_window = [window retain];
|
||||||
|
|
||||||
if (m_window == nil) {
|
if (m_window == nil)
|
||||||
|
{
|
||||||
sf::err()
|
sf::err() << "No window was given to initWithWindow:." << std::endl;
|
||||||
<< "No window was given to initWithWindow:."
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the view.
|
// Create the view.
|
||||||
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]];
|
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]];
|
||||||
|
|
||||||
if (m_oglView == nil) {
|
if (m_oglView == nil)
|
||||||
|
{
|
||||||
sf::err()
|
sf::err() << "Could not create an instance of NSOpenGLView "
|
||||||
<< "Could not create an instance of NSOpenGLView "
|
|
||||||
<< "in (SFWindowController -initWithWindow:)."
|
<< "in (SFWindowController -initWithWindow:)."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
return self;
|
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 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
|
* See http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00460.html
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
sf::err()
|
sf::err() << "Cannot create a window from a worker thread. (OS X limitation)" << std::endl;
|
||||||
<< "Cannot create a window from a worker thread. (OS X limitation)"
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((self = [super init])) {
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
m_requester = 0;
|
m_requester = 0;
|
||||||
m_fullscreenMode = new sf::VideoMode();
|
m_fullscreenMode = new sf::VideoMode();
|
||||||
|
|
||||||
// Create our window size.
|
// Create our window size.
|
||||||
NSRect rect = NSZeroRect;
|
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
|
// We use desktop mode to size the window
|
||||||
// but we set the back buffer size to 'mode' in applyContext method.
|
// but we set the back buffer size to 'mode' in applyContext method.
|
||||||
|
|
||||||
*m_fullscreenMode = mode;
|
*m_fullscreenMode = mode;
|
||||||
|
|
||||||
sf::VideoMode dm = sf::VideoMode::getDesktopMode();
|
sf::VideoMode dm = sf::VideoMode::getDesktopMode();
|
||||||
rect = NSMakeRect(0, 0, dm.width, dm.height);
|
rect = NSMakeRect(0, 0, dm.width, dm.height);
|
||||||
|
}
|
||||||
} else { // no fullscreen requested.
|
else
|
||||||
|
{
|
||||||
|
// no fullscreen requested.
|
||||||
rect = NSMakeRect(0, 0, mode.width, mode.height);
|
rect = NSMakeRect(0, 0, mode.width, mode.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the SFML window style to Cocoa window style.
|
// Convert the SFML window style to Cocoa window style.
|
||||||
unsigned int nsStyle = NSBorderlessWindowMask;
|
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,13 +169,13 @@
|
|||||||
|
|
||||||
[...]
|
[...]
|
||||||
As best as I can figure, this is happening because the NSWindow (and
|
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) {
|
if (m_window == nil)
|
||||||
sf::err()
|
{
|
||||||
<< "Could not create an instance of NSWindow "
|
sf::err() << "Could not create an instance of NSWindow "
|
||||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
@ -176,7 +183,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply special feature for fullscreen window.
|
// Apply special feature for fullscreen window.
|
||||||
if (style & sf::Style::Fullscreen) {
|
if (style & sf::Style::Fullscreen)
|
||||||
|
{
|
||||||
// We place the window above everything else.
|
// We place the window above everything else.
|
||||||
[m_window setOpaque:YES];
|
[m_window setOpaque:YES];
|
||||||
[m_window setHidesOnDeactivate:YES];
|
[m_window setHidesOnDeactivate:YES];
|
||||||
@ -195,15 +203,15 @@
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center the window to be cool =)
|
// Centre the window to be cool =)
|
||||||
[m_window center];
|
[m_window center];
|
||||||
|
|
||||||
// Create the view.
|
// Create the view.
|
||||||
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]];
|
m_oglView = [[SFOpenGLView alloc] initWithFrame:[[m_window contentView] frame]];
|
||||||
|
|
||||||
if (m_oglView == nil) {
|
if (m_oglView == nil)
|
||||||
sf::err()
|
{
|
||||||
<< "Could not create an instance of NSOpenGLView "
|
sf::err() << "Could not create an instance of NSOpenGLView "
|
||||||
<< "in (SFWindowController -initWithMode:andStyle:)."
|
<< "in (SFWindowController -initWithMode:andStyle:)."
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
@ -211,12 +219,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If a fullscreen window was requested...
|
// If a fullscreen window was requested...
|
||||||
if (style & sf::Style::Fullscreen) {
|
if (style & sf::Style::Fullscreen)
|
||||||
|
{
|
||||||
/// ... we tell the OpenGL view
|
/// ... we tell the OpenGL view
|
||||||
[m_oglView enterFullscreen];
|
[m_oglView enterFullscreen];
|
||||||
|
|
||||||
// ... and if the resolution is not the default one...
|
// ... 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).
|
// ... we set the "real size" of the view (that is the back buffer size).
|
||||||
[m_oglView setRealSize:NSMakeSize(m_fullscreenMode->width, m_fullscreenMode->height)];
|
[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.
|
// Forward to the view.
|
||||||
[m_oglView setRequesterTo:requester];
|
[m_oglView setRequesterTo:requester];
|
||||||
@ -291,21 +301,21 @@
|
|||||||
-(NSPoint)position
|
-(NSPoint)position
|
||||||
{
|
{
|
||||||
// First, get the top left corner of the view in its own base system
|
// First, get the top left corner of the view in its own base system
|
||||||
NSPoint const origin = [m_oglView frame].origin;
|
const NSPoint origin = [m_oglView frame].origin;
|
||||||
NSSize const size = [m_oglView frame].size;
|
const NSSize size = [m_oglView frame].size;
|
||||||
NSPoint const topLeftCornerOfView = NSMakePoint(origin.x, origin.y + size.height);
|
const NSPoint topLeftCornerOfView = NSMakePoint(origin.x, origin.y + size.height);
|
||||||
NSPoint const positionInView = [m_oglView convertPointToBase:topLeftCornerOfView];
|
const NSPoint positionInView = [m_oglView convertPointToBase:topLeftCornerOfView];
|
||||||
|
|
||||||
// Then, convert it to window base system
|
// 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
|
// here nil denotes the window containing the view
|
||||||
|
|
||||||
// Next, convert it to the screen base system
|
// 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
|
// Finally, flip for SFML window coordinate system
|
||||||
// Don't forget to discard the title bar !
|
// 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);
|
([self screenHeight] - [self titlebarHeight]) - positionInScreen.y);
|
||||||
|
|
||||||
return positionInSFML;
|
return positionInSFML;
|
||||||
@ -328,11 +338,10 @@
|
|||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(NSSize)size
|
-(NSSize)size
|
||||||
{
|
{
|
||||||
if (*m_fullscreenMode == sf::VideoMode()) {
|
if (*m_fullscreenMode == sf::VideoMode())
|
||||||
return [m_oglView frame].size;
|
return [m_oglView frame].size;
|
||||||
} else {
|
else
|
||||||
return NSMakeSize(m_fullscreenMode->width, m_fullscreenMode->height);
|
return NSMakeSize(m_fullscreenMode->width, m_fullscreenMode->height);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -359,7 +368,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)changeTitle:(NSString *)title
|
-(void)changeTitle:(NSString*)title
|
||||||
{
|
{
|
||||||
[m_window setTitle:title];
|
[m_window setTitle:title];
|
||||||
}
|
}
|
||||||
@ -405,7 +414,7 @@
|
|||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)setIconTo:(unsigned int)width
|
-(void)setIconTo:(unsigned int)width
|
||||||
by:(unsigned int)height
|
by:(unsigned int)height
|
||||||
with:(sf::Uint8 const *)pixels
|
with:(const sf::Uint8*)pixels
|
||||||
{
|
{
|
||||||
// Create an empty image representation.
|
// Create an empty image representation.
|
||||||
NSBitmapImageRep* bitmap =
|
NSBitmapImageRep* bitmap =
|
||||||
@ -425,12 +434,12 @@
|
|||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 // We may need to define NSUInteger.
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 // We may need to define NSUInteger.
|
||||||
#define NSUInteger unsigned int
|
#define NSUInteger unsigned int
|
||||||
#endif
|
#endif
|
||||||
for (unsigned int y = 0; y < height; ++y) {
|
for (unsigned int y = 0; y < height; ++y)
|
||||||
for (unsigned int x = 0; x < width; ++x, pixels+=4) {
|
{
|
||||||
|
for (unsigned int x = 0; x < width; ++x, pixels+=4)
|
||||||
|
{
|
||||||
NSUInteger pixel[4] = { pixels[0], pixels[1], pixels[2], pixels[3] };
|
NSUInteger pixel[4] = { pixels[0], pixels[1], pixels[2], pixels[3] };
|
||||||
[bitmap setPixel:pixel
|
[bitmap setPixel:pixel atX:x y:y];
|
||||||
atX:x
|
|
||||||
y:y];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,27 +460,25 @@
|
|||||||
-(void)processEvent
|
-(void)processEvent
|
||||||
{
|
{
|
||||||
// If we are not on the main thread we stop here and advice the user.
|
// 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
|
* See http://lists.apple.com/archives/cocoa-dev/2011/Feb/msg00460.html
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
sf::err()
|
sf::err() << "Cannot fetch event from a worker thread. (OS X restriction)" << std::endl;
|
||||||
<< "Cannot fetch event from a worker thread. (OS X restriction)"
|
|
||||||
<< std::endl;
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we don't have a requester we don't fetch event.
|
// If we don't have a requester we don't fetch event.
|
||||||
if (m_requester != 0) {
|
if (m_requester != 0)
|
||||||
[SFApplication processEvent];
|
[SFApplication processEvent];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)applyContext:(NSOpenGLContext *)context
|
-(void)applyContext:(NSOpenGLContext*)context
|
||||||
{
|
{
|
||||||
[m_oglView setOpenGLContext:context];
|
[m_oglView setOpenGLContext:context];
|
||||||
[context setView:m_oglView];
|
[context setView:m_oglView];
|
||||||
@ -479,7 +486,8 @@
|
|||||||
// If fullscreen was requested and the mode used to create the window
|
// 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
|
// was not the desktop mode, we change the back buffer size of the
|
||||||
// context.
|
// context.
|
||||||
if (*m_fullscreenMode != sf::VideoMode()) {
|
if (*m_fullscreenMode != sf::VideoMode())
|
||||||
|
{
|
||||||
CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj];
|
CGLContextObj cgcontext = (CGLContextObj)[context CGLContextObj];
|
||||||
|
|
||||||
GLint dim[2] = {m_fullscreenMode->width, m_fullscreenMode->height};
|
GLint dim[2] = {m_fullscreenMode->width, m_fullscreenMode->height};
|
||||||
@ -497,7 +505,8 @@
|
|||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(BOOL)windowShouldClose:(id)sender
|
-(BOOL)windowShouldClose:(id)sender
|
||||||
{
|
{
|
||||||
if (m_requester == 0) return YES;
|
if (m_requester == 0)
|
||||||
|
return YES;
|
||||||
|
|
||||||
m_requester->windowClosed();
|
m_requester->windowClosed();
|
||||||
return NO;
|
return NO;
|
||||||
@ -505,30 +514,30 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)windowDidBecomeKey:(NSNotification *)notification
|
-(void)windowDidBecomeKey:(NSNotification*)notification
|
||||||
{
|
{
|
||||||
// Send event.
|
// Send event.
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
m_requester->windowGainedFocus();
|
m_requester->windowGainedFocus();
|
||||||
|
|
||||||
if (*m_fullscreenMode != sf::VideoMode()) {
|
if (*m_fullscreenMode != sf::VideoMode())
|
||||||
[m_oglView enterFullscreen];
|
[m_oglView enterFullscreen];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)windowDidResignKey:(NSNotification *)notification
|
-(void)windowDidResignKey:(NSNotification*)notification
|
||||||
{
|
{
|
||||||
// Send event.
|
// Send event.
|
||||||
if (m_requester == 0) return;
|
if (m_requester == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
m_requester->windowLostFocus();
|
m_requester->windowLostFocus();
|
||||||
|
|
||||||
if (*m_fullscreenMode != sf::VideoMode()) {
|
if (*m_fullscreenMode != sf::VideoMode())
|
||||||
[m_oglView exitFullscreen];
|
[m_oglView exitFullscreen];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -538,8 +547,8 @@
|
|||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(float)screenHeight
|
-(float)screenHeight
|
||||||
{
|
{
|
||||||
NSDictionary *deviceDescription = [[m_window screen] deviceDescription];
|
NSDictionary* deviceDescription = [[m_window screen] deviceDescription];
|
||||||
NSNumber *screenNumber = [deviceDescription valueForKey:@"NSScreenNumber"];
|
NSNumber* screenNumber = [deviceDescription valueForKey:@"NSScreenNumber"];
|
||||||
CGDirectDisplayID screenID = (CGDirectDisplayID)[screenNumber intValue];
|
CGDirectDisplayID screenID = (CGDirectDisplayID)[screenNumber intValue];
|
||||||
CGFloat height = CGDisplayPixelsHigh(screenID);
|
CGFloat height = CGDisplayPixelsHigh(screenID);
|
||||||
return height;
|
return height;
|
||||||
|
@ -50,23 +50,24 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
// Retrieve array of dictionaries representing display modes.
|
// Retrieve array of dictionaries representing display modes.
|
||||||
CFArrayRef displayModes = CGDisplayAvailableModes(CGMainDisplayID());
|
CFArrayRef displayModes = CGDisplayAvailableModes(CGMainDisplayID());
|
||||||
|
|
||||||
if (displayModes == NULL) {
|
if (displayModes == NULL)
|
||||||
sf::err() << "Couldn't get VideoMode for main display.";
|
{
|
||||||
|
sf::err() << "Couldn't get VideoMode for main display." << std::endl;
|
||||||
return modes;
|
return modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop on each mode and convert it into a sf::VideoMode object.
|
// Loop on each mode and convert it into a sf::VideoMode object.
|
||||||
CFIndex const modesCount = CFArrayGetCount(displayModes);
|
const CFIndex modesCount = CFArrayGetCount(displayModes);
|
||||||
for (CFIndex i = 0; i < modesCount; i++) {
|
for (CFIndex i = 0; i < modesCount; i++)
|
||||||
|
{
|
||||||
CFDictionaryRef dictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(displayModes, i);
|
CFDictionaryRef dictionary = (CFDictionaryRef)CFArrayGetValueAtIndex(displayModes, i);
|
||||||
|
|
||||||
VideoMode mode = convertCGModeToSFMode(dictionary);
|
VideoMode mode = convertCGModeToSFMode(dictionary);
|
||||||
|
|
||||||
// If not yet listed we add it to our modes array.
|
// 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);
|
modes.push_back(mode);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return modes;
|
return modes;
|
||||||
|
|
||||||
@ -77,23 +78,24 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
|
|||||||
// Retrieve all modes available for main screen only.
|
// Retrieve all modes available for main screen only.
|
||||||
CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
|
CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
|
||||||
|
|
||||||
if (cgmodes == NULL) {
|
if (cgmodes == NULL)
|
||||||
sf::err() << "Couldn't get VideoMode for main display.";
|
{
|
||||||
|
sf::err() << "Couldn't get VideoMode for main display." << std::endl;
|
||||||
return modes;
|
return modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop on each mode and convert it into a sf::VideoMode object.
|
// Loop on each mode and convert it into a sf::VideoMode object.
|
||||||
CFIndex const modesCount = CFArrayGetCount(cgmodes);
|
const CFIndex modesCount = CFArrayGetCount(cgmodes);
|
||||||
for (CFIndex i = 0; i < modesCount; i++) {
|
for (CFIndex i = 0; i < modesCount; i++)
|
||||||
|
{
|
||||||
CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
|
CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
|
||||||
|
|
||||||
VideoMode mode = convertCGModeToSFMode(cgmode);
|
VideoMode mode = convertCGModeToSFMode(cgmode);
|
||||||
|
|
||||||
// If not yet listed we add it to our modes array.
|
// 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);
|
modes.push_back(mode);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up memory.
|
// Clean up memory.
|
||||||
CFRelease(cgmodes);
|
CFRelease(cgmodes);
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
#include <SFML/System/String.hpp>
|
#include <SFML/System/String.hpp>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Predefine OBJC classes
|
/// Predefine OBJ-C classes
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ public :
|
|||||||
///
|
///
|
||||||
/// \param mode Video mode to use
|
/// \param mode Video mode to use
|
||||||
/// \param title Title of the window
|
/// \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
|
/// \param settings Additional settings for the underlying OpenGL context
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -90,7 +90,7 @@ public :
|
|||||||
~WindowImplCocoa();
|
~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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
@ -98,18 +98,18 @@ public :
|
|||||||
void windowClosed(void);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param width
|
/// \param width new width
|
||||||
/// \param height
|
/// \param height new height
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void windowResized(unsigned int width, unsigned int 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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
@ -117,7 +117,7 @@ public :
|
|||||||
void windowLostFocus(void);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
@ -125,54 +125,54 @@ public :
|
|||||||
void windowGainedFocus(void);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param button
|
/// \param button active button
|
||||||
/// \param x
|
/// \param x mouse x position
|
||||||
/// \param y
|
/// \param y mouse y position
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void mouseDownAt(Mouse::Button button, int x, int y);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param button
|
/// \param button active button
|
||||||
/// \param x
|
/// \param x mouse x position
|
||||||
/// \param y
|
/// \param y mouse y position
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void mouseUpAt(Mouse::Button button, int x, int y);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param x
|
/// \param x mouse x position
|
||||||
/// \param y
|
/// \param y mouse y position
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void mouseMovedAt(int x, int y);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param delta
|
/// \param delta scrolling delta
|
||||||
/// \param x
|
/// \param x mouse x position
|
||||||
/// \param y
|
/// \param y mouse y position
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void mouseWheelScrolledAt(float delta, int x, int y);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
@ -180,7 +180,7 @@ public :
|
|||||||
void mouseMovedIn(void);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
@ -188,37 +188,37 @@ public :
|
|||||||
void mouseMovedOut(void);
|
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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param key
|
/// \param key active key
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void keyDown(Event::KeyEvent 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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param key
|
/// \param key active key
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void keyUp(Event::KeyEvent 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.
|
/// Send the event to SFML WindowImpl class.
|
||||||
///
|
///
|
||||||
/// \param charcode Input unicode
|
/// \param charcode Unicode input
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void textEntered(unichar charcode);
|
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.
|
/// Called by the SFML context object to finalize its creation.
|
||||||
///
|
///
|
||||||
@ -228,7 +228,9 @@ public :
|
|||||||
void applyContext(NSOpenGLContextRef context) const;
|
void applyContext(NSOpenGLContextRef context) const;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Change the type of the current process to become a full GUI app.
|
/// \brief Change the type of the current process
|
||||||
|
///
|
||||||
|
/// The type of the process is changed to become a full GUI app.
|
||||||
/// Also ensure NSApp is constructed.
|
/// Also ensure NSApp is constructed.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -332,7 +334,7 @@ private :
|
|||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplDelegateRef m_delegate; ///< Implementation in Obj-C.
|
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
|
} // namespace priv
|
||||||
|
@ -30,13 +30,13 @@
|
|||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
#include <SFML/System/String.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/AutoreleasePoolWrapper.h>
|
||||||
|
#import <SFML/Window/OSX/cpp_objc_conversion.h>
|
||||||
#import <SFML/Window/OSX/SFApplication.h>
|
#import <SFML/Window/OSX/SFApplication.h>
|
||||||
#import <SFML/Window/OSX/SFApplicationDelegate.h>
|
#import <SFML/Window/OSX/SFApplicationDelegate.h>
|
||||||
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
|
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
|
||||||
|
#import <SFML/Window/OSX/SFViewController.h>
|
||||||
|
#import <SFML/Window/OSX/SFWindowController.h>
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
@ -47,28 +47,28 @@ namespace priv
|
|||||||
#pragma mark WindowImplCocoa's ctor/dtor
|
#pragma mark WindowImplCocoa's ctor/dtor
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImplCocoa::WindowImplCocoa(WindowHandle handle)
|
WindowImplCocoa::WindowImplCocoa(WindowHandle handle) :
|
||||||
: m_showCursor(true)
|
m_showCursor(true)
|
||||||
{
|
{
|
||||||
// Ask for a pool.
|
// Ask for a pool.
|
||||||
retainPool();
|
retainPool();
|
||||||
|
|
||||||
// Treat the handle as it real type
|
// Treat the handle as it real type
|
||||||
id nsHandle = (id)handle;
|
id nsHandle = (id)handle;
|
||||||
if ([nsHandle isKindOfClass:[NSWindow class]]) {
|
if ([nsHandle isKindOfClass:[NSWindow class]])
|
||||||
|
{
|
||||||
// We have a window.
|
// We have a window.
|
||||||
m_delegate = [[SFWindowController alloc] initWithWindow:nsHandle];
|
m_delegate = [[SFWindowController alloc] initWithWindow:nsHandle];
|
||||||
|
}
|
||||||
} else if ([nsHandle isKindOfClass:[NSView class]]) {
|
else if ([nsHandle isKindOfClass:[NSView class]])
|
||||||
|
{
|
||||||
// We have a view.
|
// We have a view.
|
||||||
m_delegate = [[SFViewController alloc] initWithView:nsHandle];
|
m_delegate = [[SFViewController alloc] initWithView:nsHandle];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
} else {
|
sf::err() << "Cannot import this Window Handle because it is neither "
|
||||||
|
|
||||||
sf::err()
|
|
||||||
<< "Cannot import this Window Handle because it is neither "
|
|
||||||
<< "a <NSWindow*> nor <NSView*> object "
|
<< "a <NSWindow*> nor <NSView*> object "
|
||||||
<< "(or any of their subclasses). You gave a <"
|
<< "(or any of their subclasses). You gave a <"
|
||||||
<< [[nsHandle className] UTF8String]
|
<< [[nsHandle className] UTF8String]
|
||||||
@ -89,8 +89,8 @@ WindowImplCocoa::WindowImplCocoa(WindowHandle handle)
|
|||||||
WindowImplCocoa::WindowImplCocoa(VideoMode mode,
|
WindowImplCocoa::WindowImplCocoa(VideoMode mode,
|
||||||
const String& title,
|
const String& title,
|
||||||
unsigned long style,
|
unsigned long style,
|
||||||
const ContextSettings& /*settings*/)
|
const ContextSettings& /*settings*/) :
|
||||||
: m_showCursor(true)
|
m_showCursor(true)
|
||||||
{
|
{
|
||||||
// Transform the app process.
|
// Transform the app process.
|
||||||
setUpProcess();
|
setUpProcess();
|
||||||
@ -116,9 +116,8 @@ WindowImplCocoa::~WindowImplCocoa()
|
|||||||
|
|
||||||
// Put the next window in front, if any.
|
// Put the next window in front, if any.
|
||||||
NSArray* windows = [NSApp orderedWindows];
|
NSArray* windows = [NSApp orderedWindows];
|
||||||
if ([windows count] > 0) {
|
if ([windows count] > 0)
|
||||||
[[windows objectAtIndex:0] makeKeyAndOrderFront:nil];
|
[[windows objectAtIndex:0] makeKeyAndOrderFront:nil];
|
||||||
}
|
|
||||||
|
|
||||||
releasePool();
|
releasePool();
|
||||||
|
|
||||||
@ -140,21 +139,22 @@ void WindowImplCocoa::setUpProcess(void)
|
|||||||
{
|
{
|
||||||
static bool isTheProcessSetAsApplication = false;
|
static bool isTheProcessSetAsApplication = false;
|
||||||
|
|
||||||
if (!isTheProcessSetAsApplication) {
|
if (!isTheProcessSetAsApplication)
|
||||||
|
{
|
||||||
// Do it only once !
|
// Do it only once !
|
||||||
isTheProcessSetAsApplication = true;
|
isTheProcessSetAsApplication = true;
|
||||||
|
|
||||||
// Set the process as a normal application so it can get focus.
|
// Set the process as a normal application so it can get focus.
|
||||||
ProcessSerialNumber psn;
|
ProcessSerialNumber psn;
|
||||||
if (!GetCurrentProcess(&psn)) {
|
if (!GetCurrentProcess(&psn))
|
||||||
|
{
|
||||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
||||||
SetFrontProcess(&psn);
|
SetFrontProcess(&psn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register an application delegate if there is none
|
// Register an application delegate if there is none
|
||||||
if (![[SFApplication sharedApplication] delegate]) {
|
if (![[SFApplication sharedApplication] delegate])
|
||||||
[NSApp setDelegate:[[SFApplicationDelegate alloc] init]];
|
[NSApp setDelegate:[[SFApplicationDelegate alloc] init]];
|
||||||
}
|
|
||||||
|
|
||||||
// Create menus for the application (before finishing launching!)
|
// Create menus for the application (before finishing launching!)
|
||||||
[SFApplication setUpMenuBar];
|
[SFApplication setUpMenuBar];
|
||||||
@ -196,9 +196,8 @@ void WindowImplCocoa::windowResized(unsigned int width, unsigned int height)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplCocoa::windowLostFocus(void)
|
void WindowImplCocoa::windowLostFocus(void)
|
||||||
{
|
{
|
||||||
if (!m_showCursor) {
|
if (!m_showCursor)
|
||||||
[m_delegate showMouseCursor]; // Make sur the cursor is visible
|
[m_delegate showMouseCursor]; // Make sure the cursor is visible
|
||||||
}
|
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::LostFocus;
|
event.type = Event::LostFocus;
|
||||||
@ -210,9 +209,8 @@ void WindowImplCocoa::windowLostFocus(void)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplCocoa::windowGainedFocus(void)
|
void WindowImplCocoa::windowGainedFocus(void)
|
||||||
{
|
{
|
||||||
if (!m_showCursor) {
|
if (!m_showCursor)
|
||||||
[m_delegate hideMouseCursor]; // Restore user's setting
|
[m_delegate hideMouseCursor]; // Restore user's setting
|
||||||
}
|
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::GainedFocus;
|
event.type = Event::GainedFocus;
|
||||||
@ -276,9 +274,8 @@ void WindowImplCocoa::mouseWheelScrolledAt(float delta, int x, int y)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplCocoa::mouseMovedIn(void)
|
void WindowImplCocoa::mouseMovedIn(void)
|
||||||
{
|
{
|
||||||
if (!m_showCursor) {
|
if (!m_showCursor)
|
||||||
[m_delegate hideMouseCursor]; // Restore user's setting
|
[m_delegate hideMouseCursor]; // Restore user's setting
|
||||||
}
|
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::MouseEntered;
|
event.type = Event::MouseEntered;
|
||||||
@ -289,9 +286,8 @@ void WindowImplCocoa::mouseMovedIn(void)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplCocoa::mouseMovedOut(void)
|
void WindowImplCocoa::mouseMovedOut(void)
|
||||||
{
|
{
|
||||||
if (!m_showCursor) {
|
if (!m_showCursor)
|
||||||
[m_delegate showMouseCursor]; // Make sur the cursor is visible
|
[m_delegate showMouseCursor]; // Make sure the cursor is visible
|
||||||
}
|
|
||||||
|
|
||||||
Event event;
|
Event event;
|
||||||
event.type = Event::MouseLeft;
|
event.type = Event::MouseLeft;
|
||||||
@ -403,11 +399,10 @@ void WindowImplCocoa::setIcon(unsigned int width, unsigned int height, const Uin
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplCocoa::setVisible(bool visible)
|
void WindowImplCocoa::setVisible(bool visible)
|
||||||
{
|
{
|
||||||
if (visible) {
|
if (visible)
|
||||||
[m_delegate showWindow];
|
[m_delegate showWindow];
|
||||||
} else {
|
else
|
||||||
[m_delegate hideWindow];
|
[m_delegate hideWindow];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -416,22 +411,20 @@ void WindowImplCocoa::setMouseCursorVisible(bool visible)
|
|||||||
{
|
{
|
||||||
m_showCursor = visible;
|
m_showCursor = visible;
|
||||||
|
|
||||||
if (m_showCursor) {
|
if (m_showCursor)
|
||||||
[m_delegate showMouseCursor];
|
[m_delegate showMouseCursor];
|
||||||
} else {
|
else
|
||||||
[m_delegate hideMouseCursor];
|
[m_delegate hideMouseCursor];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
if (enabled) {
|
if (enabled)
|
||||||
[m_delegate enableKeyRepeat];
|
[m_delegate enableKeyRepeat];
|
||||||
} else {
|
else
|
||||||
[m_delegate disableKeyRepeat];
|
[m_delegate disableKeyRepeat];
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/WindowHandle.hpp>
|
|
||||||
#include <SFML/Config.hpp> // for sf::Uint8
|
#include <SFML/Config.hpp> // for sf::Uint8
|
||||||
|
#include <SFML/Window/WindowHandle.hpp>
|
||||||
|
|
||||||
#import <AppKit/AppKit.h>
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
@ -38,8 +38,7 @@ namespace sf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// This protocol defines the interface of the delegate of
|
/// \brief Interface of the delegate of the window implementation
|
||||||
/// the window implementation.
|
|
||||||
///
|
///
|
||||||
/// We don't create an interface here because Obj-C doesn't allow
|
/// We don't create an interface here because Obj-C doesn't allow
|
||||||
/// multiple inheritance (SFViewController and SFWindowController
|
/// multiple inheritance (SFViewController and SFWindowController
|
||||||
@ -47,12 +46,12 @@ namespace sf {
|
|||||||
/// we have to duplicate some code.
|
/// we have to duplicate some code.
|
||||||
///
|
///
|
||||||
/// Everything is done via a class that implement this protocol.
|
/// 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
|
/// SFViewController and SFWindowController
|
||||||
///
|
///
|
||||||
/// The requester is a WindowImplCocoa. It's used to send back
|
/// The requester is a WindowImplCocoa. It's used to send back
|
||||||
/// event via these functions :
|
/// event via these functions:
|
||||||
///
|
///
|
||||||
/// windowClosed, windowResized, windowLostFocus, windowGainedFocus
|
/// windowClosed, windowResized, windowLostFocus, windowGainedFocus
|
||||||
///
|
///
|
||||||
@ -61,99 +60,142 @@ namespace sf {
|
|||||||
///
|
///
|
||||||
/// keyDown, keyUp, textEntered
|
/// 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.
|
/// thus they're not managed by a class implementing this protocol.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@protocol WindowImplDelegateProtocol
|
@protocol WindowImplDelegateProtocol
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Set the WindowImpl who requested this delegate
|
/// \brief Set the WindowImpl who requested this delegate
|
||||||
/// (This would be a ctor in C++ or Java where we can prohibit the
|
|
||||||
/// construction of an object.)
|
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)setRequesterTo:(sf::priv::WindowImplCocoa *)requester;
|
-(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;
|
-(sf::WindowHandle)getSystemHandle;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Hide or show the mouse cursor.
|
/// \brief Hide the mouse cursor
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)hideMouseCursor;
|
-(void)hideMouseCursor;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Show the mouse cursor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
-(void)showMouseCursor;
|
-(void)showMouseCursor;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Get window's position.
|
/// \brief Get window position
|
||||||
|
///
|
||||||
|
/// \return Top left corner of the window or view
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(NSPoint)position;
|
-(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;
|
-(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;
|
-(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;
|
-(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;
|
-(void)hideWindow;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Show the window
|
||||||
|
///
|
||||||
|
/// Doesn't apply if the implementation is 'only' a view.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
-(void)showWindow;
|
-(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;
|
-(void)closeWindow;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Enable or disable key repeat.
|
/// \brief Enable key repeat
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)enableKeyRepeat;
|
-(void)enableKeyRepeat;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Disable key repeat
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
-(void)disableKeyRepeat;
|
-(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;
|
-(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
|
@end
|
||||||
|
@ -42,20 +42,13 @@ size_t modeBitsPerPixel(CGDisplayModeRef mode)
|
|||||||
|
|
||||||
// Compare encoding.
|
// Compare encoding.
|
||||||
CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
|
CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode);
|
||||||
if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
if(CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||||
|
|
||||||
bpp = 32;
|
bpp = 32;
|
||||||
|
else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||||
} else if(CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
|
||||||
|
|
||||||
bpp = 16;
|
bpp = 16;
|
||||||
|
else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
|
||||||
} else if(CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
|
||||||
|
|
||||||
bpp = 8;
|
bpp = 8;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up memory.
|
// Clean up memory.
|
||||||
CFRelease(pixEnc);
|
CFRelease(pixEnc);
|
||||||
|
|
||||||
@ -78,7 +71,7 @@ size_t displayBitsPerPixel(CGDirectDisplayID displayId)
|
|||||||
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
|
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displayId);
|
||||||
|
|
||||||
// Get bpp for the mode.
|
// Get bpp for the mode.
|
||||||
size_t const bpp = modeBitsPerPixel(mode);
|
const size_t bpp = modeBitsPerPixel(mode);
|
||||||
|
|
||||||
// Clean up Memory.
|
// Clean up Memory.
|
||||||
CGDisplayModeRelease(mode);
|
CGDisplayModeRelease(mode);
|
||||||
@ -146,31 +139,30 @@ CGDisplayModeRef convertSFModeToCGMode(VideoMode sfmode)
|
|||||||
// Retrieve all modes available for main screen only.
|
// Retrieve all modes available for main screen only.
|
||||||
CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
|
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.";
|
sf::err() << "Couldn't get VideoMode for main display.";
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop on each mode and convert it into a sf::VideoMode object.
|
// Loop on each mode and convert it into a sf::VideoMode object.
|
||||||
CFIndex const modesCount = CFArrayGetCount(cgmodes);
|
const CFIndex modesCount = CFArrayGetCount(cgmodes);
|
||||||
for (CFIndex i = 0; i < modesCount; i++) {
|
for (CFIndex i = 0; i < modesCount; i++)
|
||||||
|
{
|
||||||
CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
|
CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
|
||||||
|
|
||||||
VideoMode mode = convertCGModeToSFMode(cgmode);
|
VideoMode mode = convertCGModeToSFMode(cgmode);
|
||||||
|
|
||||||
if (mode == sfmode) {
|
if (mode == sfmode)
|
||||||
cgbestMode = cgmode;
|
cgbestMode = cgmode;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up memory.
|
// Clean up memory.
|
||||||
CFRelease(cgmodes);
|
CFRelease(cgmodes);
|
||||||
|
|
||||||
if (cgbestMode == NULL) {
|
if (cgbestMode == NULL)
|
||||||
sf::err()
|
sf::err() << "Couldn't convert the given sf:VideoMode into a CGDisplayMode."
|
||||||
<< "Couldn't convert the given sf:VideoMode into a CGDisplayMode."
|
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
}
|
|
||||||
|
|
||||||
return cgbestMode;
|
return cgbestMode;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ namespace sf
|
|||||||
namespace priv
|
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
|
/// With OS 10.6 and later, Quartz doesn't use anymore dictionaries
|
||||||
/// to represent video mode. Instead it uses a CGDisplayMode opaque type.
|
/// to represent video mode. Instead it uses a CGDisplayMode opaque type.
|
||||||
@ -48,7 +48,7 @@ size_t modeBitsPerPixel(CGDisplayModeRef mode);
|
|||||||
#endif
|
#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
|
/// This function use only non-deprecated way to get the
|
||||||
/// display bits per pixel information for a given display id.
|
/// display bits per pixel information for a given display id.
|
||||||
@ -57,7 +57,7 @@ size_t modeBitsPerPixel(CGDisplayModeRef mode);
|
|||||||
size_t displayBitsPerPixel(CGDirectDisplayID displayId);
|
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
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
|
||||||
@ -67,7 +67,7 @@ VideoMode convertCGModeToSFMode(CGDisplayModeRef cgmode);
|
|||||||
#endif
|
#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
|
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
|
||||||
|
@ -26,14 +26,19 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <string>
|
|
||||||
#include <SFML/System/String.hpp>
|
#include <SFML/System/String.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#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* stringToNSString(const std::string& string);
|
||||||
NSString* sfStringToNSString(sf::String const& string);
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Returns a NSString construct with +stringWithCString:encoding:
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
NSString* sfStringToNSString(const sf::String& string);
|
||||||
|
@ -28,11 +28,11 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/Utf.hpp>
|
#include <SFML/System/Utf.hpp>
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <SFML/Window/OSX/cpp_objc_conversion.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);
|
std::string utf8; utf8.reserve(string.size() + 1);
|
||||||
sf::Utf8::fromAnsi(string.begin(), string.end(), std::back_inserter(utf8));
|
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);
|
sf::Uint32 length = string.getSize() * sizeof(sf::Uint32);
|
||||||
const void* data = reinterpret_cast<const void*>(string.getData());
|
const void* data = reinterpret_cast<const void*>(string.getData());
|
||||||
|
Loading…
Reference in New Issue
Block a user