注我们以遥控器音量加键为说明例子
//xbmc/Application.cpp
bool CApplication::OnKey(const CKey& key)
{
...
int iWin = GetActiveWindowID();
CAction action = CButtonTranslator::GetInstance().GetAction(iWin, key);
...
if (!key.IsAnalogButton())
CLog::LogF(LOGDEBUG, "%s pressed, action is %s",
g_Keyboard.GetKeyName((int) key.GetButtonCode()).c_str(), action.GetName().c_str());
return ExecuteInputAction(action);
}
//xbmc/input/ButtonTranslator.cpp
CAction CButtonTranslator::GetAction(int window, const CKey &key, bool fallback)
{
std::string strAction;
// try to get the action from the current window
int actionID = GetActionCode(window, key, strAction);
// if it's invalid, try to get it from the global map
if (actionID == 0 && fallback)
{
int fallbackWindow = GetFallbackWindow(window);
if (fallbackWindow > -1)
actionID = GetActionCode(fallbackWindow, key, strAction);
// still no valid action? use global map
if (actionID == 0)
actionID = GetActionCode( -1, key, strAction);
}
CAction action(actionID, strAction, key);
return action;
}
在此说明以下CAction的其一构造函数//xbmc/guilib/Key.h
CAction(int actionID, const CStdString &name, const CKey &key);
看样子我们要弄清楚actionID的由来
int CButtonTranslator::GetActionCode(int window, const CKey &key, std::string &strAction) const
{
uint32_t code = key.GetButtonCode();
map<int, buttonMap>::const_iterator it = m_translatorMap.find(window);
...
buttonMap::const_iterator it2 = (*it).second.find(code);
int action = 0;
if (it2 != (*it).second.end())
{
action = (*it2).second.id;
strAction = (*it2).second.strID;
}
return action;
}
我们看看获取code的GetButtonCode代码
//xbmc/guilib/Key.h
inline uint32_t GetButtonCode() const { return m_buttonCode; }
看来似乎又要回到从OnEvent方法的g_Keyboard.ProcessKeyDown(newEvent.key.keysym)返回的key对象入手了
CKey::CKey(uint8_t vkey, wchar_t unicode, char ascii, uint32_t modifiers, unsigned int held)
{
Reset();
if (vkey) // FIXME: This needs cleaning up - should we always use the unicode key where available?
m_buttonCode = vkey | KEY_VKEY;
else
m_buttonCode = KEY_UNICODE;
m_buttonCode |= modifiers;
m_vkey = vkey;
m_unicode = unicode;
m_ascii = ascii;
m_modifiers = modifiers;
m_held = held;
}
其中
#define KEY_VKEY 0xF000
至此,我们的m_buttonCode出来了,即0xF02b,从keyboard.xml等xml的读取过程中我们知道actionID 0xF02b对应的,
action为plus,strAction为ACTION_VOLUME_UP,至此key转化为action便完成。
actions的数组的内容如下
//xbmc/input/ButtonTranslator.cpp
static const ActionMapping actions[] ={
...
{"volumeup" , ACTION_VOLUME_UP}, //这是action名称和对应的值action.GetID()
}
后续到Application.cpp的ExecuteInputAction(action);中处理