经过查看源代码发现Qt的键盘处理是判断环境变量QWS_KEYBOARD再加载相应的键盘处理拦截类, 而qt已经包含了几个典型的键盘处理,只要以它们为蓝本即可编写自己的处理类! 一下我以 vr4xx为模板, 建立QWSMx21ButtonsHandler键盘处理类! 以下是相关实现代码,
2. 添加键盘处理类
class QWSMx21ButtonsHandler : public QWSKeyboardHandler
{
Q_OBJECT
public:
QWSMx21ButtonsHandler();
virtual QWSMx21ButtonsHandler();
bool isOpen() { return buttonFD > 0; }
private slots:
void readKeyboardData(); // 这个函数最重要, 包含的读键盘扫描码的处理
private:
QString terminalName;
int buttonFD;
int kbdIdx;
int kbdBufferLen;
unsigned char *kbdBuffer;
QSocketNotifier *notifier;
};
/*
* mx21 buttons driver
*/
QWSMx21ButtonsHandler::QWSMx21ButtonsHandler() : QWSKeyboardHandler()
{
terminalName = "/dev/buttons";
buttonFD = -1;
notifier = 0;
if ((buttonFD = open(terminalName, O_RDWR | O_NDELAY, 0)) < 0)
{
qWarning("Cannot open %s/n", terminalName.latin1());
}
if ( buttonFD >= 0 ) {
notifier = new QSocketNotifier( buttonFD, QSocketNotifier::Read, this );
connect( notifier, SIGNAL(activated(int)),this,
SLOT(readKeyboardData()) );
}
kbdBufferLen = 80;
kbdBuffer = new unsigned char [kbdBufferLen];
kbdIdx = 0;
}
QWSMx21ButtonsHandler::~QWSMx21ButtonsHandler()
{
if ( buttonFD > 0 ) {
::close( buttonFD );
buttonFD = -1;
}
delete notifier;
notifier = 0;
delete [] kbdBuffer;
}
void QWSMx21ButtonsHandler::readKeyboardData()
{
int n = 0;
do {
n = read(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx );
if ( n > 0 )
kbdIdx += n;
} while ( n > 0 );
int idx = 0;
while ( kbdIdx - idx >= 2 ) {
unsigned char *next = kbdBuffer + idx;
unsigned short *code = (unsigned short *)next;
if ( ( *code & 0x8000) != 0x8000) {
idx += 2;
continue;
}
int keycode = Qt::Key_unknown;
//在此添加键盘扫描码映射关系
switch ( (*code) & 0x00ff ) {
case 59:
keycode = Qt::Key_Up;
break;
default:
qDebug("Unrecognised key sequence %d", (int)code );
}
processKeyEvent( 0, keycode, 0, TRUE, FALSE );
idx += 2;
}
int surplus = kbdIdx - idx;
for ( int i = 0; i < surplus; i++ )
kbdBuffer[i] = kbdBuffer[idx+i];
kbdIdx = surplus;
}
2. 添加加载代码
src/kernel/qkeyboard_qws.cpp
/*
* keyboard driver instantiation
*/
QWSKeyboardHandler *QWSServer::newKeyboardHandler( const QString &spec )
{
QWSKeyboardHandler *handler = 0;
QString device;
QString type;
int colon=spec.find(':');
if ( colon>=0 ) {
type = spec.left(colon);
device = spec.mid(colon+1);
} else {
type = spec;
}
if ( type == "Buttons" ) {
#if defined(QT_QWS_YOPY)
handler = new QWSyopyButtonsHandler();
#elif defined(QT_QWS_CASSIOPEIA)
handler = new QWSVr41xxButtonsHandler();
#endif
} else if ( type == "QVFbKeyboard" ) {
handler = new QWSVFbKeyboardHandler();
} else if ( type == "USB" ) {
handler = new QWSUsbKeyboardHandler(device);
} else if ( type == "TTY" ) {
handler = new QWSTtyKeyboardHandler(device);
} else if ( type == "MX21" ) { //这是我们添加的MX21键盘处理类
handler = new QWSMx21ButtonsHandler();
} else {
qWarning( "Keyboard type %s:%s unsupported", spec.latin1(), device.latin1() );
}
return handler;
}
3.重新编译链接
在目标平台上只要设置QWS_KEYBOARD=MX21即可在界面中拦截到键盘事件处理!
这里只是给出了基本原理实现,具体的键盘扫瞄码映射关系得看具体的操作!
最新的qtopia-core 版本也可以参考Vr4xx 实现来做, 在src/gui/embedded/下!
希望对有需要的人有所帮助!