mirror of
https://github.com/SFML/SFML.git
synced 2024-11-24 20:31:05 +08:00
Moved joystick initialization to happen *after* the construction of windows, to fix a deadlock happening on Windows at DLL loading
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1003 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
2f524481c1
commit
c3687b4018
@ -43,8 +43,8 @@ myWindow (NULL),
|
|||||||
myLastFrameTime (0.f),
|
myLastFrameTime (0.f),
|
||||||
myIsExternal (false),
|
myIsExternal (false),
|
||||||
myFramerateLimit(0),
|
myFramerateLimit(0),
|
||||||
mySetCursorPosX (-1),
|
mySetCursorPosX (0xFFFF),
|
||||||
mySetCursorPosY (-1)
|
mySetCursorPosY (0xFFFF)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -73,8 +73,8 @@ myWindow (NULL),
|
|||||||
myLastFrameTime (0.f),
|
myLastFrameTime (0.f),
|
||||||
myIsExternal (true),
|
myIsExternal (true),
|
||||||
myFramerateLimit(0),
|
myFramerateLimit(0),
|
||||||
mySetCursorPosX (-1),
|
mySetCursorPosX (0xFFFF),
|
||||||
mySetCursorPosY (-1)
|
mySetCursorPosY (0xFFFF)
|
||||||
{
|
{
|
||||||
Create(Handle, Params);
|
Create(Handle, Params);
|
||||||
}
|
}
|
||||||
@ -413,11 +413,12 @@ void Window::OnEvent(const Event& EventReceived)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void Window::Initialize(priv::WindowImpl* Window)
|
void Window::Initialize(priv::WindowImpl* Window)
|
||||||
{
|
{
|
||||||
// Assign new window and listen to its events
|
// Assign and initialize the new window
|
||||||
myWindow = Window;
|
myWindow = Window;
|
||||||
myWindow->AddListener(this);
|
myWindow->Initialize();
|
||||||
|
|
||||||
// Attach input to the window
|
// Listen to events from the new window
|
||||||
|
myWindow->AddListener(this);
|
||||||
myWindow->AddListener(&myInput);
|
myWindow->AddListener(&myInput);
|
||||||
|
|
||||||
// Setup default behaviours (to get a consistent behaviour across different implementations)
|
// Setup default behaviours (to get a consistent behaviour across different implementations)
|
||||||
|
@ -1,252 +1,260 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// SFML - Simple and Fast Multimedia Library
|
// SFML - Simple and Fast Multimedia Library
|
||||||
// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
|
// Copyright (C) 2007-2008 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.
|
||||||
//
|
//
|
||||||
// Permission is granted to anyone to use this software for any purpose,
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
// including commercial applications, and to alter it and redistribute it freely,
|
// including commercial applications, and to alter it and redistribute it freely,
|
||||||
// subject to the following restrictions:
|
// subject to the following restrictions:
|
||||||
//
|
//
|
||||||
// 1. The origin of this software must not be misrepresented;
|
// 1. The origin of this software must not be misrepresented;
|
||||||
// you must not claim that you wrote the original software.
|
// you must not claim that you wrote the original software.
|
||||||
// If you use this software in a product, an acknowledgment
|
// If you use this software in a product, an acknowledgment
|
||||||
// in the product documentation would be appreciated but is not required.
|
// in the product documentation would be appreciated but is not required.
|
||||||
//
|
//
|
||||||
// 2. Altered source versions must be plainly marked as such,
|
// 2. Altered source versions must be plainly marked as such,
|
||||||
// and must not be misrepresented as being the original software.
|
// and must not be misrepresented as being the original software.
|
||||||
//
|
//
|
||||||
// 3. This notice may not be removed or altered from any source distribution.
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Headers
|
// Headers
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Window/WindowImpl.hpp>
|
#include <SFML/Window/WindowImpl.hpp>
|
||||||
#include <SFML/Window/Event.hpp>
|
#include <SFML/Window/Event.hpp>
|
||||||
#include <SFML/Window/WindowListener.hpp>
|
#include <SFML/Window/WindowListener.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#if defined(SFML_SYSTEM_WINDOWS)
|
#if defined(SFML_SYSTEM_WINDOWS)
|
||||||
|
|
||||||
#include <SFML/Window/Win32/WindowImplWin32.hpp>
|
#include <SFML/Window/Win32/WindowImplWin32.hpp>
|
||||||
typedef sf::priv::WindowImplWin32 WindowImplType;
|
typedef sf::priv::WindowImplWin32 WindowImplType;
|
||||||
|
|
||||||
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
|
#elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
|
||||||
|
|
||||||
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
#include <SFML/Window/Linux/WindowImplX11.hpp>
|
||||||
typedef sf::priv::WindowImplX11 WindowImplType;
|
typedef sf::priv::WindowImplX11 WindowImplType;
|
||||||
|
|
||||||
#elif defined(SFML_SYSTEM_MACOS)
|
#elif defined(SFML_SYSTEM_MACOS)
|
||||||
|
|
||||||
#include <SFML/Window/Cocoa/WindowImplCocoa.hpp>
|
#include <SFML/Window/Cocoa/WindowImplCocoa.hpp>
|
||||||
typedef sf::priv::WindowImplCocoa WindowImplType;
|
typedef sf::priv::WindowImplCocoa WindowImplType;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
namespace priv
|
namespace priv
|
||||||
{
|
{
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Create a new window depending on the current OS
|
/// Create a new window depending on the current OS
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImpl* WindowImpl::New()
|
WindowImpl* WindowImpl::New()
|
||||||
{
|
{
|
||||||
return new WindowImplType();
|
return new WindowImplType();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Create a new window depending on the current OS
|
/// Create a new window depending on the current OS
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImpl* WindowImpl::New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params)
|
WindowImpl* WindowImpl::New(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params)
|
||||||
{
|
{
|
||||||
return new WindowImplType(Mode, Title, WindowStyle, Params);
|
return new WindowImplType(Mode, Title, WindowStyle, Params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Create a new window depending on the current OS
|
/// Create a new window depending on the current OS
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImpl* WindowImpl::New(WindowHandle Handle, WindowSettings& Params)
|
WindowImpl* WindowImpl::New(WindowHandle Handle, WindowSettings& Params)
|
||||||
{
|
{
|
||||||
return new WindowImplType(Handle, Params);
|
return new WindowImplType(Handle, Params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Default constructor
|
/// Default constructor
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
WindowImpl::WindowImpl() :
|
WindowImpl::WindowImpl() :
|
||||||
myWidth (0),
|
myWidth (0),
|
||||||
myHeight (0),
|
myHeight (0),
|
||||||
myJoyThreshold(0.1f)
|
myJoyThreshold(0.1f)
|
||||||
{
|
{
|
||||||
// Initialize the joysticks
|
}
|
||||||
for (unsigned int i = 0; i < JoysticksCount; ++i)
|
|
||||||
{
|
|
||||||
myJoysticks[i].Initialize(i);
|
////////////////////////////////////////////////////////////
|
||||||
myJoyStates[i] = myJoysticks[i].UpdateState();
|
/// Destructor
|
||||||
}
|
////////////////////////////////////////////////////////////
|
||||||
}
|
WindowImpl::~WindowImpl()
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
////////////////////////////////////////////////////////////
|
}
|
||||||
/// Destructor
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
WindowImpl::~WindowImpl()
|
////////////////////////////////////////////////////////////
|
||||||
{
|
/// Add a listener to the window
|
||||||
// Nothing to do
|
////////////////////////////////////////////////////////////
|
||||||
}
|
void WindowImpl::AddListener(WindowListener* Listener)
|
||||||
|
{
|
||||||
|
if (Listener)
|
||||||
////////////////////////////////////////////////////////////
|
myListeners.insert(Listener);
|
||||||
/// Add a listener to the window
|
}
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void WindowImpl::AddListener(WindowListener* Listener)
|
|
||||||
{
|
////////////////////////////////////////////////////////////
|
||||||
if (Listener)
|
/// Remove a listener from the window
|
||||||
myListeners.insert(Listener);
|
////////////////////////////////////////////////////////////
|
||||||
}
|
void WindowImpl::RemoveListener(WindowListener* Listener)
|
||||||
|
{
|
||||||
|
myListeners.erase(Listener);
|
||||||
////////////////////////////////////////////////////////////
|
}
|
||||||
/// Remove a listener from the window
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
void WindowImpl::RemoveListener(WindowListener* Listener)
|
////////////////////////////////////////////////////////////
|
||||||
{
|
/// Initialize window's states that can't be done at construction
|
||||||
myListeners.erase(Listener);
|
////////////////////////////////////////////////////////////
|
||||||
}
|
void WindowImpl::Initialize()
|
||||||
|
{
|
||||||
|
// Initialize the joysticks
|
||||||
////////////////////////////////////////////////////////////
|
for (unsigned int i = 0; i < JoysticksCount; ++i)
|
||||||
/// Get the client width of the window
|
{
|
||||||
////////////////////////////////////////////////////////////
|
myJoysticks[i].Initialize(i);
|
||||||
unsigned int WindowImpl::GetWidth() const
|
myJoyStates[i] = myJoysticks[i].UpdateState();
|
||||||
{
|
}
|
||||||
return myWidth;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
/// Get the client width of the window
|
||||||
/// Get the client height of the window
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
unsigned int WindowImpl::GetWidth() const
|
||||||
unsigned int WindowImpl::GetHeight() const
|
{
|
||||||
{
|
return myWidth;
|
||||||
return myHeight;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
/// Get the client height of the window
|
||||||
/// Change the joystick threshold, ie. the value below which
|
////////////////////////////////////////////////////////////
|
||||||
/// no move event will be generated
|
unsigned int WindowImpl::GetHeight() const
|
||||||
////////////////////////////////////////////////////////////
|
{
|
||||||
void WindowImpl::SetJoystickThreshold(float Threshold)
|
return myHeight;
|
||||||
{
|
}
|
||||||
myJoyThreshold = Threshold;
|
|
||||||
}
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Change the joystick threshold, ie. the value below which
|
||||||
////////////////////////////////////////////////////////////
|
/// no move event will be generated
|
||||||
/// Process incoming events from operating system
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
void WindowImpl::SetJoystickThreshold(float Threshold)
|
||||||
void WindowImpl::DoEvents()
|
{
|
||||||
{
|
myJoyThreshold = Threshold;
|
||||||
// Read the joysticks state and generate the appropriate events
|
}
|
||||||
ProcessJoystickEvents();
|
|
||||||
|
|
||||||
// Let the derived class process other events
|
////////////////////////////////////////////////////////////
|
||||||
ProcessEvents();
|
/// Process incoming events from operating system
|
||||||
}
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImpl::DoEvents()
|
||||||
|
{
|
||||||
////////////////////////////////////////////////////////////
|
// Read the joysticks state and generate the appropriate events
|
||||||
/// Check if there's an active context on the current thread
|
ProcessJoystickEvents();
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
bool WindowImpl::IsContextActive()
|
// Let the derived class process other events
|
||||||
{
|
ProcessEvents();
|
||||||
return WindowImplType::IsContextActive();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
/// Check if there's an active context on the current thread
|
||||||
/// Send an event to listeners
|
////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////
|
bool WindowImpl::IsContextActive()
|
||||||
void WindowImpl::SendEvent(const Event& EventToSend)
|
{
|
||||||
{
|
return WindowImplType::IsContextActive();
|
||||||
for (std::set<WindowListener*>::iterator i = myListeners.begin(); i != myListeners.end(); ++i)
|
}
|
||||||
{
|
|
||||||
(*i)->OnEvent(EventToSend);
|
|
||||||
}
|
////////////////////////////////////////////////////////////
|
||||||
}
|
/// Send an event to listeners
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void WindowImpl::SendEvent(const Event& EventToSend)
|
||||||
////////////////////////////////////////////////////////////
|
{
|
||||||
/// Evaluate a pixel format configuration.
|
for (std::set<WindowListener*>::iterator i = myListeners.begin(); i != myListeners.end(); ++i)
|
||||||
/// This functions can be used by implementations that have
|
{
|
||||||
/// several valid formats and want to get the best one
|
(*i)->OnEvent(EventToSend);
|
||||||
////////////////////////////////////////////////////////////
|
}
|
||||||
int WindowImpl::EvaluateConfig(const VideoMode& Mode, const WindowSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing)
|
}
|
||||||
{
|
|
||||||
return abs(static_cast<int>(Mode.BitsPerPixel - ColorBits)) +
|
|
||||||
abs(static_cast<int>(Settings.DepthBits - DepthBits)) +
|
////////////////////////////////////////////////////////////
|
||||||
abs(static_cast<int>(Settings.StencilBits - StencilBits)) +
|
/// Evaluate a pixel format configuration.
|
||||||
abs(static_cast<int>(Settings.AntialiasingLevel - Antialiasing));
|
/// This functions can be used by implementations that have
|
||||||
}
|
/// several valid formats and want to get the best one
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
int WindowImpl::EvaluateConfig(const VideoMode& Mode, const WindowSettings& Settings, int ColorBits, int DepthBits, int StencilBits, int Antialiasing)
|
||||||
////////////////////////////////////////////////////////////
|
{
|
||||||
/// Read the joysticks state and generate the appropriate events
|
return abs(static_cast<int>(Mode.BitsPerPixel - ColorBits)) +
|
||||||
////////////////////////////////////////////////////////////
|
abs(static_cast<int>(Settings.DepthBits - DepthBits)) +
|
||||||
void WindowImpl::ProcessJoystickEvents()
|
abs(static_cast<int>(Settings.StencilBits - StencilBits)) +
|
||||||
{
|
abs(static_cast<int>(Settings.AntialiasingLevel - Antialiasing));
|
||||||
for (unsigned int i = 0; i < JoysticksCount; ++i)
|
}
|
||||||
{
|
|
||||||
// Copy the previous state of the joystick and get the new one
|
|
||||||
JoystickState PreviousState = myJoyStates[i];
|
////////////////////////////////////////////////////////////
|
||||||
myJoyStates[i] = myJoysticks[i].UpdateState();
|
/// Read the joysticks state and generate the appropriate events
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
// Axis
|
void WindowImpl::ProcessJoystickEvents()
|
||||||
for (unsigned int j = 0; j < myJoysticks[i].GetAxesCount(); ++j)
|
{
|
||||||
{
|
for (unsigned int i = 0; i < JoysticksCount; ++i)
|
||||||
float PrevPos = PreviousState.Axis[j];
|
{
|
||||||
float CurrPos = myJoyStates[i].Axis[j];
|
// Copy the previous state of the joystick and get the new one
|
||||||
if (fabs(CurrPos - PrevPos) >= myJoyThreshold)
|
JoystickState PreviousState = myJoyStates[i];
|
||||||
{
|
myJoyStates[i] = myJoysticks[i].UpdateState();
|
||||||
Event Event;
|
|
||||||
Event.Type = Event::JoyMoved;
|
// Axis
|
||||||
Event.JoyMove.JoystickId = i;
|
for (unsigned int j = 0; j < myJoysticks[i].GetAxesCount(); ++j)
|
||||||
Event.JoyMove.Axis = static_cast<Joy::Axis>(j);
|
{
|
||||||
Event.JoyMove.Position = CurrPos;
|
float PrevPos = PreviousState.Axis[j];
|
||||||
SendEvent(Event);
|
float CurrPos = myJoyStates[i].Axis[j];
|
||||||
}
|
if (fabs(CurrPos - PrevPos) >= myJoyThreshold)
|
||||||
}
|
{
|
||||||
|
Event Event;
|
||||||
// Buttons
|
Event.Type = Event::JoyMoved;
|
||||||
for (unsigned int j = 0; j < myJoysticks[i].GetButtonsCount(); ++j)
|
Event.JoyMove.JoystickId = i;
|
||||||
{
|
Event.JoyMove.Axis = static_cast<Joy::Axis>(j);
|
||||||
bool PrevPressed = PreviousState.Buttons[j];
|
Event.JoyMove.Position = CurrPos;
|
||||||
bool CurrPressed = myJoyStates[i].Buttons[j];
|
SendEvent(Event);
|
||||||
|
}
|
||||||
if ((!PrevPressed && CurrPressed) || (PrevPressed && !CurrPressed))
|
}
|
||||||
{
|
|
||||||
Event Event;
|
// Buttons
|
||||||
Event.Type = CurrPressed ? Event::JoyButtonPressed : Event::JoyButtonReleased;
|
for (unsigned int j = 0; j < myJoysticks[i].GetButtonsCount(); ++j)
|
||||||
Event.JoyButton.JoystickId = i;
|
{
|
||||||
Event.JoyButton.Button = j;
|
bool PrevPressed = PreviousState.Buttons[j];
|
||||||
SendEvent(Event);
|
bool CurrPressed = myJoyStates[i].Buttons[j];
|
||||||
}
|
|
||||||
}
|
if ((!PrevPressed && CurrPressed) || (PrevPressed && !CurrPressed))
|
||||||
}
|
{
|
||||||
}
|
Event Event;
|
||||||
|
Event.Type = CurrPressed ? Event::JoyButtonPressed : Event::JoyButtonReleased;
|
||||||
|
Event.JoyButton.JoystickId = i;
|
||||||
} // namespace priv
|
Event.JoyButton.Button = j;
|
||||||
|
SendEvent(Event);
|
||||||
} // namespace sf
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace priv
|
||||||
|
|
||||||
|
} // namespace sf
|
||||||
|
@ -108,6 +108,12 @@ public :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void RemoveListener(WindowListener* Listener);
|
void RemoveListener(WindowListener* Listener);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Initialize window's states that can't be done at construction
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void Initialize();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Get the client width of the window
|
/// Get the client width of the window
|
||||||
///
|
///
|
||||||
|
Loading…
Reference in New Issue
Block a user