From 01101e2da6f4493ce8cfcf4d9509163b9c264d58 Mon Sep 17 00:00:00 2001
From: Vadim Zeitlin <vadim@wxwidgets.org>
Date: Sun, 29 Jul 2007 01:04:33 +0000
Subject: [PATCH] added support for 2 extra mouse buttons (patch 1757630)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@47802 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
---
 docs/changes.txt           |  1 +
 docs/latex/wx/mouseevt.tex | 81 ++++++++++++++++++++++++++++++++++++--
 include/wx/event.h         | 39 ++++++++++++++++--
 include/wx/utils.h         |  7 ++++
 src/common/event.cpp       | 53 ++++++++++++++++++++++---
 src/msw/window.cpp         | 30 +++++++++++++-
 6 files changed, 198 insertions(+), 13 deletions(-)

diff --git a/docs/changes.txt b/docs/changes.txt
index 5749e28c8e..6a61677bd0 100644
--- a/docs/changes.txt
+++ b/docs/changes.txt
@@ -150,6 +150,7 @@ All (GUI):
 - Support wxAPPLY and wxCLOSE in CreateStdDialogButtonSizer() (Marcin Wojdyr)
 - Show standard options in wxCmdLineParser usage message (Francesco Montorsi)
 - Added wxRect::operator+ (union) and * (intersection) (bdonner)
+- Added support for two auxiliary mouse buttons to wxMouseEvent (Chris Weiland)
 
 wxGTK:
 
diff --git a/docs/latex/wx/mouseevt.tex b/docs/latex/wx/mouseevt.tex
index 7991cbb652..63b91473f3 100644
--- a/docs/latex/wx/mouseevt.tex
+++ b/docs/latex/wx/mouseevt.tex
@@ -5,9 +5,12 @@ they include mouse buttons press and release events and mouse move events.
 
 All mouse events involving the buttons use {\tt wxMOUSE\_BTN\_LEFT} for the
 left mouse button, {\tt wxMOUSE\_BTN\_MIDDLE} for the middle one and
-{\tt wxMOUSE\_BTN\_RIGHT} for the right one. Note that not all mice have a
-middle button so a portable application should avoid relying on the events from
-it.
+{\tt wxMOUSE\_BTN\_RIGHT} for the right one. And if the system supports more
+buttons, the \texttt{wxMOUSE\_BTN\_AUX1} and \texttt{wxMOUSE\_BTN\_AUX2} events
+can also be generated. Note that not all mice have even a middle button so a
+portable application should avoid relying on the events from it (but the right
+button click can be emulated using the left mouse button with the control key
+under Mac platforms with a single button mouse).
 
 For the \texttt{wxEVT\_ENTER\_WINDOW} and \texttt{wxEVT\_LEAVE\_WINDOW} events
 purposes, the mouse is considered to be inside the window if it is in the
@@ -66,6 +69,12 @@ wouldn't get the focus.}
 \twocolitem{{\bf EVT\_RIGHT\_DOWN(func)}}{Process a wxEVT\_RIGHT\_DOWN event.}
 \twocolitem{{\bf EVT\_RIGHT\_UP(func)}}{Process a wxEVT\_RIGHT\_UP event.}
 \twocolitem{{\bf EVT\_RIGHT\_DCLICK(func)}}{Process a wxEVT\_RIGHT\_DCLICK event.}
+\twocolitem{{\bf EVT\_MOUSE\_AUX1\_DOWN(func)}}{Process a wxEVT\_MOUSE\_AUX1\_DOWN event.}
+\twocolitem{{\bf EVT\_MOUSE\_AUX1\_UP(func)}}{Process a wxEVT\_MOUSE\_AUX1\_UP event.}
+\twocolitem{{\bf EVT\_MOUSE\_AUX1\_DCLICK(func)}}{Process a wxEVT\_MOUSE\_AUX1\_DCLICK event.}
+\twocolitem{{\bf EVT\_MOUSE\_AUX2\_DOWN(func)}}{Process a wxEVT\_MOUSE\_AUX2\_DOWN event.}
+\twocolitem{{\bf EVT\_MOUSE\_AUX2\_UP(func)}}{Process a wxEVT\_MOUSE\_AUX2\_UP event.}
+\twocolitem{{\bf EVT\_MOUSE\_AUX2\_DCLICK(func)}}{Process a wxEVT\_MOUSE\_AUX2\_DCLICK event.}
 \twocolitem{{\bf EVT\_MOTION(func)}}{Process a wxEVT\_MOTION event.}
 \twocolitem{{\bf EVT\_ENTER\_WINDOW(func)}}{Process a wxEVT\_ENTER\_WINDOW event.}
 \twocolitem{{\bf EVT\_LEAVE\_WINDOW(func)}}{Process a wxEVT\_LEAVE\_WINDOW event.}
@@ -181,6 +190,12 @@ Constructor. Valid event types are:
 \item {\bf wxEVT\_RIGHT\_DOWN}
 \item {\bf wxEVT\_RIGHT\_UP}
 \item {\bf wxEVT\_RIGHT\_DCLICK}
+\item {\bf wxEVT\_MOUSE\_AUX1\_DOWN}
+\item {\bf wxEVT\_MOUSE\_AUX1\_UP}
+\item {\bf wxEVT\_MOUSE\_AUX1\_DCLICK}
+\item {\bf wxEVT\_MOUSE\_AUX2\_DOWN}
+\item {\bf wxEVT\_MOUSE\_AUX2\_UP}
+\item {\bf wxEVT\_MOUSE\_AUX2\_DCLICK}
 \item {\bf wxEVT\_MOTION}
 \item {\bf wxEVT\_MOUSEWHEEL}
 \end{itemize}
@@ -193,6 +208,64 @@ Constructor. Valid event types are:
 Returns true if the Alt key was down at the time of the event.
 
 
+\membersection{wxMouseEvent::Aux1DClick}\label{wxmouseeventaux1dclick}
+
+\constfunc{bool}{Aux1DClick}{\void}
+
+Returns true if the event was a first extra button double click.
+
+
+\membersection{wxMouseEvent::Aux1Down}\label{wxmouseeventaux1down}
+
+\constfunc{bool}{Aux1Down}{\void}
+
+Returns true if the first extra button mouse button changed to down.
+
+
+\membersection{wxMouseEvent::Aux1IsDown}\label{wxmouseeventaux1isdown}
+
+\constfunc{bool}{Aux1IsDown}{\void}
+
+Returns true if the first extra button mouse button is currently down, independent
+of the current event type.
+
+
+\membersection{wxMouseEvent::Aux1Up}\label{wxmouseeventaux1up}
+
+\constfunc{bool}{Aux1Up}{\void}
+
+Returns true if the first extra button mouse button changed to up.
+
+
+\membersection{wxMouseEvent::Aux2DClick}\label{wxmouseeventaux2dclick}
+
+\constfunc{bool}{Aux2DClick}{\void}
+
+Returns true if the event was a second extra button double click.
+
+
+\membersection{wxMouseEvent::Aux2Down}\label{wxmouseeventaux2down}
+
+\constfunc{bool}{Aux2Down}{\void}
+
+Returns true if the second extra button mouse button changed to down.
+
+
+\membersection{wxMouseEvent::Aux2IsDown}\label{wxmouseeventaux2isdown}
+
+\constfunc{bool}{Aux2IsDown}{\void}
+
+Returns true if the second extra button mouse button is currently down, independent
+of the current event type.
+
+
+\membersection{wxMouseEvent::Aux2Up}\label{wxmouseeventaux2up}
+
+\constfunc{bool}{Aux2Up}{\void}
+
+Returns true if the second extra button mouse button changed to up.
+
+
 \membersection{wxMouseEvent::Button}\label{wxmouseeventbutton}
 
 \func{bool}{Button}{\param{int}{ button}}
@@ -204,6 +277,8 @@ values of {\it button} are:
 \twocolitem{{\tt wxMOUSE\_BTN\_LEFT}}{check if left button was pressed}
 \twocolitem{{\tt wxMOUSE\_BTN\_MIDDLE}}{check if middle button was pressed}
 \twocolitem{{\tt wxMOUSE\_BTN\_RIGHT}}{check if right button was pressed}
+\twocolitem{{\tt wxMOUSE\_BTN\_AUX1}}{check if the first extra button was pressed}
+\twocolitem{{\tt wxMOUSE\_BTN\_AUX2}}{check if the second extra button was pressed}
 \twocolitem{{\tt wxMOUSE\_BTN\_ANY}}{check if any button was pressed}
 \end{twocollist}
 
diff --git a/include/wx/event.h b/include/wx/event.h
index 1278284950..3635b757ec 100644
--- a/include/wx/event.h
+++ b/include/wx/event.h
@@ -179,6 +179,12 @@ BEGIN_DECLARE_EVENT_TYPES()
     DECLARE_EVENT_TYPE(wxEVT_KILL_FOCUS, 113)
     DECLARE_EVENT_TYPE(wxEVT_CHILD_FOCUS, 114)
     DECLARE_EVENT_TYPE(wxEVT_MOUSEWHEEL, 115)
+    DECLARE_EVENT_TYPE(wxEVT_AUX1_DOWN, 116)
+    DECLARE_EVENT_TYPE(wxEVT_AUX1_UP, 117)
+    DECLARE_EVENT_TYPE(wxEVT_AUX1_DCLICK, 118)
+    DECLARE_EVENT_TYPE(wxEVT_AUX2_DOWN, 119)
+    DECLARE_EVENT_TYPE(wxEVT_AUX2_UP, 120)
+    DECLARE_EVENT_TYPE(wxEVT_AUX2_DCLICK, 121)
 
         // Non-client mouse events
     DECLARE_EVENT_TYPE(wxEVT_NC_LEFT_DOWN, 200)
@@ -676,7 +682,10 @@ enum
     wxMOUSE_BTN_NONE    = 0,
     wxMOUSE_BTN_LEFT    = 1,
     wxMOUSE_BTN_MIDDLE  = 2,
-    wxMOUSE_BTN_RIGHT   = 3
+    wxMOUSE_BTN_RIGHT   = 3,
+    wxMOUSE_BTN_AUX1    = 4,
+    wxMOUSE_BTN_AUX2    = 5,
+    wxMOUSE_BTN_MAX
 };
 
 class WXDLLIMPEXP_CORE wxMouseEvent : public wxEvent
@@ -725,20 +734,28 @@ public:
     bool LeftDown() const { return (m_eventType == wxEVT_LEFT_DOWN); }
     bool MiddleDown() const { return (m_eventType == wxEVT_MIDDLE_DOWN); }
     bool RightDown() const { return (m_eventType == wxEVT_RIGHT_DOWN); }
+    bool Aux1Down() const { return (m_eventType == wxEVT_AUX1_DOWN); }
+    bool Aux2Down() const { return (m_eventType == wxEVT_AUX2_DOWN); }
 
     bool LeftUp() const { return (m_eventType == wxEVT_LEFT_UP); }
     bool MiddleUp() const { return (m_eventType == wxEVT_MIDDLE_UP); }
     bool RightUp() const { return (m_eventType == wxEVT_RIGHT_UP); }
+    bool Aux1Up() const { return (m_eventType == wxEVT_AUX1_UP); }
+    bool Aux2Up() const { return (m_eventType == wxEVT_AUX2_UP); }
 
     bool LeftDClick() const { return (m_eventType == wxEVT_LEFT_DCLICK); }
     bool MiddleDClick() const { return (m_eventType == wxEVT_MIDDLE_DCLICK); }
     bool RightDClick() const { return (m_eventType == wxEVT_RIGHT_DCLICK); }
+    bool Aux1DClick() const { return (m_eventType == wxEVT_AUX1_UP); }
+    bool Aux2DClick() const { return (m_eventType == wxEVT_AUX2_UP); }
 
     // Find the current state of the mouse buttons (regardless
     // of current event type)
     bool LeftIsDown() const { return m_leftDown; }
     bool MiddleIsDown() const { return m_middleDown; }
     bool RightIsDown() const { return m_rightDown; }
+    bool Aux1IsDown() const { return m_aux1Down; }
+    bool Aux2IsDown() const { return m_aux2Down; }
 
     // True if a button is down and the mouse is moving
     bool Dragging() const
@@ -823,6 +840,8 @@ public:
     bool          m_leftDown;
     bool          m_middleDown;
     bool          m_rightDown;
+    bool          m_aux1Down;
+    bool          m_aux2Down;
 
     bool          m_controlDown;
     bool          m_shiftDown;
@@ -2882,19 +2901,31 @@ typedef void (wxEvtHandler::*wxClipboardTextEventFunction)(wxClipboardTextEvent&
 #define EVT_LEAVE_WINDOW(func) wx__DECLARE_EVT0(wxEVT_LEAVE_WINDOW, wxMouseEventHandler(func))
 #define EVT_ENTER_WINDOW(func) wx__DECLARE_EVT0(wxEVT_ENTER_WINDOW, wxMouseEventHandler(func))
 #define EVT_MOUSEWHEEL(func) wx__DECLARE_EVT0(wxEVT_MOUSEWHEEL, wxMouseEventHandler(func))
+#define EVT_MOUSE_AUX1_DOWN(func) wx__DECLARE_EVT0(wxEVT_AUX1_DOWN, wxMouseEventHandler(func))
+#define EVT_MOUSE_AUX1_UP(func) wx__DECLARE_EVT0(wxEVT_AUX1_UP, wxMouseEventHandler(func))
+#define EVT_MOUSE_AUX1_DCLICK(func) wx__DECLARE_EVT0(wxEVT_AUX1_DCLICK, wxMouseEventHandler(func))
+#define EVT_MOUSE_AUX2_DOWN(func) wx__DECLARE_EVT0(wxEVT_AUX2_DOWN, wxMouseEventHandler(func))
+#define EVT_MOUSE_AUX2_UP(func) wx__DECLARE_EVT0(wxEVT_AUX2_UP, wxMouseEventHandler(func))
+#define EVT_MOUSE_AUX2_DCLICK(func) wx__DECLARE_EVT0(wxEVT_AUX2_DCLICK, wxMouseEventHandler(func))
 
 // All mouse events
 #define EVT_MOUSE_EVENTS(func) \
     EVT_LEFT_DOWN(func) \
     EVT_LEFT_UP(func) \
+    EVT_LEFT_DCLICK(func) \
     EVT_MIDDLE_DOWN(func) \
     EVT_MIDDLE_UP(func) \
+    EVT_MIDDLE_DCLICK(func) \
     EVT_RIGHT_DOWN(func) \
     EVT_RIGHT_UP(func) \
-    EVT_MOTION(func) \
-    EVT_LEFT_DCLICK(func) \
-    EVT_MIDDLE_DCLICK(func) \
     EVT_RIGHT_DCLICK(func) \
+    EVT_MOUSE_AUX1_DOWN(func) \
+    EVT_MOUSE_AUX1_UP(func) \
+    EVT_MOUSE_AUX1_DCLICK(func) \
+    EVT_MOUSE_AUX2_DOWN(func) \
+    EVT_MOUSE_AUX2_UP(func) \
+    EVT_MOUSE_AUX2_DCLICK(func) \
+    EVT_MOTION(func) \
     EVT_LEAVE_WINDOW(func) \
     EVT_ENTER_WINDOW(func) \
     EVT_MOUSEWHEEL(func)
diff --git a/include/wx/utils.h b/include/wx/utils.h
index e68243b82d..2a811afba8 100644
--- a/include/wx/utils.h
+++ b/include/wx/utils.h
@@ -212,6 +212,7 @@ public:
     wxMouseState()
         : m_x(0), m_y(0),
           m_leftDown(false), m_middleDown(false), m_rightDown(false),
+          m_aux1Down(false), m_aux2Down(false),
           m_controlDown(false), m_shiftDown(false), m_altDown(false),
           m_metaDown(false)
     {}
@@ -222,6 +223,8 @@ public:
     bool        LeftDown()    { return m_leftDown; }
     bool        MiddleDown()  { return m_middleDown; }
     bool        RightDown()   { return m_rightDown; }
+    bool        Aux1Down()    { return m_aux1Down; }
+    bool        Aux2Down()    { return m_aux2Down; }
 
     bool        ControlDown() { return m_controlDown; }
     bool        ShiftDown()   { return m_shiftDown; }
@@ -242,6 +245,8 @@ public:
     void        SetLeftDown(bool down)   { m_leftDown = down; }
     void        SetMiddleDown(bool down) { m_middleDown = down; }
     void        SetRightDown(bool down)  { m_rightDown = down; }
+    void        SetAux1Down(bool down)   { m_aux1Down = down; }
+    void        SetAux2Down(bool down)   { m_aux2Down = down; }
 
     void        SetControlDown(bool down) { m_controlDown = down; }
     void        SetShiftDown(bool down)   { m_shiftDown = down; }
@@ -255,6 +260,8 @@ private:
     bool        m_leftDown : 1;
     bool        m_middleDown : 1;
     bool        m_rightDown : 1;
+    bool        m_aux1Down : 1;
+    bool        m_aux2Down : 1;
 
     bool        m_controlDown : 1;
     bool        m_shiftDown : 1;
diff --git a/src/common/event.cpp b/src/common/event.cpp
index 3ac1284d86..980f6ba965 100644
--- a/src/common/event.cpp
+++ b/src/common/event.cpp
@@ -197,6 +197,12 @@ DEFINE_EVENT_TYPE(wxEVT_SET_FOCUS)
 DEFINE_EVENT_TYPE(wxEVT_KILL_FOCUS)
 DEFINE_EVENT_TYPE(wxEVT_CHILD_FOCUS)
 DEFINE_EVENT_TYPE(wxEVT_MOUSEWHEEL)
+DEFINE_EVENT_TYPE(wxEVT_AUX1_DOWN)
+DEFINE_EVENT_TYPE(wxEVT_AUX1_UP)
+DEFINE_EVENT_TYPE(wxEVT_AUX1_DCLICK)
+DEFINE_EVENT_TYPE(wxEVT_AUX2_DOWN)
+DEFINE_EVENT_TYPE(wxEVT_AUX2_UP)
+DEFINE_EVENT_TYPE(wxEVT_AUX2_DCLICK)
 
 // Non-client mouse events
 DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DOWN)
@@ -518,6 +524,8 @@ wxMouseEvent::wxMouseEvent(wxEventType commandType)
     m_leftDown = false;
     m_rightDown = false;
     m_middleDown = false;
+    m_aux1Down = false;
+    m_aux2Down = false;
     m_x = 0;
     m_y = 0;
     m_wheelRotation = 0;
@@ -536,6 +544,8 @@ void wxMouseEvent::Assign(const wxMouseEvent& event)
     m_leftDown = event.m_leftDown;
     m_middleDown = event.m_middleDown;
     m_rightDown = event.m_rightDown;
+    m_aux1Down = event.m_aux1Down;
+    m_aux2Down = event.m_aux2Down;
 
     m_controlDown = event.m_controlDown;
     m_shiftDown = event.m_shiftDown;
@@ -558,7 +568,8 @@ bool wxMouseEvent::ButtonDClick(int but) const
             // fall through
 
         case wxMOUSE_BTN_ANY:
-            return (LeftDClick() || MiddleDClick() || RightDClick());
+            return (LeftDClick() || MiddleDClick() || RightDClick() ||
+                    Aux1DClick() || Aux2DClick());
 
         case wxMOUSE_BTN_LEFT:
             return LeftDClick();
@@ -568,6 +579,12 @@ bool wxMouseEvent::ButtonDClick(int but) const
 
         case wxMOUSE_BTN_RIGHT:
             return RightDClick();
+
+        case wxMOUSE_BTN_AUX1:
+            return Aux1DClick();
+
+        case wxMOUSE_BTN_AUX2:
+            return Aux2DClick();
     }
 }
 
@@ -581,7 +598,8 @@ bool wxMouseEvent::ButtonDown(int but) const
             // fall through
 
         case wxMOUSE_BTN_ANY:
-            return (LeftDown() || MiddleDown() || RightDown());
+            return (LeftDown() || MiddleDown() || RightDown() ||
+                    Aux1Down() || Aux2Down());
 
         case wxMOUSE_BTN_LEFT:
             return LeftDown();
@@ -591,6 +609,12 @@ bool wxMouseEvent::ButtonDown(int but) const
 
         case wxMOUSE_BTN_RIGHT:
             return RightDown();
+
+        case wxMOUSE_BTN_AUX1:
+            return Aux1Down();
+
+        case wxMOUSE_BTN_AUX2:
+            return Aux2Down();
     }
 }
 
@@ -604,7 +628,8 @@ bool wxMouseEvent::ButtonUp(int but) const
             // fall through
 
         case wxMOUSE_BTN_ANY:
-            return (LeftUp() || MiddleUp() || RightUp());
+            return (LeftUp() || MiddleUp() || RightUp() ||
+                    Aux1Up() || Aux2Up());
 
         case wxMOUSE_BTN_LEFT:
             return LeftUp();
@@ -614,6 +639,12 @@ bool wxMouseEvent::ButtonUp(int but) const
 
         case wxMOUSE_BTN_RIGHT:
             return RightUp();
+
+        case wxMOUSE_BTN_AUX1:
+            return Aux1Up();
+
+        case wxMOUSE_BTN_AUX2:
+            return Aux2Up();
     }
 }
 
@@ -639,6 +670,12 @@ bool wxMouseEvent::Button(int but) const
 
         case wxMOUSE_BTN_RIGHT:
             return RightDown() || RightUp() || RightDClick();
+
+        case wxMOUSE_BTN_AUX1:
+           return Aux1Down() || Aux1Up() || Aux1DClick();
+
+        case wxMOUSE_BTN_AUX2:
+           return Aux2Down() || Aux2Up() || Aux2DClick();
     }
 }
 
@@ -651,7 +688,7 @@ bool wxMouseEvent::ButtonIsDown(int but) const
             // fall through
 
         case wxMOUSE_BTN_ANY:
-            return LeftIsDown() || MiddleIsDown() || RightIsDown();
+            return LeftIsDown() || MiddleIsDown() || RightIsDown() || Aux1Down() || Aux2Down();
 
         case wxMOUSE_BTN_LEFT:
             return LeftIsDown();
@@ -661,12 +698,18 @@ bool wxMouseEvent::ButtonIsDown(int but) const
 
         case wxMOUSE_BTN_RIGHT:
             return RightIsDown();
+
+        case wxMOUSE_BTN_AUX1:
+            return Aux1IsDown();
+
+        case wxMOUSE_BTN_AUX2:
+            return Aux2IsDown();
     }
 }
 
 int wxMouseEvent::GetButton() const
 {
-    for ( int i = 1; i <= 3; i++ )
+    for ( int i = 1; i < wxMOUSE_BTN_MAX; i++ )
     {
         if ( Button(i) )
         {
diff --git a/src/msw/window.cpp b/src/msw/window.cpp
index 81ee66815f..ef18195d59 100644
--- a/src/msw/window.cpp
+++ b/src/msw/window.cpp
@@ -2652,6 +2652,9 @@ WXLRESULT wxWindowMSW::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM l
         case WM_MBUTTONDOWN:
         case WM_MBUTTONUP:
         case WM_MBUTTONDBLCLK:
+        case WM_XBUTTONDOWN:
+        case WM_XBUTTONUP:
+        case WM_XBUTTONDBLCLK:
             {
 #ifdef __WXMICROWIN__
                 // MicroWindows seems to ignore the fact that a window is
@@ -4794,6 +4797,8 @@ void wxWindowMSW::InitMouseEvent(wxMouseEvent& event,
     event.m_leftDown = (flags & MK_LBUTTON) != 0;
     event.m_middleDown = (flags & MK_MBUTTON) != 0;
     event.m_rightDown = (flags & MK_RBUTTON) != 0;
+    event.m_aux1Down = (flags & MK_XBUTTON1) != 0;
+    event.m_aux2Down = (flags & MK_XBUTTON2) != 0;
     event.m_altDown = ::GetKeyState(VK_MENU) < 0;
 
 #ifndef __WXWINCE__
@@ -4892,9 +4897,27 @@ bool wxWindowMSW::HandleMouseEvent(WXUINT msg, int x, int y, WXUINT flags)
         wxEVT_RIGHT_DCLICK,
         wxEVT_MIDDLE_DOWN,
         wxEVT_MIDDLE_UP,
-        wxEVT_MIDDLE_DCLICK
+        wxEVT_MIDDLE_DCLICK,
+        0, // this one is for wxEVT_MOTION which is not used here
+        wxEVT_AUX1_DOWN,
+        wxEVT_AUX1_UP,
+        wxEVT_AUX1_DCLICK,
+        wxEVT_AUX2_DOWN,
+        wxEVT_AUX2_UP,
+        wxEVT_AUX2_DCLICK
     };
 
+    // the same messages are used for both auxillary mouse buttons so we need
+    // to adjust the index manually
+    switch ( msg )
+    {
+        case WM_XBUTTONDOWN:
+        case WM_XBUTTONUP:
+        case WM_XBUTTONDBLCLK:
+            if ( flags & MK_XBUTTON2 )
+                msg += wxEVT_AUX2_DOWN - wxEVT_AUX1_DOWN;
+    }
+
     wxMouseEvent event(eventsMouse[msg - WM_MOUSEMOVE]);
     InitMouseEvent(event, x, y, flags);
 
@@ -5810,6 +5833,8 @@ wxMouseState wxGetMouseState()
     ms.SetLeftDown(wxIsKeyDown(VK_LBUTTON));
     ms.SetMiddleDown(wxIsKeyDown(VK_MBUTTON));
     ms.SetRightDown(wxIsKeyDown(VK_RBUTTON));
+    ms.SetAux1Down(wxIsKeyDown(VK_XBUTTON1));
+    ms.SetAux2Down(wxIsKeyDown(VK_XBUTTON2));
 
     ms.SetControlDown(wxIsKeyDown(VK_CONTROL));
     ms.SetShiftDown(wxIsKeyDown(VK_SHIFT));
@@ -6140,6 +6165,9 @@ const wxChar *wxGetMessageName(int message)
         case 0x0208: return wxT("WM_MBUTTONUP");
         case 0x0209: return wxT("WM_MBUTTONDBLCLK");
         case 0x020A: return wxT("WM_MOUSEWHEEL");
+        case 0x020B: return wxT("WM_XBUTTONDOWN");
+        case 0x020C: return wxT("WM_XBUTTONUP");
+        case 0x020D: return wxT("WM_XBUTTONDBLCLK");
         case 0x0210: return wxT("WM_PARENTNOTIFY");
         case 0x0211: return wxT("WM_ENTERMENULOOP");
         case 0x0212: return wxT("WM_EXITMENULOOP");
-- 
2.50.0

