mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-24 02:38:53 +01:00
parent
59399b01e3
commit
d0b6d2c41a
@ -20,7 +20,6 @@ package glfw
|
||||
#include "glfw/src/x11_window.c"
|
||||
#include "glfw/src/glx_context.c"
|
||||
#endif
|
||||
#include "glfw/src/null_joystick.c"
|
||||
#include "glfw/src/posix_time.c"
|
||||
#include "glfw/src/posix_thread.c"
|
||||
#include "glfw/src/xkb_unicode.c"
|
||||
|
@ -3,7 +3,6 @@ package glfw
|
||||
/*
|
||||
#cgo CFLAGS: -x objective-c
|
||||
#include "glfw/src/cocoa_init.m"
|
||||
#include "glfw/src/cocoa_joystick.m"
|
||||
#include "glfw/src/cocoa_monitor.m"
|
||||
#include "glfw/src/cocoa_window.m"
|
||||
#include "glfw/src/cocoa_time.c"
|
||||
|
@ -18,7 +18,6 @@ package glfw
|
||||
#include "glfw/src/x11_monitor.c"
|
||||
#include "glfw/src/glx_context.c"
|
||||
#endif
|
||||
#include "glfw/src/linux_joystick.c"
|
||||
#include "glfw/src/posix_time.c"
|
||||
#include "glfw/src/posix_thread.c"
|
||||
#include "glfw/src/xkb_unicode.c"
|
||||
|
@ -315,24 +315,6 @@ extern "C" {
|
||||
#define GLFW_REPEAT 2
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup hat_state Joystick hat states
|
||||
* @brief Joystick hat states.
|
||||
*
|
||||
* See [joystick hat input](@ref joystick_hat) for how these are used.
|
||||
*
|
||||
* @ingroup input
|
||||
* @{ */
|
||||
#define GLFW_HAT_CENTERED 0
|
||||
#define GLFW_HAT_UP 1
|
||||
#define GLFW_HAT_RIGHT 2
|
||||
#define GLFW_HAT_DOWN 4
|
||||
#define GLFW_HAT_LEFT 8
|
||||
#define GLFW_HAT_RIGHT_UP (GLFW_HAT_RIGHT | GLFW_HAT_UP)
|
||||
#define GLFW_HAT_RIGHT_DOWN (GLFW_HAT_RIGHT | GLFW_HAT_DOWN)
|
||||
#define GLFW_HAT_LEFT_UP (GLFW_HAT_LEFT | GLFW_HAT_UP)
|
||||
#define GLFW_HAT_LEFT_DOWN (GLFW_HAT_LEFT | GLFW_HAT_DOWN)
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup keys Keyboard keys
|
||||
* @brief Keyboard key IDs.
|
||||
*
|
||||
@ -552,78 +534,6 @@ extern "C" {
|
||||
#define GLFW_MOUSE_BUTTON_MIDDLE GLFW_MOUSE_BUTTON_3
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup joysticks Joysticks
|
||||
* @brief Joystick IDs.
|
||||
*
|
||||
* See [joystick input](@ref joystick) for how these are used.
|
||||
*
|
||||
* @ingroup input
|
||||
* @{ */
|
||||
#define GLFW_JOYSTICK_1 0
|
||||
#define GLFW_JOYSTICK_2 1
|
||||
#define GLFW_JOYSTICK_3 2
|
||||
#define GLFW_JOYSTICK_4 3
|
||||
#define GLFW_JOYSTICK_5 4
|
||||
#define GLFW_JOYSTICK_6 5
|
||||
#define GLFW_JOYSTICK_7 6
|
||||
#define GLFW_JOYSTICK_8 7
|
||||
#define GLFW_JOYSTICK_9 8
|
||||
#define GLFW_JOYSTICK_10 9
|
||||
#define GLFW_JOYSTICK_11 10
|
||||
#define GLFW_JOYSTICK_12 11
|
||||
#define GLFW_JOYSTICK_13 12
|
||||
#define GLFW_JOYSTICK_14 13
|
||||
#define GLFW_JOYSTICK_15 14
|
||||
#define GLFW_JOYSTICK_16 15
|
||||
#define GLFW_JOYSTICK_LAST GLFW_JOYSTICK_16
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup gamepad_buttons Gamepad buttons
|
||||
* @brief Gamepad buttons.
|
||||
*
|
||||
* See @ref gamepad for how these are used.
|
||||
*
|
||||
* @ingroup input
|
||||
* @{ */
|
||||
#define GLFW_GAMEPAD_BUTTON_A 0
|
||||
#define GLFW_GAMEPAD_BUTTON_B 1
|
||||
#define GLFW_GAMEPAD_BUTTON_X 2
|
||||
#define GLFW_GAMEPAD_BUTTON_Y 3
|
||||
#define GLFW_GAMEPAD_BUTTON_LEFT_BUMPER 4
|
||||
#define GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER 5
|
||||
#define GLFW_GAMEPAD_BUTTON_BACK 6
|
||||
#define GLFW_GAMEPAD_BUTTON_START 7
|
||||
#define GLFW_GAMEPAD_BUTTON_GUIDE 8
|
||||
#define GLFW_GAMEPAD_BUTTON_LEFT_THUMB 9
|
||||
#define GLFW_GAMEPAD_BUTTON_RIGHT_THUMB 10
|
||||
#define GLFW_GAMEPAD_BUTTON_DPAD_UP 11
|
||||
#define GLFW_GAMEPAD_BUTTON_DPAD_RIGHT 12
|
||||
#define GLFW_GAMEPAD_BUTTON_DPAD_DOWN 13
|
||||
#define GLFW_GAMEPAD_BUTTON_DPAD_LEFT 14
|
||||
#define GLFW_GAMEPAD_BUTTON_LAST GLFW_GAMEPAD_BUTTON_DPAD_LEFT
|
||||
|
||||
#define GLFW_GAMEPAD_BUTTON_CROSS GLFW_GAMEPAD_BUTTON_A
|
||||
#define GLFW_GAMEPAD_BUTTON_CIRCLE GLFW_GAMEPAD_BUTTON_B
|
||||
#define GLFW_GAMEPAD_BUTTON_SQUARE GLFW_GAMEPAD_BUTTON_X
|
||||
#define GLFW_GAMEPAD_BUTTON_TRIANGLE GLFW_GAMEPAD_BUTTON_Y
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup gamepad_axes Gamepad axes
|
||||
* @brief Gamepad axes.
|
||||
*
|
||||
* See @ref gamepad for how these are used.
|
||||
*
|
||||
* @ingroup input
|
||||
* @{ */
|
||||
#define GLFW_GAMEPAD_AXIS_LEFT_X 0
|
||||
#define GLFW_GAMEPAD_AXIS_LEFT_Y 1
|
||||
#define GLFW_GAMEPAD_AXIS_RIGHT_X 2
|
||||
#define GLFW_GAMEPAD_AXIS_RIGHT_Y 3
|
||||
#define GLFW_GAMEPAD_AXIS_LEFT_TRIGGER 4
|
||||
#define GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER 5
|
||||
#define GLFW_GAMEPAD_AXIS_LAST GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
|
||||
/*! @} */
|
||||
|
||||
/*! @defgroup errors Error codes
|
||||
* @brief Error codes.
|
||||
*
|
||||
@ -1076,13 +986,6 @@ extern "C" {
|
||||
#define GLFW_CONNECTED 0x00040001
|
||||
#define GLFW_DISCONNECTED 0x00040002
|
||||
|
||||
/*! @addtogroup init
|
||||
* @{ */
|
||||
/*! @brief Joystick hat buttons init hint.
|
||||
*
|
||||
* Joystick hat buttons [init hint](@ref GLFW_JOYSTICK_HAT_BUTTONS).
|
||||
*/
|
||||
#define GLFW_JOYSTICK_HAT_BUTTONS 0x00050001
|
||||
/*! @brief macOS specific init hint.
|
||||
*
|
||||
* macOS specific [init hint](@ref GLFW_COCOA_CHDIR_RESOURCES_hint).
|
||||
@ -1590,27 +1493,6 @@ typedef void (* GLFWdropfun)(GLFWwindow* window, int path_count, const char* pat
|
||||
*/
|
||||
typedef void (* GLFWmonitorfun)(GLFWmonitor* monitor, int event);
|
||||
|
||||
/*! @brief The function pointer type for joystick configuration callbacks.
|
||||
*
|
||||
* This is the function pointer type for joystick configuration callbacks.
|
||||
* A joystick configuration callback function has the following signature:
|
||||
* @code
|
||||
* void function_name(int jid, int event)
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] jid The joystick that was connected or disconnected.
|
||||
* @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. Future
|
||||
* releases may add more events.
|
||||
*
|
||||
* @sa @ref joystick_event
|
||||
* @sa @ref glfwSetJoystickCallback
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef void (* GLFWjoystickfun)(int jid, int event);
|
||||
|
||||
/*! @brief Video mode type.
|
||||
*
|
||||
* This describes a single video mode.
|
||||
@ -1700,29 +1582,6 @@ typedef struct GLFWimage
|
||||
unsigned char* pixels;
|
||||
} GLFWimage;
|
||||
|
||||
/*! @brief Gamepad input state
|
||||
*
|
||||
* This describes the input state of a gamepad.
|
||||
*
|
||||
* @sa @ref gamepad
|
||||
* @sa @ref glfwGetGamepadState
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef struct GLFWgamepadstate
|
||||
{
|
||||
/*! The states of each [gamepad button](@ref gamepad_buttons), `GLFW_PRESS`
|
||||
* or `GLFW_RELEASE`.
|
||||
*/
|
||||
unsigned char buttons[15];
|
||||
/*! The states of each [gamepad axis](@ref gamepad_axes), in the range -1.0
|
||||
* to 1.0 inclusive.
|
||||
*/
|
||||
float axes[6];
|
||||
} GLFWgamepadstate;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* GLFW API functions
|
||||
@ -4810,451 +4669,6 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun ca
|
||||
*/
|
||||
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun callback);
|
||||
|
||||
/*! @brief Returns whether the specified joystick is present.
|
||||
*
|
||||
* This function returns whether the specified joystick is present.
|
||||
*
|
||||
* There is no need to call this function before other functions that accept
|
||||
* a joystick ID, as they all check for presence before performing any other
|
||||
* work.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @return `GLFW_TRUE` if the joystick is present, or `GLFW_FALSE` otherwise.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref joystick
|
||||
*
|
||||
* @since Added in version 3.0. Replaces `glfwGetJoystickParam`.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwJoystickPresent(int jid);
|
||||
|
||||
/*! @brief Returns the values of all axes of the specified joystick.
|
||||
*
|
||||
* This function returns the values of all axes of the specified joystick.
|
||||
* Each element in the array is a value between -1.0 and 1.0.
|
||||
*
|
||||
* If the specified joystick is not present this function will return `NULL`
|
||||
* but will not generate an error. This can be used instead of first calling
|
||||
* @ref glfwJoystickPresent.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @param[out] count Where to store the number of axis values in the returned
|
||||
* array. This is set to zero if the joystick is not present or an error
|
||||
* occurred.
|
||||
* @return An array of axis values, or `NULL` if the joystick is not present or
|
||||
* an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the specified joystick is
|
||||
* disconnected or the library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref joystick_axis
|
||||
*
|
||||
* @since Added in version 3.0. Replaces `glfwGetJoystickPos`.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
|
||||
|
||||
/*! @brief Returns the state of all buttons of the specified joystick.
|
||||
*
|
||||
* This function returns the state of all buttons of the specified joystick.
|
||||
* Each element in the array is either `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||
*
|
||||
* For backward compatibility with earlier versions that did not have @ref
|
||||
* glfwGetJoystickHats, the button array also includes all hats, each
|
||||
* represented as four buttons. The hats are in the same order as returned by
|
||||
* __glfwGetJoystickHats__ and are in the order _up_, _right_, _down_ and
|
||||
* _left_. To disable these extra buttons, set the @ref
|
||||
* GLFW_JOYSTICK_HAT_BUTTONS init hint before initialization.
|
||||
*
|
||||
* If the specified joystick is not present this function will return `NULL`
|
||||
* but will not generate an error. This can be used instead of first calling
|
||||
* @ref glfwJoystickPresent.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @param[out] count Where to store the number of button states in the returned
|
||||
* array. This is set to zero if the joystick is not present or an error
|
||||
* occurred.
|
||||
* @return An array of button states, or `NULL` if the joystick is not present
|
||||
* or an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the specified joystick is
|
||||
* disconnected or the library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref joystick_button
|
||||
*
|
||||
* @since Added in version 2.2.
|
||||
* @glfw3 Changed to return a dynamic array.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count);
|
||||
|
||||
/*! @brief Returns the state of all hats of the specified joystick.
|
||||
*
|
||||
* This function returns the state of all hats of the specified joystick.
|
||||
* Each element in the array is one of the following values:
|
||||
*
|
||||
* Name | Value
|
||||
* ---- | -----
|
||||
* `GLFW_HAT_CENTERED` | 0
|
||||
* `GLFW_HAT_UP` | 1
|
||||
* `GLFW_HAT_RIGHT` | 2
|
||||
* `GLFW_HAT_DOWN` | 4
|
||||
* `GLFW_HAT_LEFT` | 8
|
||||
* `GLFW_HAT_RIGHT_UP` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_UP`
|
||||
* `GLFW_HAT_RIGHT_DOWN` | `GLFW_HAT_RIGHT` \| `GLFW_HAT_DOWN`
|
||||
* `GLFW_HAT_LEFT_UP` | `GLFW_HAT_LEFT` \| `GLFW_HAT_UP`
|
||||
* `GLFW_HAT_LEFT_DOWN` | `GLFW_HAT_LEFT` \| `GLFW_HAT_DOWN`
|
||||
*
|
||||
* The diagonal directions are bitwise combinations of the primary (up, right,
|
||||
* down and left) directions and you can test for these individually by ANDing
|
||||
* it with the corresponding direction.
|
||||
*
|
||||
* @code
|
||||
* if (hats[2] & GLFW_HAT_RIGHT)
|
||||
* {
|
||||
* // State of hat 2 could be right-up, right or right-down
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* If the specified joystick is not present this function will return `NULL`
|
||||
* but will not generate an error. This can be used instead of first calling
|
||||
* @ref glfwJoystickPresent.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @param[out] count Where to store the number of hat states in the returned
|
||||
* array. This is set to zero if the joystick is not present or an error
|
||||
* occurred.
|
||||
* @return An array of hat states, or `NULL` if the joystick is not present
|
||||
* or an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned array is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the specified joystick is
|
||||
* disconnected, this function is called again for that joystick or the library
|
||||
* is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref joystick_hat
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count);
|
||||
|
||||
/*! @brief Returns the name of the specified joystick.
|
||||
*
|
||||
* This function returns the name, encoded as UTF-8, of the specified joystick.
|
||||
* The returned string is allocated and freed by GLFW. You should not free it
|
||||
* yourself.
|
||||
*
|
||||
* If the specified joystick is not present this function will return `NULL`
|
||||
* but will not generate an error. This can be used instead of first calling
|
||||
* @ref glfwJoystickPresent.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @return The UTF-8 encoded name of the joystick, or `NULL` if the joystick
|
||||
* is not present or an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the specified joystick is
|
||||
* disconnected or the library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref joystick_name
|
||||
*
|
||||
* @since Added in version 3.0.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI const char* glfwGetJoystickName(int jid);
|
||||
|
||||
/*! @brief Returns the SDL compatible GUID of the specified joystick.
|
||||
*
|
||||
* This function returns the SDL compatible GUID, as a UTF-8 encoded
|
||||
* hexadecimal string, of the specified joystick. The returned string is
|
||||
* allocated and freed by GLFW. You should not free it yourself.
|
||||
*
|
||||
* The GUID is what connects a joystick to a gamepad mapping. A connected
|
||||
* joystick will always have a GUID even if there is no gamepad mapping
|
||||
* assigned to it.
|
||||
*
|
||||
* If the specified joystick is not present this function will return `NULL`
|
||||
* but will not generate an error. This can be used instead of first calling
|
||||
* @ref glfwJoystickPresent.
|
||||
*
|
||||
* The GUID uses the format introduced in SDL 2.0.5. This GUID tries to
|
||||
* uniquely identify the make and model of a joystick but does not identify
|
||||
* a specific unit, e.g. all wired Xbox 360 controllers will have the same
|
||||
* GUID on that platform. The GUID for a unit may vary between platforms
|
||||
* depending on what hardware information the platform specific APIs provide.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @return The UTF-8 encoded GUID of the joystick, or `NULL` if the joystick
|
||||
* is not present or an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
|
||||
* GLFW_INVALID_ENUM and @ref GLFW_PLATFORM_ERROR.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the specified joystick is
|
||||
* disconnected or the library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref gamepad
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI const char* glfwGetJoystickGUID(int jid);
|
||||
|
||||
/*! @brief Sets the user pointer of the specified joystick.
|
||||
*
|
||||
* This function sets the user-defined pointer of the specified joystick. The
|
||||
* current value is retained until the joystick is disconnected. The initial
|
||||
* value is `NULL`.
|
||||
*
|
||||
* This function may be called from the joystick callback, even for a joystick
|
||||
* that is being disconnected.
|
||||
*
|
||||
* @param[in] jid The joystick whose pointer to set.
|
||||
* @param[in] pointer The new value.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @sa @ref joystick_userptr
|
||||
* @sa @ref glfwGetJoystickUserPointer
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer);
|
||||
|
||||
/*! @brief Returns the user pointer of the specified joystick.
|
||||
*
|
||||
* This function returns the current value of the user-defined pointer of the
|
||||
* specified joystick. The initial value is `NULL`.
|
||||
*
|
||||
* This function may be called from the joystick callback, even for a joystick
|
||||
* that is being disconnected.
|
||||
*
|
||||
* @param[in] jid The joystick whose pointer to return.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @thread_safety This function may be called from any thread. Access is not
|
||||
* synchronized.
|
||||
*
|
||||
* @sa @ref joystick_userptr
|
||||
* @sa @ref glfwSetJoystickUserPointer
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI void* glfwGetJoystickUserPointer(int jid);
|
||||
|
||||
/*! @brief Returns whether the specified joystick has a gamepad mapping.
|
||||
*
|
||||
* This function returns whether the specified joystick is both present and has
|
||||
* a gamepad mapping.
|
||||
*
|
||||
* If the specified joystick is present but does not have a gamepad mapping
|
||||
* this function will return `GLFW_FALSE` but will not generate an error. Call
|
||||
* @ref glfwJoystickPresent to check if a joystick is present regardless of
|
||||
* whether it has a mapping.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @return `GLFW_TRUE` if a joystick is both present and has a gamepad mapping,
|
||||
* or `GLFW_FALSE` otherwise.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_INVALID_ENUM.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref gamepad
|
||||
* @sa @ref glfwGetGamepadState
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwJoystickIsGamepad(int jid);
|
||||
|
||||
/*! @brief Sets the joystick configuration callback.
|
||||
*
|
||||
* This function sets the joystick configuration callback, or removes the
|
||||
* currently set callback. This is called when a joystick is connected to or
|
||||
* disconnected from the system.
|
||||
*
|
||||
* For joystick connection and disconnection events to be delivered on all
|
||||
* platforms, you need to call one of the [event processing](@ref events)
|
||||
* functions. Joystick disconnection may also be detected and the callback
|
||||
* called by joystick functions. The function will then return whatever it
|
||||
* returns if the joystick is not present.
|
||||
*
|
||||
* @param[in] callback The new 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(int jid, int event)
|
||||
* @endcode
|
||||
* For more information about the callback parameters, see the
|
||||
* [function pointer type](@ref GLFWjoystickfun).
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref joystick_event
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun callback);
|
||||
|
||||
/*! @brief Adds the specified SDL_GameControllerDB gamepad mappings.
|
||||
*
|
||||
* This function parses the specified ASCII encoded string and updates the
|
||||
* internal list with any gamepad mappings it finds. This string may
|
||||
* contain either a single gamepad mapping or many mappings separated by
|
||||
* newlines. The parser supports the full format of the `gamecontrollerdb.txt`
|
||||
* source file including empty lines and comments.
|
||||
*
|
||||
* See @ref gamepad_mapping for a description of the format.
|
||||
*
|
||||
* If there is already a gamepad mapping for a given GUID in the internal list,
|
||||
* it will be replaced by the one passed to this function. If the library is
|
||||
* terminated and re-initialized the internal list will revert to the built-in
|
||||
* default.
|
||||
*
|
||||
* @param[in] string The string containing the gamepad mappings.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_INVALID_VALUE.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref gamepad
|
||||
* @sa @ref glfwJoystickIsGamepad
|
||||
* @sa @ref glfwGetGamepadName
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwUpdateGamepadMappings(const char* string);
|
||||
|
||||
/*! @brief Returns the human-readable gamepad name for the specified joystick.
|
||||
*
|
||||
* This function returns the human-readable name of the gamepad from the
|
||||
* gamepad mapping assigned to the specified joystick.
|
||||
*
|
||||
* If the specified joystick is not present or does not have a gamepad mapping
|
||||
* this function will return `NULL` but will not generate an error. Call
|
||||
* @ref glfwJoystickPresent to check whether it is present regardless of
|
||||
* whether it has a mapping.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @return The UTF-8 encoded name of the gamepad, or `NULL` if the
|
||||
* joystick is not present, does not have a mapping or an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref GLFW_INVALID_ENUM.
|
||||
*
|
||||
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
|
||||
* should not free it yourself. It is valid until the specified joystick is
|
||||
* disconnected, the gamepad mappings are updated or the library is terminated.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref gamepad
|
||||
* @sa @ref glfwJoystickIsGamepad
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI const char* glfwGetGamepadName(int jid);
|
||||
|
||||
/*! @brief Retrieves the state of the specified joystick remapped as a gamepad.
|
||||
*
|
||||
* This function retrieves the state of the specified joystick remapped to
|
||||
* an Xbox-like gamepad.
|
||||
*
|
||||
* If the specified joystick is not present or does not have a gamepad mapping
|
||||
* this function will return `GLFW_FALSE` but will not generate an error. Call
|
||||
* @ref glfwJoystickPresent to check whether it is present regardless of
|
||||
* whether it has a mapping.
|
||||
*
|
||||
* The Guide button may not be available for input as it is often hooked by the
|
||||
* system or the Steam client.
|
||||
*
|
||||
* Not all devices have all the buttons or axes provided by @ref
|
||||
* GLFWgamepadstate. Unavailable buttons and axes will always report
|
||||
* `GLFW_RELEASE` and 0.0 respectively.
|
||||
*
|
||||
* @param[in] jid The [joystick](@ref joysticks) to query.
|
||||
* @param[out] state The gamepad input state of the joystick.
|
||||
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if no joystick is
|
||||
* connected, it has no gamepad mapping or an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
|
||||
* GLFW_INVALID_ENUM.
|
||||
*
|
||||
* @thread_safety This function must only be called from the main thread.
|
||||
*
|
||||
* @sa @ref gamepad
|
||||
* @sa @ref glfwUpdateGamepadMappings
|
||||
* @sa @ref glfwJoystickIsGamepad
|
||||
*
|
||||
* @since Added in version 3.3.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
|
||||
|
||||
/*! @brief Sets the clipboard to the specified string.
|
||||
*
|
||||
* This function sets the system clipboard to the specified, UTF-8 encoded
|
||||
|
@ -565,7 +565,6 @@ int _glfwPlatformInit(void)
|
||||
return GLFW_FALSE;
|
||||
|
||||
_glfwInitTimerNS();
|
||||
_glfwInitJoysticksNS();
|
||||
|
||||
_glfwPollMonitorsNS();
|
||||
return GLFW_TRUE;
|
||||
@ -617,7 +616,6 @@ void _glfwPlatformTerminate(void)
|
||||
_glfwTerminateNSGL();
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateOSMesa();
|
||||
_glfwTerminateJoysticksNS();
|
||||
|
||||
} // autoreleasepool
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Cocoa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/IOCFPlugIn.h>
|
||||
#include <IOKit/hid/IOHIDLib.h>
|
||||
#include <IOKit/hid/IOHIDKeys.h>
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyJoystick; }
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME "Mac OS X"
|
||||
#define GLFW_BUILD_COCOA_MAPPINGS
|
||||
|
||||
// Cocoa-specific per-joystick data
|
||||
//
|
||||
typedef struct _GLFWjoystickNS
|
||||
{
|
||||
IOHIDDeviceRef device;
|
||||
CFMutableArrayRef axes;
|
||||
CFMutableArrayRef buttons;
|
||||
CFMutableArrayRef hats;
|
||||
} _GLFWjoystickNS;
|
||||
|
||||
|
||||
void _glfwInitJoysticksNS(void);
|
||||
void _glfwTerminateJoysticksNS(void);
|
||||
|
@ -1,488 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Cocoa - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
|
||||
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_error.h>
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
|
||||
|
||||
|
||||
// Joystick element information
|
||||
//
|
||||
typedef struct _GLFWjoyelementNS
|
||||
{
|
||||
IOHIDElementRef native;
|
||||
uint32_t usage;
|
||||
int index;
|
||||
long minimum;
|
||||
long maximum;
|
||||
|
||||
} _GLFWjoyelementNS;
|
||||
|
||||
|
||||
// Returns the value of the specified element of the specified joystick
|
||||
//
|
||||
static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
|
||||
{
|
||||
IOHIDValueRef valueRef;
|
||||
long value = 0;
|
||||
|
||||
if (js->ns.device)
|
||||
{
|
||||
if (IOHIDDeviceGetValue(js->ns.device,
|
||||
element->native,
|
||||
&valueRef) == kIOReturnSuccess)
|
||||
{
|
||||
value = IOHIDValueGetIntegerValue(valueRef);
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Comparison function for matching the SDL element order
|
||||
//
|
||||
static CFComparisonResult compareElements(const void* fp,
|
||||
const void* sp,
|
||||
void* user)
|
||||
{
|
||||
const _GLFWjoyelementNS* fe = fp;
|
||||
const _GLFWjoyelementNS* se = sp;
|
||||
if (fe->usage < se->usage)
|
||||
return kCFCompareLessThan;
|
||||
if (fe->usage > se->usage)
|
||||
return kCFCompareGreaterThan;
|
||||
if (fe->index < se->index)
|
||||
return kCFCompareLessThan;
|
||||
if (fe->index > se->index)
|
||||
return kCFCompareGreaterThan;
|
||||
return kCFCompareEqualTo;
|
||||
}
|
||||
|
||||
// Removes the specified joystick
|
||||
//
|
||||
static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
int i;
|
||||
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
|
||||
CFRelease(js->ns.axes);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
|
||||
CFRelease(js->ns.buttons);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
|
||||
CFRelease(js->ns.hats);
|
||||
|
||||
_glfwFreeJoystick(js);
|
||||
}
|
||||
|
||||
// Callback for user-initiated joystick addition
|
||||
//
|
||||
static void matchCallback(void* context,
|
||||
IOReturn result,
|
||||
void* sender,
|
||||
IOHIDDeviceRef device)
|
||||
{
|
||||
int jid;
|
||||
char name[256];
|
||||
char guid[33];
|
||||
CFIndex i;
|
||||
CFTypeRef property;
|
||||
uint32_t vendor = 0, product = 0, version = 0;
|
||||
_GLFWjoystick* js;
|
||||
CFMutableArrayRef axes, buttons, hats;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (_glfw.joysticks[jid].ns.device == device)
|
||||
return;
|
||||
}
|
||||
|
||||
axes = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
buttons = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
hats = CFArrayCreateMutable(NULL, 0, NULL);
|
||||
|
||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
|
||||
if (property)
|
||||
{
|
||||
CFStringGetCString(property,
|
||||
name,
|
||||
sizeof(name),
|
||||
kCFStringEncodingUTF8);
|
||||
}
|
||||
else
|
||||
strncpy(name, "Unknown", sizeof(name));
|
||||
|
||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
|
||||
if (property)
|
||||
CFNumberGetValue(property, kCFNumberSInt32Type, &vendor);
|
||||
|
||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
|
||||
if (property)
|
||||
CFNumberGetValue(property, kCFNumberSInt32Type, &product);
|
||||
|
||||
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey));
|
||||
if (property)
|
||||
CFNumberGetValue(property, kCFNumberSInt32Type, &version);
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (vendor && product)
|
||||
{
|
||||
sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000",
|
||||
(uint8_t) vendor, (uint8_t) (vendor >> 8),
|
||||
(uint8_t) product, (uint8_t) (product >> 8),
|
||||
(uint8_t) version, (uint8_t) (version >> 8));
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||
name[0], name[1], name[2], name[3],
|
||||
name[4], name[5], name[6], name[7],
|
||||
name[8], name[9], name[10]);
|
||||
}
|
||||
|
||||
CFArrayRef elements =
|
||||
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(elements); i++)
|
||||
{
|
||||
IOHIDElementRef native = (IOHIDElementRef)
|
||||
CFArrayGetValueAtIndex(elements, i);
|
||||
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
|
||||
continue;
|
||||
|
||||
const IOHIDElementType type = IOHIDElementGetType(native);
|
||||
if ((type != kIOHIDElementTypeInput_Axis) &&
|
||||
(type != kIOHIDElementTypeInput_Button) &&
|
||||
(type != kIOHIDElementTypeInput_Misc))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CFMutableArrayRef target = NULL;
|
||||
|
||||
const uint32_t usage = IOHIDElementGetUsage(native);
|
||||
const uint32_t page = IOHIDElementGetUsagePage(native);
|
||||
if (page == kHIDPage_GenericDesktop)
|
||||
{
|
||||
switch (usage)
|
||||
{
|
||||
case kHIDUsage_GD_X:
|
||||
case kHIDUsage_GD_Y:
|
||||
case kHIDUsage_GD_Z:
|
||||
case kHIDUsage_GD_Rx:
|
||||
case kHIDUsage_GD_Ry:
|
||||
case kHIDUsage_GD_Rz:
|
||||
case kHIDUsage_GD_Slider:
|
||||
case kHIDUsage_GD_Dial:
|
||||
case kHIDUsage_GD_Wheel:
|
||||
target = axes;
|
||||
break;
|
||||
case kHIDUsage_GD_Hatswitch:
|
||||
target = hats;
|
||||
break;
|
||||
case kHIDUsage_GD_DPadUp:
|
||||
case kHIDUsage_GD_DPadRight:
|
||||
case kHIDUsage_GD_DPadDown:
|
||||
case kHIDUsage_GD_DPadLeft:
|
||||
case kHIDUsage_GD_SystemMainMenu:
|
||||
case kHIDUsage_GD_Select:
|
||||
case kHIDUsage_GD_Start:
|
||||
target = buttons;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (page == kHIDPage_Simulation)
|
||||
{
|
||||
switch (usage)
|
||||
{
|
||||
case kHIDUsage_Sim_Accelerator:
|
||||
case kHIDUsage_Sim_Brake:
|
||||
case kHIDUsage_Sim_Throttle:
|
||||
case kHIDUsage_Sim_Rudder:
|
||||
case kHIDUsage_Sim_Steering:
|
||||
target = axes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
|
||||
target = buttons;
|
||||
|
||||
if (target)
|
||||
{
|
||||
_GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS));
|
||||
element->native = native;
|
||||
element->usage = usage;
|
||||
element->index = (int) CFArrayGetCount(target);
|
||||
element->minimum = IOHIDElementGetLogicalMin(native);
|
||||
element->maximum = IOHIDElementGetLogicalMax(native);
|
||||
CFArrayAppendValue(target, element);
|
||||
}
|
||||
}
|
||||
|
||||
CFRelease(elements);
|
||||
|
||||
CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
|
||||
compareElements, NULL);
|
||||
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
|
||||
compareElements, NULL);
|
||||
CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
|
||||
compareElements, NULL);
|
||||
|
||||
js = _glfwAllocJoystick(name, guid,
|
||||
(int) CFArrayGetCount(axes),
|
||||
(int) CFArrayGetCount(buttons),
|
||||
(int) CFArrayGetCount(hats));
|
||||
|
||||
js->ns.device = device;
|
||||
js->ns.axes = axes;
|
||||
js->ns.buttons = buttons;
|
||||
js->ns.hats = hats;
|
||||
|
||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||
}
|
||||
|
||||
// Callback for user-initiated joystick removal
|
||||
//
|
||||
static void removeCallback(void* context,
|
||||
IOReturn result,
|
||||
void* sender,
|
||||
IOHIDDeviceRef device)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device)
|
||||
{
|
||||
closeJoystick(&_glfw.joysticks[jid]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Initialize joystick interface
|
||||
//
|
||||
void _glfwInitJoysticksNS(void)
|
||||
{
|
||||
CFMutableArrayRef matching;
|
||||
const long usages[] =
|
||||
{
|
||||
kHIDUsage_GD_Joystick,
|
||||
kHIDUsage_GD_GamePad,
|
||||
kHIDUsage_GD_MultiAxisController
|
||||
};
|
||||
|
||||
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
|
||||
kIOHIDOptionsTypeNone);
|
||||
|
||||
matching = CFArrayCreateMutable(kCFAllocatorDefault,
|
||||
0,
|
||||
&kCFTypeArrayCallBacks);
|
||||
if (!matching)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
|
||||
{
|
||||
const long page = kHIDPage_GenericDesktop;
|
||||
|
||||
CFMutableDictionaryRef dict =
|
||||
CFDictionaryCreateMutable(kCFAllocatorDefault,
|
||||
0,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks);
|
||||
if (!dict)
|
||||
continue;
|
||||
|
||||
CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberLongType,
|
||||
&page);
|
||||
CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,
|
||||
kCFNumberLongType,
|
||||
&usages[i]);
|
||||
if (pageRef && usageRef)
|
||||
{
|
||||
CFDictionarySetValue(dict,
|
||||
CFSTR(kIOHIDDeviceUsagePageKey),
|
||||
pageRef);
|
||||
CFDictionarySetValue(dict,
|
||||
CFSTR(kIOHIDDeviceUsageKey),
|
||||
usageRef);
|
||||
CFArrayAppendValue(matching, dict);
|
||||
}
|
||||
|
||||
if (pageRef)
|
||||
CFRelease(pageRef);
|
||||
if (usageRef)
|
||||
CFRelease(usageRef);
|
||||
|
||||
CFRelease(dict);
|
||||
}
|
||||
|
||||
IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching);
|
||||
CFRelease(matching);
|
||||
|
||||
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
|
||||
&matchCallback, NULL);
|
||||
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
|
||||
&removeCallback, NULL);
|
||||
IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
|
||||
CFRunLoopGetMain(),
|
||||
kCFRunLoopDefaultMode);
|
||||
IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);
|
||||
|
||||
// Execute the run loop once in order to register any initially-attached
|
||||
// joysticks
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
|
||||
}
|
||||
|
||||
// Close all opened joystick handles
|
||||
//
|
||||
void _glfwTerminateJoysticksNS(void)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (_glfw.joysticks[jid].connected)
|
||||
closeJoystick(&_glfw.joysticks[jid]);
|
||||
}
|
||||
|
||||
CFRelease(_glfw.ns.hidManager);
|
||||
_glfw.ns.hidManager = NULL;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
if (mode & _GLFW_POLL_AXES)
|
||||
{
|
||||
CFIndex i;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.axes); i++)
|
||||
{
|
||||
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->ns.axes, i);
|
||||
|
||||
const long raw = getElementValue(js, axis);
|
||||
// Perform auto calibration
|
||||
if (raw < axis->minimum)
|
||||
axis->minimum = raw;
|
||||
if (raw > axis->maximum)
|
||||
axis->maximum = raw;
|
||||
|
||||
const long size = axis->maximum - axis->minimum;
|
||||
if (size == 0)
|
||||
_glfwInputJoystickAxis(js, (int) i, 0.f);
|
||||
else
|
||||
{
|
||||
const float value = (2.f * (raw - axis->minimum) / size) - 1.f;
|
||||
_glfwInputJoystickAxis(js, (int) i, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mode & _GLFW_POLL_BUTTONS)
|
||||
{
|
||||
CFIndex i;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
|
||||
{
|
||||
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->ns.buttons, i);
|
||||
const char value = getElementValue(js, button) - button->minimum;
|
||||
const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE;
|
||||
_glfwInputJoystickButton(js, (int) i, state);
|
||||
}
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->ns.hats); i++)
|
||||
{
|
||||
const int states[9] =
|
||||
{
|
||||
GLFW_HAT_UP,
|
||||
GLFW_HAT_RIGHT_UP,
|
||||
GLFW_HAT_RIGHT,
|
||||
GLFW_HAT_RIGHT_DOWN,
|
||||
GLFW_HAT_DOWN,
|
||||
GLFW_HAT_LEFT_DOWN,
|
||||
GLFW_HAT_LEFT,
|
||||
GLFW_HAT_LEFT_UP,
|
||||
GLFW_HAT_CENTERED
|
||||
};
|
||||
|
||||
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->ns.hats, i);
|
||||
long state = getElementValue(js, hat) - hat->minimum;
|
||||
if (state < 0 || state > 8)
|
||||
state = 8;
|
||||
|
||||
_glfwInputJoystickHat(js, (int) i, states[state]);
|
||||
}
|
||||
}
|
||||
|
||||
return js->connected;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
{
|
||||
if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
|
||||
(strncmp(guid + 20, "000000000000", 12) == 0))
|
||||
{
|
||||
char original[33];
|
||||
strncpy(original, guid, sizeof(original) - 1);
|
||||
sprintf(guid, "03000000%.4s0000%.4s000000000000",
|
||||
original, original + 16);
|
||||
}
|
||||
}
|
||||
|
@ -96,7 +96,6 @@ typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacO
|
||||
typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
|
||||
|
||||
#include "posix_thread.h"
|
||||
#include "cocoa_joystick.h"
|
||||
#include "nsgl_context.h"
|
||||
#include "egl_context.h"
|
||||
#include "osmesa_context.h"
|
||||
@ -157,7 +156,6 @@ typedef struct _GLFWlibraryNS
|
||||
GLFWbool finishedLaunching;
|
||||
GLFWbool cursorHidden;
|
||||
TISInputSourceRef inputSource;
|
||||
IOHIDManagerRef hidManager;
|
||||
id unicodeData;
|
||||
id helper;
|
||||
id keyUpMonitor;
|
||||
|
@ -50,7 +50,6 @@ static _GLFWerror _glfwMainThreadError;
|
||||
static GLFWerrorfun _glfwErrorCallback;
|
||||
static _GLFWinitconfig _glfwInitHints =
|
||||
{
|
||||
GLFW_TRUE, // hat buttons
|
||||
{
|
||||
GLFW_TRUE, // macOS menu bar
|
||||
GLFW_TRUE // macOS bundle chdir
|
||||
@ -83,10 +82,6 @@ static void terminate(void)
|
||||
_glfw.monitors = NULL;
|
||||
_glfw.monitorCount = 0;
|
||||
|
||||
free(_glfw.mappings);
|
||||
_glfw.mappings = NULL;
|
||||
_glfw.mappingCount = 0;
|
||||
|
||||
_glfwTerminateVulkan();
|
||||
_glfwPlatformTerminate();
|
||||
|
||||
@ -337,8 +332,6 @@ GLFWAPI int glfwInit(void)
|
||||
|
||||
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
|
||||
|
||||
_glfwInitGamepadMappings();
|
||||
|
||||
_glfw.initialized = GLFW_TRUE;
|
||||
_glfw.timer.offset = _glfwPlatformGetTimerValue();
|
||||
|
||||
@ -358,9 +351,6 @@ GLFWAPI void glfwInitHint(int hint, int value)
|
||||
{
|
||||
switch (hint)
|
||||
{
|
||||
case GLFW_JOYSTICK_HAT_BUTTONS:
|
||||
_glfwInitHints.hatButtons = value;
|
||||
return;
|
||||
case GLFW_COCOA_CHDIR_RESOURCES:
|
||||
_glfwInitHints.ns.chdir = value;
|
||||
return;
|
||||
|
@ -28,7 +28,6 @@
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
#include "mappings.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
@ -39,207 +38,6 @@
|
||||
// Internal key state used for sticky keys
|
||||
#define _GLFW_STICK 3
|
||||
|
||||
// Internal constants for gamepad mapping source types
|
||||
#define _GLFW_JOYSTICK_AXIS 1
|
||||
#define _GLFW_JOYSTICK_BUTTON 2
|
||||
#define _GLFW_JOYSTICK_HATBIT 3
|
||||
|
||||
// Finds a mapping based on joystick GUID
|
||||
//
|
||||
static _GLFWmapping* findMapping(const char* guid)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < _glfw.mappingCount; i++)
|
||||
{
|
||||
if (strcmp(_glfw.mappings[i].guid, guid) == 0)
|
||||
return _glfw.mappings + i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Checks whether a gamepad mapping element is present in the hardware
|
||||
//
|
||||
static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,
|
||||
const _GLFWjoystick* js)
|
||||
{
|
||||
if (e->type == _GLFW_JOYSTICK_HATBIT && (e->index >> 4) >= js->hatCount)
|
||||
return GLFW_FALSE;
|
||||
else if (e->type == _GLFW_JOYSTICK_BUTTON && e->index >= js->buttonCount)
|
||||
return GLFW_FALSE;
|
||||
else if (e->type == _GLFW_JOYSTICK_AXIS && e->index >= js->axisCount)
|
||||
return GLFW_FALSE;
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Finds a mapping based on joystick GUID and verifies element indices
|
||||
//
|
||||
static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
|
||||
{
|
||||
_GLFWmapping* mapping = findMapping(js->guid);
|
||||
if (mapping)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
|
||||
{
|
||||
if (!isValidElementForJoystick(mapping->buttons + i, js))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
|
||||
{
|
||||
if (!isValidElementForJoystick(mapping->axes + i, js))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
// Parses an SDL_GameControllerDB line and adds it to the mapping list
|
||||
//
|
||||
static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
|
||||
{
|
||||
const char* c = string;
|
||||
size_t i, length;
|
||||
struct
|
||||
{
|
||||
const char* name;
|
||||
_GLFWmapelement* element;
|
||||
} fields[] =
|
||||
{
|
||||
{ "platform", NULL },
|
||||
{ "a", mapping->buttons + GLFW_GAMEPAD_BUTTON_A },
|
||||
{ "b", mapping->buttons + GLFW_GAMEPAD_BUTTON_B },
|
||||
{ "x", mapping->buttons + GLFW_GAMEPAD_BUTTON_X },
|
||||
{ "y", mapping->buttons + GLFW_GAMEPAD_BUTTON_Y },
|
||||
{ "back", mapping->buttons + GLFW_GAMEPAD_BUTTON_BACK },
|
||||
{ "start", mapping->buttons + GLFW_GAMEPAD_BUTTON_START },
|
||||
{ "guide", mapping->buttons + GLFW_GAMEPAD_BUTTON_GUIDE },
|
||||
{ "leftshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_BUMPER },
|
||||
{ "rightshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER },
|
||||
{ "leftstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_THUMB },
|
||||
{ "rightstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_THUMB },
|
||||
{ "dpup", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_UP },
|
||||
{ "dpright", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_RIGHT },
|
||||
{ "dpdown", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_DOWN },
|
||||
{ "dpleft", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_LEFT },
|
||||
{ "lefttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_TRIGGER },
|
||||
{ "righttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER },
|
||||
{ "leftx", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_X },
|
||||
{ "lefty", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_Y },
|
||||
{ "rightx", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_X },
|
||||
{ "righty", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_Y }
|
||||
};
|
||||
|
||||
length = strcspn(c, ",");
|
||||
if (length != 32 || c[length] != ',')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
memcpy(mapping->guid, c, length);
|
||||
c += length + 1;
|
||||
|
||||
length = strcspn(c, ",");
|
||||
if (length >= sizeof(mapping->name) || c[length] != ',')
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_VALUE, NULL);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
memcpy(mapping->name, c, length);
|
||||
c += length + 1;
|
||||
|
||||
while (*c)
|
||||
{
|
||||
// TODO: Implement output modifiers
|
||||
if (*c == '+' || *c == '-')
|
||||
return GLFW_FALSE;
|
||||
|
||||
for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++)
|
||||
{
|
||||
length = strlen(fields[i].name);
|
||||
if (strncmp(c, fields[i].name, length) != 0 || c[length] != ':')
|
||||
continue;
|
||||
|
||||
c += length + 1;
|
||||
|
||||
if (fields[i].element)
|
||||
{
|
||||
_GLFWmapelement* e = fields[i].element;
|
||||
int8_t minimum = -1;
|
||||
int8_t maximum = 1;
|
||||
|
||||
if (*c == '+')
|
||||
{
|
||||
minimum = 0;
|
||||
c += 1;
|
||||
}
|
||||
else if (*c == '-')
|
||||
{
|
||||
maximum = 0;
|
||||
c += 1;
|
||||
}
|
||||
|
||||
if (*c == 'a')
|
||||
e->type = _GLFW_JOYSTICK_AXIS;
|
||||
else if (*c == 'b')
|
||||
e->type = _GLFW_JOYSTICK_BUTTON;
|
||||
else if (*c == 'h')
|
||||
e->type = _GLFW_JOYSTICK_HATBIT;
|
||||
else
|
||||
break;
|
||||
|
||||
if (e->type == _GLFW_JOYSTICK_HATBIT)
|
||||
{
|
||||
const unsigned long hat = strtoul(c + 1, (char**) &c, 10);
|
||||
const unsigned long bit = strtoul(c + 1, (char**) &c, 10);
|
||||
e->index = (uint8_t) ((hat << 4) | bit);
|
||||
}
|
||||
else
|
||||
e->index = (uint8_t) strtoul(c + 1, (char**) &c, 10);
|
||||
|
||||
if (e->type == _GLFW_JOYSTICK_AXIS)
|
||||
{
|
||||
e->axisScale = 2 / (maximum - minimum);
|
||||
e->axisOffset = -(maximum + minimum);
|
||||
|
||||
if (*c == '~')
|
||||
{
|
||||
e->axisScale = -e->axisScale;
|
||||
e->axisOffset = -e->axisOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = strlen(_GLFW_PLATFORM_MAPPING_NAME);
|
||||
if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
c += strcspn(c, ",");
|
||||
c += strspn(c, ",");
|
||||
}
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (mapping->guid[i] >= 'A' && mapping->guid[i] <= 'F')
|
||||
mapping->guid[i] += 'a' - 'A';
|
||||
}
|
||||
|
||||
_glfwPlatformUpdateGamepadGUID(mapping->guid);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW event API //////
|
||||
@ -354,123 +152,11 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
|
||||
window->callbacks.drop((GLFWwindow*) window, count, paths);
|
||||
}
|
||||
|
||||
// Notifies shared code of a joystick connection or disconnection
|
||||
//
|
||||
void _glfwInputJoystick(_GLFWjoystick* js, int event)
|
||||
{
|
||||
const int jid = (int) (js - _glfw.joysticks);
|
||||
|
||||
if (event == GLFW_CONNECTED)
|
||||
js->connected = GLFW_TRUE;
|
||||
else if (event == GLFW_DISCONNECTED)
|
||||
js->connected = GLFW_FALSE;
|
||||
|
||||
if (_glfw.callbacks.joystick)
|
||||
_glfw.callbacks.joystick(jid, event);
|
||||
}
|
||||
|
||||
// Notifies shared code of the new value of a joystick axis
|
||||
//
|
||||
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
|
||||
{
|
||||
js->axes[axis] = value;
|
||||
}
|
||||
|
||||
// Notifies shared code of the new value of a joystick button
|
||||
//
|
||||
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
|
||||
{
|
||||
js->buttons[button] = value;
|
||||
}
|
||||
|
||||
// Notifies shared code of the new value of a joystick hat
|
||||
//
|
||||
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
|
||||
{
|
||||
const int base = js->buttonCount + hat * 4;
|
||||
|
||||
js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE;
|
||||
js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE;
|
||||
js->buttons[base + 2] = (value & 0x04) ? GLFW_PRESS : GLFW_RELEASE;
|
||||
js->buttons[base + 3] = (value & 0x08) ? GLFW_PRESS : GLFW_RELEASE;
|
||||
|
||||
js->hats[hat] = value;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Adds the built-in set of gamepad mappings
|
||||
//
|
||||
void _glfwInitGamepadMappings(void)
|
||||
{
|
||||
int jid;
|
||||
size_t i;
|
||||
const size_t count = sizeof(_glfwDefaultMappings) / sizeof(char*);
|
||||
_glfw.mappings = calloc(count, sizeof(_GLFWmapping));
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (parseMapping(&_glfw.mappings[_glfw.mappingCount], _glfwDefaultMappings[i]))
|
||||
_glfw.mappingCount++;
|
||||
}
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->connected)
|
||||
js->mapping = findValidMapping(js);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns an available joystick object with arrays and name allocated
|
||||
//
|
||||
_GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
const char* guid,
|
||||
int axisCount,
|
||||
int buttonCount,
|
||||
int hatCount)
|
||||
{
|
||||
int jid;
|
||||
_GLFWjoystick* js;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (!_glfw.joysticks[jid].allocated)
|
||||
break;
|
||||
}
|
||||
|
||||
if (jid > GLFW_JOYSTICK_LAST)
|
||||
return NULL;
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
js->allocated = GLFW_TRUE;
|
||||
js->axes = calloc(axisCount, sizeof(float));
|
||||
js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
|
||||
js->hats = calloc(hatCount, 1);
|
||||
js->axisCount = axisCount;
|
||||
js->buttonCount = buttonCount;
|
||||
js->hatCount = hatCount;
|
||||
|
||||
strncpy(js->name, name, sizeof(js->name) - 1);
|
||||
strncpy(js->guid, guid, sizeof(js->guid) - 1);
|
||||
js->mapping = findValidMapping(js);
|
||||
|
||||
return js;
|
||||
}
|
||||
|
||||
// Frees arrays and name and flags the joystick object as unused
|
||||
//
|
||||
void _glfwFreeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
free(js->axes);
|
||||
free(js->buttons);
|
||||
free(js->hats);
|
||||
memset(js, 0, sizeof(_GLFWjoystick));
|
||||
}
|
||||
|
||||
// Center the cursor in the content area of the specified window
|
||||
//
|
||||
void _glfwCenterCursorInContentArea(_GLFWwindow* window)
|
||||
@ -933,404 +619,6 @@ GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwJoystickPresent(int jid)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return GLFW_FALSE;
|
||||
|
||||
return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
|
||||
}
|
||||
|
||||
GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
assert(count != NULL);
|
||||
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES))
|
||||
return NULL;
|
||||
|
||||
*count = js->axisCount;
|
||||
return js->axes;
|
||||
}
|
||||
|
||||
GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
assert(count != NULL);
|
||||
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
|
||||
return NULL;
|
||||
|
||||
if (_glfw.hints.init.hatButtons)
|
||||
*count = js->buttonCount + js->hatCount * 4;
|
||||
else
|
||||
*count = js->buttonCount;
|
||||
|
||||
return js->buttons;
|
||||
}
|
||||
|
||||
GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
assert(count != NULL);
|
||||
|
||||
*count = 0;
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
|
||||
return NULL;
|
||||
|
||||
*count = js->hatCount;
|
||||
return js->hats;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetJoystickName(int jid)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
return NULL;
|
||||
|
||||
return js->name;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetJoystickGUID(int jid)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
return NULL;
|
||||
|
||||
return js->guid;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT();
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->allocated)
|
||||
return;
|
||||
|
||||
js->userPointer = pointer;
|
||||
}
|
||||
|
||||
GLFWAPI void* glfwGetJoystickUserPointer(int jid)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->allocated)
|
||||
return NULL;
|
||||
|
||||
return js->userPointer;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwUpdateGamepadMappings(const char* string)
|
||||
{
|
||||
int jid;
|
||||
const char* c = string;
|
||||
|
||||
assert(string != NULL);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
while (*c)
|
||||
{
|
||||
if ((*c >= '0' && *c <= '9') ||
|
||||
(*c >= 'a' && *c <= 'f') ||
|
||||
(*c >= 'A' && *c <= 'F'))
|
||||
{
|
||||
char line[1024];
|
||||
|
||||
const size_t length = strcspn(c, "\r\n");
|
||||
if (length < sizeof(line))
|
||||
{
|
||||
_GLFWmapping mapping = {{0}};
|
||||
|
||||
memcpy(line, c, length);
|
||||
line[length] = '\0';
|
||||
|
||||
if (parseMapping(&mapping, line))
|
||||
{
|
||||
_GLFWmapping* previous = findMapping(mapping.guid);
|
||||
if (previous)
|
||||
*previous = mapping;
|
||||
else
|
||||
{
|
||||
_glfw.mappingCount++;
|
||||
_glfw.mappings =
|
||||
realloc(_glfw.mappings,
|
||||
sizeof(_GLFWmapping) * _glfw.mappingCount);
|
||||
_glfw.mappings[_glfw.mappingCount - 1] = mapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
c += strcspn(c, "\r\n");
|
||||
c += strspn(c, "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->connected)
|
||||
js->mapping = findValidMapping(js);
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwJoystickIsGamepad(int jid)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
return GLFW_FALSE;
|
||||
|
||||
return js->mapping != NULL;
|
||||
}
|
||||
|
||||
GLFWAPI const char* glfwGetGamepadName(int jid)
|
||||
{
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return NULL;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
|
||||
return NULL;
|
||||
|
||||
if (!js->mapping)
|
||||
return NULL;
|
||||
|
||||
return js->mapping->name;
|
||||
}
|
||||
|
||||
GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
|
||||
{
|
||||
int i;
|
||||
_GLFWjoystick* js;
|
||||
|
||||
assert(jid >= GLFW_JOYSTICK_1);
|
||||
assert(jid <= GLFW_JOYSTICK_LAST);
|
||||
assert(state != NULL);
|
||||
|
||||
memset(state, 0, sizeof(GLFWgamepadstate));
|
||||
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
|
||||
|
||||
if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
|
||||
{
|
||||
_glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
js = _glfw.joysticks + jid;
|
||||
if (!js->connected)
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
|
||||
return GLFW_FALSE;
|
||||
|
||||
if (!js->mapping)
|
||||
return GLFW_FALSE;
|
||||
|
||||
for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
|
||||
{
|
||||
const _GLFWmapelement* e = js->mapping->buttons + i;
|
||||
if (e->type == _GLFW_JOYSTICK_AXIS)
|
||||
{
|
||||
const float value = js->axes[e->index] * e->axisScale + e->axisOffset;
|
||||
// HACK: This should be baked into the value transform
|
||||
// TODO: Bake into transform when implementing output modifiers
|
||||
if (e->axisOffset < 0 || (e->axisOffset == 0 && e->axisScale > 0))
|
||||
{
|
||||
if (value >= 0.f)
|
||||
state->buttons[i] = GLFW_PRESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value <= 0.f)
|
||||
state->buttons[i] = GLFW_PRESS;
|
||||
}
|
||||
}
|
||||
else if (e->type == _GLFW_JOYSTICK_HATBIT)
|
||||
{
|
||||
const unsigned int hat = e->index >> 4;
|
||||
const unsigned int bit = e->index & 0xf;
|
||||
if (js->hats[hat] & bit)
|
||||
state->buttons[i] = GLFW_PRESS;
|
||||
}
|
||||
else if (e->type == _GLFW_JOYSTICK_BUTTON)
|
||||
state->buttons[i] = js->buttons[e->index];
|
||||
}
|
||||
|
||||
for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
|
||||
{
|
||||
const _GLFWmapelement* e = js->mapping->axes + i;
|
||||
if (e->type == _GLFW_JOYSTICK_AXIS)
|
||||
{
|
||||
const float value = js->axes[e->index] * e->axisScale + e->axisOffset;
|
||||
state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f);
|
||||
}
|
||||
else if (e->type == _GLFW_JOYSTICK_HATBIT)
|
||||
{
|
||||
const unsigned int hat = e->index >> 4;
|
||||
const unsigned int bit = e->index & 0xf;
|
||||
if (js->hats[hat] & bit)
|
||||
state->axes[i] = 1.f;
|
||||
else
|
||||
state->axes[i] = -1.f;
|
||||
}
|
||||
else if (e->type == _GLFW_JOYSTICK_BUTTON)
|
||||
state->axes[i] = js->buttons[e->index] * 2.f - 1.f;
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
{
|
||||
assert(string != NULL);
|
||||
|
@ -71,8 +71,6 @@ typedef struct _GLFWlibrary _GLFWlibrary;
|
||||
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||
typedef struct _GLFWcursor _GLFWcursor;
|
||||
typedef struct _GLFWmapelement _GLFWmapelement;
|
||||
typedef struct _GLFWmapping _GLFWmapping;
|
||||
typedef struct _GLFWjoystick _GLFWjoystick;
|
||||
typedef struct _GLFWtls _GLFWtls;
|
||||
typedef struct _GLFWmutex _GLFWmutex;
|
||||
|
||||
@ -237,7 +235,6 @@ struct _GLFWerror
|
||||
//
|
||||
struct _GLFWinitconfig
|
||||
{
|
||||
GLFWbool hatButtons;
|
||||
struct {
|
||||
GLFWbool menubar;
|
||||
GLFWbool chdir;
|
||||
@ -452,47 +449,6 @@ struct _GLFWcursor
|
||||
_GLFW_PLATFORM_CURSOR_STATE;
|
||||
};
|
||||
|
||||
// Gamepad mapping element structure
|
||||
//
|
||||
struct _GLFWmapelement
|
||||
{
|
||||
uint8_t type;
|
||||
uint8_t index;
|
||||
int8_t axisScale;
|
||||
int8_t axisOffset;
|
||||
};
|
||||
|
||||
// Gamepad mapping structure
|
||||
//
|
||||
struct _GLFWmapping
|
||||
{
|
||||
char name[128];
|
||||
char guid[33];
|
||||
_GLFWmapelement buttons[15];
|
||||
_GLFWmapelement axes[6];
|
||||
};
|
||||
|
||||
// Joystick structure
|
||||
//
|
||||
struct _GLFWjoystick
|
||||
{
|
||||
GLFWbool allocated;
|
||||
GLFWbool connected;
|
||||
float* axes;
|
||||
int axisCount;
|
||||
unsigned char* buttons;
|
||||
int buttonCount;
|
||||
unsigned char* hats;
|
||||
int hatCount;
|
||||
char name[128];
|
||||
void* userPointer;
|
||||
char guid[33];
|
||||
_GLFWmapping* mapping;
|
||||
|
||||
// This is defined in the joystick API's joystick.h
|
||||
_GLFW_PLATFORM_JOYSTICK_STATE;
|
||||
};
|
||||
|
||||
// Thread local storage structure
|
||||
//
|
||||
struct _GLFWtls
|
||||
@ -530,10 +486,6 @@ struct _GLFWlibrary
|
||||
_GLFWmonitor** monitors;
|
||||
int monitorCount;
|
||||
|
||||
_GLFWjoystick joysticks[GLFW_JOYSTICK_LAST + 1];
|
||||
_GLFWmapping* mappings;
|
||||
int mappingCount;
|
||||
|
||||
_GLFWtls errorSlot;
|
||||
_GLFWtls contextSlot;
|
||||
_GLFWmutex errorLock;
|
||||
@ -566,15 +518,12 @@ struct _GLFWlibrary
|
||||
|
||||
struct {
|
||||
GLFWmonitorfun monitor;
|
||||
GLFWjoystickfun joystick;
|
||||
} callbacks;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
|
||||
// This is defined in the context API's context.h
|
||||
_GLFW_PLATFORM_LIBRARY_CONTEXT_STATE;
|
||||
// This is defined in the platform's joystick.h
|
||||
_GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE;
|
||||
// This is defined in egl_context.h
|
||||
_GLFW_EGL_LIBRARY_CONTEXT_STATE;
|
||||
// This is defined in osmesa_context.h
|
||||
@ -621,9 +570,6 @@ void _glfwPlatformSetGammaRamp(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
|
||||
void _glfwPlatformSetClipboardString(const char* string);
|
||||
const char* _glfwPlatformGetClipboardString(void);
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode);
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid);
|
||||
|
||||
uint64_t _glfwPlatformGetTimerValue(void);
|
||||
uint64_t _glfwPlatformGetTimerFrequency(void);
|
||||
|
||||
@ -721,10 +667,6 @@ void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
|
||||
void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos);
|
||||
void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered);
|
||||
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
||||
void _glfwInputJoystick(_GLFWjoystick* js, int event);
|
||||
void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value);
|
||||
void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value);
|
||||
void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value);
|
||||
|
||||
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement);
|
||||
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window);
|
||||
@ -758,13 +700,6 @@ void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size);
|
||||
void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
|
||||
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
|
||||
|
||||
void _glfwInitGamepadMappings(void);
|
||||
_GLFWjoystick* _glfwAllocJoystick(const char* name,
|
||||
const char* guid,
|
||||
int axisCount,
|
||||
int buttonCount,
|
||||
int hatCount);
|
||||
void _glfwFreeJoystick(_GLFWjoystick* js);
|
||||
void _glfwCenterCursorInContentArea(_GLFWwindow* window);
|
||||
|
||||
GLFWbool _glfwInitVulkan(int mode);
|
||||
|
@ -1,433 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Linux - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.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.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef SYN_DROPPED // < v2.6.39 kernel headers
|
||||
// Workaround for CentOS-6, which is supported till 2020-11-30, but still on v2.6.32
|
||||
#define SYN_DROPPED 3
|
||||
#endif
|
||||
|
||||
// Apply an EV_KEY event to the specified joystick
|
||||
//
|
||||
static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
|
||||
{
|
||||
_glfwInputJoystickButton(js,
|
||||
js->linjs.keyMap[code - BTN_MISC],
|
||||
value ? GLFW_PRESS : GLFW_RELEASE);
|
||||
}
|
||||
|
||||
// Apply an EV_ABS event to the specified joystick
|
||||
//
|
||||
static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
|
||||
{
|
||||
const int index = js->linjs.absMap[code];
|
||||
|
||||
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
|
||||
{
|
||||
static const char stateMap[3][3] =
|
||||
{
|
||||
{ GLFW_HAT_CENTERED, GLFW_HAT_UP, GLFW_HAT_DOWN },
|
||||
{ GLFW_HAT_LEFT, GLFW_HAT_LEFT_UP, GLFW_HAT_LEFT_DOWN },
|
||||
{ GLFW_HAT_RIGHT, GLFW_HAT_RIGHT_UP, GLFW_HAT_RIGHT_DOWN },
|
||||
};
|
||||
|
||||
const int hat = (code - ABS_HAT0X) / 2;
|
||||
const int axis = (code - ABS_HAT0X) % 2;
|
||||
int* state = js->linjs.hats[hat];
|
||||
|
||||
// NOTE: Looking at several input drivers, it seems all hat events use
|
||||
// -1 for left / up, 0 for centered and 1 for right / down
|
||||
if (value == 0)
|
||||
state[axis] = 0;
|
||||
else if (value < 0)
|
||||
state[axis] = 1;
|
||||
else if (value > 0)
|
||||
state[axis] = 2;
|
||||
|
||||
_glfwInputJoystickHat(js, index, stateMap[state[0]][state[1]]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const struct input_absinfo* info = &js->linjs.absInfo[code];
|
||||
float normalized = value;
|
||||
|
||||
const int range = info->maximum - info->minimum;
|
||||
if (range)
|
||||
{
|
||||
// Normalize to 0.0 -> 1.0
|
||||
normalized = (normalized - info->minimum) / range;
|
||||
// Normalize to -1.0 -> 1.0
|
||||
normalized = normalized * 2.0f - 1.0f;
|
||||
}
|
||||
|
||||
_glfwInputJoystickAxis(js, index, normalized);
|
||||
}
|
||||
}
|
||||
|
||||
// Poll state of absolute axes
|
||||
//
|
||||
static void pollAbsState(_GLFWjoystick* js)
|
||||
{
|
||||
for (int code = 0; code < ABS_CNT; code++)
|
||||
{
|
||||
if (js->linjs.absMap[code] < 0)
|
||||
continue;
|
||||
|
||||
struct input_absinfo* info = &js->linjs.absInfo[code];
|
||||
|
||||
if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0)
|
||||
continue;
|
||||
|
||||
handleAbsEvent(js, code, info->value);
|
||||
}
|
||||
}
|
||||
|
||||
#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
|
||||
|
||||
// Attempt to open the specified joystick device
|
||||
//
|
||||
static GLFWbool openJoystickDevice(const char* path)
|
||||
{
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (!_glfw.joysticks[jid].connected)
|
||||
continue;
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
_GLFWjoystickLinux linjs = {0};
|
||||
linjs.fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||
if (linjs.fd == -1)
|
||||
return GLFW_FALSE;
|
||||
|
||||
char evBits[(EV_CNT + 7) / 8] = {0};
|
||||
char keyBits[(KEY_CNT + 7) / 8] = {0};
|
||||
char absBits[(ABS_CNT + 7) / 8] = {0};
|
||||
struct input_id id;
|
||||
|
||||
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
|
||||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Linux: Failed to query input device: %s",
|
||||
strerror(errno));
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
// Ensure this device supports the events expected of a joystick
|
||||
if (!isBitSet(EV_KEY, evBits) || !isBitSet(EV_ABS, evBits))
|
||||
{
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
char name[256] = "";
|
||||
|
||||
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
|
||||
strncpy(name, "Unknown", sizeof(name));
|
||||
|
||||
char guid[33] = "";
|
||||
|
||||
// Generate a joystick GUID that matches the SDL 2.0.5+ one
|
||||
if (id.vendor && id.product && id.version)
|
||||
{
|
||||
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
|
||||
id.bustype & 0xff, id.bustype >> 8,
|
||||
id.vendor & 0xff, id.vendor >> 8,
|
||||
id.product & 0xff, id.product >> 8,
|
||||
id.version & 0xff, id.version >> 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
|
||||
id.bustype & 0xff, id.bustype >> 8,
|
||||
name[0], name[1], name[2], name[3],
|
||||
name[4], name[5], name[6], name[7],
|
||||
name[8], name[9], name[10]);
|
||||
}
|
||||
|
||||
int axisCount = 0, buttonCount = 0, hatCount = 0;
|
||||
|
||||
for (int code = BTN_MISC; code < KEY_CNT; code++)
|
||||
{
|
||||
if (!isBitSet(code, keyBits))
|
||||
continue;
|
||||
|
||||
linjs.keyMap[code - BTN_MISC] = buttonCount;
|
||||
buttonCount++;
|
||||
}
|
||||
|
||||
for (int code = 0; code < ABS_CNT; code++)
|
||||
{
|
||||
linjs.absMap[code] = -1;
|
||||
if (!isBitSet(code, absBits))
|
||||
continue;
|
||||
|
||||
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
|
||||
{
|
||||
linjs.absMap[code] = hatCount;
|
||||
hatCount++;
|
||||
// Skip the Y axis
|
||||
code++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0)
|
||||
continue;
|
||||
|
||||
linjs.absMap[code] = axisCount;
|
||||
axisCount++;
|
||||
}
|
||||
}
|
||||
|
||||
_GLFWjoystick* js =
|
||||
_glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
|
||||
if (!js)
|
||||
{
|
||||
close(linjs.fd);
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
|
||||
memcpy(&js->linjs, &linjs, sizeof(linjs));
|
||||
|
||||
pollAbsState(js);
|
||||
|
||||
_glfwInputJoystick(js, GLFW_CONNECTED);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
#undef isBitSet
|
||||
|
||||
// Frees all resources associated with the specified joystick
|
||||
//
|
||||
static void closeJoystick(_GLFWjoystick* js)
|
||||
{
|
||||
_glfwInputJoystick(js, GLFW_DISCONNECTED);
|
||||
close(js->linjs.fd);
|
||||
_glfwFreeJoystick(js);
|
||||
}
|
||||
|
||||
// Lexically compare joysticks by name; used by qsort
|
||||
//
|
||||
static int compareJoysticks(const void* fp, const void* sp)
|
||||
{
|
||||
const _GLFWjoystick* fj = fp;
|
||||
const _GLFWjoystick* sj = sp;
|
||||
return strcmp(fj->linjs.path, sj->linjs.path);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Initialize joystick interface
|
||||
//
|
||||
GLFWbool _glfwInitJoysticksLinux(void)
|
||||
{
|
||||
const char* dirname = "/dev/input";
|
||||
|
||||
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
{
|
||||
// HACK: Register for IN_ATTRIB to get notified when udev is done
|
||||
// This works well in practice but the true way is libudev
|
||||
|
||||
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
|
||||
dirname,
|
||||
IN_CREATE | IN_ATTRIB | IN_DELETE);
|
||||
}
|
||||
|
||||
// Continue without device connection notifications if inotify fails
|
||||
|
||||
if (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) != 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
|
||||
DIR* dir = opendir(dirname);
|
||||
if (dir)
|
||||
{
|
||||
struct dirent* entry;
|
||||
|
||||
while ((entry = readdir(dir)))
|
||||
{
|
||||
regmatch_t match;
|
||||
|
||||
if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0)
|
||||
continue;
|
||||
|
||||
char path[PATH_MAX];
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
|
||||
|
||||
if (openJoystickDevice(path))
|
||||
count++;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
// Continue with no joysticks if enumeration fails
|
||||
|
||||
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Close all opened joystick handles
|
||||
//
|
||||
void _glfwTerminateJoysticksLinux(void)
|
||||
{
|
||||
int jid;
|
||||
|
||||
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
_GLFWjoystick* js = _glfw.joysticks + jid;
|
||||
if (js->connected)
|
||||
closeJoystick(js);
|
||||
}
|
||||
|
||||
regfree(&_glfw.linjs.regex);
|
||||
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
{
|
||||
if (_glfw.linjs.watch > 0)
|
||||
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
|
||||
|
||||
close(_glfw.linjs.inotify);
|
||||
}
|
||||
}
|
||||
|
||||
void _glfwDetectJoystickConnectionLinux(void)
|
||||
{
|
||||
if (_glfw.linjs.inotify <= 0)
|
||||
return;
|
||||
|
||||
ssize_t offset = 0;
|
||||
char buffer[16384];
|
||||
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
|
||||
|
||||
while (size > offset)
|
||||
{
|
||||
regmatch_t match;
|
||||
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
|
||||
|
||||
offset += sizeof(struct inotify_event) + e->len;
|
||||
|
||||
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
|
||||
continue;
|
||||
|
||||
char path[PATH_MAX];
|
||||
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
|
||||
|
||||
if (e->mask & (IN_CREATE | IN_ATTRIB))
|
||||
openJoystickDevice(path);
|
||||
else if (e->mask & IN_DELETE)
|
||||
{
|
||||
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
|
||||
{
|
||||
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
|
||||
{
|
||||
closeJoystick(_glfw.joysticks + jid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
// Read all queued events (non-blocking)
|
||||
for (;;)
|
||||
{
|
||||
struct input_event e;
|
||||
|
||||
errno = 0;
|
||||
if (read(js->linjs.fd, &e, sizeof(e)) < 0)
|
||||
{
|
||||
// Reset the joystick slot if the device was disconnected
|
||||
if (errno == ENODEV)
|
||||
closeJoystick(js);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.type == EV_SYN)
|
||||
{
|
||||
if (e.code == SYN_DROPPED)
|
||||
_glfw.linjs.dropped = GLFW_TRUE;
|
||||
else if (e.code == SYN_REPORT)
|
||||
{
|
||||
_glfw.linjs.dropped = GLFW_FALSE;
|
||||
pollAbsState(js);
|
||||
}
|
||||
}
|
||||
|
||||
if (_glfw.linjs.dropped)
|
||||
continue;
|
||||
|
||||
if (e.type == EV_KEY)
|
||||
handleKeyEvent(js, e.code, e.value);
|
||||
else if (e.type == EV_ABS)
|
||||
handleAbsEvent(js, e.code, e.value);
|
||||
}
|
||||
|
||||
return js->connected;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
{
|
||||
}
|
||||
|
@ -1,63 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 Linux - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
|
||||
//
|
||||
// This software is provided 'as-is', without any express or implied
|
||||
// warranty. In no event will the authors be held liable for any damages
|
||||
// arising from the use of this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. The origin of this software must not be misrepresented; you must not
|
||||
// claim that you wrote the original software. If you use this software
|
||||
// in a product, an acknowledgment in the product documentation would
|
||||
// be appreciated but is not required.
|
||||
//
|
||||
// 2. Altered source versions must be plainly marked as such, and must not
|
||||
// be misrepresented as being the original software.
|
||||
//
|
||||
// 3. This notice may not be removed or altered from any source
|
||||
// distribution.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/limits.h>
|
||||
#include <regex.h>
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME "Linux"
|
||||
#define GLFW_BUILD_LINUX_MAPPINGS
|
||||
|
||||
// Linux-specific joystick data
|
||||
//
|
||||
typedef struct _GLFWjoystickLinux
|
||||
{
|
||||
int fd;
|
||||
char path[PATH_MAX];
|
||||
int keyMap[KEY_CNT - BTN_MISC];
|
||||
int absMap[ABS_CNT];
|
||||
struct input_absinfo absInfo[ABS_CNT];
|
||||
int hats[4][2];
|
||||
} _GLFWjoystickLinux;
|
||||
|
||||
// Linux-specific joystick API data
|
||||
//
|
||||
typedef struct _GLFWlibraryLinux
|
||||
{
|
||||
int inotify;
|
||||
int watch;
|
||||
regex_t regex;
|
||||
GLFWbool dropped;
|
||||
} _GLFWlibraryLinux;
|
||||
|
||||
|
||||
GLFWbool _glfwInitJoysticksLinux(void);
|
||||
void _glfwTerminateJoysticksLinux(void);
|
||||
void _glfwDetectJoystickConnectionLinux(void);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,44 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.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.
|
||||
//
|
||||
//========================================================================
|
||||
// It is fine to use C99 in this file because it will not be built with VS
|
||||
//========================================================================
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW platform API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode)
|
||||
{
|
||||
return GLFW_FALSE;
|
||||
}
|
||||
|
||||
void _glfwPlatformUpdateGamepadGUID(char* guid)
|
||||
{
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
//========================================================================
|
||||
// GLFW 3.3 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.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.
|
||||
//
|
||||
//========================================================================
|
||||
|
||||
#define _GLFW_PLATFORM_JOYSTICK_STATE struct { int dummyJoystick; }
|
||||
#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE struct { int dummyLibraryJoystick; }
|
||||
|
||||
#define _GLFW_PLATFORM_MAPPING_NAME ""
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "osmesa_context.h"
|
||||
#include "posix_time.h"
|
||||
#include "posix_thread.h"
|
||||
#include "null_joystick.h"
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
|
@ -426,11 +426,6 @@ int _glfwPlatformInit(void)
|
||||
// Sync so we got all initial output events
|
||||
wl_display_roundtrip(_glfw.wl.display);
|
||||
|
||||
#ifdef __linux__
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
#ifdef WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION
|
||||
@ -486,9 +481,6 @@ int _glfwPlatformInit(void)
|
||||
|
||||
void _glfwPlatformTerminate(void)
|
||||
{
|
||||
#ifdef __linux__
|
||||
_glfwTerminateJoysticksLinux();
|
||||
#endif
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateOSMesa();
|
||||
|
||||
|
@ -45,11 +45,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR
|
||||
|
||||
#include "posix_thread.h"
|
||||
#include "posix_time.h"
|
||||
#ifdef __linux__
|
||||
#include "linux_joystick.h"
|
||||
#else
|
||||
#include "null_joystick.h"
|
||||
#endif
|
||||
#include "xkb_unicode.h"
|
||||
#include "egl_context.h"
|
||||
#include "osmesa_context.h"
|
||||
|
@ -1150,11 +1150,6 @@ int _glfwPlatformInit(void)
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
if (!_glfwInitJoysticksLinux())
|
||||
return GLFW_FALSE;
|
||||
#endif
|
||||
|
||||
_glfwInitTimerPOSIX();
|
||||
|
||||
_glfwPollMonitorsX11();
|
||||
@ -1244,10 +1239,6 @@ void _glfwPlatformTerminate(void)
|
||||
_glfwTerminateEGL();
|
||||
_glfwTerminateGLX();
|
||||
|
||||
#if defined(__linux__)
|
||||
_glfwTerminateJoysticksLinux();
|
||||
#endif
|
||||
|
||||
if (_glfw.x11.emptyEventPipe[0] || _glfw.x11.emptyEventPipe[1])
|
||||
{
|
||||
close(_glfw.x11.emptyEventPipe[0]);
|
||||
|
@ -155,11 +155,6 @@ typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceXcbPresentationSupportKHR)(Vk
|
||||
#include "glx_context.h"
|
||||
#include "egl_context.h"
|
||||
#include "osmesa_context.h"
|
||||
#if defined(__linux__)
|
||||
#include "linux_joystick.h"
|
||||
#else
|
||||
#include "null_joystick.h"
|
||||
#endif
|
||||
|
||||
#define _glfw_dlopen(name) dlopen(name, RTLD_LAZY | RTLD_LOCAL)
|
||||
#define _glfw_dlclose(handle) dlclose(handle)
|
||||
|
@ -137,11 +137,6 @@ static GLFWbool waitForAnyEvent(double* timeout)
|
||||
{ _glfw.x11.emptyEventPipe[0], POLLIN }
|
||||
};
|
||||
|
||||
#if defined(__linux__)
|
||||
if (_glfw.linjs.inotify > 0)
|
||||
fds[count++] = (struct pollfd) { _glfw.linjs.inotify, POLLIN };
|
||||
#endif
|
||||
|
||||
while (!XPending(_glfw.x11.display))
|
||||
{
|
||||
if (!waitForData(fds, count, timeout))
|
||||
@ -2774,9 +2769,6 @@ void _glfwPlatformPollEvents(void)
|
||||
{
|
||||
drainEmptyEvents();
|
||||
|
||||
#if defined(__linux__)
|
||||
_glfwDetectJoystickConnectionLinux();
|
||||
#endif
|
||||
XPending(_glfw.x11.display);
|
||||
|
||||
while (XQLength(_glfw.x11.display))
|
||||
|
@ -1,9 +1,5 @@
|
||||
#include "_cgo_export.h"
|
||||
|
||||
void glfwSetJoystickCallbackCB() {
|
||||
glfwSetJoystickCallback((GLFWjoystickfun)goJoystickCB);
|
||||
}
|
||||
|
||||
void glfwSetKeyCallbackCB(GLFWwindow *window) {
|
||||
glfwSetKeyCallback(window, (GLFWkeyfun)goKeyCB);
|
||||
}
|
||||
@ -35,15 +31,3 @@ void glfwSetScrollCallbackCB(GLFWwindow *window) {
|
||||
void glfwSetDropCallbackCB(GLFWwindow *window) {
|
||||
glfwSetDropCallback(window, (GLFWdropfun)goDropCB);
|
||||
}
|
||||
|
||||
float GetAxisAtIndex(float *axis, int i) { return axis[i]; }
|
||||
|
||||
unsigned char GetButtonsAtIndex(unsigned char *buttons, int i) {
|
||||
return buttons[i];
|
||||
}
|
||||
|
||||
unsigned char GetGamepadButtonAtIndex(GLFWgamepadstate *gp, int i) {
|
||||
return gp->buttons[i];
|
||||
}
|
||||
|
||||
float GetGamepadAxisAtIndex(GLFWgamepadstate *gp, int i) { return gp->axes[i]; }
|
||||
|
@ -5,7 +5,6 @@ package glfw
|
||||
//#include <stdlib.h>
|
||||
//#define GLFW_INCLUDE_NONE
|
||||
//#include "glfw/include/GLFW/glfw3.h"
|
||||
//void glfwSetJoystickCallbackCB();
|
||||
//void glfwSetKeyCallbackCB(GLFWwindow *window);
|
||||
//void glfwSetCharCallbackCB(GLFWwindow *window);
|
||||
//void glfwSetCharModsCallbackCB(GLFWwindow *window);
|
||||
@ -14,10 +13,6 @@ package glfw
|
||||
//void glfwSetCursorEnterCallbackCB(GLFWwindow *window);
|
||||
//void glfwSetScrollCallbackCB(GLFWwindow *window);
|
||||
//void glfwSetDropCallbackCB(GLFWwindow *window);
|
||||
//float GetAxisAtIndex(float *axis, int i);
|
||||
//unsigned char GetButtonsAtIndex(unsigned char *buttons, int i);
|
||||
//float GetGamepadAxisAtIndex(GLFWgamepadstate *gp, int i);
|
||||
//unsigned char GetGamepadButtonAtIndex(GLFWgamepadstate *gp, int i);
|
||||
import "C"
|
||||
|
||||
import (
|
||||
@ -26,93 +21,6 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Joystick corresponds to a joystick.
|
||||
type Joystick int
|
||||
|
||||
// Joystick IDs.
|
||||
const (
|
||||
Joystick1 Joystick = C.GLFW_JOYSTICK_1
|
||||
Joystick2 Joystick = C.GLFW_JOYSTICK_2
|
||||
Joystick3 Joystick = C.GLFW_JOYSTICK_3
|
||||
Joystick4 Joystick = C.GLFW_JOYSTICK_4
|
||||
Joystick5 Joystick = C.GLFW_JOYSTICK_5
|
||||
Joystick6 Joystick = C.GLFW_JOYSTICK_6
|
||||
Joystick7 Joystick = C.GLFW_JOYSTICK_7
|
||||
Joystick8 Joystick = C.GLFW_JOYSTICK_8
|
||||
Joystick9 Joystick = C.GLFW_JOYSTICK_9
|
||||
Joystick10 Joystick = C.GLFW_JOYSTICK_10
|
||||
Joystick11 Joystick = C.GLFW_JOYSTICK_11
|
||||
Joystick12 Joystick = C.GLFW_JOYSTICK_12
|
||||
Joystick13 Joystick = C.GLFW_JOYSTICK_13
|
||||
Joystick14 Joystick = C.GLFW_JOYSTICK_14
|
||||
Joystick15 Joystick = C.GLFW_JOYSTICK_15
|
||||
Joystick16 Joystick = C.GLFW_JOYSTICK_16
|
||||
JoystickLast Joystick = C.GLFW_JOYSTICK_LAST
|
||||
)
|
||||
|
||||
// JoystickHatState corresponds to joystick hat states.
|
||||
type JoystickHatState int
|
||||
|
||||
// Joystick Hat State IDs.
|
||||
const (
|
||||
HatCentered JoystickHatState = C.GLFW_HAT_CENTERED
|
||||
HatUp JoystickHatState = C.GLFW_HAT_UP
|
||||
HatRight JoystickHatState = C.GLFW_HAT_RIGHT
|
||||
HatDown JoystickHatState = C.GLFW_HAT_DOWN
|
||||
HatLeft JoystickHatState = C.GLFW_HAT_LEFT
|
||||
HatRightUp JoystickHatState = C.GLFW_HAT_RIGHT_UP
|
||||
HatRightDown JoystickHatState = C.GLFW_HAT_RIGHT_DOWN
|
||||
HatLeftUp JoystickHatState = C.GLFW_HAT_LEFT_UP
|
||||
HatLeftDown JoystickHatState = C.GLFW_HAT_LEFT_DOWN
|
||||
)
|
||||
|
||||
// GamepadAxis corresponds to a gamepad axis.
|
||||
type GamepadAxis int
|
||||
|
||||
// Gamepad axis IDs.
|
||||
const (
|
||||
AxisLeftX GamepadAxis = C.GLFW_GAMEPAD_AXIS_LEFT_X
|
||||
AxisLeftY GamepadAxis = C.GLFW_GAMEPAD_AXIS_LEFT_Y
|
||||
AxisRightX GamepadAxis = C.GLFW_GAMEPAD_AXIS_RIGHT_X
|
||||
AxisRightY GamepadAxis = C.GLFW_GAMEPAD_AXIS_RIGHT_Y
|
||||
AxisLeftTrigger GamepadAxis = C.GLFW_GAMEPAD_AXIS_LEFT_TRIGGER
|
||||
AxisRightTrigger GamepadAxis = C.GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER
|
||||
AxisLast GamepadAxis = C.GLFW_GAMEPAD_AXIS_LAST
|
||||
)
|
||||
|
||||
// GamepadButton corresponds to a gamepad button.
|
||||
type GamepadButton int
|
||||
|
||||
// Gamepad button IDs.
|
||||
const (
|
||||
ButtonA GamepadButton = C.GLFW_GAMEPAD_BUTTON_A
|
||||
ButtonB GamepadButton = C.GLFW_GAMEPAD_BUTTON_B
|
||||
ButtonX GamepadButton = C.GLFW_GAMEPAD_BUTTON_X
|
||||
ButtonY GamepadButton = C.GLFW_GAMEPAD_BUTTON_Y
|
||||
ButtonLeftBumper GamepadButton = C.GLFW_GAMEPAD_BUTTON_LEFT_BUMPER
|
||||
ButtonRightBumper GamepadButton = C.GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER
|
||||
ButtonBack GamepadButton = C.GLFW_GAMEPAD_BUTTON_BACK
|
||||
ButtonStart GamepadButton = C.GLFW_GAMEPAD_BUTTON_START
|
||||
ButtonGuide GamepadButton = C.GLFW_GAMEPAD_BUTTON_GUIDE
|
||||
ButtonLeftThumb GamepadButton = C.GLFW_GAMEPAD_BUTTON_LEFT_THUMB
|
||||
ButtonRightThumb GamepadButton = C.GLFW_GAMEPAD_BUTTON_RIGHT_THUMB
|
||||
ButtonDpadUp GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_UP
|
||||
ButtonDpadRight GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_RIGHT
|
||||
ButtonDpadDown GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_DOWN
|
||||
ButtonDpadLeft GamepadButton = C.GLFW_GAMEPAD_BUTTON_DPAD_LEFT
|
||||
ButtonLast GamepadButton = C.GLFW_GAMEPAD_BUTTON_LAST
|
||||
ButtonCross GamepadButton = C.GLFW_GAMEPAD_BUTTON_CROSS
|
||||
ButtonCircle GamepadButton = C.GLFW_GAMEPAD_BUTTON_CIRCLE
|
||||
ButtonSquare GamepadButton = C.GLFW_GAMEPAD_BUTTON_SQUARE
|
||||
ButtonTriangle GamepadButton = C.GLFW_GAMEPAD_BUTTON_TRIANGLE
|
||||
)
|
||||
|
||||
// GamepadState describes the input state of a gamepad.
|
||||
type GamepadState struct {
|
||||
Buttons [15]Action
|
||||
Axes [6]float32
|
||||
}
|
||||
|
||||
// Key corresponds to a keyboard key.
|
||||
type Key int
|
||||
|
||||
@ -323,13 +231,6 @@ type Cursor struct {
|
||||
data *C.GLFWcursor
|
||||
}
|
||||
|
||||
var fJoystickHolder func(joy Joystick, event PeripheralEvent)
|
||||
|
||||
//export goJoystickCB
|
||||
func goJoystickCB(joy, event C.int) {
|
||||
fJoystickHolder(Joystick(joy), PeripheralEvent(event))
|
||||
}
|
||||
|
||||
//export goMouseButtonCB
|
||||
func goMouseButtonCB(window unsafe.Pointer, button, action, mods C.int) {
|
||||
w := windows.get((*C.GLFWwindow)(window))
|
||||
@ -554,24 +455,6 @@ func (w *Window) SetCursor(c *Cursor) {
|
||||
panicError()
|
||||
}
|
||||
|
||||
// JoystickCallback is the joystick configuration callback.
|
||||
type JoystickCallback func(joy Joystick, event PeripheralEvent)
|
||||
|
||||
// SetJoystickCallback sets the joystick configuration callback, or removes the
|
||||
// currently set callback. This is called when a joystick is connected to or
|
||||
// disconnected from the system.
|
||||
func SetJoystickCallback(cbfun JoystickCallback) (previous JoystickCallback) {
|
||||
previous = fJoystickHolder
|
||||
fJoystickHolder = cbfun
|
||||
if cbfun == nil {
|
||||
C.glfwSetJoystickCallback(nil)
|
||||
} else {
|
||||
C.glfwSetJoystickCallbackCB()
|
||||
}
|
||||
panicError()
|
||||
return previous
|
||||
}
|
||||
|
||||
// KeyCallback is the key callback.
|
||||
type KeyCallback func(w *Window, key Key, scancode int, action Action, mods ModifierKey)
|
||||
|
||||
@ -746,230 +629,3 @@ func (w *Window) SetDropCallback(cbfun DropCallback) (previous DropCallback) {
|
||||
panicError()
|
||||
return previous
|
||||
}
|
||||
|
||||
// Present returns whether the specified joystick is present.
|
||||
//
|
||||
// There is no need to call this function before other methods of Joystick type
|
||||
// as they all check for presence before performing any other work.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) Present() bool {
|
||||
return glfwbool(C.glfwJoystickPresent(C.int(joy)))
|
||||
}
|
||||
|
||||
// GetAxes returns the values of all axes of the specified joystick. Each
|
||||
// element in the array is a value between -1.0 and 1.0.
|
||||
//
|
||||
// If the specified joystick is not present this function will return nil but
|
||||
// will not generate an error. This can be used instead of first calling
|
||||
// Present.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) GetAxes() []float32 {
|
||||
var length int
|
||||
|
||||
axis := C.glfwGetJoystickAxes(C.int(joy), (*C.int)(unsafe.Pointer(&length)))
|
||||
if axis == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
a := make([]float32, length)
|
||||
for i := 0; i < length; i++ {
|
||||
a[i] = float32(C.GetAxisAtIndex(axis, C.int(i)))
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
// GetButtons returns the state of all buttons of the specified joystick. Each
|
||||
// element in the array is either Press or Release.
|
||||
//
|
||||
// For backward compatibility with earlier versions that did not have GetHats,
|
||||
// the button array also includes all hats, each represented as four buttons.
|
||||
// The hats are in the same order as returned by GetHats and are in the order
|
||||
// up, right, down and left. To disable these extra buttons, set the
|
||||
// JoystickHatButtons init hint before initialization.
|
||||
//
|
||||
// If the specified joystick is not present this function will return nil but
|
||||
// will not generate an error. This can be used instead of first calling
|
||||
// Present.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) GetButtons() []Action {
|
||||
var length int
|
||||
|
||||
buttons := C.glfwGetJoystickButtons(
|
||||
C.int(joy),
|
||||
(*C.int)(unsafe.Pointer(&length)),
|
||||
)
|
||||
if buttons == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b := make([]Action, length)
|
||||
for i := 0; i < length; i++ {
|
||||
b[i] = Action(C.GetButtonsAtIndex(buttons, C.int(i)))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// GetHats returns the state of all hats of the specified joystick.
|
||||
//
|
||||
// If the specified joystick is not present this function will return nil but
|
||||
// will not generate an error. This can be used instead of first calling
|
||||
// Present.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) GetHats() []JoystickHatState {
|
||||
var length int
|
||||
|
||||
hats := C.glfwGetJoystickHats(C.int(joy), (*C.int)(unsafe.Pointer(&length)))
|
||||
if hats == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
b := make([]JoystickHatState, length)
|
||||
for i := 0; i < length; i++ {
|
||||
b[i] = JoystickHatState(C.GetButtonsAtIndex(hats, C.int(i)))
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// GetName returns the name, encoded as UTF-8, of the specified joystick.
|
||||
//
|
||||
// If the specified joystick is not present this function will return nil but
|
||||
// will not generate an error. This can be used instead of first calling
|
||||
// Present.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) GetName() string {
|
||||
jn := C.glfwGetJoystickName(C.int(joy))
|
||||
return C.GoString(jn)
|
||||
}
|
||||
|
||||
// GetGUID returns the SDL compatible GUID, as a UTF-8 encoded
|
||||
// hexadecimal string, of the specified joystick.
|
||||
//
|
||||
// The GUID is what connects a joystick to a gamepad mapping. A connected
|
||||
// joystick will always have a GUID even if there is no gamepad mapping
|
||||
// assigned to it.
|
||||
//
|
||||
// If the specified joystick is not present this function will return empty
|
||||
// string but will not generate an error. This can be used instead of first
|
||||
// calling JoystickPresent.
|
||||
//
|
||||
// The GUID uses the format introduced in SDL 2.0.5. This GUID tries to uniquely
|
||||
// identify the make and model of a joystick but does not identify a specific
|
||||
// unit, e.g. all wired Xbox 360 controllers will have the same GUID on that
|
||||
// platform. The GUID for a unit may vary between platforms depending on what
|
||||
// hardware information the platform specific APIs provide.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) GetGUID() string {
|
||||
guid := C.glfwGetJoystickGUID(C.int(joy))
|
||||
return C.GoString(guid)
|
||||
}
|
||||
|
||||
// SetUserPointer sets the user-defined pointer of the joystick. The current value
|
||||
// is retained until the joystick is disconnected. The initial value is nil.
|
||||
//
|
||||
// This function may be called from the joystick callback, even for a joystick
|
||||
// that is being disconnected.
|
||||
//
|
||||
// This function may be called from any thread. Access is not synchronized.
|
||||
func (joy Joystick) SetUserPointer(pointer unsafe.Pointer) {
|
||||
C.glfwSetJoystickUserPointer(C.int(joy), pointer)
|
||||
}
|
||||
|
||||
// GetUserPointer returns the current value of the user-defined pointer of the
|
||||
// joystick. The initial value is nil.
|
||||
//
|
||||
// This function may be called from the joystick callback, even for a joystick
|
||||
// that is being disconnected.
|
||||
//
|
||||
// This function may be called from any thread. Access is not synchronized.
|
||||
func (joy Joystick) GetUserPointer() unsafe.Pointer {
|
||||
return C.glfwGetJoystickUserPointer(C.int(joy))
|
||||
}
|
||||
|
||||
// IsGamepad returns whether the specified joystick is both present and
|
||||
// has a gamepad mapping.
|
||||
//
|
||||
// If the specified joystick is present but does not have a gamepad mapping this
|
||||
// function will return false but will not generate an error. Call Present to
|
||||
// check if a joystick is present regardless of whether it has a mapping.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) IsGamepad() bool {
|
||||
return glfwbool(C.glfwJoystickIsGamepad(C.int(joy)))
|
||||
}
|
||||
|
||||
// UpdateGamepadMappings parses the specified ASCII encoded string and updates
|
||||
// the internal list with any gamepad mappings it finds. This string may contain
|
||||
// either a single gamepad mapping or many mappings separated by newlines. The
|
||||
// parser supports the full format of the gamecontrollerdb.txt source file
|
||||
// including empty lines and comments.
|
||||
//
|
||||
// See Gamepad mappings for a description of the format.
|
||||
//
|
||||
// If there is already a gamepad mapping for a given GUID in the internal list,
|
||||
// it will be replaced by the one passed to this function. If the library is
|
||||
// terminated and re-initialized the internal list will revert to the built-in
|
||||
// default.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func UpdateGamepadMappings(mapping string) bool {
|
||||
m := C.CString(mapping)
|
||||
defer C.free(unsafe.Pointer(m))
|
||||
return glfwbool(C.glfwUpdateGamepadMappings(m))
|
||||
}
|
||||
|
||||
// GetGamepadName returns the human-readable name of the gamepad from the
|
||||
// gamepad mapping assigned to the specified joystick.
|
||||
//
|
||||
// If the specified joystick is not present or does not have a gamepad mapping
|
||||
// this function will return empty string but will not generate an error. Call
|
||||
// Present to check whether it is present regardless of whether it has a
|
||||
// mapping.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) GetGamepadName() string {
|
||||
gn := C.glfwGetGamepadName(C.int(joy))
|
||||
return C.GoString(gn)
|
||||
}
|
||||
|
||||
// GetGamepadState retrives the state of the specified joystick remapped to an
|
||||
// Xbox-like gamepad.
|
||||
//
|
||||
// If the specified joystick is not present or does not have a gamepad mapping
|
||||
// this function will return nil but will not generate an error. Call
|
||||
// Present to check whether it is present regardless of whether it has a
|
||||
// mapping.
|
||||
//
|
||||
// The Guide button may not be available for input as it is often hooked by the
|
||||
// system or the Steam client.
|
||||
//
|
||||
// Not all devices have all the buttons or axes provided by GamepadState.
|
||||
// Unavailable buttons and axes will always report Release and 0.0 respectively.
|
||||
//
|
||||
// This function must only be called from the main thread.
|
||||
func (joy Joystick) GetGamepadState() *GamepadState {
|
||||
var (
|
||||
gs GamepadState
|
||||
cgs C.GLFWgamepadstate
|
||||
)
|
||||
|
||||
ret := C.glfwGetGamepadState(C.int(joy), &cgs)
|
||||
if ret == C.GLFW_FALSE {
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < 15; i++ {
|
||||
gs.Buttons[i] = Action(C.GetGamepadButtonAtIndex(&cgs, C.int(i)))
|
||||
}
|
||||
|
||||
for i := 0; i < 6; i++ {
|
||||
gs.Axes[i] = float32(C.GetGamepadAxisAtIndex(&cgs, C.int(i)))
|
||||
}
|
||||
|
||||
return &gs
|
||||
}
|
||||
|
@ -57,7 +57,6 @@ type Hint int
|
||||
|
||||
// Init related hints. (Use with glfw.InitHint)
|
||||
const (
|
||||
JoystickHatButtons Hint = C.GLFW_JOYSTICK_HAT_BUTTONS // Specifies whether to also expose joystick hats as buttons, for compatibility with earlier versions of GLFW that did not have glfwGetJoystickHats.
|
||||
CocoaChdirResources Hint = C.GLFW_COCOA_CHDIR_RESOURCES // Specifies whether to set the current directory to the application to the Contents/Resources subdirectory of the application's bundle, if present.
|
||||
CocoaMenubar Hint = C.GLFW_COCOA_MENUBAR // Specifies whether to create a basic menu bar, either from a nib or manually, when the first window is created, which is when AppKit is initialized.
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user