Test and fix joystick and game pad callbacks on Linux.

This commit is contained in:
Beoran 2019-11-07 01:01:31 +01:00
parent f5536ccae0
commit ee4132b5cf
6 changed files with 125 additions and 37 deletions

View File

@ -1168,17 +1168,6 @@ typedef struct GLFWwindow GLFWwindow;
*/ */
typedef struct GLFWcursor GLFWcursor; typedef struct GLFWcursor GLFWcursor;
/*! @brief Gamepad state object.
*
* Gamepad state object, predeclared here.
*
* @since Added in version 3.4.
*
* @ingroup input
*/
typedef struct GLFWgamepadstate GLFWgamepadstate;
/*! @brief The function pointer type for error callbacks. /*! @brief The function pointer type for error callbacks.
* *
* This is the function pointer type for error callbacks. An error callback * This is the function pointer type for error callbacks. An error callback
@ -1711,7 +1700,11 @@ typedef void (* GLFWjoystickhatfun)(int,int,int);
* @endcode * @endcode
* *
* @param[in] jid The ID of the game pad that changed state. * @param[in] jid The ID of the game pad that changed state.
* @param[in] state The updated state of the game pad. * @param[in] buttons The states of each
* [gamepad button](@ref gamepad_buttons),
* `GLFW_PRESS` or `GLFW_RELEASE`.
* @param[in] axes The states of each [gamepad axis](@ref gamepad_axes),
* in the range -1.0 to 1.0 inclusive.
* *
* @sa @ref input_gamepad * @sa @ref input_gamepad
* @sa @ref glfwSetGamepadStateCallback * @sa @ref glfwSetGamepadStateCallback
@ -1719,7 +1712,8 @@ typedef void (* GLFWjoystickhatfun)(int,int,int);
* @since Added in version 3.4. * @since Added in version 3.4.
* @ingroup input * @ingroup input
*/ */
typedef void (* GLFWgamepadstatefun)(int,GLFWgamepadstate*); typedef void (* GLFWgamepadstatefun)(int, unsigned char buttons[15],
float axes[6]);
/*! @brief The function pointer type for Unicode character callbacks. /*! @brief The function pointer type for Unicode character callbacks.
@ -5385,7 +5379,7 @@ GLFWAPI GLFWjoystickhatfun glfwSetJoystickHatCallback(GLFWjoystickhatfun callbac
* *
* @callback_signature * @callback_signature
* @code * @code
* void function_name(int jid, GLFWgamepadstate* state) * void function_name(int jid, unsigned char buttons[15], float axes[6])
* @endcode * @endcode
* For more information about the callback parameters, see the * For more information about the callback parameters, see the
* [function pointer type](@ref GLFWgamepadstatefun). * [function pointer type](@ref GLFWgamepadstatefun).

View File

@ -370,10 +370,15 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
void _glfwInputGamepad(_GLFWjoystick* js) void _glfwInputGamepad(_GLFWjoystick* js)
{ {
const int jid = (int) (js - _glfw.joysticks); const int jid = (int) (js - _glfw.joysticks);
if (glfwJoystickIsGamepad(jid) && (_glfw.callbacks.gamepad_state)) {
if (!_glfw.initialized) {
return;
}
if ((js->mapping != NULL) && (_glfw.callbacks.gamepad_state)) {
GLFWgamepadstate state; GLFWgamepadstate state;
if (0 == glfwGetGamepadState(jid, &state)) { if (glfwGetGamepadState(jid, &state)) {
_glfw.callbacks.gamepad_state(jid, &state); _glfw.callbacks.gamepad_state(jid, state.buttons, state.axes);
} }
} }
} }
@ -394,10 +399,11 @@ void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
{ {
const int jid = (int) (js - _glfw.joysticks); const int jid = (int) (js - _glfw.joysticks);
if ((_glfw.callbacks.joystick_axis) && (js->axes[axis] != value))
_glfw.callbacks.joystick_axis(jid, axis, value);
js->axes[axis] = value; js->axes[axis] = value;
if (_glfw.callbacks.joystick_axis)
_glfw.callbacks.joystick_axis(jid, axis, value);
_glfwInputGamepad(js); _glfwInputGamepad(js);
} }
@ -495,6 +501,17 @@ void _glfwCenterCursorInContentArea(_GLFWwindow* window)
_glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0); _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
} }
void _glfwPollAllJoysticks() {
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].present == GLFW_TRUE) {
_glfwPlatformPollJoystick(_glfw.joysticks + jid, _GLFW_POLL_ALL);
}
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW public API ////// ////// GLFW public API //////

View File

@ -769,6 +769,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name,
int hatCount); int hatCount);
void _glfwFreeJoystick(_GLFWjoystick* js); void _glfwFreeJoystick(_GLFWjoystick* js);
void _glfwCenterCursorInContentArea(_GLFWwindow* window); void _glfwCenterCursorInContentArea(_GLFWwindow* window);
void _glfwPollAllJoysticks();
GLFWbool _glfwInitVulkan(int mode); GLFWbool _glfwInitVulkan(int mode);
void _glfwTerminateVulkan(void); void _glfwTerminateVulkan(void);

View File

@ -1069,12 +1069,14 @@ GLFWAPI GLFWwindowcontentscalefun glfwSetWindowContentScaleCallback(GLFWwindow*
GLFWAPI void glfwPollEvents(void) GLFWAPI void glfwPollEvents(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPollAllJoysticks();
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
} }
GLFWAPI void glfwWaitEvents(void) GLFWAPI void glfwWaitEvents(void)
{ {
_GLFW_REQUIRE_INIT(); _GLFW_REQUIRE_INIT();
_glfwPollAllJoysticks();
_glfwPlatformWaitEvents(); _glfwPlatformWaitEvents();
} }

View File

@ -65,21 +65,32 @@ static GLFWbool waitForEvent(double* timeout)
{ {
fd_set fds; fd_set fds;
const int fd = ConnectionNumber(_glfw.x11.display); const int fd = ConnectionNumber(_glfw.x11.display);
int count = fd + 1;
#if defined(__linux__)
if (_glfw.linjs.inotify > fd)
count = _glfw.linjs.inotify + 1;
#endif
for (;;) for (;;)
{ {
int count = fd + 1;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
#if defined(__linux__) #if defined(__linux__)
if (_glfw.linjs.inotify > 0) if (_glfw.linjs.inotify > 0)
FD_SET(_glfw.linjs.inotify, &fds); {
#endif if (_glfw.linjs.inotify >= count )
count = _glfw.linjs.inotify + 1;
FD_SET(_glfw.linjs.inotify, &fds);
}
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].present) {
if (_glfw.joysticks[jid].linjs.fd >= count)
count = _glfw.joysticks[jid].linjs.fd + 1;
FD_SET(_glfw.joysticks[jid].linjs.fd, &fds);
}
}
#endif
if (timeout) if (timeout)
{ {
const long seconds = (long) *timeout; const long seconds = (long) *timeout;
@ -2681,6 +2692,7 @@ void _glfwPlatformPollEvents(void)
#if defined(__linux__) #if defined(__linux__)
_glfwDetectJoystickConnectionLinux(); _glfwDetectJoystickConnectionLinux();
_glfwPollAllJoysticks();
#endif #endif
XPending(_glfw.x11.display); XPending(_glfw.x11.display);
@ -2709,23 +2721,35 @@ void _glfwPlatformPollEvents(void)
XFlush(_glfw.x11.display); XFlush(_glfw.x11.display);
} }
void _glfwPlatformWaitEvents(void) static GLFWbool waitForAndPollEvents(double * timeout)
{ {
while (!XPending(_glfw.x11.display)) GLFWbool result = GLFW_FALSE;
waitForEvent(NULL); for (;;)
{
int xpending = XPending(_glfw.x11.display);
GLFWbool event = waitForEvent(timeout);
// We cannot use the boolean shortcut here, since
// waiting for events might have a side effect.
if (event || xpending )
{
result = GLFW_TRUE;
break;
}
}
_glfwPlatformPollEvents(); _glfwPlatformPollEvents();
return result;
}
void _glfwPlatformWaitEvents(void)
{
waitForAndPollEvents(NULL);
} }
void _glfwPlatformWaitEventsTimeout(double timeout) void _glfwPlatformWaitEventsTimeout(double timeout)
{ {
while (!XPending(_glfw.x11.display)) waitForAndPollEvents(&timeout);
{
if (!waitForEvent(&timeout))
break;
}
_glfwPlatformPollEvents();
} }
void _glfwPlatformPostEmptyEvent(void) void _glfwPlatformPostEmptyEvent(void)

View File

@ -494,6 +494,52 @@ static void joystick_callback(int jid, int event)
} }
} }
static void joystick_button_callback(int jid, int button, int state) {
printf("%08x at %0.3f: Joystick %i (%s) button %d state %d\n",
counter++, glfwGetTime(),
jid,
glfwGetJoystickName(jid),
button,
state);
}
static void joystick_axis_callback(int jid, int axis, float value) {
printf("%08x at %0.3f: Joystick %i (%s) axis %d value %0.4f\n",
counter++, glfwGetTime(), jid,
glfwGetJoystickName(jid),
axis,
value);
}
static void joystick_hat_callback(int jid, int hat, int value) {
printf("%08x at %0.3f: Joystick %i (%s) hat %d value %d\n",
counter++, glfwGetTime(),
jid,
glfwGetJoystickName(jid),
hat,
value);
}
static void gamepad_state_callback(int jid, unsigned char buttons[15], float axes[6]) {
int i = 0;
printf("%08x at %0.3f: Gamepad %i (%s) state:",
counter++, glfwGetTime(),
jid,
glfwGetJoystickName(jid));
printf("Buttons: ");
for (i= 0 ; i < 15; i++) {
printf(" %d:%d", i, buttons[i]);
}
printf("Axes: ");
for (i= 0 ; i < 6; i++) {
printf(" %d:%0.4f", i, axes[i]);
}
printf("\n");
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
Slot* slots; Slot* slots;
@ -511,6 +557,10 @@ int main(int argc, char** argv)
glfwSetMonitorCallback(monitor_callback); glfwSetMonitorCallback(monitor_callback);
glfwSetJoystickCallback(joystick_callback); glfwSetJoystickCallback(joystick_callback);
glfwSetJoystickAxisCallback(joystick_axis_callback);
glfwSetJoystickButtonCallback(joystick_button_callback);
glfwSetJoystickHatCallback(joystick_hat_callback);
glfwSetGamepadStateCallback(gamepad_state_callback);
while ((ch = getopt(argc, argv, "hfn:")) != -1) while ((ch = getopt(argc, argv, "hfn:")) != -1)
{ {