AndroidKey.cpp将scancode装换为sym,并形成XBMC_Key
//xbmc/android/activity/AndroidKey.cpp
typedef struct {
int32_t nativeKey;
int16_t xbmcKey;
} KeyMap;
static KeyMap keyMap[] = {
{ AKEYCODE_VOLUME_UP , XBMCK_PLUS },
};
bool CAndroidKey::onKeyboardEvent(AInputEvent *event)
{
int32_t flags = AKeyEvent_getFlags(event);
int32_t state = AKeyEvent_getMetaState(event);
int32_t action = AKeyEvent_getAction(event);
int32_t repeat = AKeyEvent_getRepeatCount(event);
int32_t keycode = AKeyEvent_getKeyCode(event);
int32_t deviceId = AInputEvent_getDeviceId(event);
CJNIKeyCharacterMap map = CJNIKeyCharacterMap::load(deviceId);
uint16_t unicode = map.get(keycode, state);
// Check if we got some special key
uint16_t sym = XBMCK_UNKNOWN;
for (unsigned int index = 0; index < sizeof(keyMap) / sizeof(KeyMap); index++)
{
if (keycode == keyMap[index].nativeKey)
{
sym = keyMap[index].xbmcKey;
break;
}
}
switch (action)
{
case AKEY_EVENT_ACTION_DOWN:
CXBMCApp::android_printf("CAndroidKey: key down (code: %d; repeat: %d; flags: 0x%0X; alt: %s; shift: %s; sym: %s)",
keycode, repeat, flags,
(state & AMETA_ALT_ON) ? "yes" : "no",
(state & AMETA_SHIFT_ON) ? "yes" : "no",
(state & AMETA_SYM_ON) ? "yes" : "no");
XBMC_Key((uint8_t)keycode, sym, modifiers, unicode, false);
return true;
...
}
}
keyMap[index].nativeKey的值在这儿定义的这句话
/*
tools/depends/target/android-sources-ics/android-source/frameworks/base/native/include/android/keycodes.h
*/
enum {
AKEYCODE_VOLUME_UP = 24,
...
}
接下来就是把android键盘打包为xbmc内部的XBMC_Event,扔到消息队列中
void CAndroidKey::XBMC_Key(uint8_t code, uint16_t key, uint16_t modifiers, uint16_t unicode, bool up)
{
XBMC_Event newEvent;
memset(&newEvent, 0, sizeof(newEvent));
unsigned char type = up ? XBMC_KEYUP : XBMC_KEYDOWN;
newEvent.type = type;
newEvent.key.type = type;
newEvent.key.keysym.scancode = code;
newEvent.key.keysym.sym = (XBMCKey)key;
newEvent.key.keysym.unicode = unicode;
newEvent.key.keysym.mod = (XBMCMod)modifiers;
//CXBMCApp::android_printf("XBMC_Key(%u, %u, 0x%04X, %d)", code, key, modifiers, up);
CWinEvents::MessagePush(&newEvent);
}
传到Application.cpp的OnEvent,由XBMC_Event获得CKey对象
//xbmc/Application.cpp
bool CApplication::OnEvent(XBMC_Event& newEvent)
{
switch(newEvent.type)
{
case XBMC_QUIT: //退出xbmc
...
CApplicationMessenger::Get().Quit();
break;
case XBMC_KEYDOWN:
//这里一句输出了:Keyboard: scancode: 0x18, sym: 0x002b, unicode: 0x0000, modifier: 0x0
g_application.OnKey(g_Keyboard.ProcessKeyDown(newEvent.key.keysym));
break;
}
}
CKey获取CAction对象
//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);
}
bool CApplication::ExecuteInputAction(const CAction &action)
{
bool bResult = false;
// play sound before the action unless the button is held,
// where we execute after the action as held actions aren't fired every time.
bResult = OnAction(action);
...
g_audioManager.PlayActionSound(action);//播放按键音
return bResult;
}
bool CApplication::OnAction(const CAction &action)
{
...
if (action.GetAmount() && (action.GetID() == ACTION_VOLUME_UP || action.GetID() == ACTION_VOLUME_DOWN))
{
if (!m_pPlayer->IsPassthrough())
{
...
SetVolume(volume, false);
}
ShowVolumeBar(&action);
return true;
}
...
}
ACTION_VOLUME_UP的值在哪里定义的呢
//xbmc/guilib/Key.h
#define ACTION_VOLUME_UP 88
void CApplication::VolumeChanged() const
{
CVariant data(CVariant::VariantTypeObject);
data["volume"] = GetVolume();
data["muted"] = m_muted;
CAnnouncementManager::Get().Announce(Application, "xbmc", "OnVolumeChanged", data);
// if player has volume control, set it.
if (m_pPlayer->ControlsVolume())
{
m_pPlayer->SetVolume(m_volumeLevel);
m_pPlayer->SetMute(m_muted);
}
}