Merge branch 'keepup'
Conflicts: bindings/c/src/SFML/System/Mutex.cpp bindings/c/src/SFML/Window/Context.cpp src/SFML/Window/CMakeLists.txt src/SFML/Window/InputImpl.hpp src/SFML/Window/Mouse.cpp src/SFML/Window/OSX/InputImpl.cpp src/SFML/Window/OSX/InputImpl.hpp src/SFML/Window/OSX/JoystickImpl.cpp src/SFML/Window/OSX/JoystickImpl.hpp src/SFML/Window/OSX/SFApplication.h src/SFML/Window/OSX/SFOpenGLView.mm src/SFML/Window/Win32/Joystick.hpp src/SFML/Window/Win32/JoystickImpl.hpp
This commit is contained in:
commit
88c5e350bf
@ -67,10 +67,10 @@ else() # MACOSX
|
|||||||
${SRCROOT}/OSX/cpp_objc_conversion.mm
|
${SRCROOT}/OSX/cpp_objc_conversion.mm
|
||||||
${SRCROOT}/OSX/cg_sf_conversion.hpp
|
${SRCROOT}/OSX/cg_sf_conversion.hpp
|
||||||
${SRCROOT}/OSX/cg_sf_conversion.cpp
|
${SRCROOT}/OSX/cg_sf_conversion.cpp
|
||||||
${SRCROOT}/OSX/Joystick.cpp
|
${SRCROOT}/OSX/InputImpl.mm
|
||||||
${SRCROOT}/OSX/Joystick.hpp
|
|
||||||
${SRCROOT}/OSX/InputImpl.cpp
|
|
||||||
${SRCROOT}/OSX/InputImpl.hpp
|
${SRCROOT}/OSX/InputImpl.hpp
|
||||||
|
${SRCROOT}/OSX/HIDInputManager.hpp
|
||||||
|
${SRCROOT}/OSX/HIDInputManager.mm
|
||||||
${SRCROOT}/OSX/JoystickImpl.cpp
|
${SRCROOT}/OSX/JoystickImpl.cpp
|
||||||
${SRCROOT}/OSX/JoystickImpl.hpp
|
${SRCROOT}/OSX/JoystickImpl.hpp
|
||||||
${SRCROOT}/OSX/SFApplication.h
|
${SRCROOT}/OSX/SFApplication.h
|
||||||
@ -107,7 +107,7 @@ if(WINDOWS)
|
|||||||
elseif(LINUX)
|
elseif(LINUX)
|
||||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
|
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} ${X11_X11_LIB} ${X11_Xrandr_LIB})
|
||||||
elseif(MACOSX)
|
elseif(MACOSX)
|
||||||
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} "-framework Foundation -framework AppKit -framework IOKit")
|
set(WINDOW_EXT_LIBS ${WINDOW_EXT_LIBS} "-framework Foundation -framework AppKit -framework IOKit -framework Carbon")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# define the sfml-window target
|
# define the sfml-window target
|
||||||
|
@ -23,6 +23,21 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Ensure at least one autorelease pool is available on this thread.
|
||||||
|
///
|
||||||
|
/// Increment a retain count.
|
||||||
|
/// See SPECIAL CONSIDERATION in implementation file.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
void RetainPool(void);
|
void RetainPool(void);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Release the pool.
|
||||||
|
///
|
||||||
|
/// Drain the pool if it is no more needed (retain count is zero).
|
||||||
|
/// See SPECIAL CONSIDERATION in implementation file.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
void ReleasePool(void);
|
void ReleasePool(void);
|
||||||
|
|
||||||
|
@ -23,32 +23,89 @@
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/System/ThreadLocalPtr.hpp>
|
#include <SFML/System/ThreadLocalPtr.hpp>
|
||||||
|
#include <SFML/System/NonCopyable.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
#import "AutoreleasePoolWrapper.h"
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
|
||||||
|
|
||||||
// Here we manage one and only one pool by thread. This prevents draining one
|
|
||||||
// pool and making other pools invalid which can lead to a crash on 10.5 and an
|
|
||||||
// annoying message on 10.6 (*** attempt to pop an unknown autorelease pool).
|
|
||||||
|
|
||||||
// Because NSAutoreleasePool cannot be retain we have to do it ourself.
|
////////////////////////////////////////////////////////////
|
||||||
// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread.
|
/// Here we manage one and only one pool by thread. This prevents draining one
|
||||||
|
/// pool and making other pools invalid which can lead to a crash on 10.5 and an
|
||||||
|
/// annoying message on 10.6 (*** attempt to pop an unknown autorelease pool).
|
||||||
|
///
|
||||||
|
/// Because NSAutoreleasePool cannot be retain we have to do it ourself.
|
||||||
|
/// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread.
|
||||||
|
///
|
||||||
|
/// SPECIAL CONSIDERATION :
|
||||||
|
/// =======================
|
||||||
|
/// This implies that if RetainPool is called X times in a thread Y then
|
||||||
|
/// ReleasePool must be called X times too in the same thread Y.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// This implies that if RetainPool is called X times in a thread Y then
|
namespace sf
|
||||||
// ReleasePool must be called X times too in the same thread Y.
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief C++ Wrapper of Obj-C Autorelease Pool.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
class PoolWrapper : NonCopyable {
|
||||||
|
public :
|
||||||
|
|
||||||
class PoolWrapper {
|
////////////////////////////////////////////////////////////
|
||||||
public:
|
/// \brief Default constructor
|
||||||
PoolWrapper()
|
///
|
||||||
: count(0)
|
////////////////////////////////////////////////////////////
|
||||||
, pool(0)
|
PoolWrapper();
|
||||||
{
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Default destructor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
~PoolWrapper();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Increment retain count and allocate memory if needed
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void Retain();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Decrement retain count and releasing memory if needed
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void Release();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Member data
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
int count; ///< How many times was the pool retained ?
|
||||||
|
NSAutoreleasePool* pool; ///< Our dedicated pool
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
PoolWrapper::PoolWrapper()
|
||||||
|
: count(0)
|
||||||
|
, pool(0)
|
||||||
|
{
|
||||||
/* Nothing else */
|
/* Nothing else */
|
||||||
}
|
}
|
||||||
|
|
||||||
~PoolWrapper()
|
|
||||||
{
|
////////////////////////////////////////////////////////////
|
||||||
|
PoolWrapper::~PoolWrapper()
|
||||||
|
{
|
||||||
#ifdef SFML_DEBUG
|
#ifdef SFML_DEBUG
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
sf::Err() << "~PoolWrapper : count is less than zero! "
|
sf::Err() << "~PoolWrapper : count is less than zero! "
|
||||||
@ -62,10 +119,12 @@ public:
|
|||||||
sf::Err() << "~PoolWrapper is HAPPY!" << std::endl;
|
sf::Err() << "~PoolWrapper is HAPPY!" << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Retain()
|
|
||||||
{
|
////////////////////////////////////////////////////////////
|
||||||
|
void PoolWrapper::Retain()
|
||||||
|
{
|
||||||
// Increase counter.
|
// Increase counter.
|
||||||
++count;
|
++count;
|
||||||
|
|
||||||
@ -79,10 +138,12 @@ public:
|
|||||||
sf::Err() << "PoolWrapper::Retain : count <= 0! " << std::endl;
|
sf::Err() << "PoolWrapper::Retain : count <= 0! " << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Release()
|
|
||||||
{
|
////////////////////////////////////////////////////////////
|
||||||
|
void PoolWrapper::Release()
|
||||||
|
{
|
||||||
// Decrease counter.
|
// Decrease counter.
|
||||||
--count;
|
--count;
|
||||||
|
|
||||||
@ -97,28 +158,37 @@ public:
|
|||||||
sf::Err() << "PoolWrapper::Release : count < 0! " << std::endl;
|
sf::Err() << "PoolWrapper::Release : count < 0! " << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
} // namespace priv
|
||||||
int count; ///< How many times the pool was retained ?
|
|
||||||
NSAutoreleasePool* pool; ///< Our pool.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Thread shared variable but with local-only shared content.
|
} // namespace sf
|
||||||
sf::ThreadLocalPtr<PoolWrapper> localPool;
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Private data
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// This per-thread variable holds the current autorelease pool for each thread
|
||||||
|
sf::ThreadLocalPtr<sf::priv::PoolWrapper> localPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
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 PoolWrapper();
|
localPool = new sf::priv::PoolWrapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then retains!
|
// Then retains!
|
||||||
localPool->Retain();
|
localPool->Retain();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
void ReleasePool(void)
|
void ReleasePool(void)
|
||||||
{
|
{
|
||||||
#ifdef SFML_DEBUG
|
#ifdef SFML_DEBUG
|
||||||
@ -136,3 +206,4 @@ void ReleasePool(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
253
src/SFML/Window/OSX/HIDInputManager.hpp
Normal file
253
src/SFML/Window/OSX/HIDInputManager.hpp
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent.gom@gmail.com),
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef SFML_HIDINPUTMANAGER_HPP
|
||||||
|
#define SFML_HIDINPUTMANAGER_HPP
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/System/NonCopyable.hpp>
|
||||||
|
#include <SFML/Window/JoystickImpl.hpp>
|
||||||
|
#include <SFML/Window/Keyboard.hpp>
|
||||||
|
#include <SFML/Window/Mouse.hpp>
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
#include <IOKit/hid/IOHIDManager.h>
|
||||||
|
#include <IOKit/hid/IOHIDDevice.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace sf
|
||||||
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief This class manage as a singleton instance the
|
||||||
|
/// keyboard and mouse states. It's only purpose is
|
||||||
|
/// to help sf::priv::InputImpl class.
|
||||||
|
///
|
||||||
|
/// sf::priv::JoystickImpl is not concerned by this class.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
class HIDInputManager : NonCopyable
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Get the unique instance of the class
|
||||||
|
///
|
||||||
|
/// \note Private use only
|
||||||
|
///
|
||||||
|
/// \return Reference to the HIDInputManager instance
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static HIDInputManager& GetInstance();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check if a key is pressed
|
||||||
|
///
|
||||||
|
/// \param key Key to check
|
||||||
|
///
|
||||||
|
/// \return True if the key is pressed, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool IsKeyPressed(Keyboard::Key key);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Check if a mouse button is pressed
|
||||||
|
///
|
||||||
|
/// \param button Button to check
|
||||||
|
///
|
||||||
|
/// \return True if the button is pressed, false otherwise
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool IsMouseButtonPressed(Mouse::Button button);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Try to convert a character into a SFML key code.
|
||||||
|
///
|
||||||
|
/// Return sf::Keyboard::KeyCount if it doesn't match any 'localized' keys.
|
||||||
|
///
|
||||||
|
/// By 'localized' I mean keys that depend on the keyboard layout
|
||||||
|
/// and might not be the same as the US keycode in some country
|
||||||
|
/// (e.g. the keys 'Y' and 'Z' are switched on QWERTZ keyboard and
|
||||||
|
/// US keyboard layouts.)
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static Keyboard::Key LocalizedKeys(UniChar ch);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Try to convert a virtual keycode into a SFML key code.
|
||||||
|
///
|
||||||
|
/// Return sf::Keyboard::KeyCount if the keycode is unknown.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static Keyboard::Key NonLocalizedKeys(UniChar virtualKeycode);
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Default constructor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
HIDInputManager();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Destructor
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
~HIDInputManager();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Initialize the keyboard part of this class
|
||||||
|
///
|
||||||
|
/// If something went wrong FreeUp is called
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void InitializeKeyboard();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Initialize the mouse part of this class
|
||||||
|
///
|
||||||
|
/// If something went wrong FreeUp is called
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void InitializeMouse();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Load the given keyboard into myKeys
|
||||||
|
///
|
||||||
|
/// If the given keyboard has no key this function simply
|
||||||
|
/// returns. FreeUp is _not_ called because this is not fatal.
|
||||||
|
///
|
||||||
|
/// \param keyboard Keyboard to load
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void LoadKeyboard(IOHIDDeviceRef keyboard);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Load the given mouse into myButtons
|
||||||
|
///
|
||||||
|
/// If the given mouse has no button this function simply
|
||||||
|
/// returns. FreeUp is _not_ called because this is not fatal.
|
||||||
|
///
|
||||||
|
/// \param mouse Mouse to load
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void LoadMouse(IOHIDDeviceRef mouse);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Load the given key into myKeys
|
||||||
|
///
|
||||||
|
/// FreeUp is _not_ called by this function.
|
||||||
|
///
|
||||||
|
/// \param key Key to load
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void LoadKey(IOHIDElementRef key);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Load the given button into myButtons
|
||||||
|
///
|
||||||
|
/// FreeUp is _not_ called by this function.
|
||||||
|
///
|
||||||
|
/// \param button Button to load
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void LoadButton(IOHIDElementRef button);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Release all resources
|
||||||
|
///
|
||||||
|
/// Close all connections to any devices, if required
|
||||||
|
/// Set amIValid to false
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void FreeUp();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Create a mask (dictionary) for an IOHIDManager
|
||||||
|
///
|
||||||
|
/// \param page HID page
|
||||||
|
/// \param usage HID usage page
|
||||||
|
/// \return a retained CFDictionaryRef
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static CFDictionaryRef CopyDevicesMaskForManager(UInt32 page, UInt32 usage);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Filter the devices and return them.
|
||||||
|
///
|
||||||
|
/// If something went wrong FreeUp is called
|
||||||
|
///
|
||||||
|
/// \param page HID page like kHIDPage_GenericDesktop
|
||||||
|
/// \param usage HID usage page like kHIDUsage_GD_Keyboard or kHIDUsage_GD_Mouse
|
||||||
|
/// \return a retained CFSetRef of IOHIDDeviceRef or NULL
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
CFSetRef CopyDevices(UInt32 page, UInt32 usage);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Converte a HID key usage to its corresponding virtual code
|
||||||
|
///
|
||||||
|
/// See IOHIDUsageTables.h
|
||||||
|
///
|
||||||
|
/// \param usage Any kHIDUsage_Keyboard* usage
|
||||||
|
/// \return the virtual code associate with the given HID key usage
|
||||||
|
/// or 0xff if it is associate with no virtual code
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
static UInt8 UsageToVirtualCode(UInt32 usage);
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Member data
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool amIValid; ///< If any error occurs this variable is false
|
||||||
|
CFDataRef myLayoutData; ///< CFData containing the layout
|
||||||
|
UCKeyboardLayout* myLayout; ///< Current Keyboard Layout
|
||||||
|
IOHIDManagerRef myManager; ///< HID Manager
|
||||||
|
|
||||||
|
typedef std::vector<IOHIDElementRef> IOHIDElements;
|
||||||
|
IOHIDElements myKeys[Keyboard::KeyCount]; ///< All the keys on any connected keyboard
|
||||||
|
IOHIDElements myButtons[Mouse::ButtonCount];///< All the buttons on any connected mouse
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// myKeys' index corresponds to sf::Keyboard::Key enum.
|
||||||
|
/// if no key is assigned with key XYZ then myKeys[XYZ].size() == 0.
|
||||||
|
/// if there are several keyboards connected and several HID keys associate
|
||||||
|
/// with the same sf::Keyboard::Key then myKeys[XYZ] contains all these
|
||||||
|
/// HID keys.
|
||||||
|
///
|
||||||
|
/// myButtons works the same way.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
||||||
|
|
||||||
|
#endif
|
1015
src/SFML/Window/OSX/HIDInputManager.mm
Normal file
1015
src/SFML/Window/OSX/HIDInputManager.mm
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,82 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/Window/OSX/InputImpl.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool InputImpl::IsKeyPressed(Keyboard::Key key)
|
|
||||||
{
|
|
||||||
// @to be implemented
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool InputImpl::IsMouseButtonPressed(Mouse::Button button)
|
|
||||||
{
|
|
||||||
// @to be implemented
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Vector2i InputImpl::GetMousePosition()
|
|
||||||
{
|
|
||||||
// @to be implemented
|
|
||||||
return Vector2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Vector2i InputImpl::GetMousePosition(const Window& relativeTo)
|
|
||||||
{
|
|
||||||
// @to be implemented
|
|
||||||
return Vector2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void InputImpl::SetMousePosition(const Vector2i& position)
|
|
||||||
{
|
|
||||||
// @to be implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void InputImpl::SetMousePosition(const Vector2i& position, const Window& relativeTo)
|
|
||||||
{
|
|
||||||
// @to be implemented
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
@ -1,7 +1,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// SFML - Simple and Fast Multimedia Library
|
// SFML - Simple and Fast Multimedia Library
|
||||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent.gom@gmail.com),
|
||||||
//
|
//
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
177
src/SFML/Window/OSX/InputImpl.mm
Normal file
177
src/SFML/Window/OSX/InputImpl.mm
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// SFML - Simple and Fast Multimedia Library
|
||||||
|
// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent.gom@gmail.com),
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
|
// subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented;
|
||||||
|
// you must not claim that you wrote the original software.
|
||||||
|
// If you use this software in a product, an acknowledgment
|
||||||
|
// in the product documentation would be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
|
// and must not be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Headers
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
#include <SFML/Window/OSX/InputImpl.hpp>
|
||||||
|
#include <SFML/Window/VideoMode.hpp>
|
||||||
|
#include <SFML/Window/Window.hpp>
|
||||||
|
#include <SFML/System/Err.hpp>
|
||||||
|
#include <SFML/Window/OSX/HIDInputManager.hpp>
|
||||||
|
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// In order to keep track of the keyboard's state and mouse buttons' state
|
||||||
|
/// we use the HID manager. Mouse position is handled differently.
|
||||||
|
///
|
||||||
|
/// NB : we probably could use
|
||||||
|
/// NSEvent +addGlobalMonitorForEventsMatchingMask:handler: for mouse only.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace sf
|
||||||
|
{
|
||||||
|
namespace priv
|
||||||
|
{
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Extract the dedicated SFOpenGLView from the SFML window
|
||||||
|
///
|
||||||
|
/// \param window a SFML window
|
||||||
|
/// \return nil if something went wrong or a SFOpenGLView*.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
SFOpenGLView* GetSFOpenGLViewFromSFMLWindow(const Window& window)
|
||||||
|
{
|
||||||
|
id nsHandle = (id)window.GetSystemHandle();
|
||||||
|
|
||||||
|
// Get our SFOpenGLView from ...
|
||||||
|
SFOpenGLView* view = nil;
|
||||||
|
if ([nsHandle isKindOfClass:[NSWindow class]]) {
|
||||||
|
// If system handle is a window then from its content view.
|
||||||
|
view = [nsHandle contentView];
|
||||||
|
|
||||||
|
// Subview doesn't match ?
|
||||||
|
if (![view isKindOfClass:[SFOpenGLView class]]) {
|
||||||
|
sf::Err() << "The content view is not a valid SFOpenGLView"
|
||||||
|
<< std::endl;
|
||||||
|
view = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if ([nsHandle isKindOfClass:[NSView class]]) {
|
||||||
|
// If system handle is a view then from a subview of kind SFOpenGLView.
|
||||||
|
NSArray* subviews = [nsHandle subviews];
|
||||||
|
for (NSView* subview in subviews) {
|
||||||
|
if ([subview isKindOfClass:[SFOpenGLView class]]) {
|
||||||
|
view = (SFOpenGLView *)subview;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No matching subview ?
|
||||||
|
if (view == nil) {
|
||||||
|
sf::Err() << "Cannot find a valid SFOpenGLView subview." << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
sf::Err() << "The system handle is neither a <NSWindow*> nor <NSView*>"
|
||||||
|
<< "object. This shouldn't happen."
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool InputImpl::IsKeyPressed(Keyboard::Key key)
|
||||||
|
{
|
||||||
|
return HIDInputManager::GetInstance().IsKeyPressed(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
bool InputImpl::IsMouseButtonPressed(Mouse::Button button)
|
||||||
|
{
|
||||||
|
return HIDInputManager::GetInstance().IsMouseButtonPressed(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
Vector2i InputImpl::GetMousePosition()
|
||||||
|
{
|
||||||
|
// Reverse Y axis to match SFML coord.
|
||||||
|
NSPoint pos = [NSEvent mouseLocation];
|
||||||
|
pos.y = sf::VideoMode::GetDesktopMode().Height - pos.y;
|
||||||
|
|
||||||
|
return Vector2i(pos.x, pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
Vector2i InputImpl::GetMousePosition(const Window& relativeTo)
|
||||||
|
{
|
||||||
|
SFOpenGLView* view = GetSFOpenGLViewFromSFMLWindow(relativeTo);
|
||||||
|
|
||||||
|
// No view ?
|
||||||
|
if (view == nil) {
|
||||||
|
return Vector2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use -cursorPositionFromEvent: with nil.
|
||||||
|
NSPoint pos = [view cursorPositionFromEvent:nil];
|
||||||
|
|
||||||
|
return Vector2i(pos.x, pos.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void InputImpl::SetMousePosition(const Vector2i& position)
|
||||||
|
{
|
||||||
|
// Here we don't need to reverse the coordinates.
|
||||||
|
CGPoint pos = CGPointMake(position.x, position.y);
|
||||||
|
|
||||||
|
// Place the cursor.
|
||||||
|
CGEventRef event = CGEventCreateMouseEvent(NULL,
|
||||||
|
kCGEventMouseMoved,
|
||||||
|
pos,
|
||||||
|
/*we don't care about this : */0);
|
||||||
|
CGEventPost(kCGHIDEventTap, event);
|
||||||
|
CFRelease(event);
|
||||||
|
// This is a workaround to deprecated CGSetLocalEventsSuppressionInterval.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void InputImpl::SetMousePosition(const Vector2i& position, const Window& relativeTo)
|
||||||
|
{
|
||||||
|
SFOpenGLView* view = GetSFOpenGLViewFromSFMLWindow(relativeTo);
|
||||||
|
|
||||||
|
// No view ?
|
||||||
|
if (view == nil) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use -setCursorPositionToX:Y:.
|
||||||
|
[view setCursorPositionToX:position.x Y:position.y];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
@ -1,371 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
|
|
||||||
// Laurent Gomila (laurent.gom@gmail.com),
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <SFML/Window/Joystick.hpp>
|
|
||||||
#include <SFML/System/Err.hpp>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Joystick::Joystick()
|
|
||||||
: myManager(0)
|
|
||||||
, myElements(0)
|
|
||||||
{
|
|
||||||
/* Nothing else */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Joystick::~Joystick()
|
|
||||||
{
|
|
||||||
FreeUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void Joystick::Initialize(unsigned int Index)
|
|
||||||
{
|
|
||||||
// Try to create a joystick manager.
|
|
||||||
if (!CreateManager()) return;
|
|
||||||
|
|
||||||
// Get the joysticks.
|
|
||||||
CFSetRef devices = CopyJoysticksOnly();
|
|
||||||
|
|
||||||
// If none exit the function.
|
|
||||||
if (devices == NULL) {
|
|
||||||
FreeUp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is there enough joystick ?
|
|
||||||
CFIndex joysticksCount = CFSetGetCount(devices);
|
|
||||||
if (joysticksCount <= CFIndex(Index)) {
|
|
||||||
FreeUp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a usable copy of the joysticks devices.
|
|
||||||
CFTypeRef devicesArray[joysticksCount];
|
|
||||||
CFSetGetValues(devices, devicesArray);
|
|
||||||
|
|
||||||
// Release unused stuff.
|
|
||||||
CFRelease(devices); // Maybe we should have a field for that and not release it here...
|
|
||||||
|
|
||||||
// Get the Index-th joystick.
|
|
||||||
IOHIDDeviceRef device = (IOHIDDeviceRef) devicesArray[Index];
|
|
||||||
|
|
||||||
// Retrive all connected elements to this joystick.
|
|
||||||
if (!RetriveElements(device)) {
|
|
||||||
FreeUp();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Happy end!
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
JoystickState Joystick::UpdateState()
|
|
||||||
{
|
|
||||||
// If we don't have any joystick we exit.
|
|
||||||
if (myElements == 0) return JoystickState();
|
|
||||||
|
|
||||||
// Fill a JoystickState instance with the current joystick state.
|
|
||||||
JoystickState s;
|
|
||||||
|
|
||||||
// Update the buttons.
|
|
||||||
for (ButtonsVector::size_type i = 0; i < myButtons.size(); ++i) {
|
|
||||||
IOHIDValueRef value = 0;
|
|
||||||
IOHIDDeviceGetValue(IOHIDElementGetDevice(myButtons[i]), myButtons[i], &value);
|
|
||||||
|
|
||||||
// Check for plug out.
|
|
||||||
if (!value) {
|
|
||||||
// No value ? Hum... Seems like the joystick is gone.
|
|
||||||
|
|
||||||
FreeUp();
|
|
||||||
return JoystickState();
|
|
||||||
}
|
|
||||||
|
|
||||||
s.Buttons[i] = IOHIDValueGetIntegerValue(value) == 1; // 1 means pressed, others mean released.
|
|
||||||
}
|
|
||||||
|
|
||||||
for (AxisMap::iterator it = myAxis.begin(); it != myAxis.end(); ++it) {
|
|
||||||
IOHIDValueRef value = 0;
|
|
||||||
IOHIDDeviceGetValue(IOHIDElementGetDevice(it->second), it->second, &value);
|
|
||||||
|
|
||||||
// Check for plug out.
|
|
||||||
if (!value) {
|
|
||||||
// No value ? Hum... Seems like the joystick is gone.
|
|
||||||
|
|
||||||
FreeUp();
|
|
||||||
return JoystickState();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We want to bind [physicalMin,physicalMax] to [-100=min,100=max].
|
|
||||||
//
|
|
||||||
// General formula to bind [a,b] to [c,d] with a linear progression :
|
|
||||||
//
|
|
||||||
// f : [a, b] -> [c, d]
|
|
||||||
// x |-> (x-a)(d-c)/(b-a)+c
|
|
||||||
//
|
|
||||||
// This method might not be very accurate (the "0 position" can be
|
|
||||||
// slightly shift with some device) but we don't care because most
|
|
||||||
// of devices are so sensitive that this is not relevant.
|
|
||||||
double physicalMax = IOHIDElementGetPhysicalMax(it->second);
|
|
||||||
double physicalMin = IOHIDElementGetPhysicalMin(it->second);
|
|
||||||
double scaledMin = -100;
|
|
||||||
double scaledMax = 100;
|
|
||||||
double physicalValue = IOHIDValueGetScaledValue(value, kIOHIDValueScaleTypePhysical);
|
|
||||||
float scaledValue = ((physicalValue - physicalMin) * (scaledMax - scaledMin) / (physicalMax - physicalMin)) + scaledMin;
|
|
||||||
s.Axis[it->first] = scaledValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool Joystick::HasAxis(Joy::Axis Axis) const
|
|
||||||
{
|
|
||||||
return myAxis.find(Axis) != myAxis.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
unsigned int Joystick::GetButtonsCount() const
|
|
||||||
{
|
|
||||||
// Return number of supported buttons.
|
|
||||||
return myButtons.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
CFDictionaryRef Joystick::DevicesMaskForManager(UInt32 page, UInt32 usage)
|
|
||||||
{
|
|
||||||
// Create the dictionary.
|
|
||||||
CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 2,
|
|
||||||
&kCFTypeDictionaryKeyCallBacks,
|
|
||||||
&kCFTypeDictionaryValueCallBacks);
|
|
||||||
|
|
||||||
// Add the page value.
|
|
||||||
CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &page);
|
|
||||||
CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsagePageKey), value);
|
|
||||||
CFRelease(value);
|
|
||||||
|
|
||||||
// Add the usage value (which is only valid if page value exists).
|
|
||||||
value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &usage);
|
|
||||||
CFDictionarySetValue(dict, CFSTR(kIOHIDDeviceUsageKey), value);
|
|
||||||
CFRelease(value);
|
|
||||||
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool Joystick::CreateManager()
|
|
||||||
{
|
|
||||||
// Create HID Manager reference.
|
|
||||||
myManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
|
|
||||||
|
|
||||||
// Open a HID Manager reference.
|
|
||||||
IOReturn openStatus = IOHIDManagerOpen(myManager, kIOHIDOptionsTypeNone);
|
|
||||||
|
|
||||||
if (openStatus != kIOReturnSuccess) {
|
|
||||||
sf::Err() << "Error when opening the joystick manager : "
|
|
||||||
<< std::hex << openStatus << std::endl;
|
|
||||||
|
|
||||||
CFRelease(myManager);
|
|
||||||
myManager = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Everything went fine.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
CFSetRef Joystick::CopyJoysticksOnly()
|
|
||||||
{
|
|
||||||
// Create a mask to get only joystick devices.
|
|
||||||
CFDictionaryRef joysticksMask = DevicesMaskForManager(kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick);
|
|
||||||
|
|
||||||
// Sets single matching criteria (dictionary) for device enumeration.
|
|
||||||
IOHIDManagerSetDeviceMatching(myManager, joysticksMask);
|
|
||||||
|
|
||||||
// No more needed -> free up.
|
|
||||||
CFRelease(joysticksMask);
|
|
||||||
|
|
||||||
// Retrieve devices.
|
|
||||||
CFSetRef devices = IOHIDManagerCopyDevices(myManager);
|
|
||||||
return devices; // The caller is responsible for releasing it.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool Joystick::RetriveElements(IOHIDDeviceRef device)
|
|
||||||
{
|
|
||||||
// Get a list of all elements attached to the device.
|
|
||||||
myElements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
|
||||||
|
|
||||||
if (myElements == NULL) {
|
|
||||||
// What is a joystick with no element ? Let the user know that.
|
|
||||||
sf::Err() << "No array of element for this device" << std::endl;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// How many elements are there ?
|
|
||||||
CFIndex elements_count = CFArrayGetCount(myElements);
|
|
||||||
|
|
||||||
if (elements_count == 0) {
|
|
||||||
// What is a joystick with no element ? Let the user know that.
|
|
||||||
sf::Err() << "No element attached to this device" << std::endl;
|
|
||||||
|
|
||||||
CFRelease(myElements);
|
|
||||||
myElements = 0;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through all connected elements.
|
|
||||||
for (int i = 0; i < elements_count; ++i) {
|
|
||||||
IOHIDElementRef element = (IOHIDElementRef) CFArrayGetValueAtIndex(myElements, i);
|
|
||||||
|
|
||||||
switch (IOHIDElementGetType(element)) {
|
|
||||||
|
|
||||||
case kIOHIDElementTypeInput_Misc:
|
|
||||||
switch (IOHIDElementGetUsage(element)) {
|
|
||||||
|
|
||||||
case kHIDUsage_GD_X:
|
|
||||||
myAxis[Joy::AxisX] = element;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kHIDUsage_GD_Y:
|
|
||||||
myAxis[Joy::AxisY] = element;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kHIDUsage_GD_Z:
|
|
||||||
myAxis[Joy::AxisZ] = element;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kHIDUsage_GD_Rx:
|
|
||||||
myAxis[Joy::AxisU] = element; // use same binding as on Linux.
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kHIDUsage_GD_Ry:
|
|
||||||
myAxis[Joy::AxisV] = element; // use same binding as on Linux.
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kHIDUsage_GD_Rz:
|
|
||||||
myAxis[Joy::AxisR] = element; // use same binding as on Linux.
|
|
||||||
break;
|
|
||||||
|
|
||||||
// kHIDUsage_GD_Vx, kHIDUsage_GD_Vy, kHIDUsage_GD_Vz are ignored.
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kIOHIDElementTypeInput_Button:
|
|
||||||
if (myButtons.size() < Joy::ButtonCount) { // If we can managed this button through events...
|
|
||||||
myButtons.push_back(element); // ...we add this element to the list.
|
|
||||||
} else {
|
|
||||||
// Too many buttons. We ignore this one.
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // Make compiler happy.
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note : Joy::AxisPOV not yet supported.
|
|
||||||
// Maybe kIOHIDElementTypeInput_Axis is the type but I can't test.
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void Joystick::FreeUp()
|
|
||||||
{
|
|
||||||
ReleaseElements();
|
|
||||||
|
|
||||||
ReleaseManager();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void Joystick::ReleaseManager()
|
|
||||||
{
|
|
||||||
if (myManager != 0) {
|
|
||||||
// Closes the IOHIDManager
|
|
||||||
IOReturn closeStatus = IOHIDManagerClose(myManager, kIOHIDOptionsTypeNone);
|
|
||||||
|
|
||||||
if (closeStatus != kIOReturnSuccess) {
|
|
||||||
// Closing the manager failed. We don't care that much about this.
|
|
||||||
// It often happens when the connection with the device is closed after
|
|
||||||
// the device is deconected from the computer.
|
|
||||||
|
|
||||||
/*
|
|
||||||
sf::Err() << "Error when closing the manager : "
|
|
||||||
<< std::hex << closeStatus << std::endl;
|
|
||||||
//*/
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release the manager.
|
|
||||||
CFRelease(myManager);
|
|
||||||
myManager = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void Joystick::ReleaseElements()
|
|
||||||
{
|
|
||||||
if (myElements != 0) {
|
|
||||||
// Release all elements.
|
|
||||||
CFRelease(myElements);
|
|
||||||
myElements = 0;
|
|
||||||
|
|
||||||
// Both myAxis and myButton contains only reference from myElements.
|
|
||||||
// Thus no special cleanup is required on these two.
|
|
||||||
myButtons.clear();
|
|
||||||
myAxis.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
@ -1,176 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// SFML - Simple and Fast Multimedia Library
|
|
||||||
// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
|
|
||||||
// Laurent Gomila (laurent.gom@gmail.com),
|
|
||||||
//
|
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
|
||||||
//
|
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
|
||||||
// subject to the following restrictions:
|
|
||||||
//
|
|
||||||
// 1. The origin of this software must not be misrepresented;
|
|
||||||
// you must not claim that you wrote the original software.
|
|
||||||
// If you use this software in a product, an acknowledgment
|
|
||||||
// in the product documentation would be appreciated but is not required.
|
|
||||||
//
|
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
|
||||||
// and must not be misrepresented as being the original software.
|
|
||||||
//
|
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef SFML_JOYSTICKOSX_HPP
|
|
||||||
#define SFML_JOYSTICKOSX_HPP
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Headers
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
#include <IOKit/hid/IOHIDManager.h>
|
|
||||||
#include <IOKit/hid/IOHIDDevice.h>
|
|
||||||
#include <map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace sf
|
|
||||||
{
|
|
||||||
namespace priv
|
|
||||||
{
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief OSX implementation of Joystick
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
class Joystick
|
|
||||||
{
|
|
||||||
public :
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Default constructor
|
|
||||||
///
|
|
||||||
/// This constructors initializes all members to 0.
|
|
||||||
/// That is, it does nothing.
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
Joystick();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Destructor
|
|
||||||
///
|
|
||||||
/// Close all connections to any devices if required.
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
~Joystick();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Initialize the instance and bind it to a physical joystick
|
|
||||||
///
|
|
||||||
/// \param index Index of the physical joystick to bind to
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void Initialize(unsigned int index);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Update the current joystick and return its new state
|
|
||||||
///
|
|
||||||
/// \return Current state of the joystick
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
JoystickState UpdateState();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Check if the joystick supports the given axis
|
|
||||||
///
|
|
||||||
/// \param axis Axis to check
|
|
||||||
///
|
|
||||||
/// \return True of the axis is supported, false otherwise
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool HasAxis(Joy::Axis Axis) const;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Get the number of buttons supported by the joystick
|
|
||||||
///
|
|
||||||
/// \return Number of buttons
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
unsigned int GetButtonsCount() const;
|
|
||||||
|
|
||||||
private :
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Create a mask (dictionary) for an IOHIDManager
|
|
||||||
///
|
|
||||||
/// \param page
|
|
||||||
/// \param usage
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
static CFDictionaryRef DevicesMaskForManager(UInt32 page, UInt32 usage);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Create and open the manager
|
|
||||||
///
|
|
||||||
/// \return Return false if someting went wrong
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool CreateManager();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Copy all connected joysticks to the manager
|
|
||||||
///
|
|
||||||
/// \return NULL or a valid (possibly empty) set of devices
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
CFSetRef CopyJoysticksOnly();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Load all connected elements to the given device
|
|
||||||
///
|
|
||||||
/// \param device The desired joystick
|
|
||||||
/// \return False if something went wrong
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool RetriveElements(IOHIDDeviceRef device);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Release all resources
|
|
||||||
///
|
|
||||||
/// Close all connections to any devices, if required
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void FreeUp();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Close and release the manager
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void ReleaseManager();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// \brief Release all elements
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void ReleaseElements();
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Member data
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
typedef std::map<sf::Joy::Axis, IOHIDElementRef> AxisMap;
|
|
||||||
typedef std::vector<IOHIDElementRef> ButtonsVector;
|
|
||||||
|
|
||||||
AxisMap myAxis; ///< Axis (IOHIDElementRef) connected to the joystick.
|
|
||||||
ButtonsVector myButtons; ///< Buttons (IOHIDElementRef) connected to the joystick.
|
|
||||||
// Note : Both myAxis and myButton contains only reference from myElements.
|
|
||||||
// Thus no special cleanup is required on these two.
|
|
||||||
|
|
||||||
IOHIDManagerRef myManager; ///< HID Manager.
|
|
||||||
CFArrayRef myElements; ///< IOHIDElementRef connected to the joytick.
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace priv
|
|
||||||
|
|
||||||
} // namespace sf
|
|
||||||
|
|
||||||
|
|
||||||
#endif // SFML_JOYSTICKOSX_HPP
|
|
@ -1,7 +1,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// SFML - Simple and Fast Multimedia Library
|
// SFML - Simple and Fast Multimedia Library
|
||||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent.gom@gmail.com),
|
||||||
//
|
//
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// SFML - Simple and Fast Multimedia Library
|
// SFML - Simple and Fast Multimedia Library
|
||||||
// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
|
// Copyright (C) 2007-2011 Marco Antognini (antognini.marco@gmail.com),
|
||||||
|
// Laurent Gomila (laurent.gom@gmail.com),
|
||||||
//
|
//
|
||||||
// This software is provided 'as-is', without any express or implied warranty.
|
// This software is provided 'as-is', without any express or implied warranty.
|
||||||
// In no event will the authors be held liable for any damages arising from the use of this software.
|
// In no event will the authors be held liable for any damages arising from the use of this software.
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
/// \brief Event processing
|
/// \brief Event processing
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
+(void)processEvent
|
+(void)processEvent;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -100,4 +100,10 @@ namespace sf {
|
|||||||
-(void)enableKeyRepeat;
|
-(void)enableKeyRepeat;
|
||||||
-(void)disableKeyRepeat;
|
-(void)disableKeyRepeat;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Compute the position of the cursor.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
-(NSPoint)cursorPositionFromEvent:(NSEvent *)eventOrNil;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
|
||||||
|
#include <SFML/Window/OSX/HIDInputManager.hpp> // For LocalizedKeys and NonLocalizedKeys
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
|
||||||
#import <SFML/Window/OSX/SFOpenGLView.h>
|
#import <SFML/Window/OSX/SFOpenGLView.h>
|
||||||
@ -60,25 +61,6 @@ NSUInteger EraseMaskFromData(NSUInteger data, NSUInteger mask);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
NSUInteger KeepOnlyMaskFromData(NSUInteger data, NSUInteger mask);
|
NSUInteger KeepOnlyMaskFromData(NSUInteger data, NSUInteger mask);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Try to convert a character into a SFML key code.
|
|
||||||
/// Return sf::Key::Count if it doesn't match any 'localized' keys.
|
|
||||||
///
|
|
||||||
/// By 'localized' I mean keys that depend on the keyboard layout
|
|
||||||
/// and might not be the same as the US keycode in some country
|
|
||||||
/// (e.g. the keys 'Y' and 'Z' are switched on QWERTZ keyboard and
|
|
||||||
/// US keyboard layouts.)
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
sf::Key::Code LocalizedKeys(unichar ch);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Try to convert a keycode into a SFML key code.
|
|
||||||
/// Return sf::Key::Count if the keycode is unknown.
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// SFOpenGLView class : Privates Methods Declaration
|
/// SFOpenGLView class : Privates Methods Declaration
|
||||||
///
|
///
|
||||||
@ -103,15 +85,11 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)initModifiersState;
|
-(void)initModifiersState;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
/// Compute the position of the cursor.
|
|
||||||
///
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
-(NSPoint)cursorPositionFromEvent:(NSEvent *)event;
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Converte the NSEvent mouse button type to SFML type.
|
/// Converte the NSEvent mouse button type to SFML type.
|
||||||
///
|
///
|
||||||
|
/// Returns ButtonCount if the button is unknown
|
||||||
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent *)event;
|
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent *)event;
|
||||||
|
|
||||||
@ -119,7 +97,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
/// Convert a key down/up NSEvent into an SFML key event.
|
/// Convert a key down/up NSEvent into an SFML key event.
|
||||||
/// Based on LocalizedKeys and NonLocalizedKeys function.
|
/// Based on LocalizedKeys and NonLocalizedKeys function.
|
||||||
///
|
///
|
||||||
/// Return sf::Key::Count as Code if the key is unknown.
|
/// Return sf::Keyboard::KeyCount as Code if the key is unknown.
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent;
|
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent;
|
||||||
@ -198,11 +176,12 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
// Place the cursor.
|
// Place the cursor.
|
||||||
CGEventRef event = CGEventCreateMouseEvent(NULL,
|
CGEventRef event = CGEventCreateMouseEvent(NULL,
|
||||||
kCGEventMouseMoved,
|
kCGEventMouseMoved,
|
||||||
CGPointMake(screenCoord.x, screenCoord.y),
|
CGPointMake(screenCoord.x,
|
||||||
|
screenCoord.y),
|
||||||
/*we don't care about this : */0);
|
/*we don't care about this : */0);
|
||||||
CGEventPost(kCGHIDEventTap, event);
|
CGEventPost(kCGHIDEventTap, event);
|
||||||
CFRelease(event);
|
CFRelease(event);
|
||||||
// This is a workaround to deprecated CGSetLocalEventsSuppressionInterval.
|
// This is a workaround to deprecated CGSetLocalEventsSuppressionInterval function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -384,7 +363,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
|
|
||||||
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
||||||
|
|
||||||
|
if (button != sf::Mouse::ButtonCount) {
|
||||||
myRequester->MouseDownAt(button, loc.x, loc.y);
|
myRequester->MouseDownAt(button, loc.x, loc.y);
|
||||||
|
}
|
||||||
|
//#ifdef SFML_DEBUG
|
||||||
|
// else {
|
||||||
|
// sf::Err() << "Unknown mouse button released." << std::endl;
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -397,7 +383,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
|
|
||||||
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
|
||||||
|
|
||||||
|
if (button != sf::Mouse::ButtonCount) {
|
||||||
myRequester->MouseUpAt(button, loc.x, loc.y);
|
myRequester->MouseUpAt(button, loc.x, loc.y);
|
||||||
|
}
|
||||||
|
//#ifdef SFML_DEBUG
|
||||||
|
// else {
|
||||||
|
// sf::Err() << "Unknown mouse button released." << std::endl;
|
||||||
|
// }
|
||||||
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -431,6 +424,46 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(NSPoint)cursorPositionFromEvent:(NSEvent *)eventOrNil
|
||||||
|
{
|
||||||
|
NSPoint loc;
|
||||||
|
// If no event given then get current mouse pos.
|
||||||
|
if (eventOrNil == nil) {
|
||||||
|
NSPoint rawPos = [[self window] mouseLocationOutsideOfEventStream];
|
||||||
|
loc = [self convertPoint:rawPos fromView:nil];
|
||||||
|
} else {
|
||||||
|
loc = [self convertPoint:[eventOrNil locationInWindow] fromView:nil];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't forget to change to SFML coord system.
|
||||||
|
float h = [self frame].size.height;
|
||||||
|
loc.y = h - loc.y;
|
||||||
|
|
||||||
|
// Recompute the mouse pos if required.
|
||||||
|
if (!NSEqualSizes(myRealSize, NSZeroSize)) {
|
||||||
|
loc.x = loc.x * myRealSize.width / [self frame].size.width;
|
||||||
|
loc.y = loc.y * myRealSize.height / [self frame].size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////
|
||||||
|
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent *)event
|
||||||
|
{
|
||||||
|
switch ([event buttonNumber]) {
|
||||||
|
case 0: return sf::Mouse::Left;
|
||||||
|
case 1: return sf::Mouse::Right;
|
||||||
|
case 2: return sf::Mouse::Middle;
|
||||||
|
case 3: return sf::Mouse::XButton1;
|
||||||
|
case 4: return sf::Mouse::XButton2;
|
||||||
|
default: return sf::Mouse::ButtonCount; // Never happens! (hopefully)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#pragma mark
|
#pragma mark
|
||||||
#pragma mark Key-event methods
|
#pragma mark Key-event methods
|
||||||
|
|
||||||
@ -440,14 +473,17 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
{
|
{
|
||||||
if (myRequester == 0) return;
|
if (myRequester == 0) return;
|
||||||
|
|
||||||
|
// Handle key down event
|
||||||
if (myUseKeyRepeat || ![theEvent isARepeat]) {
|
if (myUseKeyRepeat || ![theEvent isARepeat]) {
|
||||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
||||||
|
|
||||||
if (key.Code != sf::Key::Count) { // The key is recognized.
|
if (key.Code != sf::Keyboard::KeyCount) { // The key is recognized.
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Handle text entred event
|
||||||
if ((myUseKeyRepeat || ![theEvent isARepeat]) && [[theEvent characters] length] > 0) {
|
if ((myUseKeyRepeat || ![theEvent isARepeat]) && [[theEvent characters] length] > 0) {
|
||||||
|
|
||||||
// Ignore escape key and non text keycode. (See NSEvent.h)
|
// Ignore escape key and non text keycode. (See NSEvent.h)
|
||||||
@ -478,7 +514,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
|
|
||||||
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
|
||||||
|
|
||||||
if (key.Code != sf::Key::Count) { // The key is recognized.
|
if (key.Code != sf::Keyboard::KeyCount) { // The key is recognized.
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,7 +529,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
|
|
||||||
// Setup a potential event key.
|
// Setup a potential event key.
|
||||||
sf::Event::KeyEvent key;
|
sf::Event::KeyEvent key;
|
||||||
key.Code = sf::Key::Count;
|
key.Code = sf::Keyboard::KeyCount;
|
||||||
key.Alt = modifiers & NSAlternateKeyMask;
|
key.Alt = modifiers & NSAlternateKeyMask;
|
||||||
key.Control = modifiers & NSControlKeyMask;
|
key.Control = modifiers & NSControlKeyMask;
|
||||||
key.Shift = modifiers & NSShiftKeyMask;
|
key.Shift = modifiers & NSShiftKeyMask;
|
||||||
@ -522,14 +558,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
// left shift released
|
// left shift released
|
||||||
leftShiftIsDown = NO;
|
leftShiftIsDown = NO;
|
||||||
|
|
||||||
key.Code = sf::Key::LShift;
|
key.Code = sf::Keyboard::LShift;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myRightShiftWasDown) {
|
if (!myRightShiftWasDown) {
|
||||||
// right shift pressed
|
// right shift pressed
|
||||||
|
|
||||||
key.Code = sf::Key::RShift;
|
key.Code = sf::Keyboard::RShift;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -543,14 +579,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
// right shift released
|
// right shift released
|
||||||
rightShiftIsDown = NO;
|
rightShiftIsDown = NO;
|
||||||
|
|
||||||
key.Code = sf::Key::RShift;
|
key.Code = sf::Keyboard::RShift;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myLeftShiftWasDown) {
|
if (!myLeftShiftWasDown) {
|
||||||
// left shift pressed
|
// left shift pressed
|
||||||
|
|
||||||
key.Code = sf::Key::LShift;
|
key.Code = sf::Keyboard::LShift;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -564,14 +600,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (!myRightShiftWasDown) {
|
if (!myRightShiftWasDown) {
|
||||||
// right shift pressed
|
// right shift pressed
|
||||||
|
|
||||||
key.Code = sf::Key::RShift;
|
key.Code = sf::Keyboard::RShift;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myLeftShiftWasDown) {
|
if (!myLeftShiftWasDown) {
|
||||||
// left shift pressed
|
// left shift pressed
|
||||||
|
|
||||||
key.Code = sf::Key::LShift;
|
key.Code = sf::Keyboard::LShift;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -583,14 +619,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (myRightShiftWasDown) {
|
if (myRightShiftWasDown) {
|
||||||
// right shift released
|
// right shift released
|
||||||
|
|
||||||
key.Code = sf::Key::RShift;
|
key.Code = sf::Keyboard::RShift;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myLeftShiftWasDown) {
|
if (myLeftShiftWasDown) {
|
||||||
// left shift released
|
// left shift released
|
||||||
|
|
||||||
key.Code = sf::Key::LShift;
|
key.Code = sf::Keyboard::LShift;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -609,14 +645,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
// left command released
|
// left command released
|
||||||
leftCommandIsDown = NO;
|
leftCommandIsDown = NO;
|
||||||
|
|
||||||
key.Code = sf::Key::LSystem;
|
key.Code = sf::Keyboard::LSystem;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myRightCommandWasDown) {
|
if (!myRightCommandWasDown) {
|
||||||
// right command pressed
|
// right command pressed
|
||||||
|
|
||||||
key.Code = sf::Key::RSystem;
|
key.Code = sf::Keyboard::RSystem;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -630,14 +666,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
// right command released
|
// right command released
|
||||||
rightCommandIsDown = NO;
|
rightCommandIsDown = NO;
|
||||||
|
|
||||||
key.Code = sf::Key::RSystem;
|
key.Code = sf::Keyboard::RSystem;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myLeftCommandWasDown) {
|
if (!myLeftCommandWasDown) {
|
||||||
// left command pressed
|
// left command pressed
|
||||||
|
|
||||||
key.Code = sf::Key::LSystem;
|
key.Code = sf::Keyboard::LSystem;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -651,14 +687,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (!myRightCommandWasDown) {
|
if (!myRightCommandWasDown) {
|
||||||
// right command pressed
|
// right command pressed
|
||||||
|
|
||||||
key.Code = sf::Key::RSystem;
|
key.Code = sf::Keyboard::RSystem;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myLeftCommandWasDown) {
|
if (!myLeftCommandWasDown) {
|
||||||
// left command pressed
|
// left command pressed
|
||||||
|
|
||||||
key.Code = sf::Key::LSystem;
|
key.Code = sf::Keyboard::LSystem;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -670,14 +706,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (myRightCommandWasDown) {
|
if (myRightCommandWasDown) {
|
||||||
// right command released
|
// right command released
|
||||||
|
|
||||||
key.Code = sf::Key::RSystem;
|
key.Code = sf::Keyboard::RSystem;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myLeftCommandWasDown) {
|
if (myLeftCommandWasDown) {
|
||||||
// left command released
|
// left command released
|
||||||
|
|
||||||
key.Code = sf::Key::LSystem;
|
key.Code = sf::Keyboard::LSystem;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -696,14 +732,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
// left alt released
|
// left alt released
|
||||||
leftAlternateIsDown = NO;
|
leftAlternateIsDown = NO;
|
||||||
|
|
||||||
key.Code = sf::Key::LAlt;
|
key.Code = sf::Keyboard::LAlt;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myRightAlternateWasDown) {
|
if (!myRightAlternateWasDown) {
|
||||||
// right alt pressed
|
// right alt pressed
|
||||||
|
|
||||||
key.Code = sf::Key::RAlt;
|
key.Code = sf::Keyboard::RAlt;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -717,14 +753,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
// right alt released
|
// right alt released
|
||||||
rightAlternateIsDown = NO;
|
rightAlternateIsDown = NO;
|
||||||
|
|
||||||
key.Code = sf::Key::RAlt;
|
key.Code = sf::Keyboard::RAlt;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myLeftAlternateWasDown) {
|
if (!myLeftAlternateWasDown) {
|
||||||
// left alt pressed
|
// left alt pressed
|
||||||
|
|
||||||
key.Code = sf::Key::LAlt;
|
key.Code = sf::Keyboard::LAlt;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -738,14 +774,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (!myRightAlternateWasDown) {
|
if (!myRightAlternateWasDown) {
|
||||||
// right alt pressed
|
// right alt pressed
|
||||||
|
|
||||||
key.Code = sf::Key::RAlt;
|
key.Code = sf::Keyboard::RAlt;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!myLeftAlternateWasDown) {
|
if (!myLeftAlternateWasDown) {
|
||||||
// left alt pressed
|
// left alt pressed
|
||||||
|
|
||||||
key.Code = sf::Key::LAlt;
|
key.Code = sf::Keyboard::LAlt;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -757,14 +793,14 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (myRightAlternateWasDown) {
|
if (myRightAlternateWasDown) {
|
||||||
// right alt released
|
// right alt released
|
||||||
|
|
||||||
key.Code = sf::Key::RAlt;
|
key.Code = sf::Keyboard::RAlt;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (myLeftAlternateWasDown) {
|
if (myLeftAlternateWasDown) {
|
||||||
// left alt released
|
// left alt released
|
||||||
|
|
||||||
key.Code = sf::Key::LAlt;
|
key.Code = sf::Keyboard::LAlt;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -778,7 +814,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (!myControlWasDown) {
|
if (!myControlWasDown) {
|
||||||
// ctrl pressed
|
// ctrl pressed
|
||||||
|
|
||||||
key.Code = sf::Key::LControl;
|
key.Code = sf::Keyboard::LControl;
|
||||||
myRequester->KeyDown(key);
|
myRequester->KeyDown(key);
|
||||||
}
|
}
|
||||||
} else { // No control key down.
|
} else { // No control key down.
|
||||||
@ -787,7 +823,7 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
if (myControlWasDown) {
|
if (myControlWasDown) {
|
||||||
// ctrl released
|
// ctrl released
|
||||||
|
|
||||||
key.Code = sf::Key::LControl;
|
key.Code = sf::Keyboard::LControl;
|
||||||
myRequester->KeyUp(key);
|
myRequester->KeyUp(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -903,39 +939,6 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(NSPoint)cursorPositionFromEvent:(NSEvent *)event
|
|
||||||
{
|
|
||||||
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
|
|
||||||
|
|
||||||
// Don't forget to change to SFML coord system.
|
|
||||||
float h = [self frame].size.height;
|
|
||||||
loc.y = h - loc.y;
|
|
||||||
|
|
||||||
// Recompute the mouse pos if required.
|
|
||||||
if (!NSEqualSizes(myRealSize, NSZeroSize)) {
|
|
||||||
loc.x = loc.x * myRealSize.width / [self frame].size.width;
|
|
||||||
loc.y = loc.y * myRealSize.height / [self frame].size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
return loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
-(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent *)event
|
|
||||||
{
|
|
||||||
switch ([event buttonNumber]) {
|
|
||||||
case 0: return sf::Mouse::Left;
|
|
||||||
case 1: return sf::Mouse::Right;
|
|
||||||
case 2: return sf::Mouse::Middle;
|
|
||||||
case 3: return sf::Mouse::XButton1;
|
|
||||||
case 4: return sf::Mouse::XButton2;
|
|
||||||
default: return sf::Mouse::ButtonCount; // Never happens! (hopefully)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent
|
+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent *)anEvent
|
||||||
{
|
{
|
||||||
@ -949,28 +952,30 @@ sf::Key::Code NonLocalizedKeys(unsigned short keycode);
|
|||||||
key.System = modifierFlags & NSCommandKeyMask;
|
key.System = modifierFlags & NSCommandKeyMask;
|
||||||
|
|
||||||
// Key code.
|
// Key code.
|
||||||
key.Code = sf::Key::Count;
|
key.Code = sf::Keyboard::KeyCount;
|
||||||
// First we look if the key down is from a list of caracter that depend on keyboard localization.
|
|
||||||
|
// First we look if the key down is from a list of caracter
|
||||||
|
// that depend on keyboard localization.
|
||||||
NSString* string = [anEvent charactersIgnoringModifiers];
|
NSString* string = [anEvent charactersIgnoringModifiers];
|
||||||
if ([string length] > 0) {
|
if ([string length] > 0) {
|
||||||
key.Code = LocalizedKeys([string characterAtIndex:0]);
|
key.Code = sf::priv::HIDInputManager::LocalizedKeys([string characterAtIndex:0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The key is not a localized one, the other keys.
|
// The key is not a localized one, so we try to find a corresponding code
|
||||||
if (key.Code == sf::Key::Count) {
|
// through virtual key code.
|
||||||
key.Code = NonLocalizedKeys([anEvent keyCode]);
|
if (key.Code == sf::Keyboard::KeyCount) {
|
||||||
|
key.Code = sf::priv::HIDInputManager::NonLocalizedKeys([anEvent keyCode]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SFML_DEBUG // We don't want to bother the final customer with anoying messages.
|
//#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages.
|
||||||
if (key.Code == sf::Key::Count) { // The key is unknown.
|
// if (key.Code == sf::Keyboard::KeyCount) { // The key is unknown.
|
||||||
sf::Err()
|
// sf::Err() << "This is an unknow key. Virtual key code is 0x"
|
||||||
<< "This is an unknow key. Should not happen (?). Keycode is 0x"
|
// << std::hex
|
||||||
<< std::hex
|
// << [anEvent keyCode]
|
||||||
<< [anEvent keyCode]
|
// << "."
|
||||||
<< "."
|
// << std::endl;
|
||||||
<< std::endl;
|
// }
|
||||||
}
|
//#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
@ -996,256 +1001,3 @@ NSUInteger KeepOnlyMaskFromData(NSUInteger data, NSUInteger mask)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
sf::Key::Code LocalizedKeys(unichar ch)
|
|
||||||
{
|
|
||||||
switch (ch) {
|
|
||||||
case 'a':
|
|
||||||
case 'A': return sf::Key::A;
|
|
||||||
|
|
||||||
case 'b':
|
|
||||||
case 'B': return sf::Key::B;
|
|
||||||
|
|
||||||
case 'c':
|
|
||||||
case 'C': return sf::Key::C;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
case 'D': return sf::Key::D;
|
|
||||||
|
|
||||||
case 'e':
|
|
||||||
case 'E': return sf::Key::E;
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
case 'F': return sf::Key::F;
|
|
||||||
|
|
||||||
case 'g':
|
|
||||||
case 'G': return sf::Key::G;
|
|
||||||
|
|
||||||
case 'h':
|
|
||||||
case 'H': return sf::Key::H;
|
|
||||||
|
|
||||||
case 'i':
|
|
||||||
case 'I': return sf::Key::I;
|
|
||||||
|
|
||||||
case 'j':
|
|
||||||
case 'J': return sf::Key::J;
|
|
||||||
|
|
||||||
case 'k':
|
|
||||||
case 'K': return sf::Key::K;
|
|
||||||
|
|
||||||
case 'l':
|
|
||||||
case 'L': return sf::Key::L;
|
|
||||||
|
|
||||||
case 'm':
|
|
||||||
case 'M': return sf::Key::M;
|
|
||||||
|
|
||||||
case 'n':
|
|
||||||
case 'N': return sf::Key::N;
|
|
||||||
|
|
||||||
case 'o':
|
|
||||||
case 'O': return sf::Key::O;
|
|
||||||
|
|
||||||
case 'p':
|
|
||||||
case 'P': return sf::Key::P;
|
|
||||||
|
|
||||||
case 'q':
|
|
||||||
case 'Q': return sf::Key::Q;
|
|
||||||
|
|
||||||
case 'r':
|
|
||||||
case 'R': return sf::Key::R;
|
|
||||||
|
|
||||||
case 's':
|
|
||||||
case 'S': return sf::Key::S;
|
|
||||||
|
|
||||||
case 't':
|
|
||||||
case 'T': return sf::Key::T;
|
|
||||||
|
|
||||||
case 'u':
|
|
||||||
case 'U': return sf::Key::U;
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
case 'V': return sf::Key::V;
|
|
||||||
|
|
||||||
case 'w':
|
|
||||||
case 'W': return sf::Key::W;
|
|
||||||
|
|
||||||
case 'x':
|
|
||||||
case 'X': return sf::Key::X;
|
|
||||||
|
|
||||||
case 'y':
|
|
||||||
case 'Y': return sf::Key::Y;
|
|
||||||
|
|
||||||
case 'z':
|
|
||||||
case 'Z': return sf::Key::Z;
|
|
||||||
|
|
||||||
// The kew is not 'localized'.
|
|
||||||
default: return sf::Key::Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
|
||||||
sf::Key::Code NonLocalizedKeys(unsigned short keycode)
|
|
||||||
{
|
|
||||||
// (Some) 0x code based on http://forums.macrumors.com/showthread.php?t=780577
|
|
||||||
// Some sf::Key are present twice.
|
|
||||||
switch (keycode) {
|
|
||||||
// These cases should not be used but anyway...
|
|
||||||
case 0x00: return sf::Key::A;
|
|
||||||
case 0x0b: return sf::Key::B;
|
|
||||||
case 0x08: return sf::Key::C;
|
|
||||||
case 0x02: return sf::Key::D;
|
|
||||||
case 0x0e: return sf::Key::E;
|
|
||||||
case 0x03: return sf::Key::F;
|
|
||||||
case 0x05: return sf::Key::G;
|
|
||||||
case 0x04: return sf::Key::H;
|
|
||||||
case 0x22: return sf::Key::I;
|
|
||||||
case 0x26: return sf::Key::J;
|
|
||||||
case 0x28: return sf::Key::K;
|
|
||||||
case 0x25: return sf::Key::L;
|
|
||||||
case 0x2e: return sf::Key::M;
|
|
||||||
case 0x2d: return sf::Key::N;
|
|
||||||
case 0x1f: return sf::Key::O;
|
|
||||||
case 0x23: return sf::Key::P;
|
|
||||||
case 0x0c: return sf::Key::Q;
|
|
||||||
case 0x0f: return sf::Key::R;
|
|
||||||
case 0x01: return sf::Key::S;
|
|
||||||
case 0x11: return sf::Key::T;
|
|
||||||
case 0x20: return sf::Key::U;
|
|
||||||
case 0x09: return sf::Key::V;
|
|
||||||
case 0x0d: return sf::Key::W;
|
|
||||||
case 0x07: return sf::Key::X;
|
|
||||||
case 0x10: return sf::Key::Y;
|
|
||||||
case 0x06: return sf::Key::Z;
|
|
||||||
|
|
||||||
// These cases should not be used but anyway...
|
|
||||||
case 0x1d: return sf::Key::Num0;
|
|
||||||
case 0x12: return sf::Key::Num1;
|
|
||||||
case 0x13: return sf::Key::Num2;
|
|
||||||
case 0x14: return sf::Key::Num3;
|
|
||||||
case 0x15: return sf::Key::Num4;
|
|
||||||
case 0x17: return sf::Key::Num5;
|
|
||||||
case 0x16: return sf::Key::Num6;
|
|
||||||
case 0x1a: return sf::Key::Num7;
|
|
||||||
case 0x1c: return sf::Key::Num8;
|
|
||||||
case 0x19: return sf::Key::Num9;
|
|
||||||
|
|
||||||
case 0x35: return sf::Key::Escape;
|
|
||||||
|
|
||||||
// Modifier keys : never happen with keyDown/keyUp methods (?)
|
|
||||||
case 0x3b: return sf::Key::LControl;
|
|
||||||
case 0x38: return sf::Key::LShift;
|
|
||||||
case 0x3a: return sf::Key::LAlt;
|
|
||||||
case 0x37: return sf::Key::LSystem;
|
|
||||||
case 0x3e: return sf::Key::RControl;
|
|
||||||
case 0x3c: return sf::Key::RShift;
|
|
||||||
case 0x3d: return sf::Key::RAlt;
|
|
||||||
case 0x36: return sf::Key::RSystem;
|
|
||||||
|
|
||||||
case NSMenuFunctionKey: return sf::Key::Menu;
|
|
||||||
|
|
||||||
case 0x21: return sf::Key::LBracket;
|
|
||||||
case 0x1e: return sf::Key::RBracket;
|
|
||||||
case 0x29: return sf::Key::SemiColon;
|
|
||||||
case 0x2b: return sf::Key::Comma;
|
|
||||||
case 0x2f: return sf::Key::Period;
|
|
||||||
case 0x27: return sf::Key::Quote;
|
|
||||||
case 0x2c: return sf::Key::Slash;
|
|
||||||
case 0x2a: return sf::Key::BackSlash;
|
|
||||||
|
|
||||||
#warning sf::Key::Tilde might be in conflict with some other key.
|
|
||||||
// 0x0a is for "Non-US Backslash" according to HID Calibrator,
|
|
||||||
// a sample provided by Apple.
|
|
||||||
case 0x0a: return sf::Key::Tilde;
|
|
||||||
|
|
||||||
case 0x18: return sf::Key::Equal;
|
|
||||||
case 0x32: return sf::Key::Dash;
|
|
||||||
case 0x31: return sf::Key::Space;
|
|
||||||
case 0x24: return sf::Key::Return;
|
|
||||||
case 0x33: return sf::Key::Back;
|
|
||||||
case 0x30: return sf::Key::Tab;
|
|
||||||
|
|
||||||
// Duplicates (see next §).
|
|
||||||
case 0x74: return sf::Key::PageUp;
|
|
||||||
case 0x79: return sf::Key::PageDown;
|
|
||||||
case 0x77: return sf::Key::End;
|
|
||||||
case 0x73: return sf::Key::Home;
|
|
||||||
|
|
||||||
case NSPageUpFunctionKey: return sf::Key::PageUp;
|
|
||||||
case NSPageDownFunctionKey: return sf::Key::PageDown;
|
|
||||||
case NSEndFunctionKey: return sf::Key::End;
|
|
||||||
case NSHomeFunctionKey: return sf::Key::Home;
|
|
||||||
|
|
||||||
case NSInsertFunctionKey: return sf::Key::Insert;
|
|
||||||
case NSDeleteFunctionKey: return sf::Key::Delete;
|
|
||||||
|
|
||||||
case 0x45: return sf::Key::Add;
|
|
||||||
case 0x4e: return sf::Key::Subtract;
|
|
||||||
case 0x43: return sf::Key::Multiply;
|
|
||||||
case 0x4b: return sf::Key::Divide;
|
|
||||||
|
|
||||||
// Duplicates (see next §).
|
|
||||||
case 0x7b: return sf::Key::Left;
|
|
||||||
case 0x7c: return sf::Key::Right;
|
|
||||||
case 0x7e: return sf::Key::Up;
|
|
||||||
case 0x7d: return sf::Key::Down;
|
|
||||||
|
|
||||||
case NSLeftArrowFunctionKey: return sf::Key::Left;
|
|
||||||
case NSRightArrowFunctionKey: return sf::Key::Right;
|
|
||||||
case NSUpArrowFunctionKey: return sf::Key::Up;
|
|
||||||
case NSDownArrowFunctionKey: return sf::Key::Down;
|
|
||||||
|
|
||||||
case 0x52: return sf::Key::Numpad0;
|
|
||||||
case 0x53: return sf::Key::Numpad1;
|
|
||||||
case 0x54: return sf::Key::Numpad2;
|
|
||||||
case 0x55: return sf::Key::Numpad3;
|
|
||||||
case 0x56: return sf::Key::Numpad4;
|
|
||||||
case 0x57: return sf::Key::Numpad5;
|
|
||||||
case 0x58: return sf::Key::Numpad6;
|
|
||||||
case 0x59: return sf::Key::Numpad7;
|
|
||||||
case 0x5b: return sf::Key::Numpad8;
|
|
||||||
case 0x5c: return sf::Key::Numpad9;
|
|
||||||
|
|
||||||
// Duplicates (see next §).
|
|
||||||
case 0x7a: return sf::Key::F1;
|
|
||||||
case 0x78: return sf::Key::F2;
|
|
||||||
case 0x63: return sf::Key::F3;
|
|
||||||
case 0x76: return sf::Key::F4;
|
|
||||||
case 0x60: return sf::Key::F5;
|
|
||||||
case 0x61: return sf::Key::F6;
|
|
||||||
case 0x62: return sf::Key::F7;
|
|
||||||
case 0x64: return sf::Key::F8;
|
|
||||||
case 0x65: return sf::Key::F9;
|
|
||||||
case 0x6d: return sf::Key::F10;
|
|
||||||
case 0x67: return sf::Key::F11;
|
|
||||||
case 0x6f: return sf::Key::F12;
|
|
||||||
case 0x69: return sf::Key::F13;
|
|
||||||
case 0x6b: return sf::Key::F14;
|
|
||||||
case 0x71: return sf::Key::F15;
|
|
||||||
|
|
||||||
case NSF1FunctionKey: return sf::Key::F1;
|
|
||||||
case NSF2FunctionKey: return sf::Key::F2;
|
|
||||||
case NSF3FunctionKey: return sf::Key::F3;
|
|
||||||
case NSF4FunctionKey: return sf::Key::F4;
|
|
||||||
case NSF5FunctionKey: return sf::Key::F5;
|
|
||||||
case NSF6FunctionKey: return sf::Key::F6;
|
|
||||||
case NSF7FunctionKey: return sf::Key::F7;
|
|
||||||
case NSF8FunctionKey: return sf::Key::F8;
|
|
||||||
case NSF9FunctionKey: return sf::Key::F9;
|
|
||||||
case NSF10FunctionKey: return sf::Key::F10;
|
|
||||||
case NSF11FunctionKey: return sf::Key::F11;
|
|
||||||
case NSF12FunctionKey: return sf::Key::F12;
|
|
||||||
case NSF13FunctionKey: return sf::Key::F13;
|
|
||||||
case NSF14FunctionKey: return sf::Key::F14;
|
|
||||||
case NSF15FunctionKey: return sf::Key::F15;
|
|
||||||
|
|
||||||
case NSPauseFunctionKey: return sf::Key::Pause;
|
|
||||||
|
|
||||||
#warning keycode 0x1b is not bound to any key.
|
|
||||||
// This key is ' on CH-FR, ) on FR and - on US layouts.
|
|
||||||
|
|
||||||
// An unknown key.
|
|
||||||
default: return sf::Key::Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////
|
||||||
-(void)processEventWithBlockingMode:(BOOL)block
|
-(void)processEvent
|
||||||
{
|
{
|
||||||
sf::Err() << "Cannot process event from the view." << std::endl;
|
sf::Err() << "Cannot process event from the view." << std::endl;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the view to the window as its content view.
|
// Set the view to the window as its content view.
|
||||||
[[myWindow contentView] addSubview:myOGLView];
|
[myWindow setContentView:myOGLView];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -137,7 +137,7 @@ namespace sf {
|
|||||||
/// Fetch new event
|
/// Fetch new event
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
-(void)processEventWithBlockingMode:(BOOL)block;
|
-(void)processEvent;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Apply a given context to an OpenGL view.
|
/// Apply a given context to an OpenGL view.
|
||||||
|
Loading…
Reference in New Issue
Block a user