From 1b5e6812fbecb0983bfd83204a23f7b146ed291a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 24 Jun 2018 02:19:04 +0200 Subject: [PATCH] Platform: setup GlfwApplication callbacks in a central place. Removes all needless private static class members and fixes a bug introduced when getting rid of the global window pointer -- the user window pointer was set only in the case of having a GL context, not in the contextless case. Boom. (This bug happened after 2018.04, so I'm not putting that in the changelog.) --- src/Magnum/Platform/GlfwApplication.cpp | 159 +++++++++++------------- src/Magnum/Platform/GlfwApplication.h | 9 +- 2 files changed, 73 insertions(+), 95 deletions(-) diff --git a/src/Magnum/Platform/GlfwApplication.cpp b/src/Magnum/Platform/GlfwApplication.cpp index 78a6d31ef..fcfd93e5a 100644 --- a/src/Magnum/Platform/GlfwApplication.cpp +++ b/src/Magnum/Platform/GlfwApplication.cpp @@ -64,7 +64,9 @@ GlfwApplication::GlfwApplication(const Arguments& arguments, NoCreateT): #endif { /* Init GLFW */ - glfwSetErrorCallback(staticErrorCallback); + glfwSetErrorCallback([](int, const char* const description) { + Error{} << description; + }); if(!glfwInit()) { Error() << "Could not initialize GLFW"; @@ -138,12 +140,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration) { glfwSetInputMode(_window, GLFW_CURSOR, Int(configuration.cursorMode())); /* Set callbacks */ - glfwSetFramebufferSizeCallback(_window, staticViewportEvent); - glfwSetKeyCallback(_window, staticKeyEvent); - glfwSetCursorPosCallback(_window, staticMouseMoveEvent); - glfwSetMouseButtonCallback(_window, staticMouseEvent); - glfwSetScrollCallback(_window, staticMouseScrollEvent); - glfwSetCharCallback(_window, staticTextInputEvent); + setupCallbacks(); return true; } @@ -325,13 +322,7 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf glfwSetInputMode(_window, GLFW_CURSOR, Int(configuration.cursorMode())); /* Set callbacks */ - glfwSetWindowUserPointer(_window, this); - glfwSetFramebufferSizeCallback(_window, staticViewportEvent); - glfwSetKeyCallback(_window, staticKeyEvent); - glfwSetCursorPosCallback(_window, staticMouseMoveEvent); - glfwSetMouseButtonCallback(_window, staticMouseEvent); - glfwSetScrollCallback(_window, staticMouseScrollEvent); - glfwSetCharCallback(_window, staticTextInputEvent); + setupCallbacks(); /* Make the final context current */ glfwMakeContextCurrent(_window); @@ -351,6 +342,73 @@ bool GlfwApplication::tryCreate(const Configuration& configuration, const GLConf } #endif +void GlfwApplication::setupCallbacks() { + glfwSetWindowUserPointer(_window, this); + glfwSetFramebufferSizeCallback(_window, [](GLFWwindow* const window, const int w, const int h) { + static_cast(glfwGetWindowUserPointer(window))->viewportEvent({w, h}); + }); + glfwSetKeyCallback(_window, [](GLFWwindow* const window, const int key, int, const int action, const int mods) { + const auto instance = static_cast(glfwGetWindowUserPointer(window)); + + KeyEvent e(static_cast(key), {static_cast(mods)}, action == GLFW_REPEAT); + + if(action == GLFW_PRESS) { + instance->keyPressEvent(e); + } else if(action == GLFW_RELEASE) { + instance->keyReleaseEvent(e); + } else if(action == GLFW_REPEAT) { + instance->keyPressEvent(e); + } + }); + glfwSetMouseButtonCallback(_window, [](GLFWwindow* const window, const int button, const int action, const int mods) { + const auto instance = static_cast(glfwGetWindowUserPointer(window)); + + double x, y; + glfwGetCursorPos(window, &x, &y); + MouseEvent e(static_cast(button), {Int(x), Int(y)}, {static_cast(mods)}); + + if(action == GLFW_PRESS) { + instance->mousePressEvent(e); + } else if(action == GLFW_RELEASE) { + instance->mouseReleaseEvent(e); + } /* we don't handle GLFW_REPEAT */ + }); + glfwSetCursorPosCallback(_window, [](GLFWwindow* const window, const double x, const double y) { + MouseMoveEvent e{window, Vector2i{Int(x), Int(y)}}; + static_cast(glfwGetWindowUserPointer(window))->mouseMoveEvent(e); + }); + glfwSetScrollCallback(_window, [](GLFWwindow* window, double xoffset, double yoffset) { + const auto instance = static_cast(glfwGetWindowUserPointer(window)); + + MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)}); + instance->mouseScrollEvent(e); + + #ifdef MAGNUM_BUILD_DEPRECATED + if(yoffset != 0.0) { + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #endif + MouseEvent e1((yoffset > 0.0) ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {}, currentGlfwModifiers(window)); + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif + instance->mousePressEvent(e1); + } + #endif + }); + glfwSetCharCallback(_window, [](GLFWwindow* window, unsigned int codepoint) { + const auto instance = static_cast(glfwGetWindowUserPointer(window)); + + if(!(instance->_flags & Flag::TextInputActive)) return; + + char utf8[4]; + const std::size_t size = Utility::Unicode::utf8(codepoint, utf8); + TextInputEvent e{{utf8, size}}; + instance->textInputEvent(e); + }); +} + GlfwApplication::~GlfwApplication() { glfwDestroyWindow(_window); glfwTerminate(); @@ -377,24 +435,6 @@ int GlfwApplication::exec() { return 0; } -void GlfwApplication::staticViewportEvent(GLFWwindow* const window, const int w, const int h) { - static_cast(glfwGetWindowUserPointer(window))->viewportEvent({w, h}); -} - -void GlfwApplication::staticKeyEvent(GLFWwindow* const window, const int key, int, const int action, const int mods) { - const auto instance = static_cast(glfwGetWindowUserPointer(window)); - - KeyEvent e(static_cast(key), {static_cast(mods)}, action == GLFW_REPEAT); - - if(action == GLFW_PRESS) { - instance->keyPressEvent(e); - } else if(action == GLFW_RELEASE) { - instance->keyReleaseEvent(e); - } else if(action == GLFW_REPEAT) { - instance->keyPressEvent(e); - } -} - auto GlfwApplication::MouseMoveEvent::buttons() -> Buttons { if(!_buttons) { _buttons = Buttons{}; @@ -419,61 +459,6 @@ auto GlfwApplication::MouseScrollEvent::modifiers() -> Modifiers { return *_modifiers; } -void GlfwApplication::staticMouseEvent(GLFWwindow* window, int button, int action, int mods) { - const auto instance = static_cast(glfwGetWindowUserPointer(window)); - - double x, y; - glfwGetCursorPos(window, &x, &y); - MouseEvent e(static_cast(button), {Int(x), Int(y)}, {static_cast(mods)}); - - if(action == GLFW_PRESS) { - instance->mousePressEvent(e); - } else if(action == GLFW_RELEASE) { - instance->mouseReleaseEvent(e); - } /* we don't handle GLFW_REPEAT */ -} - -void GlfwApplication::staticMouseMoveEvent(GLFWwindow* window, double x, double y) { - MouseMoveEvent e{window, Vector2i{Int(x), Int(y)}}; - static_cast(glfwGetWindowUserPointer(window))->mouseMoveEvent(e); -} - -void GlfwApplication::staticMouseScrollEvent(GLFWwindow* window, double xoffset, double yoffset) { - const auto instance = static_cast(glfwGetWindowUserPointer(window)); - - MouseScrollEvent e(window, Vector2{Float(xoffset), Float(yoffset)}); - instance->mouseScrollEvent(e); - - #ifdef MAGNUM_BUILD_DEPRECATED - if(yoffset != 0.0) { - #ifdef __GNUC__ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - #endif - MouseEvent e1((yoffset > 0.0) ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {}, currentGlfwModifiers(window)); - #ifdef __GNUC__ - #pragma GCC diagnostic pop - #endif - instance->mousePressEvent(e1); - } - #endif -} - -void GlfwApplication::staticTextInputEvent(GLFWwindow* window, unsigned int codepoint) { - const auto instance = static_cast(glfwGetWindowUserPointer(window)); - - if(!(instance->_flags & Flag::TextInputActive)) return; - - char utf8[4]; - const std::size_t size = Utility::Unicode::utf8(codepoint, utf8); - TextInputEvent e{{utf8, size}}; - instance->textInputEvent(e); -} - -void GlfwApplication::staticErrorCallback(int, const char* description) { - Error() << description; -} - void GlfwApplication::viewportEvent(const Vector2i&) {} void GlfwApplication::keyPressEvent(KeyEvent&) {} void GlfwApplication::keyReleaseEvent(KeyEvent&) {} diff --git a/src/Magnum/Platform/GlfwApplication.h b/src/Magnum/Platform/GlfwApplication.h index f20083d0b..316cd2bfb 100644 --- a/src/Magnum/Platform/GlfwApplication.h +++ b/src/Magnum/Platform/GlfwApplication.h @@ -467,14 +467,7 @@ class GlfwApplication { typedef Containers::EnumSet Flags; CORRADE_ENUMSET_FRIEND_OPERATORS(Flags) - static void staticErrorCallback(int error, const char* description); - - static void staticViewportEvent(GLFWwindow* window, int w, int h); - static void staticKeyEvent(GLFWwindow* window, int key, int scancode, int action, int mod); - static void staticMouseEvent(GLFWwindow* window, int button, int action, int mods); - static void staticMouseMoveEvent(GLFWwindow* window, double x, double y); - static void staticMouseScrollEvent(GLFWwindow* window, double xoffset, double yoffset); - static void staticTextInputEvent(GLFWwindow* window, unsigned int codepoint); + void setupCallbacks(); GLFWwindow* _window{nullptr}; Flags _flags;