Chinaunix首页 | 论坛 | 博客
  • 博客访问: 620169
  • 博文数量: 112
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 1406
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-25 18:46
文章分类
文章存档

2011年(1)

2010年(5)

2009年(25)

2008年(81)

我的朋友

分类: LINUX

2008-05-06 16:50:38

 

 

一、Qt3/Embedded的输入设备的驱动接口实现原理分析

       1Qt3/Embedded把与底层硬件相关的源文件统一放在src/embedded目录下,所以我们最好也把自己的设备驱动接口文件放到此目录。

 

2Qt/Embedded中的输入设备分为鼠标类与键盘类。在3.x版本系列中,鼠标设备的抽象基类为QWSMouseHandler,在src/embedded/qmouse_qws.h中定义,键盘设备的抽象基类为QWSKeyboardHandler,在src/embedded/qkbd_qws.h中定义。对于具体的输入设备我们则从这两个基类重新派生出它的实现类。

 

3、系统加载过程分析。Qt/Embedded在体系上为C/S结构,任何一个Qt/Embedded程序都可以作为系统中唯一的一个GUI Server存在。当应用程序首次以系统GUI Server的方式加载时,将建立QWSServer实体。在系统加载构造QWSServer时,将会调用QWSServer::openMouseQWSServer::openKeyboard函数 (建立QWSServer实体的源文件是src/kernel/qwindowsystem_qws.cpp)。这两个函数分别调用QMouseDriverFactory::create()QKbdDriverFactory::create()函数,它们分别是在src/embedded/qmousedriverfactory_qws.hsrc/embedded/qkbddriverfactory_qws.h中定义。这时会根据嵌入式Linux系统的环境变量QWS_MOUSE_PROTOQWS_KEYBOARD获得鼠标类设备和键盘类设备的设备类型和设备节点。打开相应设备并返回相应设备的基类句柄指针给系统,系统通过将该基类指令强制转换为对应的具体子类设备指针,获得对具体鼠标类设备和键盘类设备的调用操作。也就是说,我们只要把自己的设备类放在create()函数中即可。调用关系如下:

QWSServer::openMouse() à QMouseDriverFactory::create() à MyMouseHandler  QWSMouseHandler

鼠标接口的加载过程

QWSServer::openKeyboard() à QKbdDriverFactory::create() à MyKeyboarddHandler QWSKeyboardHandler

键盘接口的加载过程

 

二、在QTE中实现自己的设备驱动接口

    经过上面的分析可以发现,要在QTE中实现自己的设备接口其实是很容易的事情。下面以键盘接口的实现为例,简单介绍一下具体的实现过程,鼠标接口也是差不多的。

QTE中实现自己的键盘接口只需要三步:

1、从抽象基类QWSKeyboardHandler派生出具体类,如MyKbdHandler。为此我们在QTE的子目录src/embedded中新建两个文件mykbd_qws.hmykbd_qws.cpp,内容如下:

(1) mykbd_qws.h的内容:

#ifndef MYKBD_QWS_H

#define MYKBD_QWS_H

 

#include "qkbd_qws.h"  //QT定义抽象基类QWSKeyboardHandler

 

#ifndef QT_NO_MYKBD   //编译时可以通过定义这个变量从而不编译这个模块

 

class MyKbdPrivate;   //我们的键盘设备私有类,实现具体的键盘设备操作,如打开键盘、读键盘数据,解析按键等等。

 

class MyKbdHandler : public QWSKeyboardHandler //供系统调用的键盘句柄

{

public:

    MyKbdHandler(const QString&);

    virtual ~MyKbdHandler();

private:

    MyKbdPrivate *d;

};

 

#endif // QT_NO_MYKBD

#endif // MYKBD_QWS_H

 

(2)mykbd_qws.cpp的内容:

#include "mykbd_qws.h"

 

#ifndef QT_NO_MYKBD

 

#include sys/types.h

#include sys/stat.h

#include sys/ioctl.h

#include fcntl.h

#include termios.h

#include unistd.h

#include errno.h

 

#include qsocketnotifier.h

 

class MyKbdPrivate : public QObject

{

    Q_OBJECT

public:

    MyKbdPrivate( MyKbdHandler *h, const QString& );

    virtual ~MyKbdPrivate();

 

    bool isOpen() { return buttonFD > 0; }

 

private slots:

    void readKeyboardData();

 

private:

    QString terminalName;

    int buttonFD;

    int kbdIdx;

    int kbdBufferLen;

    unsigned char *kbdBuffer;

    QSocketNotifier *notifier;

    MyKbdHandler *handler;

};

 

MyKbdPrivate::MyKbdPrivate(MyKbdHandler *h, const QString &device ) : handler(h)

{

    terminalName = device.isEmpty()?"/dev/mykeyboard":device.latin1();

    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;

}

 

MyKbdPrivate::~ MyKbdPrivate()

{

    if ( buttonFD > 0 ) {

        ::close( buttonFD );

        buttonFD = -1;

    }

    delete notifier;

    notifier = 0;

    delete [] kbdBuffer;

}

 

void MyKbdPrivate::readKeyboardData()

{

int n = 0;

int idx = 0;

    n  = read(buttonFD, kbdBuffer+kbdIdx, 4);

 

    unsigned char *next = kbdBuffer + idx;

    int *code = (int *)next;

    int keycode = Qt::Key_unknown;

 

    switch ( (*code) & 0xff ) {

        case 11:

        keycode = Qt::Key_Backtab;

        break;

        case 12:

        keycode = Qt::Key_Return;

        break;

        case 13:

        keycode = Qt::Key_Tab;

        break;

        case 14:

        keycode = Qt::Key_Up;

        break;

        case 15:

        keycode = Qt::Key_Down;

        break;

 

        default:

qDebug("Unrecognised key code %d", *code );

    }

 

        handler->processKeyEvent( 0, keycode, 0, TRUE, FALSE );

          

}

 

MyKbdHandler::MyKbdHandler(const QString &device)

{

    d = new MyKbdPrivate( this, device );

}

 

MyKbdHandler::~MyKbdHandler()

{

    delete d;

}

 

#include "mykbd_qws.moc"

 

#endif // QT_NO_MYKBD

 

2、把MyKbdHandler加入QkbdDriverFactory::create()函数中。在src/embedded/qkbddriverfactory_qws.cpp文件中加入头文件:

#include “mykbd_qws.h”

然后找到QkbdDriverFactory::create()这个函数,在”Qstring  driver = key.lower();”这一行的后面加上以下几行:

#ifndef QT_NO_MYKBD

      if ( driver == “mykbd” || driver.isEmpty() )

            return new MyKbdHandler( device );

#endif

3、重新编译QT/Embedded并把生成的qt库文件下载到开发板上,然后在目标板上设置系统变量,输入命令:export  QWS_KEYBOARD=’MYKBD:/dev/mykeyboard’

至此QT3/Embedded的键盘设备接口已经完成。
 
阅读(1931) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~