diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 36a040e2..41efe310 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -136,6 +136,7 @@ video tutorials. - Kenneth Miller - Bruce Mitchener - Jack Moffitt + - Ravi Mohan - Jeff Molofee - Alexander Monakov - Pierre Morel diff --git a/README.md b/README.md index 61b20c71..26a6092a 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ information on what to include when reporting a bug. - Bugfix: `glfwMakeContextCurrent` would access TLS slot before initialization - Bugfix: `glfwSetGammaRamp` could emit `GLFW_INVALID_VALUE` before initialization + - Bugfix: `glfwGetJoystickUserPointer` returned `NULL` during disconnection (#2092) - [Win32] Bugfix: `Alt+PrtSc` would emit `GLFW_KEY_UNKNOWN` and a different scancode than `PrtSc` (#1993) - [Win32] Bugfix: `GLFW_KEY_PAUSE` scancode from `glfwGetKeyScancode` did not diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 2c8d82d9..3d306777 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -98,8 +98,7 @@ static void closeJoystick(_GLFWjoystick* js) { int i; - if (!js->present) - return; + _glfwInputJoystick(js, GLFW_DISCONNECTED); for (i = 0; i < CFArrayGetCount(js->ns.axes); i++) free((void*) CFArrayGetValueAtIndex(js->ns.axes, i)); @@ -114,7 +113,6 @@ static void closeJoystick(_GLFWjoystick* js) CFRelease(js->ns.hats); _glfwFreeJoystick(js); - _glfwInputJoystick(js, GLFW_DISCONNECTED); } // Callback for user-initiated joystick addition @@ -294,9 +292,9 @@ static void removeCallback(void* context, for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (_glfw.joysticks[jid].ns.device == device) + if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device) { - closeJoystick(_glfw.joysticks + jid); + closeJoystick(&_glfw.joysticks[jid]); break; } } @@ -392,7 +390,10 @@ void _glfwTerminateJoysticksNS(void) int jid; for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - closeJoystick(_glfw.joysticks + jid); + { + if (_glfw.joysticks[jid].connected) + closeJoystick(&_glfw.joysticks[jid]); + } CFRelease(_glfw.ns.hidManager); _glfw.ns.hidManager = NULL; @@ -470,7 +471,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) } } - return js->present; + return js->connected; } void _glfwPlatformUpdateGamepadGUID(char* guid) diff --git a/src/input.c b/src/input.c index f6c1ed79..7ea1222c 100644 --- a/src/input.c +++ b/src/input.c @@ -360,6 +360,11 @@ 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); } @@ -415,7 +420,7 @@ void _glfwInitGamepadMappings(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) js->mapping = findValidMapping(js); } } @@ -433,7 +438,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (!_glfw.joysticks[jid].present) + if (!_glfw.joysticks[jid].allocated) break; } @@ -441,7 +446,7 @@ _GLFWjoystick* _glfwAllocJoystick(const char* name, return NULL; js = _glfw.joysticks + jid; - js->present = GLFW_TRUE; + js->allocated = GLFW_TRUE; js->axes = calloc(axisCount, sizeof(float)); js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1); js->hats = calloc(hatCount, 1); @@ -944,7 +949,7 @@ GLFWAPI int glfwJoystickPresent(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return GLFW_FALSE; return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); @@ -969,7 +974,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES)) @@ -998,7 +1003,7 @@ GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) @@ -1031,7 +1036,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS)) @@ -1057,7 +1062,7 @@ GLFWAPI const char* glfwGetJoystickName(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1082,7 +1087,7 @@ GLFWAPI const char* glfwGetJoystickGUID(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1101,7 +1106,7 @@ GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer) _GLFW_REQUIRE_INIT(); js = _glfw.joysticks + jid; - if (!js->present) + if (!js->allocated) return; js->userPointer = pointer; @@ -1117,7 +1122,7 @@ GLFWAPI void* glfwGetJoystickUserPointer(int jid) _GLFW_REQUIRE_INIT_OR_RETURN(NULL); js = _glfw.joysticks + jid; - if (!js->present) + if (!js->allocated) return NULL; return js->userPointer; @@ -1183,7 +1188,7 @@ GLFWAPI int glfwUpdateGamepadMappings(const char* string) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) js->mapping = findValidMapping(js); } @@ -1206,7 +1211,7 @@ GLFWAPI int glfwJoystickIsGamepad(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return GLFW_FALSE; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1231,7 +1236,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return NULL; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE)) @@ -1263,7 +1268,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state) } js = _glfw.joysticks + jid; - if (!js->present) + if (!js->connected) return GLFW_FALSE; if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL)) diff --git a/src/internal.h b/src/internal.h index 3e9283a3..7734caa3 100644 --- a/src/internal.h +++ b/src/internal.h @@ -478,7 +478,8 @@ struct _GLFWmapping // struct _GLFWjoystick { - GLFWbool present; + GLFWbool allocated; + GLFWbool connected; float* axes; int axisCount; unsigned char* buttons; diff --git a/src/linux_joystick.c b/src/linux_joystick.c index 5a3b806c..0894a726 100644 --- a/src/linux_joystick.c +++ b/src/linux_joystick.c @@ -128,7 +128,7 @@ static GLFWbool openJoystickDevice(const char* path) { for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (!_glfw.joysticks[jid].present) + if (!_glfw.joysticks[jid].connected) continue; if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) return GLFW_FALSE; @@ -245,9 +245,9 @@ static GLFWbool openJoystickDevice(const char* path) // static void closeJoystick(_GLFWjoystick* js) { + _glfwInputJoystick(js, GLFW_DISCONNECTED); close(js->linjs.fd); _glfwFreeJoystick(js); - _glfwInputJoystick(js, GLFW_DISCONNECTED); } // Lexically compare joysticks by name; used by qsort @@ -329,7 +329,7 @@ void _glfwTerminateJoysticksLinux(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) closeJoystick(js); } @@ -424,7 +424,7 @@ int _glfwPlatformPollJoystick(_GLFWjoystick* js, int mode) handleAbsEvent(js, e.code, e.value); } - return js->present; + return js->connected; } void _glfwPlatformUpdateGamepadGUID(char* guid) diff --git a/src/win32_joystick.c b/src/win32_joystick.c index 67e3465c..f471f0a9 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -256,6 +256,8 @@ static GLFWbool supportsXInput(const GUID* guid) // static void closeJoystick(_GLFWjoystick* js) { + _glfwInputJoystick(js, GLFW_DISCONNECTED); + if (js->win32.device) { IDirectInputDevice8_Unacquire(js->win32.device); @@ -263,9 +265,7 @@ static void closeJoystick(_GLFWjoystick* js) } free(js->win32.objects); - _glfwFreeJoystick(js); - _glfwInputJoystick(js, GLFW_DISCONNECTED); } // DirectInput device object enumeration callback @@ -357,7 +357,7 @@ static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) { if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0) return DIENUM_CONTINUE; @@ -541,7 +541,7 @@ void _glfwDetectJoystickConnectionWin32(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { - if (_glfw.joysticks[jid].present && + if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].win32.device == NULL && _glfw.joysticks[jid].win32.index == index) { @@ -593,7 +593,7 @@ void _glfwDetectJoystickDisconnectionWin32(void) for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) { _GLFWjoystick* js = _glfw.joysticks + jid; - if (js->present) + if (js->connected) _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE); } }