diff options
author | John Rennie <john.rennie@ratsauce.co.uk> | 2011-06-02 22:32:55 -0700 |
---|---|---|
committer | John Rennie <john.rennie@ratsauce.co.uk> | 2011-06-02 22:32:55 -0700 |
commit | 5db18b13993b91f0d18ba96af6069836b234f549 (patch) | |
tree | 5056a06d5e5406f948a55e33192adfa105e2f5b9 | |
parent | e8b12e530c7bbf21596664384426ed356ae8dd6d (diff) | |
parent | 620780e55ee039998cc10f106cec1936f3b86f9d (diff) |
Merge pull request #166 from jhsrennie/master
Allow mouse actions to be mapped with an XML file
-rw-r--r-- | system/keymaps/mouse.xml | 14 | ||||
-rw-r--r-- | xbmc/Application.cpp | 37 | ||||
-rw-r--r-- | xbmc/guilib/Key.h | 8 | ||||
-rw-r--r-- | xbmc/input/ButtonTranslator.cpp | 54 | ||||
-rw-r--r-- | xbmc/input/ButtonTranslator.h | 2 | ||||
-rw-r--r-- | xbmc/input/MouseStat.cpp | 15 | ||||
-rw-r--r-- | xbmc/input/MouseStat.h | 8 |
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 |