summaryrefslogtreecommitdiff
path: root/src/SFML/Window/Win32
diff options
context:
space:
mode:
Diffstat (limited to 'src/SFML/Window/Win32')
-rw-r--r--src/SFML/Window/Win32/InputImpl.cpp35
-rw-r--r--src/SFML/Window/Win32/InputImpl.hpp49
-rw-r--r--src/SFML/Window/Win32/JoystickImpl.cpp491
-rw-r--r--src/SFML/Window/Win32/JoystickImpl.hpp260
-rw-r--r--src/SFML/Window/Win32/SensorImpl.cpp88
-rw-r--r--src/SFML/Window/Win32/SensorImpl.hpp101
-rw-r--r--src/SFML/Window/Win32/VideoModeImpl.cpp142
-rw-r--r--src/SFML/Window/Win32/WglContext.cpp650
-rw-r--r--src/SFML/Window/Win32/WglContext.hpp272
-rw-r--r--src/SFML/Window/Win32/WindowImplWin32.cpp1964
-rw-r--r--src/SFML/Window/Win32/WindowImplWin32.hpp509
11 files changed, 2524 insertions, 2037 deletions
diff --git a/src/SFML/Window/Win32/InputImpl.cpp b/src/SFML/Window/Win32/InputImpl.cpp
index 0ad303b..bace512 100644
--- a/src/SFML/Window/Win32/InputImpl.cpp
+++ b/src/SFML/Window/Win32/InputImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 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.
@@ -148,7 +148,7 @@ bool InputImpl::isKeyPressed(Keyboard::Key key)
case Keyboard::F12: vkey = VK_F12; break;
case Keyboard::F13: vkey = VK_F13; break;
case Keyboard::F14: vkey = VK_F14; break;
- case Keyboard::F15: vkey = VK_F16; break;
+ case Keyboard::F15: vkey = VK_F15; break;
case Keyboard::Pause: vkey = VK_PAUSE; break;
}
@@ -157,6 +157,13 @@ bool InputImpl::isKeyPressed(Keyboard::Key key)
////////////////////////////////////////////////////////////
+void InputImpl::setVirtualKeyboardVisible(bool visible)
+{
+ // Not applicable
+}
+
+
+////////////////////////////////////////////////////////////
bool InputImpl::isMouseButtonPressed(Mouse::Button button)
{
int vkey = 0;
@@ -220,6 +227,30 @@ void InputImpl::setMousePosition(const Vector2i& position, const Window& relativ
}
}
+
+////////////////////////////////////////////////////////////
+bool InputImpl::isTouchDown(unsigned int /*finger*/)
+{
+ // Not applicable
+ return false;
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/)
+{
+ // Not applicable
+ return Vector2i();
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2i InputImpl::getTouchPosition(unsigned int /*finger*/, const Window& /*relativeTo*/)
+{
+ // Not applicable
+ return Vector2i();
+}
+
} // namespace priv
} // namespace sf
diff --git a/src/SFML/Window/Win32/InputImpl.hpp b/src/SFML/Window/Win32/InputImpl.hpp
index 0669b4a..f62f2d2 100644
--- a/src/SFML/Window/Win32/InputImpl.hpp
+++ b/src/SFML/Window/Win32/InputImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 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.
@@ -42,7 +42,7 @@ namespace priv
////////////////////////////////////////////////////////////
class InputImpl
{
-public :
+public:
////////////////////////////////////////////////////////////
/// \brief Check if a key is pressed
@@ -55,6 +55,14 @@ public :
static bool isKeyPressed(Keyboard::Key key);
////////////////////////////////////////////////////////////
+ /// \brief Show or hide the virtual keyboard
+ ///
+ /// \param visible True to show, false to hide
+ ///
+ ////////////////////////////////////////////////////////////
+ static void setVirtualKeyboardVisible(bool visible);
+
+ ////////////////////////////////////////////////////////////
/// \brief Check if a mouse button is pressed
///
/// \param button Button to check
@@ -113,6 +121,43 @@ public :
///
////////////////////////////////////////////////////////////
static void setMousePosition(const Vector2i& position, const Window& relativeTo);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Check if a touch event is currently down
+ ///
+ /// \param finger Finger index
+ ///
+ /// \return True if \a finger is currently touching the screen, false otherwise
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool isTouchDown(unsigned int finger);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the current position of a touch in desktop coordinates
+ ///
+ /// This function returns the current touch position
+ /// in global (desktop) coordinates.
+ ///
+ /// \param finger Finger index
+ ///
+ /// \return Current position of \a finger, or undefined if it's not down
+ ///
+ ////////////////////////////////////////////////////////////
+ static Vector2i getTouchPosition(unsigned int finger);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the current position of a touch in window coordinates
+ ///
+ /// This function returns the current touch position
+ /// in global (desktop) coordinates.
+ ///
+ /// \param finger Finger index
+ /// \param relativeTo Reference window
+ ///
+ /// \return Current position of \a finger, or undefined if it's not down
+ ///
+ ////////////////////////////////////////////////////////////
+ static Vector2i getTouchPosition(unsigned int finger, const Window& relativeTo);
};
} // namespace priv
diff --git a/src/SFML/Window/Win32/JoystickImpl.cpp b/src/SFML/Window/Win32/JoystickImpl.cpp
index c2645e8..380e25f 100644
--- a/src/SFML/Window/Win32/JoystickImpl.cpp
+++ b/src/SFML/Window/Win32/JoystickImpl.cpp
@@ -1,189 +1,302 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/JoystickImpl.hpp>
-#include <SFML/System/Clock.hpp>
-#include <windows.h>
-#include <cmath>
-
-
-namespace
-{
- struct ConnectionCache
- {
- ConnectionCache() : connected(false) {}
- bool connected;
- sf::Clock timer;
- };
-
- const sf::Time connectionRefreshDelay = sf::milliseconds(500);
- ConnectionCache connectionCache[sf::Joystick::Count];
-}
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-void JoystickImpl::initialize()
-{
- // Perform the initial scan and populate the connection cache
- for (unsigned int i = 0; i < Joystick::Count; ++i)
- {
- ConnectionCache& cache = connectionCache[i];
-
- // Check if the joystick is connected
- JOYINFOEX joyInfo;
- joyInfo.dwSize = sizeof(joyInfo);
- joyInfo.dwFlags = 0;
- cache.connected = joyGetPosEx(JOYSTICKID1 + i, &joyInfo) == JOYERR_NOERROR;
-
- // start the timeout
- cache.timer.restart();
- }
-}
-
-
-////////////////////////////////////////////////////////////
-void JoystickImpl::cleanup()
-{
- // Nothing to do
-}
-
-
-////////////////////////////////////////////////////////////
-bool JoystickImpl::isConnected(unsigned int index)
-{
- // We check the connection state of joysticks only every N milliseconds,
- // because of a strange (buggy?) behaviour of joyGetPosEx when joysticks
- // are just plugged/unplugged -- it takes really long and kills the app performances
- ConnectionCache& cache = connectionCache[index];
- if (cache.timer.getElapsedTime() > connectionRefreshDelay)
- {
- cache.timer.restart();
-
- JOYINFOEX joyInfo;
- joyInfo.dwSize = sizeof(joyInfo);
- joyInfo.dwFlags = 0;
-
- cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
- return cache.connected;
- }
- else
- {
- return cache.connected;
- }
-}
-
-
-////////////////////////////////////////////////////////////
-bool JoystickImpl::open(unsigned int index)
-{
- // No explicit "open" action is required
- m_index = JOYSTICKID1 + index;
-
- // Store the joystick capabilities
- return joyGetDevCaps(m_index, &m_caps, sizeof(m_caps)) == JOYERR_NOERROR;
-}
-
-
-////////////////////////////////////////////////////////////
-void JoystickImpl::close()
-{
- // Nothing to do
-}
-
-
-////////////////////////////////////////////////////////////
-JoystickCaps JoystickImpl::getCapabilities() const
-{
- JoystickCaps caps;
-
- caps.buttonCount = m_caps.wNumButtons;
- if (caps.buttonCount > Joystick::ButtonCount)
- caps.buttonCount = Joystick::ButtonCount;
-
- caps.axes[Joystick::X] = true;
- caps.axes[Joystick::Y] = true;
- caps.axes[Joystick::Z] = (m_caps.wCaps & JOYCAPS_HASZ) != 0;
- caps.axes[Joystick::R] = (m_caps.wCaps & JOYCAPS_HASR) != 0;
- caps.axes[Joystick::U] = (m_caps.wCaps & JOYCAPS_HASU) != 0;
- caps.axes[Joystick::V] = (m_caps.wCaps & JOYCAPS_HASV) != 0;
- caps.axes[Joystick::PovX] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
- caps.axes[Joystick::PovY] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
-
- return caps;
-}
-
-
-////////////////////////////////////////////////////////////
-JoystickState JoystickImpl::update()
-{
- JoystickState state;
-
- // Get the current joystick state
- JOYINFOEX pos;
- pos.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | JOY_RETURNBUTTONS;
- pos.dwFlags |= (m_caps.wCaps & JOYCAPS_POVCTS) ? JOY_RETURNPOVCTS : JOY_RETURNPOV;
- pos.dwSize = sizeof(JOYINFOEX);
- if (joyGetPosEx(m_index, &pos) == JOYERR_NOERROR)
- {
- // The joystick is connected
- state.connected = true;
-
- // Axes
- state.axes[Joystick::X] = (pos.dwXpos - (m_caps.wXmax + m_caps.wXmin) / 2.f) * 200.f / (m_caps.wXmax - m_caps.wXmin);
- state.axes[Joystick::Y] = (pos.dwYpos - (m_caps.wYmax + m_caps.wYmin) / 2.f) * 200.f / (m_caps.wYmax - m_caps.wYmin);
- state.axes[Joystick::Z] = (pos.dwZpos - (m_caps.wZmax + m_caps.wZmin) / 2.f) * 200.f / (m_caps.wZmax - m_caps.wZmin);
- state.axes[Joystick::R] = (pos.dwRpos - (m_caps.wRmax + m_caps.wRmin) / 2.f) * 200.f / (m_caps.wRmax - m_caps.wRmin);
- state.axes[Joystick::U] = (pos.dwUpos - (m_caps.wUmax + m_caps.wUmin) / 2.f) * 200.f / (m_caps.wUmax - m_caps.wUmin);
- state.axes[Joystick::V] = (pos.dwVpos - (m_caps.wVmax + m_caps.wVmin) / 2.f) * 200.f / (m_caps.wVmax - m_caps.wVmin);
-
- // Special case for POV, it is given as an angle
- if (pos.dwPOV != 0xFFFF)
- {
- float angle = pos.dwPOV / 18000.f * 3.141592654f;
- state.axes[Joystick::PovX] = std::cos(angle) * 100;
- state.axes[Joystick::PovY] = std::sin(angle) * 100;
- }
- else
- {
- state.axes[Joystick::PovX] = 0;
- state.axes[Joystick::PovY] = 0;
- }
-
- // Buttons
- for (unsigned int i = 0; i < Joystick::ButtonCount; ++i)
- state.buttons[i] = (pos.dwButtons & (1 << i)) != 0;
- }
-
- return state;
-}
-
-} // namespace priv
-
-} // namespace sf
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 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/JoystickImpl.hpp>
+#include <SFML/System/Clock.hpp>
+#include <SFML/System/Err.hpp>
+#include <windows.h>
+#include <tchar.h>
+#include <regstr.h>
+#include <algorithm>
+#include <cmath>
+#include <sstream>
+#include <string>
+
+namespace
+{
+ struct ConnectionCache
+ {
+ ConnectionCache() : connected(false) {}
+ bool connected;
+ sf::Clock timer;
+ };
+
+ const sf::Time connectionRefreshDelay = sf::milliseconds(500);
+ ConnectionCache connectionCache[sf::Joystick::Count];
+
+ // Get a system error string from an error code
+ std::string getErrorString(DWORD error)
+ {
+ PTCHAR buffer;
+
+ if (FormatMessage(FORMAT_MESSAGE_MAX_WIDTH_MASK | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, reinterpret_cast<PTCHAR>(&buffer), 0, NULL) == 0)
+ return "Unknown error.";
+
+ sf::String message = buffer;
+ LocalFree(buffer);
+ return message.toAnsiString();
+ }
+
+ // Get the joystick's name
+ sf::String getDeviceName(unsigned int index, JOYCAPS caps)
+ {
+ // Give the joystick a default name
+ sf::String joystickDescription = "Unknown Joystick";
+
+ LONG result;
+ HKEY rootKey;
+ HKEY currentKey;
+ std::basic_string<TCHAR> subkey;
+
+ subkey = REGSTR_PATH_JOYCONFIG;
+ subkey += TEXT('\\');
+ subkey += caps.szRegKey;
+ subkey += TEXT('\\');
+ subkey += REGSTR_KEY_JOYCURR;
+
+ rootKey = HKEY_CURRENT_USER;
+ result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey);
+
+ if (result != ERROR_SUCCESS)
+ {
+ rootKey = HKEY_LOCAL_MACHINE;
+ result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey);
+
+ if (result != ERROR_SUCCESS)
+ {
+ sf::err() << "Unable to open registry for joystick at index " << index << ": " << getErrorString(result) << std::endl;
+ return joystickDescription;
+ }
+ }
+
+ std::basic_ostringstream<TCHAR> indexString;
+ indexString << index + 1;
+
+ subkey = TEXT("Joystick");
+ subkey += indexString.str();
+ subkey += REGSTR_VAL_JOYOEMNAME;
+
+ TCHAR keyData[256];
+ DWORD keyDataSize = sizeof(keyData);
+
+ result = RegQueryValueEx(currentKey, subkey.c_str(), NULL, NULL, reinterpret_cast<LPBYTE>(keyData), &keyDataSize);
+ RegCloseKey(currentKey);
+
+ if (result != ERROR_SUCCESS)
+ {
+ sf::err() << "Unable to query registry key for joystick at index " << index << ": " << getErrorString(result) << std::endl;
+ return joystickDescription;
+ }
+
+ subkey = REGSTR_PATH_JOYOEM;
+ subkey += TEXT('\\');
+ subkey.append(keyData, keyDataSize / sizeof(TCHAR));
+
+ result = RegOpenKeyEx(rootKey, subkey.c_str(), 0, KEY_READ, &currentKey);
+
+ if (result != ERROR_SUCCESS)
+ {
+ sf::err() << "Unable to open registry key for joystick at index " << index << ": " << getErrorString(result) << std::endl;
+ return joystickDescription;
+ }
+
+ keyDataSize = sizeof(keyData);
+
+ result = RegQueryValueEx(currentKey, REGSTR_VAL_JOYOEMNAME, NULL, NULL, reinterpret_cast<LPBYTE>(keyData), &keyDataSize);
+ RegCloseKey(currentKey);
+
+ if (result != ERROR_SUCCESS)
+ {
+ sf::err() << "Unable to query name for joystick at index " << index << ": " << getErrorString(result) << std::endl;
+ return joystickDescription;
+ }
+
+ keyData[255] = TEXT('\0'); // Ensure null terminator in case the data is too long.
+ joystickDescription = keyData;
+
+ return joystickDescription;
+ }
+}
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+void JoystickImpl::initialize()
+{
+ // Perform the initial scan and populate the connection cache
+ for (unsigned int i = 0; i < Joystick::Count; ++i)
+ {
+ ConnectionCache& cache = connectionCache[i];
+
+ // Check if the joystick is connected
+ JOYINFOEX joyInfo;
+ joyInfo.dwSize = sizeof(joyInfo);
+ joyInfo.dwFlags = 0;
+ cache.connected = joyGetPosEx(JOYSTICKID1 + i, &joyInfo) == JOYERR_NOERROR;
+
+ // start the timeout
+ cache.timer.restart();
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+void JoystickImpl::cleanup()
+{
+ // Nothing to do
+}
+
+
+////////////////////////////////////////////////////////////
+bool JoystickImpl::isConnected(unsigned int index)
+{
+ // We check the connection state of joysticks only every N milliseconds,
+ // because of a strange (buggy?) behavior of joyGetPosEx when joysticks
+ // are just plugged/unplugged -- it takes really long and kills the app performances
+ ConnectionCache& cache = connectionCache[index];
+ if (cache.timer.getElapsedTime() > connectionRefreshDelay)
+ {
+ cache.timer.restart();
+
+ JOYINFOEX joyInfo;
+ joyInfo.dwSize = sizeof(joyInfo);
+ joyInfo.dwFlags = 0;
+
+ cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
+ return cache.connected;
+ }
+ else
+ {
+ return cache.connected;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+bool JoystickImpl::open(unsigned int index)
+{
+ // No explicit "open" action is required
+ m_index = JOYSTICKID1 + index;
+
+ // Store the joystick capabilities
+ bool success = joyGetDevCaps(m_index, &m_caps, sizeof(m_caps)) == JOYERR_NOERROR;
+
+ if (success)
+ {
+ m_identification.name = getDeviceName(m_index, m_caps);
+ m_identification.productId = m_caps.wPid;
+ m_identification.vendorId = m_caps.wMid;
+ }
+
+ return success;
+}
+
+
+////////////////////////////////////////////////////////////
+void JoystickImpl::close()
+{
+ // Nothing to do
+}
+
+////////////////////////////////////////////////////////////
+JoystickCaps JoystickImpl::getCapabilities() const
+{
+ JoystickCaps caps;
+
+ caps.buttonCount = m_caps.wNumButtons;
+ if (caps.buttonCount > Joystick::ButtonCount)
+ caps.buttonCount = Joystick::ButtonCount;
+
+ caps.axes[Joystick::X] = true;
+ caps.axes[Joystick::Y] = true;
+ caps.axes[Joystick::Z] = (m_caps.wCaps & JOYCAPS_HASZ) != 0;
+ caps.axes[Joystick::R] = (m_caps.wCaps & JOYCAPS_HASR) != 0;
+ caps.axes[Joystick::U] = (m_caps.wCaps & JOYCAPS_HASU) != 0;
+ caps.axes[Joystick::V] = (m_caps.wCaps & JOYCAPS_HASV) != 0;
+ caps.axes[Joystick::PovX] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
+ caps.axes[Joystick::PovY] = (m_caps.wCaps & JOYCAPS_HASPOV) != 0;
+
+ return caps;
+}
+
+
+////////////////////////////////////////////////////////////
+Joystick::Identification JoystickImpl::getIdentification() const
+{
+ return m_identification;
+}
+
+
+////////////////////////////////////////////////////////////
+JoystickState JoystickImpl::update()
+{
+ JoystickState state;
+
+ // Get the current joystick state
+ JOYINFOEX pos;
+ pos.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | JOY_RETURNBUTTONS;
+ pos.dwFlags |= (m_caps.wCaps & JOYCAPS_POVCTS) ? JOY_RETURNPOVCTS : JOY_RETURNPOV;
+ pos.dwSize = sizeof(JOYINFOEX);
+ if (joyGetPosEx(m_index, &pos) == JOYERR_NOERROR)
+ {
+ // The joystick is connected
+ state.connected = true;
+
+ // Axes
+ state.axes[Joystick::X] = (pos.dwXpos - (m_caps.wXmax + m_caps.wXmin) / 2.f) * 200.f / (m_caps.wXmax - m_caps.wXmin);
+ state.axes[Joystick::Y] = (pos.dwYpos - (m_caps.wYmax + m_caps.wYmin) / 2.f) * 200.f / (m_caps.wYmax - m_caps.wYmin);
+ state.axes[Joystick::Z] = (pos.dwZpos - (m_caps.wZmax + m_caps.wZmin) / 2.f) * 200.f / (m_caps.wZmax - m_caps.wZmin);
+ state.axes[Joystick::R] = (pos.dwRpos - (m_caps.wRmax + m_caps.wRmin) / 2.f) * 200.f / (m_caps.wRmax - m_caps.wRmin);
+ state.axes[Joystick::U] = (pos.dwUpos - (m_caps.wUmax + m_caps.wUmin) / 2.f) * 200.f / (m_caps.wUmax - m_caps.wUmin);
+ state.axes[Joystick::V] = (pos.dwVpos - (m_caps.wVmax + m_caps.wVmin) / 2.f) * 200.f / (m_caps.wVmax - m_caps.wVmin);
+
+ // Special case for POV, it is given as an angle
+ if (pos.dwPOV != 0xFFFF)
+ {
+ float angle = pos.dwPOV / 18000.f * 3.141592654f;
+ state.axes[Joystick::PovX] = std::sin(angle) * 100;
+ state.axes[Joystick::PovY] = std::cos(angle) * 100;
+ }
+ else
+ {
+ state.axes[Joystick::PovX] = 0;
+ state.axes[Joystick::PovY] = 0;
+ }
+
+ // Buttons
+ for (unsigned int i = 0; i < Joystick::ButtonCount; ++i)
+ state.buttons[i] = (pos.dwButtons & (1 << i)) != 0;
+ }
+
+ return state;
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Win32/JoystickImpl.hpp b/src/SFML/Window/Win32/JoystickImpl.hpp
index 1630f99..a5d258d 100644
--- a/src/SFML/Window/Win32/JoystickImpl.hpp
+++ b/src/SFML/Window/Win32/JoystickImpl.hpp
@@ -1,125 +1,135 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_JOYSTICKIMPLWIN32_HPP
-#define SFML_JOYSTICKIMPLWIN32_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#ifdef _WIN32_WINDOWS
- #undef _WIN32_WINDOWS
-#endif
-#ifdef _WIN32_WINNT
- #undef _WIN32_WINNT
-#endif
-#define _WIN32_WINDOWS 0x0501
-#define _WIN32_WINNT 0x0501
-#include <SFML/Window/JoystickImpl.hpp>
-#include <windows.h>
-#include <mmsystem.h>
-#include <cmath>
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-/// \brief Windows implementation of joysticks
-///
-////////////////////////////////////////////////////////////
-class JoystickImpl
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Perform the global initialization of the joystick module
- ///
- ////////////////////////////////////////////////////////////
- static void initialize();
-
- ////////////////////////////////////////////////////////////
- /// \brief Perform the global cleanup of the joystick module
- ///
- ////////////////////////////////////////////////////////////
- static void cleanup();
-
- ////////////////////////////////////////////////////////////
- /// \brief Check if a joystick is currently connected
- ///
- /// \param index Index of the joystick to check
- ///
- /// \return True if the joystick is connected, false otherwise
- ///
- ////////////////////////////////////////////////////////////
- static bool isConnected(unsigned int index);
-
- ////////////////////////////////////////////////////////////
- /// \brief Open the joystick
- ///
- /// \param index Index assigned to the joystick
- ///
- /// \return True on success, false on failure
- ///
- ////////////////////////////////////////////////////////////
- bool open(unsigned int index);
-
- ////////////////////////////////////////////////////////////
- /// \brief Close the joystick
- ///
- ////////////////////////////////////////////////////////////
- void close();
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the joystick capabilities
- ///
- /// \return Joystick capabilities
- ///
- ////////////////////////////////////////////////////////////
- JoystickCaps getCapabilities() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Update the joystick and get its new state
- ///
- /// \return Joystick state
- ///
- ////////////////////////////////////////////////////////////
- JoystickState update();
-
-private :
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- unsigned int m_index; ///< Index of the joystick
- JOYCAPS m_caps; ///< Joystick capabilities
-};
-
-} // namespace priv
-
-} // namespace sf
-
-
-#endif // SFML_JOYSTICKIMPLWIN32_HPP
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 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_JOYSTICKIMPLWIN32_HPP
+#define SFML_JOYSTICKIMPLWIN32_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#ifdef _WIN32_WINDOWS
+ #undef _WIN32_WINDOWS
+#endif
+#ifdef _WIN32_WINNT
+ #undef _WIN32_WINNT
+#endif
+#define _WIN32_WINDOWS 0x0501
+#define _WIN32_WINNT 0x0501
+#include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/JoystickImpl.hpp>
+#include <SFML/System/String.hpp>
+#include <windows.h>
+#include <mmsystem.h>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Windows implementation of joysticks
+///
+////////////////////////////////////////////////////////////
+class JoystickImpl
+{
+public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Perform the global initialization of the joystick module
+ ///
+ ////////////////////////////////////////////////////////////
+ static void initialize();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Perform the global cleanup of the joystick module
+ ///
+ ////////////////////////////////////////////////////////////
+ static void cleanup();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Check if a joystick is currently connected
+ ///
+ /// \param index Index of the joystick to check
+ ///
+ /// \return True if the joystick is connected, false otherwise
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool isConnected(unsigned int index);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Open the joystick
+ ///
+ /// \param index Index assigned to the joystick
+ ///
+ /// \return True on success, false on failure
+ ///
+ ////////////////////////////////////////////////////////////
+ bool open(unsigned int index);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Close the joystick
+ ///
+ ////////////////////////////////////////////////////////////
+ void close();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the joystick capabilities
+ ///
+ /// \return Joystick capabilities
+ ///
+ ////////////////////////////////////////////////////////////
+ JoystickCaps getCapabilities() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the joystick identification
+ ///
+ /// \return Joystick identification
+ ///
+ ////////////////////////////////////////////////////////////
+ Joystick::Identification getIdentification() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Update the joystick and get its new state
+ ///
+ /// \return Joystick state
+ ///
+ ////////////////////////////////////////////////////////////
+ JoystickState update();
+
+private:
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ unsigned int m_index; ///< Index of the joystick
+ JOYCAPS m_caps; ///< Joystick capabilities
+ Joystick::Identification m_identification; ///< Joystick identification
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICKIMPLWIN32_HPP
diff --git a/src/SFML/Window/Win32/SensorImpl.cpp b/src/SFML/Window/Win32/SensorImpl.cpp
new file mode 100644
index 0000000..be5e439
--- /dev/null
+++ b/src/SFML/Window/Win32/SensorImpl.cpp
@@ -0,0 +1,88 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2013 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/SensorImpl.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+void SensorImpl::initialize()
+{
+ // To be implemented
+}
+
+
+////////////////////////////////////////////////////////////
+void SensorImpl::cleanup()
+{
+ // To be implemented
+}
+
+
+////////////////////////////////////////////////////////////
+bool SensorImpl::isAvailable(Sensor::Type /*sensor*/)
+{
+ // To be implemented
+ return false;
+}
+
+
+////////////////////////////////////////////////////////////
+bool SensorImpl::open(Sensor::Type /*sensor*/)
+{
+ // To be implemented
+ return false;
+}
+
+
+////////////////////////////////////////////////////////////
+void SensorImpl::close()
+{
+ // To be implemented
+}
+
+
+////////////////////////////////////////////////////////////
+Vector3f SensorImpl::update()
+{
+ // To be implemented
+ return Vector3f(0, 0, 0);
+}
+
+
+////////////////////////////////////////////////////////////
+void SensorImpl::setEnabled(bool /*enabled*/)
+{
+ // To be implemented
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Win32/SensorImpl.hpp b/src/SFML/Window/Win32/SensorImpl.hpp
new file mode 100644
index 0000000..e174fa2
--- /dev/null
+++ b/src/SFML/Window/Win32/SensorImpl.hpp
@@ -0,0 +1,101 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2013 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_SENSORIMPLWIN32_HPP
+#define SFML_SENSORIMPLWIN32_HPP
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Windows implementation of sensors
+///
+////////////////////////////////////////////////////////////
+class SensorImpl
+{
+public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Perform the global initialization of the sensor module
+ ///
+ ////////////////////////////////////////////////////////////
+ static void initialize();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Perform the global cleanup of the sensor module
+ ///
+ ////////////////////////////////////////////////////////////
+ static void cleanup();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Check if a sensor is available
+ ///
+ /// \param sensor Sensor to check
+ ///
+ /// \return True if the sensor is available, false otherwise
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool isAvailable(Sensor::Type sensor);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Open the sensor
+ ///
+ /// \param sensor Type of the sensor
+ ///
+ /// \return True on success, false on failure
+ ///
+ ////////////////////////////////////////////////////////////
+ bool open(Sensor::Type sensor);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Close the sensor
+ ///
+ ////////////////////////////////////////////////////////////
+ void close();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Update the sensor and get its new value
+ ///
+ /// \return Sensor value
+ ///
+ ////////////////////////////////////////////////////////////
+ Vector3f update();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Enable or disable the sensor
+ ///
+ /// \param enabled True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ void setEnabled(bool enabled);
+};
+
+} // namespace priv
+
+} // namespace sf
+
+
+#endif // SFML_SENSORIMPLWIN32_HPP
diff --git a/src/SFML/Window/Win32/VideoModeImpl.cpp b/src/SFML/Window/Win32/VideoModeImpl.cpp
index 11f04ab..b19588a 100644
--- a/src/SFML/Window/Win32/VideoModeImpl.cpp
+++ b/src/SFML/Window/Win32/VideoModeImpl.cpp
@@ -1,71 +1,71 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/VideoModeImpl.hpp>
-#include <windows.h>
-#include <algorithm>
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
-{
- std::vector<VideoMode> modes;
-
- // Enumerate all available video modes for the primary display adapter
- DEVMODE win32Mode;
- win32Mode.dmSize = sizeof(win32Mode);
- for (int count = 0; EnumDisplaySettings(NULL, count, &win32Mode); ++count)
- {
- // Convert to sf::VideoMode
- VideoMode mode(win32Mode.dmPelsWidth, win32Mode.dmPelsHeight, win32Mode.dmBitsPerPel);
-
- // Add it only if it is not already in the array
- if (std::find(modes.begin(), modes.end(), mode) == modes.end())
- modes.push_back(mode);
- }
-
- return modes;
-}
-
-
-////////////////////////////////////////////////////////////
-VideoMode VideoModeImpl::getDesktopMode()
-{
- DEVMODE win32Mode;
- win32Mode.dmSize = sizeof(win32Mode);
- EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &win32Mode);
-
- return VideoMode(win32Mode.dmPelsWidth, win32Mode.dmPelsHeight, win32Mode.dmBitsPerPel);
-}
-
-} // namespace priv
-
-} // namespace sf
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 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/VideoModeImpl.hpp>
+#include <windows.h>
+#include <algorithm>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
+{
+ std::vector<VideoMode> modes;
+
+ // Enumerate all available video modes for the primary display adapter
+ DEVMODE win32Mode;
+ win32Mode.dmSize = sizeof(win32Mode);
+ for (int count = 0; EnumDisplaySettings(NULL, count, &win32Mode); ++count)
+ {
+ // Convert to sf::VideoMode
+ VideoMode mode(win32Mode.dmPelsWidth, win32Mode.dmPelsHeight, win32Mode.dmBitsPerPel);
+
+ // Add it only if it is not already in the array
+ if (std::find(modes.begin(), modes.end(), mode) == modes.end())
+ modes.push_back(mode);
+ }
+
+ return modes;
+}
+
+
+////////////////////////////////////////////////////////////
+VideoMode VideoModeImpl::getDesktopMode()
+{
+ DEVMODE win32Mode;
+ win32Mode.dmSize = sizeof(win32Mode);
+ EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &win32Mode);
+
+ return VideoMode(win32Mode.dmPelsWidth, win32Mode.dmPelsHeight, win32Mode.dmBitsPerPel);
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp
index 7d9cc43..c6e7c33 100644
--- a/src/SFML/Window/Win32/WglContext.cpp
+++ b/src/SFML/Window/Win32/WglContext.cpp
@@ -1,325 +1,325 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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/WindowImpl.hpp> // included first to avoid a warning about macro redefinition
-#include <SFML/Window/Win32/WglContext.hpp>
-#include <SFML/Window/glext/wglext.h>
-#include <SFML/System/Lock.hpp>
-#include <SFML/System/Mutex.hpp>
-#include <SFML/System/Err.hpp>
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-WglContext::WglContext(WglContext* shared) :
-m_window (NULL),
-m_deviceContext(NULL),
-m_context (NULL),
-m_ownsWindow (true)
-{
- // Creating a dummy window is mandatory: we could create a memory DC but then
- // its pixel format wouldn't match the regular contexts' format, and thus
- // wglShareLists would always fail. Too bad...
-
- // Create a dummy window (disabled and hidden)
- m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL);
- ShowWindow(m_window, SW_HIDE);
- m_deviceContext = GetDC(m_window);
-
- // Create the context
- if (m_deviceContext)
- createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
-}
-
-
-////////////////////////////////////////////////////////////
-WglContext::WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
-m_window (NULL),
-m_deviceContext(NULL),
-m_context (NULL),
-m_ownsWindow (false)
-{
- // Get the owner window and its device context
- m_window = owner->getSystemHandle();
- m_deviceContext = GetDC(m_window);
-
- // Create the context
- if (m_deviceContext)
- createContext(shared, bitsPerPixel, settings);
-}
-
-
-////////////////////////////////////////////////////////////
-WglContext::WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) :
-m_window (NULL),
-m_deviceContext(NULL),
-m_context (NULL),
-m_ownsWindow (true)
-{
- // The target of the context is a hidden window.
- // We can't create a memory DC (the resulting context wouldn't be compatible
- // with other contexts), and we don't add the extra complexity of P-Buffers;
- // we can still support them in the future if this solution is not good enough.
-
- // Create the hidden window
- m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, width, height, NULL, NULL, GetModuleHandle(NULL), NULL);
- ShowWindow(m_window, SW_HIDE);
- m_deviceContext = GetDC(m_window);
-
- // Create the context
- if (m_deviceContext)
- createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings);
-}
-
-
-////////////////////////////////////////////////////////////
-WglContext::~WglContext()
-{
- // Destroy the OpenGL context
- if (m_context)
- {
- if (wglGetCurrentContext() == m_context)
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(m_context);
- }
-
- // Destroy the device context
- if (m_deviceContext)
- ReleaseDC(m_window, m_deviceContext);
-
- // Destroy the window if we own it
- if (m_window && m_ownsWindow)
- DestroyWindow(m_window);
-}
-
-
-////////////////////////////////////////////////////////////
-bool WglContext::makeCurrent()
-{
- return m_deviceContext && m_context && wglMakeCurrent(m_deviceContext, m_context);
-}
-
-
-////////////////////////////////////////////////////////////
-void WglContext::display()
-{
- if (m_deviceContext && m_context)
- SwapBuffers(m_deviceContext);
-}
-
-
-////////////////////////////////////////////////////////////
-void WglContext::setVerticalSyncEnabled(bool enabled)
-{
- PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
- if (wglSwapIntervalEXT)
- wglSwapIntervalEXT(enabled ? 1 : 0);
-}
-
-
-////////////////////////////////////////////////////////////
-void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
-{
- // Save the creation settings
- m_settings = settings;
-
- // Let's find a suitable pixel format -- first try with antialiasing
- int bestFormat = 0;
- if (m_settings.antialiasingLevel > 0)
- {
- // Get the wglChoosePixelFormatARB function (it is an extension)
- PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(wglGetProcAddress("wglChoosePixelFormatARB"));
- if (wglChoosePixelFormatARB)
- {
- // Define the basic attributes we want for our window
- int intAttributes[] =
- {
- WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
- WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
- WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
- WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
- WGL_SAMPLE_BUFFERS_ARB, (m_settings.antialiasingLevel ? GL_TRUE : GL_FALSE),
- WGL_SAMPLES_ARB, static_cast<int>(m_settings.antialiasingLevel),
- 0, 0
- };
-
- // Let's check how many formats are supporting our requirements
- int formats[128];
- UINT nbFormats;
- float floatAttributes[] = {0, 0};
- bool isValid = wglChoosePixelFormatARB(m_deviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
- while ((!isValid || (nbFormats == 0)) && m_settings.antialiasingLevel > 0)
- {
- // Decrease the antialiasing level until we find a valid one
- m_settings.antialiasingLevel--;
- intAttributes[11] = m_settings.antialiasingLevel;
- isValid = wglChoosePixelFormatARB(m_deviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
- }
-
- // Get the best format among the returned ones
- if (isValid && (nbFormats > 0))
- {
- int bestScore = 0xFFFF;
- for (UINT i = 0; i < nbFormats; ++i)
- {
- // Get the current format's attributes
- PIXELFORMATDESCRIPTOR attributes;
- attributes.nSize = sizeof(attributes);
- attributes.nVersion = 1;
- DescribePixelFormat(m_deviceContext, formats[i], sizeof(attributes), &attributes);
-
- // Evaluate the current configuration
- int color = attributes.cRedBits + attributes.cGreenBits + attributes.cBlueBits + attributes.cAlphaBits;
- int score = evaluateFormat(bitsPerPixel, m_settings, color, attributes.cDepthBits, attributes.cStencilBits, m_settings.antialiasingLevel);
-
- // Keep it if it's better than the current best
- if (score < bestScore)
- {
- bestScore = score;
- bestFormat = formats[i];
- }
- }
- }
- }
- else
- {
- // wglChoosePixelFormatARB not supported ; disabling antialiasing
- err() << "Antialiasing is not supported ; it will be disabled" << std::endl;
- m_settings.antialiasingLevel = 0;
- }
- }
-
- // Find a pixel format with no antialiasing, if not needed or not supported
- if (bestFormat == 0)
- {
- // Setup a pixel format descriptor from the rendering settings
- PIXELFORMATDESCRIPTOR descriptor;
- ZeroMemory(&descriptor, sizeof(descriptor));
- descriptor.nSize = sizeof(descriptor);
- descriptor.nVersion = 1;
- descriptor.iLayerType = PFD_MAIN_PLANE;
- descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
- descriptor.iPixelType = PFD_TYPE_RGBA;
- descriptor.cColorBits = static_cast<BYTE>(bitsPerPixel);
- descriptor.cDepthBits = static_cast<BYTE>(m_settings.depthBits);
- descriptor.cStencilBits = static_cast<BYTE>(m_settings.stencilBits);
- descriptor.cAlphaBits = bitsPerPixel == 32 ? 8 : 0;
-
- // Get the pixel format that best matches our requirements
- bestFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
- if (bestFormat == 0)
- {
- err() << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
- return;
- }
- }
-
- // Extract the depth and stencil bits from the chosen format
- PIXELFORMATDESCRIPTOR actualFormat;
- actualFormat.nSize = sizeof(actualFormat);
- actualFormat.nVersion = 1;
- DescribePixelFormat(m_deviceContext, bestFormat, sizeof(actualFormat), &actualFormat);
- m_settings.depthBits = actualFormat.cDepthBits;
- m_settings.stencilBits = actualFormat.cStencilBits;
-
- // Set the chosen pixel format
- if (!SetPixelFormat(m_deviceContext, bestFormat, &actualFormat))
- {
- err() << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
- return;
- }
-
- // Get the context to share display lists with
- HGLRC sharedContext = shared ? shared->m_context : NULL;
-
- // Create the OpenGL context -- first try context versions >= 3.0 if it is requested (they require special code)
- while (!m_context && (m_settings.majorVersion >= 3))
- {
- PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(wglGetProcAddress("wglCreateContextAttribsARB"));
- if (wglCreateContextAttribsARB)
- {
- int attributes[] =
- {
- WGL_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
- WGL_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
- WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
- 0, 0
- };
- m_context = wglCreateContextAttribsARB(m_deviceContext, sharedContext, attributes);
- }
-
- // If we couldn't create the context, lower the version number and try again -- stop at 3.0
- // Invalid version numbers will be generated by this algorithm (like 3.9), but we really don't care
- if (!m_context)
- {
- if (m_settings.minorVersion > 0)
- {
- // If the minor version is not 0, we decrease it and try again
- m_settings.minorVersion--;
- }
- else
- {
- // If the minor version is 0, we decrease the major version
- m_settings.majorVersion--;
- m_settings.minorVersion = 9;
- }
- }
- }
-
- // If the OpenGL >= 3.0 context failed or if we don't want one, create a regular OpenGL 1.x/2.x context
- if (!m_context)
- {
- // set the context version to 2.0 (arbitrary)
- m_settings.majorVersion = 2;
- m_settings.minorVersion = 0;
-
- m_context = wglCreateContext(m_deviceContext);
- if (!m_context)
- {
- err() << "Failed to create an OpenGL context for this window" << std::endl;
- return;
- }
-
- // Share this context with others
- if (sharedContext)
- {
- // wglShareLists doesn't seem to be thread-safe
- static Mutex mutex;
- Lock lock(mutex);
-
- if (!wglShareLists(sharedContext, m_context))
- err() << "Failed to share the OpenGL context" << std::endl;
- }
- }
-}
-
-} // namespace priv
-
-} // namespace sf
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 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/WindowImpl.hpp> // included first to avoid a warning about macro redefinition
+#include <SFML/Window/Win32/WglContext.hpp>
+#include <SFML/Window/glext/wglext.h>
+#include <SFML/System/Lock.hpp>
+#include <SFML/System/Mutex.hpp>
+#include <SFML/System/Err.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+WglContext::WglContext(WglContext* shared) :
+m_window (NULL),
+m_deviceContext(NULL),
+m_context (NULL),
+m_ownsWindow (true)
+{
+ // Creating a dummy window is mandatory: we could create a memory DC but then
+ // its pixel format wouldn't match the regular contexts' format, and thus
+ // wglShareLists would always fail. Too bad...
+
+ // Create a dummy window (disabled and hidden)
+ m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL);
+ ShowWindow(m_window, SW_HIDE);
+ m_deviceContext = GetDC(m_window);
+
+ // Create the context
+ if (m_deviceContext)
+ createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
+}
+
+
+////////////////////////////////////////////////////////////
+WglContext::WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
+m_window (NULL),
+m_deviceContext(NULL),
+m_context (NULL),
+m_ownsWindow (false)
+{
+ // Get the owner window and its device context
+ m_window = owner->getSystemHandle();
+ m_deviceContext = GetDC(m_window);
+
+ // Create the context
+ if (m_deviceContext)
+ createContext(shared, bitsPerPixel, settings);
+}
+
+
+////////////////////////////////////////////////////////////
+WglContext::WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) :
+m_window (NULL),
+m_deviceContext(NULL),
+m_context (NULL),
+m_ownsWindow (true)
+{
+ // The target of the context is a hidden window.
+ // We can't create a memory DC (the resulting context wouldn't be compatible
+ // with other contexts), and we don't add the extra complexity of P-Buffers;
+ // we can still support them in the future if this solution is not good enough.
+
+ // Create the hidden window
+ m_window = CreateWindowA("STATIC", "", WS_POPUP | WS_DISABLED, 0, 0, width, height, NULL, NULL, GetModuleHandle(NULL), NULL);
+ ShowWindow(m_window, SW_HIDE);
+ m_deviceContext = GetDC(m_window);
+
+ // Create the context
+ if (m_deviceContext)
+ createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings);
+}
+
+
+////////////////////////////////////////////////////////////
+WglContext::~WglContext()
+{
+ // Destroy the OpenGL context
+ if (m_context)
+ {
+ if (wglGetCurrentContext() == m_context)
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(m_context);
+ }
+
+ // Destroy the device context
+ if (m_deviceContext)
+ ReleaseDC(m_window, m_deviceContext);
+
+ // Destroy the window if we own it
+ if (m_window && m_ownsWindow)
+ DestroyWindow(m_window);
+}
+
+
+////////////////////////////////////////////////////////////
+bool WglContext::makeCurrent()
+{
+ return m_deviceContext && m_context && wglMakeCurrent(m_deviceContext, m_context);
+}
+
+
+////////////////////////////////////////////////////////////
+void WglContext::display()
+{
+ if (m_deviceContext && m_context)
+ SwapBuffers(m_deviceContext);
+}
+
+
+////////////////////////////////////////////////////////////
+void WglContext::setVerticalSyncEnabled(bool enabled)
+{
+ PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(wglGetProcAddress("wglSwapIntervalEXT"));
+ if (wglSwapIntervalEXT)
+ wglSwapIntervalEXT(enabled ? 1 : 0);
+}
+
+
+////////////////////////////////////////////////////////////
+void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
+{
+ // Save the creation settings
+ m_settings = settings;
+
+ // Let's find a suitable pixel format -- first try with antialiasing
+ int bestFormat = 0;
+ if (m_settings.antialiasingLevel > 0)
+ {
+ // Get the wglChoosePixelFormatARB function (it is an extension)
+ PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(wglGetProcAddress("wglChoosePixelFormatARB"));
+ if (wglChoosePixelFormatARB)
+ {
+ // Define the basic attributes we want for our window
+ int intAttributes[] =
+ {
+ WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
+ WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
+ WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
+ WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
+ WGL_SAMPLE_BUFFERS_ARB, (m_settings.antialiasingLevel ? GL_TRUE : GL_FALSE),
+ WGL_SAMPLES_ARB, static_cast<int>(m_settings.antialiasingLevel),
+ 0, 0
+ };
+
+ // Let's check how many formats are supporting our requirements
+ int formats[128];
+ UINT nbFormats;
+ float floatAttributes[] = {0, 0};
+ bool isValid = wglChoosePixelFormatARB(m_deviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
+ while ((!isValid || (nbFormats == 0)) && m_settings.antialiasingLevel > 0)
+ {
+ // Decrease the antialiasing level until we find a valid one
+ m_settings.antialiasingLevel--;
+ intAttributes[11] = m_settings.antialiasingLevel;
+ isValid = wglChoosePixelFormatARB(m_deviceContext, intAttributes, floatAttributes, sizeof(formats) / sizeof(*formats), formats, &nbFormats) != 0;
+ }
+
+ // Get the best format among the returned ones
+ if (isValid && (nbFormats > 0))
+ {
+ int bestScore = 0xFFFF;
+ for (UINT i = 0; i < nbFormats; ++i)
+ {
+ // Get the current format's attributes
+ PIXELFORMATDESCRIPTOR attributes;
+ attributes.nSize = sizeof(attributes);
+ attributes.nVersion = 1;
+ DescribePixelFormat(m_deviceContext, formats[i], sizeof(attributes), &attributes);
+
+ // Evaluate the current configuration
+ int color = attributes.cRedBits + attributes.cGreenBits + attributes.cBlueBits + attributes.cAlphaBits;
+ int score = evaluateFormat(bitsPerPixel, m_settings, color, attributes.cDepthBits, attributes.cStencilBits, m_settings.antialiasingLevel);
+
+ // Keep it if it's better than the current best
+ if (score < bestScore)
+ {
+ bestScore = score;
+ bestFormat = formats[i];
+ }
+ }
+ }
+ }
+ else
+ {
+ // wglChoosePixelFormatARB not supported ; disabling antialiasing
+ err() << "Antialiasing is not supported ; it will be disabled" << std::endl;
+ m_settings.antialiasingLevel = 0;
+ }
+ }
+
+ // Find a pixel format with no antialiasing, if not needed or not supported
+ if (bestFormat == 0)
+ {
+ // Setup a pixel format descriptor from the rendering settings
+ PIXELFORMATDESCRIPTOR descriptor;
+ ZeroMemory(&descriptor, sizeof(descriptor));
+ descriptor.nSize = sizeof(descriptor);
+ descriptor.nVersion = 1;
+ descriptor.iLayerType = PFD_MAIN_PLANE;
+ descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+ descriptor.iPixelType = PFD_TYPE_RGBA;
+ descriptor.cColorBits = static_cast<BYTE>(bitsPerPixel);
+ descriptor.cDepthBits = static_cast<BYTE>(m_settings.depthBits);
+ descriptor.cStencilBits = static_cast<BYTE>(m_settings.stencilBits);
+ descriptor.cAlphaBits = bitsPerPixel == 32 ? 8 : 0;
+
+ // Get the pixel format that best matches our requirements
+ bestFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
+ if (bestFormat == 0)
+ {
+ err() << "Failed to find a suitable pixel format for device context -- cannot create OpenGL context" << std::endl;
+ return;
+ }
+ }
+
+ // Extract the depth and stencil bits from the chosen format
+ PIXELFORMATDESCRIPTOR actualFormat;
+ actualFormat.nSize = sizeof(actualFormat);
+ actualFormat.nVersion = 1;
+ DescribePixelFormat(m_deviceContext, bestFormat, sizeof(actualFormat), &actualFormat);
+ m_settings.depthBits = actualFormat.cDepthBits;
+ m_settings.stencilBits = actualFormat.cStencilBits;
+
+ // Set the chosen pixel format
+ if (!SetPixelFormat(m_deviceContext, bestFormat, &actualFormat))
+ {
+ err() << "Failed to set pixel format for device context -- cannot create OpenGL context" << std::endl;
+ return;
+ }
+
+ // Get the context to share display lists with
+ HGLRC sharedContext = shared ? shared->m_context : NULL;
+
+ // Create the OpenGL context -- first try context versions >= 3.0 if it is requested (they require special code)
+ while (!m_context && (m_settings.majorVersion >= 3))
+ {
+ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(wglGetProcAddress("wglCreateContextAttribsARB"));
+ if (wglCreateContextAttribsARB)
+ {
+ int attributes[] =
+ {
+ WGL_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
+ WGL_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
+ WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
+ 0, 0
+ };
+ m_context = wglCreateContextAttribsARB(m_deviceContext, sharedContext, attributes);
+ }
+
+ // If we couldn't create the context, lower the version number and try again -- stop at 3.0
+ // Invalid version numbers will be generated by this algorithm (like 3.9), but we really don't care
+ if (!m_context)
+ {
+ if (m_settings.minorVersion > 0)
+ {
+ // If the minor version is not 0, we decrease it and try again
+ m_settings.minorVersion--;
+ }
+ else
+ {
+ // If the minor version is 0, we decrease the major version
+ m_settings.majorVersion--;
+ m_settings.minorVersion = 9;
+ }
+ }
+ }
+
+ // If the OpenGL >= 3.0 context failed or if we don't want one, create a regular OpenGL 1.x/2.x context
+ if (!m_context)
+ {
+ // set the context version to 2.0 (arbitrary)
+ m_settings.majorVersion = 2;
+ m_settings.minorVersion = 0;
+
+ m_context = wglCreateContext(m_deviceContext);
+ if (!m_context)
+ {
+ err() << "Failed to create an OpenGL context for this window" << std::endl;
+ return;
+ }
+
+ // Share this context with others
+ if (sharedContext)
+ {
+ // wglShareLists doesn't seem to be thread-safe
+ static Mutex mutex;
+ Lock lock(mutex);
+
+ if (!wglShareLists(sharedContext, m_context))
+ err() << "Failed to share the OpenGL context" << std::endl;
+ }
+ }
+}
+
+} // namespace priv
+
+} // namespace sf
diff --git a/src/SFML/Window/Win32/WglContext.hpp b/src/SFML/Window/Win32/WglContext.hpp
index 3fa1c3a..75ef4d5 100644
--- a/src/SFML/Window/Win32/WglContext.hpp
+++ b/src/SFML/Window/Win32/WglContext.hpp
@@ -1,136 +1,136 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_WGLCONTEXT_HPP
-#define SFML_WGLCONTEXT_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Window/GlContext.hpp>
-#include <SFML/OpenGL.hpp>
-#include <windows.h>
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-/// \brief Windows (WGL) implementation of OpenGL contexts
-///
-////////////////////////////////////////////////////////////
-class WglContext : public GlContext
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Create a new default context
- ///
- /// \param shared Context to share the new one with (can be NULL)
- ///
- ////////////////////////////////////////////////////////////
- WglContext(WglContext* shared);
-
- ////////////////////////////////////////////////////////////
- /// \brief Create a new context attached to a window
- ///
- /// \param shared Context to share the new one with
- /// \param settings Creation parameters
- /// \param owner Pointer to the owner window
- /// \param bitsPerPixel Pixel depth, in bits per pixel
- ///
- ////////////////////////////////////////////////////////////
- WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
-
- ////////////////////////////////////////////////////////////
- /// \brief Create a new context that embeds its own rendering target
- ///
- /// \param shared Context to share the new one with
- /// \param settings Creation parameters
- /// \param width Back buffer width, in pixels
- /// \param height Back buffer height, in pixels
- ///
- ////////////////////////////////////////////////////////////
- WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height);
-
- ////////////////////////////////////////////////////////////
- /// \brief Destructor
- ///
- ////////////////////////////////////////////////////////////
- ~WglContext();
-
- ////////////////////////////////////////////////////////////
- /// \brief Activate the context as the current target for rendering
- ///
- /// \return True on success, false if any error happened
- ///
- ////////////////////////////////////////////////////////////
- virtual bool makeCurrent();
-
- ////////////////////////////////////////////////////////////
- /// \brief Display what has been rendered to the context so far
- ///
- ////////////////////////////////////////////////////////////
- virtual void display();
-
- ////////////////////////////////////////////////////////////
- /// \brief Enable or disable vertical synchronization
- ///
- /// Activating vertical synchronization will limit the number
- /// of frames displayed to the refresh rate of the monitor.
- /// This can avoid some visual artifacts, and limit the framerate
- /// to a good value (but not constant across different computers).
- ///
- /// \param enabled : True to enable v-sync, false to deactivate
- ///
- ////////////////////////////////////////////////////////////
- virtual void setVerticalSyncEnabled(bool enabled);
-
-private :
-
- ////////////////////////////////////////////////////////////
- /// \brief Create the context
- ///
- /// \param shared Context to share the new one with (can be NULL)
- /// \param bitsPerPixel Pixel depth, in bits per pixel
- /// \param settings Creation parameters
- ///
- ////////////////////////////////////////////////////////////
- void createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings);
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- HWND m_window; ///< Window to which the context is attached
- HDC m_deviceContext; ///< Device context associated to the context
- HGLRC m_context; ///< OpenGL context
- bool m_ownsWindow; ///< Do we own the target window?
-};
-
-} // namespace priv
-
-} // namespace sf
-
-#endif // SFML_WGLCONTEXT_HPP
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 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_WGLCONTEXT_HPP
+#define SFML_WGLCONTEXT_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/GlContext.hpp>
+#include <SFML/OpenGL.hpp>
+#include <windows.h>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Windows (WGL) implementation of OpenGL contexts
+///
+////////////////////////////////////////////////////////////
+class WglContext : public GlContext
+{
+public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create a new default context
+ ///
+ /// \param shared Context to share the new one with (can be NULL)
+ ///
+ ////////////////////////////////////////////////////////////
+ WglContext(WglContext* shared);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create a new context attached to a window
+ ///
+ /// \param shared Context to share the new one with
+ /// \param settings Creation parameters
+ /// \param owner Pointer to the owner window
+ /// \param bitsPerPixel Pixel depth, in bits per pixel
+ ///
+ ////////////////////////////////////////////////////////////
+ WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create a new context that embeds its own rendering target
+ ///
+ /// \param shared Context to share the new one with
+ /// \param settings Creation parameters
+ /// \param width Back buffer width, in pixels
+ /// \param height Back buffer height, in pixels
+ ///
+ ////////////////////////////////////////////////////////////
+ WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Destructor
+ ///
+ ////////////////////////////////////////////////////////////
+ ~WglContext();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Activate the context as the current target for rendering
+ ///
+ /// \return True on success, false if any error happened
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual bool makeCurrent();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Display what has been rendered to the context so far
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void display();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Enable or disable vertical synchronization
+ ///
+ /// Activating vertical synchronization will limit the number
+ /// of frames displayed to the refresh rate of the monitor.
+ /// This can avoid some visual artifacts, and limit the framerate
+ /// to a good value (but not constant across different computers).
+ ///
+ /// \param enabled: True to enable v-sync, false to deactivate
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setVerticalSyncEnabled(bool enabled);
+
+private:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create the context
+ ///
+ /// \param shared Context to share the new one with (can be NULL)
+ /// \param bitsPerPixel Pixel depth, in bits per pixel
+ /// \param settings Creation parameters
+ ///
+ ////////////////////////////////////////////////////////////
+ void createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ HWND m_window; ///< Window to which the context is attached
+ HDC m_deviceContext; ///< Device context associated to the context
+ HGLRC m_context; ///< OpenGL context
+ bool m_ownsWindow; ///< Do we own the target window?
+};
+
+} // namespace priv
+
+} // namespace sf
+
+#endif // SFML_WGLCONTEXT_HPP
diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp
index 4c83cae..69fe2ea 100644
--- a/src/SFML/Window/Win32/WindowImplWin32.cpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.cpp
@@ -1,939 +1,1025 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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
-////////////////////////////////////////////////////////////
-#ifdef _WIN32_WINDOWS
- #undef _WIN32_WINDOWS
-#endif
-#ifdef _WIN32_WINNT
- #undef _WIN32_WINNT
-#endif
-#define _WIN32_WINDOWS 0x0501
-#define _WIN32_WINNT 0x0501
-#include <SFML/Window/Win32/WindowImplWin32.hpp>
-#include <SFML/Window/WindowStyle.hpp>
-#include <GL/gl.h>
-#include <SFML/System/Err.hpp>
-#include <SFML/System/Utf.hpp>
-#include <vector>
-
-// MinGW lacks the definition of some Win32 constants
-#ifndef XBUTTON1
- #define XBUTTON1 0x0001
-#endif
-#ifndef XBUTTON2
- #define XBUTTON2 0x0002
-#endif
-#ifndef MAPVK_VK_TO_VSC
- #define MAPVK_VK_TO_VSC (0)
-#endif
-
-
-namespace
-{
- unsigned int windowCount = 0;
- const char* classNameA = "SFML_Window";
- const wchar_t* classNameW = L"SFML_Window";
- sf::priv::WindowImplWin32* fullscreenWindow = NULL;
-}
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-WindowImplWin32::WindowImplWin32(WindowHandle handle) :
-m_handle (handle),
-m_callback (0),
-m_cursor (NULL),
-m_icon (NULL),
-m_keyRepeatEnabled(true),
-m_lastSize (0, 0),
-m_resizing (false),
-m_surrogate (0)
-{
- if (m_handle)
- {
- // We change the event procedure of the control (it is important to save the old one)
- SetWindowLongPtr(m_handle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
- m_callback = SetWindowLongPtr(m_handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&WindowImplWin32::globalOnEvent));
- }
-}
-
-
-////////////////////////////////////////////////////////////
-WindowImplWin32::WindowImplWin32(VideoMode mode, const String& title, Uint32 style, const ContextSettings& /*settings*/) :
-m_handle (NULL),
-m_callback (0),
-m_cursor (NULL),
-m_icon (NULL),
-m_keyRepeatEnabled(true),
-m_lastSize (mode.width, mode.height),
-m_resizing (false),
-m_surrogate (0)
-{
- // Register the window class at first call
- if (windowCount == 0)
- registerWindowClass();
-
- // Compute position and size
- HDC screenDC = GetDC(NULL);
- int left = (GetDeviceCaps(screenDC, HORZRES) - static_cast<int>(mode.width)) / 2;
- int top = (GetDeviceCaps(screenDC, VERTRES) - static_cast<int>(mode.height)) / 2;
- int width = mode.width;
- int height = mode.height;
- ReleaseDC(NULL, screenDC);
-
- // Choose the window style according to the Style parameter
- DWORD win32Style = WS_VISIBLE;
- if (style == Style::None)
- {
- win32Style |= WS_POPUP;
- }
- else
- {
- if (style & Style::Titlebar) win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
- if (style & Style::Resize) win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
- if (style & Style::Close) win32Style |= WS_SYSMENU;
- }
-
- // In windowed mode, adjust width and height so that window will have the requested client area
- bool fullscreen = (style & Style::Fullscreen) != 0;
- if (!fullscreen)
- {
- RECT rectangle = {0, 0, width, height};
- AdjustWindowRect(&rectangle, win32Style, false);
- width = rectangle.right - rectangle.left;
- height = rectangle.bottom - rectangle.top;
- }
-
- // Create the window
- if (hasUnicodeSupport())
- {
- m_handle = CreateWindowW(classNameW, title.toWideString().c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
- }
- else
- {
- m_handle = CreateWindowA(classNameA, title.toAnsiString().c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
- }
-
- // By default, the OS limits the size of the window the the desktop size,
- // we have to resize it after creation to apply the real size
- setSize(Vector2u(mode.width, mode.height));
-
- // Switch to fullscreen if requested
- if (fullscreen)
- switchToFullscreen(mode);
-
- // Increment window count
- windowCount++;
-}
-
-
-////////////////////////////////////////////////////////////
-WindowImplWin32::~WindowImplWin32()
-{
- // Destroy the custom icon, if any
- if (m_icon)
- DestroyIcon(m_icon);
-
- if (!m_callback)
- {
- // Destroy the window
- if (m_handle)
- DestroyWindow(m_handle);
-
- // Decrement the window count
- windowCount--;
-
- // Unregister window class if we were the last window
- if (windowCount == 0)
- {
- if (hasUnicodeSupport())
- {
- UnregisterClassW(classNameW, GetModuleHandle(NULL));
- }
- else
- {
- UnregisterClassA(classNameA, GetModuleHandle(NULL));
- }
- }
- }
- else
- {
- // The window is external : remove the hook on its message callback
- SetWindowLongPtr(m_handle, GWLP_WNDPROC, m_callback);
- }
-}
-
-
-////////////////////////////////////////////////////////////
-WindowHandle WindowImplWin32::getSystemHandle() const
-{
- return m_handle;
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::processEvents()
-{
- // We process the window events only if we own it
- if (!m_callback)
- {
- MSG message;
- while (PeekMessage(&message, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&message);
- DispatchMessage(&message);
- }
- }
-}
-
-
-////////////////////////////////////////////////////////////
-Vector2i WindowImplWin32::getPosition() const
-{
- RECT rect;
- GetWindowRect(m_handle, &rect);
-
- return Vector2i(rect.left, rect.top);
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::setPosition(const Vector2i& position)
-{
- SetWindowPos(m_handle, NULL, position.x, position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
-}
-
-
-////////////////////////////////////////////////////////////
-Vector2u WindowImplWin32::getSize() const
-{
- RECT rect;
- GetClientRect(m_handle, &rect);
-
- return Vector2u(rect.right - rect.left, rect.bottom - rect.top);
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::setSize(const Vector2u& size)
-{
- // SetWindowPos wants the total size of the window (including title bar and borders),
- // so we have to compute it
- RECT rectangle = {0, 0, static_cast<long>(size.x), static_cast<long>(size.y)};
- AdjustWindowRect(&rectangle, GetWindowLong(m_handle, GWL_STYLE), false);
- int width = rectangle.right - rectangle.left;
- int height = rectangle.bottom - rectangle.top;
-
- SetWindowPos(m_handle, NULL, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER);
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::setTitle(const String& title)
-{
- if (hasUnicodeSupport())
- {
- SetWindowTextW(m_handle, title.toWideString().c_str());
- }
- else
- {
- SetWindowTextA(m_handle, title.toAnsiString().c_str());
- }
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::setIcon(unsigned int width, unsigned int height, const Uint8* pixels)
-{
- // First destroy the previous one
- if (m_icon)
- DestroyIcon(m_icon);
-
- // Windows wants BGRA pixels: swap red and blue channels
- std::vector<Uint8> iconPixels(width * height * 4);
- for (std::size_t i = 0; i < iconPixels.size() / 4; ++i)
- {
- iconPixels[i * 4 + 0] = pixels[i * 4 + 2];
- iconPixels[i * 4 + 1] = pixels[i * 4 + 1];
- iconPixels[i * 4 + 2] = pixels[i * 4 + 0];
- iconPixels[i * 4 + 3] = pixels[i * 4 + 3];
- }
-
- // Create the icon from the pixel array
- m_icon = CreateIcon(GetModuleHandle(NULL), width, height, 1, 32, NULL, &iconPixels[0]);
-
- // Set it as both big and small icon of the window
- if (m_icon)
- {
- SendMessage(m_handle, WM_SETICON, ICON_BIG, (LPARAM)m_icon);
- SendMessage(m_handle, WM_SETICON, ICON_SMALL, (LPARAM)m_icon);
- }
- else
- {
- err() << "Failed to set the window's icon" << std::endl;
- }
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::setVisible(bool visible)
-{
- ShowWindow(m_handle, visible ? SW_SHOW : SW_HIDE);
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::setMouseCursorVisible(bool visible)
-{
- if (visible)
- m_cursor = LoadCursor(NULL, IDC_ARROW);
- else
- m_cursor = NULL;
-
- SetCursor(m_cursor);
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
-{
- m_keyRepeatEnabled = enabled;
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::registerWindowClass()
-{
- if (hasUnicodeSupport())
- {
- WNDCLASSW windowClass;
- windowClass.style = 0;
- windowClass.lpfnWndProc = &WindowImplWin32::globalOnEvent;
- windowClass.cbClsExtra = 0;
- windowClass.cbWndExtra = 0;
- windowClass.hInstance = GetModuleHandle(NULL);
- windowClass.hIcon = NULL;
- windowClass.hCursor = 0;
- windowClass.hbrBackground = 0;
- windowClass.lpszMenuName = NULL;
- windowClass.lpszClassName = classNameW;
- RegisterClassW(&windowClass);
- }
- else
- {
- WNDCLASSA windowClass;
- windowClass.style = 0;
- windowClass.lpfnWndProc = &WindowImplWin32::globalOnEvent;
- windowClass.cbClsExtra = 0;
- windowClass.cbWndExtra = 0;
- windowClass.hInstance = GetModuleHandle(NULL);
- windowClass.hIcon = NULL;
- windowClass.hCursor = 0;
- windowClass.hbrBackground = 0;
- windowClass.lpszMenuName = NULL;
- windowClass.lpszClassName = classNameA;
- RegisterClassA(&windowClass);
- }
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::switchToFullscreen(const VideoMode& mode)
-{
- DEVMODE devMode;
- devMode.dmSize = sizeof(devMode);
- devMode.dmPelsWidth = mode.width;
- devMode.dmPelsHeight = mode.height;
- devMode.dmBitsPerPel = mode.bitsPerPixel;
- devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
-
- // Apply fullscreen mode
- if (ChangeDisplaySettings(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
- {
- err() << "Failed to change display mode for fullscreen" << std::endl;
- return;
- }
-
- // Make the window flags compatible with fullscreen mode
- SetWindowLong(m_handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
- SetWindowLong(m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
-
- // Resize the window so that it fits the entire screen
- SetWindowPos(m_handle, HWND_TOP, 0, 0, mode.width, mode.height, SWP_FRAMECHANGED);
- ShowWindow(m_handle, SW_SHOW);
-
- // Set "this" as the current fullscreen window
- fullscreenWindow = this;
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::cleanup()
-{
- // Restore the previous video mode (in case we were running in fullscreen)
- if (fullscreenWindow == this)
- {
- ChangeDisplaySettings(NULL, 0);
- fullscreenWindow = NULL;
- }
-
- // Unhide the mouse cursor (in case it was hidden)
- setMouseCursorVisible(true);
-}
-
-
-////////////////////////////////////////////////////////////
-void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
-{
- // Don't process any message until window is created
- if (m_handle == NULL)
- return;
-
- switch (message)
- {
- // Destroy event
- case WM_DESTROY :
- {
- // Here we must cleanup resources !
- cleanup();
- break;
- }
-
- // Set cursor event
- case WM_SETCURSOR :
- {
- // The mouse has moved, if the cursor is in our window we must refresh the cursor
- if (LOWORD(lParam) == HTCLIENT)
- SetCursor(m_cursor);
-
- break;
- }
-
- // Close event
- case WM_CLOSE :
- {
- Event event;
- event.type = Event::Closed;
- pushEvent(event);
- break;
- }
-
- // Resize event
- case WM_SIZE :
- {
- // Consider only events triggered by a maximize or a un-maximize
- if (wParam != SIZE_MINIMIZED && !m_resizing && m_lastSize != getSize())
- {
- // Update the last handled size
- m_lastSize = getSize();
-
- // Push a resize event
- Event event;
- event.type = Event::Resized;
- event.size.width = m_lastSize.x;
- event.size.height = m_lastSize.y;
- pushEvent(event);
- }
- break;
- }
-
- // Start resizing
- case WM_ENTERSIZEMOVE:
- {
- m_resizing = true;
- break;
- }
-
- // Stop resizing
- case WM_EXITSIZEMOVE:
- {
- m_resizing = false;
-
- // Ignore cases where the window has only been moved
- if(m_lastSize != getSize())
- {
- // Update the last handled size
- m_lastSize = getSize();
-
- // Push a resize event
- Event event;
- event.type = Event::Resized;
- event.size.width = m_lastSize.x;
- event.size.height = m_lastSize.y;
- pushEvent(event);
- }
- break;
- }
-
- // The system request the min/max window size and position
- case WM_GETMINMAXINFO :
- {
- // We override the returned information to remove the default limit
- // (the OS doesn't allow windows bigger than the desktop by default)
- MINMAXINFO* info = reinterpret_cast<MINMAXINFO*>(lParam);
- info->ptMaxTrackSize.x = 50000;
- info->ptMaxTrackSize.y = 50000;
- break;
- }
-
- // Gain focus event
- case WM_SETFOCUS :
- {
- Event event;
- event.type = Event::GainedFocus;
- pushEvent(event);
- break;
- }
-
- // Lost focus event
- case WM_KILLFOCUS :
- {
- Event event;
- event.type = Event::LostFocus;
- pushEvent(event);
- break;
- }
-
- // Text event
- case WM_CHAR :
- {
- if (m_keyRepeatEnabled || ((lParam & (1 << 30)) == 0))
- {
- // Get the code of the typed character
- Uint32 character = static_cast<Uint32>(wParam);
-
- // Check if it is the first part of a surrogate pair, or a regular character
- if ((character >= 0xD800) && (character <= 0xDBFF))
- {
- // First part of a surrogate pair: store it and wait for the second one
- m_surrogate = static_cast<Uint16>(character);
- }
- else
- {
-
- // Check if it is the second part of a surrogate pair, or a regular character
- if ((character >= 0xDC00) && (character <= 0xDFFF))
- {
- // Convert the UTF-16 surrogate pair to a single UTF-32 value
- Uint16 utf16[] = {m_surrogate, static_cast<Uint16>(character)};
- sf::Utf16::toUtf32(utf16, utf16 + 2, &character);
- m_surrogate = 0;
- }
-
- // Send a TextEntered event
- Event event;
- event.type = Event::TextEntered;
- event.text.unicode = character;
- pushEvent(event);
- }
- }
- break;
- }
-
- // Keydown event
- case WM_KEYDOWN :
- case WM_SYSKEYDOWN :
- {
- if (m_keyRepeatEnabled || ((HIWORD(lParam) & KF_REPEAT) == 0))
- {
- Event event;
- event.type = Event::KeyPressed;
- event.key.alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
- event.key.control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
- event.key.shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
- event.key.system = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
- event.key.code = virtualKeyCodeToSF(wParam, lParam);
- pushEvent(event);
- }
- break;
- }
-
- // Keyup event
- case WM_KEYUP :
- case WM_SYSKEYUP :
- {
- Event event;
- event.type = Event::KeyReleased;
- event.key.alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
- event.key.control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
- event.key.shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
- event.key.system = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
- event.key.code = virtualKeyCodeToSF(wParam, lParam);
- pushEvent(event);
- break;
- }
-
- // Mouse wheel event
- case WM_MOUSEWHEEL :
- {
- // Mouse position is in screen coordinates, convert it to window coordinates
- POINT position;
- position.x = static_cast<Int16>(LOWORD(lParam));
- position.y = static_cast<Int16>(HIWORD(lParam));
- ScreenToClient(m_handle, &position);
-
- Event event;
- event.type = Event::MouseWheelMoved;
- event.mouseWheel.delta = static_cast<Int16>(HIWORD(wParam)) / 120;
- event.mouseWheel.x = position.x;
- event.mouseWheel.y = position.y;
- pushEvent(event);
- break;
- }
-
- // Mouse left button down event
- case WM_LBUTTONDOWN :
- {
- Event event;
- event.type = Event::MouseButtonPressed;
- event.mouseButton.button = Mouse::Left;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse left button up event
- case WM_LBUTTONUP :
- {
- Event event;
- event.type = Event::MouseButtonReleased;
- event.mouseButton.button = Mouse::Left;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse right button down event
- case WM_RBUTTONDOWN :
- {
- Event event;
- event.type = Event::MouseButtonPressed;
- event.mouseButton.button = Mouse::Right;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse right button up event
- case WM_RBUTTONUP :
- {
- Event event;
- event.type = Event::MouseButtonReleased;
- event.mouseButton.button = Mouse::Right;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse wheel button down event
- case WM_MBUTTONDOWN :
- {
- Event event;
- event.type = Event::MouseButtonPressed;
- event.mouseButton.button = Mouse::Middle;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse wheel button up event
- case WM_MBUTTONUP :
- {
- Event event;
- event.type = Event::MouseButtonReleased;
- event.mouseButton.button = Mouse::Middle;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse X button down event
- case WM_XBUTTONDOWN :
- {
- Event event;
- event.type = Event::MouseButtonPressed;
- event.mouseButton.button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse X button up event
- case WM_XBUTTONUP :
- {
- Event event;
- event.type = Event::MouseButtonReleased;
- event.mouseButton.button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
- event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
- event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
- pushEvent(event);
- break;
- }
-
- // Mouse move event
- case WM_MOUSEMOVE :
- {
- // Extract the mouse local coordinates
- int x = static_cast<Int16>(LOWORD(lParam));
- int y = static_cast<Int16>(HIWORD(lParam));
-
- // Get the client area of the window
- RECT area;
- GetClientRect(m_handle, &area);
-
- // Check the mouse position against the window
- if ((x < area.left) || (x > area.right) || (y < area.top) || (y > area.bottom))
- {
- // Mouse is outside
-
- // Release the mouse capture
- ReleaseCapture();
-
- // Generate a MouseLeft event
- Event event;
- event.type = Event::MouseLeft;
- pushEvent(event);
- }
- else
- {
- // Mouse is inside
- if (GetCapture() != m_handle)
- {
- // Mouse was previously outside the window
-
- // Capture the mouse
- SetCapture(m_handle);
-
- // Generate a MouseEntered event
- Event event;
- event.type = Event::MouseEntered;
- pushEvent(event);
- }
-
- // Generate a MouseMove event
- Event event;
- event.type = Event::MouseMoved;
- event.mouseMove.x = x;
- event.mouseMove.y = y;
- pushEvent(event);
- break;
- }
- }
- }
-}
-
-
-////////////////////////////////////////////////////////////
-Keyboard::Key WindowImplWin32::virtualKeyCodeToSF(WPARAM key, LPARAM flags)
-{
- switch (key)
- {
- // Check the scancode to distinguish between left and right shift
- case VK_SHIFT :
- {
- static UINT lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
- UINT scancode = static_cast<UINT>((flags & (0xFF << 16)) >> 16);
- return scancode == lShift ? Keyboard::LShift : Keyboard::RShift;
- }
-
- // Check the "extended" flag to distinguish between left and right alt
- case VK_MENU : return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RAlt : Keyboard::LAlt;
-
- // Check the "extended" flag to distinguish between left and right control
- case VK_CONTROL : return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RControl : Keyboard::LControl;
-
- // Other keys are reported properly
- case VK_LWIN : return Keyboard::LSystem;
- case VK_RWIN : return Keyboard::RSystem;
- case VK_APPS : return Keyboard::Menu;
- case VK_OEM_1 : return Keyboard::SemiColon;
- case VK_OEM_2 : return Keyboard::Slash;
- case VK_OEM_PLUS : return Keyboard::Equal;
- case VK_OEM_MINUS : return Keyboard::Dash;
- case VK_OEM_4 : return Keyboard::LBracket;
- case VK_OEM_6 : return Keyboard::RBracket;
- case VK_OEM_COMMA : return Keyboard::Comma;
- case VK_OEM_PERIOD : return Keyboard::Period;
- case VK_OEM_7 : return Keyboard::Quote;
- case VK_OEM_5 : return Keyboard::BackSlash;
- case VK_OEM_3 : return Keyboard::Tilde;
- case VK_ESCAPE : return Keyboard::Escape;
- case VK_SPACE : return Keyboard::Space;
- case VK_RETURN : return Keyboard::Return;
- case VK_BACK : return Keyboard::BackSpace;
- case VK_TAB : return Keyboard::Tab;
- case VK_PRIOR : return Keyboard::PageUp;
- case VK_NEXT : return Keyboard::PageDown;
- case VK_END : return Keyboard::End;
- case VK_HOME : return Keyboard::Home;
- case VK_INSERT : return Keyboard::Insert;
- case VK_DELETE : return Keyboard::Delete;
- case VK_ADD : return Keyboard::Add;
- case VK_SUBTRACT : return Keyboard::Subtract;
- case VK_MULTIPLY : return Keyboard::Multiply;
- case VK_DIVIDE : return Keyboard::Divide;
- case VK_PAUSE : return Keyboard::Pause;
- case VK_F1 : return Keyboard::F1;
- case VK_F2 : return Keyboard::F2;
- case VK_F3 : return Keyboard::F3;
- case VK_F4 : return Keyboard::F4;
- case VK_F5 : return Keyboard::F5;
- case VK_F6 : return Keyboard::F6;
- case VK_F7 : return Keyboard::F7;
- case VK_F8 : return Keyboard::F8;
- case VK_F9 : return Keyboard::F9;
- case VK_F10 : return Keyboard::F10;
- case VK_F11 : return Keyboard::F11;
- case VK_F12 : return Keyboard::F12;
- case VK_F13 : return Keyboard::F13;
- case VK_F14 : return Keyboard::F14;
- case VK_F15 : return Keyboard::F15;
- case VK_LEFT : return Keyboard::Left;
- case VK_RIGHT : return Keyboard::Right;
- case VK_UP : return Keyboard::Up;
- case VK_DOWN : return Keyboard::Down;
- case VK_NUMPAD0 : return Keyboard::Numpad0;
- case VK_NUMPAD1 : return Keyboard::Numpad1;
- case VK_NUMPAD2 : return Keyboard::Numpad2;
- case VK_NUMPAD3 : return Keyboard::Numpad3;
- case VK_NUMPAD4 : return Keyboard::Numpad4;
- case VK_NUMPAD5 : return Keyboard::Numpad5;
- case VK_NUMPAD6 : return Keyboard::Numpad6;
- case VK_NUMPAD7 : return Keyboard::Numpad7;
- case VK_NUMPAD8 : return Keyboard::Numpad8;
- case VK_NUMPAD9 : return Keyboard::Numpad9;
- case 'A' : return Keyboard::A;
- case 'Z' : return Keyboard::Z;
- case 'E' : return Keyboard::E;
- case 'R' : return Keyboard::R;
- case 'T' : return Keyboard::T;
- case 'Y' : return Keyboard::Y;
- case 'U' : return Keyboard::U;
- case 'I' : return Keyboard::I;
- case 'O' : return Keyboard::O;
- case 'P' : return Keyboard::P;
- case 'Q' : return Keyboard::Q;
- case 'S' : return Keyboard::S;
- case 'D' : return Keyboard::D;
- case 'F' : return Keyboard::F;
- case 'G' : return Keyboard::G;
- case 'H' : return Keyboard::H;
- case 'J' : return Keyboard::J;
- case 'K' : return Keyboard::K;
- case 'L' : return Keyboard::L;
- case 'M' : return Keyboard::M;
- case 'W' : return Keyboard::W;
- case 'X' : return Keyboard::X;
- case 'C' : return Keyboard::C;
- case 'V' : return Keyboard::V;
- case 'B' : return Keyboard::B;
- case 'N' : return Keyboard::N;
- case '0' : return Keyboard::Num0;
- case '1' : return Keyboard::Num1;
- case '2' : return Keyboard::Num2;
- case '3' : return Keyboard::Num3;
- case '4' : return Keyboard::Num4;
- case '5' : return Keyboard::Num5;
- case '6' : return Keyboard::Num6;
- case '7' : return Keyboard::Num7;
- case '8' : return Keyboard::Num8;
- case '9' : return Keyboard::Num9;
- }
-
- return Keyboard::Unknown;
-}
-
-
-////////////////////////////////////////////////////////////
-bool WindowImplWin32::hasUnicodeSupport()
-{
- OSVERSIONINFO version;
- ZeroMemory(&version, sizeof(version));
- version.dwOSVersionInfoSize = sizeof(version);
-
- if (GetVersionEx(&version))
- {
- return version.dwPlatformId == VER_PLATFORM_WIN32_NT;
- }
- else
- {
- return false;
- }
-}
-
-
-////////////////////////////////////////////////////////////
-LRESULT CALLBACK WindowImplWin32::globalOnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
-{
- // Associate handle and Window instance when the creation message is received
- if (message == WM_CREATE)
- {
- // Get WindowImplWin32 instance (it was passed as the last argument of CreateWindow)
- LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;
-
- // Set as the "user data" parameter of the window
- SetWindowLongPtr(handle, GWLP_USERDATA, window);
- }
-
- // Get the WindowImpl instance corresponding to the window handle
- WindowImplWin32* window = handle ? reinterpret_cast<WindowImplWin32*>(GetWindowLongPtr(handle, GWLP_USERDATA)) : NULL;
-
- // Forward the event to the appropriate function
- if (window)
- {
- window->processEvent(message, wParam, lParam);
-
- if (window->m_callback)
- return CallWindowProc(reinterpret_cast<WNDPROC>(window->m_callback), handle, message, wParam, lParam);
- }
-
- // We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window
- if (message == WM_CLOSE)
- return 0;
-
- // Don't forward the menu system command, so that pressing ALT or F10 doesn't steal the focus
- if ((message == WM_SYSCOMMAND) && (wParam == SC_KEYMENU))
- return 0;
-
- static const bool hasUnicode = hasUnicodeSupport();
- return hasUnicode ? DefWindowProcW(handle, message, wParam, lParam) :
- DefWindowProcA(handle, message, wParam, lParam);
-}
-
-} // namespace priv
-
-} // namespace sf
-
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 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
+////////////////////////////////////////////////////////////
+#ifdef _WIN32_WINDOWS
+ #undef _WIN32_WINDOWS
+#endif
+#ifdef _WIN32_WINNT
+ #undef _WIN32_WINNT
+#endif
+#define _WIN32_WINDOWS 0x0501
+#define _WIN32_WINNT 0x0501
+#define WINVER 0x0501
+#include <SFML/Window/Win32/WindowImplWin32.hpp>
+#include <SFML/Window/WindowStyle.hpp>
+#include <GL/gl.h>
+#include <SFML/System/Err.hpp>
+#include <SFML/System/Utf.hpp>
+#include <vector>
+
+// MinGW lacks the definition of some Win32 constants
+#ifndef XBUTTON1
+ #define XBUTTON1 0x0001
+#endif
+#ifndef XBUTTON2
+ #define XBUTTON2 0x0002
+#endif
+#ifndef MAPVK_VK_TO_VSC
+ #define MAPVK_VK_TO_VSC (0)
+#endif
+
+
+namespace
+{
+ unsigned int windowCount = 0;
+ const wchar_t* className = L"SFML_Window";
+ sf::priv::WindowImplWin32* fullscreenWindow = NULL;
+
+ void setProcessDpiAware()
+ {
+ // Try SetProcessDpiAwareness first
+ HINSTANCE shCoreDll = LoadLibrary(L"Shcore.dll");
+
+ if (shCoreDll)
+ {
+ enum ProcessDpiAwareness
+ {
+ ProcessDpiUnaware = 0,
+ ProcessSystemDpiAware = 1,
+ ProcessPerMonitorDpiAware = 2
+ };
+
+ typedef HRESULT (WINAPI* SetProcessDpiAwarenessFuncType)(ProcessDpiAwareness);
+ SetProcessDpiAwarenessFuncType SetProcessDpiAwarenessFunc = reinterpret_cast<SetProcessDpiAwarenessFuncType>(GetProcAddress(shCoreDll, "SetProcessDpiAwareness"));
+
+ if (SetProcessDpiAwarenessFunc)
+ {
+ // We only check for E_INVALIDARG because we would get
+ // E_ACCESSDENIED if the DPI was already set previously
+ // and S_OK means the call was successful
+ if (SetProcessDpiAwarenessFunc(ProcessSystemDpiAware) == E_INVALIDARG)
+ {
+ sf::err() << "Failed to set process DPI awareness" << std::endl;
+ }
+ else
+ {
+ FreeLibrary(shCoreDll);
+ return;
+ }
+ }
+
+ FreeLibrary(shCoreDll);
+ }
+
+ // Fall back to SetProcessDPIAware if SetProcessDpiAwareness
+ // is not available on this system
+ HINSTANCE user32Dll = LoadLibrary(L"user32.dll");
+
+ if (user32Dll)
+ {
+ typedef BOOL (WINAPI* SetProcessDPIAwareFuncType)(void);
+ SetProcessDPIAwareFuncType SetProcessDPIAwareFunc = reinterpret_cast<SetProcessDPIAwareFuncType>(GetProcAddress(user32Dll, "SetProcessDPIAware"));
+
+ if (SetProcessDPIAwareFunc)
+ {
+ if (!SetProcessDPIAwareFunc())
+ sf::err() << "Failed to set process DPI awareness" << std::endl;
+ }
+
+ FreeLibrary(user32Dll);
+ }
+ }
+}
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+WindowImplWin32::WindowImplWin32(WindowHandle handle) :
+m_handle (handle),
+m_callback (0),
+m_cursor (NULL),
+m_icon (NULL),
+m_keyRepeatEnabled(true),
+m_lastSize (0, 0),
+m_resizing (false),
+m_surrogate (0),
+m_mouseInside (false)
+{
+ // Set that this process is DPI aware and can handle DPI scaling
+ setProcessDpiAware();
+
+ if (m_handle)
+ {
+ // We change the event procedure of the control (it is important to save the old one)
+ SetWindowLongPtrW(m_handle, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(this));
+ m_callback = SetWindowLongPtrW(m_handle, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&WindowImplWin32::globalOnEvent));
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+WindowImplWin32::WindowImplWin32(VideoMode mode, const String& title, Uint32 style, const ContextSettings& /*settings*/) :
+m_handle (NULL),
+m_callback (0),
+m_cursor (NULL),
+m_icon (NULL),
+m_keyRepeatEnabled(true),
+m_lastSize (mode.width, mode.height),
+m_resizing (false),
+m_surrogate (0),
+m_mouseInside (false)
+{
+ // Set that this process is DPI aware and can handle DPI scaling
+ setProcessDpiAware();
+
+ // Register the window class at first call
+ if (windowCount == 0)
+ registerWindowClass();
+
+ // Compute position and size
+ HDC screenDC = GetDC(NULL);
+ int left = (GetDeviceCaps(screenDC, HORZRES) - static_cast<int>(mode.width)) / 2;
+ int top = (GetDeviceCaps(screenDC, VERTRES) - static_cast<int>(mode.height)) / 2;
+ int width = mode.width;
+ int height = mode.height;
+ ReleaseDC(NULL, screenDC);
+
+ // Choose the window style according to the Style parameter
+ DWORD win32Style = WS_VISIBLE;
+ if (style == Style::None)
+ {
+ win32Style |= WS_POPUP;
+ }
+ else
+ {
+ if (style & Style::Titlebar) win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
+ if (style & Style::Resize) win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
+ if (style & Style::Close) win32Style |= WS_SYSMENU;
+ }
+
+ // In windowed mode, adjust width and height so that window will have the requested client area
+ bool fullscreen = (style & Style::Fullscreen) != 0;
+ if (!fullscreen)
+ {
+ RECT rectangle = {0, 0, width, height};
+ AdjustWindowRect(&rectangle, win32Style, false);
+ width = rectangle.right - rectangle.left;
+ height = rectangle.bottom - rectangle.top;
+ }
+
+ // Create the window
+ m_handle = CreateWindowW(className, title.toWideString().c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
+
+ // By default, the OS limits the size of the window the the desktop size,
+ // we have to resize it after creation to apply the real size
+ setSize(Vector2u(mode.width, mode.height));
+
+ // Switch to fullscreen if requested
+ if (fullscreen)
+ switchToFullscreen(mode);
+
+ // Increment window count
+ windowCount++;
+}
+
+
+////////////////////////////////////////////////////////////
+WindowImplWin32::~WindowImplWin32()
+{
+ // Destroy the custom icon, if any
+ if (m_icon)
+ DestroyIcon(m_icon);
+
+ if (!m_callback)
+ {
+ // Destroy the window
+ if (m_handle)
+ DestroyWindow(m_handle);
+
+ // Decrement the window count
+ windowCount--;
+
+ // Unregister window class if we were the last window
+ if (windowCount == 0)
+ UnregisterClassW(className, GetModuleHandleW(NULL));
+ }
+ else
+ {
+ // The window is external: remove the hook on its message callback
+ SetWindowLongPtrW(m_handle, GWLP_WNDPROC, m_callback);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+WindowHandle WindowImplWin32::getSystemHandle() const
+{
+ return m_handle;
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::processEvents()
+{
+ // We process the window events only if we own it
+ if (!m_callback)
+ {
+ MSG message;
+ while (PeekMessageW(&message, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&message);
+ DispatchMessageW(&message);
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2i WindowImplWin32::getPosition() const
+{
+ RECT rect;
+ GetWindowRect(m_handle, &rect);
+
+ return Vector2i(rect.left, rect.top);
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setPosition(const Vector2i& position)
+{
+ SetWindowPos(m_handle, NULL, position.x, position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+}
+
+
+////////////////////////////////////////////////////////////
+Vector2u WindowImplWin32::getSize() const
+{
+ RECT rect;
+ GetClientRect(m_handle, &rect);
+
+ return Vector2u(rect.right - rect.left, rect.bottom - rect.top);
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setSize(const Vector2u& size)
+{
+ // SetWindowPos wants the total size of the window (including title bar and borders),
+ // so we have to compute it
+ RECT rectangle = {0, 0, static_cast<long>(size.x), static_cast<long>(size.y)};
+ AdjustWindowRect(&rectangle, GetWindowLong(m_handle, GWL_STYLE), false);
+ int width = rectangle.right - rectangle.left;
+ int height = rectangle.bottom - rectangle.top;
+
+ SetWindowPos(m_handle, NULL, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER);
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setTitle(const String& title)
+{
+ SetWindowTextW(m_handle, title.toWideString().c_str());
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setIcon(unsigned int width, unsigned int height, const Uint8* pixels)
+{
+ // First destroy the previous one
+ if (m_icon)
+ DestroyIcon(m_icon);
+
+ // Windows wants BGRA pixels: swap red and blue channels
+ std::vector<Uint8> iconPixels(width * height * 4);
+ for (std::size_t i = 0; i < iconPixels.size() / 4; ++i)
+ {
+ iconPixels[i * 4 + 0] = pixels[i * 4 + 2];
+ iconPixels[i * 4 + 1] = pixels[i * 4 + 1];
+ iconPixels[i * 4 + 2] = pixels[i * 4 + 0];
+ iconPixels[i * 4 + 3] = pixels[i * 4 + 3];
+ }
+
+ // Create the icon from the pixel array
+ m_icon = CreateIcon(GetModuleHandleW(NULL), width, height, 1, 32, NULL, &iconPixels[0]);
+
+ // Set it as both big and small icon of the window
+ if (m_icon)
+ {
+ SendMessageW(m_handle, WM_SETICON, ICON_BIG, (LPARAM)m_icon);
+ SendMessageW(m_handle, WM_SETICON, ICON_SMALL, (LPARAM)m_icon);
+ }
+ else
+ {
+ err() << "Failed to set the window's icon" << std::endl;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setVisible(bool visible)
+{
+ ShowWindow(m_handle, visible ? SW_SHOW : SW_HIDE);
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setMouseCursorVisible(bool visible)
+{
+ if (visible)
+ m_cursor = LoadCursorW(NULL, IDC_ARROW);
+ else
+ m_cursor = NULL;
+
+ SetCursor(m_cursor);
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
+{
+ m_keyRepeatEnabled = enabled;
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::requestFocus()
+{
+ // Allow focus stealing only within the same process; compare PIDs of current and foreground window
+ DWORD thisPid = GetWindowThreadProcessId(m_handle, NULL);
+ DWORD foregroundPid = GetWindowThreadProcessId(GetForegroundWindow(), NULL);
+
+ if (thisPid == foregroundPid)
+ {
+ // The window requesting focus belongs to the same process as the current window: steal focus
+ SetForegroundWindow(m_handle);
+ }
+ else
+ {
+ // Different process: don't steal focus, but create a taskbar notification ("flash")
+ FLASHWINFO info;
+ info.cbSize = sizeof(info);
+ info.hwnd = m_handle;
+ info.dwFlags = FLASHW_TRAY;
+ info.dwTimeout = 0;
+ info.uCount = 3;
+
+ FlashWindowEx(&info);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+bool WindowImplWin32::hasFocus() const
+{
+ return m_handle == GetForegroundWindow();
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::registerWindowClass()
+{
+ WNDCLASSW windowClass;
+ windowClass.style = 0;
+ windowClass.lpfnWndProc = &WindowImplWin32::globalOnEvent;
+ windowClass.cbClsExtra = 0;
+ windowClass.cbWndExtra = 0;
+ windowClass.hInstance = GetModuleHandleW(NULL);
+ windowClass.hIcon = NULL;
+ windowClass.hCursor = 0;
+ windowClass.hbrBackground = 0;
+ windowClass.lpszMenuName = NULL;
+ windowClass.lpszClassName = className;
+ RegisterClassW(&windowClass);
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::switchToFullscreen(const VideoMode& mode)
+{
+ DEVMODE devMode;
+ devMode.dmSize = sizeof(devMode);
+ devMode.dmPelsWidth = mode.width;
+ devMode.dmPelsHeight = mode.height;
+ devMode.dmBitsPerPel = mode.bitsPerPixel;
+ devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
+
+ // Apply fullscreen mode
+ if (ChangeDisplaySettingsW(&devMode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
+ {
+ err() << "Failed to change display mode for fullscreen" << std::endl;
+ return;
+ }
+
+ // Make the window flags compatible with fullscreen mode
+ SetWindowLongW(m_handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ SetWindowLongW(m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
+
+ // Resize the window so that it fits the entire screen
+ SetWindowPos(m_handle, HWND_TOP, 0, 0, mode.width, mode.height, SWP_FRAMECHANGED);
+ ShowWindow(m_handle, SW_SHOW);
+
+ // Set "this" as the current fullscreen window
+ fullscreenWindow = this;
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::cleanup()
+{
+ // Restore the previous video mode (in case we were running in fullscreen)
+ if (fullscreenWindow == this)
+ {
+ ChangeDisplaySettingsW(NULL, 0);
+ fullscreenWindow = NULL;
+ }
+
+ // Unhide the mouse cursor (in case it was hidden)
+ setMouseCursorVisible(true);
+
+ // No longer track the cursor
+ setTracking(false);
+
+ // No longer capture the cursor
+ ReleaseCapture();
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::setTracking(bool track)
+{
+ TRACKMOUSEEVENT mouseEvent;
+ mouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
+ mouseEvent.dwFlags = track ? TME_LEAVE : TME_CANCEL;
+ mouseEvent.hwndTrack = m_handle;
+ mouseEvent.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&mouseEvent);
+}
+
+
+////////////////////////////////////////////////////////////
+void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
+{
+ // Don't process any message until window is created
+ if (m_handle == NULL)
+ return;
+
+ switch (message)
+ {
+ // Destroy event
+ case WM_DESTROY:
+ {
+ // Here we must cleanup resources !
+ cleanup();
+ break;
+ }
+
+ // Set cursor event
+ case WM_SETCURSOR:
+ {
+ // The mouse has moved, if the cursor is in our window we must refresh the cursor
+ if (LOWORD(lParam) == HTCLIENT)
+ SetCursor(m_cursor);
+
+ break;
+ }
+
+ // Close event
+ case WM_CLOSE:
+ {
+ Event event;
+ event.type = Event::Closed;
+ pushEvent(event);
+ break;
+ }
+
+ // Resize event
+ case WM_SIZE:
+ {
+ // Consider only events triggered by a maximize or a un-maximize
+ if (wParam != SIZE_MINIMIZED && !m_resizing && m_lastSize != getSize())
+ {
+ // Update the last handled size
+ m_lastSize = getSize();
+
+ // Push a resize event
+ Event event;
+ event.type = Event::Resized;
+ event.size.width = m_lastSize.x;
+ event.size.height = m_lastSize.y;
+ pushEvent(event);
+ }
+ break;
+ }
+
+ // Start resizing
+ case WM_ENTERSIZEMOVE:
+ {
+ m_resizing = true;
+ break;
+ }
+
+ // Stop resizing
+ case WM_EXITSIZEMOVE:
+ {
+ m_resizing = false;
+
+ // Ignore cases where the window has only been moved
+ if(m_lastSize != getSize())
+ {
+ // Update the last handled size
+ m_lastSize = getSize();
+
+ // Push a resize event
+ Event event;
+ event.type = Event::Resized;
+ event.size.width = m_lastSize.x;
+ event.size.height = m_lastSize.y;
+ pushEvent(event);
+ }
+ break;
+ }
+
+ // The system request the min/max window size and position
+ case WM_GETMINMAXINFO:
+ {
+ // We override the returned information to remove the default limit
+ // (the OS doesn't allow windows bigger than the desktop by default)
+ MINMAXINFO* info = reinterpret_cast<MINMAXINFO*>(lParam);
+ info->ptMaxTrackSize.x = 50000;
+ info->ptMaxTrackSize.y = 50000;
+ break;
+ }
+
+ // Gain focus event
+ case WM_SETFOCUS:
+ {
+ Event event;
+ event.type = Event::GainedFocus;
+ pushEvent(event);
+ break;
+ }
+
+ // Lost focus event
+ case WM_KILLFOCUS:
+ {
+ Event event;
+ event.type = Event::LostFocus;
+ pushEvent(event);
+ break;
+ }
+
+ // Text event
+ case WM_CHAR:
+ {
+ if (m_keyRepeatEnabled || ((lParam & (1 << 30)) == 0))
+ {
+ // Get the code of the typed character
+ Uint32 character = static_cast<Uint32>(wParam);
+
+ // Check if it is the first part of a surrogate pair, or a regular character
+ if ((character >= 0xD800) && (character <= 0xDBFF))
+ {
+ // First part of a surrogate pair: store it and wait for the second one
+ m_surrogate = static_cast<Uint16>(character);
+ }
+ else
+ {
+ // Check if it is the second part of a surrogate pair, or a regular character
+ if ((character >= 0xDC00) && (character <= 0xDFFF))
+ {
+ // Convert the UTF-16 surrogate pair to a single UTF-32 value
+ Uint16 utf16[] = {m_surrogate, static_cast<Uint16>(character)};
+ sf::Utf16::toUtf32(utf16, utf16 + 2, &character);
+ m_surrogate = 0;
+ }
+
+ // Send a TextEntered event
+ Event event;
+ event.type = Event::TextEntered;
+ event.text.unicode = character;
+ pushEvent(event);
+ }
+ }
+ break;
+ }
+
+ // Keydown event
+ case WM_KEYDOWN:
+ case WM_SYSKEYDOWN:
+ {
+ if (m_keyRepeatEnabled || ((HIWORD(lParam) & KF_REPEAT) == 0))
+ {
+ Event event;
+ event.type = Event::KeyPressed;
+ event.key.alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
+ event.key.control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
+ event.key.shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
+ event.key.system = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
+ event.key.code = virtualKeyCodeToSF(wParam, lParam);
+ pushEvent(event);
+ }
+ break;
+ }
+
+ // Keyup event
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ {
+ Event event;
+ event.type = Event::KeyReleased;
+ event.key.alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
+ event.key.control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
+ event.key.shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
+ event.key.system = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
+ event.key.code = virtualKeyCodeToSF(wParam, lParam);
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse wheel event
+ case WM_MOUSEWHEEL:
+ {
+ // Mouse position is in screen coordinates, convert it to window coordinates
+ POINT position;
+ position.x = static_cast<Int16>(LOWORD(lParam));
+ position.y = static_cast<Int16>(HIWORD(lParam));
+ ScreenToClient(m_handle, &position);
+
+ Event event;
+ event.type = Event::MouseWheelMoved;
+ event.mouseWheel.delta = static_cast<Int16>(HIWORD(wParam)) / 120;
+ event.mouseWheel.x = position.x;
+ event.mouseWheel.y = position.y;
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse left button down event
+ case WM_LBUTTONDOWN:
+ {
+ Event event;
+ event.type = Event::MouseButtonPressed;
+ event.mouseButton.button = Mouse::Left;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse left button up event
+ case WM_LBUTTONUP:
+ {
+ Event event;
+ event.type = Event::MouseButtonReleased;
+ event.mouseButton.button = Mouse::Left;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse right button down event
+ case WM_RBUTTONDOWN:
+ {
+ Event event;
+ event.type = Event::MouseButtonPressed;
+ event.mouseButton.button = Mouse::Right;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse right button up event
+ case WM_RBUTTONUP:
+ {
+ Event event;
+ event.type = Event::MouseButtonReleased;
+ event.mouseButton.button = Mouse::Right;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse wheel button down event
+ case WM_MBUTTONDOWN:
+ {
+ Event event;
+ event.type = Event::MouseButtonPressed;
+ event.mouseButton.button = Mouse::Middle;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse wheel button up event
+ case WM_MBUTTONUP:
+ {
+ Event event;
+ event.type = Event::MouseButtonReleased;
+ event.mouseButton.button = Mouse::Middle;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse X button down event
+ case WM_XBUTTONDOWN:
+ {
+ Event event;
+ event.type = Event::MouseButtonPressed;
+ event.mouseButton.button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse X button up event
+ case WM_XBUTTONUP:
+ {
+ Event event;
+ event.type = Event::MouseButtonReleased;
+ event.mouseButton.button = HIWORD(wParam) == XBUTTON1 ? Mouse::XButton1 : Mouse::XButton2;
+ event.mouseButton.x = static_cast<Int16>(LOWORD(lParam));
+ event.mouseButton.y = static_cast<Int16>(HIWORD(lParam));
+ pushEvent(event);
+ break;
+ }
+
+ // Mouse leave event
+ case WM_MOUSELEAVE:
+ {
+ // Avoid this firing a second time in case the cursor is dragged outside
+ if (m_mouseInside)
+ {
+ m_mouseInside = false;
+
+ // Generate a MouseLeft event
+ Event event;
+ event.type = Event::MouseLeft;
+ pushEvent(event);
+ }
+ break;
+ }
+
+ // Mouse move event
+ case WM_MOUSEMOVE:
+ {
+ // Extract the mouse local coordinates
+ int x = static_cast<Int16>(LOWORD(lParam));
+ int y = static_cast<Int16>(HIWORD(lParam));
+
+ // Get the client area of the window
+ RECT area;
+ GetClientRect(m_handle, &area);
+
+ // Capture the mouse in case the user wants to drag it outside
+ if ((wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) == 0)
+ {
+ // Only release the capture if we really have it
+ if (GetCapture() == m_handle)
+ ReleaseCapture();
+ }
+ else if (GetCapture() != m_handle)
+ {
+ // Set the capture to continue receiving mouse events
+ SetCapture(m_handle);
+ }
+
+ // If the cursor is outside the client area...
+ if ((x < area.left) || (x > area.right) || (y < area.top) || (y > area.bottom))
+ {
+ // and it used to be inside, the mouse left it.
+ if (m_mouseInside)
+ {
+ m_mouseInside = false;
+
+ // No longer care for the mouse leaving the window
+ setTracking(false);
+
+ // Generate a MouseLeft event
+ Event event;
+ event.type = Event::MouseLeft;
+ pushEvent(event);
+ }
+ }
+ else
+ {
+ // and vice-versa
+ if (!m_mouseInside)
+ {
+ m_mouseInside = true;
+
+ // Look for the mouse leaving the window
+ setTracking(true);
+
+ // Generate a MouseEntered event
+ Event event;
+ event.type = Event::MouseEntered;
+ pushEvent(event);
+ }
+ }
+
+ // Generate a MouseMove event
+ Event event;
+ event.type = Event::MouseMoved;
+ event.mouseMove.x = x;
+ event.mouseMove.y = y;
+ pushEvent(event);
+ break;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+Keyboard::Key WindowImplWin32::virtualKeyCodeToSF(WPARAM key, LPARAM flags)
+{
+ switch (key)
+ {
+ // Check the scancode to distinguish between left and right shift
+ case VK_SHIFT:
+ {
+ static UINT lShift = MapVirtualKeyW(VK_LSHIFT, MAPVK_VK_TO_VSC);
+ UINT scancode = static_cast<UINT>((flags & (0xFF << 16)) >> 16);
+ return scancode == lShift ? Keyboard::LShift : Keyboard::RShift;
+ }
+
+ // Check the "extended" flag to distinguish between left and right alt
+ case VK_MENU : return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RAlt : Keyboard::LAlt;
+
+ // Check the "extended" flag to distinguish between left and right control
+ case VK_CONTROL : return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RControl : Keyboard::LControl;
+
+ // Other keys are reported properly
+ case VK_LWIN: return Keyboard::LSystem;
+ case VK_RWIN: return Keyboard::RSystem;
+ case VK_APPS: return Keyboard::Menu;
+ case VK_OEM_1: return Keyboard::SemiColon;
+ case VK_OEM_2: return Keyboard::Slash;
+ case VK_OEM_PLUS: return Keyboard::Equal;
+ case VK_OEM_MINUS: return Keyboard::Dash;
+ case VK_OEM_4: return Keyboard::LBracket;
+ case VK_OEM_6: return Keyboard::RBracket;
+ case VK_OEM_COMMA: return Keyboard::Comma;
+ case VK_OEM_PERIOD: return Keyboard::Period;
+ case VK_OEM_7: return Keyboard::Quote;
+ case VK_OEM_5: return Keyboard::BackSlash;
+ case VK_OEM_3: return Keyboard::Tilde;
+ case VK_ESCAPE: return Keyboard::Escape;
+ case VK_SPACE: return Keyboard::Space;
+ case VK_RETURN: return Keyboard::Return;
+ case VK_BACK: return Keyboard::BackSpace;
+ case VK_TAB: return Keyboard::Tab;
+ case VK_PRIOR: return Keyboard::PageUp;
+ case VK_NEXT: return Keyboard::PageDown;
+ case VK_END: return Keyboard::End;
+ case VK_HOME: return Keyboard::Home;
+ case VK_INSERT: return Keyboard::Insert;
+ case VK_DELETE: return Keyboard::Delete;
+ case VK_ADD: return Keyboard::Add;
+ case VK_SUBTRACT: return Keyboard::Subtract;
+ case VK_MULTIPLY: return Keyboard::Multiply;
+ case VK_DIVIDE: return Keyboard::Divide;
+ case VK_PAUSE: return Keyboard::Pause;
+ case VK_F1: return Keyboard::F1;
+ case VK_F2: return Keyboard::F2;
+ case VK_F3: return Keyboard::F3;
+ case VK_F4: return Keyboard::F4;
+ case VK_F5: return Keyboard::F5;
+ case VK_F6: return Keyboard::F6;
+ case VK_F7: return Keyboard::F7;
+ case VK_F8: return Keyboard::F8;
+ case VK_F9: return Keyboard::F9;
+ case VK_F10: return Keyboard::F10;
+ case VK_F11: return Keyboard::F11;
+ case VK_F12: return Keyboard::F12;
+ case VK_F13: return Keyboard::F13;
+ case VK_F14: return Keyboard::F14;
+ case VK_F15: return Keyboard::F15;
+ case VK_LEFT: return Keyboard::Left;
+ case VK_RIGHT: return Keyboard::Right;
+ case VK_UP: return Keyboard::Up;
+ case VK_DOWN: return Keyboard::Down;
+ case VK_NUMPAD0: return Keyboard::Numpad0;
+ case VK_NUMPAD1: return Keyboard::Numpad1;
+ case VK_NUMPAD2: return Keyboard::Numpad2;
+ case VK_NUMPAD3: return Keyboard::Numpad3;
+ case VK_NUMPAD4: return Keyboard::Numpad4;
+ case VK_NUMPAD5: return Keyboard::Numpad5;
+ case VK_NUMPAD6: return Keyboard::Numpad6;
+ case VK_NUMPAD7: return Keyboard::Numpad7;
+ case VK_NUMPAD8: return Keyboard::Numpad8;
+ case VK_NUMPAD9: return Keyboard::Numpad9;
+ case 'A': return Keyboard::A;
+ case 'Z': return Keyboard::Z;
+ case 'E': return Keyboard::E;
+ case 'R': return Keyboard::R;
+ case 'T': return Keyboard::T;
+ case 'Y': return Keyboard::Y;
+ case 'U': return Keyboard::U;
+ case 'I': return Keyboard::I;
+ case 'O': return Keyboard::O;
+ case 'P': return Keyboard::P;
+ case 'Q': return Keyboard::Q;
+ case 'S': return Keyboard::S;
+ case 'D': return Keyboard::D;
+ case 'F': return Keyboard::F;
+ case 'G': return Keyboard::G;
+ case 'H': return Keyboard::H;
+ case 'J': return Keyboard::J;
+ case 'K': return Keyboard::K;
+ case 'L': return Keyboard::L;
+ case 'M': return Keyboard::M;
+ case 'W': return Keyboard::W;
+ case 'X': return Keyboard::X;
+ case 'C': return Keyboard::C;
+ case 'V': return Keyboard::V;
+ case 'B': return Keyboard::B;
+ case 'N': return Keyboard::N;
+ case '0': return Keyboard::Num0;
+ case '1': return Keyboard::Num1;
+ case '2': return Keyboard::Num2;
+ case '3': return Keyboard::Num3;
+ case '4': return Keyboard::Num4;
+ case '5': return Keyboard::Num5;
+ case '6': return Keyboard::Num6;
+ case '7': return Keyboard::Num7;
+ case '8': return Keyboard::Num8;
+ case '9': return Keyboard::Num9;
+ }
+
+ return Keyboard::Unknown;
+}
+
+
+////////////////////////////////////////////////////////////
+LRESULT CALLBACK WindowImplWin32::globalOnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ // Associate handle and Window instance when the creation message is received
+ if (message == WM_CREATE)
+ {
+ // Get WindowImplWin32 instance (it was passed as the last argument of CreateWindow)
+ LONG_PTR window = (LONG_PTR)reinterpret_cast<CREATESTRUCT*>(lParam)->lpCreateParams;
+
+ // Set as the "user data" parameter of the window
+ SetWindowLongPtrW(handle, GWLP_USERDATA, window);
+ }
+
+ // Get the WindowImpl instance corresponding to the window handle
+ WindowImplWin32* window = handle ? reinterpret_cast<WindowImplWin32*>(GetWindowLongPtr(handle, GWLP_USERDATA)) : NULL;
+
+ // Forward the event to the appropriate function
+ if (window)
+ {
+ window->processEvent(message, wParam, lParam);
+
+ if (window->m_callback)
+ return CallWindowProcW(reinterpret_cast<WNDPROC>(window->m_callback), handle, message, wParam, lParam);
+ }
+
+ // We don't forward the WM_CLOSE message to prevent the OS from automatically destroying the window
+ if (message == WM_CLOSE)
+ return 0;
+
+ // Don't forward the menu system command, so that pressing ALT or F10 doesn't steal the focus
+ if ((message == WM_SYSCOMMAND) && (wParam == SC_KEYMENU))
+ return 0;
+
+ return DefWindowProcW(handle, message, wParam, lParam);
+}
+
+} // namespace priv
+
+} // namespace sf
+
diff --git a/src/SFML/Window/Win32/WindowImplWin32.hpp b/src/SFML/Window/Win32/WindowImplWin32.hpp
index a0ccc61..0bb3ce8 100644
--- a/src/SFML/Window/Win32/WindowImplWin32.hpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.hpp
@@ -1,248 +1,261 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2013 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_WINDOWIMPLWIN32_HPP
-#define SFML_WINDOWIMPLWIN32_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Window/Event.hpp>
-#include <SFML/Window/WindowImpl.hpp>
-#include <SFML/System/String.hpp>
-#include <windows.h>
-
-
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-/// \brief Windows implementation of WindowImpl
-///
-////////////////////////////////////////////////////////////
-class WindowImplWin32 : public WindowImpl
-{
-public :
-
- ////////////////////////////////////////////////////////////
- /// \brief Construct the window implementation from an existing control
- ///
- /// \param handle Platform-specific handle of the control
- ///
- ////////////////////////////////////////////////////////////
- WindowImplWin32(WindowHandle handle);
-
- ////////////////////////////////////////////////////////////
- /// \brief Create the window implementation
- ///
- /// \param mode Video mode to use
- /// \param title Title of the window
- /// \param style Window style
- /// \param settings Additional settings for the underlying OpenGL context
- ///
- ////////////////////////////////////////////////////////////
- WindowImplWin32(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings);
-
- ////////////////////////////////////////////////////////////
- /// \brief Destructor
- ///
- ////////////////////////////////////////////////////////////
- ~WindowImplWin32();
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the OS-specific handle of the window
- ///
- /// \return Handle of the window
- ///
- ////////////////////////////////////////////////////////////
- virtual WindowHandle getSystemHandle() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the position of the window
- ///
- /// \return Position of the window, in pixels
- ///
- ////////////////////////////////////////////////////////////
- virtual Vector2i getPosition() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Change the position of the window on screen
- ///
- /// \param position New position of the window, in pixels
- ///
- ////////////////////////////////////////////////////////////
- virtual void setPosition(const Vector2i& position);
-
- ////////////////////////////////////////////////////////////
- /// \brief Get the client size of the window
- ///
- /// \return Size of the window, in pixels
- ///
- ////////////////////////////////////////////////////////////
- virtual Vector2u getSize() const;
-
- ////////////////////////////////////////////////////////////
- /// \brief Change the size of the rendering region of the window
- ///
- /// \param size New size, in pixels
- ///
- ////////////////////////////////////////////////////////////
- virtual void setSize(const Vector2u& size);
-
- ////////////////////////////////////////////////////////////
- /// \brief Change the title of the window
- ///
- /// \param title New title
- ///
- ////////////////////////////////////////////////////////////
- virtual void setTitle(const String& title);
-
- ////////////////////////////////////////////////////////////
- /// \brief Change the window's icon
- ///
- /// \param width Icon's width, in pixels
- /// \param height Icon's height, in pixels
- /// \param pixels Pointer to the pixels in memory, format must be RGBA 32 bits
- ///
- ////////////////////////////////////////////////////////////
- virtual void setIcon(unsigned int width, unsigned int height, const Uint8* pixels);
-
- ////////////////////////////////////////////////////////////
- /// \brief Show or hide the window
- ///
- /// \param visible True to show, false to hide
- ///
- ////////////////////////////////////////////////////////////
- virtual void setVisible(bool visible);
-
- ////////////////////////////////////////////////////////////
- /// \brief Show or hide the mouse cursor
- ///
- /// \param visible True to show, false to hide
- ///
- ////////////////////////////////////////////////////////////
- virtual void setMouseCursorVisible(bool visible);
-
- ////////////////////////////////////////////////////////////
- /// \brief Enable or disable automatic key-repeat
- ///
- /// \param enabled True to enable, false to disable
- ///
- ////////////////////////////////////////////////////////////
- virtual void setKeyRepeatEnabled(bool enabled);
-
-protected:
-
- ////////////////////////////////////////////////////////////
- /// \brief Process incoming events from the operating system
- ///
- ////////////////////////////////////////////////////////////
- virtual void processEvents();
-
-private :
-
- ////////////////////////////////////////////////////////////
- /// Register the window class
- ///
- ////////////////////////////////////////////////////////////
- void registerWindowClass();
-
- ////////////////////////////////////////////////////////////
- /// \brief Switch to fullscreen mode
- ///
- /// \param mode Video mode to switch to
- ///
- ////////////////////////////////////////////////////////////
- void switchToFullscreen(const VideoMode& mode);
-
- ////////////////////////////////////////////////////////////
- /// \brief Free all the graphical resources attached to the window
- ///
- ////////////////////////////////////////////////////////////
- void cleanup();
-
- ////////////////////////////////////////////////////////////
- /// \brief Process a Win32 event
- ///
- /// \param message Message to process
- /// \param wParam First parameter of the event
- /// \param lParam Second parameter of the event
- ///
- ////////////////////////////////////////////////////////////
- void processEvent(UINT message, WPARAM wParam, LPARAM lParam);
-
- ////////////////////////////////////////////////////////////
- /// \brief Convert a Win32 virtual key code to a SFML key code
- ///
- /// \param key Virtual key code to convert
- /// \param flags Additional flags
- ///
- /// \return SFML key code corresponding to the key
- ///
- ////////////////////////////////////////////////////////////
- static Keyboard::Key virtualKeyCodeToSF(WPARAM key, LPARAM flags);
-
- ////////////////////////////////////////////////////////////
- /// \brief Check if the current version of the OS supports
- /// unicode messages and functions ; Windows 95/98/Me
- /// may not support it, whereas Windows NT/2000/XP/Vista
- /// will
- ///
- /// \return True if the OS supports unicode
- ///
- ////////////////////////////////////////////////////////////
- static bool hasUnicodeSupport();
-
- ////////////////////////////////////////////////////////////
- /// \brief Function called whenever one of our windows receives a message
- ///
- /// \param handle Win32 handle of the window
- /// \param message Message received
- /// \param wParam First parameter of the message
- /// \param lParam Second parameter of the message
- ///
- /// \return True to discard the event after it has been processed
- ///
- ////////////////////////////////////////////////////////////
- static LRESULT CALLBACK globalOnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam);
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- HWND m_handle; ///< Win32 handle of the window
- LONG_PTR m_callback; ///< Stores the original event callback function of the control
- HCURSOR m_cursor; ///< The system cursor to display into the window
- HICON m_icon; ///< Custom icon assigned to the window
- bool m_keyRepeatEnabled; ///< Automatic key-repeat state for keydown events
- Vector2u m_lastSize; ///< The last handled size of the window
- bool m_resizing; ///< Is the window being resized ?
- Uint16 m_surrogate; ///< First half of the surrogate pair, in case we're receiving a Unicode character in two events
-};
-
-} // namespace priv
-
-} // namespace sf
-
-#endif // SFML_WINDOWIMPLWIN32_HPP
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 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_WINDOWIMPLWIN32_HPP
+#define SFML_WINDOWIMPLWIN32_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Event.hpp>
+#include <SFML/Window/WindowImpl.hpp>
+#include <SFML/System/String.hpp>
+#include <windows.h>
+
+
+namespace sf
+{
+namespace priv
+{
+////////////////////////////////////////////////////////////
+/// \brief Windows implementation of WindowImpl
+///
+////////////////////////////////////////////////////////////
+class WindowImplWin32 : public WindowImpl
+{
+public:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Construct the window implementation from an existing control
+ ///
+ /// \param handle Platform-specific handle of the control
+ ///
+ ////////////////////////////////////////////////////////////
+ WindowImplWin32(WindowHandle handle);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create the window implementation
+ ///
+ /// \param mode Video mode to use
+ /// \param title Title of the window
+ /// \param style Window style
+ /// \param settings Additional settings for the underlying OpenGL context
+ ///
+ ////////////////////////////////////////////////////////////
+ WindowImplWin32(VideoMode mode, const String& title, Uint32 style, const ContextSettings& settings);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Destructor
+ ///
+ ////////////////////////////////////////////////////////////
+ ~WindowImplWin32();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the OS-specific handle of the window
+ ///
+ /// \return Handle of the window
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual WindowHandle getSystemHandle() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the position of the window
+ ///
+ /// \return Position of the window, in pixels
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual Vector2i getPosition() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Change the position of the window on screen
+ ///
+ /// \param position New position of the window, in pixels
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setPosition(const Vector2i& position);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Get the client size of the window
+ ///
+ /// \return Size of the window, in pixels
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual Vector2u getSize() const;
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Change the size of the rendering region of the window
+ ///
+ /// \param size New size, in pixels
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setSize(const Vector2u& size);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Change the title of the window
+ ///
+ /// \param title New title
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setTitle(const String& title);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Change the window's icon
+ ///
+ /// \param width Icon's width, in pixels
+ /// \param height Icon's height, in pixels
+ /// \param pixels Pointer to the pixels in memory, format must be RGBA 32 bits
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setIcon(unsigned int width, unsigned int height, const Uint8* pixels);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Show or hide the window
+ ///
+ /// \param visible True to show, false to hide
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setVisible(bool visible);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Show or hide the mouse cursor
+ ///
+ /// \param visible True to show, false to hide
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setMouseCursorVisible(bool visible);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Enable or disable automatic key-repeat
+ ///
+ /// \param enabled True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setKeyRepeatEnabled(bool enabled);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Request the current window to be made the active
+ /// foreground window
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void requestFocus();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Check whether the window has the input focus
+ ///
+ /// \return True if window has focus, false otherwise
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual bool hasFocus() const;
+
+protected:
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Process incoming events from the operating system
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void processEvents();
+
+private:
+
+ ////////////////////////////////////////////////////////////
+ /// Register the window class
+ ///
+ ////////////////////////////////////////////////////////////
+ void registerWindowClass();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Switch to fullscreen mode
+ ///
+ /// \param mode Video mode to switch to
+ ///
+ ////////////////////////////////////////////////////////////
+ void switchToFullscreen(const VideoMode& mode);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Free all the graphical resources attached to the window
+ ///
+ ////////////////////////////////////////////////////////////
+ void cleanup();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Process a Win32 event
+ ///
+ /// \param message Message to process
+ /// \param wParam First parameter of the event
+ /// \param lParam Second parameter of the event
+ ///
+ ////////////////////////////////////////////////////////////
+ void processEvent(UINT message, WPARAM wParam, LPARAM lParam);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Enables or disables tracking for the mouse cursor leaving the window
+ ///
+ /// \param track True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ void setTracking(bool track);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Convert a Win32 virtual key code to a SFML key code
+ ///
+ /// \param key Virtual key code to convert
+ /// \param flags Additional flags
+ ///
+ /// \return SFML key code corresponding to the key
+ ///
+ ////////////////////////////////////////////////////////////
+ static Keyboard::Key virtualKeyCodeToSF(WPARAM key, LPARAM flags);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Function called whenever one of our windows receives a message
+ ///
+ /// \param handle Win32 handle of the window
+ /// \param message Message received
+ /// \param wParam First parameter of the message
+ /// \param lParam Second parameter of the message
+ ///
+ /// \return True to discard the event after it has been processed
+ ///
+ ////////////////////////////////////////////////////////////
+ static LRESULT CALLBACK globalOnEvent(HWND handle, UINT message, WPARAM wParam, LPARAM lParam);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ HWND m_handle; ///< Win32 handle of the window
+ LONG_PTR m_callback; ///< Stores the original event callback function of the control
+ HCURSOR m_cursor; ///< The system cursor to display into the window
+ HICON m_icon; ///< Custom icon assigned to the window
+ bool m_keyRepeatEnabled; ///< Automatic key-repeat state for keydown events
+ Vector2u m_lastSize; ///< The last handled size of the window
+ bool m_resizing; ///< Is the window being resized?
+ Uint16 m_surrogate; ///< First half of the surrogate pair, in case we're receiving a Unicode character in two events
+ bool m_mouseInside; ///< Mouse is inside the window?
+};
+
+} // namespace priv
+
+} // namespace sf
+
+#endif // SFML_WINDOWIMPLWIN32_HPP