diff --git a/src/cocoa_joystick.h b/src/cocoa_joystick.h deleted file mode 100644 index 9cb12e651d..0000000000 --- a/src/cocoa_joystick.h +++ /dev/null @@ -1,53 +0,0 @@ -//======================================================================== -// GLFW 3.3 Cocoa - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2006-2016 Camilla Löwy -// -// 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. -// -//======================================================================== - -#ifndef _glfw3_cocoa_joystick_h_ -#define _glfw3_cocoa_joystick_h_ - -#include -#include -#include -#include - -#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickNS ns -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE - - -// Cocoa-specific per-joystick data -// -typedef struct _GLFWjoystickNS -{ - IOHIDDeviceRef device; - CFMutableArrayRef axes; - CFMutableArrayRef buttons; - CFMutableArrayRef hats; -} _GLFWjoystickNS; - - -void _glfwInitJoysticksNS(void); -void _glfwTerminateJoysticksNS(void); - -#endif // _glfw3_cocoa_joystick_h_ diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m deleted file mode 100644 index e828002b05..0000000000 --- a/src/cocoa_joystick.m +++ /dev/null @@ -1,399 +0,0 @@ -//======================================================================== -// GLFW 3.3 Cocoa - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2009-2016 Camilla Löwy -// Copyright (c) 2012 Torsten Walluhn -// -// 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 "internal.h" - -#include -#include -#include - -#include -#include - -#include -#include - - -// Joystick element information -// -typedef struct _GLFWjoyelementNS -{ - IOHIDElementRef native; - long minimum; - long maximum; - -} _GLFWjoyelementNS; - - -// Returns the value of the specified element of the specified joystick -// -static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element) -{ - IOReturn result = kIOReturnSuccess; - IOHIDValueRef valueRef; - long value = 0; - - if (js && element && js->ns.device) - { - result = IOHIDDeviceGetValue(js->ns.device, - element->native, - &valueRef); - - if (kIOReturnSuccess == result) - { - value = IOHIDValueGetIntegerValue(valueRef); - - // Record min and max for auto calibration - if (value < element->minimum) - element->minimum = value; - if (value > element->maximum) - element->maximum = value; - } - } - - // Auto user scale - return value; -} - -// Removes the specified joystick -// -static void closeJoystick(_GLFWjoystick* js) -{ - int i; - - if (!js->present) - return; - - 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); - _glfwInputJoystick(_GLFW_JOYSTICK_ID(js), GLFW_DISCONNECTED); -} - -// Callback for user-initiated joystick addition -// -static void matchCallback(void* context, - IOReturn result, - void* sender, - IOHIDDeviceRef device) -{ - int jid; - char name[256]; - CFIndex i; - CFStringRef productKey; - _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); - - productKey = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey)); - if (productKey) - { - CFStringGetCString(productKey, - name, - sizeof(name), - kCFStringEncodingUTF8); - } - else - strncpy(name, "Unknown", sizeof(name)); - - 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; - - switch (IOHIDElementGetUsagePage(native)) - { - case kHIDPage_GenericDesktop: - { - switch (IOHIDElementGetUsage(native)) - { - 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; - } - - break; - } - - case kHIDPage_Button: - target = buttons; - break; - default: - break; - } - - if (target) - { - _GLFWjoyelementNS* element = calloc(1, sizeof(_GLFWjoyelementNS)); - element->native = native; - element->minimum = IOHIDElementGetLogicalMin(native); - element->maximum = IOHIDElementGetLogicalMax(native); - CFArrayAppendValue(target, element); - } - } - - CFRelease(elements); - - js = _glfwAllocJoystick(name, - CFArrayGetCount(axes), - CFArrayGetCount(buttons), - CFArrayGetCount(hats)); - - js->ns.device = device; - js->ns.axes = axes; - js->ns.buttons = buttons; - js->ns.hats = hats; - - _glfwInputJoystick(_GLFW_JOYSTICK_ID(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].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 (int 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++) - closeJoystick(_glfw.joysticks + jid); - - CFRelease(_glfw.ns.hidManager); - _glfw.ns.hidManager = NULL; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformPollJoystick(int jid, int mode) -{ - _GLFWjoystick* js = _glfw.joysticks + jid; - - 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 value = getElementValue(js, axis); - const long delta = axis->maximum - axis->minimum; - - if (delta == 0) - _glfwInputJoystickAxis(jid, i, value); - else - _glfwInputJoystickAxis(jid, i, (2.f * (value - axis->minimum) / delta) - 1.f); - } - } - else 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) ? 1 : 0; - _glfwInputJoystickButton(jid, i, value); - } - - 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); - if (state < 0 || state > 8) - state = 8; - - _glfwInputJoystickHat(jid, i, states[state]); - } - } - - return js->present; -} - diff --git a/src/internal.h b/src/internal.h index 13214b0713..43ae232f1a 100644 --- a/src/internal.h +++ b/src/internal.h @@ -27,6 +27,7 @@ #ifndef _glfw3_internal_h_ #define _glfw3_internal_h_ +#endif #if defined(_GLFW_USE_CONFIG_H) @@ -805,35 +806,6 @@ void _glfwInputError(int error, const char* format, ...); */ void _glfwInputDrop(_GLFWwindow* window, int count, const char** names); -/*! @brief Notifies shared code of a joystick connection or disconnection. - * @param[in] jid The joystick that was connected or disconnected. - * @param[in] event One of `GLFW_CONNECTED` or `GLFW_DISCONNECTED`. - * @ingroup event - */ -void _glfwInputJoystick(int jid, int event); - -/*! @brief Notifies shared code of the new value of a joystick axis. - * @param[in] jid The joystick whose axis to update. - * @param[in] axis The index of the axis to update. - * @param[in] value The new value of the axis. - */ -void _glfwInputJoystickAxis(int jid, int axis, float value); - -/*! @brief Notifies shared code of the new value of a joystick button. - * @param[in] jid The joystick whose button to update. - * @param[in] button The index of the button to update. - * @param[in] value The new value of the button. - */ -void _glfwInputJoystickButton(int jid, int button, char value); - -/*! @brief Notifies shared code of the new value of a joystick hat. - * @param[in] jid The joystick whose hat to update. - * @param[in] button The index of the hat to update. - * @param[in] value The new value of the hat. - */ -void _glfwInputJoystickHat(int jid, int hat, char value); - - //======================================================================== // Utility functions //======================================================================== @@ -919,30 +891,6 @@ _GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM); */ void _glfwFreeMonitor(_GLFWmonitor* monitor); -/*! @brief Returns an available joystick object with arrays and name allocated. - * @ingroup utility - */ -_GLFWjoystick* _glfwAllocJoystick(const char* name, int axisCount, int buttonCount, int hatCount); - -/*! @brief Frees arrays and name and flags the joystick object as unused. - * @ingroup utility - */ -void _glfwFreeJoystick(_GLFWjoystick* js); - /*! @ingroup utility */ GLFWbool _glfwIsPrintable(int key); - -/*! @ingroup utility - */ -GLFWbool _glfwInitVulkan(int mode); - -/*! @ingroup utility - */ -void _glfwTerminateVulkan(void); - -/*! @ingroup utility - */ -const char* _glfwGetVulkanResultString(VkResult result); - -#endif // _glfw3_internal_h_ diff --git a/src/linux_joystick.c b/src/linux_joystick.c deleted file mode 100644 index 6e4b6a8c90..0000000000 --- a/src/linux_joystick.c +++ /dev/null @@ -1,286 +0,0 @@ -//======================================================================== -// GLFW 3.3 Linux - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2016 Camilla Löwy -// -// 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 "internal.h" - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// Attempt to open the specified joystick device -// -static GLFWbool openJoystickDevice(const char* path) -{ - char axisCount, buttonCount; - char name[256] = ""; - int jid, fd, version; - _GLFWjoystick* js; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - { - if (!_glfw.joysticks[jid].present) - continue; - if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) - return GLFW_FALSE; - } - - fd = open(path, O_RDONLY | O_NONBLOCK); - if (fd == -1) - return GLFW_FALSE; - - // Verify that the joystick driver version is at least 1.0 - ioctl(fd, JSIOCGVERSION, &version); - if (version < 0x010000) - { - // It's an old 0.x interface (we don't support it) - close(fd); - return GLFW_FALSE; - } - - if (ioctl(fd, JSIOCGNAME(sizeof(name)), name) < 0) - strncpy(name, "Unknown", sizeof(name)); - - ioctl(fd, JSIOCGAXES, &axisCount); - ioctl(fd, JSIOCGBUTTONS, &buttonCount); - - js = _glfwAllocJoystick(name, axisCount, buttonCount, 0); - if (!js) - { - close(fd); - return GLFW_FALSE; - } - - js->linjs.path = strdup(path); - js->linjs.fd = fd; - - _glfwInputJoystick(_GLFW_JOYSTICK_ID(js), GLFW_CONNECTED); - return GLFW_TRUE; -} - -// Frees all resources associated with the specified joystick -// -static void closeJoystick(_GLFWjoystick* js) -{ - close(js->linjs.fd); - free(js->linjs.path); - _glfwFreeJoystick(js); - _glfwInputJoystick(_GLFW_JOYSTICK_ID(js), GLFW_DISCONNECTED); -} - -// 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) -{ - DIR* dir; - int count = 0; - const char* dirname = "/dev/input"; - - _glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); - if (_glfw.linjs.inotify == -1) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Linux: Failed to initialize inotify: %s", - strerror(errno)); - return GLFW_FALSE; - } - - // HACK: Register for IN_ATTRIB as well 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); - if (_glfw.linjs.watch == -1) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Linux: Failed to watch for joystick connections in %s: %s", - dirname, - strerror(errno)); - // Continue without device connection notifications - } - - if (regcomp(&_glfw.linjs.regex, "^js[0-9]\\+$", 0) != 0) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex"); - return GLFW_FALSE; - } - - dir = opendir(dirname); - if (dir) - { - struct dirent* entry; - - while ((entry = readdir(dir))) - { - char path[20]; - regmatch_t match; - - if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0) - continue; - - snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name); - if (openJoystickDevice(path)) - count++; - } - - closedir(dir); - } - else - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Linux: Failed to open joystick device directory %s: %s", - dirname, - strerror(errno)); - // Continue with no joysticks detected - } - - 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->present) - 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) -{ - 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); - - if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) == 0) - { - char path[20]; - snprintf(path, sizeof(path), "/dev/input/%s", e->name); - - if (e->mask & (IN_CREATE | IN_ATTRIB)) - openJoystickDevice(path); - else if (e->mask & IN_DELETE) - { - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - { - if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0) - { - closeJoystick(_glfw.joysticks + jid); - break; - } - } - } - } - - offset += sizeof(struct inotify_event) + e->len; - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformPollJoystick(int jid, int mode) -{ - _GLFWjoystick* js = _glfw.joysticks + jid; - - // Read all queued events (non-blocking) - for (;;) - { - struct js_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; - } - - // Clear the initial-state bit - e.type &= ~JS_EVENT_INIT; - - if (e.type == JS_EVENT_AXIS) - _glfwInputJoystickAxis(jid, e.number, e.value / 32767.0f); - else if (e.type == JS_EVENT_BUTTON) - _glfwInputJoystickButton(jid, e.number, e.value ? 1 : 0); - } - - return js->present; -} - diff --git a/src/linux_joystick.h b/src/linux_joystick.h deleted file mode 100644 index 3698b7e070..0000000000 --- a/src/linux_joystick.h +++ /dev/null @@ -1,58 +0,0 @@ -//======================================================================== -// GLFW 3.3 Linux - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2014 Jonas Ådahl -// -// 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. -// -//======================================================================== - -#ifndef _glfw3_linux_joystick_h_ -#define _glfw3_linux_joystick_h_ - -#include - -#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickLinux linjs -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs - - -// Linux-specific joystick data -// -typedef struct _GLFWjoystickLinux -{ - int fd; - char* path; -} _GLFWjoystickLinux; - -// Linux-specific joystick API data -// -typedef struct _GLFWlibraryLinux -{ - int inotify; - int watch; - regex_t regex; -} _GLFWlibraryLinux; - - -GLFWbool _glfwInitJoysticksLinux(void); -void _glfwTerminateJoysticksLinux(void); -void _glfwDetectJoystickConnectionLinux(void); - -#endif // _glfw3_linux_joystick_h_ diff --git a/src/win32_joystick.c b/src/win32_joystick.c deleted file mode 100644 index ecbf4b90ed..0000000000 --- a/src/win32_joystick.c +++ /dev/null @@ -1,720 +0,0 @@ -//======================================================================== -// GLFW 3.3 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2016 Camilla Löwy -// -// 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 "internal.h" - -#include - -#include - -#define _GLFW_TYPE_AXIS 0 -#define _GLFW_TYPE_SLIDER 1 -#define _GLFW_TYPE_BUTTON 2 -#define _GLFW_TYPE_POV 3 - -// Data produced with DirectInput device object enumeration -// -typedef struct _GLFWobjenumWin32 -{ - IDirectInputDevice8W* device; - _GLFWjoyobjectWin32* objects; - int objectCount; - int axisCount; - int sliderCount; - int buttonCount; - int povCount; -} _GLFWobjenumWin32; - -// Define only the necessary GUIDs (it's bad enough that we're exporting these) -// -DEFINE_GUID(IID_IDirectInput8W,0xbf798031,0x483a,0x4da2,0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00); -DEFINE_GUID(GUID_XAxis,0xa36d02e0,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_YAxis,0xa36d02e1,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_ZAxis,0xa36d02e2,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_RxAxis,0xa36d02f4,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_RyAxis,0xa36d02f5,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_RzAxis,0xa36d02e3,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_Slider,0xa36d02e4,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_Button,0xa36d02f0,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); -DEFINE_GUID(GUID_POV,0xa36d02f2,0xc9f3,0x11cf,0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00); - -// Object data array for our clone of c_dfDIJoystick -// Generated with https://github.com/elmindreda/c_dfDIJoystick2 -// -static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] = -{ - { &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION }, - { &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, - { NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 }, -}; - -// Our clone of c_dfDIJoystick -// -static const DIDATAFORMAT _glfwDataFormat = -{ - sizeof(DIDATAFORMAT), - sizeof(DIOBJECTDATAFORMAT), - DIDFT_ABSAXIS, - sizeof(DIJOYSTATE), - sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT), - _glfwObjectDataFormats -}; - -// Returns a description fitting the specified XInput capabilities -// -static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic) -{ - switch (xic->SubType) - { - case XINPUT_DEVSUBTYPE_WHEEL: - return "XInput Wheel"; - case XINPUT_DEVSUBTYPE_ARCADE_STICK: - return "XInput Arcade Stick"; - case XINPUT_DEVSUBTYPE_FLIGHT_STICK: - return "XInput Flight Stick"; - case XINPUT_DEVSUBTYPE_DANCE_PAD: - return "XInput Dance Pad"; - case XINPUT_DEVSUBTYPE_GUITAR: - return "XInput Guitar"; - case XINPUT_DEVSUBTYPE_DRUM_KIT: - return "XInput Drum Kit"; - case XINPUT_DEVSUBTYPE_GAMEPAD: - { - if (xic->Flags & XINPUT_CAPS_WIRELESS) - return "Wireless Xbox 360 Controller"; - else - return "Xbox 360 Controller"; - } - } - - return "Unknown XInput Device"; -} - -// Lexically compare device objects -// -static int compareJoystickObjects(const void* first, const void* second) -{ - const _GLFWjoyobjectWin32* fo = first; - const _GLFWjoyobjectWin32* so = second; - - if (fo->type != so->type) - return fo->type - so->type; - - return fo->offset - so->offset; -} - -// Checks whether the specified device supports XInput -// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom -// -static GLFWbool supportsXInput(const GUID* guid) -{ - UINT i, count = 0; - RAWINPUTDEVICELIST* ridl; - GLFWbool result = GLFW_FALSE; - - if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0) - return GLFW_FALSE; - - ridl = calloc(count, sizeof(RAWINPUTDEVICELIST)); - - if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1) - { - free(ridl); - return GLFW_FALSE; - } - - for (i = 0; i < count; i++) - { - RID_DEVICE_INFO rdi; - char name[256]; - UINT size; - - if (ridl[i].dwType != RIM_TYPEHID) - continue; - - ZeroMemory(&rdi, sizeof(rdi)); - rdi.cbSize = sizeof(rdi); - size = sizeof(rdi); - - if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice, - RIDI_DEVICEINFO, - &rdi, &size) == -1) - { - continue; - } - - if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1) - continue; - - memset(name, 0, sizeof(name)); - size = sizeof(name); - - if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice, - RIDI_DEVICENAME, - name, &size) == -1) - { - break; - } - - name[sizeof(name) - 1] = '\0'; - if (strstr(name, "IG_")) - { - result = GLFW_TRUE; - break; - } - } - - free(ridl); - return result; -} - -// Frees all resources associated with the specified joystick -// -static void closeJoystick(_GLFWjoystick* js) -{ - if (js->win32.device) - { - IDirectInputDevice8_Unacquire(js->win32.device); - IDirectInputDevice8_Release(js->win32.device); - } - - _glfwFreeJoystick(js); - _glfwInputJoystick(_GLFW_JOYSTICK_ID(js), GLFW_DISCONNECTED); -} - -// DirectInput device object enumeration callback -// Insights gleaned from SDL2 -// -static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi, - void* user) -{ - _GLFWobjenumWin32* data = user; - _GLFWjoyobjectWin32* object = data->objects + data->objectCount; - - if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS) - { - DIPROPRANGE dipr; - - if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0) - object->offset = DIJOFS_SLIDER(data->sliderCount); - else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0) - object->offset = DIJOFS_X; - else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0) - object->offset = DIJOFS_Y; - else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0) - object->offset = DIJOFS_Z; - else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0) - object->offset = DIJOFS_RX; - else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0) - object->offset = DIJOFS_RY; - else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0) - object->offset = DIJOFS_RZ; - else - return DIENUM_CONTINUE; - - ZeroMemory(&dipr, sizeof(dipr)); - dipr.diph.dwSize = sizeof(dipr); - dipr.diph.dwHeaderSize = sizeof(dipr.diph); - dipr.diph.dwObj = doi->dwType; - dipr.diph.dwHow = DIPH_BYID; - dipr.lMin = -32768; - dipr.lMax = 32767; - - if (FAILED(IDirectInputDevice8_SetProperty(data->device, - DIPROP_RANGE, - &dipr.diph))) - { - return DIENUM_CONTINUE; - } - - if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0) - { - object->type = _GLFW_TYPE_SLIDER; - data->sliderCount++; - } - else - { - object->type = _GLFW_TYPE_AXIS; - data->axisCount++; - } - } - else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON) - { - object->offset = DIJOFS_BUTTON(data->buttonCount); - object->type = _GLFW_TYPE_BUTTON; - data->buttonCount++; - } - else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV) - { - object->offset = DIJOFS_POV(data->povCount); - object->type = _GLFW_TYPE_POV; - data->povCount++; - } - - data->objectCount++; - return DIENUM_CONTINUE; -} - -// DirectInput device enumeration callback -// -static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user) -{ - int jid = 0; - DIDEVCAPS dc; - DIPROPDWORD dipd; - IDirectInputDevice8* device; - _GLFWobjenumWin32 data; - _GLFWjoystick* js; - char name[256]; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - { - if (!_glfw.joysticks[jid].present) - continue; - if (memcmp(&_glfw.joysticks[jid].win32.guid, &di->guidInstance, sizeof(GUID)) == 0) - return DIENUM_CONTINUE; - } - - if (supportsXInput(&di->guidProduct)) - return DIENUM_CONTINUE; - - if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api, - &di->guidInstance, - &device, - NULL))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device"); - return DIENUM_CONTINUE; - } - - if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to set device data format"); - - IDirectInputDevice8_Release(device); - return DIENUM_CONTINUE; - } - - ZeroMemory(&dc, sizeof(dc)); - dc.dwSize = sizeof(dc); - - if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to query device capabilities"); - - IDirectInputDevice8_Release(device); - return DIENUM_CONTINUE; - } - - ZeroMemory(&dipd, sizeof(dipd)); - dipd.diph.dwSize = sizeof(dipd); - dipd.diph.dwHeaderSize = sizeof(dipd.diph); - dipd.diph.dwHow = DIPH_DEVICE; - dipd.dwData = DIPROPAXISMODE_ABS; - - if (FAILED(IDirectInputDevice8_SetProperty(device, - DIPROP_AXISMODE, - &dipd.diph))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to set device axis mode"); - - IDirectInputDevice8_Release(device); - return DIENUM_CONTINUE; - } - - memset(&data, 0, sizeof(data)); - data.device = device; - data.objects = calloc(dc.dwAxes + dc.dwButtons + dc.dwPOVs, - sizeof(_GLFWjoyobjectWin32)); - - if (FAILED(IDirectInputDevice8_EnumObjects(device, - deviceObjectCallback, - &data, - DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to enumerate device objects"); - - IDirectInputDevice8_Release(device); - free(data.objects); - return DIENUM_CONTINUE; - } - - qsort(data.objects, data.objectCount, - sizeof(_GLFWjoyobjectWin32), - compareJoystickObjects); - - if (!WideCharToMultiByte(CP_UTF8, 0, - di->tszInstanceName, -1, - name, sizeof(name), - NULL, NULL)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to convert joystick name to UTF-8"); - - IDirectInputDevice8_Release(device); - free(data.objects); - return DIENUM_STOP; - } - - js = _glfwAllocJoystick(name, - data.axisCount + data.sliderCount, - data.buttonCount, - data.povCount); - if (!js) - { - IDirectInputDevice8_Release(device); - free(data.objects); - return DIENUM_STOP; - } - - js->win32.device = device; - js->win32.guid = di->guidInstance; - js->win32.objects = data.objects; - js->win32.objectCount = data.objectCount; - - _glfwInputJoystick(_GLFW_JOYSTICK_ID(js), GLFW_CONNECTED); - return DIENUM_CONTINUE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -// Initialize joystick interface -// -void _glfwInitJoysticksWin32(void) -{ - if (_glfw.win32.dinput8.instance) - { - if (FAILED(DirectInput8Create(GetModuleHandle(NULL), - DIRECTINPUT_VERSION, - &IID_IDirectInput8W, - (void**) &_glfw.win32.dinput8.api, - NULL))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Win32: Failed to create interface"); - } - } - - _glfwDetectJoystickConnectionWin32(); -} - -// Close all opened joystick handles -// -void _glfwTerminateJoysticksWin32(void) -{ - int jid; - - for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++) - closeJoystick(_glfw.joysticks + jid); - - if (_glfw.win32.dinput8.api) - IDirectInput8_Release(_glfw.win32.dinput8.api); -} - -// Checks for new joysticks after DBT_DEVICEARRIVAL -// -void _glfwDetectJoystickConnectionWin32(void) -{ - if (_glfw.win32.xinput.instance) - { - DWORD index; - - for (index = 0; index < XUSER_MAX_COUNT; index++) - { - int jid; - XINPUT_CAPABILITIES xic; - _GLFWjoystick* js; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - { - if (_glfw.joysticks[jid].present && - _glfw.joysticks[jid].win32.device == NULL && - _glfw.joysticks[jid].win32.index == index) - { - break; - } - } - - if (jid <= GLFW_JOYSTICK_LAST) - continue; - - if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS) - continue; - - js = _glfwAllocJoystick(getDeviceDescription(&xic), 6, 10, 1); - if (!js) - continue; - - js->win32.index = index; - - _glfwInputJoystick(_GLFW_JOYSTICK_ID(js), GLFW_CONNECTED); - } - } - - if (_glfw.win32.dinput8.api) - { - if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api, - DI8DEVCLASS_GAMECTRL, - deviceCallback, - NULL, - DIEDFL_ALLDEVICES))) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "Failed to enumerate DirectInput8 devices"); - return; - } - } -} - -// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE -// -void _glfwDetectJoystickDisconnectionWin32(void) -{ - int jid; - - for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++) - { - if (_glfw.joysticks[jid].present) - _glfwPlatformPollJoystick(jid, _GLFW_POLL_PRESENCE); - } -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - -int _glfwPlatformPollJoystick(int jid, int mode) -{ - _GLFWjoystick* js = _glfw.joysticks + jid; - - if (js->win32.device) - { - int i, ai = 0, bi = 0, pi = 0; - HRESULT result; - DIJOYSTATE state; - - IDirectInputDevice8_Poll(js->win32.device); - result = IDirectInputDevice8_GetDeviceState(js->win32.device, - sizeof(state), - &state); - if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST) - { - IDirectInputDevice8_Acquire(js->win32.device); - IDirectInputDevice8_Poll(js->win32.device); - result = IDirectInputDevice8_GetDeviceState(js->win32.device, - sizeof(state), - &state); - } - - if (FAILED(result)) - { - closeJoystick(js); - return GLFW_FALSE; - } - - if (mode == _GLFW_POLL_PRESENCE) - return GLFW_TRUE; - - for (i = 0; i < js->win32.objectCount; i++) - { - const void* data = (char*) &state + js->win32.objects[i].offset; - - switch (js->win32.objects[i].type) - { - case _GLFW_TYPE_AXIS: - case _GLFW_TYPE_SLIDER: - { - const float value = (*((LONG*) data) + 0.5f) / 32767.5f; - _glfwInputJoystickAxis(jid, ai, value); - ai++; - break; - } - - case _GLFW_TYPE_BUTTON: - { - const char value = (*((BYTE*) data) & 0x80) != 0; - _glfwInputJoystickButton(jid, bi, value); - bi++; - break; - } - - case _GLFW_TYPE_POV: - { - 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 - }; - - // Screams of horror are appropriate at this point - int state = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES); - if (state < 0 || state > 8) - state = 8; - - _glfwInputJoystickHat(jid, pi, states[state]); - pi++; - break; - } - } - } - } - else - { - int i, dpad = 0; - DWORD result; - XINPUT_STATE xis; - float axes[6] = { 0.f, 0.f, 0.f, 0.f, -1.f, -1.f }; - const WORD buttons[14] = - { - XINPUT_GAMEPAD_A, - XINPUT_GAMEPAD_B, - XINPUT_GAMEPAD_X, - XINPUT_GAMEPAD_Y, - XINPUT_GAMEPAD_LEFT_SHOULDER, - XINPUT_GAMEPAD_RIGHT_SHOULDER, - XINPUT_GAMEPAD_BACK, - XINPUT_GAMEPAD_START, - XINPUT_GAMEPAD_LEFT_THUMB, - XINPUT_GAMEPAD_RIGHT_THUMB - }; - - result = XInputGetState(js->win32.index, &xis); - if (result != ERROR_SUCCESS) - { - if (result == ERROR_DEVICE_NOT_CONNECTED) - closeJoystick(js); - - return GLFW_FALSE; - } - - if (mode == _GLFW_POLL_PRESENCE) - return GLFW_TRUE; - - if ((float) xis.Gamepad.sThumbLX * xis.Gamepad.sThumbLX + - (float) xis.Gamepad.sThumbLY * xis.Gamepad.sThumbLY > - (float) XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE * - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) - { - axes[0] = (xis.Gamepad.sThumbLX + 0.5f) / 32767.f; - axes[1] = (xis.Gamepad.sThumbLY + 0.5f) / 32767.f; - } - - if ((float) xis.Gamepad.sThumbRX * xis.Gamepad.sThumbRX + - (float) xis.Gamepad.sThumbRY * xis.Gamepad.sThumbRY > - (float) XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE * - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) - { - axes[2] = (xis.Gamepad.sThumbRX + 0.5f) / 32767.f; - axes[3] = (xis.Gamepad.sThumbRY + 0.5f) / 32767.f; - } - - if (xis.Gamepad.bLeftTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) - axes[4] = xis.Gamepad.bLeftTrigger / 127.5f - 1.f; - - if (xis.Gamepad.bRightTrigger > XINPUT_GAMEPAD_TRIGGER_THRESHOLD) - axes[5] = xis.Gamepad.bRightTrigger / 127.5f - 1.f; - - for (i = 0; i < 6; i++) - _glfwInputJoystickAxis(jid, i, axes[i]); - - for (i = 0; i < 10; i++) - { - const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0; - _glfwInputJoystickButton(jid, i, value); - } - - if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP) - dpad |= GLFW_HAT_UP; - if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) - dpad |= GLFW_HAT_RIGHT; - if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN) - dpad |= GLFW_HAT_DOWN; - if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) - dpad |= GLFW_HAT_LEFT; - - _glfwInputJoystickHat(jid, 0, dpad); - } - - return GLFW_TRUE; -} - diff --git a/src/win32_joystick.h b/src/win32_joystick.h deleted file mode 100644 index 8070a42590..0000000000 --- a/src/win32_joystick.h +++ /dev/null @@ -1,59 +0,0 @@ -//======================================================================== -// GLFW 3.3 Win32 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2006-2016 Camilla Löwy -// -// 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. -// -//======================================================================== - -#ifndef _glfw3_win32_joystick_h_ -#define _glfw3_win32_joystick_h_ - -#define _GLFW_PLATFORM_JOYSTICK_STATE _GLFWjoystickWin32 win32 -#define _GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE int dummy - - -// Joystick element (axis, button or slider) -// -typedef struct _GLFWjoyobjectWin32 -{ - int offset; - int type; -} _GLFWjoyobjectWin32; - -// Win32-specific per-joystick data -// -typedef struct _GLFWjoystickWin32 -{ - _GLFWjoyobjectWin32* objects; - int objectCount; - IDirectInputDevice8W* device; - DWORD index; - GUID guid; -} _GLFWjoystickWin32; - - -void _glfwInitJoysticksWin32(void); -void _glfwTerminateJoysticksWin32(void); -void _glfwDetectJoystickConnectionWin32(void); -void _glfwDetectJoystickDisconnectionWin32(void); - -#endif // _glfw3_win32_joystick_h_