在进行libvlc二次开发的过程中梳理了一下hotkey处理过程。
本文主要介绍了热键如何设置的以及按键后如果触发响应的动作
友情提示:阅读本文章前需要了解vlc的模块机制和vlc_variables机制
热键设置
qt界面上修改热键后,保存,实际调用了如下代码
void KeySelectorControl::doApply()
{
QTreeWidgetItem *it;
for( int i = 0; i < table->topLevelItemCount() ; i++ )
{
it = table->topLevelItem(i);
if( it->data( HOTKEY_COL, Qt::UserRole ).toInt() >= 0 )
config_PutPsz( p_this,
qtu( it->data( ACTION_COL, Qt::UserRole ).toString() ),
qtu( it->data( HOTKEY_COL, Qt::UserRole ).toString() ) );
config_PutPsz( p_this,
qtu( "global-" + it->data( ACTION_COL, Qt::UserRole ).toString() ),
qtu( it->data( GLOBAL_HOTKEY_COL, Qt::UserRole ).toString() ) );
}
}
循环取得用户设置的hotkey,调用config_PutPsz保存到配置变量中(动作和按键码以键值方式保存)
热键触发
qt窗口收到按键消息之后,执行如下操作
void MainInterface::handleKeyPress( QKeyEvent *e )
{
if( ( ( e->modifiers() & Qt::ControlModifier ) && ( e->key() == Qt::Key_H ) ) ||
( b_minimalView && !b_videoFullScreen && e->key() == Qt::Key_Escape ) )
{
toggleMinimalView( !b_minimalView );
e->accept();
}
int i_vlck = qtEventToVLCKey( e );
if( i_vlck > 0 )
{
var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlck );
e->accept();
}
else
e->ignore();
}
将qt按键码转为vlc按键码,通过var_SetInteger设置key-pressed变量的值(按键码)
var_SetInteger会调用注册了key-pressed的回调函数vlc_key_to_action
static int vlc_key_to_action (vlc_object_t *obj, const char *varname,
vlc_value_t prevkey, vlc_value_t curkey, void *d)
{
void *const *map = d;
const struct mapping **pent;
uint32_t keycode = curkey.i_int;
pent = tfind (&keycode, map, keycmp);
if (pent == NULL)
return VLC_SUCCESS;
(void) varname;
(void) prevkey;
return var_SetInteger (obj, "key-action", (*pent)->action);
}
vlc_key_to_action内部调用config_GetPsz得到按键码对应的动作,调用var_SetInteger 设置key-action变量的值(动作)
var_SetInteger内部会调用注册了key-action的回调函数ActionEvent,ActionEvent内部根据动作执行响应的控制
下图为hotkeys模块在加载的时候将ActionEvent函数注册到key-action变量上:
下图是ActionEvent内部根据动作执行响应的控制相关代码