注我們以遙控器音量加鍵爲說明例子
//xbmc/Application.cpp
bool CApplication::OnEvent(XBMC_Event& newEvent)
{
switch(newEvent.type)
{
case XBMC_QUIT: //退出xbmc
...
CApplicationMessenger::Get().Quit();
break;
case XBMC_KEYDOWN:
g_application.OnKey(g_Keyboard.ProcessKeyDown(newEvent.key.keysym));
break;
}
}
/*
xbmc/input/KeyboardStat.cpp
*/
const CKey CKeyboardStat::ProcessKeyDown(XBMC_keysym& keysym)
{ uint8_t vkey;
wchar_t unicode;
char ascii;
uint32_t modifiers;
unsigned int held;
XBMCKEYTABLE keytable;
...
//這裏一句輸出了:Keyboard: scancode: 0x18, sym: 0x002b, unicode: 0x0000, modifier: 0x0
CLog::Log(LOGDEBUG, "Keyboard: scancode: 0x%02x, sym: 0x%04x, unicode: 0x%04x, modifier: 0x%x",
keysym.scancode, keysym.sym, keysym.unicode, keysym.mod);
if (LookupSymAndUnicodePeripherals(keysym, &vkey, &ascii))
{
CLog::Log(LOGDEBUG, "%s - keypress translated by a HID peripheral", __FUNCTION__);
}
// Continue by trying to match both the sym and unicode. This will identify
else if (KeyTableLookupSymAndUnicode(keysym.sym, keysym.unicode, &keytable))
{
vkey = keytable.vkey;
ascii = keytable.ascii;
}
// If we failed to match the sym and unicode try just the unicode. This
else if (KeyTableLookupUnicode(keysym.unicode, &keytable))
{
vkey = keytable.vkey;
ascii = keytable.ascii;
}
// If there is still no match try the sym我們按音量加進入了這裏
else if (KeyTableLookupSym(keysym.sym, &keytable))
{
vkey = keytable.vkey;
if (keytable.unicode == 0 && unicode != 0)
unicode = 0;
else if (keysym.unicode > 32 && keysym.unicode < 128)
ascii = unicode & 0x7f;
}
...
//我們點擊遙控器音量加到這裏是 vkey:+, unicode:0x0000, ascii:null, modifiers:0x0000, held:0
CKey key(vkey, unicode, ascii, modifiers, held);
return key;
}
/*
xbmc/input/XBMC_keytable.cpp
*/
bool KeyTableLookupSym(uint16_t sym, XBMCKEYTABLE* keytable)
{
...
// Look up the sym in XBMCKeyTable
for (int i = 0; i < XBMCKeyTableSize; i++)
{ if (sym == XBMCKeyTable[i].sym)
{ *keytable = XBMCKeyTable[i];
return true;
}
}
return false;
}
這裏會查找XBMCKeyTable這個數組,以找到sym號相同的的數組。我們知道sym爲0x002b,這個
值是在AndroidKey.cpp將鍵盤scancode轉化爲sym而來。
/*
xbmc/input/XBMC_keytable.h
*/
typedef struct struct_XBMCKEYTABLE
{
uint16_t sym;
uint16_t unicode;
char ascii;
uint32_t vkey;
const char* keyname;
}
static const XBMCKEYTABLE XBMCKeyTable[] =
{
...
// Misc printing characters
{ XBMCK_PLUS, '+', '+', XBMCVK_PLUS, "plus" }
...
}
到此,我們就解析完了CKey對象的創建過程,然後它被傳遞給了
//xbmc/Application.cpp
bool CApplication::OnKey(const CKey& key)
{
// get the current active window
int iWin = GetActiveWindowID();
// this will be checked for certain keycodes that need
// special handling if the screensaver is active
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);
}