Synchronize joystick events between all ports

Generate wxJoystickEvent with the same fields under all platforms by
making the Linux and macOS versions follow MSW convention of using
"1 << N" for the changed button.

Add GetButtonOrdinal() accessor which can be used to retrieve just N.

Closes #18233.
This commit is contained in:
Mick Phillips
2018-11-05 16:37:53 +00:00
committed by Vadim Zeitlin
parent cf980cf5e3
commit 291a880d0c
8 changed files with 57 additions and 25 deletions

View File

@@ -15,6 +15,7 @@
#include "wx/cpp.h" #include "wx/cpp.h"
#include "wx/object.h" #include "wx/object.h"
#include "wx/clntdata.h" #include "wx/clntdata.h"
#include "wx/math.h"
#if wxUSE_GUI #if wxUSE_GUI
#include "wx/gdicmn.h" #include "wx/gdicmn.h"
@@ -2760,6 +2761,7 @@ public:
int GetZPosition() const { return m_zPosition; } int GetZPosition() const { return m_zPosition; }
int GetButtonState() const { return m_buttonState; } int GetButtonState() const { return m_buttonState; }
int GetButtonChange() const { return m_buttonChange; } int GetButtonChange() const { return m_buttonChange; }
int GetButtonOrdinal() const { return wxCTZ(m_buttonChange); }
int GetJoystick() const { return m_joyStick; } int GetJoystick() const { return m_joyStick; }
void SetJoystick(int stick) { m_joyStick = stick; } void SetJoystick(int stick) { m_joyStick = stick; }

View File

@@ -181,4 +181,14 @@ inline double wxRadToDeg(double rad) { return (rad * 180.0) / M_PI; }
/* Compute the greatest common divisor of two positive integers */ /* Compute the greatest common divisor of two positive integers */
WXDLLIMPEXP_BASE unsigned int wxGCD(unsigned int u, unsigned int v); WXDLLIMPEXP_BASE unsigned int wxGCD(unsigned int u, unsigned int v);
#ifdef __cplusplus
/* Count trailing zeros
Returns the number of trailing zeros in unsigned input x.
@since 3.1.2
*/
WXDLLIMPEXP_BASE unsigned int wxCTZ(unsigned x);
#endif
#endif /* _WX_MATH_H_ */ #endif /* _WX_MATH_H_ */

View File

@@ -1741,10 +1741,24 @@ public:
/** /**
Returns the identifier of the button changing state. Returns the identifier of the button changing state.
This is a @c wxJOY_BUTTONn identifier, where @c n is one of 1, 2, 3, 4. The return value is @code 1 << n @endcode where @c n is the index of the
button changing state.
Note that for @c n equal to 1, 2, 3 or 4 there are predefined @c wxJOY_BUTTONn
constants which can be used for more clarity, however these constants are not
defined for the buttons beyond the first four.
and whose values were 1 << n. To support more than four buttons, the return value
is now defined as 1 << n.
*/ */
int GetButtonChange() const; int GetButtonChange() const;
/**
Returns the 0-indexed ordinal of the button changing state.
@since 3.1.2.
*/
int GetButtonOrdinal() const;
/** /**
Returns the down state of the buttons. Returns the down state of the buttons.

View File

@@ -159,7 +159,7 @@ void MyCanvas::OnJoystickEvent(wxJoystickEvent& event)
#if wxUSE_STATUSBAR #if wxUSE_STATUSBAR
wxString buf; wxString buf;
if (event.ButtonDown()) if (event.ButtonDown())
buf.Printf("Joystick (%ld, %ld) #%i Fire!", xpos, ypos, event.GetButtonChange()); buf.Printf("Joystick (%ld, %ld) #%i Fire!", xpos, ypos, event.GetButtonOrdinal());
else else
buf.Printf("Joystick (%ld, %ld) ", xpos, ypos); buf.Printf("Joystick (%ld, %ld) ", xpos, ypos);

View File

@@ -19,6 +19,8 @@
// For compilers that support precompilation, includes "wx.h". // For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h" #include "wx/wxprec.h"
#include "wx/debug.h"
#ifdef __BORLANDC__ #ifdef __BORLANDC__
#pragma hdrstop #pragma hdrstop
#endif #endif
@@ -1015,6 +1017,27 @@ unsigned int wxGCD(unsigned int u, unsigned int v)
return u << shift; return u << shift;
} }
// ----------------------------------------------------------------------------
// wxCTZ
// Count trailing zeros. Use optimised builtin where available.
// ----------------------------------------------------------------------------
unsigned int wxCTZ(unsigned x)
{
wxCHECK_MSG(x > 0, 0, "Undefined for x == 0.");
#ifdef __GNUC__
return __builtin_ctz(x);
#else
int n;
n = 1;
if ((x & 0x0000FFFF) == 0) {n = n +16; x = x >>16;}
if ((x & 0x000000FF) == 0) {n = n + 8; x = x >> 8;}
if ((x & 0x0000000F) == 0) {n = n + 4; x = x >> 4;}
if ((x & 0x00000003) == 0) {n = n + 2; x = x >> 2;}
return n - (x & 1);
#endif
}
#endif // wxUSE_BASE #endif // wxUSE_BASE
// ============================================================================ // ============================================================================

View File

@@ -37,23 +37,6 @@
#include <regstr.h> #include <regstr.h>
// Use optimised count trailing zeros where available.
static int wxCtz(unsigned x)
{
wxCHECK_MSG(x > 0, 0, "Undefined for x == 0.");
#ifdef __GNUC__
return __builtin_ctz(x);
#else
int n;
n = 1;
if ((x & 0x0000FFFF) == 0) {n = n +16; x = x >>16;}
if ((x & 0x000000FF) == 0) {n = n + 8; x = x >> 8;}
if ((x & 0x0000000F) == 0) {n = n + 4; x = x >> 4;}
if ((x & 0x00000003) == 0) {n = n + 2; x = x >> 2;}
return n - (x & 1);
#endif
}
enum { enum {
wxJS_AXIS_X = 0, wxJS_AXIS_X = 0,
@@ -90,7 +73,7 @@ public:
private: private:
void SendEvent(wxEventType type, long ts, int change = 0); void SendEvent(wxEventType type, long ts, int change = 0);
int m_joystick; int m_joystick;
UINT m_buttons; int m_buttons;
wxWindow* m_catchwin; wxWindow* m_catchwin;
int m_polling; int m_polling;
JOYINFO m_joyInfo; JOYINFO m_joyInfo;
@@ -141,9 +124,9 @@ void* wxJoystickThread::Entry()
// "Current button number that is pressed.", but it turns out // "Current button number that is pressed.", but it turns out
// it is the *total* number of buttons pressed. // it is the *total* number of buttons pressed.
if (deltaUp) if (deltaUp)
SendEvent(wxEVT_JOY_BUTTON_UP, ts, wxCtz(deltaUp)+1); SendEvent(wxEVT_JOY_BUTTON_UP, ts, deltaUp);
if (deltaDown) if (deltaDown)
SendEvent(wxEVT_JOY_BUTTON_DOWN, ts, wxCtz(deltaDown)+1); SendEvent(wxEVT_JOY_BUTTON_DOWN, ts, deltaDown);
if ((m_joyInfo.wXpos != m_lastJoyInfo.wXpos) || if ((m_joyInfo.wXpos != m_lastJoyInfo.wXpos) ||
(m_joyInfo.wYpos != m_lastJoyInfo.wYpos) || (m_joyInfo.wYpos != m_lastJoyInfo.wYpos) ||

View File

@@ -872,7 +872,7 @@ void* wxJoystickThread::Entry()
wxevent.SetEventType(wxEVT_JOY_BUTTON_UP); wxevent.SetEventType(wxEVT_JOY_BUTTON_UP);
} }
wxevent.SetButtonChange(nIndex+1); wxevent.SetButtonChange(1 << nIndex);
} }
else if (nIndex == wxJS_AXIS_X) else if (nIndex == wxJS_AXIS_X)
{ {

View File

@@ -181,12 +181,12 @@ void* wxJoystickThread::Entry()
if (j_evt.value) if (j_evt.value)
{ {
m_buttons |= (1 << j_evt.number); m_buttons |= (1 << j_evt.number);
SendEvent(wxEVT_JOY_BUTTON_DOWN, j_evt.time, j_evt.number); SendEvent(wxEVT_JOY_BUTTON_DOWN, j_evt.time, 1 << j_evt.number);
} }
else else
{ {
m_buttons &= ~(1 << j_evt.number); m_buttons &= ~(1 << j_evt.number);
SendEvent(wxEVT_JOY_BUTTON_UP, j_evt.time, j_evt.number); SendEvent(wxEVT_JOY_BUTTON_UP, j_evt.time, 1 << j_evt.number);
} }
} }
} }