diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 79b06288..bebaf8e4 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -1871,6 +1871,40 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow* window, int entered); */ typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffset); +/*! @brief The function pointer type for trackpad zoom callbacks. + * + * This is the function pointer type for trackpad zoom callbacks. A zoom + * callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, double scale) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] scale The manigification amount + * + * @sa @ref glfwSetTrackpadZoomCallback + * + * @ingroup input + */ +typedef void (* GLFWtrackpadzoomfun)(GLFWwindow* window, double scale); + +/*! @brief The function pointer type for trackpad rotate callbacks. + * + * This is the function pointer type for trackpad rotate callbacks. A rotate + * callback function has the following signature: + * @code + * void function_name(GLFWwindow* window, double angle) + * @endcode + * + * @param[in] window The window that received the event. + * @param[in] angle The rotation amount + * + * @sa @ref glfwSetTrackpadRotateCallback + * + * @ingroup input + */ +typedef void (* GLFWtrackpadrotatefun)(GLFWwindow* window, double angle); + /*! @brief The function pointer type for keyboard key callbacks. * * This is the function pointer type for keyboard key callbacks. A keyboard @@ -5430,6 +5464,58 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu */ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun callback); +/*! @brief Sets the trackpad zoom callback. + * + * This function sets the trackpad zoom of the specified window, which is + * called when a trackpad magnification gesture is used on macOS. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new trackpad zoom callback, or `NULL` to remove the + * currently set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double scale) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWtrackpadzoomfun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @ingroup input + */ +GLFWAPI GLFWtrackpadzoomfun glfwSetTrackpadZoomCallback(GLFWwindow* window, GLFWtrackpadzoomfun callback); + +/*! @brief Sets the trackpad rotate callback. + * + * This function sets the trackpad rotate of the specified window, which is + * called when a trackpad rotation gesture is used on macOS. + * + * @param[in] window The window whose callback to set. + * @param[in] callback The new trackpad rotate callback, or `NULL` to remove the + * currently set callback. + * @return The previously set callback, or `NULL` if no callback was set or the + * library had not been [initialized](@ref intro_init). + * + * @callback_signature + * @code + * void function_name(GLFWwindow* window, double angle) + * @endcode + * For more information about the callback parameters, see the + * [function pointer type](@ref GLFWtrackpadrotatefun). + * + * @errors Possible errors include @ref GLFW_NOT_INITIALIZED. + * + * @thread_safety This function must only be called from the main thread. + * + * @ingroup input + */ +GLFWAPI GLFWtrackpadrotatefun glfwSetTrackpadRotateCallback(GLFWwindow* window, GLFWtrackpadrotatefun callback); + /*! @brief Sets the path drop callback. * * This function sets the path drop callback of the specified window, which is diff --git a/src/cocoa_window.m b/src/cocoa_window.m index e69b5fe0..05cb2e51 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -614,6 +614,22 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; _glfwInputScroll(window, deltaX, deltaY); } +- (void)magnifyWithEvent:(NSEvent *)event +{ + double magnification = [event magnification]; + + if (fabs(magnification) > 0.0) + _glfwInputTrackpadZoom(window, magnification); +} + +- (void)rotateWithEvent:(NSEvent *)event +{ + double rotation = [event rotation]; + + if (fabs(rotation) > 0.0) + _glfwInputTrackpadRotate(window, rotation); +} + - (NSDragOperation)draggingEntered:(id )sender { // HACK: We don't know what to say here because we don't know what the diff --git a/src/input.c b/src/input.c index c619eefc..4aa44e3d 100644 --- a/src/input.c +++ b/src/input.c @@ -342,6 +342,30 @@ void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset) window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset); } +// Notifies shared code of a trackpad zoom event +// +void _glfwInputTrackpadZoom(_GLFWwindow* window, double scale) +{ + assert(window != NULL); + assert(scale > -FLT_MAX); + assert(scale < FLT_MAX); + + if (window->callbacks.trackpadZoom) + window->callbacks.trackpadZoom((GLFWwindow*) window, scale); +} + +// Notifies shared code of a trackpad rotate event +// +void _glfwInputTrackpadRotate(_GLFWwindow* window, double angle) +{ + assert(window != NULL); + assert(angle > -FLT_MAX); + assert(angle < FLT_MAX); + + if (window->callbacks.trackpadRotate) + window->callbacks.trackpadRotate((GLFWwindow*) window, angle); +} + // Notifies shared code of a mouse button click event // void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods) @@ -1034,6 +1058,28 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, return cbfun; } +GLFWAPI GLFWtrackpadzoomfun glfwSetTrackpadZoomCallback(GLFWwindow* handle, + GLFWtrackpadzoomfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP(GLFWtrackpadzoomfun, window->callbacks.trackpadZoom, cbfun); + return cbfun; +} + +GLFWAPI GLFWtrackpadzoomfun glfwSetTrackpadRotateCallback(GLFWwindow* handle, + GLFWtrackpadrotatefun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + assert(window != NULL); + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + _GLFW_SWAP(GLFWtrackpadrotatefun, window->callbacks.trackpadRotate, cbfun); + return cbfun; +} + GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) { _GLFW_REQUIRE_INIT_OR_RETURN(NULL); diff --git a/src/internal.h b/src/internal.h index 4f097aa8..7a58cbae 100644 --- a/src/internal.h +++ b/src/internal.h @@ -577,6 +577,8 @@ struct _GLFWwindow GLFWcursorposfun cursorPos; GLFWcursorenterfun cursorEnter; GLFWscrollfun scroll; + GLFWtrackpadzoomfun trackpadZoom; + GLFWtrackpadrotatefun trackpadRotate; GLFWkeyfun key; GLFWcharfun character; GLFWcharmodsfun charmods; @@ -935,6 +937,8 @@ void _glfwInputKey(_GLFWwindow* window, void _glfwInputChar(_GLFWwindow* window, uint32_t codepoint, int mods, GLFWbool plain); void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset); +void _glfwInputTrackpadZoom(_GLFWwindow* window, double scale); +void _glfwInputTrackpadRotate(_GLFWwindow* window, double angle); void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods); void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos); void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered); diff --git a/tests/events.c b/tests/events.c index ab3b99a7..f3c68949 100644 --- a/tests/events.c +++ b/tests/events.c @@ -397,6 +397,20 @@ static void scroll_callback(GLFWwindow* window, double x, double y) counter++, slot->number, glfwGetTime(), x, y); } +static void trackpad_zoom_callback(GLFWwindow* window, double scale) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Trackpad Zoom: %0.3f\n", + counter++, slot->number, glfwGetTime(), scale); +} + +static void trackpad_rotate_callback(GLFWwindow* window, double angle) +{ + Slot* slot = glfwGetWindowUserPointer(window); + printf("%08x to %i at %0.3f: Trackpad Rotate: %0.3f\n", + counter++, slot->number, glfwGetTime(), angle); +} + static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) { Slot* slot = glfwGetWindowUserPointer(window); @@ -647,6 +661,8 @@ int main(int argc, char** argv) glfwSetCursorPosCallback(slots[i].window, cursor_position_callback); glfwSetCursorEnterCallback(slots[i].window, cursor_enter_callback); glfwSetScrollCallback(slots[i].window, scroll_callback); + glfwSetTrackpadZoomCallback(slots[i].window, trackpad_zoom_callback); + glfwSetTrackpadRotateCallback(slots[i].window, trackpad_rotate_callback); glfwSetKeyCallback(slots[i].window, key_callback); glfwSetCharCallback(slots[i].window, char_callback); glfwSetDropCallback(slots[i].window, drop_callback);