aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Rennie <john.rennie@ratsauce.co.uk>2011-06-02 22:32:55 -0700
committerJohn Rennie <john.rennie@ratsauce.co.uk>2011-06-02 22:32:55 -0700
commit5db18b13993b91f0d18ba96af6069836b234f549 (patch)
tree5056a06d5e5406f948a55e33192adfa105e2f5b9
parente8b12e530c7bbf21596664384426ed356ae8dd6d (diff)
parent620780e55ee039998cc10f106cec1936f3b86f9d (diff)
Merge pull request #166 from jhsrennie/master
Allow mouse actions to be mapped with an XML file
-rw-r--r--system/keymaps/mouse.xml14
-rw-r--r--xbmc/Application.cpp37
-rw-r--r--xbmc/guilib/Key.h8
-rw-r--r--xbmc/input/ButtonTranslator.cpp54
-rw-r--r--xbmc/input/ButtonTranslator.h2
-rw-r--r--xbmc/input/MouseStat.cpp15
-rw-r--r--xbmc/input/MouseStat.h8
7 files changed, 128 insertions, 10 deletions
diff --git a/system/keymaps/mouse.xml b/system/keymaps/mouse.xml
new file mode 100644
index 0000000000..5172650f6e
--- /dev/null
+++ b/system/keymaps/mouse.xml
@@ -0,0 +1,14 @@
+<keymap>
+ <global>
+ <mouse>
+ <leftclick>leftclick</leftclick>
+ <middleclick>middleclick</middleclick>
+ <rightclick>rightclick</rightclick>
+ <doubleclick>doubleclick</doubleclick>
+ <wheeldown>wheeldown</wheeldown>
+ <wheelup>wheelup</wheelup>
+ <mousedrag>mousedrag</mousedrag>
+ <mousemove>mousemove</mousemove>
+ </mouse>
+ </global>
+</keymap>
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index f170874c1f..6980ed8a64 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -2904,13 +2904,48 @@ bool CApplication::ProcessMouse()
if (!g_Mouse.IsActive() || !m_AppFocused)
return false;
+ // Update the pointer position here so it gets updated even for ACTION_NOOP
+ m_guiPointer.SetPosition((float) g_Mouse.GetX(), (float) g_Mouse.GetY());
+
// Reset the screensaver and idle timers
m_idleTimer.StartZero();
ResetScreenSaver();
if (WakeUpScreenSaverAndDPMS())
return true;
- return OnAction(g_Mouse.GetAction());
+ // Get the mouse command ID
+ uint32_t mousecommand = g_Mouse.GetAction();
+
+ // Retrieve the corresponding action
+ int iWin;
+ CKey key(mousecommand | KEY_MOUSE, (unsigned int) 0);
+ if (g_windowManager.HasModalDialog())
+ iWin = g_windowManager.GetTopMostModalDialogID() & WINDOW_ID_MASK;
+ else
+ iWin = g_windowManager.GetActiveWindow() & WINDOW_ID_MASK;
+ CAction mouseaction = CButtonTranslator::GetInstance().GetAction(iWin, key);
+
+ // If we couldn't find an action return false to indicate we have not
+ // handled this mouse action
+ if (!mouseaction.GetID())
+ {
+ CLog::Log(LOGDEBUG, "%s: unknown mouse command %d", __FUNCTION__, mousecommand);
+ return false;
+ }
+
+ // Process the appcommand
+ CAction newmouseaction = CAction(mouseaction.GetID(),
+ g_Mouse.GetHold(MOUSE_LEFT_BUTTON),
+ (float)g_Mouse.GetX(),
+ (float)g_Mouse.GetY(),
+ (float)g_Mouse.GetDX(),
+ (float)g_Mouse.GetDY());
+
+ // Log mouse actions except for move and noop
+ if (newmouseaction.GetID() != ACTION_MOUSE_MOVE && newmouseaction.GetID() != ACTION_NOOP)
+ CLog::Log(LOGDEBUG, "%s: trying mouse action %s", __FUNCTION__, mouseaction.GetName().c_str());
+
+ return OnAction(newmouseaction);
}
void CApplication::CheckForTitleChange()
diff --git a/xbmc/guilib/Key.h b/xbmc/guilib/Key.h
index a160cf5fbb..43dc94be52 100644
--- a/xbmc/guilib/Key.h
+++ b/xbmc/guilib/Key.h
@@ -76,6 +76,9 @@
#define KEY_ASCII 0xF100 // a printable character in the range of TRUE ASCII (from 0 to 127) // FIXME make it clean and pure unicode! remove the need for KEY_ASCII
#define KEY_UNICODE 0xF200 // another printable character whose range is not included in this KEY code
+// 0xE000 -> 0xE0FF is reserved for mouse actions
+#define KEY_MOUSE 0xE000
+
// 0xD000 -> 0xD0FF is reserved for WM_APPCOMMAND messages
#define KEY_APPCOMMAND 0xD000
@@ -292,6 +295,11 @@
#define ACTION_PLAYER_PLAYPAUSE 227 // Play/pause. If playing it pauses, if paused it plays.
+// The NOOP action can be specified to disable an input event. This is
+// useful in user keyboard.xml etc to disable actions specified in the
+// system mappings.
+#define ACTION_NOOP 999
+
// Window ID defines to make the code a bit more readable
#define WINDOW_INVALID 9999
#define WINDOW_HOME 10000
diff --git a/xbmc/input/ButtonTranslator.cpp b/xbmc/input/ButtonTranslator.cpp
index 4945fb7afa..60adef8f62 100644
--- a/xbmc/input/ButtonTranslator.cpp
+++ b/xbmc/input/ButtonTranslator.cpp
@@ -45,7 +45,8 @@ typedef struct
} ActionMapping;
static const ActionMapping actions[] =
- {{"left" , ACTION_MOVE_LEFT },
+{
+ {"left" , ACTION_MOVE_LEFT },
{"right" , ACTION_MOVE_RIGHT},
{"up" , ACTION_MOVE_UP },
{"down" , ACTION_MOVE_DOWN },
@@ -194,7 +195,21 @@ static const ActionMapping actions[] =
{"yellow" , ACTION_TELETEXT_YELLOW},
{"blue" , ACTION_TELETEXT_BLUE},
{"increasepar" , ACTION_INCREASE_PAR},
- {"decreasepar" , ACTION_DECREASE_PAR}};
+ {"decreasepar" , ACTION_DECREASE_PAR},
+
+ // Mouse actions
+ {"leftclick" , ACTION_MOUSE_LEFT_CLICK},
+ {"rightclick" , ACTION_MOUSE_RIGHT_CLICK},
+ {"middleclick" , ACTION_MOUSE_MIDDLE_CLICK},
+ {"doubleclick" , ACTION_MOUSE_DOUBLE_CLICK},
+ {"wheelup" , ACTION_MOUSE_WHEEL_UP},
+ {"wheeldown" , ACTION_MOUSE_WHEEL_DOWN},
+ {"mousedrag" , ACTION_MOUSE_DRAG},
+ {"mousemove" , ACTION_MOUSE_MOVE},
+
+ // Do nothing action
+ { "noop" , ACTION_NOOP}
+};
static const ActionMapping windows[] =
{{"home" , WINDOW_HOME},
@@ -291,6 +306,18 @@ static const ActionMapping windows[] =
{"startwindow" , WINDOW_START},
{"startup" , WINDOW_STARTUP_ANIM}};
+static const ActionMapping mousecommands[] =
+{
+ { "leftclick", ACTION_MOUSE_LEFT_CLICK },
+ { "rightclick", ACTION_MOUSE_RIGHT_CLICK },
+ { "middleclick", ACTION_MOUSE_MIDDLE_CLICK },
+ { "doubleclick", ACTION_MOUSE_DOUBLE_CLICK },
+ { "wheelup", ACTION_MOUSE_WHEEL_UP },
+ { "wheeldown", ACTION_MOUSE_WHEEL_DOWN },
+ { "mousedrag", ACTION_MOUSE_DRAG },
+ { "mousemove", ACTION_MOUSE_MOVE }
+};
+
#ifdef WIN32
static const ActionMapping appcommands[] =
{
@@ -826,7 +853,7 @@ void CButtonTranslator::MapWindowActions(TiXmlNode *pWindow, int windowID)
}
TiXmlNode* pDevice;
- const char* types[] = {"gamepad", "remote", "universalremote", "keyboard", "appcommand", NULL};
+ const char* types[] = {"gamepad", "remote", "universalremote", "keyboard", "mouse", "appcommand", NULL};
for (int i = 0; types[i]; ++i)
{
CStdString type(types[i]);
@@ -845,6 +872,8 @@ void CButtonTranslator::MapWindowActions(TiXmlNode *pWindow, int windowID)
buttonCode = TranslateUniversalRemoteString(pButton->Value());
else if (type == "keyboard")
buttonCode = TranslateKeyboardButton(pButton);
+ else if (type == "mouse")
+ buttonCode = TranslateMouseCommand(pButton->Value());
else if (type == "appcommand")
buttonCode = TranslateAppCommand(pButton->Value());
@@ -878,9 +907,6 @@ bool CButtonTranslator::TranslateActionString(const char *szAction, int &action)
if (CBuiltins::HasCommand(strAction))
action = ACTION_BUILT_IN_FUNCTION;
- if (strAction.Equals("noop"))
- return true;
-
for (unsigned int index=0;index < sizeof(actions)/sizeof(actions[0]);++index)
{
if (strAction.Equals(actions[index].name))
@@ -1149,6 +1175,22 @@ uint32_t CButtonTranslator::TranslateAppCommand(const char *szButton)
return 0;
}
+uint32_t CButtonTranslator::TranslateMouseCommand(const char *szButton)
+{
+ CStdString strMouseCommand = szButton;
+ strMouseCommand.ToLower();
+
+ int j = sizeof(mousecommands)/sizeof(mousecommands[0]);
+
+ for (int i = 0; i < sizeof(mousecommands)/sizeof(mousecommands[0]); i++)
+ if (strMouseCommand.Equals(mousecommands[i].name))
+ return mousecommands[i].action | KEY_MOUSE;
+
+ CLog::Log(LOGERROR, "%s: Can't find mouse command %s", __FUNCTION__, szButton);
+
+ return 0;
+}
+
void CButtonTranslator::Clear()
{
translatorMap.clear();
diff --git a/xbmc/input/ButtonTranslator.h b/xbmc/input/ButtonTranslator.h
index 594e63a85f..a1f0e9c608 100644
--- a/xbmc/input/ButtonTranslator.h
+++ b/xbmc/input/ButtonTranslator.h
@@ -106,6 +106,8 @@ private:
static uint32_t TranslateKeyboardString(const char *szButton);
static uint32_t TranslateKeyboardButton(TiXmlElement *pButton);
+ static uint32_t TranslateMouseCommand(const char *szButton);
+
static uint32_t TranslateAppCommand(const char *szButton);
void MapWindowActions(TiXmlNode *pWindow, int wWindowID);
diff --git a/xbmc/input/MouseStat.cpp b/xbmc/input/MouseStat.cpp
index 7cde327f99..7027e066e3 100644
--- a/xbmc/input/MouseStat.cpp
+++ b/xbmc/input/MouseStat.cpp
@@ -254,9 +254,10 @@ bool CMouseStat::MovedPastThreshold() const
return (m_mouseState.dx * m_mouseState.dx + m_mouseState.dy * m_mouseState.dy >= MOUSE_MINIMUM_MOVEMENT * MOUSE_MINIMUM_MOVEMENT);
}
-CAction CMouseStat::GetAction() const
+uint32_t CMouseStat::GetAction() const
{
int actionID = ACTION_MOUSE_MOVE;
+
if (bClick[MOUSE_LEFT_BUTTON])
actionID = ACTION_MOUSE_LEFT_CLICK;
else if (bClick[MOUSE_RIGHT_BUTTON])
@@ -272,5 +273,15 @@ CAction CMouseStat::GetAction() const
else if (m_mouseState.dz < 0)
actionID = ACTION_MOUSE_WHEEL_DOWN;
- return CAction(actionID, (unsigned int)bHold[MOUSE_LEFT_BUTTON], (float)m_mouseState.x, (float)m_mouseState.y, (float)m_mouseState.dx, (float)m_mouseState.dy);
+ return actionID;
+}
+
+int CMouseStat::GetHold(int ButtonID) const
+{
+ switch (ButtonID)
+ { case MOUSE_LEFT_BUTTON:
+ return bHold[MOUSE_LEFT_BUTTON];
+ }
+ return false;
}
+
diff --git a/xbmc/input/MouseStat.h b/xbmc/input/MouseStat.h
index 656e034cce..33f6ac5403 100644
--- a/xbmc/input/MouseStat.h
+++ b/xbmc/input/MouseStat.h
@@ -76,7 +76,13 @@ public:
void SetState(MOUSE_STATE state) { m_pointerState = state; };
void SetEnabled(bool enabled = true);
MOUSE_STATE GetState() const { return m_pointerState; };
- CAction GetAction() const;
+ uint32_t GetAction() const;
+
+ int GetHold(int ButtonID) const;
+ inline int GetX(void) const { return m_mouseState.x; }
+ inline int GetY(void) const { return m_mouseState.y; }
+ inline int GetDX(void) const { return m_mouseState.dx; }
+ inline int GetDY(void) const { return m_mouseState.dy; }
private:
/*! \brief Holds information regarding a particular mouse button state