summaryrefslogtreecommitdiff
path: root/src/SFML/Window
diff options
context:
space:
mode:
authorJames Cowgill <jcowgill@debian.org>2016-08-09 15:20:03 +0000
committerJames Cowgill <jcowgill@debian.org>2016-08-09 15:20:03 +0000
commitdf93e238e30e97850d76ad5585b8ab9ad9c03e67 (patch)
tree2ae5f3305e1ee1882f563d2803f94aa6446dc367 /src/SFML/Window
parent301fd78b3ac87cf1fbce9d2c955db89094a304a5 (diff)
Imported Upstream version 2.4.0+dfsg
Diffstat (limited to 'src/SFML/Window')
-rw-r--r--src/SFML/Window/Android/InputImpl.cpp1
-rw-r--r--src/SFML/Window/Android/SensorImpl.cpp2
-rw-r--r--src/SFML/Window/Android/SensorImpl.hpp2
-rw-r--r--src/SFML/Window/Android/WindowImplAndroid.cpp15
-rw-r--r--src/SFML/Window/Android/WindowImplAndroid.hpp8
-rw-r--r--src/SFML/Window/CMakeLists.txt9
-rw-r--r--src/SFML/Window/Context.cpp110
-rw-r--r--src/SFML/Window/EglContext.cpp25
-rw-r--r--src/SFML/Window/EglContext.hpp5
-rw-r--r--src/SFML/Window/FreeBSD/JoystickImpl.cpp2
-rw-r--r--src/SFML/Window/FreeBSD/JoystickImpl.hpp2
-rw-r--r--src/SFML/Window/GlContext.cpp72
-rw-r--r--src/SFML/Window/GlContext.hpp8
-rw-r--r--src/SFML/Window/GlResource.cpp2
-rw-r--r--src/SFML/Window/InputImpl.hpp2
-rw-r--r--src/SFML/Window/Joystick.cpp2
-rw-r--r--src/SFML/Window/JoystickImpl.hpp2
-rw-r--r--src/SFML/Window/JoystickManager.cpp2
-rw-r--r--src/SFML/Window/JoystickManager.hpp2
-rw-r--r--src/SFML/Window/Keyboard.cpp2
-rw-r--r--src/SFML/Window/Mouse.cpp2
-rw-r--r--src/SFML/Window/OSX/AutoreleasePoolWrapper.h22
-rw-r--r--src/SFML/Window/OSX/AutoreleasePoolWrapper.mm168
-rw-r--r--src/SFML/Window/OSX/HIDInputManager.hpp2
-rw-r--r--src/SFML/Window/OSX/HIDInputManager.mm6
-rw-r--r--src/SFML/Window/OSX/HIDJoystickManager.cpp6
-rw-r--r--src/SFML/Window/OSX/HIDJoystickManager.hpp2
-rw-r--r--src/SFML/Window/OSX/InputImpl.hpp2
-rw-r--r--src/SFML/Window/OSX/InputImpl.mm4
-rw-r--r--src/SFML/Window/OSX/JoystickImpl.cpp2
-rw-r--r--src/SFML/Window/OSX/JoystickImpl.hpp2
-rw-r--r--src/SFML/Window/OSX/NSImage+raw.h52
-rw-r--r--src/SFML/Window/OSX/NSImage+raw.mm68
-rw-r--r--src/SFML/Window/OSX/SFApplication.h2
-rw-r--r--src/SFML/Window/OSX/SFApplication.m2
-rw-r--r--src/SFML/Window/OSX/SFApplicationDelegate.h2
-rw-r--r--src/SFML/Window/OSX/SFApplicationDelegate.m2
-rw-r--r--src/SFML/Window/OSX/SFContext.hpp2
-rw-r--r--src/SFML/Window/OSX/SFContext.mm13
-rw-r--r--src/SFML/Window/OSX/SFKeyboardModifiersHelper.h2
-rw-r--r--src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm2
-rw-r--r--src/SFML/Window/OSX/SFOpenGLView+keyboard.mm220
-rw-r--r--src/SFML/Window/OSX/SFOpenGLView+keyboard_priv.h68
-rw-r--r--src/SFML/Window/OSX/SFOpenGLView+mouse.mm402
-rw-r--r--src/SFML/Window/OSX/SFOpenGLView+mouse_priv.h110
-rw-r--r--src/SFML/Window/OSX/SFOpenGLView.h65
-rw-r--r--src/SFML/Window/OSX/SFOpenGLView.mm507
-rw-r--r--src/SFML/Window/OSX/SFSilentResponder.h2
-rw-r--r--src/SFML/Window/OSX/SFSilentResponder.m2
-rw-r--r--src/SFML/Window/OSX/SFViewController.h2
-rw-r--r--src/SFML/Window/OSX/SFViewController.mm9
-rw-r--r--src/SFML/Window/OSX/SFWindow.h2
-rw-r--r--src/SFML/Window/OSX/SFWindow.m2
-rw-r--r--src/SFML/Window/OSX/SFWindowController.h9
-rw-r--r--src/SFML/Window/OSX/SFWindowController.mm181
-rw-r--r--src/SFML/Window/OSX/Scaling.h103
-rw-r--r--src/SFML/Window/OSX/SensorImpl.cpp2
-rw-r--r--src/SFML/Window/OSX/SensorImpl.hpp2
-rw-r--r--src/SFML/Window/OSX/VideoModeImpl.cpp25
-rw-r--r--src/SFML/Window/OSX/WindowImplCocoa.hpp10
-rw-r--r--src/SFML/Window/OSX/WindowImplCocoa.mm92
-rw-r--r--src/SFML/Window/OSX/WindowImplDelegateProtocol.h10
-rw-r--r--src/SFML/Window/OSX/cg_sf_conversion.hpp2
-rw-r--r--src/SFML/Window/OSX/cg_sf_conversion.mm (renamed from src/SFML/Window/OSX/cg_sf_conversion.cpp)63
-rw-r--r--src/SFML/Window/OSX/cpp_objc_conversion.h2
-rw-r--r--src/SFML/Window/OSX/cpp_objc_conversion.mm2
-rw-r--r--src/SFML/Window/Sensor.cpp2
-rw-r--r--src/SFML/Window/SensorImpl.hpp2
-rw-r--r--src/SFML/Window/SensorManager.cpp2
-rw-r--r--src/SFML/Window/SensorManager.hpp2
-rw-r--r--src/SFML/Window/Touch.cpp2
-rw-r--r--src/SFML/Window/Unix/Display.cpp2
-rw-r--r--src/SFML/Window/Unix/Display.hpp2
-rw-r--r--src/SFML/Window/Unix/GlxContext.cpp451
-rw-r--r--src/SFML/Window/Unix/GlxContext.hpp40
-rw-r--r--src/SFML/Window/Unix/GlxExtensions.cpp135
-rw-r--r--src/SFML/Window/Unix/GlxExtensions.hpp89
-rw-r--r--src/SFML/Window/Unix/GlxExtensions.txt9
-rw-r--r--src/SFML/Window/Unix/InputImpl.cpp2
-rw-r--r--src/SFML/Window/Unix/InputImpl.hpp2
-rw-r--r--src/SFML/Window/Unix/JoystickImpl.cpp38
-rw-r--r--src/SFML/Window/Unix/JoystickImpl.hpp8
-rw-r--r--src/SFML/Window/Unix/ScopedXcbPtr.hpp2
-rw-r--r--src/SFML/Window/Unix/ScopedXcbPtr.inl2
-rw-r--r--src/SFML/Window/Unix/SensorImpl.cpp2
-rw-r--r--src/SFML/Window/Unix/SensorImpl.hpp2
-rw-r--r--src/SFML/Window/Unix/VideoModeImpl.cpp2
-rw-r--r--src/SFML/Window/Unix/WindowImplX11.cpp224
-rw-r--r--src/SFML/Window/Unix/WindowImplX11.hpp16
-rw-r--r--src/SFML/Window/VideoMode.cpp2
-rw-r--r--src/SFML/Window/VideoModeImpl.hpp2
-rw-r--r--src/SFML/Window/Win32/InputImpl.cpp2
-rw-r--r--src/SFML/Window/Win32/InputImpl.hpp2
-rw-r--r--src/SFML/Window/Win32/JoystickImpl.cpp2
-rw-r--r--src/SFML/Window/Win32/JoystickImpl.hpp2
-rw-r--r--src/SFML/Window/Win32/SensorImpl.cpp2
-rw-r--r--src/SFML/Window/Win32/SensorImpl.hpp2
-rw-r--r--src/SFML/Window/Win32/VideoModeImpl.cpp2
-rw-r--r--src/SFML/Window/Win32/WglContext.cpp290
-rw-r--r--src/SFML/Window/Win32/WglContext.hpp57
-rw-r--r--src/SFML/Window/Win32/WglExtensions.cpp153
-rw-r--r--src/SFML/Window/Win32/WglExtensions.hpp58
-rw-r--r--src/SFML/Window/Win32/WglExtensions.txt7
-rw-r--r--src/SFML/Window/Win32/WindowImplWin32.cpp56
-rw-r--r--src/SFML/Window/Win32/WindowImplWin32.hpp25
-rw-r--r--src/SFML/Window/Window.cpp10
-rw-r--r--src/SFML/Window/WindowImpl.cpp2
-rw-r--r--src/SFML/Window/WindowImpl.hpp10
-rw-r--r--src/SFML/Window/iOS/EaglContext.hpp2
-rw-r--r--src/SFML/Window/iOS/EaglContext.mm2
-rw-r--r--src/SFML/Window/iOS/InputImpl.hpp2
-rw-r--r--src/SFML/Window/iOS/InputImpl.mm2
-rw-r--r--src/SFML/Window/iOS/JoystickImpl.hpp2
-rw-r--r--src/SFML/Window/iOS/JoystickImpl.mm2
-rw-r--r--src/SFML/Window/iOS/ObjCType.hpp2
-rw-r--r--src/SFML/Window/iOS/SFAppDelegate.hpp2
-rw-r--r--src/SFML/Window/iOS/SFAppDelegate.mm2
-rw-r--r--src/SFML/Window/iOS/SFMain.hpp2
-rw-r--r--src/SFML/Window/iOS/SFMain.mm2
-rw-r--r--src/SFML/Window/iOS/SFView.hpp2
-rw-r--r--src/SFML/Window/iOS/SFView.mm2
-rw-r--r--src/SFML/Window/iOS/SFViewController.hpp2
-rw-r--r--src/SFML/Window/iOS/SFViewController.mm2
-rw-r--r--src/SFML/Window/iOS/SensorImpl.hpp2
-rw-r--r--src/SFML/Window/iOS/SensorImpl.mm2
-rw-r--r--src/SFML/Window/iOS/VideoModeImpl.mm2
-rw-r--r--src/SFML/Window/iOS/WindowImplUIKit.hpp10
-rw-r--r--src/SFML/Window/iOS/WindowImplUIKit.mm9
128 files changed, 2908 insertions, 1405 deletions
diff --git a/src/SFML/Window/Android/InputImpl.cpp b/src/SFML/Window/Android/InputImpl.cpp
index 8940b9e..9da3a13 100644
--- a/src/SFML/Window/Android/InputImpl.cpp
+++ b/src/SFML/Window/Android/InputImpl.cpp
@@ -125,7 +125,6 @@ void InputImpl::setVirtualKeyboardVisible(bool visible)
MethodHideSoftInput, lBinder, lFlags);
lJNIEnv->DeleteLocalRef(lBinder);
}
- lJNIEnv->DeleteLocalRef(lNativeActivity);
lJNIEnv->DeleteLocalRef(ClassNativeActivity);
lJNIEnv->DeleteLocalRef(ClassInputMethodManager);
lJNIEnv->DeleteLocalRef(lDecorView);
diff --git a/src/SFML/Window/Android/SensorImpl.cpp b/src/SFML/Window/Android/SensorImpl.cpp
index 2b691a1..756833f 100644
--- a/src/SFML/Window/Android/SensorImpl.cpp
+++ b/src/SFML/Window/Android/SensorImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Android/SensorImpl.hpp b/src/SFML/Window/Android/SensorImpl.hpp
index 0b34997..0adb44d 100644
--- a/src/SFML/Window/Android/SensorImpl.hpp
+++ b/src/SFML/Window/Android/SensorImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Android/WindowImplAndroid.cpp b/src/SFML/Window/Android/WindowImplAndroid.cpp
index fb1906b..27d2f10 100644
--- a/src/SFML/Window/Android/WindowImplAndroid.cpp
+++ b/src/SFML/Window/Android/WindowImplAndroid.cpp
@@ -179,6 +179,13 @@ void WindowImplAndroid::setMouseCursorVisible(bool visible)
////////////////////////////////////////////////////////////
+void WindowImplAndroid::setMouseCursorGrabbed(bool grabbed)
+{
+ // Not applicable
+}
+
+
+////////////////////////////////////////////////////////////
void WindowImplAndroid::setKeyRepeatEnabled(bool enabled)
{
// Not applicable
@@ -433,7 +440,7 @@ int WindowImplAndroid::processMotionEvent(AInputEvent* _event, ActivityStates* s
if (device == AINPUT_SOURCE_MOUSE)
event.type = Event::MouseMoved;
- else if (device == AINPUT_SOURCE_TOUCHSCREEN)
+ else if (device & AINPUT_SOURCE_TOUCHSCREEN)
event.type = Event::TouchMoved;
int pointerCount = AMotionEvent_getPointerCount(_event);
@@ -452,7 +459,7 @@ int WindowImplAndroid::processMotionEvent(AInputEvent* _event, ActivityStates* s
states->mousePosition = Vector2i(event.mouseMove.x, event.mouseMove.y);
}
- else if (device == AINPUT_SOURCE_TOUCHSCREEN)
+ else if (device & AINPUT_SOURCE_TOUCHSCREEN)
{
if (states->touchEvents[id].x == x && states->touchEvents[id].y == y)
continue;
@@ -496,7 +503,7 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Act
if (id >= 0 && id < Mouse::ButtonCount)
states->isButtonPressed[id] = true;
}
- else if (device == AINPUT_SOURCE_TOUCHSCREEN)
+ else if (device & AINPUT_SOURCE_TOUCHSCREEN)
{
event.type = Event::TouchBegan;
event.touch.finger = id;
@@ -518,7 +525,7 @@ int WindowImplAndroid::processPointerEvent(bool isDown, AInputEvent* _event, Act
if (id >= 0 && id < Mouse::ButtonCount)
states->isButtonPressed[id] = false;
}
- else if (device == AINPUT_SOURCE_TOUCHSCREEN)
+ else if (device & AINPUT_SOURCE_TOUCHSCREEN)
{
event.type = Event::TouchEnded;
event.touch.finger = id;
diff --git a/src/SFML/Window/Android/WindowImplAndroid.hpp b/src/SFML/Window/Android/WindowImplAndroid.hpp
index fb05b35..88250d4 100644
--- a/src/SFML/Window/Android/WindowImplAndroid.hpp
+++ b/src/SFML/Window/Android/WindowImplAndroid.hpp
@@ -147,6 +147,14 @@ public:
virtual void setMouseCursorVisible(bool visible);
////////////////////////////////////////////////////////////
+ /// \brief Clips or releases the mouse cursor
+ ///
+ /// \param grabbed True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setMouseCursorGrabbed(bool grabbed);
+
+ ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat
///
/// \param enabled True to enable, false to disable
diff --git a/src/SFML/Window/CMakeLists.txt b/src/SFML/Window/CMakeLists.txt
index 386c077..231dee8 100644
--- a/src/SFML/Window/CMakeLists.txt
+++ b/src/SFML/Window/CMakeLists.txt
@@ -111,7 +111,7 @@ elseif(SFML_OS_MACOSX)
${SRCROOT}/OSX/cpp_objc_conversion.h
${SRCROOT}/OSX/cpp_objc_conversion.mm
${SRCROOT}/OSX/cg_sf_conversion.hpp
- ${SRCROOT}/OSX/cg_sf_conversion.cpp
+ ${SRCROOT}/OSX/cg_sf_conversion.mm
${SRCROOT}/OSX/InputImpl.mm
${SRCROOT}/OSX/InputImpl.hpp
${SRCROOT}/OSX/HIDInputManager.hpp
@@ -120,6 +120,9 @@ elseif(SFML_OS_MACOSX)
${SRCROOT}/OSX/HIDJoystickManager.cpp
${SRCROOT}/OSX/JoystickImpl.cpp
${SRCROOT}/OSX/JoystickImpl.hpp
+ ${SRCROOT}/OSX/NSImage+raw.h
+ ${SRCROOT}/OSX/NSImage+raw.mm
+ ${SRCROOT}/OSX/Scaling.h
${SRCROOT}/OSX/SensorImpl.cpp
${SRCROOT}/OSX/SensorImpl.hpp
${SRCROOT}/OSX/SFApplication.h
@@ -132,6 +135,10 @@ elseif(SFML_OS_MACOSX)
${SRCROOT}/OSX/SFKeyboardModifiersHelper.mm
${SRCROOT}/OSX/SFOpenGLView.h
${SRCROOT}/OSX/SFOpenGLView.mm
+ ${SRCROOT}/OSX/SFOpenGLView+keyboard.mm
+ ${SRCROOT}/OSX/SFOpenGLView+keyboard_priv.h
+ ${SRCROOT}/OSX/SFOpenGLView+mouse.mm
+ ${SRCROOT}/OSX/SFOpenGLView+mouse_priv.h
${SRCROOT}/OSX/SFSilentResponder.h
${SRCROOT}/OSX/SFSilentResponder.m
${SRCROOT}/OSX/SFWindow.h
diff --git a/src/SFML/Window/Context.cpp b/src/SFML/Window/Context.cpp
index 0ec500a..2d51bbc 100644
--- a/src/SFML/Window/Context.cpp
+++ b/src/SFML/Window/Context.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -27,7 +27,32 @@
////////////////////////////////////////////////////////////
#include <SFML/Window/Context.hpp>
#include <SFML/Window/GlContext.hpp>
+#include <SFML/System/ThreadLocalPtr.hpp>
+#include <SFML/OpenGL.hpp>
+#include <algorithm>
+#include <vector>
+#include <string>
+#if defined(SFML_SYSTEM_WINDOWS)
+
+ typedef const GLubyte* (APIENTRY *glGetStringiFuncType)(GLenum, GLuint);
+
+#else
+
+ typedef const GLubyte* (*glGetStringiFuncType)(GLenum, GLuint);
+
+#endif
+
+#if !defined(GL_NUM_EXTENSIONS)
+ #define GL_NUM_EXTENSIONS 0x821D
+#endif
+
+
+namespace
+{
+ // This per-thread variable holds the current context for each thread
+ sf::ThreadLocalPtr<sf::Context> currentContext(NULL);
+}
namespace sf
{
@@ -42,6 +67,7 @@ Context::Context()
////////////////////////////////////////////////////////////
Context::~Context()
{
+ setActive(false);
delete m_context;
}
@@ -49,7 +75,26 @@ Context::~Context()
////////////////////////////////////////////////////////////
bool Context::setActive(bool active)
{
- return m_context->setActive(active);
+ bool result = m_context->setActive(active);
+
+ if (result)
+ currentContext = (active ? this : NULL);
+
+ return result;
+}
+
+
+////////////////////////////////////////////////////////////
+const ContextSettings& Context::getSettings() const
+{
+ return m_context->getSettings();
+}
+
+
+////////////////////////////////////////////////////////////
+const Context* Context::getActiveContext()
+{
+ return currentContext;
}
@@ -61,6 +106,67 @@ GlFunctionPointer Context::getFunction(const char* name)
////////////////////////////////////////////////////////////
+bool Context::isExtensionAvailable(const char* name)
+{
+ static std::vector<std::string> extensions;
+ static bool loaded = false;
+
+ if (!loaded)
+ {
+ const Context* context = getActiveContext();
+
+ if (!context)
+ return false;
+
+ const char* extensionString = NULL;
+
+ if(context->getSettings().majorVersion < 3)
+ {
+ // Try to load the < 3.0 way
+ extensionString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
+
+ do
+ {
+ const char* extension = extensionString;
+
+ while(*extensionString && (*extensionString != ' '))
+ extensionString++;
+
+ extensions.push_back(std::string(extension, extensionString));
+ }
+ while (*extensionString++);
+ }
+ else
+ {
+ // Try to load the >= 3.0 way
+ glGetStringiFuncType glGetStringiFunc = NULL;
+ glGetStringiFunc = reinterpret_cast<glGetStringiFuncType>(getFunction("glGetStringi"));
+
+ if (glGetStringiFunc)
+ {
+ int numExtensions = 0;
+ glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions);
+
+ if (numExtensions)
+ {
+ for (unsigned int i = 0; i < static_cast<unsigned int>(numExtensions); ++i)
+ {
+ extensionString = reinterpret_cast<const char*>(glGetStringiFunc(GL_EXTENSIONS, i));
+
+ extensions.push_back(extensionString);
+ }
+ }
+ }
+ }
+
+ loaded = true;
+ }
+
+ return std::find(extensions.begin(), extensions.end(), name) != extensions.end();
+}
+
+
+////////////////////////////////////////////////////////////
Context::Context(const ContextSettings& settings, unsigned int width, unsigned int height)
{
m_context = priv::GlContext::create(settings, width, height);
diff --git a/src/SFML/Window/EglContext.cpp b/src/SFML/Window/EglContext.cpp
index ed7d294..f6686f1 100644
--- a/src/SFML/Window/EglContext.cpp
+++ b/src/SFML/Window/EglContext.cpp
@@ -85,6 +85,7 @@ m_config (NULL)
// Get the best EGL config matching the default video settings
m_config = getBestConfig(m_display, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
+ updateSettings();
// Note: The EGL specs say that attrib_list can be NULL when passed to eglCreatePbufferSurface,
// but this is resulting in a segfault. Bug in Android?
@@ -123,6 +124,7 @@ m_config (NULL)
// Get the best EGL config matching the requested video settings
m_config = getBestConfig(m_display, bitsPerPixel, settings);
+ updateSettings();
// Create EGL context
createContext(shared);
@@ -250,10 +252,33 @@ EGLConfig EglContext::getBestConfig(EGLDisplay display, unsigned int bitsPerPixe
// Ask EGL for the best config matching our video settings
eglCheck(eglChooseConfig(display, attributes, configs, 1, &configCount));
+ // TODO: This should check EGL_CONFORMANT and pick the first conformant configuration.
+
return configs[0];
}
+////////////////////////////////////////////////////////////
+void EglContext::updateSettings()
+{
+ EGLint tmp;
+
+ // Update the internal context settings with the current config
+ eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_DEPTH_SIZE, &tmp));
+ m_settings.depthBits = tmp;
+
+ eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_STENCIL_SIZE, &tmp));
+ m_settings.stencilBits = tmp;
+
+ eglCheck(eglGetConfigAttrib(m_display, m_config, EGL_SAMPLES, &tmp));
+ m_settings.antialiasingLevel = tmp;
+
+ m_settings.majorVersion = 1;
+ m_settings.minorVersion = 1;
+ m_settings.attributeFlags = ContextSettings::Default;
+}
+
+
#ifdef SFML_SYSTEM_LINUX
////////////////////////////////////////////////////////////
XVisualInfo EglContext::selectBestVisual(::Display* XDisplay, unsigned int bitsPerPixel, const ContextSettings& settings)
diff --git a/src/SFML/Window/EglContext.hpp b/src/SFML/Window/EglContext.hpp
index ef30cb4..6df6a53 100644
--- a/src/SFML/Window/EglContext.hpp
+++ b/src/SFML/Window/EglContext.hpp
@@ -166,6 +166,11 @@ public:
private:
////////////////////////////////////////////////////////////
+ /// \brief Helper to copy the picked EGL configuration
+ ////////////////////////////////////////////////////////////
+ void updateSettings();
+
+ ////////////////////////////////////////////////////////////
// Member data
////////////////////////////////////////////////////////////
EGLDisplay m_display; ///< The internal EGL display
diff --git a/src/SFML/Window/FreeBSD/JoystickImpl.cpp b/src/SFML/Window/FreeBSD/JoystickImpl.cpp
index ff21293..4409893 100644
--- a/src/SFML/Window/FreeBSD/JoystickImpl.cpp
+++ b/src/SFML/Window/FreeBSD/JoystickImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
// 2013-2013 David Demelier (demelier.david@gmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/FreeBSD/JoystickImpl.hpp b/src/SFML/Window/FreeBSD/JoystickImpl.hpp
index b52307c..f861815 100644
--- a/src/SFML/Window/FreeBSD/JoystickImpl.hpp
+++ b/src/SFML/Window/FreeBSD/JoystickImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/GlContext.cpp b/src/SFML/Window/GlContext.cpp
index 1a66774..b74725e 100644
--- a/src/SFML/Window/GlContext.cpp
+++ b/src/SFML/Window/GlContext.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -100,6 +100,10 @@
#define GL_CONTEXT_FLAGS 0x821E
#endif
+#if !defined(GL_FRAMEBUFFER_SRGB)
+ #define GL_FRAMEBUFFER_SRGB 0x8DB9
+#endif
+
#if !defined(GL_CONTEXT_FLAG_DEBUG_BIT)
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
#endif
@@ -131,8 +135,8 @@ namespace
ContextType* sharedContext = NULL;
// Internal contexts
- sf::ThreadLocalPtr<sf::priv::GlContext> internalContext(NULL);
- std::set<sf::priv::GlContext*> internalContexts;
+ sf::ThreadLocalPtr<sf::Context> internalContext(NULL);
+ std::set<sf::Context*> internalContexts;
sf::Mutex internalContextsMutex;
// Check if the internal context of the current thread is valid
@@ -148,11 +152,11 @@ namespace
}
// Retrieve the internal context for the current thread
- sf::priv::GlContext* getInternalContext()
+ sf::Context* getInternalContext()
{
if (!hasInternalContext())
{
- internalContext = sf::priv::GlContext::create();
+ internalContext = new sf::Context;
sf::Lock lock(internalContextsMutex);
internalContexts.insert(internalContext);
}
@@ -171,9 +175,12 @@ void GlContext::globalInit()
{
Lock lock(mutex);
+ if (sharedContext)
+ return;
+
// Create the shared context
sharedContext = new ContextType(NULL);
- sharedContext->initialize();
+ sharedContext->initialize(ContextSettings());
// This call makes sure that:
// - the shared context is inactive (it must never be)
@@ -187,13 +194,16 @@ void GlContext::globalCleanup()
{
Lock lock(mutex);
+ if (!sharedContext)
+ return;
+
// Destroy the shared context
delete sharedContext;
sharedContext = NULL;
// Destroy the internal contexts
Lock internalContextsLock(internalContextsMutex);
- for (std::set<GlContext*>::iterator it = internalContexts.begin(); it != internalContexts.end(); ++it)
+ for (std::set<Context*>::iterator it = internalContexts.begin(); it != internalContexts.end(); ++it)
delete *it;
internalContexts.clear();
}
@@ -215,7 +225,7 @@ GlContext* GlContext::create()
// Create the context
GlContext* context = new ContextType(sharedContext);
- context->initialize();
+ context->initialize(ContextSettings());
return context;
}
@@ -231,7 +241,7 @@ GlContext* GlContext::create(const ContextSettings& settings, const WindowImpl*
// Create the context
GlContext* context = new ContextType(sharedContext, settings, owner, bitsPerPixel);
- context->initialize();
+ context->initialize(settings);
context->checkSettings(settings);
return context;
@@ -248,7 +258,7 @@ GlContext* GlContext::create(const ContextSettings& settings, unsigned int width
// Create the context
GlContext* context = new ContextType(sharedContext, settings, width, height);
- context->initialize();
+ context->initialize(settings);
context->checkSettings(settings);
return context;
@@ -340,7 +350,7 @@ GlContext::GlContext()
////////////////////////////////////////////////////////////
-int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated)
+int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated, bool sRgb)
{
int colorDiff = static_cast<int>(bitsPerPixel) - colorBits;
int depthDiff = static_cast<int>(settings.depthBits) - depthBits;
@@ -356,6 +366,10 @@ int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings&
// Aggregate the scores
int score = std::abs(colorDiff) + std::abs(depthDiff) + std::abs(stencilDiff) + std::abs(antialiasingDiff);
+ // If the user wants an sRGB capable format, try really hard to get one
+ if (settings.sRgbCapable && !sRgb)
+ score += 10000000;
+
// Make sure we prefer hardware acceleration over features
if (!accelerated)
score += 100000000;
@@ -365,7 +379,7 @@ int GlContext::evaluateFormat(unsigned int bitsPerPixel, const ContextSettings&
////////////////////////////////////////////////////////////
-void GlContext::initialize()
+void GlContext::initialize(const ContextSettings& requestedSettings)
{
// Activate the context
setActive(true);
@@ -462,9 +476,32 @@ void GlContext::initialize()
}
}
- // Enable antialiasing if needed
- if (m_settings.antialiasingLevel > 0)
+ // Enable anti-aliasing if requested by the user and supported
+ if ((requestedSettings.antialiasingLevel > 0) && (m_settings.antialiasingLevel > 0))
+ {
glEnable(GL_MULTISAMPLE);
+ }
+ else
+ {
+ m_settings.antialiasingLevel = 0;
+ }
+
+ // Enable sRGB if requested by the user and supported
+ if (requestedSettings.sRgbCapable && m_settings.sRgbCapable)
+ {
+ glEnable(GL_FRAMEBUFFER_SRGB);
+
+ // Check to see if the enable was successful
+ if (glIsEnabled(GL_FRAMEBUFFER_SRGB) == GL_FALSE)
+ {
+ err() << "Warning: Failed to enable GL_FRAMEBUFFER_SRGB" << std::endl;
+ m_settings.sRgbCapable = false;
+ }
+ }
+ else
+ {
+ m_settings.sRgbCapable = false;
+ }
}
@@ -490,10 +527,11 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings)
int requestedVersion = requestedSettings.majorVersion * 10 + requestedSettings.minorVersion;
if ((m_settings.attributeFlags != requestedSettings.attributeFlags) ||
- (version < requestedVersion) ||
+ (version < requestedVersion) ||
(m_settings.stencilBits < requestedSettings.stencilBits) ||
(m_settings.antialiasingLevel < requestedSettings.antialiasingLevel) ||
- (m_settings.depthBits < requestedSettings.depthBits))
+ (m_settings.depthBits < requestedSettings.depthBits) ||
+ (!m_settings.sRgbCapable && requestedSettings.sRgbCapable))
{
err() << "Warning: The created OpenGL context does not fully meet the settings that were requested" << std::endl;
err() << "Requested: version = " << requestedSettings.majorVersion << "." << requestedSettings.minorVersion
@@ -503,6 +541,7 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings)
<< std::boolalpha
<< " ; core = " << ((requestedSettings.attributeFlags & ContextSettings::Core) != 0)
<< " ; debug = " << ((requestedSettings.attributeFlags & ContextSettings::Debug) != 0)
+ << " ; sRGB = " << requestedSettings.sRgbCapable
<< std::noboolalpha << std::endl;
err() << "Created: version = " << m_settings.majorVersion << "." << m_settings.minorVersion
<< " ; depth bits = " << m_settings.depthBits
@@ -511,6 +550,7 @@ void GlContext::checkSettings(const ContextSettings& requestedSettings)
<< std::boolalpha
<< " ; core = " << ((m_settings.attributeFlags & ContextSettings::Core) != 0)
<< " ; debug = " << ((m_settings.attributeFlags & ContextSettings::Debug) != 0)
+ << " ; sRGB = " << m_settings.sRgbCapable
<< std::noboolalpha << std::endl;
}
}
diff --git a/src/SFML/Window/GlContext.hpp b/src/SFML/Window/GlContext.hpp
index f9225cd..8c4ce01 100644
--- a/src/SFML/Window/GlContext.hpp
+++ b/src/SFML/Window/GlContext.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -217,11 +217,12 @@ protected:
/// \param stencilBits Stencil bits of the configuration to evaluate
/// \param antialiasing Antialiasing level of the configuration to evaluate
/// \param accelerated Whether the pixel format is hardware accelerated
+ /// \param sRgb Whether the pixel format is sRGB capable
///
/// \return Score of the configuration
///
////////////////////////////////////////////////////////////
- static int evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated);
+ static int evaluateFormat(unsigned int bitsPerPixel, const ContextSettings& settings, int colorBits, int depthBits, int stencilBits, int antialiasing, bool accelerated, bool sRgb);
////////////////////////////////////////////////////////////
// Member data
@@ -232,9 +233,10 @@ private:
////////////////////////////////////////////////////////////
/// \brief Perform various initializations after the context construction
+ /// \param requestedSettings Requested settings during context creation
///
////////////////////////////////////////////////////////////
- void initialize();
+ void initialize(const ContextSettings& requestedSettings);
////////////////////////////////////////////////////////////
/// \brief Check whether the context is compatible with the requested settings
diff --git a/src/SFML/Window/GlResource.cpp b/src/SFML/Window/GlResource.cpp
index 921874d..dfcbe7a 100644
--- a/src/SFML/Window/GlResource.cpp
+++ b/src/SFML/Window/GlResource.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/InputImpl.hpp b/src/SFML/Window/InputImpl.hpp
index df52a78..a0244e2 100644
--- a/src/SFML/Window/InputImpl.hpp
+++ b/src/SFML/Window/InputImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Joystick.cpp b/src/SFML/Window/Joystick.cpp
index 11cf289..c713696 100644
--- a/src/SFML/Window/Joystick.cpp
+++ b/src/SFML/Window/Joystick.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/JoystickImpl.hpp b/src/SFML/Window/JoystickImpl.hpp
index 6648b59..e7b6724 100644
--- a/src/SFML/Window/JoystickImpl.hpp
+++ b/src/SFML/Window/JoystickImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/JoystickManager.cpp b/src/SFML/Window/JoystickManager.cpp
index 99c100d..9038afa 100644
--- a/src/SFML/Window/JoystickManager.cpp
+++ b/src/SFML/Window/JoystickManager.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/JoystickManager.hpp b/src/SFML/Window/JoystickManager.hpp
index 229160b..7f7a22a 100644
--- a/src/SFML/Window/JoystickManager.hpp
+++ b/src/SFML/Window/JoystickManager.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Keyboard.cpp b/src/SFML/Window/Keyboard.cpp
index 6076122..b9ad152 100644
--- a/src/SFML/Window/Keyboard.cpp
+++ b/src/SFML/Window/Keyboard.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Mouse.cpp b/src/SFML/Window/Mouse.cpp
index 0f966bc..6b43c9f 100644
--- a/src/SFML/Window/Mouse.cpp
+++ b/src/SFML/Window/Mouse.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/OSX/AutoreleasePoolWrapper.h b/src/SFML/Window/OSX/AutoreleasePoolWrapper.h
index 6921533..75c414f 100644
--- a/src/SFML/Window/OSX/AutoreleasePoolWrapper.h
+++ b/src/SFML/Window/OSX/AutoreleasePoolWrapper.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -24,26 +24,14 @@
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
-/// \brief Ensure at least one autorelease pool is available on this thread
-///
-/// Increment a retain count for *this* thread.
+/// \brief Ensure one autorelease pool is available on this thread
///
////////////////////////////////////////////////////////////
-void retainPool(void);
+void ensureThreadHasPool(void);
-////////////////////////////////////////////////////////////
-/// \brief Drain the pool
-///
-/// The pool retain count should be absolutely positive before calling this function on this thread.
-///
-////////////////////////////////////////////////////////////
-void drainCurrentPool(void);
////////////////////////////////////////////////////////////
-/// \brief Release the pool.
-///
-/// Decrease the retain count for *this* thread.
+/// \brief Drain the thread's pool but keep it alive
///
////////////////////////////////////////////////////////////
-void releasePool(void);
-
+void drainThreadPool(void);
diff --git a/src/SFML/Window/OSX/AutoreleasePoolWrapper.mm b/src/SFML/Window/OSX/AutoreleasePoolWrapper.mm
index 2afd8ab..f0ae7b4 100644
--- a/src/SFML/Window/OSX/AutoreleasePoolWrapper.mm
+++ b/src/SFML/Window/OSX/AutoreleasePoolWrapper.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -26,11 +26,8 @@
////////////////////////////////////////////////////////////
// Headers
////////////////////////////////////////////////////////////
-#include <SFML/System/Err.hpp>
-#include <SFML/System/NonCopyable.hpp>
-#include <SFML/System/ThreadLocalPtr.hpp>
-
#include <cassert>
+#include <pthread.h>
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
#import <Foundation/Foundation.h>
@@ -41,165 +38,68 @@
/// pool and making other pools invalid which can lead to a crash on 10.5 and an
/// annoying message on 10.6 (*** attempt to pop an unknown autorelease pool).
///
-/// Because NSAutoreleasePool cannot be retain we have to do it ourself.
-/// We use an sf::ThreadLocalPtr to have one PoolWrapper in each thread.
-///
-/// SPECIAL CONSIDERATION:
-/// ======================
-/// This implies that if retainPool is called X times in a thread Y then
-/// releasePool must be called X times too in the same thread Y.
-///
////////////////////////////////////////////////////////////
-namespace sf
-{
-namespace priv
-{
-////////////////////////////////////////////////////////////
-/// \brief C++ Wrapper of Obj-C Autorelease Pool
-///
-////////////////////////////////////////////////////////////
-class PoolWrapper : NonCopyable
-{
-public:
-
- ////////////////////////////////////////////////////////////
- /// \brief Default constructor
- ///
- ////////////////////////////////////////////////////////////
- PoolWrapper();
-
- ////////////////////////////////////////////////////////////
- /// \brief Default destructor
- ///
- /// Make sure the pool is drained (if appropriate)
- ///
- ////////////////////////////////////////////////////////////
- ~PoolWrapper();
-
- ////////////////////////////////////////////////////////////
- /// \brief Increment retain count and allocate memory if needed
- ///
- ////////////////////////////////////////////////////////////
- void retain();
-
- ////////////////////////////////////////////////////////////
- /// \brief Decrement retain count and releasing memory if needed
- ///
- /// \return true if the pool wrapper can be released
- ///
- ////////////////////////////////////////////////////////////
- bool release();
-
- ////////////////////////////////////////////////////////////
- /// \brief Drain the pool
- ///
- ////////////////////////////////////////////////////////////
- void drain();
-
-private:
-
- ////////////////////////////////////////////////////////////
- // Member data
- ////////////////////////////////////////////////////////////
- int m_count; ///< How many times was the pool retained?
- NSAutoreleasePool* m_pool; ///< Our dedicated pool
-};
-
-
-////////////////////////////////////////////////////////////
-PoolWrapper::PoolWrapper() :
-m_count(0),
-m_pool(nil)
-{
- /* Nothing else */
-}
-
////////////////////////////////////////////////////////////
-PoolWrapper::~PoolWrapper()
-{
- // Make sure everything is drained
- m_count = 0;
- drain();
-}
-
-
+// Private data
////////////////////////////////////////////////////////////
-void PoolWrapper::retain()
-{
- // Increase counter
- ++m_count;
-
- // Allocate pool if required
- if (m_pool == nil)
- m_pool = [[NSAutoreleasePool alloc] init];
-}
+static pthread_key_t poolKey;
+static pthread_once_t initOnceToken = PTHREAD_ONCE_INIT;
////////////////////////////////////////////////////////////
-bool PoolWrapper::release()
-{
- // Decrease counter
- --m_count;
-
- return m_count == 0;
-}
-
-void PoolWrapper::drain()
+/// \brief (local function) Drain one more time the pool
+/// but this time don't create a new one.
+///
+////////////////////////////////////////////////////////////
+static void destroyPool(void* data)
{
- [m_pool drain];
- m_pool = nil;
-
- if (m_count != 0)
- m_pool = [[NSAutoreleasePool alloc] init];
+ NSAutoreleasePool* pool = (NSAutoreleasePool*)data;
+ [pool drain];
}
-} // namespace priv
-
-} // namespace sf
-
////////////////////////////////////////////////////////////
-// Private data
+/// \brief (local function) Init the pthread key for the pool
+///
////////////////////////////////////////////////////////////
-namespace
+static void createPoolKey(void)
{
- // This per-thread variable holds the current autorelease pool for each thread
- sf::ThreadLocalPtr<sf::priv::PoolWrapper> localPool;
+ pthread_key_create(&poolKey, destroyPool);
}
////////////////////////////////////////////////////////////
-void retainPool(void)
+/// \brief (local function) Store a new pool for this thread
+///
+////////////////////////////////////////////////////////////
+static void createNewPool(void)
{
- // First, Check that we have a valid PoolWrapper object in our local pool.
- if (localPool == NULL)
- localPool = new sf::priv::PoolWrapper();
-
- // Then retains!
- localPool->retain();
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ pthread_setspecific(poolKey, pool);
}
////////////////////////////////////////////////////////////
-void drainCurrentPool(void)
+void ensureThreadHasPool(void)
{
- assert(localPool != NULL);
- localPool->drain();
+ pthread_once(&initOnceToken, createPoolKey);
+ if (pthread_getspecific(poolKey) == NULL)
+ {
+ createNewPool();
+ }
}
////////////////////////////////////////////////////////////
-void releasePool(void)
+void drainThreadPool(void)
{
- assert(localPool != NULL);
+ void* data = pthread_getspecific(poolKey);
+ assert(data != NULL);
- // If we're done with the pool, let's release the memory
- if (localPool->release())
- {
- delete localPool;
- localPool = NULL;
- }
+ // Drain the pool but keep it alive by creating a new one
+ destroyPool(data);
+ createNewPool();
}
diff --git a/src/SFML/Window/OSX/HIDInputManager.hpp b/src/SFML/Window/OSX/HIDInputManager.hpp
index 01c5ccd..19e2568 100644
--- a/src/SFML/Window/OSX/HIDInputManager.hpp
+++ b/src/SFML/Window/OSX/HIDInputManager.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/HIDInputManager.mm b/src/SFML/Window/OSX/HIDInputManager.mm
index 37ef79e..c53bd53 100644
--- a/src/SFML/Window/OSX/HIDInputManager.mm
+++ b/src/SFML/Window/OSX/HIDInputManager.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -763,7 +763,7 @@ Keyboard::Key HIDInputManager::nonLocalizedKeys(UniChar virtualKeycode)
case 0x2c: return sf::Keyboard::Slash;
case 0x2a: return sf::Keyboard::BackSlash;
-#warning sf::Keyboard::Tilde might be in conflict with some other key.
+ // sf::Keyboard::Tilde might be in conflict with some other key.
// 0x0a is for "Non-US Backslash" according to HID Calibrator,
// a sample provided by Apple.
case 0x0a: return sf::Keyboard::Tilde;
@@ -855,7 +855,7 @@ Keyboard::Key HIDInputManager::nonLocalizedKeys(UniChar virtualKeycode)
case NSPauseFunctionKey: return sf::Keyboard::Pause;
-#warning keycode 0x1b is not bound to any key.
+ // keycode 0x1b is not bound to any key.
// This key is ' on CH-FR, ) on FR and - on US layouts.
// An unknown key.
diff --git a/src/SFML/Window/OSX/HIDJoystickManager.cpp b/src/SFML/Window/OSX/HIDJoystickManager.cpp
index 1724fe6..20b1e37 100644
--- a/src/SFML/Window/OSX/HIDJoystickManager.cpp
+++ b/src/SFML/Window/OSX/HIDJoystickManager.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -133,7 +133,7 @@ void HIDJoystickManager::update()
////////////////////////////////////////////////////////////
void HIDJoystickManager::pluggedIn(void* context, IOReturn, void*, IOHIDDeviceRef)
{
- HIDJoystickManager* manager = (HIDJoystickManager*)context;
+ HIDJoystickManager* manager = static_cast<HIDJoystickManager*>(context);
manager->m_joystickCount++;
}
@@ -141,7 +141,7 @@ void HIDJoystickManager::pluggedIn(void* context, IOReturn, void*, IOHIDDeviceRe
////////////////////////////////////////////////////////////
void HIDJoystickManager::pluggedOut(void* context, IOReturn, void*, IOHIDDeviceRef)
{
- HIDJoystickManager* manager = (HIDJoystickManager*)context;
+ HIDJoystickManager* manager = static_cast<HIDJoystickManager*>(context);
manager->m_joystickCount--;
}
diff --git a/src/SFML/Window/OSX/HIDJoystickManager.hpp b/src/SFML/Window/OSX/HIDJoystickManager.hpp
index a128df5..614e58b 100644
--- a/src/SFML/Window/OSX/HIDJoystickManager.hpp
+++ b/src/SFML/Window/OSX/HIDJoystickManager.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/InputImpl.hpp b/src/SFML/Window/OSX/InputImpl.hpp
index ef897b1..2263551 100644
--- a/src/SFML/Window/OSX/InputImpl.hpp
+++ b/src/SFML/Window/OSX/InputImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/InputImpl.mm b/src/SFML/Window/OSX/InputImpl.mm
index f0e8ee4..0bdade5 100644
--- a/src/SFML/Window/OSX/InputImpl.mm
+++ b/src/SFML/Window/OSX/InputImpl.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -185,7 +185,7 @@ void InputImpl::setMousePosition(const Vector2i& position)
CGEventRef event = CGEventCreateMouseEvent(NULL,
kCGEventMouseMoved,
pos,
- /*we don't care about this: */0);
+ /* we don't care about this: */ kCGMouseButtonLeft);
CGEventPost(kCGHIDEventTap, event);
CFRelease(event);
// This is a workaround to deprecated CGSetLocalEventsSuppressionInterval.
diff --git a/src/SFML/Window/OSX/JoystickImpl.cpp b/src/SFML/Window/OSX/JoystickImpl.cpp
index 09d7614..19acb86 100644
--- a/src/SFML/Window/OSX/JoystickImpl.cpp
+++ b/src/SFML/Window/OSX/JoystickImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/JoystickImpl.hpp b/src/SFML/Window/OSX/JoystickImpl.hpp
index 5b08ba6..a71b82d 100644
--- a/src/SFML/Window/OSX/JoystickImpl.hpp
+++ b/src/SFML/Window/OSX/JoystickImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/NSImage+raw.h b/src/SFML/Window/OSX/NSImage+raw.h
new file mode 100644
index 0000000..745f49c
--- /dev/null
+++ b/src/SFML/Window/OSX/NSImage+raw.h
@@ -0,0 +1,52 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
+// Laurent Gomila (laurent@sfml-dev.org)
+//
+// 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/Config.hpp>
+
+#import <AppKit/AppKit.h>
+
+////////////////////////////////////////////////////////////
+/// Extends NSImage with a convenience method to load images
+/// from raw data.
+///
+////////////////////////////////////////////////////////////
+
+@interface NSImage (raw)
+
+////////////////////////////////////////////////////////////
+/// \brief Load an image from raw RGBA pixels
+///
+/// \param pixels array of 4 * `size` bytes representing the image
+/// \param size size of the image
+///
+/// \return an instance of NSImage that needs to be released by the caller
+///
+////////////////////////////////////////////////////////////
++(NSImage*)imageWithRawData:(const sf::Uint8*)pixels andSize:(NSSize)size;
+
+@end
diff --git a/src/SFML/Window/OSX/NSImage+raw.mm b/src/SFML/Window/OSX/NSImage+raw.mm
new file mode 100644
index 0000000..571a286
--- /dev/null
+++ b/src/SFML/Window/OSX/NSImage+raw.mm
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
+// Laurent Gomila (laurent@sfml-dev.org)
+//
+// 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
+////////////////////////////////////////////////////////////
+#import <SFML/Window/OSX/NSImage+raw.h>
+
+@implementation NSImage (raw)
+
++(NSImage*)imageWithRawData:(const sf::Uint8*)pixels andSize:(NSSize)size
+{
+ // Create an empty image representation.
+ NSBitmapImageRep* bitmap =
+ [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 // if 0: only allocate memory
+ pixelsWide:size.width
+ pixelsHigh:size.height
+ bitsPerSample:8 // The number of bits used to specify
+ // one pixel in a single component of the data.
+ samplesPerPixel:4 // 3 if no alpha, 4 with it
+ hasAlpha:YES
+ isPlanar:NO // I don't know what it is but it works
+ colorSpaceName:NSCalibratedRGBColorSpace
+ bytesPerRow:0 // 0 == determine automatically
+ bitsPerPixel:0]; // 0 == determine automatically
+
+ // Load data pixels.
+ for (unsigned int y = 0; y < size.height; ++y)
+ {
+ for (unsigned int x = 0; x < size.width; ++x, pixels += 4)
+ {
+ NSUInteger pixel[4] = { pixels[0], pixels[1], pixels[2], pixels[3] };
+ [bitmap setPixel:pixel atX:x y:y];
+ }
+ }
+
+ // Create an image from the representation.
+ NSImage* image = [[NSImage alloc] initWithSize:size];
+ [image addRepresentation:bitmap];
+
+ [bitmap release];
+
+ return image;
+}
+
+@end
diff --git a/src/SFML/Window/OSX/SFApplication.h b/src/SFML/Window/OSX/SFApplication.h
index b388d80..454bf8c 100644
--- a/src/SFML/Window/OSX/SFApplication.h
+++ b/src/SFML/Window/OSX/SFApplication.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFApplication.m b/src/SFML/Window/OSX/SFApplication.m
index 6ba1f90..934e89f 100644
--- a/src/SFML/Window/OSX/SFApplication.m
+++ b/src/SFML/Window/OSX/SFApplication.m
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFApplicationDelegate.h b/src/SFML/Window/OSX/SFApplicationDelegate.h
index 4a99550..53033c9 100644
--- a/src/SFML/Window/OSX/SFApplicationDelegate.h
+++ b/src/SFML/Window/OSX/SFApplicationDelegate.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFApplicationDelegate.m b/src/SFML/Window/OSX/SFApplicationDelegate.m
index c15037c..9566c46 100644
--- a/src/SFML/Window/OSX/SFApplicationDelegate.m
+++ b/src/SFML/Window/OSX/SFApplicationDelegate.m
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFContext.hpp b/src/SFML/Window/OSX/SFContext.hpp
index 761c12e..3e2a979 100644
--- a/src/SFML/Window/OSX/SFContext.hpp
+++ b/src/SFML/Window/OSX/SFContext.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFContext.mm b/src/SFML/Window/OSX/SFContext.mm
index 810bcb4..0970007 100644
--- a/src/SFML/Window/OSX/SFContext.mm
+++ b/src/SFML/Window/OSX/SFContext.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -46,7 +46,7 @@ m_view(0),
m_window(0)
{
// Ask for a pool.
- retainPool();
+ ensureThreadHasPool();
// Create the context
createContext(shared,
@@ -62,7 +62,7 @@ m_view(0),
m_window(0)
{
// Ask for a pool.
- retainPool();
+ ensureThreadHasPool();
// Create the context.
createContext(shared, bitsPerPixel, settings);
@@ -83,7 +83,7 @@ m_window(0)
WindowImplCocoa::setUpProcess();
// Ask for a pool.
- retainPool();
+ ensureThreadHasPool();
// Create the context.
createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings);
@@ -108,8 +108,6 @@ SFContext::~SFContext()
[m_view release]; // Might be nil but we don't care.
[m_window release]; // Idem.
-
- releasePool();
}
@@ -244,6 +242,9 @@ void SFContext::createContext(SFContext* shared,
attrs.push_back((NSOpenGLPixelFormatAttribute)0); // end of array
+ // All OS X pixel formats are sRGB capable
+ m_settings.sRgbCapable = true;
+
// Create the pixel format.
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:&attrs[0]];
diff --git a/src/SFML/Window/OSX/SFKeyboardModifiersHelper.h b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.h
index 60bdb3f..39b18ec 100644
--- a/src/SFML/Window/OSX/SFKeyboardModifiersHelper.h
+++ b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm
index 89c23b5..08594da 100644
--- a/src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm
+++ b/src/SFML/Window/OSX/SFKeyboardModifiersHelper.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFOpenGLView+keyboard.mm b/src/SFML/Window/OSX/SFOpenGLView+keyboard.mm
new file mode 100644
index 0000000..4fbef01
--- /dev/null
+++ b/src/SFML/Window/OSX/SFOpenGLView+keyboard.mm
@@ -0,0 +1,220 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
+// Laurent Gomila (laurent@sfml-dev.org)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/OSX/WindowImplCocoa.hpp>
+#include <SFML/Window/OSX/HIDInputManager.hpp> // For localizedKeys and nonLocalizedKeys
+
+#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
+#import <SFML/Window/OSX/SFOpenGLView.h>
+#import <SFML/Window/OSX/SFOpenGLView+keyboard_priv.h>
+
+////////////////////////////////////////////////////////////
+/// In this file, we implement keyboard handling for SFOpenGLView
+///
+////////////////////////////////////////////////////////////
+
+
+@implementation SFOpenGLView (keyboard)
+
+
+////////////////////////////////////////////////////////
+-(BOOL)acceptsFirstResponder
+{
+ // Accepts key event.
+ return YES;
+}
+
+
+////////////////////////////////////////////////////////
+-(BOOL)canBecomeKeyView
+{
+ // Accepts key event.
+ return YES;
+}
+
+
+////////////////////////////////////////////////////////
+-(void)enableKeyRepeat
+{
+ m_useKeyRepeat = YES;
+}
+
+
+////////////////////////////////////////////////////////
+-(void)disableKeyRepeat
+{
+ m_useKeyRepeat = NO;
+}
+
+
+////////////////////////////////////////////////////////
+-(void)keyDown:(NSEvent*)theEvent
+{
+ // Transmit to non-SFML responder
+ [[self nextResponder] keyDown:theEvent];
+
+ if (m_requester == 0)
+ return;
+
+ // Handle key down event
+ if (m_useKeyRepeat || ![theEvent isARepeat])
+ {
+ sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
+
+ if (key.code != sf::Keyboard::Unknown) // The key is recognized.
+ m_requester->keyDown(key);
+ }
+
+
+ // Handle text entered event:
+ // Ignore event if we don't want repeated keystrokes
+ if (m_useKeyRepeat || ![theEvent isARepeat])
+ {
+ // Ignore escape key and other non text keycode (See NSEvent.h)
+ // because they produce a sound alert.
+ if ([SFOpenGLView isValidTextUnicode:theEvent])
+ {
+ // Send the event to the hidden text view for processing
+ [m_hiddenTextView interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
+ }
+
+ // Carefully handle backspace and delete..
+ // Note: the event is intentionally sent to the hidden view
+ // even if we do something more specific below. This way
+ // key combination are correctly interpreted.
+
+ unsigned short keycode = [theEvent keyCode];
+
+ // Backspace
+ if (keycode == 0x33)
+ {
+ // Send the correct Unicode value (i.e. 8) instead of 127 (which is 'delete')
+ m_requester->textEntered(8);
+ }
+
+ // Delete
+ else if ((keycode == 0x75) || (keycode == NSDeleteFunctionKey))
+ {
+ // Instead of the value 63272 we send 127.
+ m_requester->textEntered(127);
+ }
+
+ // Otherwise, let's see what our hidden field has computed
+ else
+ {
+ NSString* string = [m_hiddenTextView string];
+
+ // Send each character to SFML event requester
+ for (NSUInteger index = 0; index < [string length]; ++index)
+ m_requester->textEntered([string characterAtIndex:index]);
+
+ // Empty our hidden cache
+ [m_hiddenTextView setString:@""];
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////
+-(void)sfKeyUp:(NSEvent*)theEvent
+{
+ // For some mystic reasons, key released events don't work the same way
+ // as key pressed events... We somewhat hijack the event chain of response
+ // in -[SFApplication sendEvent:] and resume this chain with the next
+ // responder.
+ // This is workaround to make sure key released events are fired in
+ // fullscreen window too.
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] keyUp:theEvent];
+
+ if (m_requester == 0)
+ return;
+
+ sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
+
+ if (key.code != sf::Keyboard::Unknown) // The key is recognized.
+ m_requester->keyUp(key);
+}
+
+
+////////////////////////////////////////////////////////
+-(void)flagsChanged:(NSEvent*)theEvent
+{
+ // Transmit to non-SFML responder
+ [[self nextResponder] flagsChanged:theEvent];
+
+ if (m_requester == 0)
+ return;
+
+ NSUInteger modifiers = [theEvent modifierFlags];
+ handleModifiersChanged(modifiers, *m_requester);
+}
+
+
+////////////////////////////////////////////////////////
++(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
+{
+ // Key code
+ sf::Keyboard::Key key = sf::Keyboard::Unknown;
+
+ // First we look if the key down is from a list of characters
+ // that depend on keyboard localization.
+ NSString* string = [event charactersIgnoringModifiers];
+ if ([string length] > 0)
+ key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
+
+ // If the key is not a localized one, we try to find a corresponding code
+ // through virtual key code.
+ if (key == sf::Keyboard::Unknown)
+ key = sf::priv::HIDInputManager::nonLocalizedKeys([event keyCode]);
+
+ return keyEventWithModifiers([event modifierFlags], key);
+}
+
+
+////////////////////////////////////////////////////////
++(BOOL)isValidTextUnicode:(NSEvent*)event
+{
+ if ([event keyCode] == 0x35) // Escape
+ {
+ return false;
+ }
+ else if ([[event characters] length] > 0)
+ {
+ unichar code = [[event characters] characterAtIndex:0];
+ return ((code < 0xF700) || (code > 0xF8FF));
+ }
+ else
+ {
+ return true;
+ }
+}
+
+@end
+
diff --git a/src/SFML/Window/OSX/SFOpenGLView+keyboard_priv.h b/src/SFML/Window/OSX/SFOpenGLView+keyboard_priv.h
new file mode 100644
index 0000000..c3710f5
--- /dev/null
+++ b/src/SFML/Window/OSX/SFOpenGLView+keyboard_priv.h
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
+// Laurent Gomila (laurent@sfml-dev.org)
+//
+// 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/Mouse.hpp>
+
+#import <AppKit/AppKit.h>
+
+
+////////////////////////////////////////////////////////////
+/// Here are defined a few private messages for keyboard
+/// handling in SFOpenGLView.
+///
+////////////////////////////////////////////////////////////
+
+
+@interface SFOpenGLView (keyboard_priv)
+
+////////////////////////////////////////////////////////////
+/// \brief Convert a key down/up NSEvent into an SFML key event
+///
+/// The conversion is based on localizedKeys and nonLocalizedKeys functions.
+///
+/// \param event a key event
+///
+/// \return sf::Keyboard::Unknown as Code if the key is unknown
+///
+////////////////////////////////////////////////////////////
++(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event;
+
+////////////////////////////////////////////////////////////
+/// \brief Check if the event represent some Unicode text
+///
+/// The event is assumed to be a key down event.
+/// False is returned if the event is either escape or a non text Unicode.
+///
+/// \param event a key down event
+///
+/// \return true if event represents a Unicode character, false otherwise
+///
+////////////////////////////////////////////////////////////
++(BOOL)isValidTextUnicode:(NSEvent*)event;
+
+@end
diff --git a/src/SFML/Window/OSX/SFOpenGLView+mouse.mm b/src/SFML/Window/OSX/SFOpenGLView+mouse.mm
new file mode 100644
index 0000000..6349081
--- /dev/null
+++ b/src/SFML/Window/OSX/SFOpenGLView+mouse.mm
@@ -0,0 +1,402 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
+// Laurent Gomila (laurent@sfml-dev.org)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/OSX/WindowImplCocoa.hpp>
+#include <cmath>
+
+#import <SFML/Window/OSX/SFOpenGLView.h>
+#import <SFML/Window/OSX/SFOpenGLView+mouse_priv.h>
+
+
+////////////////////////////////////////////////////////////
+/// In this file, we implement mouse handling for SFOpenGLView
+///
+////////////////////////////////////////////////////////////
+
+@implementation SFOpenGLView (mouse)
+
+////////////////////////////////////////////////////////
+-(BOOL)isMouseInside
+{
+ NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
+ NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
+
+ return NSPointInRect(relativeToView, [self bounds]);
+}
+
+
+////////////////////////////////////////////////////////
+-(void)updateMouseState
+{
+ // Update in/out state
+ BOOL mouseWasIn = m_mouseIsIn;
+ m_mouseIsIn = [self isMouseInside];
+
+ // Send event if needed.
+ if (m_requester != 0)
+ {
+ if (mouseWasIn && !m_mouseIsIn)
+ m_requester->mouseMovedOut();
+ else if (!mouseWasIn && m_mouseIsIn)
+ m_requester->mouseMovedIn();
+ }
+}
+
+
+////////////////////////////////////////////////////////
+-(void)setCursorGrabbed:(BOOL)grabbed
+{
+ m_cursorGrabbed = grabbed;
+
+ [self updateCursorGrabbed];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)mouseDown:(NSEvent*)theEvent
+{
+ [self handleMouseDown:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] mouseDown:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)rightMouseDown:(NSEvent*)theEvent
+{
+ [self handleMouseDown:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] rightMouseDown:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)otherMouseDown:(NSEvent*)theEvent
+{
+ [self handleMouseDown:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] otherMouseDown:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)handleMouseDown:(NSEvent*)theEvent
+{
+ sf::Mouse::Button button = [SFOpenGLView mouseButtonFromEvent:theEvent];
+
+ if (m_requester != 0)
+ {
+ NSPoint loc = [self cursorPositionFromEvent:theEvent];
+
+ if (button != sf::Mouse::ButtonCount)
+ m_requester->mouseDownAt(button, loc.x, loc.y);
+ }
+}
+
+
+////////////////////////////////////////////////////////
+-(void)mouseUp:(NSEvent*)theEvent
+{
+ [self handleMouseUp:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] mouseUp:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)rightMouseUp:(NSEvent*)theEvent
+{
+ [self handleMouseUp:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] rightMouseUp:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)otherMouseUp:(NSEvent*)theEvent
+{
+ [self handleMouseUp:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] otherMouseUp:theEvent];
+}
+
+
+////////////////////////////////////////////////////////////
+-(void)handleMouseUp:(NSEvent*)theEvent
+{
+ sf::Mouse::Button button = [SFOpenGLView mouseButtonFromEvent:theEvent];
+
+ if (m_requester != 0)
+ {
+ NSPoint loc = [self cursorPositionFromEvent:theEvent];
+
+ if (button != sf::Mouse::ButtonCount)
+ m_requester->mouseUpAt(button, loc.x, loc.y);
+ }
+}
+
+
+////////////////////////////////////////////////////////
+-(void)mouseMoved:(NSEvent*)theEvent
+{
+ [self handleMouseMove:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] mouseMoved:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)rightMouseDragged:(NSEvent*)theEvent
+{
+ [self handleMouseMove:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] rightMouseDragged:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)mouseDragged:(NSEvent*)theEvent
+{
+ [self handleMouseMove:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] mouseDragged:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)otherMouseDragged:(NSEvent*)theEvent
+{
+ [self handleMouseMove:theEvent];
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] otherMouseUp:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)handleMouseMove:(NSEvent*)theEvent
+{
+ NSPoint loc = [self cursorPositionFromEvent:theEvent];
+
+ // If the cursor is grabbed, cursorPositionFromEvent: will
+ // return its correct position but not move actually it
+ // so we do it now.
+ if ([self isCursorCurrentlyGrabbed])
+ [self moveCursorTo:loc];
+
+ // Make sure the point is inside the view.
+ // (mouseEntered: and mouseExited: are not immediately called
+ // when the mouse is dragged. That would be too easy!)
+ [self updateMouseState];
+ if ((m_requester != 0) && m_mouseIsIn)
+ m_requester->mouseMovedAt(loc.x, loc.y);
+}
+
+
+////////////////////////////////////////////////////////
+-(BOOL)isCursorCurrentlyGrabbed
+{
+ return [[self window] isKeyWindow] && (m_cursorGrabbed || m_fullscreen);
+}
+
+
+////////////////////////////////////////////////////////
+-(void)updateCursorGrabbed
+{
+ // Disable/enable normal movements of the cursor
+ // and project the cursor if needed.
+ if ([self isCursorCurrentlyGrabbed])
+ {
+ CGAssociateMouseAndMouseCursorPosition(NO);
+
+ // Similarly to handleMouseMove: but without event.
+ NSPoint loc = [self cursorPositionFromEvent:nil];
+ [self moveCursorTo:loc];
+ }
+ else
+ {
+ CGAssociateMouseAndMouseCursorPosition(YES);
+ }
+}
+
+
+////////////////////////////////////////////////////////
+-(void)moveCursorTo:(NSPoint)loc
+{
+ // Convert the point from SFML coord system to screen coord system.
+ NSPoint screenLocation = [self computeGlobalPositionOfRelativePoint:loc];
+
+ // This won't produce a move event, which is perfect if the cursor was grabbed
+ // as we move it manually based on delta values of the cursor.
+ CGDisplayMoveCursorToPoint([self displayId], NSPointToCGPoint(screenLocation));
+}
+
+
+////////////////////////////////////////////////////////
+-(CGDirectDisplayID)displayId
+{
+ NSScreen* screen = [[self window] screen];
+ NSNumber* displayId = [[screen deviceDescription] objectForKey:@"NSScreenNumber"];
+ return [displayId intValue];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)scrollWheel:(NSEvent*)theEvent
+{
+ if (m_requester != 0)
+ {
+ NSPoint loc = [self cursorPositionFromEvent:theEvent];
+ m_requester->mouseWheelScrolledAt([theEvent deltaX], [theEvent deltaY], loc.x, loc.y);
+ }
+
+ // Transmit to non-SFML responder
+ [[self nextResponder] scrollWheel:theEvent];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)mouseEntered:(NSEvent*)theEvent
+{
+ (void)theEvent;
+ [self updateMouseState];
+}
+
+
+////////////////////////////////////////////////////////
+-(void)mouseExited:(NSEvent*)theEvent
+{
+ (void)theEvent;
+ [self updateMouseState];
+}
+
+
+////////////////////////////////////////////////////////
+-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil
+{
+ NSPoint rawPos;
+
+ // If no event given then get current mouse pos.
+ if (eventOrNil == nil)
+ rawPos = [[self window] mouseLocationOutsideOfEventStream];
+ else
+ rawPos = [eventOrNil locationInWindow];
+
+ if ([self isCursorCurrentlyGrabbed])
+ {
+ if (eventOrNil != nil)
+ {
+ // Special case when the mouse is grabbed:
+ // we need to take into account the delta since the cursor
+ // is dissociated from its position.
+
+ // Ignore any non-move related event
+ if (([eventOrNil type] == NSMouseMoved) ||
+ ([eventOrNil type] == NSLeftMouseDragged) ||
+ ([eventOrNil type] == NSRightMouseDragged) ||
+ ([eventOrNil type] == NSOtherMouseDragged))
+ {
+ // Without this factor, the cursor flies around waaay too fast!
+ // But I don't know if it because of retina display or because
+ // some event are sent twice (and that in itself is another mystery).
+ CGFloat factor = 2;
+
+ // Also, this factor is not the same when keeping track of how much
+ // we move the cursor (buffers) when projecting the cursor into the
+ // view when grabbing the cursor for the first time.
+ CGFloat factorBuffer = m_fullscreen ? 1 : 2;
+
+ CGFloat deltaX = [eventOrNil deltaX];
+ CGFloat deltaY = [eventOrNil deltaY];
+
+ // If the buffer for X is empty, move the cursor;
+ // otherwise decrement this buffer a bit.
+ if (m_deltaXBuffer <= 0)
+ rawPos.x += deltaX / factor;
+ else
+ m_deltaXBuffer -= std::abs(deltaX / factorBuffer);
+
+ // Rinse and repeat for Y.
+ if (m_deltaYBuffer <= 0)
+ rawPos.y -= deltaY / factor;
+ else
+ m_deltaYBuffer -= std::abs(deltaY / factorBuffer);
+ }
+ }
+
+ // We also make sure the new point is inside the view
+ NSSize size = [self frame].size;
+ NSPoint origin = [self frame].origin;
+ NSPoint oldPos = rawPos;
+ rawPos.x = std::min(std::max(origin.x, rawPos.x), origin.x + size.width - 1);
+ rawPos.y = std::min(std::max(origin.y + 1, rawPos.y), origin.y + size.height);
+ // Note: the `-1` and `+1` on the two lines above prevent the user to click
+ // on the left or below the window, repectively, and therefore prevent the
+ // application to lose focus by accident. The sign of this offset is determinded
+ // by the direction of the x and y axis.
+
+ // Increase X and Y buffer with the distance of the projection
+ m_deltaXBuffer += std::abs(rawPos.x - oldPos.x);
+ m_deltaYBuffer += std::abs(rawPos.y - oldPos.y);
+ }
+
+ NSPoint loc = [self convertPoint:rawPos fromView:nil];
+
+ // Don't forget to change to SFML coord system.
+ float h = [self frame].size.height;
+ loc.y = h - loc.y;
+
+ return loc;
+}
+
+
+////////////////////////////////////////////////////////
++(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event
+{
+ switch ([event buttonNumber])
+ {
+ case 0: return sf::Mouse::Left;
+ case 1: return sf::Mouse::Right;
+ case 2: return sf::Mouse::Middle;
+ case 3: return sf::Mouse::XButton1;
+ case 4: return sf::Mouse::XButton2;
+ default: return sf::Mouse::ButtonCount; // Never happens! (hopefully)
+ }
+}
+
+
+@end
diff --git a/src/SFML/Window/OSX/SFOpenGLView+mouse_priv.h b/src/SFML/Window/OSX/SFOpenGLView+mouse_priv.h
new file mode 100644
index 0000000..f9b2ab7
--- /dev/null
+++ b/src/SFML/Window/OSX/SFOpenGLView+mouse_priv.h
@@ -0,0 +1,110 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
+// Laurent Gomila (laurent@sfml-dev.org)
+//
+// 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/Mouse.hpp>
+
+#import <AppKit/AppKit.h>
+
+
+////////////////////////////////////////////////////////////
+/// Here are defined a few private messages for mouse
+/// handling in SFOpenGLView.
+///
+////////////////////////////////////////////////////////////
+
+
+@interface SFOpenGLView (mouse_priv)
+
+////////////////////////////////////////////////////////////
+/// \brief Update the mouse state (in or out)
+///
+/// Fire an event if its state has changed.
+///
+////////////////////////////////////////////////////////////
+-(void)updateMouseState;
+
+////////////////////////////////////////////////////////////
+/// \brief handle mouse down event
+///
+////////////////////////////////////////////////////////////
+-(void)handleMouseDown:(NSEvent*)theEvent;
+
+////////////////////////////////////////////////////////////
+/// \brief handle mouse up event
+///
+////////////////////////////////////////////////////////////
+-(void)handleMouseUp:(NSEvent*)theEvent;
+
+////////////////////////////////////////////////////////////
+/// \brief handle mouse move event
+///
+////////////////////////////////////////////////////////////
+-(void)handleMouseMove:(NSEvent*)theEvent;
+
+////////////////////////////////////////////////////////////
+/// \brief Check whether the cursor is grabbed or not
+///
+/// The cursor is grabbed if the window is active (key) and
+/// either it is in fullscreen mode or the user wants to
+/// grab it.
+///
+////////////////////////////////////////////////////////////
+-(BOOL)isCursorCurrentlyGrabbed;
+
+////////////////////////////////////////////////////////////
+/// \brief (Dis)connect the cursor's movements from/to the system
+/// and project the cursor into the view
+///
+////////////////////////////////////////////////////////////
+-(void)updateCursorGrabbed;
+
+////////////////////////////////////////////////////////////
+/// \brief Move the cursor to the given location
+///
+/// \param loc location expressed in SFML coordinate system
+///
+////////////////////////////////////////////////////////////
+-(void)moveCursorTo:(NSPoint)loc;
+
+////////////////////////////////////////////////////////////
+/// \brief Get the display identifier on which the view is
+///
+////////////////////////////////////////////////////////////
+-(CGDirectDisplayID)displayId;
+
+////////////////////////////////////////////////////////////
+/// \brief Convert the NSEvent mouse button type to SFML type
+///
+/// \param event a mouse button event
+///
+/// \return Left, Right, ..., or ButtonCount if the button is unknown
+///
+////////////////////////////////////////////////////////////
++(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event;
+
+@end
diff --git a/src/SFML/Window/OSX/SFOpenGLView.h b/src/SFML/Window/OSX/SFOpenGLView.h
index 6a0d0b0..41d0c76 100644
--- a/src/SFML/Window/OSX/SFOpenGLView.h
+++ b/src/SFML/Window/OSX/SFOpenGLView.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -47,6 +47,24 @@ namespace sf {
/// Modifiers keys (cmd, ctrl, alt, shift) are handled by this class
/// but the actual logic is done in SFKeyboardModifiersHelper.(h|mm).
///
+/// The interface is subdivided into several categories in order
+/// to have multiple implementation files to divide this monolithic
+/// implementation. However, all attributes are defined in the main
+/// interface declaration right below.
+///
+/// Note about deltaXBuffer and deltaYBuffer: when grabbing the cursor
+/// for the first time, either by entering fullscreen or through
+/// setCursorGrabbed:, the cursor might be projected into the view.
+/// Doing this will result in a big delta (relative movement) in the
+/// next move event (cursorPositionFromEvent:), because no move event
+/// is generated, which in turn will give the impression that the user
+/// want to move the cursor by the same distance it was projected. To
+/// prevent the cursor to fly twice the distance we keep track of how
+/// much the cursor was projected in deltaXBuffer and deltaYBuffer. In
+/// cursorPositionFromEvent: we can then reduce/augment those buffers
+/// to determine when a move event should result in an actual move of
+/// the cursor (that was disconnected from the system).
+///
////////////////////////////////////////////////////////////
@interface SFOpenGLView : NSOpenGLView
{
@@ -56,6 +74,9 @@ namespace sf {
NSTrackingArea* m_trackingArea; ///< Mouse tracking area
BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not
CGFloat m_scaleFactor; ///< Display scale factor (e.g. 1x for classic display, 2x for retina)
+ BOOL m_cursorGrabbed; ///< Is the mouse cursor trapped?
+ CGFloat m_deltaXBuffer; ///< See note about cursor grabbing above
+ CGFloat m_deltaYBuffer; ///< See note about cursor grabbing above
// Hidden text view used to convert key event to actual chars.
// We use a silent responder to prevent sound alerts.
@@ -106,6 +127,18 @@ namespace sf {
-(NSPoint)computeGlobalPositionOfRelativePoint:(NSPoint)point;
////////////////////////////////////////////////////////////
+/// \brief Get the display scale factor
+///
+/// \return e.g. 1.0 for classic display, 2.0 for retina display
+///
+////////////////////////////////////////////////////////////
+-(CGFloat)displayScaleFactor;
+
+@end
+
+@interface SFOpenGLView (keyboard)
+
+////////////////////////////////////////////////////////////
/// \brief Enable key repeat
///
////////////////////////////////////////////////////////////
@@ -117,19 +150,17 @@ namespace sf {
////////////////////////////////////////////////////////////
-(void)disableKeyRepeat;
-////////////////////////////////////////////////////////////
-/// \brief Get the display scale factor
-///
-/// \return e.g. 1.0 for classic display, 2.0 for retina display
-///
-////////////////////////////////////////////////////////////
--(CGFloat)displayScaleFactor;
+@end
+
+@interface SFOpenGLView (mouse)
////////////////////////////////////////////////////////////
/// \brief Compute the position of the cursor
///
/// \param eventOrNil if nil the cursor position is the current one
///
+/// \return the mouse position in SFML coord system
+///
////////////////////////////////////////////////////////////
-(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil;
@@ -141,4 +172,22 @@ namespace sf {
////////////////////////////////////////////////////////////
-(BOOL)isMouseInside;
+////////////////////////////////////////////////////////////
+/// Clips or releases the mouse cursor
+///
+/// Generate a MouseEntered event when it makes sense.
+///
+/// \param grabbed YES to grab, NO to release
+///
+////////////////////////////////////////////////////////////
+-(void)setCursorGrabbed:(BOOL)grabbed;
+
+////////////////////////////////////////////////////////////
+/// Update the cursor position according to the grabbing behaviour
+///
+/// This function has to be called when the window's state change
+///
+////////////////////////////////////////////////////////////
+-(void)updateCursorGrabbed;
+
@end
diff --git a/src/SFML/Window/OSX/SFOpenGLView.mm b/src/SFML/Window/OSX/SFOpenGLView.mm
index 137b7b0..80cd624 100644
--- a/src/SFML/Window/OSX/SFOpenGLView.mm
+++ b/src/SFML/Window/OSX/SFOpenGLView.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -27,29 +27,14 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
-#include <SFML/Window/OSX/HIDInputManager.hpp> // For localizedKeys and nonLocalizedKeys
#include <SFML/System/Err.hpp>
-#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
+#import <SFML/Window/OSX/SFOpenGLView+mouse_priv.h>
#import <SFML/Window/OSX/SFSilentResponder.h>
////////////////////////////////////////////////////////////
-/// \brief Check if the event represent some Unicode text
-///
-/// The event is assumed to be a key down event.
-/// False is returned if the event is either escape or a non text Unicode.
-///
-/// \param event a key down event
-///
-/// \return true if event represents a Unicode character, false otherwise
-///
-////////////////////////////////////////////////////////////
-BOOL isValidTextUnicode(NSEvent* event);
-
-
-////////////////////////////////////////////////////////////
/// SFOpenGLView class: Privates Methods Declaration
///
////////////////////////////////////////////////////////////
@@ -68,14 +53,6 @@ BOOL isValidTextUnicode(NSEvent* event);
-(void)viewDidEndLiveResize;
////////////////////////////////////////////////////////////
-/// \brief Update the mouse state (in or out)
-///
-/// Fire an event if its state has changed.
-///
-////////////////////////////////////////////////////////////
--(void)updateMouseState;
-
-////////////////////////////////////////////////////////////
/// \brief Callback for focus event
///
////////////////////////////////////////////////////////////
@@ -99,28 +76,6 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////////
-(void)exitFullscreen;
-////////////////////////////////////////////////////////////
-/// \brief Convert the NSEvent mouse button type to SFML type
-///
-/// \param event a mouse button event
-///
-/// \return Left, Right, ..., or ButtonCount if the button is unknown
-///
-////////////////////////////////////////////////////////////
--(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event;
-
-////////////////////////////////////////////////////////////
-/// \brief Convert a key down/up NSEvent into an SFML key event
-///
-/// The conversion is based on localizedKeys and nonLocalizedKeys functions.
-///
-/// \param event a key event
-///
-/// \return sf::Keyboard::Unknown as Code if the key is unknown
-///
-////////////////////////////////////////////////////////////
-+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event;
-
@end
@implementation SFOpenGLView
@@ -153,6 +108,9 @@ BOOL isValidTextUnicode(NSEvent* event);
m_fullscreen = isFullscreen;
m_scaleFactor = 1.0; // Default value; it will be updated in finishInit
+ m_cursorGrabbed = NO;
+ m_deltaXBuffer = 0;
+ m_deltaYBuffer = 0;
// Create a hidden text view for parsing key down event properly
m_silentResponder = [[SFSilentResponder alloc] init];
@@ -171,6 +129,17 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
+-(void)update
+{
+ // In order to prevent an infinite recursion when the window/view is
+ // resized to zero-height/width, we ignore update event when resizing.
+ if (![self inLiveResize]) {
+ [super update];
+ }
+}
+
+
+////////////////////////////////////////////////////////
-(void)finishInit
{
// Register for window focus events
@@ -197,8 +166,9 @@ BOOL isValidTextUnicode(NSEvent* event);
name:NSWindowDidChangeScreenProfileNotification
object:[self window]];
- // Now that we have a window, set up correctly the scale factor
+ // Now that we have a window, set up correctly the scale factor and cursor grabbing
[self updateScaleFactor];
+ [self updateCursorGrabbed]; // update for fullscreen
}
@@ -241,20 +211,6 @@ BOOL isValidTextUnicode(NSEvent* event);
////////////////////////////////////////////////////////
--(void)enableKeyRepeat
-{
- m_useKeyRepeat = YES;
-}
-
-
-////////////////////////////////////////////////////////
--(void)disableKeyRepeat
-{
- m_useKeyRepeat = NO;
-}
-
-
-////////////////////////////////////////////////////////
-(CGFloat)displayScaleFactor
{
return m_scaleFactor;
@@ -293,6 +249,7 @@ BOOL isValidTextUnicode(NSEvent* event);
// Update mouse internal state.
[self updateMouseState];
+ [self updateCursorGrabbed];
// Update the OGL view to fit the new size.
[self update];
@@ -306,39 +263,13 @@ BOOL isValidTextUnicode(NSEvent* event);
m_requester->windowResized(newSize.width, newSize.height);
}
-
-////////////////////////////////////////////////////////
--(BOOL)isMouseInside
-{
- NSPoint relativeToWindow = [[self window] mouseLocationOutsideOfEventStream];
- NSPoint relativeToView = [self convertPoint:relativeToWindow fromView:nil];
-
- return NSPointInRect(relativeToView, [self bounds]);
-}
-
-
-////////////////////////////////////////////////////////
--(void)updateMouseState
-{
- BOOL mouseWasIn = m_mouseIsIn;
- m_mouseIsIn = [self isMouseInside];
-
- if (m_requester == 0)
- return;
-
- // Send event if needed.
- if (mouseWasIn && !m_mouseIsIn)
- m_requester->mouseMovedOut();
- else if (!mouseWasIn && m_mouseIsIn)
- m_requester->mouseMovedIn();
-}
-
-
////////////////////////////////////////////////////////
-(void)windowDidBecomeKey:(NSNotification*)notification
{
(void)notification;
+ [self updateCursorGrabbed];
+
if (m_requester)
m_requester->windowGainedFocus();
@@ -352,6 +283,8 @@ BOOL isValidTextUnicode(NSEvent* event);
{
(void)notification;
+ [self updateCursorGrabbed];
+
if (m_requester)
m_requester->windowLostFocus();
@@ -415,398 +348,4 @@ BOOL isValidTextUnicode(NSEvent* event);
}
-////////////////////////////////////////////////////////
--(BOOL)acceptsFirstResponder
-{
- // Accepts key event.
- return YES;
-}
-
-
-////////////////////////////////////////////////////////
--(BOOL)canBecomeKeyView
-{
- // Accepts key event.
- return YES;
-}
-
-
-#pragma mark
-#pragma mark Mouse-event methods
-
-
-////////////////////////////////////////////////////////
--(void)mouseDown:(NSEvent*)theEvent
-{
- // Forward to...
- [self otherMouseDown:theEvent];
-
- // Transmit to non-SFML responder
- [[self nextResponder] mouseDown:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)mouseUp:(NSEvent*)theEvent
-{
- // Forward to...
- [self otherMouseUp:theEvent];
-
- // Transmit to non-SFML responder
- [[self nextResponder] mouseUp:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)mouseMoved:(NSEvent*)theEvent
-{
- // Forward to...
- [self otherMouseDragged:theEvent];
-
- // Transmit to non-SFML responder
- [[self nextResponder] mouseMoved:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)scrollWheel:(NSEvent*)theEvent
-{
- if (m_requester != 0)
- {
- NSPoint loc = [self cursorPositionFromEvent:theEvent];
- m_requester->mouseWheelScrolledAt([theEvent deltaX], [theEvent deltaY], loc.x, loc.y);
- }
-
- // Transmit to non-SFML responder
- [[self nextResponder] scrollWheel:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)mouseEntered:(NSEvent*)theEvent
-{
- (void)theEvent;
- [self updateMouseState];
-}
-
-
-////////////////////////////////////////////////////////
--(void)mouseExited:(NSEvent*)theEvent
-{
- (void)theEvent;
- [self updateMouseState];
-}
-
-
-////////////////////////////////////////////////////////
--(void)rightMouseDown:(NSEvent*)theEvent
-{
- // Forward to...
- [self otherMouseDown:theEvent];
-
- // Transmit to non-SFML responder
- [[self nextResponder] rightMouseDown:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)rightMouseUp:(NSEvent*)theEvent
-{
- // Forward to...
- [self otherMouseUp:theEvent];
-
- // Transmit to non-SFML responder
- [[self nextResponder] rightMouseUp:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)otherMouseDown:(NSEvent*)theEvent
-{
- sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
-
- if (m_requester != 0)
- {
- NSPoint loc = [self cursorPositionFromEvent:theEvent];
-
- if (button != sf::Mouse::ButtonCount)
- m_requester->mouseDownAt(button, loc.x, loc.y);
- }
-
- // If the event is not forwarded by mouseDown or rightMouseDown...
- if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
- {
- // ... transmit to non-SFML responder
- [[self nextResponder] otherMouseDown:theEvent];
- }
-}
-
-
-////////////////////////////////////////////////////////
--(void)otherMouseUp:(NSEvent*)theEvent
-{
- sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
-
- if (m_requester != 0)
- {
- NSPoint loc = [self cursorPositionFromEvent:theEvent];
-
- if (button != sf::Mouse::ButtonCount)
- m_requester->mouseUpAt(button, loc.x, loc.y);
- }
-
- // If the event is not forwarded by mouseUp or rightMouseUp...
- if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
- {
- // ... transmit to non-SFML responder
- [[self nextResponder] otherMouseUp:theEvent];
- }
-}
-
-
-////////////////////////////////////////////////////////
--(void)rightMouseDragged:(NSEvent*)theEvent
-{
- // Forward to...
- [self otherMouseDragged:theEvent];
-
- // Transmit to non-SFML responder
- [[self nextResponder] rightMouseDragged:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)mouseDragged:(NSEvent*)theEvent
-{
- // Forward to...
- [self otherMouseDragged:theEvent];
-
- // Transmit to non-SFML responder
- [[self nextResponder] mouseDragged:theEvent];
-}
-
-
-////////////////////////////////////////////////////////
--(void)otherMouseDragged:(NSEvent*)theEvent
-{
- if (m_requester != 0)
- {
- NSPoint loc = [self cursorPositionFromEvent:theEvent];
-
- // Make sure the point is inside the view.
- // (mouseEntered: and mouseExited: are not immediately called
- // when the mouse is dragged. That would be too easy!)
- [self updateMouseState];
- if (m_mouseIsIn)
- m_requester->mouseMovedAt(loc.x, loc.y);
- }
-
- // If the event is not forwarded by mouseDragged or rightMouseDragged...
- sf::Mouse::Button button = [self mouseButtonFromEvent:theEvent];
- if ((button != sf::Mouse::Left) && (button != sf::Mouse::Right))
- {
- // ... transmit to non-SFML responder
- [[self nextResponder] otherMouseUp:theEvent];
- }
-}
-
-
-////////////////////////////////////////////////////////
--(NSPoint)cursorPositionFromEvent:(NSEvent*)eventOrNil
-{
- NSPoint loc;
- // If no event given then get current mouse pos.
- if (eventOrNil == nil)
- {
- NSPoint rawPos = [[self window] mouseLocationOutsideOfEventStream];
- loc = [self convertPoint:rawPos fromView:nil];
- }
- else
- {
- loc = [self convertPoint:[eventOrNil locationInWindow] fromView:nil];
- }
-
- // Don't forget to change to SFML coord system.
- float h = [self frame].size.height;
- loc.y = h - loc.y;
-
- return loc;
-}
-
-
-////////////////////////////////////////////////////////
--(sf::Mouse::Button)mouseButtonFromEvent:(NSEvent*)event
-{
- switch ([event buttonNumber])
- {
- case 0: return sf::Mouse::Left;
- case 1: return sf::Mouse::Right;
- case 2: return sf::Mouse::Middle;
- case 3: return sf::Mouse::XButton1;
- case 4: return sf::Mouse::XButton2;
- default: return sf::Mouse::ButtonCount; // Never happens! (hopefully)
- }
-}
-
-
-#pragma mark
-#pragma mark Key-event methods
-
-
-////////////////////////////////////////////////////////
--(void)keyDown:(NSEvent*)theEvent
-{
- // Transmit to non-SFML responder
- [[self nextResponder] keyDown:theEvent];
-
- if (m_requester == 0)
- return;
-
- // Handle key down event
- if (m_useKeyRepeat || ![theEvent isARepeat])
- {
- sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
-
- if (key.code != sf::Keyboard::Unknown) // The key is recognized.
- m_requester->keyDown(key);
- }
-
-
- // Handle text entered event:
- // Ignore event if we don't want repeated keystrokes
- if (m_useKeyRepeat || ![theEvent isARepeat])
- {
- // Ignore escape key and other non text keycode (See NSEvent.h)
- // because they produce a sound alert.
- if (isValidTextUnicode(theEvent))
- {
- // Send the event to the hidden text view for processing
- [m_hiddenTextView interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
- }
-
- // Carefully handle backspace and delete..
- // Note: the event is intentionally sent to the hidden view
- // even if we do something more specific below. This way
- // key combination are correctly interpreted.
-
- unsigned short keycode = [theEvent keyCode];
-
- // Backspace
- if (keycode == 0x33)
- {
- // Send the correct Unicode value (i.e. 8) instead of 127 (which is 'delete')
- m_requester->textEntered(8);
- }
-
- // Delete
- else if ((keycode == 0x75) || (keycode == NSDeleteFunctionKey))
- {
- // Instead of the value 63272 we send 127.
- m_requester->textEntered(127);
- }
-
- // Otherwise, let's see what our hidden field has computed
- else
- {
- NSString* string = [m_hiddenTextView string];
-
- // Send each character to SFML event requester
- for (NSUInteger index = 0; index < [string length]; ++index)
- m_requester->textEntered([string characterAtIndex:index]);
-
- // Empty our hidden cache
- [m_hiddenTextView setString:@""];
- }
- }
-}
-
-
-////////////////////////////////////////////////////////
--(void)sfKeyUp:(NSEvent*)theEvent
-{
- // For some mystic reasons, key released events don't work the same way
- // as key pressed events... We somewhat hijack the event chain of response
- // in -[SFApplication sendEvent:] and resume this chain with the next
- // responder.
- // This is workaround to make sure key released events are fired in
- // fullscreen window too.
-
- // Transmit to non-SFML responder
- [[self nextResponder] keyUp:theEvent];
-
- if (m_requester == 0)
- return;
-
- sf::Event::KeyEvent key = [SFOpenGLView convertNSKeyEventToSFMLEvent:theEvent];
-
- if (key.code != sf::Keyboard::Unknown) // The key is recognized.
- m_requester->keyUp(key);
-}
-
-
-////////////////////////////////////////////////////////
--(void)flagsChanged:(NSEvent*)theEvent
-{
- // Transmit to non-SFML responder
- [[self nextResponder] flagsChanged:theEvent];
-
- if (m_requester == 0)
- return;
-
- NSUInteger modifiers = [theEvent modifierFlags];
- handleModifiersChanged(modifiers, *m_requester);
-}
-
-
-////////////////////////////////////////////////////////
-+(sf::Event::KeyEvent)convertNSKeyEventToSFMLEvent:(NSEvent*)event
-{
- // Key code
- sf::Keyboard::Key key = sf::Keyboard::Unknown;
-
- // First we look if the key down is from a list of characters
- // that depend on keyboard localization.
- NSString* string = [event charactersIgnoringModifiers];
- if ([string length] > 0)
- key = sf::priv::HIDInputManager::localizedKeys([string characterAtIndex:0]);
-
- // If the key is not a localized one, we try to find a corresponding code
- // through virtual key code.
- if (key == sf::Keyboard::Unknown)
- key = sf::priv::HIDInputManager::nonLocalizedKeys([event keyCode]);
-
-//#ifdef SFML_DEBUG // Don't bother the final customers with annoying messages.
-// if (key.code == sf::Keyboard::Unknown) { // The key is unknown.
-// sf::err() << "This is an unknown key. Virtual key code is 0x"
-// << std::hex
-// << [event keyCode]
-// << "."
-// << std::endl;
-// }
-//#endif
-
- return keyEventWithModifiers([event modifierFlags], key);
-}
-
@end
-
-
-#pragma mark - C-like functions
-
-BOOL isValidTextUnicode(NSEvent* event)
-{
- if ([event keyCode] == 0x35) // Escape
- {
- return false;
- }
- else if ([[event characters] length] > 0)
- {
- unichar code = [[event characters] characterAtIndex:0];
- return ((code < 0xF700) || (code > 0xF8FF));
- }
- else
- {
- return true;
- }
-}
-
diff --git a/src/SFML/Window/OSX/SFSilentResponder.h b/src/SFML/Window/OSX/SFSilentResponder.h
index 0f00dd3..0a92244 100644
--- a/src/SFML/Window/OSX/SFSilentResponder.h
+++ b/src/SFML/Window/OSX/SFSilentResponder.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFSilentResponder.m b/src/SFML/Window/OSX/SFSilentResponder.m
index f256a2f..e576d77 100644
--- a/src/SFML/Window/OSX/SFSilentResponder.m
+++ b/src/SFML/Window/OSX/SFSilentResponder.m
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFViewController.h b/src/SFML/Window/OSX/SFViewController.h
index b6d0a0a..3907538 100644
--- a/src/SFML/Window/OSX/SFViewController.h
+++ b/src/SFML/Window/OSX/SFViewController.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFViewController.mm b/src/SFML/Window/OSX/SFViewController.mm
index 8e35f79..7d736e3 100644
--- a/src/SFML/Window/OSX/SFViewController.mm
+++ b/src/SFML/Window/OSX/SFViewController.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -121,6 +121,13 @@
}
+////////////////////////////////////////////////////////
+-(void)setCursorGrabbed:(BOOL)grabbed
+{
+ [m_oglView setCursorGrabbed:grabbed];
+}
+
+
////////////////////////////////////////////////////////////
-(NSPoint)position
{
diff --git a/src/SFML/Window/OSX/SFWindow.h b/src/SFML/Window/OSX/SFWindow.h
index 36ebc92..af0e10a 100644
--- a/src/SFML/Window/OSX/SFWindow.h
+++ b/src/SFML/Window/OSX/SFWindow.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFWindow.m b/src/SFML/Window/OSX/SFWindow.m
index 7a4ee75..2e8c14b 100644
--- a/src/SFML/Window/OSX/SFWindow.m
+++ b/src/SFML/Window/OSX/SFWindow.m
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/SFWindowController.h b/src/SFML/Window/OSX/SFWindowController.h
index 4435ad0..331336b 100644
--- a/src/SFML/Window/OSX/SFWindowController.h
+++ b/src/SFML/Window/OSX/SFWindowController.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -49,12 +49,19 @@ namespace sf {
/// Used when SFML handle everything and when a NSWindow* is given
/// as handle to WindowImpl.
///
+/// When grabbing the cursor, if the window is resizeable, m_restoreResize is
+/// set to YES and the window is marked as not resizeable. This is to prevent
+/// accidental resize by the user. When the cursor is released, the window
+/// style is restored.
+///
////////////////////////////////////////////////////////////
@interface SFWindowController : NSResponder <WindowImplDelegateProtocol, NSWindowDelegate>
{
NSWindow* m_window; ///< Underlying Cocoa window to be controlled
SFOpenGLView* m_oglView; ///< OpenGL view for rendering
sf::priv::WindowImplCocoa* m_requester; ///< Requester
+ BOOL m_fullscreen; ///< Indicate whether the window is fullscreen or not
+ BOOL m_restoreResize; ///< See note above
}
////////////////////////////////////////////////////////////
diff --git a/src/SFML/Window/OSX/SFWindowController.mm b/src/SFML/Window/OSX/SFWindowController.mm
index 1d2a915..a6e52ed 100644
--- a/src/SFML/Window/OSX/SFWindowController.mm
+++ b/src/SFML/Window/OSX/SFWindowController.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -32,7 +32,10 @@
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/System/Err.hpp>
#include <ApplicationServices/ApplicationServices.h>
+#include <algorithm>
+#import <SFML/Window/OSX/NSImage+raw.h>
+#import <SFML/Window/OSX/Scaling.h>
#import <SFML/Window/OSX/SFApplication.h>
#import <SFML/Window/OSX/SFOpenGLView.h>
#import <SFML/Window/OSX/SFWindow.h>
@@ -94,6 +97,8 @@
m_window = nil;
m_oglView = nil;
m_requester = 0;
+ m_fullscreen = NO; // assuming this is the case... too hard to handle anyway.
+ m_restoreResize = NO;
// Retain the window for our own use.
m_window = [window retain];
@@ -144,8 +149,10 @@
m_window = nil;
m_oglView = nil;
m_requester = 0;
+ m_fullscreen = (style & sf::Style::Fullscreen);
+ m_restoreResize = NO;
- if (style & sf::Style::Fullscreen)
+ if (m_fullscreen)
[self setupFullscreenViewWithMode:mode];
else
[self setupWindowWithMode:mode andStyle:style];
@@ -161,6 +168,7 @@
{
// Create a screen-sized window on the main display
sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
+ sf::priv::scaleInWidthHeight(desktop, nil);
NSRect windowRect = NSMakeRect(0, 0, desktop.width, desktop.height);
m_window = [[SFWindow alloc] initWithContentRect:windowRect
styleMask:NSBorderlessWindowMask
@@ -201,9 +209,11 @@
}
// Create our OpenGL view size and the view
- CGFloat x = (desktop.width - mode.width) / 2.0;
- CGFloat y = (desktop.height - mode.height) / 2.0;
- NSRect oglRect = NSMakeRect(x, y, mode.width, mode.height);
+ CGFloat width = std::min(mode.width, desktop.width);
+ CGFloat height = std::min(mode.height, desktop.height);
+ CGFloat x = (desktop.width - width) / 2.0;
+ CGFloat y = (desktop.height - height) / 2.0;
+ NSRect oglRect = NSMakeRect(x, y, width, height);
m_oglView = [[SFOpenGLView alloc] initWithFrame:oglRect
fullscreen:YES];
@@ -338,41 +348,66 @@
}
+////////////////////////////////////////////////////////
+-(void)setCursorGrabbed:(BOOL)grabbed
+{
+ // Remove or restore resizeable style if needed
+ BOOL resizeable = [m_window styleMask] & NSResizableWindowMask;
+ if (grabbed && resizeable)
+ {
+ m_restoreResize = YES;
+ NSUInteger newStyle = [m_window styleMask] & ~NSResizableWindowMask;
+ [m_window setStyleMask:newStyle];
+ }
+ else if (!grabbed && m_restoreResize)
+ {
+ m_restoreResize = NO;
+ NSUInteger newStyle = [m_window styleMask] | NSResizableWindowMask;
+ [m_window setStyleMask:newStyle];
+ }
+
+ // Forward to our view
+ [m_oglView setCursorGrabbed:grabbed];
+}
+
+
////////////////////////////////////////////////////////////
-(NSPoint)position
{
- // First, get the top left corner of the view in its own base system
- const NSPoint origin = [m_oglView frame].origin;
- const NSSize size = [m_oglView frame].size;
- const NSPoint topLeftCornerOfView = NSMakePoint(origin.x, origin.y + size.height);
- const NSPoint positionInView = [m_oglView convertPointToBacking:topLeftCornerOfView];
+ // Note: since 10.7 the conversion API works with NSRect
+ // instead of NSPoint. Therefore we use a NSRect but ignore
+ // its width and height.
- // Then, convert it to window base system
- const NSPoint positionInWindow = [m_oglView convertPoint:positionInView toView:nil];
- // here nil denotes the window containing the view
+ // Position of the bottom-left corner in the different coordinate systems:
+ NSRect corner = [m_oglView frame]; // bottom left; size is ignored
+ NSRect view = [m_oglView convertRectToBacking:corner];
+ NSRect window = [m_oglView convertRect:view toView:nil];
+ NSRect screen = [[m_oglView window] convertRectToScreen:window];
- // Next, convert it to the screen base system
- const NSPoint positionInScreen = [[m_oglView window] convertBaseToScreen:positionInWindow];
+ // Get the top-left corner in screen coordinates
+ CGFloat x = screen.origin.x;
+ CGFloat y = screen.origin.y + [m_oglView frame].size.height;
- // Finally, flip for SFML window coordinate system
- // Don't forget to discard the title bar !
- const NSPoint positionInSFML = NSMakePoint(positionInScreen.x,
- ([self screenHeight] - [self titlebarHeight]) - positionInScreen.y);
+ // Flip y-axis (titlebar was already taken into account above)
+ y = [self screenHeight] - y;
- return positionInSFML;
+ return NSMakePoint(x, y);
}
-////////////////////////////////////////////////////////.
+////////////////////////////////////////////////////////
-(void)setWindowPositionToX:(int)x Y:(int)y
{
NSPoint point = NSMakePoint(x, y);
- // Flip for SFML window coordinate system.
- point.y = [self screenHeight] - point.y;
+ // Flip for SFML window coordinate system and take titlebar into account
+ point.y = [self screenHeight] - point.y + [self titlebarHeight];
// Place the window.
[m_window setFrameTopLeftPoint:point];
+
+ // In case the cursor was grabbed we need to update its position
+ [m_oglView updateCursorGrabbed];
}
@@ -386,37 +421,57 @@
////////////////////////////////////////////////////////
-(void)resizeTo:(unsigned int)width by:(unsigned int)height
{
- // Before resizing, remove resizable mask to be able to resize
- // beyond the desktop boundaries.
- NSUInteger styleMask = [m_window styleMask];
+ if (m_fullscreen)
+ {
+ // Special case when fullscreen: only resize the opengl view
+ // and make sure the requested size is not bigger than the window.
+ sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
+ sf::priv::scaleInWidthHeight(desktop, nil);
- [m_window setStyleMask:styleMask ^ NSResizableWindowMask];
+ width = std::min(width, desktop.width);
+ height = std::min(height, desktop.height);
- // Add titlebar height.
- height += [self titlebarHeight];
+ CGFloat x = (desktop.width - width) / 2.0;
+ CGFloat y = (desktop.height - height) / 2.0;
+ NSRect oglRect = NSMakeRect(x, y, width, height);
- // Corner case: don't set the window height bigger than the screen height
- // or the view will be resized _later_ without generating a resize event.
- NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
- CGFloat maxVisibleHeight = screenFrame.size.height;
- if (height > maxVisibleHeight)
+ [m_oglView setFrame:oglRect];
+ [m_oglView setNeedsDisplay:YES];
+ }
+ else
{
- height = maxVisibleHeight;
+ // Before resizing, remove resizable mask to be able to resize
+ // beyond the desktop boundaries.
+ NSUInteger styleMask = [m_window styleMask];
- // The size is not the requested one, we fire an event
- if (m_requester != 0)
- m_requester->windowResized(width, height - [self titlebarHeight]);
- }
+ [m_window setStyleMask:styleMask ^ NSResizableWindowMask];
+
+ // Add titlebar height.
+ height += [self titlebarHeight];
- NSRect frame = NSMakeRect([m_window frame].origin.x,
- [m_window frame].origin.y,
- width,
- height);
+ // Corner case: don't set the window height bigger than the screen height
+ // or the view will be resized _later_ without generating a resize event.
+ NSRect screenFrame = [[NSScreen mainScreen] visibleFrame];
+ CGFloat maxVisibleHeight = screenFrame.size.height;
+ if (height > maxVisibleHeight)
+ {
+ height = maxVisibleHeight;
- [m_window setFrame:frame display:YES];
+ // The size is not the requested one, we fire an event
+ if (m_requester != 0)
+ m_requester->windowResized(width, height - [self titlebarHeight]);
+ }
- // And restore the mask
- [m_window setStyleMask:styleMask];
+ NSRect frame = NSMakeRect([m_window frame].origin.x,
+ [m_window frame].origin.y,
+ width,
+ height);
+
+ [m_window setFrame:frame display:YES];
+
+ // And restore the mask
+ [m_window setStyleMask:styleMask];
+ }
}
@@ -487,40 +542,13 @@
by:(unsigned int)height
with:(const sf::Uint8*)pixels
{
- // Create an empty image representation.
- NSBitmapImageRep* bitmap =
- [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:0 // if 0: only allocate memory
- pixelsWide:width
- pixelsHigh:height
- bitsPerSample:8 // The number of bits used to specify
- // one pixel in a single component of the data.
- samplesPerPixel:4 // 3 if no alpha, 4 with it
- hasAlpha:YES
- isPlanar:NO // I don't know what it is but it works
- colorSpaceName:NSCalibratedRGBColorSpace
- bytesPerRow:0 // 0 == determine automatically
- bitsPerPixel:0]; // 0 == determine automatically
-
- // Load data pixels.
- for (unsigned int y = 0; y < height; ++y)
- {
- for (unsigned int x = 0; x < width; ++x, pixels+=4)
- {
- NSUInteger pixel[4] = { pixels[0], pixels[1], pixels[2], pixels[3] };
- [bitmap setPixel:pixel atX:x y:y];
- }
- }
-
- // Create an image from the representation.
- NSImage* icon = [[NSImage alloc] initWithSize:NSMakeSize(width, height)];
- [icon addRepresentation:bitmap];
+ // Load image and set app icon.
+ NSImage* icon = [NSImage imageWithRawData:pixels
+ andSize:NSMakeSize(width, height)];
- // Set app icon.
[[SFApplication sharedApplication] setApplicationIconImage:icon];
- // Free up.
[icon release];
- [bitmap release];
}
@@ -591,3 +619,4 @@
}
@end
+
diff --git a/src/SFML/Window/OSX/Scaling.h b/src/SFML/Window/OSX/Scaling.h
new file mode 100644
index 0000000..ee5d29b
--- /dev/null
+++ b/src/SFML/Window/OSX/Scaling.h
@@ -0,0 +1,103 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
+// Laurent Gomila (laurent@sfml-dev.org)
+//
+// 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
+////////////////////////////////////////////////////////////
+#import <SFML/Window/OSX/WindowImplDelegateProtocol.h>
+
+#import <AppKit/AppKit.h>
+
+namespace sf
+{
+namespace priv
+{
+
+////////////////////////////////////////////////////////////
+/// \brief Get the scale factor of the main screen
+///
+////////////////////////////////////////////////////////////
+inline CGFloat getDefaultScaleFactor()
+{
+ return [[NSScreen mainScreen] backingScaleFactor];
+}
+
+////////////////////////////////////////////////////////////
+/// \brief Scale SFML coordinates to backing coordinates
+///
+/// \param in SFML coordinates to be converted
+/// \param delegate an object implementing WindowImplDelegateProtocol, or nil for default scale
+///
+////////////////////////////////////////////////////////////
+template <class T>
+void scaleIn(T& in, id<WindowImplDelegateProtocol> delegate)
+{
+ in /= delegate ? [delegate displayScaleFactor] : getDefaultScaleFactor();
+}
+
+template <class T>
+void scaleInWidthHeight(T& in, id<WindowImplDelegateProtocol> delegate)
+{
+ scaleIn(in.width, delegate);
+ scaleIn(in.height, delegate);
+}
+
+template <class T>
+void scaleInXY(T& in, id<WindowImplDelegateProtocol> delegate)
+{
+ scaleIn(in.x, delegate);
+ scaleIn(in.y, delegate);
+}
+
+////////////////////////////////////////////////////////////
+/// \brief Scale backing coordinates to SFML coordinates
+///
+/// \param out backing coordinates to be converted
+/// \param delegate an object implementing WindowImplDelegateProtocol, or nil for default scale
+///
+////////////////////////////////////////////////////////////
+template <class T>
+void scaleOut(T& out, id<WindowImplDelegateProtocol> delegate)
+{
+ out *= delegate ? [delegate displayScaleFactor] : getDefaultScaleFactor();
+}
+
+template <class T>
+void scaleOutWidthHeight(T& out, id<WindowImplDelegateProtocol> delegate)
+{
+ scaleOut(out.width, delegate);
+ scaleOut(out.height, delegate);
+}
+
+template <class T>
+void scaleOutXY(T& out, id<WindowImplDelegateProtocol> delegate)
+{
+ scaleOut(out.x, delegate);
+ scaleOut(out.y, delegate);
+}
+
+} // namespace priv
+} // namespace sf
+
diff --git a/src/SFML/Window/OSX/SensorImpl.cpp b/src/SFML/Window/OSX/SensorImpl.cpp
index 144c6d7..fb8fce1 100644
--- a/src/SFML/Window/OSX/SensorImpl.cpp
+++ b/src/SFML/Window/OSX/SensorImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/OSX/SensorImpl.hpp b/src/SFML/Window/OSX/SensorImpl.hpp
index 68b810e..c630c39 100644
--- a/src/SFML/Window/OSX/SensorImpl.hpp
+++ b/src/SFML/Window/OSX/SensorImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/OSX/VideoModeImpl.cpp b/src/SFML/Window/OSX/VideoModeImpl.cpp
index d83d17d..94d8edd 100644
--- a/src/SFML/Window/OSX/VideoModeImpl.cpp
+++ b/src/SFML/Window/OSX/VideoModeImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -50,6 +50,8 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
return modes;
}
+ VideoMode desktop = getDesktopMode();
+
// Loop on each mode and convert it into a sf::VideoMode object.
const CFIndex modesCount = CFArrayGetCount(cgmodes);
for (CFIndex i = 0; i < modesCount; i++)
@@ -58,6 +60,10 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
VideoMode mode = convertCGModeToSFMode(cgmode);
+ // Skip if bigger than desktop as we currently don't perform hard resolution switch
+ if ((mode.width > desktop.width) || (mode.height > desktop.height))
+ continue;
+
// If not yet listed we add it to our modes array.
if (std::find(modes.begin(), modes.end(), mode) == modes.end())
modes.push_back(mode);
@@ -73,12 +79,21 @@ std::vector<VideoMode> VideoModeImpl::getFullscreenModes()
////////////////////////////////////////////////////////////
VideoMode VideoModeImpl::getDesktopMode()
{
+ VideoMode mode; // RVO
+
+ // Rely exclusively on mode and convertCGModeToSFMode
+ // instead of display id and CGDisplayPixelsHigh/Wide.
+
CGDirectDisplayID display = CGMainDisplayID();
- return VideoMode(CGDisplayPixelsWide(display),
- CGDisplayPixelsHigh(display),
- displayBitsPerPixel(display));
+ CGDisplayModeRef cgmode = CGDisplayCopyDisplayMode(display);
+
+ mode = convertCGModeToSFMode(cgmode);
+
+ CGDisplayModeRelease(cgmode);
+
+ return mode;
}
} // namespace priv
-
} // namespace sf
+
diff --git a/src/SFML/Window/OSX/WindowImplCocoa.hpp b/src/SFML/Window/OSX/WindowImplCocoa.hpp
index 486bf78..1036f72 100644
--- a/src/SFML/Window/OSX/WindowImplCocoa.hpp
+++ b/src/SFML/Window/OSX/WindowImplCocoa.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -314,6 +314,14 @@ public:
virtual void setMouseCursorVisible(bool visible);
////////////////////////////////////////////////////////////
+ /// \brief Grab or release the mouse cursor
+ ///
+ /// \param grabbed True to grab, false to release
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setMouseCursorGrabbed(bool grabbed);
+
+ ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat
///
/// \param enabled True to enable, false to disable
diff --git a/src/SFML/Window/OSX/WindowImplCocoa.mm b/src/SFML/Window/OSX/WindowImplCocoa.mm
index 927d5b4..78be5af 100644
--- a/src/SFML/Window/OSX/WindowImplCocoa.mm
+++ b/src/SFML/Window/OSX/WindowImplCocoa.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -28,10 +28,10 @@
////////////////////////////////////////////////////////////
#include <SFML/Window/OSX/WindowImplCocoa.hpp>
#include <SFML/System/Err.hpp>
-#include <SFML/System/String.hpp>
#import <SFML/Window/OSX/AutoreleasePoolWrapper.h>
#import <SFML/Window/OSX/cpp_objc_conversion.h>
+#import <SFML/Window/OSX/Scaling.h>
#import <SFML/Window/OSX/SFApplication.h>
#import <SFML/Window/OSX/SFApplicationDelegate.h>
#import <SFML/Window/OSX/SFKeyboardModifiersHelper.h>
@@ -44,76 +44,6 @@ namespace priv
{
////////////////////////////////////////////////////////////
-/// \brief Get the scale factor of the main screen
-///
-////////////////////////////////////////////////////////////
-CGFloat getDefaultScaleFactor()
-{
- return [[NSScreen mainScreen] backingScaleFactor];
-}
-
-////////////////////////////////////////////////////////////
-/// \brief Scale SFML coordinates to backing coordinates
-///
-/// Use -[NSScreen backingScaleFactor] to find out if the user
-/// has a retina display or not.
-///
-/// \param in SFML coordinates to be converted
-/// \param delegate a object implementing WindowImplDelegateProtocol, or nil for default scale
-///
-////////////////////////////////////////////////////////////
-template <class T>
-void scaleIn(T& in, id<WindowImplDelegateProtocol> delegate)
-{
- in /= delegate ? [delegate displayScaleFactor] : getDefaultScaleFactor();
-}
-
-template <class T>
-void scaleInWidthHeight(T& in, id<WindowImplDelegateProtocol> delegate)
-{
- scaleIn(in.width, delegate);
- scaleIn(in.height, delegate);
-}
-
-template <class T>
-void scaleInXY(T& in, id<WindowImplDelegateProtocol> delegate)
-{
- scaleIn(in.x, delegate);
- scaleIn(in.y, delegate);
-}
-
-////////////////////////////////////////////////////////////
-/// \brief Scale backing coordinates to SFML coordinates
-///
-/// Use -[NSScreen backingScaleFactor] to find out if the user
-/// has a retina display or not.
-///
-/// \param out backing coordinates to be converted
-/// \param delegate a object implementing WindowImplDelegateProtocol, or nil for default scale
-///
-////////////////////////////////////////////////////////////
-template <class T>
-void scaleOut(T& out, id<WindowImplDelegateProtocol> delegate)
-{
- out *= delegate ? [delegate displayScaleFactor] : getDefaultScaleFactor();
-}
-
-template <class T>
-void scaleOutWidthHeight(T& out, id<WindowImplDelegateProtocol> delegate)
-{
- scaleOut(out.width, delegate);
- scaleOut(out.height, delegate);
-}
-
-template <class T>
-void scaleOutXY(T& out, id<WindowImplDelegateProtocol> delegate)
-{
- scaleOut(out.x, delegate);
- scaleOut(out.y, delegate);
-}
-
-
-////////////////////////////////////////////////////////////
/// According to Apple's documentation, each invocation of
/// unhide must be balanced by an invocation of hide in
/// order for the cursor display to be correct.
@@ -155,7 +85,7 @@ WindowImplCocoa::WindowImplCocoa(WindowHandle handle) :
m_showCursor(true)
{
// Ask for a pool.
- retainPool();
+ ensureThreadHasPool();
// Treat the handle as it real type
id nsHandle = (id)handle;
@@ -200,7 +130,7 @@ m_showCursor(true)
setUpProcess();
// Ask for a pool.
- retainPool();
+ ensureThreadHasPool();
// Use backing size
scaleInWidthHeight(mode, nil);
@@ -226,11 +156,9 @@ WindowImplCocoa::~WindowImplCocoa()
if ([windows count] > 0)
[[windows objectAtIndex:0] makeKeyAndOrderFront:nil];
- drainCurrentPool(); // Make sure everything was freed
+ drainThreadPool(); // Make sure everything was freed
// This solve some issue when sf::Window::Create is called for the
// second time (nothing was render until the function was called again)
-
- releasePool();
}
@@ -467,7 +395,7 @@ void WindowImplCocoa::textEntered(unichar charcode)
void WindowImplCocoa::processEvents()
{
[m_delegate processEvent];
- drainCurrentPool(); // Reduce memory footprint
+ drainThreadPool(); // Reduce memory footprint
}
#pragma mark
@@ -559,6 +487,13 @@ void WindowImplCocoa::setMouseCursorVisible(bool visible)
////////////////////////////////////////////////////////////
+void WindowImplCocoa::setMouseCursorGrabbed(bool grabbed)
+{
+ [m_delegate setCursorGrabbed:grabbed];
+}
+
+
+////////////////////////////////////////////////////////////
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
{
if (enabled)
@@ -585,3 +520,4 @@ bool WindowImplCocoa::hasFocus() const
} // namespace priv
} // namespace sf
+
diff --git a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h
index 0c4595c..4e0c327 100644
--- a/src/SFML/Window/OSX/WindowImplDelegateProtocol.h
+++ b/src/SFML/Window/OSX/WindowImplDelegateProtocol.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -97,6 +97,14 @@ namespace sf {
-(BOOL)isMouseInside;
////////////////////////////////////////////////////////////
+/// \brief Grab or release the mouse cursor
+///
+/// \param grabbed YES to grab, NO to release
+///
+////////////////////////////////////////////////////////////
+-(void)setCursorGrabbed:(BOOL)grabbed;
+
+////////////////////////////////////////////////////////////
/// \brief Get window position
///
/// \return Top left corner of the window or view
diff --git a/src/SFML/Window/OSX/cg_sf_conversion.hpp b/src/SFML/Window/OSX/cg_sf_conversion.hpp
index c0083f8..8b3845e 100644
--- a/src/SFML/Window/OSX/cg_sf_conversion.hpp
+++ b/src/SFML/Window/OSX/cg_sf_conversion.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/cg_sf_conversion.cpp b/src/SFML/Window/OSX/cg_sf_conversion.mm
index 60318cd..32495c3 100644
--- a/src/SFML/Window/OSX/cg_sf_conversion.cpp
+++ b/src/SFML/Window/OSX/cg_sf_conversion.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
@@ -29,6 +29,8 @@
#include <SFML/Window/OSX/cg_sf_conversion.hpp>
#include <SFML/System/Err.hpp>
+#import <SFML/Window/OSX/Scaling.h>
+
namespace sf
{
namespace priv
@@ -74,51 +76,22 @@ size_t displayBitsPerPixel(CGDirectDisplayID displayId)
////////////////////////////////////////////////////////////
VideoMode convertCGModeToSFMode(CGDisplayModeRef cgmode)
{
- return VideoMode(CGDisplayModeGetWidth(cgmode),
- CGDisplayModeGetHeight(cgmode),
- modeBitsPerPixel(cgmode));
-}
-
-
-////////////////////////////////////////////////////////////
-CGDisplayModeRef convertSFModeToCGMode(VideoMode sfmode)
-{
- // Starting with 10.6 we should query the display all the modes and
- // search for the best one.
-
- // Will return NULL if sfmode is not in VideoMode::GetFullscreenModes.
- CGDisplayModeRef cgbestMode = NULL;
-
- // Retrieve all modes available for main screen only.
- CFArrayRef cgmodes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL);
-
- if (cgmodes == NULL) // Should not happen but anyway...
- {
- sf::err() << "Couldn't get VideoMode for main display.";
- return NULL;
- }
-
- // Loop on each mode and convert it into a sf::VideoMode object.
- const CFIndex modesCount = CFArrayGetCount(cgmodes);
- for (CFIndex i = 0; i < modesCount; i++)
- {
- CGDisplayModeRef cgmode = (CGDisplayModeRef)CFArrayGetValueAtIndex(cgmodes, i);
-
- VideoMode mode = convertCGModeToSFMode(cgmode);
-
- if (mode == sfmode)
- cgbestMode = cgmode;
- }
-
- // Clean up memory.
- CFRelease(cgmodes);
-
- if (cgbestMode == NULL)
- sf::err() << "Couldn't convert the given sf:VideoMode into a CGDisplayMode."
- << std::endl;
-
- return cgbestMode;
+ // The main documentation says the sizes returned by
+ // CGDisplayModeGetWidth and CGDisplayModeGetHeight
+ // are expressed in pixels. However, some additional
+ // documentation [1] states they actually return
+ // values in points starting with 10.8.
+ //
+ // We therefore needs to use the scaling factor to
+ // convert the dimensions properly.
+ //
+ // [1]: "APIs for Supporting High Resolution" > "Additions and Changes for OS X v10.8"
+ // https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/APIs/APIs.html#//apple_ref/doc/uid/TP40012302-CH5-SW27
+ VideoMode mode(CGDisplayModeGetWidth(cgmode), CGDisplayModeGetHeight(cgmode), modeBitsPerPixel(cgmode));
+ scaleOutWidthHeight(mode, nil);
+ return mode;
}
} // namespace priv
} // namespace sf
+
diff --git a/src/SFML/Window/OSX/cpp_objc_conversion.h b/src/SFML/Window/OSX/cpp_objc_conversion.h
index 42f1557..9683a6e 100644
--- a/src/SFML/Window/OSX/cpp_objc_conversion.h
+++ b/src/SFML/Window/OSX/cpp_objc_conversion.h
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/OSX/cpp_objc_conversion.mm b/src/SFML/Window/OSX/cpp_objc_conversion.mm
index ea7c84b..539a41e 100644
--- a/src/SFML/Window/OSX/cpp_objc_conversion.mm
+++ b/src/SFML/Window/OSX/cpp_objc_conversion.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Marco Antognini (antognini.marco@gmail.com),
+// Copyright (C) 2007-2016 Marco Antognini (antognini.marco@gmail.com),
// Laurent Gomila (laurent@sfml-dev.org)
//
// This software is provided 'as-is', without any express or implied warranty.
diff --git a/src/SFML/Window/Sensor.cpp b/src/SFML/Window/Sensor.cpp
index 64b9fff..a2ddb2b 100644
--- a/src/SFML/Window/Sensor.cpp
+++ b/src/SFML/Window/Sensor.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/SensorImpl.hpp b/src/SFML/Window/SensorImpl.hpp
index 39ca794..25b44d2 100644
--- a/src/SFML/Window/SensorImpl.hpp
+++ b/src/SFML/Window/SensorImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/SensorManager.cpp b/src/SFML/Window/SensorManager.cpp
index dd3e7a0..319767d 100644
--- a/src/SFML/Window/SensorManager.cpp
+++ b/src/SFML/Window/SensorManager.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/SensorManager.hpp b/src/SFML/Window/SensorManager.hpp
index 2d9f9c1..a0faa87 100644
--- a/src/SFML/Window/SensorManager.hpp
+++ b/src/SFML/Window/SensorManager.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Touch.cpp b/src/SFML/Window/Touch.cpp
index 4ff400e..b2d9615 100644
--- a/src/SFML/Window/Touch.cpp
+++ b/src/SFML/Window/Touch.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/Display.cpp b/src/SFML/Window/Unix/Display.cpp
index c57ae0f..a078b97 100644
--- a/src/SFML/Window/Unix/Display.cpp
+++ b/src/SFML/Window/Unix/Display.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/Display.hpp b/src/SFML/Window/Unix/Display.hpp
index 2b33c96..2743678 100644
--- a/src/SFML/Window/Unix/Display.hpp
+++ b/src/SFML/Window/Unix/Display.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/GlxContext.cpp b/src/SFML/Window/Unix/GlxContext.cpp
index c89c9d3..7251db2 100644
--- a/src/SFML/Window/Unix/GlxContext.cpp
+++ b/src/SFML/Window/Unix/GlxContext.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -31,6 +31,7 @@
#include <SFML/System/Mutex.hpp>
#include <SFML/System/Lock.hpp>
#include <SFML/System/Err.hpp>
+#include <vector>
#if !defined(GLX_DEBUGGING) && defined(SFML_DEBUG)
// Enable this to print messages to err() everytime GLX produces errors
@@ -53,8 +54,8 @@ namespace
public:
GlxErrorHandler(::Display* display) :
- m_display(display),
- m_lock (glxErrorMutex)
+ m_lock (glxErrorMutex),
+ m_display(display)
{
glxErrorOccurred = false;
m_previousHandler = XSetErrorHandler(HandleXError);
@@ -95,101 +96,73 @@ void ensureExtensionsInit(::Display* display, int screen)
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared) :
+m_display (NULL),
m_window (0),
m_context (NULL),
-m_ownsWindow(true)
+m_pbuffer (0),
+m_ownsWindow(false)
{
- // Open a connection with the X server
- m_display = OpenDisplay();
- m_connection = XGetXCBConnection(m_display);
- xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display));
+ // Save the creation settings
+ m_settings = ContextSettings();
- // Choose the visual according to the context settings
- XVisualInfo visualInfo = selectBestVisual(m_display, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
+ // Make sure that extensions are initialized if this is not the shared context
+ // The shared context is the context used to initialize the extensions
+ if (shared && shared->m_display)
+ ensureExtensionsInit(shared->m_display, DefaultScreen(shared->m_display));
- // Define the window attributes
- xcb_colormap_t colormap = xcb_generate_id(m_connection);
- xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid);
- const uint32_t value_list[] = {colormap};
-
- // Create a dummy window (disabled and hidden)
- m_window = xcb_generate_id(m_connection);
- xcb_create_window(
- m_connection,
- static_cast<uint8_t>(visualInfo.depth),
- m_window,
- screen->root,
- 0, 0,
- 1, 1,
- 0,
- XCB_WINDOW_CLASS_INPUT_OUTPUT,
- visualInfo.visualid,
- XCB_CW_COLORMAP,
- value_list
- );
+ // Create the rendering surface (window or pbuffer if supported)
+ createSurface(shared, 1, 1, VideoMode::getDesktopMode().bitsPerPixel);
// Create the context
- createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
+ createContext(shared);
}
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
+m_display (NULL),
m_window (0),
m_context (NULL),
+m_pbuffer (0),
m_ownsWindow(false)
{
- // Open a connection with the X server
- // (important: must be the same display as the owner window)
- m_display = OpenDisplay();
- m_connection = XGetXCBConnection(m_display);
+ // Save the creation settings
+ m_settings = settings;
- // Get the owner window and its device context
- m_window = static_cast< ::Window>(owner->getSystemHandle());
+ // Make sure that extensions are initialized if this is not the shared context
+ // The shared context is the context used to initialize the extensions
+ if (shared && shared->m_display)
+ ensureExtensionsInit(shared->m_display, DefaultScreen(shared->m_display));
+
+ // Create the rendering surface from the owner window
+ createSurface(static_cast< ::Window>(owner->getSystemHandle()));
// Create the context
- if (m_window)
- createContext(shared, bitsPerPixel, settings);
+ createContext(shared);
}
////////////////////////////////////////////////////////////
GlxContext::GlxContext(GlxContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) :
+m_display (NULL),
m_window (0),
m_context (NULL),
-m_ownsWindow(true)
+m_pbuffer (0),
+m_ownsWindow(false)
{
- // Open a connection with the X server
- m_display = OpenDisplay();
- m_connection = XGetXCBConnection(m_display);
- xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display));
+ // Save the creation settings
+ m_settings = settings;
- // Choose the visual according to the context settings
- XVisualInfo visualInfo = selectBestVisual(m_display, VideoMode::getDesktopMode().bitsPerPixel, settings);
+ // Make sure that extensions are initialized if this is not the shared context
+ // The shared context is the context used to initialize the extensions
+ if (shared && shared->m_display)
+ ensureExtensionsInit(shared->m_display, DefaultScreen(shared->m_display));
- // Define the window attributes
- xcb_colormap_t colormap = xcb_generate_id(m_connection);
- xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid);
- const uint32_t value_list[] = {colormap};
-
- // Create the hidden window
- m_window = xcb_generate_id(m_connection);
- xcb_create_window(
- m_connection,
- static_cast<uint8_t>(visualInfo.depth),
- m_window,
- screen->root,
- 0, 0,
- width, height,
- 0,
- XCB_WINDOW_CLASS_INPUT_OUTPUT,
- visualInfo.visualid,
- XCB_CW_COLORMAP,
- value_list
- );
+ // Create the rendering surface (window or pbuffer if supported)
+ createSurface(shared, width, height, VideoMode::getDesktopMode().bitsPerPixel);
// Create the context
- createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings);
+ createContext(shared);
}
@@ -213,6 +186,11 @@ GlxContext::~GlxContext()
#endif
}
+ if (m_pbuffer)
+ {
+ glXDestroyPbuffer(m_display, m_pbuffer);
+ }
+
// Destroy the window if we own it
if (m_window && m_ownsWindow)
{
@@ -242,7 +220,16 @@ bool GlxContext::makeCurrent()
GlxErrorHandler handler(m_display);
#endif
- bool result = glXMakeCurrent(m_display, m_window, m_context);
+ bool result = false;
+
+ if (m_pbuffer)
+ {
+ result = glXMakeContextCurrent(m_display, m_pbuffer, m_pbuffer, m_context);
+ }
+ else if (m_window)
+ {
+ result = glXMakeCurrent(m_display, m_window, m_context);
+ }
#if defined(GLX_DEBUGGING)
if (glxErrorOccurred)
@@ -260,7 +247,9 @@ void GlxContext::display()
GlxErrorHandler handler(m_display);
#endif
- if (m_window)
+ if (m_pbuffer)
+ glXSwapBuffers(m_display, m_pbuffer);
+ else if (m_window)
glXSwapBuffers(m_display, m_window);
#if defined(GLX_DEBUGGING)
@@ -284,7 +273,7 @@ void GlxContext::setVerticalSyncEnabled(bool enabled)
// which would require us to link in an additional library
if (sfglx_ext_EXT_swap_control == sfglx_LOAD_SUCCEEDED)
{
- glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0);
+ glXSwapIntervalEXT(m_display, m_pbuffer ? m_pbuffer : m_window, enabled ? 1 : 0);
}
else if (sfglx_ext_MESA_swap_control == sfglx_LOAD_SUCCEEDED)
{
@@ -321,7 +310,7 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
{
// Evaluate all the returned visuals, and pick the best one
int bestScore = 0x7FFFFFFF;
- XVisualInfo bestVisual;
+ XVisualInfo bestVisual = XVisualInfo();
for (int i = 0; i < count; ++i)
{
// Check mandatory attributes
@@ -331,7 +320,7 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
continue;
// Extract the components of the current visual
- int red, green, blue, alpha, depth, stencil, multiSampling, samples;
+ int red, green, blue, alpha, depth, stencil, multiSampling, samples, sRgb;
glXGetConfig(display, &visuals[i], GLX_RED_SIZE, &red);
glXGetConfig(display, &visuals[i], GLX_GREEN_SIZE, &green);
glXGetConfig(display, &visuals[i], GLX_BLUE_SIZE, &blue);
@@ -350,12 +339,21 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
samples = 0;
}
+ if ((sfglx_ext_EXT_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED) || (sfglx_ext_ARB_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED))
+ {
+ glXGetConfig(display, &visuals[i], GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &sRgb);
+ }
+ else
+ {
+ sRgb = 0;
+ }
+
// TODO: Replace this with proper acceleration detection
bool accelerated = true;
// Evaluate the visual
int color = red + green + blue + alpha;
- int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0, accelerated);
+ int score = evaluateFormat(bitsPerPixel, settings, color, depth, stencil, multiSampling ? samples : 0, accelerated, sRgb == True);
// If it's better than the current best, make it the new best
if (score < bestScore)
@@ -379,12 +377,45 @@ XVisualInfo GlxContext::selectBestVisual(::Display* display, unsigned int bitsPe
}
}
+
////////////////////////////////////////////////////////////
-void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
+void GlxContext::updateSettingsFromVisualInfo(XVisualInfo* visualInfo)
{
- // Save the creation settings
- m_settings = settings;
+ // Update the creation settings from the chosen format
+ int depth, stencil, multiSampling, samples, sRgb;
+ glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth);
+ glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil);
+
+ if (sfglx_ext_ARB_multisample == sfglx_LOAD_SUCCEEDED)
+ {
+ glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
+ glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples);
+ }
+ else
+ {
+ multiSampling = 0;
+ samples = 0;
+ }
+ if ((sfglx_ext_EXT_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED) || (sfglx_ext_ARB_framebuffer_sRGB == sfglx_LOAD_SUCCEEDED))
+ {
+ glXGetConfig(m_display, visualInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB, &sRgb);
+ }
+ else
+ {
+ sRgb = 0;
+ }
+
+ m_settings.depthBits = static_cast<unsigned int>(depth);
+ m_settings.stencilBits = static_cast<unsigned int>(stencil);
+ m_settings.antialiasingLevel = multiSampling ? samples : 0;
+ m_settings.sRgbCapable = (sRgb == True);
+}
+
+
+////////////////////////////////////////////////////////////
+void GlxContext::updateSettingsFromWindow()
+{
// Retrieve the attributes of the target window
XWindowAttributes windowAttributes;
if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0)
@@ -400,6 +431,180 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
int nbVisuals = 0;
XVisualInfo* visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
+ if (!visualInfo)
+ return;
+
+ updateSettingsFromVisualInfo(visualInfo);
+
+ XFree(visualInfo);
+}
+
+
+////////////////////////////////////////////////////////////
+void GlxContext::createSurface(GlxContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel)
+{
+ m_display = OpenDisplay();
+ m_connection = XGetXCBConnection(m_display);
+
+ // Choose the visual according to the context settings
+ XVisualInfo visualInfo = selectBestVisual(m_display, bitsPerPixel, m_settings);
+
+ // Check if the shared context already exists and pbuffers are supported
+ if (shared && (sfglx_ext_SGIX_pbuffer == sfglx_LOAD_SUCCEEDED))
+ {
+ // There are no GLX versions prior to 1.0
+ int major = 0;
+ int minor = 0;
+
+ glXQueryVersion(m_display, &major, &minor);
+
+ // Check if glXCreatePbuffer is available (requires GLX 1.3 or greater)
+ bool hasCreatePbuffer = ((major > 1) || (minor >= 3));
+
+ if (hasCreatePbuffer)
+ {
+ // Get a GLXFBConfig that matches the visual
+ GLXFBConfig* config = NULL;
+
+ // We don't supply attributes to match against, since
+ // the visual we are matching against was already
+ // deemed suitable in selectBestVisual()
+ int nbConfigs = 0;
+ GLXFBConfig* configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), NULL, &nbConfigs);
+
+ for (int i = 0; configs && (i < nbConfigs); ++i)
+ {
+ XVisualInfo* visual = glXGetVisualFromFBConfig(m_display, configs[i]);
+
+ if (!visual)
+ continue;
+
+ if (visual->visualid == visualInfo.visualid)
+ {
+ config = &configs[i];
+ break;
+ }
+ }
+
+ if (config)
+ {
+ int attributes[] =
+ {
+ GLX_PBUFFER_WIDTH, static_cast<int>(width),
+ GLX_PBUFFER_HEIGHT, static_cast<int>(height),
+ 0, 0
+ };
+
+ m_pbuffer = glXCreatePbuffer(m_display, *config, attributes);
+
+ updateSettingsFromVisualInfo(&visualInfo);
+
+ XFree(configs);
+
+ return;
+ }
+
+ if (configs)
+ XFree(configs);
+ }
+ }
+
+ // If pbuffers are not available we use a hidden window as the off-screen surface to draw to
+ xcb_screen_t* screen = XCBScreenOfDisplay(m_connection, DefaultScreen(m_display));
+
+ // Define the window attributes
+ xcb_colormap_t colormap = xcb_generate_id(m_connection);
+ xcb_create_colormap(m_connection, XCB_COLORMAP_ALLOC_NONE, colormap, screen->root, visualInfo.visualid);
+ const uint32_t value_list[] = {colormap};
+
+ // Create a dummy window (disabled and hidden)
+ m_window = xcb_generate_id(m_connection);
+ xcb_create_window(
+ m_connection,
+ static_cast<uint8_t>(visualInfo.depth),
+ m_window,
+ screen->root,
+ 0, 0,
+ width, height,
+ 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ visualInfo.visualid,
+ XCB_CW_COLORMAP,
+ value_list
+ );
+
+ m_ownsWindow = true;
+
+ updateSettingsFromWindow();
+}
+
+
+////////////////////////////////////////////////////////////
+void GlxContext::createSurface(::Window window)
+{
+ m_display = OpenDisplay();
+ m_connection = XGetXCBConnection(m_display);
+
+ // A window already exists, so just use it
+ m_window = window;
+
+ updateSettingsFromWindow();
+}
+
+
+////////////////////////////////////////////////////////////
+void GlxContext::createContext(GlxContext* shared)
+{
+ // Get a working copy of the context settings
+ ContextSettings settings = m_settings;
+
+ XVisualInfo* visualInfo = NULL;
+
+ if (m_pbuffer)
+ {
+ unsigned int fbConfigId = 0;
+
+ glXQueryDrawable(m_display, m_pbuffer, GLX_FBCONFIG_ID, &fbConfigId);
+
+ int attributes[] =
+ {
+ GLX_FBCONFIG_ID, static_cast<int>(fbConfigId),
+ 0, 0
+ };
+
+ int count = 0;
+ GLXFBConfig* fbconfig = glXChooseFBConfig(m_display, DefaultScreen(m_display), attributes, &count);
+
+ if (count == 1)
+ visualInfo = glXGetVisualFromFBConfig(m_display, *fbconfig);
+
+ if (fbconfig)
+ XFree(fbconfig);
+ }
+ else
+ {
+ // Retrieve the attributes of the target window
+ XWindowAttributes windowAttributes;
+ if (XGetWindowAttributes(m_display, m_window, &windowAttributes) == 0)
+ {
+ err() << "Failed to get the window attributes" << std::endl;
+ return;
+ }
+
+ // Get its visuals
+ XVisualInfo tpl;
+ tpl.screen = DefaultScreen(m_display);
+ tpl.visualid = XVisualIDFromVisual(windowAttributes.visual);
+ int nbVisuals = 0;
+ visualInfo = XGetVisualInfo(m_display, VisualIDMask | VisualScreenMask, &tpl, &nbVisuals);
+ }
+
+ if (!visualInfo)
+ {
+ err() << "Failed to get visual info" << std::endl;
+ return;
+ }
+
// Get the context to share display lists with
GLXContext toShare = shared ? shared->m_context : NULL;
@@ -410,26 +615,13 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
if (!glXQueryVersion(m_display, &major, &minor))
err() << "Failed to query GLX version, limited to legacy context creation" << std::endl;
- // Make sure that extensions are initialized if this is not the shared context
- // The shared context is the context used to initialize the extensions
- if (shared)
- ensureExtensionsInit(m_display, DefaultScreen(m_display));
-
// Check if glXCreateContextAttribsARB is available (requires GLX 1.3 or greater)
bool hasCreateContextArb = (sfglx_ext_ARB_create_context == sfglx_LOAD_SUCCEEDED) && ((major > 1) || (minor >= 3));
- // Check if we need to use glXCreateContextAttribsARB
- bool needCreateContextArb = false;
-
- if (m_settings.attributeFlags)
- needCreateContextArb = true;
- else if (m_settings.majorVersion >= 3)
- needCreateContextArb = true;
-
- // Create the OpenGL context -- first try using glXCreateContextAttribsARB if we need to
- if (hasCreateContextArb && needCreateContextArb)
+ // Create the OpenGL context -- first try using glXCreateContextAttribsARB
+ if (hasCreateContextArb)
{
- // Get a GLXFBConfig that matches the the window's visual, for glXCreateContextAttribsARB
+ // Get a GLXFBConfig that matches the window's visual, for glXCreateContextAttribsARB
GLXFBConfig* config = NULL;
// We don't supply attributes to match against, since
@@ -457,27 +649,27 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
while (config && !m_context && m_settings.majorVersion)
{
+ std::vector<int> attributes;
+
+ // Check if the user requested a specific context version (anything > 1.1)
+ if ((m_settings.majorVersion > 1) || ((m_settings.majorVersion == 1) && (m_settings.minorVersion > 1)))
+ {
+ attributes.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
+ attributes.push_back(m_settings.majorVersion);
+ attributes.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
+ attributes.push_back(m_settings.minorVersion);
+ }
+
// Check if setting the profile is supported
if (sfglx_ext_ARB_create_context_profile == sfglx_LOAD_SUCCEEDED)
{
int profile = (m_settings.attributeFlags & ContextSettings::Core) ? GLX_CONTEXT_CORE_PROFILE_BIT_ARB : GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
int debug = (m_settings.attributeFlags & ContextSettings::Debug) ? GLX_CONTEXT_DEBUG_BIT_ARB : 0;
- // Create the context
- int attributes[] =
- {
- GLX_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
- GLX_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
- GLX_CONTEXT_PROFILE_MASK_ARB, profile,
- GLX_CONTEXT_FLAGS_ARB, debug,
- 0, 0
- };
-
- // RAII GLX error handler (we simply ignore errors here)
- // On an error, glXCreateContextAttribsARB will return 0 anyway
- GlxErrorHandler handler(m_display);
-
- m_context = glXCreateContextAttribsARB(m_display, *config, toShare, true, attributes);
+ attributes.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
+ attributes.push_back(profile);
+ attributes.push_back(GLX_CONTEXT_FLAGS_ARB);
+ attributes.push_back(debug);
}
else
{
@@ -486,21 +678,18 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
<< "disabling comptibility and debug" << std::endl;
m_settings.attributeFlags = ContextSettings::Default;
+ }
- // Create the context
- int attributes[] =
- {
- GLX_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
- GLX_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
- 0, 0
- };
+ // Append the terminating 0
+ attributes.push_back(0);
+ attributes.push_back(0);
- // RAII GLX error handler (we simply ignore errors here)
- // On an error, glXCreateContextAttribsARB will return 0 anyway
- GlxErrorHandler handler(m_display);
+ // RAII GLX error handler (we simply ignore errors here)
+ // On an error, glXCreateContextAttribsARB will return 0 anyway
+ GlxErrorHandler handler(m_display);
- m_context = glXCreateContextAttribsARB(m_display, *config, toShare, true, attributes);
- }
+ // Create the context
+ m_context = glXCreateContextAttribsARB(m_display, *config, toShare, true, &attributes[0]);
if (!m_context)
{
@@ -555,31 +744,7 @@ void GlxContext::createContext(GlxContext* shared, unsigned int bitsPerPixel, co
}
if (!m_context)
- {
err() << "Failed to create an OpenGL context for this window" << std::endl;
- }
- else
- {
- // Update the creation settings from the chosen format
- int depth, stencil, multiSampling, samples;
- glXGetConfig(m_display, visualInfo, GLX_DEPTH_SIZE, &depth);
- glXGetConfig(m_display, visualInfo, GLX_STENCIL_SIZE, &stencil);
-
- if (sfglx_ext_ARB_multisample == sfglx_LOAD_SUCCEEDED)
- {
- glXGetConfig(m_display, visualInfo, GLX_SAMPLE_BUFFERS_ARB, &multiSampling);
- glXGetConfig(m_display, visualInfo, GLX_SAMPLES_ARB, &samples);
- }
- else
- {
- multiSampling = 0;
- samples = 0;
- }
-
- m_settings.depthBits = static_cast<unsigned int>(depth);
- m_settings.stencilBits = static_cast<unsigned int>(stencil);
- m_settings.antialiasingLevel = multiSampling ? samples : 0;
- }
// Free the visual info
XFree(visualInfo);
diff --git a/src/SFML/Window/Unix/GlxContext.hpp b/src/SFML/Window/Unix/GlxContext.hpp
index e1ad899..4a9444f 100644
--- a/src/SFML/Window/Unix/GlxContext.hpp
+++ b/src/SFML/Window/Unix/GlxContext.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -133,14 +133,45 @@ public:
private:
////////////////////////////////////////////////////////////
- /// \brief Create the context
+ /// \brief Update the context visual settings from XVisualInfo
+ ///
+ /// \param visualInfo XVisualInfo to update settings from
+ ///
+ ////////////////////////////////////////////////////////////
+ void updateSettingsFromVisualInfo(XVisualInfo* visualInfo);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Update the context visual settings from the window
+ ///
+ ////////////////////////////////////////////////////////////
+ void updateSettingsFromWindow();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create the context's drawing surface
///
/// \param shared Context to share the new one with (can be NULL)
+ /// \param width Back buffer width, in pixels
+ /// \param height Back buffer height, in pixels
/// \param bitsPerPixel Pixel depth, in bits per pixel
- /// \param settings Creation parameters
///
////////////////////////////////////////////////////////////
- void createContext(GlxContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings);
+ void createSurface(GlxContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create the context's drawing surface from an existing window
+ ///
+ /// \param window Window ID of the owning window
+ ///
+ ////////////////////////////////////////////////////////////
+ void createSurface(::Window window);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create the context
+ ///
+ /// \param shared Context to share the new one with (can be NULL)
+ ///
+ ////////////////////////////////////////////////////////////
+ void createContext(GlxContext* shared);
////////////////////////////////////////////////////////////
// Member data
@@ -149,6 +180,7 @@ private:
::Window m_window; ///< Window to which the context is attached
xcb_connection_t* m_connection; ///< Pointer to the xcb connection
GLXContext m_context; ///< OpenGL context
+ GLXPbuffer m_pbuffer; ///< GLX pbuffer ID if one was created
bool m_ownsWindow; ///< Do we own the window associated to the context?
};
diff --git a/src/SFML/Window/Unix/GlxExtensions.cpp b/src/SFML/Window/Unix/GlxExtensions.cpp
index 029095c..e418e2e 100644
--- a/src/SFML/Window/Unix/GlxExtensions.cpp
+++ b/src/SFML/Window/Unix/GlxExtensions.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -30,6 +30,7 @@
#include <cstdlib>
#include <cstring>
#include <cstddef>
+#include <string>
static sf::GlFunctionPointer IntGetProcAddress(const char* name)
{
@@ -39,17 +40,21 @@ static sf::GlFunctionPointer IntGetProcAddress(const char* name)
int sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED;
int sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED;
int sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED;
+int sfglx_ext_EXT_framebuffer_sRGB = sfglx_LOAD_FAILED;
+int sfglx_ext_ARB_framebuffer_sRGB = sfglx_LOAD_FAILED;
int sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED;
+int sfglx_ext_SGIX_pbuffer = sfglx_LOAD_FAILED;
int sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED;
int sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED;
-void (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalEXT)(Display *, GLXDrawable, int) = NULL;
+void (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalEXT)(Display*, GLXDrawable, int) = NULL;
static int Load_EXT_swap_control(void)
{
int numFailed = 0;
- sf_ptrc_glXSwapIntervalEXT = (void (CODEGEN_FUNCPTR *)(Display *, GLXDrawable, int))IntGetProcAddress("glXSwapIntervalEXT");
- if(!sf_ptrc_glXSwapIntervalEXT) numFailed++;
+ sf_ptrc_glXSwapIntervalEXT = reinterpret_cast<void (CODEGEN_FUNCPTR*)(Display*, GLXDrawable, int)>(IntGetProcAddress("glXSwapIntervalEXT"));
+ if (!sf_ptrc_glXSwapIntervalEXT)
+ numFailed++;
return numFailed;
}
@@ -58,8 +63,9 @@ int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalMESA)(int) = NULL;
static int Load_MESA_swap_control(void)
{
int numFailed = 0;
- sf_ptrc_glXSwapIntervalMESA = (int (CODEGEN_FUNCPTR *)(int))IntGetProcAddress("glXSwapIntervalMESA");
- if(!sf_ptrc_glXSwapIntervalMESA) numFailed++;
+ sf_ptrc_glXSwapIntervalMESA = reinterpret_cast<int (CODEGEN_FUNCPTR*)(int)>(IntGetProcAddress("glXSwapIntervalMESA"));
+ if (!sf_ptrc_glXSwapIntervalMESA)
+ numFailed++;
return numFailed;
}
@@ -68,74 +74,110 @@ int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalSGI)(int) = NULL;
static int Load_SGI_swap_control(void)
{
int numFailed = 0;
- sf_ptrc_glXSwapIntervalSGI = (int (CODEGEN_FUNCPTR *)(int))IntGetProcAddress("glXSwapIntervalSGI");
- if(!sf_ptrc_glXSwapIntervalSGI) numFailed++;
+ sf_ptrc_glXSwapIntervalSGI = reinterpret_cast<int (CODEGEN_FUNCPTR *)(int)>(IntGetProcAddress("glXSwapIntervalSGI"));
+ if (!sf_ptrc_glXSwapIntervalSGI)
+ numFailed++;
return numFailed;
}
-GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *) = NULL;
+GLXPbufferSGIX (CODEGEN_FUNCPTR *sf_ptrc_glXCreateGLXPbufferSGIX)(Display*, GLXFBConfigSGIX, unsigned int, unsigned int, int*) = NULL;
+void (CODEGEN_FUNCPTR *sf_ptrc_glXDestroyGLXPbufferSGIX)(Display*, GLXPbufferSGIX) = NULL;
+void (CODEGEN_FUNCPTR *sf_ptrc_glXGetSelectedEventSGIX)(Display*, GLXDrawable, unsigned long*) = NULL;
+int (CODEGEN_FUNCPTR *sf_ptrc_glXQueryGLXPbufferSGIX)(Display*, GLXPbufferSGIX, int, unsigned int*) = NULL;
+void (CODEGEN_FUNCPTR *sf_ptrc_glXSelectEventSGIX)(Display*, GLXDrawable, unsigned long) = NULL;
+
+static int Load_SGIX_pbuffer(void)
+{
+ int numFailed = 0;
+ sf_ptrc_glXCreateGLXPbufferSGIX = reinterpret_cast<GLXPbufferSGIX (CODEGEN_FUNCPTR*)(Display*, GLXFBConfigSGIX, unsigned int, unsigned int, int*)>(IntGetProcAddress("glXCreateGLXPbufferSGIX"));
+ if (!sf_ptrc_glXCreateGLXPbufferSGIX)
+ numFailed++;
+ sf_ptrc_glXDestroyGLXPbufferSGIX = reinterpret_cast<void (CODEGEN_FUNCPTR*)(Display*, GLXPbufferSGIX)>(IntGetProcAddress("glXDestroyGLXPbufferSGIX"));
+ if (!sf_ptrc_glXDestroyGLXPbufferSGIX)
+ numFailed++;
+ sf_ptrc_glXGetSelectedEventSGIX = reinterpret_cast<void (CODEGEN_FUNCPTR*)(Display*, GLXDrawable, unsigned long*)>(IntGetProcAddress("glXGetSelectedEventSGIX"));
+ if (!sf_ptrc_glXGetSelectedEventSGIX)
+ numFailed++;
+ sf_ptrc_glXQueryGLXPbufferSGIX = reinterpret_cast<int (CODEGEN_FUNCPTR*)(Display*, GLXPbufferSGIX, int, unsigned int*)>(IntGetProcAddress("glXQueryGLXPbufferSGIX"));
+ if (!sf_ptrc_glXQueryGLXPbufferSGIX)
+ numFailed++;
+ sf_ptrc_glXSelectEventSGIX = reinterpret_cast<void (CODEGEN_FUNCPTR*)(Display*, GLXDrawable, unsigned long)>(IntGetProcAddress("glXSelectEventSGIX"));
+ if (!sf_ptrc_glXSelectEventSGIX)
+ numFailed++;
+ return numFailed;
+}
+
+GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display*, GLXFBConfig, GLXContext, Bool, const int*) = NULL;
static int Load_ARB_create_context(void)
{
int numFailed = 0;
- sf_ptrc_glXCreateContextAttribsARB = (GLXContext (CODEGEN_FUNCPTR *)(Display *, GLXFBConfig, GLXContext, Bool, const int *))IntGetProcAddress("glXCreateContextAttribsARB");
- if(!sf_ptrc_glXCreateContextAttribsARB) numFailed++;
+ sf_ptrc_glXCreateContextAttribsARB = reinterpret_cast<GLXContext (CODEGEN_FUNCPTR*)(Display*, GLXFBConfig, GLXContext, Bool, const int*)>(IntGetProcAddress("glXCreateContextAttribsARB"));
+ if (!sf_ptrc_glXCreateContextAttribsARB)
+ numFailed++;
return numFailed;
}
typedef int (*PFN_LOADFUNCPOINTERS)(void);
typedef struct sfglx_StrToExtMap_s
{
- const char *extensionName;
- int *extensionVariable;
+ const char* extensionName;
+ int* extensionVariable;
PFN_LOADFUNCPOINTERS LoadExtension;
} sfglx_StrToExtMap;
-static sfglx_StrToExtMap ExtensionMap[6] = {
+static sfglx_StrToExtMap ExtensionMap[9] = {
{"GLX_EXT_swap_control", &sfglx_ext_EXT_swap_control, Load_EXT_swap_control},
{"GLX_MESA_swap_control", &sfglx_ext_MESA_swap_control, Load_MESA_swap_control},
{"GLX_SGI_swap_control", &sfglx_ext_SGI_swap_control, Load_SGI_swap_control},
+ {"GLX_EXT_framebuffer_sRGB", &sfglx_ext_EXT_framebuffer_sRGB, NULL},
+ {"GLX_ARB_framebuffer_sRGB", &sfglx_ext_ARB_framebuffer_sRGB, NULL},
{"GLX_ARB_multisample", &sfglx_ext_ARB_multisample, NULL},
+ {"GLX_SGIX_pbuffer", &sfglx_ext_SGIX_pbuffer, Load_SGIX_pbuffer},
{"GLX_ARB_create_context", &sfglx_ext_ARB_create_context, Load_ARB_create_context},
- {"GLX_ARB_create_context_profile", &sfglx_ext_ARB_create_context_profile, NULL},
+ {"GLX_ARB_create_context_profile", &sfglx_ext_ARB_create_context_profile, NULL}
};
-static int g_extensionMapSize = 6;
+static int g_extensionMapSize = 9;
+
-static sfglx_StrToExtMap *FindExtEntry(const char *extensionName)
+static sfglx_StrToExtMap* FindExtEntry(const char* extensionName)
{
- int loop;
- sfglx_StrToExtMap *currLoc = ExtensionMap;
- for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
+ sfglx_StrToExtMap* currLoc = ExtensionMap;
+ for (int loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
{
- if(strcmp(extensionName, currLoc->extensionName) == 0)
+ if (std::strcmp(extensionName, currLoc->extensionName) == 0)
return currLoc;
}
return NULL;
}
+
static void ClearExtensionVars(void)
{
sfglx_ext_EXT_swap_control = sfglx_LOAD_FAILED;
sfglx_ext_MESA_swap_control = sfglx_LOAD_FAILED;
sfglx_ext_SGI_swap_control = sfglx_LOAD_FAILED;
+ sfglx_ext_EXT_framebuffer_sRGB = sfglx_LOAD_FAILED;
+ sfglx_ext_ARB_framebuffer_sRGB = sfglx_LOAD_FAILED;
sfglx_ext_ARB_multisample = sfglx_LOAD_FAILED;
+ sfglx_ext_SGIX_pbuffer = sfglx_LOAD_FAILED;
sfglx_ext_ARB_create_context = sfglx_LOAD_FAILED;
sfglx_ext_ARB_create_context_profile = sfglx_LOAD_FAILED;
}
-static void LoadExtByName(const char *extensionName)
+static void LoadExtByName(const char* extensionName)
{
- sfglx_StrToExtMap *entry = NULL;
+ sfglx_StrToExtMap* entry = NULL;
entry = FindExtEntry(extensionName);
- if(entry)
+ if (entry)
{
- if(entry->LoadExtension)
+ if (entry->LoadExtension)
{
int numFailed = entry->LoadExtension();
- if(numFailed == 0)
+ if (numFailed == 0)
{
*(entry->extensionVariable) = sfglx_LOAD_SUCCEEDED;
}
@@ -152,46 +194,25 @@ static void LoadExtByName(const char *extensionName)
}
-static void ProcExtsFromExtString(const char *strExtList)
+static void ProcExtsFromExtString(const char* strExtList)
{
- size_t iExtListLen = strlen(strExtList);
- const char *strExtListEnd = strExtList + iExtListLen;
- const char *strCurrPos = strExtList;
- char strWorkBuff[256];
-
- while(*strCurrPos)
+ do
{
- /*Get the extension at our position.*/
- int iStrLen = 0;
- const char *strEndStr = strchr(strCurrPos, ' ');
- int iStop = 0;
- if(strEndStr == NULL)
- {
- strEndStr = strExtListEnd;
- iStop = 1;
- }
-
- iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos);
-
- if(iStrLen > 255)
- return;
+ const char* begin = strExtList;
- strncpy(strWorkBuff, strCurrPos, iStrLen);
- strWorkBuff[iStrLen] = '\0';
+ while ((*strExtList != ' ') && *strExtList)
+ strExtList++;
- LoadExtByName(strWorkBuff);
-
- strCurrPos = strEndStr + 1;
- if(iStop) break;
- }
+ LoadExtByName(std::string(begin, strExtList).c_str());
+ } while (*strExtList++);
}
-int sfglx_LoadFunctions(Display *display, int screen)
+
+int sfglx_LoadFunctions(Display* display, int screen)
{
ClearExtensionVars();
- ProcExtsFromExtString((const char *)glXQueryExtensionsString(display, screen));
+ ProcExtsFromExtString(reinterpret_cast<const char*>(glXQueryExtensionsString(display, screen)));
return sfglx_LOAD_SUCCEEDED;
}
-
diff --git a/src/SFML/Window/Unix/GlxExtensions.hpp b/src/SFML/Window/Unix/GlxExtensions.hpp
index 9e9a749..44c9165 100644
--- a/src/SFML/Window/Unix/GlxExtensions.hpp
+++ b/src/SFML/Window/Unix/GlxExtensions.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -36,7 +36,7 @@
#include <GL/glx.h>
#ifdef CODEGEN_FUNCPTR
#undef CODEGEN_FUNCPTR
-#endif /*CODEGEN_FUNCPTR*/
+#endif // CODEGEN_FUNCPTR
#define CODEGEN_FUNCPTR
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
@@ -58,21 +58,21 @@ typedef double GLdouble;
typedef double GLclampd;
#define GLvoid void
-#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
+#endif // GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
-#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
+#endif // GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
#ifndef GLEXT_64_TYPES_DEFINED
-/* This code block is duplicated in glext.h, so must be protected */
+// This code block is duplicated in glext.h, so must be protected
#define GLEXT_64_TYPES_DEFINED
-/* Define int32_t, int64_t, and uint64_t types for UST/MSC */
-/* (as used in the GLX_OML_sync_control extension). */
+// Define int32_t, int64_t, and uint64_t types for UST/MSC
+// (as used in the GLX_OML_sync_control extension).
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#include <inttypes.h>
#elif defined(__sun__) || defined(__digital__)
@@ -84,8 +84,8 @@ typedef unsigned long int uint64_t;
#else
typedef long long int int64_t;
typedef unsigned long long int uint64_t;
-#endif /* __arch64__ */
-#endif /* __STDC__ */
+#endif // __arch64__
+#endif // __STDC__
#elif defined( __VMS ) || defined(__sgi)
#include <inttypes.h>
#elif defined(__SCO__) || defined(__USLC__)
@@ -101,7 +101,7 @@ typedef __int32 int32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
-/* Fallback if nothing above works */
+// Fallback if nothing above works
#include <inttypes.h>
#endif
#endif
@@ -118,42 +118,75 @@ typedef unsigned __int64 uint64_t;
typedef struct __GLXFBConfigRec *GLXFBConfigSGIX;
typedef XID GLXPbufferSGIX;
typedef struct {
- char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ char pipeName[80]; // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
int networkId;
} GLXHyperpipeNetworkSGIX;
typedef struct {
- char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ char pipeName[80]; // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
int channel;
unsigned int participationType;
int timeSlice;
} GLXHyperpipeConfigSGIX;
typedef struct {
- char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ char pipeName[80]; // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
int srcXOrigin, srcYOrigin, srcWidth, srcHeight;
int destXOrigin, destYOrigin, destWidth, destHeight;
} GLXPipeRect;
typedef struct {
- char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */
+ char pipeName[80]; // Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX]
int XOrigin, YOrigin, maxHeight, maxWidth;
} GLXPipeRectLimits;
#ifdef __cplusplus
extern "C" {
-#endif /*__cplusplus*/
+#endif // __cplusplus
extern int sfglx_ext_EXT_swap_control;
extern int sfglx_ext_MESA_swap_control;
extern int sfglx_ext_SGI_swap_control;
+extern int sfglx_ext_EXT_framebuffer_sRGB;
+extern int sfglx_ext_ARB_framebuffer_sRGB;
extern int sfglx_ext_ARB_multisample;
+extern int sfglx_ext_SGIX_pbuffer;
extern int sfglx_ext_ARB_create_context;
extern int sfglx_ext_ARB_create_context_profile;
#define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2
#define GLX_SWAP_INTERVAL_EXT 0x20F1
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20B2
+
+#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2
+
#define GLX_SAMPLES_ARB 100001
#define GLX_SAMPLE_BUFFERS_ARB 100000
+#define GLX_ACCUM_BUFFER_BIT_SGIX 0x00000080
+#define GLX_AUX_BUFFERS_BIT_SGIX 0x00000010
+#define GLX_BACK_LEFT_BUFFER_BIT_SGIX 0x00000004
+#define GLX_BACK_RIGHT_BUFFER_BIT_SGIX 0x00000008
+#define GLX_BUFFER_CLOBBER_MASK_SGIX 0x08000000
+#define GLX_DAMAGED_SGIX 0x8020
+#define GLX_DEPTH_BUFFER_BIT_SGIX 0x00000020
+#define GLX_EVENT_MASK_SGIX 0x801F
+#define GLX_FRONT_LEFT_BUFFER_BIT_SGIX 0x00000001
+#define GLX_FRONT_RIGHT_BUFFER_BIT_SGIX 0x00000002
+#define GLX_HEIGHT_SGIX 0x801E
+#define GLX_LARGEST_PBUFFER_SGIX 0x801C
+#define GLX_MAX_PBUFFER_HEIGHT_SGIX 0x8017
+#define GLX_MAX_PBUFFER_PIXELS_SGIX 0x8018
+#define GLX_MAX_PBUFFER_WIDTH_SGIX 0x8016
+#define GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX 0x801A
+#define GLX_OPTIMAL_PBUFFER_WIDTH_SGIX 0x8019
+#define GLX_PBUFFER_BIT_SGIX 0x00000004
+#define GLX_PBUFFER_SGIX 0x8023
+#define GLX_PRESERVED_CONTENTS_SGIX 0x801B
+#define GLX_SAMPLE_BUFFERS_BIT_SGIX 0x00000100
+#define GLX_SAVED_SGIX 0x8021
+#define GLX_STENCIL_BUFFER_BIT_SGIX 0x00000040
+#define GLX_WIDTH_SGIX 0x801D
+#define GLX_WINDOW_SGIX 0x8022
+
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
@@ -168,7 +201,7 @@ extern int sfglx_ext_ARB_create_context_profile;
#define GLX_EXT_swap_control 1
extern void (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalEXT)(Display *, GLXDrawable, int);
#define glXSwapIntervalEXT sf_ptrc_glXSwapIntervalEXT
-#endif /*GLX_EXT_swap_control*/
+#endif // GLX_EXT_swap_control
// Declare entry point even if GLX header already provides glXSwapIntervalMESA
// We won't make use of an alias here
@@ -178,13 +211,27 @@ extern int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalMESA)(int);
#define GLX_SGI_swap_control 1
extern int (CODEGEN_FUNCPTR *sf_ptrc_glXSwapIntervalSGI)(int);
#define glXSwapIntervalSGI sf_ptrc_glXSwapIntervalSGI
-#endif /*GLX_SGI_swap_control*/
+#endif // GLX_SGI_swap_control
+
+#ifndef GLX_SGIX_pbuffer
+#define GLX_SGIX_pbuffer 1
+extern GLXPbufferSGIX (CODEGEN_FUNCPTR *sf_ptrc_glXCreateGLXPbufferSGIX)(Display*, GLXFBConfigSGIX, unsigned int, unsigned int, int*);
+#define glXCreateGLXPbufferSGIX sf_ptrc_glXCreateGLXPbufferSGIX
+extern void (CODEGEN_FUNCPTR *sf_ptrc_glXDestroyGLXPbufferSGIX)(Display*, GLXPbufferSGIX);
+#define glXDestroyGLXPbufferSGIX sf_ptrc_glXDestroyGLXPbufferSGIX
+extern void (CODEGEN_FUNCPTR *sf_ptrc_glXGetSelectedEventSGIX)(Display*, GLXDrawable, unsigned long*);
+#define glXGetSelectedEventSGIX sf_ptrc_glXGetSelectedEventSGIX
+extern int (CODEGEN_FUNCPTR *sf_ptrc_glXQueryGLXPbufferSGIX)(Display*, GLXPbufferSGIX, int, unsigned int*);
+#define glXQueryGLXPbufferSGIX sf_ptrc_glXQueryGLXPbufferSGIX
+extern void (CODEGEN_FUNCPTR *sf_ptrc_glXSelectEventSGIX)(Display*, GLXDrawable, unsigned long);
+#define glXSelectEventSGIX sf_ptrc_glXSelectEventSGIX
+#endif // GLX_SGIX_pbuffer
#ifndef GLX_ARB_create_context
#define GLX_ARB_create_context 1
-extern GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
+extern GLXContext (CODEGEN_FUNCPTR *sf_ptrc_glXCreateContextAttribsARB)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
#define glXCreateContextAttribsARB sf_ptrc_glXCreateContextAttribsARB
-#endif /*GLX_ARB_create_context*/
+#endif // GLX_ARB_create_context
enum sfglx_LoadStatus
@@ -198,6 +245,6 @@ int sfglx_LoadFunctions(Display *display, int screen);
#ifdef __cplusplus
}
-#endif /*__cplusplus*/
+#endif // __cplusplus
-#endif /* SF_POINTER_C_GENERATED_HEADER_GLXWIN_HPP */
+#endif // SF_POINTER_C_GENERATED_HEADER_GLXWIN_HPP
diff --git a/src/SFML/Window/Unix/GlxExtensions.txt b/src/SFML/Window/Unix/GlxExtensions.txt
index b6b06fa..9c8a641 100644
--- a/src/SFML/Window/Unix/GlxExtensions.txt
+++ b/src/SFML/Window/Unix/GlxExtensions.txt
@@ -1,11 +1,14 @@
// Created with:
-// https://bitbucket.org/Anteru/glloadgen-reloaded
-// Commit 20f19482b7a844d20b9785c3e3fd1f16419f6e0a
+// https://bitbucket.org/KhronosGroup/glloadgen
+// Commit d143d66ac90d538ed06f806188714861b8e8e2f9
// lua LoadGen.lua -style=pointer_c -spec=glX -indent=space -prefix=sf -extfile=GlxExtensions.txt GlxExtensions
EXT_swap_control
// MESA_swap_control
SGI_swap_control
+EXT_framebuffer_sRGB
+ARB_framebuffer_sRGB
GLX_ARB_multisample
+GLX_SGIX_pbuffer
GLX_ARB_create_context
-GLX_ARB_create_context_profile \ No newline at end of file
+GLX_ARB_create_context_profile
diff --git a/src/SFML/Window/Unix/InputImpl.cpp b/src/SFML/Window/Unix/InputImpl.cpp
index 53d92be..ad62cd5 100644
--- a/src/SFML/Window/Unix/InputImpl.cpp
+++ b/src/SFML/Window/Unix/InputImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/InputImpl.hpp b/src/SFML/Window/Unix/InputImpl.hpp
index 9425c3d..f61647d 100644
--- a/src/SFML/Window/Unix/InputImpl.hpp
+++ b/src/SFML/Window/Unix/InputImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/JoystickImpl.cpp b/src/SFML/Window/Unix/JoystickImpl.cpp
index d60075d..903d588 100644
--- a/src/SFML/Window/Unix/JoystickImpl.cpp
+++ b/src/SFML/Window/Unix/JoystickImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -440,6 +440,14 @@ namespace sf
namespace priv
{
////////////////////////////////////////////////////////////
+JoystickImpl::JoystickImpl() :
+m_file(-1)
+{
+ std::fill(m_mapping, m_mapping + ABS_MAX + 1, 0);
+}
+
+
+////////////////////////////////////////////////////////////
void JoystickImpl::initialize()
{
udevContext = udev_new();
@@ -650,19 +658,23 @@ JoystickState JoystickImpl::JoystickImpl::update()
case JS_EVENT_AXIS:
{
float value = joyState.value * 100.f / 32767.f;
- switch (m_mapping[joyState.number])
+
+ if (joyState.number < ABS_MAX + 1)
{
- case ABS_X: m_state.axes[Joystick::X] = value; break;
- case ABS_Y: m_state.axes[Joystick::Y] = value; break;
- case ABS_Z:
- case ABS_THROTTLE: m_state.axes[Joystick::Z] = value; break;
- case ABS_RZ:
- case ABS_RUDDER: m_state.axes[Joystick::R] = value; break;
- case ABS_RX: m_state.axes[Joystick::U] = value; break;
- case ABS_RY: m_state.axes[Joystick::V] = value; break;
- case ABS_HAT0X: m_state.axes[Joystick::PovX] = value; break;
- case ABS_HAT0Y: m_state.axes[Joystick::PovY] = value; break;
- default: break;
+ switch (m_mapping[joyState.number])
+ {
+ case ABS_X: m_state.axes[Joystick::X] = value; break;
+ case ABS_Y: m_state.axes[Joystick::Y] = value; break;
+ case ABS_Z:
+ case ABS_THROTTLE: m_state.axes[Joystick::Z] = value; break;
+ case ABS_RZ:
+ case ABS_RUDDER: m_state.axes[Joystick::R] = value; break;
+ case ABS_RX: m_state.axes[Joystick::U] = value; break;
+ case ABS_RY: m_state.axes[Joystick::V] = value; break;
+ case ABS_HAT0X: m_state.axes[Joystick::PovX] = value; break;
+ case ABS_HAT0Y: m_state.axes[Joystick::PovY] = value; break;
+ default: break;
+ }
}
break;
}
diff --git a/src/SFML/Window/Unix/JoystickImpl.hpp b/src/SFML/Window/Unix/JoystickImpl.hpp
index 34fce2e..e454b03 100644
--- a/src/SFML/Window/Unix/JoystickImpl.hpp
+++ b/src/SFML/Window/Unix/JoystickImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -45,6 +45,12 @@ class JoystickImpl
public:
////////////////////////////////////////////////////////////
+ /// \brief Constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ JoystickImpl();
+
+ ////////////////////////////////////////////////////////////
/// \brief Perform the global initialization of the joystick module
///
////////////////////////////////////////////////////////////
diff --git a/src/SFML/Window/Unix/ScopedXcbPtr.hpp b/src/SFML/Window/Unix/ScopedXcbPtr.hpp
index 6c98065..f610d81 100644
--- a/src/SFML/Window/Unix/ScopedXcbPtr.hpp
+++ b/src/SFML/Window/Unix/ScopedXcbPtr.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/ScopedXcbPtr.inl b/src/SFML/Window/Unix/ScopedXcbPtr.inl
index 6683a1e..5869d91 100644
--- a/src/SFML/Window/Unix/ScopedXcbPtr.inl
+++ b/src/SFML/Window/Unix/ScopedXcbPtr.inl
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/SensorImpl.cpp b/src/SFML/Window/Unix/SensorImpl.cpp
index 144c6d7..fb8fce1 100644
--- a/src/SFML/Window/Unix/SensorImpl.cpp
+++ b/src/SFML/Window/Unix/SensorImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/SensorImpl.hpp b/src/SFML/Window/Unix/SensorImpl.hpp
index 49ced87..7006377 100644
--- a/src/SFML/Window/Unix/SensorImpl.hpp
+++ b/src/SFML/Window/Unix/SensorImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/VideoModeImpl.cpp b/src/SFML/Window/Unix/VideoModeImpl.cpp
index 9ee812f..f95d323 100644
--- a/src/SFML/Window/Unix/VideoModeImpl.cpp
+++ b/src/SFML/Window/Unix/VideoModeImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Unix/WindowImplX11.cpp b/src/SFML/Window/Unix/WindowImplX11.cpp
index 7aaf4e4..88176bf 100644
--- a/src/SFML/Window/Unix/WindowImplX11.cpp
+++ b/src/SFML/Window/Unix/WindowImplX11.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -34,6 +34,7 @@
#include <SFML/System/Err.hpp>
#include <SFML/System/Mutex.hpp>
#include <SFML/System/Lock.hpp>
+#include <SFML/System/Sleep.hpp>
#include <xcb/xcb_image.h>
#include <xcb/randr.h>
#include <X11/Xlibint.h>
@@ -69,7 +70,10 @@ namespace
XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_MOTION |
XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_KEY_PRESS |
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
- XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW;
+ XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW |
+ XCB_EVENT_MASK_VISIBILITY_CHANGE;
+
+ static const unsigned int maxTrialsCount = 5;
// Filter the events received by windows (only allow those matching a specific window)
Bool checkEvent(::Display*, XEvent* event, XPointer userData)
@@ -358,6 +362,7 @@ namespace priv
////////////////////////////////////////////////////////////
WindowImplX11::WindowImplX11(WindowHandle handle) :
m_window (0),
+m_screen (NULL),
m_inputMethod (NULL),
m_inputContext (NULL),
m_isExternal (true),
@@ -365,7 +370,9 @@ m_hiddenCursor (0),
m_keyRepeat (true),
m_previousSize (-1, -1),
m_useSizeHints (false),
-m_fullscreen (false)
+m_fullscreen (false),
+m_cursorGrabbed (false),
+m_windowMapped (false)
{
// Open a connection with the X server
m_display = OpenDisplay();
@@ -411,6 +418,7 @@ m_fullscreen (false)
////////////////////////////////////////////////////////////
WindowImplX11::WindowImplX11(VideoMode mode, const String& title, unsigned long style, const ContextSettings& settings) :
m_window (0),
+m_screen (NULL),
m_inputMethod (NULL),
m_inputContext (NULL),
m_isExternal (false),
@@ -418,7 +426,9 @@ m_hiddenCursor (0),
m_keyRepeat (true),
m_previousSize (-1, -1),
m_useSizeHints (false),
-m_fullscreen ((style & Style::Fullscreen) != 0)
+m_fullscreen ((style & Style::Fullscreen) != 0),
+m_cursorGrabbed (m_fullscreen),
+m_windowMapped (false)
{
// Open a connection with the X server
m_display = OpenDisplay();
@@ -732,7 +742,7 @@ void WindowImplX11::setTitle(const String& title)
err() << "Failed to set _NET_WM_NAME property" << std::endl;
}
- if (utf8StringType && netWmName)
+ if (utf8StringType && netWmIconName)
{
if (!changeWindowProperty(netWmIconName, utf8StringType, 8, utf8String.length(), utf8String.c_str()))
err() << "Failed to set _NET_WM_ICON_NAME property" << std::endl;
@@ -909,6 +919,13 @@ void WindowImplX11::setVisible(bool visible)
if (error)
err() << "Failed to change window visibility" << std::endl;
+
+ xcb_flush(m_connection);
+
+ // Before continuing, make sure the WM has
+ // internally marked the window as viewable
+ while (!m_windowMapped)
+ processEvents();
}
else
{
@@ -922,9 +939,14 @@ void WindowImplX11::setVisible(bool visible)
if (error)
err() << "Failed to change window visibility" << std::endl;
- }
- xcb_flush(m_connection);
+ xcb_flush(m_connection);
+
+ // Before continuing, make sure the WM has
+ // internally marked the window as unviewable
+ while (m_windowMapped)
+ processEvents();
+ }
}
@@ -951,6 +973,71 @@ void WindowImplX11::setMouseCursorVisible(bool visible)
////////////////////////////////////////////////////////////
+void WindowImplX11::setMouseCursorGrabbed(bool grabbed)
+{
+ // This has no effect in fullscreen mode
+ if (m_fullscreen || (m_cursorGrabbed == grabbed))
+ return;
+
+ if (grabbed)
+ {
+ // Try multiple times to grab the cursor
+ for (unsigned int trial = 0; trial < maxTrialsCount; ++trial)
+ {
+ sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
+
+ sf::priv::ScopedXcbPtr<xcb_grab_pointer_reply_t> grabPointerReply(xcb_grab_pointer_reply(
+ m_connection,
+ xcb_grab_pointer(
+ m_connection,
+ true,
+ m_window,
+ XCB_NONE,
+ XCB_GRAB_MODE_ASYNC,
+ XCB_GRAB_MODE_ASYNC,
+ m_window,
+ XCB_NONE,
+ XCB_CURRENT_TIME
+ ),
+ &error
+ ));
+
+ if (!error && grabPointerReply && (grabPointerReply->status == XCB_GRAB_STATUS_SUCCESS))
+ {
+ m_cursorGrabbed = true;
+ break;
+ }
+
+ // The cursor grab failed, trying again after a small sleep
+ sf::sleep(sf::milliseconds(50));
+ }
+
+ if (!m_cursorGrabbed)
+ err() << "Failed to grab mouse cursor" << std::endl;
+ }
+ else
+ {
+ ScopedXcbPtr<xcb_generic_error_t> error(xcb_request_check(
+ m_connection,
+ xcb_ungrab_pointer_checked(
+ m_connection,
+ XCB_CURRENT_TIME
+ )
+ ));
+
+ if (!error)
+ {
+ m_cursorGrabbed = false;
+ }
+ else
+ {
+ err() << "Failed to ungrab mouse cursor" << std::endl;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
void WindowImplX11::setKeyRepeatEnabled(bool enabled)
{
m_keyRepeat = enabled;
@@ -1604,7 +1691,7 @@ void WindowImplX11::cleanup()
////////////////////////////////////////////////////////////
-bool WindowImplX11::processEvent(XEvent windowEvent)
+bool WindowImplX11::processEvent(XEvent& windowEvent)
{
// This function implements a workaround to properly discard
// repeated key events when necessary. The problem is that the
@@ -1659,6 +1746,44 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
if (m_inputContext)
XSetICFocus(m_inputContext);
+ // Grab cursor
+ if (m_cursorGrabbed)
+ {
+ // Try multiple times to grab the cursor
+ for (unsigned int trial = 0; trial < maxTrialsCount; ++trial)
+ {
+ sf::priv::ScopedXcbPtr<xcb_generic_error_t> error(NULL);
+
+ sf::priv::ScopedXcbPtr<xcb_grab_pointer_reply_t> grabPointerReply(xcb_grab_pointer_reply(
+ m_connection,
+ xcb_grab_pointer(
+ m_connection,
+ true,
+ m_window,
+ XCB_NONE,
+ XCB_GRAB_MODE_ASYNC,
+ XCB_GRAB_MODE_ASYNC,
+ m_window,
+ XCB_NONE,
+ XCB_CURRENT_TIME
+ ),
+ &error
+ ));
+
+ if (!error && grabPointerReply && (grabPointerReply->status == XCB_GRAB_STATUS_SUCCESS))
+ {
+ m_cursorGrabbed = true;
+ break;
+ }
+
+ // The cursor grab failed, trying again after a small sleep
+ sf::sleep(sf::milliseconds(50));
+ }
+
+ if (!m_cursorGrabbed)
+ err() << "Failed to grab mouse cursor" << std::endl;
+ }
+
Event event;
event.type = Event::GainedFocus;
pushEvent(event);
@@ -1701,6 +1826,21 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
if (m_inputContext)
XUnsetICFocus(m_inputContext);
+ // Release cursor
+ if (m_cursorGrabbed)
+ {
+ ScopedXcbPtr<xcb_generic_error_t> error(xcb_request_check(
+ m_connection,
+ xcb_ungrab_pointer_checked(
+ m_connection,
+ XCB_CURRENT_TIME
+ )
+ ));
+
+ if (error)
+ err() << "Failed to ungrab mouse cursor" << std::endl;
+ }
+
Event event;
event.type = Event::LostFocus;
pushEvent(event);
@@ -1757,17 +1897,23 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
// Key down event
case KeyPress:
{
- // Get the keysym of the key that has been pressed
- static XComposeStatus keyboard;
- char buffer[32];
- KeySym symbol;
- XLookupString(&windowEvent.xkey, buffer, sizeof(buffer), &symbol, &keyboard);
+ Keyboard::Key key = Keyboard::Unknown;
+
+ // Try each KeySym index (modifier group) until we get a match
+ for (int i = 0; i < 4; ++i)
+ {
+ // Get the SFML keyboard code from the keysym of the key that has been pressed
+ key = keysymToSF(XLookupKeysym(&windowEvent.xkey, i));
+
+ if (key != Keyboard::Unknown)
+ break;
+ }
// Fill the event parameters
// TODO: if modifiers are wrong, use XGetModifierMapping to retrieve the actual modifiers mapping
Event event;
event.type = Event::KeyPressed;
- event.key.code = keysymToSF(symbol);
+ event.key.code = key;
event.key.alt = windowEvent.xkey.state & Mod1Mask;
event.key.control = windowEvent.xkey.state & ControlMask;
event.key.shift = windowEvent.xkey.state & ShiftMask;
@@ -1826,15 +1972,22 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
// Key up event
case KeyRelease:
{
- // Get the keysym of the key that has been pressed
- char buffer[32];
- KeySym symbol;
- XLookupString(&windowEvent.xkey, buffer, 32, &symbol, NULL);
+ Keyboard::Key key = Keyboard::Unknown;
+
+ // Try each KeySym index (modifier group) until we get a match
+ for (int i = 0; i < 4; ++i)
+ {
+ // Get the SFML keyboard code from the keysym of the key that has been released
+ key = keysymToSF(XLookupKeysym(&windowEvent.xkey, i));
+
+ if (key != Keyboard::Unknown)
+ break;
+ }
// Fill the event parameters
Event event;
event.type = Event::KeyReleased;
- event.key.code = keysymToSF(symbol);
+ event.key.code = key;
event.key.alt = windowEvent.xkey.state & Mod1Mask;
event.key.control = windowEvent.xkey.state & ControlMask;
event.key.shift = windowEvent.xkey.state & ShiftMask;
@@ -1962,16 +2115,33 @@ bool WindowImplX11::processEvent(XEvent windowEvent)
break;
}
- // Parent window changed
- case ReparentNotify:
+ // Window unmapped
+ case UnmapNotify:
{
- // Catch reparent events to properly apply fullscreen on
- // some "strange" window managers (like Awesome) which
- // seem to make use of temporary parents during mapping
- if (m_fullscreen)
- switchToFullscreen();
+ if (windowEvent.xunmap.window == m_window)
+ m_windowMapped = false;
+
+ break;
+ }
+
+ // Window visibility change
+ case VisibilityNotify:
+ {
+ // We prefer using VisibilityNotify over MapNotify because
+ // some window managers like awesome don't internally flag a
+ // window as viewable even after it is mapped but before it
+ // is visible leading to certain function calls failing with
+ // an unviewable error if called before VisibilityNotify arrives
+
+ // Empirical testing on most widely used window managers shows
+ // that mapping a window will always lead to a VisibilityNotify
+ // event that is not VisibilityFullyObscured
+ if (windowEvent.xvisibility.window == m_window)
+ {
+ if (windowEvent.xvisibility.state != VisibilityFullyObscured)
+ m_windowMapped = true;
+ }
- XSync(m_display, True); // Discard remaining events
break;
}
}
diff --git a/src/SFML/Window/Unix/WindowImplX11.hpp b/src/SFML/Window/Unix/WindowImplX11.hpp
index a717bfb..ea6f741 100644
--- a/src/SFML/Window/Unix/WindowImplX11.hpp
+++ b/src/SFML/Window/Unix/WindowImplX11.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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,6 +148,14 @@ public:
virtual void setMouseCursorVisible(bool visible);
////////////////////////////////////////////////////////////
+ /// \brief Grab or release the mouse cursor
+ ///
+ /// \param grabbed True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setMouseCursorGrabbed(bool grabbed);
+
+ ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat
///
/// \param enabled True to enable, false to disable
@@ -301,7 +309,7 @@ private:
/// \return True if the event was processed, false if it was discarded
///
////////////////////////////////////////////////////////////
- bool processEvent(XEvent windowEvent);
+ bool processEvent(XEvent& windowEvent);
////////////////////////////////////////////////////////////
// Member data
@@ -318,7 +326,9 @@ private:
bool m_keyRepeat; ///< Is the KeyRepeat feature enabled?
Vector2i m_previousSize; ///< Previous size of the window, to find if a ConfigureNotify event is a resize event (could be a move event only)
bool m_useSizeHints; ///< Is the size of the window fixed with size hints?
- bool m_fullscreen; ///< Is window in fullscreen?
+ bool m_fullscreen; ///< Is the window in fullscreen?
+ bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
+ bool m_windowMapped; ///< Has the window been mapped by the window manager?
};
} // namespace priv
diff --git a/src/SFML/Window/VideoMode.cpp b/src/SFML/Window/VideoMode.cpp
index 8f3861d..2202d77 100644
--- a/src/SFML/Window/VideoMode.cpp
+++ b/src/SFML/Window/VideoMode.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/VideoModeImpl.hpp b/src/SFML/Window/VideoModeImpl.hpp
index cc992f9..f1a1b03 100644
--- a/src/SFML/Window/VideoModeImpl.hpp
+++ b/src/SFML/Window/VideoModeImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/InputImpl.cpp b/src/SFML/Window/Win32/InputImpl.cpp
index 6b1a472..8be35ec 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-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/InputImpl.hpp b/src/SFML/Window/Win32/InputImpl.hpp
index 9f455f4..598ef62 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-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/JoystickImpl.cpp b/src/SFML/Window/Win32/JoystickImpl.cpp
index ab40d5f..50cc819 100644
--- a/src/SFML/Window/Win32/JoystickImpl.cpp
+++ b/src/SFML/Window/Win32/JoystickImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/JoystickImpl.hpp b/src/SFML/Window/Win32/JoystickImpl.hpp
index ab0a724..591b0e8 100644
--- a/src/SFML/Window/Win32/JoystickImpl.hpp
+++ b/src/SFML/Window/Win32/JoystickImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/SensorImpl.cpp b/src/SFML/Window/Win32/SensorImpl.cpp
index 144c6d7..fb8fce1 100644
--- a/src/SFML/Window/Win32/SensorImpl.cpp
+++ b/src/SFML/Window/Win32/SensorImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/SensorImpl.hpp b/src/SFML/Window/Win32/SensorImpl.hpp
index 666e5d2..8bea45b 100644
--- a/src/SFML/Window/Win32/SensorImpl.hpp
+++ b/src/SFML/Window/Win32/SensorImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/VideoModeImpl.cpp b/src/SFML/Window/Win32/VideoModeImpl.cpp
index 4b34a0f..90f522f 100644
--- a/src/SFML/Window/Win32/VideoModeImpl.cpp
+++ b/src/SFML/Window/Win32/VideoModeImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/Win32/WglContext.cpp b/src/SFML/Window/Win32/WglContext.cpp
index c4e8b93..486946f 100644
--- a/src/SFML/Window/Win32/WglContext.cpp
+++ b/src/SFML/Window/Win32/WglContext.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -26,12 +26,13 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/WindowImpl.hpp> // included first to avoid a warning about macro redefinition
+#include <SFML/OpenGL.hpp> // included second to avoid an error in WglExtensions.hpp
#include <SFML/Window/Win32/WglContext.hpp>
-#include <SFML/Window/Win32/WglExtensions.hpp>
#include <SFML/System/Lock.hpp>
#include <SFML/System/Mutex.hpp>
#include <SFML/System/Err.hpp>
#include <sstream>
+#include <vector>
namespace sf
@@ -69,62 +70,75 @@ String getErrorString(DWORD errorCode)
////////////////////////////////////////////////////////////
WglContext::WglContext(WglContext* shared) :
m_window (NULL),
+m_pbuffer (NULL),
m_deviceContext(NULL),
m_context (NULL),
-m_ownsWindow (true)
+m_ownsWindow (false)
{
- // 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...
+ // Save the creation settings
+ m_settings = ContextSettings();
+
+ // Make sure that extensions are initialized if this is not the shared context
+ // The shared context is the context used to initialize the extensions
+ if (shared && shared->m_deviceContext)
+ ensureExtensionsInit(shared->m_deviceContext);
- // 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 rendering surface (window or pbuffer if supported)
+ createSurface(shared, 1, 1, VideoMode::getDesktopMode().bitsPerPixel);
// Create the context
if (m_deviceContext)
- createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, ContextSettings());
+ createContext(shared);
}
////////////////////////////////////////////////////////////
WglContext::WglContext(WglContext* shared, const ContextSettings& settings, const WindowImpl* owner, unsigned int bitsPerPixel) :
m_window (NULL),
+m_pbuffer (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);
+ // Save the creation settings
+ m_settings = settings;
+
+ // Make sure that extensions are initialized if this is not the shared context
+ // The shared context is the context used to initialize the extensions
+ if (shared && shared->m_deviceContext)
+ ensureExtensionsInit(shared->m_deviceContext);
+
+ // Create the rendering surface from the owner window
+ createSurface(owner->getSystemHandle(), bitsPerPixel);
// Create the context
if (m_deviceContext)
- createContext(shared, bitsPerPixel, settings);
+ createContext(shared);
}
////////////////////////////////////////////////////////////
WglContext::WglContext(WglContext* shared, const ContextSettings& settings, unsigned int width, unsigned int height) :
m_window (NULL),
+m_pbuffer (NULL),
m_deviceContext(NULL),
m_context (NULL),
-m_ownsWindow (true)
+m_ownsWindow (false)
{
- // 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.
+ // Save the creation settings
+ m_settings = settings;
+
+ // Make sure that extensions are initialized if this is not the shared context
+ // The shared context is the context used to initialize the extensions
+ if (shared && shared->m_deviceContext)
+ ensureExtensionsInit(shared->m_deviceContext);
- // 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 rendering surface (window or pbuffer if supported)
+ createSurface(shared, width, height, VideoMode::getDesktopMode().bitsPerPixel);
// Create the context
if (m_deviceContext)
- createContext(shared, VideoMode::getDesktopMode().bitsPerPixel, settings);
+ createContext(shared);
}
@@ -141,7 +155,17 @@ WglContext::~WglContext()
// Destroy the device context
if (m_deviceContext)
- ReleaseDC(m_window, m_deviceContext);
+ {
+ if (m_pbuffer)
+ {
+ wglReleasePbufferDCARB(m_pbuffer, m_deviceContext);
+ wglDestroyPbufferARB(m_pbuffer);
+ }
+ else
+ {
+ ReleaseDC(m_window, m_deviceContext);
+ }
+ }
// Destroy the window if we own it
if (m_window && m_ownsWindow)
@@ -217,7 +241,7 @@ void WglContext::setVerticalSyncEnabled(bool enabled)
////////////////////////////////////////////////////////////
-int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings)
+int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings, bool pbuffer)
{
// Let's find a suitable pixel format -- first try with wglChoosePixelFormatARB
int bestFormat = 0;
@@ -279,9 +303,40 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
}
}
+ int sRgbCapableValue = 0;
+ if ((sfwgl_ext_ARB_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED) || (sfwgl_ext_EXT_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED))
+ {
+ const int sRgbCapableAttribute = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
+
+ if (!wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 1, &sRgbCapableAttribute, &sRgbCapableValue))
+ {
+ err() << "Failed to retrieve pixel format sRGB capability information: " << getErrorString(GetLastError()).toAnsiString() << std::endl;
+ break;
+ }
+ }
+
+ if (pbuffer)
+ {
+ const int pbufferAttributes[] =
+ {
+ WGL_DRAW_TO_PBUFFER_ARB
+ };
+
+ int pbufferValue = 0;
+
+ if (!wglGetPixelFormatAttribivARB(deviceContext, formats[i], PFD_MAIN_PLANE, 1, pbufferAttributes, &pbufferValue))
+ {
+ err() << "Failed to retrieve pixel format pbuffer information: " << getErrorString(GetLastError()).toAnsiString() << std::endl;
+ break;
+ }
+
+ if (pbufferValue != GL_TRUE)
+ continue;
+ }
+
// Evaluate the current configuration
int color = values[0] + values[1] + values[2] + values[3];
- int score = evaluateFormat(bitsPerPixel, settings, color, values[4], values[5], sampleValues[0] ? sampleValues[1] : 0, values[6] == WGL_FULL_ACCELERATION_ARB);
+ int score = evaluateFormat(bitsPerPixel, settings, color, values[4], values[5], sampleValues[0] ? sampleValues[1] : 0, values[6] == WGL_FULL_ACCELERATION_ARB, sRgbCapableValue == TRUE);
// Keep it if it's better than the current best
if (score < bestScore)
@@ -293,6 +348,10 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
}
}
+ // ChoosePixelFormat doesn't support pbuffers
+ if (pbuffer)
+ return bestFormat;
+
// Find a pixel format with ChoosePixelFormat, if wglChoosePixelFormatARB is not supported
if (bestFormat == 0)
{
@@ -318,17 +377,9 @@ int WglContext::selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPix
////////////////////////////////////////////////////////////
-void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings)
+void WglContext::setDevicePixelFormat(unsigned int bitsPerPixel)
{
- // Save the creation settings
- m_settings = settings;
-
- // Make sure that extensions are initialized if this is not the shared context
- // The shared context is the context used to initialize the extensions
- if (shared)
- ensureExtensionsInit(m_deviceContext);
-
- int bestFormat = selectBestPixelFormat(m_deviceContext, bitsPerPixel, settings);
+ int bestFormat = selectBestPixelFormat(m_deviceContext, bitsPerPixel, m_settings);
if (bestFormat == 0)
{
@@ -343,12 +394,38 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co
actualFormat.nVersion = 1;
DescribePixelFormat(m_deviceContext, bestFormat, sizeof(actualFormat), &actualFormat);
+ // Set the chosen pixel format
+ if (!SetPixelFormat(m_deviceContext, bestFormat, &actualFormat))
+ {
+ err() << "Failed to set pixel format for device context: " << getErrorString(GetLastError()).toAnsiString() << std::endl
+ << "Cannot create OpenGL context" << std::endl;
+ return;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+void WglContext::updateSettingsFromPixelFormat()
+{
+ int format = GetPixelFormat(m_deviceContext);
+
+ PIXELFORMATDESCRIPTOR actualFormat;
+ actualFormat.nSize = sizeof(actualFormat);
+ actualFormat.nVersion = 1;
+ DescribePixelFormat(m_deviceContext, format, sizeof(actualFormat), &actualFormat);
+
+ if (format == 0)
+ {
+ err() << "Failed to get selected pixel format" << std::endl;
+ return;
+ }
+
if (sfwgl_ext_ARB_pixel_format == sfwgl_LOAD_SUCCEEDED)
{
const int attributes[] = {WGL_DEPTH_BITS_ARB, WGL_STENCIL_BITS_ARB};
int values[2];
- if (wglGetPixelFormatAttribivARB(m_deviceContext, bestFormat, PFD_MAIN_PLANE, 2, attributes, values))
+ if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 2, attributes, values))
{
m_settings.depthBits = values[0];
m_settings.stencilBits = values[1];
@@ -365,7 +442,7 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co
const int sampleAttributes[] = {WGL_SAMPLE_BUFFERS_ARB, WGL_SAMPLES_ARB};
int sampleValues[2];
- if (wglGetPixelFormatAttribivARB(m_deviceContext, bestFormat, PFD_MAIN_PLANE, 2, sampleAttributes, sampleValues))
+ if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 2, sampleAttributes, sampleValues))
{
m_settings.antialiasingLevel = sampleValues[0] ? sampleValues[1] : 0;
}
@@ -379,6 +456,26 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co
{
m_settings.antialiasingLevel = 0;
}
+
+ if ((sfwgl_ext_ARB_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED) || (sfwgl_ext_EXT_framebuffer_sRGB == sfwgl_LOAD_SUCCEEDED))
+ {
+ const int sRgbCapableAttribute = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
+ int sRgbCapableValue = 0;
+
+ if (wglGetPixelFormatAttribivARB(m_deviceContext, format, PFD_MAIN_PLANE, 1, &sRgbCapableAttribute, &sRgbCapableValue))
+ {
+ m_settings.sRgbCapable = (sRgbCapableValue == TRUE);
+ }
+ else
+ {
+ err() << "Failed to retrieve pixel format sRGB capability information: " << getErrorString(GetLastError()).toAnsiString() << std::endl;
+ m_settings.sRgbCapable = false;
+ }
+ }
+ else
+ {
+ m_settings.sRgbCapable = false;
+ }
}
else
{
@@ -386,15 +483,79 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co
m_settings.stencilBits = actualFormat.cStencilBits;
m_settings.antialiasingLevel = 0;
}
+}
- // Set the chosen pixel format
- if (!SetPixelFormat(m_deviceContext, bestFormat, &actualFormat))
+
+////////////////////////////////////////////////////////////
+void WglContext::createSurface(WglContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel)
+{
+ // Check if the shared context already exists and pbuffers are supported
+ if (shared && shared->m_deviceContext && (sfwgl_ext_ARB_pbuffer == sfwgl_LOAD_SUCCEEDED))
{
- err() << "Failed to set pixel format for device context: " << getErrorString(GetLastError()).toAnsiString() << std::endl
- << "Cannot create OpenGL context" << std::endl;
- return;
+ int bestFormat = selectBestPixelFormat(shared->m_deviceContext, bitsPerPixel, m_settings, true);
+
+ if (bestFormat > 0)
+ {
+ int attributes[] = {0, 0};
+
+ m_pbuffer = wglCreatePbufferARB(shared->m_deviceContext, bestFormat, width, height, attributes);
+
+ if (m_pbuffer)
+ {
+ m_window = shared->m_window;
+ m_deviceContext = wglGetPbufferDCARB(m_pbuffer);
+
+ if (!m_deviceContext)
+ {
+ wglDestroyPbufferARB(m_pbuffer);
+ m_pbuffer = NULL;
+ }
+ }
+ }
+ }
+
+ // If pbuffers are not available we use a hidden window as the off-screen surface to draw to
+ if (!m_deviceContext)
+ {
+ // We can't create a memory DC, the resulting context wouldn't be compatible
+ // with other contexts and thus wglShareLists would always fail
+
+ // 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);
+
+ m_ownsWindow = true;
+
+ // Set the pixel format of the device context
+ setDevicePixelFormat(bitsPerPixel);
}
+ // Update context settings from the selected pixel format
+ updateSettingsFromPixelFormat();
+}
+
+
+////////////////////////////////////////////////////////////
+void WglContext::createSurface(HWND window, unsigned int bitsPerPixel)
+{
+ m_window = window;
+ m_deviceContext = GetDC(window);
+
+ // Set the pixel format of the device context
+ setDevicePixelFormat(bitsPerPixel);
+
+ // Update context settings from the selected pixel format
+ updateSettingsFromPixelFormat();
+}
+
+
+////////////////////////////////////////////////////////////
+void WglContext::createContext(WglContext* shared)
+{
+ // Get a working copy of the context settings
+ ContextSettings settings = m_settings;
+
// Get the context to share display lists with
HGLRC sharedContext = shared ? shared->m_context : NULL;
@@ -403,21 +564,27 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co
{
if (sfwgl_ext_ARB_create_context == sfwgl_LOAD_SUCCEEDED)
{
+ std::vector<int> attributes;
+
+ // Check if the user requested a specific context version (anything > 1.1)
+ if ((m_settings.majorVersion > 1) || ((m_settings.majorVersion == 1) && (m_settings.minorVersion > 1)))
+ {
+ attributes.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
+ attributes.push_back(m_settings.majorVersion);
+ attributes.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
+ attributes.push_back(m_settings.minorVersion);
+ }
+
// Check if setting the profile is supported
if (sfwgl_ext_ARB_create_context_profile == sfwgl_LOAD_SUCCEEDED)
{
int profile = (m_settings.attributeFlags & ContextSettings::Core) ? WGL_CONTEXT_CORE_PROFILE_BIT_ARB : WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
int debug = (m_settings.attributeFlags & ContextSettings::Debug) ? WGL_CONTEXT_DEBUG_BIT_ARB : 0;
- 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, profile,
- WGL_CONTEXT_FLAGS_ARB, debug,
- 0, 0
- };
- m_context = wglCreateContextAttribsARB(m_deviceContext, sharedContext, attributes);
+ attributes.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
+ attributes.push_back(profile);
+ attributes.push_back(WGL_CONTEXT_FLAGS_ARB);
+ attributes.push_back(debug);
}
else
{
@@ -426,15 +593,14 @@ void WglContext::createContext(WglContext* shared, unsigned int bitsPerPixel, co
<< "disabling comptibility and debug" << std::endl;
m_settings.attributeFlags = ContextSettings::Default;
-
- int attributes[] =
- {
- WGL_CONTEXT_MAJOR_VERSION_ARB, static_cast<int>(m_settings.majorVersion),
- WGL_CONTEXT_MINOR_VERSION_ARB, static_cast<int>(m_settings.minorVersion),
- 0, 0
- };
- m_context = wglCreateContextAttribsARB(m_deviceContext, sharedContext, attributes);
}
+
+ // Append the terminating 0
+ attributes.push_back(0);
+ attributes.push_back(0);
+
+ // Create the context
+ m_context = wglCreateContextAttribsARB(m_deviceContext, sharedContext, &attributes[0]);
}
else
{
diff --git a/src/SFML/Window/Win32/WglContext.hpp b/src/SFML/Window/Win32/WglContext.hpp
index 45070f6..ceecc2d 100644
--- a/src/SFML/Window/Win32/WglContext.hpp
+++ b/src/SFML/Window/Win32/WglContext.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -29,8 +29,7 @@
// Headers
////////////////////////////////////////////////////////////
#include <SFML/Window/GlContext.hpp>
-#include <SFML/OpenGL.hpp>
-#include <windows.h>
+#include <SFML/Window/Win32/WglExtensions.hpp>
namespace sf
@@ -124,31 +123,65 @@ public:
/// \param deviceContext Device context
/// \param bitsPerPixel Pixel depth, in bits per pixel
/// \param settings Requested context settings
+ /// \param pbuffer Whether the pixel format should support pbuffers
///
/// \return The best pixel format
///
////////////////////////////////////////////////////////////
- static int selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings);
+ static int selectBestPixelFormat(HDC deviceContext, unsigned int bitsPerPixel, const ContextSettings& settings, bool pbuffer = false);
private:
////////////////////////////////////////////////////////////
+ /// \brief Set the pixel format of the device context
+ ///
+ /// \param bitsPerPixel Pixel depth, in bits per pixel
+ ///
+ ////////////////////////////////////////////////////////////
+ void setDevicePixelFormat(unsigned int bitsPerPixel);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Update the context settings from the selected pixel format
+ ///
+ ////////////////////////////////////////////////////////////
+ void updateSettingsFromPixelFormat();
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create the context's drawing surface
+ ///
+ /// \param shared Shared context (can be NULL)
+ /// \param width Back buffer width, in pixels
+ /// \param height Back buffer height, in pixels
+ /// \param bitsPerPixel Pixel depth, in bits per pixel
+ ///
+ ////////////////////////////////////////////////////////////
+ void createSurface(WglContext* shared, unsigned int width, unsigned int height, unsigned int bitsPerPixel);
+
+ ////////////////////////////////////////////////////////////
+ /// \brief Create the context's drawing surface from an existing window
+ ///
+ /// \param window Window handle of the owning window
+ /// \param bitsPerPixel Pixel depth, in bits per pixel
+ ///
+ ////////////////////////////////////////////////////////////
+ void createSurface(HWND window, unsigned int bitsPerPixel);
+
+ ////////////////////////////////////////////////////////////
/// \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
+ /// \param shared Context to share the new one with (can be NULL)
///
////////////////////////////////////////////////////////////
- void createContext(WglContext* shared, unsigned int bitsPerPixel, const ContextSettings& settings);
+ void createContext(WglContext* shared);
////////////////////////////////////////////////////////////
// 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?
+ HWND m_window; ///< Window to which the context is attached
+ HPBUFFERARB m_pbuffer; ///< Handle to a pbuffer if one was created
+ 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
diff --git a/src/SFML/Window/Win32/WglExtensions.cpp b/src/SFML/Window/Win32/WglExtensions.cpp
index 0d82b74..16cf473 100644
--- a/src/SFML/Window/Win32/WglExtensions.cpp
+++ b/src/SFML/Window/Win32/WglExtensions.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -30,6 +30,7 @@
#include <cstdlib>
#include <cstring>
#include <cstddef>
+#include <string>
static sf::GlFunctionPointer IntGetProcAddress(const char* name)
{
@@ -37,8 +38,11 @@ static sf::GlFunctionPointer IntGetProcAddress(const char* name)
}
int sfwgl_ext_EXT_swap_control = sfwgl_LOAD_FAILED;
+int sfwgl_ext_EXT_framebuffer_sRGB = sfwgl_LOAD_FAILED;
+int sfwgl_ext_ARB_framebuffer_sRGB = sfwgl_LOAD_FAILED;
int sfwgl_ext_ARB_multisample = sfwgl_LOAD_FAILED;
int sfwgl_ext_ARB_pixel_format = sfwgl_LOAD_FAILED;
+int sfwgl_ext_ARB_pbuffer = sfwgl_LOAD_FAILED;
int sfwgl_ext_ARB_create_context = sfwgl_LOAD_FAILED;
int sfwgl_ext_ARB_create_context_profile = sfwgl_LOAD_FAILED;
@@ -48,93 +52,133 @@ BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglSwapIntervalEXT)(int) = NULL;
static int Load_EXT_swap_control(void)
{
int numFailed = 0;
- sf_ptrc_wglGetSwapIntervalEXT = (int (CODEGEN_FUNCPTR *)(void))IntGetProcAddress("wglGetSwapIntervalEXT");
- if(!sf_ptrc_wglGetSwapIntervalEXT) numFailed++;
- sf_ptrc_wglSwapIntervalEXT = (BOOL (CODEGEN_FUNCPTR *)(int))IntGetProcAddress("wglSwapIntervalEXT");
- if(!sf_ptrc_wglSwapIntervalEXT) numFailed++;
+ sf_ptrc_wglGetSwapIntervalEXT = reinterpret_cast<int (CODEGEN_FUNCPTR*)(void)>(IntGetProcAddress("wglGetSwapIntervalEXT"));
+ if (!sf_ptrc_wglGetSwapIntervalEXT)
+ numFailed++;
+ sf_ptrc_wglSwapIntervalEXT = reinterpret_cast<BOOL (CODEGEN_FUNCPTR*)(int)>(IntGetProcAddress("wglSwapIntervalEXT"));
+ if (!sf_ptrc_wglSwapIntervalEXT)
+ numFailed++;
return numFailed;
}
-BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *) = NULL;
-BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribfvARB)(HDC, int, int, UINT, const int *, FLOAT *) = NULL;
-BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int *, int *) = NULL;
+BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglChoosePixelFormatARB)(HDC, const int*, const FLOAT*, UINT, int*, UINT*) = NULL;
+BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribfvARB)(HDC, int, int, UINT, const int*, FLOAT*) = NULL;
+BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int*, int*) = NULL;
static int Load_ARB_pixel_format(void)
{
int numFailed = 0;
- sf_ptrc_wglChoosePixelFormatARB = (BOOL (CODEGEN_FUNCPTR *)(HDC, const int *, const FLOAT *, UINT, int *, UINT *))IntGetProcAddress("wglChoosePixelFormatARB");
- if(!sf_ptrc_wglChoosePixelFormatARB) numFailed++;
- sf_ptrc_wglGetPixelFormatAttribfvARB = (BOOL (CODEGEN_FUNCPTR *)(HDC, int, int, UINT, const int *, FLOAT *))IntGetProcAddress("wglGetPixelFormatAttribfvARB");
- if(!sf_ptrc_wglGetPixelFormatAttribfvARB) numFailed++;
- sf_ptrc_wglGetPixelFormatAttribivARB = (BOOL (CODEGEN_FUNCPTR *)(HDC, int, int, UINT, const int *, int *))IntGetProcAddress("wglGetPixelFormatAttribivARB");
- if(!sf_ptrc_wglGetPixelFormatAttribivARB) numFailed++;
+ sf_ptrc_wglChoosePixelFormatARB = reinterpret_cast<BOOL (CODEGEN_FUNCPTR*)(HDC, const int*, const FLOAT*, UINT, int*, UINT*)>(IntGetProcAddress("wglChoosePixelFormatARB"));
+ if (!sf_ptrc_wglChoosePixelFormatARB)
+ numFailed++;
+ sf_ptrc_wglGetPixelFormatAttribfvARB = reinterpret_cast<BOOL (CODEGEN_FUNCPTR *)(HDC, int, int, UINT, const int*, FLOAT*)>(IntGetProcAddress("wglGetPixelFormatAttribfvARB"));
+ if (!sf_ptrc_wglGetPixelFormatAttribfvARB)
+ numFailed++;
+ sf_ptrc_wglGetPixelFormatAttribivARB = reinterpret_cast<BOOL (CODEGEN_FUNCPTR*)(HDC, int, int, UINT, const int*, int*)>(IntGetProcAddress("wglGetPixelFormatAttribivARB"));
+ if (!sf_ptrc_wglGetPixelFormatAttribivARB)
+ numFailed++;
return numFailed;
}
-HGLRC (CODEGEN_FUNCPTR *sf_ptrc_wglCreateContextAttribsARB)(HDC, HGLRC, const int *) = NULL;
+HPBUFFERARB (CODEGEN_FUNCPTR *sf_ptrc_wglCreatePbufferARB)(HDC, int, int, int, const int*) = NULL;
+BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglDestroyPbufferARB)(HPBUFFERARB) = NULL;
+HDC (CODEGEN_FUNCPTR *sf_ptrc_wglGetPbufferDCARB)(HPBUFFERARB) = NULL;
+BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglQueryPbufferARB)(HPBUFFERARB, int, int*) = NULL;
+int (CODEGEN_FUNCPTR *sf_ptrc_wglReleasePbufferDCARB)(HPBUFFERARB, HDC) = NULL;
+
+static int Load_ARB_pbuffer()
+{
+ int numFailed = 0;
+ sf_ptrc_wglCreatePbufferARB = reinterpret_cast<HPBUFFERARB (CODEGEN_FUNCPTR*)(HDC, int, int, int, const int*)>(IntGetProcAddress("wglCreatePbufferARB"));
+ if (!sf_ptrc_wglCreatePbufferARB)
+ numFailed++;
+ sf_ptrc_wglDestroyPbufferARB = reinterpret_cast<BOOL (CODEGEN_FUNCPTR*)(HPBUFFERARB)>(IntGetProcAddress("wglDestroyPbufferARB"));
+ if (!sf_ptrc_wglDestroyPbufferARB)
+ numFailed++;
+ sf_ptrc_wglGetPbufferDCARB = reinterpret_cast<HDC (CODEGEN_FUNCPTR*)(HPBUFFERARB)>(IntGetProcAddress("wglGetPbufferDCARB"));
+ if (!sf_ptrc_wglGetPbufferDCARB)
+ numFailed++;
+ sf_ptrc_wglQueryPbufferARB = reinterpret_cast<BOOL (CODEGEN_FUNCPTR*)(HPBUFFERARB, int, int*)>(IntGetProcAddress("wglQueryPbufferARB"));
+ if (!sf_ptrc_wglQueryPbufferARB)
+ numFailed++;
+ sf_ptrc_wglReleasePbufferDCARB = reinterpret_cast<int (CODEGEN_FUNCPTR*)(HPBUFFERARB, HDC)>(IntGetProcAddress("wglReleasePbufferDCARB"));
+ if (!sf_ptrc_wglReleasePbufferDCARB)
+ numFailed++;
+ return numFailed;
+}
+
+HGLRC (CODEGEN_FUNCPTR *sf_ptrc_wglCreateContextAttribsARB)(HDC, HGLRC, const int*) = NULL;
static int Load_ARB_create_context(void)
{
int numFailed = 0;
- sf_ptrc_wglCreateContextAttribsARB = (HGLRC (CODEGEN_FUNCPTR *)(HDC, HGLRC, const int *))IntGetProcAddress("wglCreateContextAttribsARB");
- if(!sf_ptrc_wglCreateContextAttribsARB) numFailed++;
+ sf_ptrc_wglCreateContextAttribsARB = reinterpret_cast<HGLRC (CODEGEN_FUNCPTR*)(HDC, HGLRC, const int*)>(IntGetProcAddress("wglCreateContextAttribsARB"));
+ if (!sf_ptrc_wglCreateContextAttribsARB)
+ numFailed++;
return numFailed;
}
-static const char * (CODEGEN_FUNCPTR *sf_ptrc_wglGetExtensionsStringARB)(HDC) = NULL;
+static const char* (CODEGEN_FUNCPTR *sf_ptrc_wglGetExtensionsStringARB)(HDC) = NULL;
typedef int (*PFN_LOADFUNCPOINTERS)(void);
typedef struct sfwgl_StrToExtMap_s
{
- const char *extensionName;
- int *extensionVariable;
+ const char* extensionName;
+ int* extensionVariable;
PFN_LOADFUNCPOINTERS LoadExtension;
} sfwgl_StrToExtMap;
-static sfwgl_StrToExtMap ExtensionMap[5] = {
+static sfwgl_StrToExtMap ExtensionMap[8] = {
{"WGL_EXT_swap_control", &sfwgl_ext_EXT_swap_control, Load_EXT_swap_control},
+ {"WGL_EXT_framebuffer_sRGB", &sfwgl_ext_EXT_framebuffer_sRGB, NULL},
+ {"WGL_ARB_framebuffer_sRGB", &sfwgl_ext_ARB_framebuffer_sRGB, NULL},
{"WGL_ARB_multisample", &sfwgl_ext_ARB_multisample, NULL},
{"WGL_ARB_pixel_format", &sfwgl_ext_ARB_pixel_format, Load_ARB_pixel_format},
+ {"WGL_ARB_pbuffer", &sfwgl_ext_ARB_pbuffer, Load_ARB_pbuffer},
{"WGL_ARB_create_context", &sfwgl_ext_ARB_create_context, Load_ARB_create_context},
- {"WGL_ARB_create_context_profile", &sfwgl_ext_ARB_create_context_profile, NULL},
+ {"WGL_ARB_create_context_profile", &sfwgl_ext_ARB_create_context_profile, NULL}
};
-static int g_extensionMapSize = 5;
+static int g_extensionMapSize = 8;
-static sfwgl_StrToExtMap *FindExtEntry(const char *extensionName)
+
+static sfwgl_StrToExtMap* FindExtEntry(const char* extensionName)
{
- int loop;
- sfwgl_StrToExtMap *currLoc = ExtensionMap;
- for(loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
+ sfwgl_StrToExtMap* currLoc = ExtensionMap;
+ for (int loop = 0; loop < g_extensionMapSize; ++loop, ++currLoc)
{
- if(strcmp(extensionName, currLoc->extensionName) == 0)
+ if (std::strcmp(extensionName, currLoc->extensionName) == 0)
return currLoc;
}
return NULL;
}
+
static void ClearExtensionVars(void)
{
sfwgl_ext_EXT_swap_control = sfwgl_LOAD_FAILED;
+ sfwgl_ext_EXT_framebuffer_sRGB = sfwgl_LOAD_FAILED;
+ sfwgl_ext_ARB_framebuffer_sRGB = sfwgl_LOAD_FAILED;
sfwgl_ext_ARB_multisample = sfwgl_LOAD_FAILED;
sfwgl_ext_ARB_pixel_format = sfwgl_LOAD_FAILED;
+ sfwgl_ext_ARB_pbuffer = sfwgl_LOAD_FAILED;
sfwgl_ext_ARB_create_context = sfwgl_LOAD_FAILED;
sfwgl_ext_ARB_create_context_profile = sfwgl_LOAD_FAILED;
}
-static void LoadExtByName(const char *extensionName)
+static void LoadExtByName(const char* extensionName)
{
- sfwgl_StrToExtMap *entry = NULL;
+ sfwgl_StrToExtMap* entry = NULL;
entry = FindExtEntry(extensionName);
- if(entry)
+ if (entry)
{
- if(entry->LoadExtension)
+ if (entry->LoadExtension)
{
int numFailed = entry->LoadExtension();
- if(numFailed == 0)
+ if (numFailed == 0)
{
*(entry->extensionVariable) = sfwgl_LOAD_SUCCEEDED;
}
@@ -151,48 +195,29 @@ static void LoadExtByName(const char *extensionName)
}
-static void ProcExtsFromExtString(const char *strExtList)
+static void ProcExtsFromExtString(const char* strExtList)
{
- size_t iExtListLen = strlen(strExtList);
- const char *strExtListEnd = strExtList + iExtListLen;
- const char *strCurrPos = strExtList;
- char strWorkBuff[256];
-
- while(*strCurrPos)
+ do
{
- /*Get the extension at our position.*/
- int iStrLen = 0;
- const char *strEndStr = strchr(strCurrPos, ' ');
- int iStop = 0;
- if(strEndStr == NULL)
- {
- strEndStr = strExtListEnd;
- iStop = 1;
- }
-
- iStrLen = (int)((ptrdiff_t)strEndStr - (ptrdiff_t)strCurrPos);
+ const char* begin = strExtList;
- if(iStrLen > 255)
- return;
+ while ((*strExtList != ' ') && *strExtList)
+ strExtList++;
- strncpy(strWorkBuff, strCurrPos, iStrLen);
- strWorkBuff[iStrLen] = '\0';
-
- LoadExtByName(strWorkBuff);
-
- strCurrPos = strEndStr + 1;
- if(iStop) break;
- }
+ LoadExtByName(std::string(begin, strExtList).c_str());
+ } while (*strExtList++);
}
+
int sfwgl_LoadFunctions(HDC hdc)
{
ClearExtensionVars();
- sf_ptrc_wglGetExtensionsStringARB = (const char * (CODEGEN_FUNCPTR *)(HDC))IntGetProcAddress("wglGetExtensionsStringARB");
- if(!sf_ptrc_wglGetExtensionsStringARB) return sfwgl_LOAD_FAILED;
+ sf_ptrc_wglGetExtensionsStringARB = reinterpret_cast<const char* (CODEGEN_FUNCPTR*)(HDC)>(IntGetProcAddress("wglGetExtensionsStringARB"));
+ if (!sf_ptrc_wglGetExtensionsStringARB)
+ return sfwgl_LOAD_FAILED;
- ProcExtsFromExtString((const char *)sf_ptrc_wglGetExtensionsStringARB(hdc));
+ ProcExtsFromExtString(reinterpret_cast<const char*>(sf_ptrc_wglGetExtensionsStringARB(hdc)));
return sfwgl_LOAD_SUCCEEDED;
}
diff --git a/src/SFML/Window/Win32/WglExtensions.hpp b/src/SFML/Window/Win32/WglExtensions.hpp
index 1b389c0..30d5253 100644
--- a/src/SFML/Window/Win32/WglExtensions.hpp
+++ b/src/SFML/Window/Win32/WglExtensions.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -41,7 +41,7 @@
#ifdef CODEGEN_FUNCPTR
#undef CODEGEN_FUNCPTR
-#endif /*CODEGEN_FUNCPTR*/
+#endif // CODEGEN_FUNCPTR
#define CODEGEN_FUNCPTR WINAPI
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
@@ -63,14 +63,14 @@ typedef double GLdouble;
typedef double GLclampd;
#define GLvoid void
-#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
+#endif // GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
#ifndef GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
#define GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
-#endif /*GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS*/
+#endif // GL_LOAD_GEN_BASIC_OPENGL_TYPEDEFS
struct _GPU_DEVICE {
@@ -90,14 +90,21 @@ typedef struct _GPU_DEVICE *PGPU_DEVICE;
#ifdef __cplusplus
extern "C" {
-#endif /*__cplusplus*/
+#endif // __cplusplus
extern int sfwgl_ext_EXT_swap_control;
+extern int sfwgl_ext_EXT_framebuffer_sRGB;
+extern int sfwgl_ext_ARB_framebuffer_sRGB;
extern int sfwgl_ext_ARB_multisample;
extern int sfwgl_ext_ARB_pixel_format;
+extern int sfwgl_ext_ARB_pbuffer;
extern int sfwgl_ext_ARB_create_context;
extern int sfwgl_ext_ARB_create_context_profile;
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
+
+#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
+
#define WGL_SAMPLES_ARB 0x2042
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
@@ -151,6 +158,15 @@ extern int sfwgl_ext_ARB_create_context_profile;
#define WGL_TYPE_COLORINDEX_ARB 0x202C
#define WGL_TYPE_RGBA_ARB 0x202B
+#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
+#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
+#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
+#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
+#define WGL_PBUFFER_HEIGHT_ARB 0x2035
+#define WGL_PBUFFER_LARGEST_ARB 0x2033
+#define WGL_PBUFFER_LOST_ARB 0x2036
+#define WGL_PBUFFER_WIDTH_ARB 0x2034
+
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
@@ -170,24 +186,38 @@ extern int (CODEGEN_FUNCPTR *sf_ptrc_wglGetSwapIntervalEXT)(void);
#define wglGetSwapIntervalEXT sf_ptrc_wglGetSwapIntervalEXT
extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglSwapIntervalEXT)(int);
#define wglSwapIntervalEXT sf_ptrc_wglSwapIntervalEXT
-#endif /*WGL_EXT_swap_control*/
+#endif // WGL_EXT_swap_control
#ifndef WGL_ARB_pixel_format
#define WGL_ARB_pixel_format 1
-extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglChoosePixelFormatARB)(HDC, const int *, const FLOAT *, UINT, int *, UINT *);
+extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglChoosePixelFormatARB)(HDC, const int*, const FLOAT*, UINT, int*, UINT*);
#define wglChoosePixelFormatARB sf_ptrc_wglChoosePixelFormatARB
-extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribfvARB)(HDC, int, int, UINT, const int *, FLOAT *);
+extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribfvARB)(HDC, int, int, UINT, const int*, FLOAT*);
#define wglGetPixelFormatAttribfvARB sf_ptrc_wglGetPixelFormatAttribfvARB
-extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int *, int *);
+extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglGetPixelFormatAttribivARB)(HDC, int, int, UINT, const int*, int*);
#define wglGetPixelFormatAttribivARB sf_ptrc_wglGetPixelFormatAttribivARB
-#endif /*WGL_ARB_pixel_format*/
+#endif // WGL_ARB_pixel_format
+
+#ifndef WGL_ARB_pbuffer
+#define WGL_ARB_pbuffer 1
+extern HPBUFFERARB (CODEGEN_FUNCPTR *sf_ptrc_wglCreatePbufferARB)(HDC, int, int, int, const int*);
+#define wglCreatePbufferARB sf_ptrc_wglCreatePbufferARB
+extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglDestroyPbufferARB)(HPBUFFERARB);
+#define wglDestroyPbufferARB sf_ptrc_wglDestroyPbufferARB
+extern HDC (CODEGEN_FUNCPTR *sf_ptrc_wglGetPbufferDCARB)(HPBUFFERARB);
+#define wglGetPbufferDCARB sf_ptrc_wglGetPbufferDCARB
+extern BOOL (CODEGEN_FUNCPTR *sf_ptrc_wglQueryPbufferARB)(HPBUFFERARB, int, int*);
+#define wglQueryPbufferARB sf_ptrc_wglQueryPbufferARB
+extern int (CODEGEN_FUNCPTR *sf_ptrc_wglReleasePbufferDCARB)(HPBUFFERARB, HDC);
+#define wglReleasePbufferDCARB sf_ptrc_wglReleasePbufferDCARB
+#endif // WGL_ARB_pbuffer
#ifndef WGL_ARB_create_context
#define WGL_ARB_create_context 1
-extern HGLRC (CODEGEN_FUNCPTR *sf_ptrc_wglCreateContextAttribsARB)(HDC, HGLRC, const int *);
+extern HGLRC (CODEGEN_FUNCPTR *sf_ptrc_wglCreateContextAttribsARB)(HDC, HGLRC, const int*);
#define wglCreateContextAttribsARB sf_ptrc_wglCreateContextAttribsARB
-#endif /*WGL_ARB_create_context*/
+#endif // WGL_ARB_create_context
enum sfwgl_LoadStatus
@@ -201,6 +231,6 @@ int sfwgl_LoadFunctions(HDC hdc);
#ifdef __cplusplus
}
-#endif /*__cplusplus*/
+#endif // __cplusplus
-#endif /* SF_POINTER_C_GENERATED_HEADER_WINDOWSGL_HPP */
+#endif // SF_POINTER_C_GENERATED_HEADER_WINDOWSGL_HPP
diff --git a/src/SFML/Window/Win32/WglExtensions.txt b/src/SFML/Window/Win32/WglExtensions.txt
index 99610a6..667c853 100644
--- a/src/SFML/Window/Win32/WglExtensions.txt
+++ b/src/SFML/Window/Win32/WglExtensions.txt
@@ -1,10 +1,13 @@
// Created with:
-// https://bitbucket.org/Anteru/glloadgen-reloaded
-// Commit 20f19482b7a844d20b9785c3e3fd1f16419f6e0a
+// https://bitbucket.org/KhronosGroup/glloadgen
+// Commit d143d66ac90d538ed06f806188714861b8e8e2f9
// lua LoadGen.lua -style=pointer_c -spec=wgl -indent=space -prefix=sf -extfile=WglExtensions.txt WglExtensions
EXT_swap_control
+EXT_framebuffer_sRGB
+ARB_framebuffer_sRGB
WGL_ARB_multisample
WGL_ARB_pixel_format
+WGL_ARB_pbuffer
WGL_ARB_create_context
WGL_ARB_create_context_profile \ No newline at end of file
diff --git a/src/SFML/Window/Win32/WindowImplWin32.cpp b/src/SFML/Window/Win32/WindowImplWin32.cpp
index 8bf86ab..cc999f9 100644
--- a/src/SFML/Window/Win32/WindowImplWin32.cpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -132,7 +132,9 @@ m_keyRepeatEnabled(true),
m_lastSize (0, 0),
m_resizing (false),
m_surrogate (0),
-m_mouseInside (false)
+m_mouseInside (false),
+m_fullscreen (false),
+m_cursorGrabbed (false)
{
// Set that this process is DPI aware and can handle DPI scaling
setProcessDpiAware();
@@ -156,7 +158,9 @@ m_keyRepeatEnabled(true),
m_lastSize (mode.width, mode.height),
m_resizing (false),
m_surrogate (0),
-m_mouseInside (false)
+m_mouseInside (false),
+m_fullscreen (style & Style::Fullscreen),
+m_cursorGrabbed (m_fullscreen)
{
// Set that this process is DPI aware and can handle DPI scaling
setProcessDpiAware();
@@ -187,8 +191,7 @@ m_mouseInside (false)
}
// In windowed mode, adjust width and height so that window will have the requested client area
- bool fullscreen = (style & Style::Fullscreen) != 0;
- if (!fullscreen)
+ if (!m_fullscreen)
{
RECT rectangle = {0, 0, width, height};
AdjustWindowRect(&rectangle, win32Style, false);
@@ -204,7 +207,7 @@ m_mouseInside (false)
setSize(Vector2u(mode.width, mode.height));
// Switch to fullscreen if requested
- if (fullscreen)
+ if (m_fullscreen)
switchToFullscreen(mode);
// Increment window count
@@ -277,6 +280,9 @@ Vector2i WindowImplWin32::getPosition() const
void WindowImplWin32::setPosition(const Vector2i& position)
{
SetWindowPos(m_handle, NULL, position.x, position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
+
+ if(m_cursorGrabbed)
+ grabCursor(true);
}
@@ -364,6 +370,14 @@ void WindowImplWin32::setMouseCursorVisible(bool visible)
////////////////////////////////////////////////////////////
+void WindowImplWin32::setMouseCursorGrabbed(bool grabbed)
+{
+ m_cursorGrabbed = grabbed;
+ grabCursor(m_cursorGrabbed);
+}
+
+
+////////////////////////////////////////////////////////////
void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
{
m_keyRepeatEnabled = enabled;
@@ -486,6 +500,23 @@ void WindowImplWin32::setTracking(bool track)
////////////////////////////////////////////////////////////
+void WindowImplWin32::grabCursor(bool grabbed)
+{
+ if (grabbed)
+ {
+ RECT rect;
+ GetClientRect(m_handle, &rect);
+ MapWindowPoints(m_handle, NULL, reinterpret_cast<LPPOINT>(&rect), 2);
+ ClipCursor(&rect);
+ }
+ else
+ {
+ ClipCursor(NULL);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
{
// Don't process any message until window is created
@@ -536,6 +567,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.size.width = m_lastSize.x;
event.size.height = m_lastSize.y;
pushEvent(event);
+
+ // Restore/update cursor grabbing
+ grabCursor(m_cursorGrabbed);
}
break;
}
@@ -544,6 +578,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
case WM_ENTERSIZEMOVE:
{
m_resizing = true;
+ grabCursor(false);
break;
}
@@ -565,6 +600,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
event.size.height = m_lastSize.y;
pushEvent(event);
}
+
+ // Restore/update cursor grabbing
+ grabCursor(m_cursorGrabbed);
break;
}
@@ -582,6 +620,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Gain focus event
case WM_SETFOCUS:
{
+ // Restore cursor grabbing
+ grabCursor(m_cursorGrabbed);
+
Event event;
event.type = Event::GainedFocus;
pushEvent(event);
@@ -591,6 +632,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Lost focus event
case WM_KILLFOCUS:
{
+ // Ungrab the cursor
+ grabCursor(false);
+
Event event;
event.type = Event::LostFocus;
pushEvent(event);
diff --git a/src/SFML/Window/Win32/WindowImplWin32.hpp b/src/SFML/Window/Win32/WindowImplWin32.hpp
index fb5fe0f..d7ef4e0 100644
--- a/src/SFML/Window/Win32/WindowImplWin32.hpp
+++ b/src/SFML/Window/Win32/WindowImplWin32.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -146,6 +146,14 @@ public:
virtual void setMouseCursorVisible(bool visible);
////////////////////////////////////////////////////////////
+ /// \brief Grab or release the mouse cursor
+ ///
+ /// \param grabbed True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setMouseCursorGrabbed(bool grabbed);
+
+ ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat
///
/// \param enabled True to enable, false to disable
@@ -217,6 +225,19 @@ private:
void setTracking(bool track);
////////////////////////////////////////////////////////////
+ /// \brief Grab or release the mouse cursor
+ ///
+ /// This is not to be confused with setMouseCursorGrabbed.
+ /// Here m_cursorGrabbed is not modified; it is used,
+ /// for example, to release the cursor when switching to
+ /// another application.
+ ///
+ /// \param grabbed True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ void grabCursor(bool grabbed);
+
+ ////////////////////////////////////////////////////////////
/// \brief Convert a Win32 virtual key code to a SFML key code
///
/// \param key Virtual key code to convert
@@ -252,6 +273,8 @@ private:
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?
+ bool m_fullscreen; ///< Is the window fullscreen?
+ bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
};
} // namespace priv
diff --git a/src/SFML/Window/Window.cpp b/src/SFML/Window/Window.cpp
index a091325..70cb418 100644
--- a/src/SFML/Window/Window.cpp
+++ b/src/SFML/Window/Window.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -289,6 +289,14 @@ void Window::setMouseCursorVisible(bool visible)
////////////////////////////////////////////////////////////
+void Window::setMouseCursorGrabbed(bool grabbed)
+{
+ if (m_impl)
+ m_impl->setMouseCursorGrabbed(grabbed);
+}
+
+
+////////////////////////////////////////////////////////////
void Window::setKeyRepeatEnabled(bool enabled)
{
if (m_impl)
diff --git a/src/SFML/Window/WindowImpl.cpp b/src/SFML/Window/WindowImpl.cpp
index 679aaed..e7133e1 100644
--- a/src/SFML/Window/WindowImpl.cpp
+++ b/src/SFML/Window/WindowImpl.cpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/WindowImpl.hpp b/src/SFML/Window/WindowImpl.hpp
index 1e07a0f..1243506 100644
--- a/src/SFML/Window/WindowImpl.hpp
+++ b/src/SFML/Window/WindowImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -187,6 +187,14 @@ public:
virtual void setMouseCursorVisible(bool visible) = 0;
////////////////////////////////////////////////////////////
+ /// \brief Grab or release the mouse cursor and keeps it from leaving
+ ///
+ /// \param grabbed True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setMouseCursorGrabbed(bool grabbed) = 0;
+
+ ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat
///
/// \param enabled True to enable, false to disable
diff --git a/src/SFML/Window/iOS/EaglContext.hpp b/src/SFML/Window/iOS/EaglContext.hpp
index 1ad457f..a3c48ea 100644
--- a/src/SFML/Window/iOS/EaglContext.hpp
+++ b/src/SFML/Window/iOS/EaglContext.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/EaglContext.mm b/src/SFML/Window/iOS/EaglContext.mm
index 380c139..e033718 100644
--- a/src/SFML/Window/iOS/EaglContext.mm
+++ b/src/SFML/Window/iOS/EaglContext.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/InputImpl.hpp b/src/SFML/Window/iOS/InputImpl.hpp
index 43733cb..8c89dcb 100644
--- a/src/SFML/Window/iOS/InputImpl.hpp
+++ b/src/SFML/Window/iOS/InputImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/InputImpl.mm b/src/SFML/Window/iOS/InputImpl.mm
index b8dd103..c6cccaa 100644
--- a/src/SFML/Window/iOS/InputImpl.mm
+++ b/src/SFML/Window/iOS/InputImpl.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/JoystickImpl.hpp b/src/SFML/Window/iOS/JoystickImpl.hpp
index 59f31f2..47f8517 100644
--- a/src/SFML/Window/iOS/JoystickImpl.hpp
+++ b/src/SFML/Window/iOS/JoystickImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/JoystickImpl.mm b/src/SFML/Window/iOS/JoystickImpl.mm
index 6821e03..240c700 100644
--- a/src/SFML/Window/iOS/JoystickImpl.mm
+++ b/src/SFML/Window/iOS/JoystickImpl.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/ObjCType.hpp b/src/SFML/Window/iOS/ObjCType.hpp
index 5b111d5..17cb1b4 100644
--- a/src/SFML/Window/iOS/ObjCType.hpp
+++ b/src/SFML/Window/iOS/ObjCType.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFAppDelegate.hpp b/src/SFML/Window/iOS/SFAppDelegate.hpp
index cd20bfc..012e02e 100644
--- a/src/SFML/Window/iOS/SFAppDelegate.hpp
+++ b/src/SFML/Window/iOS/SFAppDelegate.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFAppDelegate.mm b/src/SFML/Window/iOS/SFAppDelegate.mm
index 5908b4e..3284b9a 100644
--- a/src/SFML/Window/iOS/SFAppDelegate.mm
+++ b/src/SFML/Window/iOS/SFAppDelegate.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFMain.hpp b/src/SFML/Window/iOS/SFMain.hpp
index f52857b..bcd3153 100644
--- a/src/SFML/Window/iOS/SFMain.hpp
+++ b/src/SFML/Window/iOS/SFMain.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFMain.mm b/src/SFML/Window/iOS/SFMain.mm
index 0e9d481..81b2452 100644
--- a/src/SFML/Window/iOS/SFMain.mm
+++ b/src/SFML/Window/iOS/SFMain.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFView.hpp b/src/SFML/Window/iOS/SFView.hpp
index 4804797..1066927 100644
--- a/src/SFML/Window/iOS/SFView.hpp
+++ b/src/SFML/Window/iOS/SFView.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFView.mm b/src/SFML/Window/iOS/SFView.mm
index b818749..efe8d3e 100644
--- a/src/SFML/Window/iOS/SFView.mm
+++ b/src/SFML/Window/iOS/SFView.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFViewController.hpp b/src/SFML/Window/iOS/SFViewController.hpp
index ecc8476..37a06aa 100644
--- a/src/SFML/Window/iOS/SFViewController.hpp
+++ b/src/SFML/Window/iOS/SFViewController.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SFViewController.mm b/src/SFML/Window/iOS/SFViewController.mm
index 0142297..a17f99c 100644
--- a/src/SFML/Window/iOS/SFViewController.mm
+++ b/src/SFML/Window/iOS/SFViewController.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SensorImpl.hpp b/src/SFML/Window/iOS/SensorImpl.hpp
index 0e3f211..cce8e44 100644
--- a/src/SFML/Window/iOS/SensorImpl.hpp
+++ b/src/SFML/Window/iOS/SensorImpl.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/SensorImpl.mm b/src/SFML/Window/iOS/SensorImpl.mm
index 96e4c7a..7801a8f 100644
--- a/src/SFML/Window/iOS/SensorImpl.mm
+++ b/src/SFML/Window/iOS/SensorImpl.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/VideoModeImpl.mm b/src/SFML/Window/iOS/VideoModeImpl.mm
index dd3d134..d054adf 100644
--- a/src/SFML/Window/iOS/VideoModeImpl.mm
+++ b/src/SFML/Window/iOS/VideoModeImpl.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
diff --git a/src/SFML/Window/iOS/WindowImplUIKit.hpp b/src/SFML/Window/iOS/WindowImplUIKit.hpp
index 53c066e..444672c 100644
--- a/src/SFML/Window/iOS/WindowImplUIKit.hpp
+++ b/src/SFML/Window/iOS/WindowImplUIKit.hpp
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -150,6 +150,14 @@ public:
virtual void setMouseCursorVisible(bool visible);
////////////////////////////////////////////////////////////
+ /// \brief Clips or releases the mouse cursor
+ ///
+ /// \param grabbed True to enable, false to disable
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void setMouseCursorGrabbed(bool grabbed);
+
+ ////////////////////////////////////////////////////////////
/// \brief Enable or disable automatic key-repeat
///
/// \param enabled True to enable, false to disable
diff --git a/src/SFML/Window/iOS/WindowImplUIKit.mm b/src/SFML/Window/iOS/WindowImplUIKit.mm
index 3e7c833..3abfc10 100644
--- a/src/SFML/Window/iOS/WindowImplUIKit.mm
+++ b/src/SFML/Window/iOS/WindowImplUIKit.mm
@@ -1,7 +1,7 @@
////////////////////////////////////////////////////////////
//
// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2015 Laurent Gomila (laurent@sfml-dev.org)
+// Copyright (C) 2007-2016 Laurent Gomila (laurent@sfml-dev.org)
//
// 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.
@@ -184,6 +184,13 @@ void WindowImplUIKit::setMouseCursorVisible(bool visible)
////////////////////////////////////////////////////////////
+void WindowImplUIKit::setMouseCursorGrabbed(bool grabbed)
+{
+ // Not applicable
+}
+
+
+////////////////////////////////////////////////////////////
void WindowImplUIKit::setKeyRepeatEnabled(bool enabled)
{
// Not applicable