mirror of
https://github.com/glfw/glfw.git
synced 2025-10-05 06:06:36 +00:00
Merge d3eaf9a9fa
into ca084d40c1
This commit is contained in:
commit
cf2dab9b27
@ -1140,6 +1140,42 @@ typedef void (* GLFWmonitorfun)(GLFWmonitor*,int);
|
||||
*/
|
||||
typedef void (* GLFWjoystickfun)(int,int);
|
||||
|
||||
/*! @brief The function signature for joystick button callbacks.
|
||||
*
|
||||
* This is the function signature for joystick button callback
|
||||
* functions.
|
||||
*
|
||||
* @param[in] joy The joystick that had a button pressed or released.
|
||||
* @param[in] button The button that was pressed or released.
|
||||
* @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||
*
|
||||
* @sa @ref joystick_event
|
||||
* @sa glfwSetJoystickButtonCallback
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef void (* GLFWjoystickbuttonfun)(int,int,int);
|
||||
|
||||
/*! @brief The function signature for joystick axis callbacks.
|
||||
*
|
||||
* This is the function signature for joystick axis callback
|
||||
* functions.
|
||||
*
|
||||
* @param[in] joy The joystick that had an axis moved.
|
||||
* @param[in] axis The axis that was moved.
|
||||
* @param[in] value The axis value.
|
||||
*
|
||||
* @sa @ref joystick_event
|
||||
* @sa glfwSetJoystickAxisCallback
|
||||
*
|
||||
* @since Added in version 3.2.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef void (* GLFWjoystickaxisfun)(int,int,float);
|
||||
|
||||
/*! @brief Video mode type.
|
||||
*
|
||||
* This describes a single video mode.
|
||||
@ -3724,6 +3760,50 @@ GLFWAPI const char* glfwGetJoystickName(int joy);
|
||||
*/
|
||||
GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun);
|
||||
|
||||
/*! @brief Sets the joystick button callback.
|
||||
*
|
||||
* This function sets the joystick button callback, or removes the currently
|
||||
* set callback. This is called when a joystick button is pressed or released.
|
||||
*
|
||||
* @param[in] cbfun 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).
|
||||
*
|
||||
* @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 GLFWjoystickbuttonfun glfwSetJoystickButtonCallback(GLFWjoystickbuttonfun cbfun);
|
||||
|
||||
/*! @brief Sets the joystick axis callback.
|
||||
*
|
||||
* This function sets the joystick axis callback, or removes the currently
|
||||
* set callback. This is called when a joystick axis is moved.
|
||||
*
|
||||
* @param[in] cbfun 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).
|
||||
*
|
||||
* @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 GLFWjoystickaxisfun glfwSetJoystickAxisCallback(GLFWjoystickaxisfun cbfun);
|
||||
|
||||
/*! @brief Sets the clipboard to the specified string.
|
||||
*
|
||||
* This function sets the system clipboard to the specified, UTF-8 encoded
|
||||
|
@ -37,7 +37,6 @@
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
|
||||
|
||||
|
||||
// Joystick element information
|
||||
//
|
||||
typedef struct _GLFWjoyelementNS
|
||||
@ -193,75 +192,96 @@ static void removeJoystick(_GLFWjoystickNS* js)
|
||||
_glfwInputJoystickChange(js - _glfw.ns_js, GLFW_DISCONNECTED);
|
||||
}
|
||||
|
||||
// Polls for joystick axis events and updates GLFW state
|
||||
// Input value callback
|
||||
//
|
||||
static GLFWbool pollJoystickAxisEvents(_GLFWjoystickNS* js)
|
||||
static void inputValueCallback (void* context,
|
||||
IOReturn valueResult,
|
||||
void* deviceRef,
|
||||
IOHIDValueRef valueRef)
|
||||
{
|
||||
_GLFWjoystickNS* js;
|
||||
CFIndex i;
|
||||
int buttonIndex = 0;
|
||||
|
||||
if (kIOReturnSuccess != valueResult)
|
||||
return;
|
||||
|
||||
js = (_GLFWjoystickNS*)context;
|
||||
if (!js)
|
||||
return;
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
return;
|
||||
|
||||
IOHIDElementRef elementRef = IOHIDValueGetElement(valueRef);
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->axisElements); i++)
|
||||
{
|
||||
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->axisElements, i);
|
||||
|
||||
long value = getElementValue(js, axis);
|
||||
long readScale = axis->maxReport - axis->minReport;
|
||||
if (elementRef == axis->elementRef)
|
||||
{
|
||||
long value = getElementValue(js, axis);
|
||||
long readScale = axis->maxReport - axis->minReport;
|
||||
|
||||
if (readScale == 0)
|
||||
js->axes[i] = value;
|
||||
else
|
||||
js->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;
|
||||
if (readScale == 0)
|
||||
js->axes[i] = value;
|
||||
else
|
||||
js->axes[i] = (2.f * (value - axis->minReport) / readScale) - 1.f;
|
||||
|
||||
_glfwInputJoystickAxisMoved(js-_glfw.ns_js,i,js->axes[i]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
return GLFW_TRUE;
|
||||
}
|
||||
|
||||
// Polls for joystick button events and updates GLFW state
|
||||
//
|
||||
static GLFWbool pollJoystickButtonEvents(_GLFWjoystickNS* js)
|
||||
{
|
||||
CFIndex i;
|
||||
int buttonIndex = 0;
|
||||
|
||||
if (!js->present)
|
||||
return GLFW_FALSE;
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->buttonElements); i++)
|
||||
for (i = 0; i < CFArrayGetCount(js->buttonElements); i++, buttonIndex++)
|
||||
{
|
||||
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->buttonElements, i);
|
||||
|
||||
if (getElementValue(js, button))
|
||||
js->buttons[buttonIndex++] = GLFW_PRESS;
|
||||
else
|
||||
js->buttons[buttonIndex++] = GLFW_RELEASE;
|
||||
if (elementRef == button->elementRef)
|
||||
{
|
||||
if (getElementValue(js, button))
|
||||
js->buttons[buttonIndex] = GLFW_PRESS;
|
||||
else
|
||||
js->buttons[buttonIndex] = GLFW_RELEASE;
|
||||
|
||||
_glfwInputJoystickButtonState(js-_glfw.ns_js,buttonIndex,js->buttons[buttonIndex]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < CFArrayGetCount(js->hatElements); i++)
|
||||
for (i = 0; i < CFArrayGetCount(js->hatElements); i++, buttonIndex += 4)
|
||||
{
|
||||
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
|
||||
CFArrayGetValueAtIndex(js->hatElements, i);
|
||||
|
||||
// Bit fields of button presses for each direction, including nil
|
||||
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||
|
||||
long j, value = getElementValue(js, hat);
|
||||
if (value < 0 || value > 8)
|
||||
value = 8;
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
if (elementRef == hat->elementRef)
|
||||
{
|
||||
if (directions[value] & (1 << j))
|
||||
js->buttons[buttonIndex++] = GLFW_PRESS;
|
||||
else
|
||||
js->buttons[buttonIndex++] = GLFW_RELEASE;
|
||||
}
|
||||
}
|
||||
// Bit fields of button presses for each direction, including nil
|
||||
const int directions[9] = { 1, 3, 2, 6, 4, 12, 8, 9, 0 };
|
||||
|
||||
return GLFW_TRUE;
|
||||
long j, value = getElementValue(js, hat);
|
||||
if (value < 0 || value > 8)
|
||||
value = 8;
|
||||
|
||||
for (j = 0; j < 4; j++)
|
||||
{
|
||||
const unsigned char oldValue = js->buttons[buttonIndex+j];
|
||||
|
||||
if (directions[value] & (1 << j))
|
||||
js->buttons[buttonIndex+j] = GLFW_PRESS;
|
||||
else
|
||||
js->buttons[buttonIndex+j] = GLFW_RELEASE;
|
||||
|
||||
// Since we're treating hat switches as buttons, only send events for
|
||||
// the values that have actually changed.
|
||||
if (oldValue != js->buttons[buttonIndex+j])
|
||||
_glfwInputJoystickButtonState(js-_glfw.ns_js,buttonIndex+j,js->buttons[buttonIndex+j]);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Callback for user-initiated joystick addition
|
||||
@ -324,6 +344,10 @@ static void matchCallback(void* context,
|
||||
js->buttons = calloc(CFArrayGetCount(js->buttonElements) +
|
||||
CFArrayGetCount(js->hatElements) * 4, 1);
|
||||
|
||||
IOHIDDeviceRegisterInputValueCallback(deviceRef,
|
||||
inputValueCallback,
|
||||
(void*)js);
|
||||
|
||||
_glfwInputJoystickChange(joy, GLFW_CONNECTED);
|
||||
}
|
||||
|
||||
@ -399,7 +423,6 @@ void _glfwInitJoysticksNS(void)
|
||||
|
||||
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
|
||||
kIOHIDOptionsTypeNone);
|
||||
|
||||
matchingCFArrayRef = CFArrayCreateMutable(kCFAllocatorDefault,
|
||||
0,
|
||||
&kCFTypeArrayCallBacks);
|
||||
@ -482,7 +505,8 @@ int _glfwPlatformJoystickPresent(int joy)
|
||||
const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
|
||||
{
|
||||
_GLFWjoystickNS* js = _glfw.ns_js + joy;
|
||||
if (!pollJoystickAxisEvents(js))
|
||||
|
||||
if (!js->present)
|
||||
return NULL;
|
||||
|
||||
*count = (int) CFArrayGetCount(js->axisElements);
|
||||
@ -492,7 +516,8 @@ const float* _glfwPlatformGetJoystickAxes(int joy, int* count)
|
||||
const unsigned char* _glfwPlatformGetJoystickButtons(int joy, int* count)
|
||||
{
|
||||
_GLFWjoystickNS* js = _glfw.ns_js + joy;
|
||||
if (!pollJoystickButtonEvents(js))
|
||||
|
||||
if (!js->present)
|
||||
return NULL;
|
||||
|
||||
*count = (int) CFArrayGetCount(js->buttonElements) +
|
||||
|
26
src/input.c
26
src/input.c
@ -130,6 +130,18 @@ void _glfwInputJoystickChange(int joy, int event)
|
||||
_glfw.callbacks.joystick(joy, event);
|
||||
}
|
||||
|
||||
void _glfwInputJoystickButtonState(int joy, int button, int action)
|
||||
{
|
||||
if (_glfw.callbacks.joystick_button)
|
||||
_glfw.callbacks.joystick_button(joy, button, action);
|
||||
}
|
||||
|
||||
void _glfwInputJoystickAxisMoved(int joy, int axis, float value)
|
||||
{
|
||||
if (_glfw.callbacks.joystick_axis)
|
||||
_glfw.callbacks.joystick_axis(joy, axis, value);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW internal API //////
|
||||
@ -618,6 +630,20 @@ GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWjoystickbuttonfun glfwSetJoystickButtonCallback(GLFWjoystickbuttonfun cbfun)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick_button, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWjoystickaxisfun glfwSetJoystickAxisCallback(GLFWjoystickaxisfun cbfun)
|
||||
{
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(_glfw.callbacks.joystick_axis, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
|
@ -469,8 +469,10 @@ struct _GLFWlibrary
|
||||
} vk;
|
||||
|
||||
struct {
|
||||
GLFWmonitorfun monitor;
|
||||
GLFWjoystickfun joystick;
|
||||
GLFWmonitorfun monitor;
|
||||
GLFWjoystickfun joystick;
|
||||
GLFWjoystickbuttonfun joystick_button;
|
||||
GLFWjoystickaxisfun joystick_axis;
|
||||
} callbacks;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
@ -967,6 +969,22 @@ void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
||||
*/
|
||||
void _glfwInputJoystickChange(int joy, int event);
|
||||
|
||||
/*! @brief Notifies shared code of a joystick button pressed/release action.
|
||||
* @param[in] joy The joystick that had a button pressed or released.
|
||||
* @param[in] button The button that was pressed or released.
|
||||
* @param[in] action One of `GLFW_PRESS` or `GLFW_RELEASE`.
|
||||
* @ingroup event
|
||||
*/
|
||||
void _glfwInputJoystickButtonState(int joy, int button, int action);
|
||||
|
||||
/*! @brief Notifies shared code of joystick axis motion.
|
||||
* @param[in] joy The joystick that had an axis moved.
|
||||
* @param[in] axis The axis that was moved.
|
||||
* @param[in] value The current position of the axis.
|
||||
* @ingroup event
|
||||
*/
|
||||
void _glfwInputJoystickAxisMoved(int joy, int axis, float value);
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Utility functions
|
||||
|
@ -482,6 +482,18 @@ static void joystick_callback(int joy, int event)
|
||||
}
|
||||
}
|
||||
|
||||
static void joystick_button_callback(int joy, int button, int action)
|
||||
{
|
||||
printf("%08x at %0.3f: Joystick %i button %i was %s\n",
|
||||
counter++, glfwGetTime(), joy, button, get_action_name(action));
|
||||
}
|
||||
|
||||
static void joystick_axis_callback(int joy, int axis, float value)
|
||||
{
|
||||
printf("%08x at %0.3f: Joystick %i axis %i was moved to %f\n",
|
||||
counter++, glfwGetTime(), joy, axis, value);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Slot* slots;
|
||||
@ -499,6 +511,8 @@ int main(int argc, char** argv)
|
||||
|
||||
glfwSetMonitorCallback(monitor_callback);
|
||||
glfwSetJoystickCallback(joystick_callback);
|
||||
glfwSetJoystickButtonCallback(joystick_button_callback);
|
||||
glfwSetJoystickAxisCallback(joystick_axis_callback);
|
||||
|
||||
while ((ch = getopt(argc, argv, "hfn:")) != -1)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user