您的位置:首页 > 编程语言 > Qt开发

修改Embedded QT鼠标驱动支持IRTOUCH触摸屏

2012-04-07 18:28 183 查看
背景知识:
http://doc.qt.nokia.com/4.6/qt-embedded-architecture.html    Qt for Embedded Linux Architecture   
http://doc.qt.nokia.com/4.6/qt-embedded-pointer.html#available-drivers  Qt for Embedded Linux Pointer Handling  

QTSRC/src/gui/embeded/qmouselinuxinput_qws.cpp     

主要的要点是:

        1. EQT 默认只支持“pc”类型的鼠标驱动,具体来说就是如下类型:Auto、IntelliMouse、Microsoft、MouseSystems。

            要使EQT 支持Linux input子系统的鼠标驱动,在编译QT时 configure 要添加参数: -qt-mouse-linuxinput

            (具体的configure的帮助请运行: ./configure -embedded -help .)

        2. 确保触摸屏提交到Linux input子系统的坐标数据是正确的,我们需要通过解析/dev/event0 的数据来证明

原理说明:

1. 分辨率转化和校准

         其实,这一款32寸的IRTOUCH产生的坐标值是绝对坐标,范围x、y均为 0~4096。所以,我们运行的QT程序如果直接获取

event0产生的坐标的话,鼠标位置便会超出屏幕的显示范围,因此,我们需要进行一下坐标值转化,具体的函数如下:

void adjuest(int* pX,int* pY) 

{

        //* pX = 1280.0f / 1248 * (2272 - *pX); // 中间版本

        ////* pY = 720.0f / 700 * (*pY - 1030);

            

        ////* pX = (int)(1280.0f / 4062 * (*pX - 7)); // 最旧版本

        ////* pY = (int)(720.0f / 4071 * (*pY));

        *pX = (int)((*pX)*1280.0f/4050);

        *pY = (int)((*pY)*720.0f/4080);

            

        ////* pX = (int)((*pX)*1280.0f/4095); // 最新版本

        ////* pY = (int)((*pY)*720.0f/4095);

}

该函数就可以将原来4096*4096的分辨率转换成 1280*720;至于具体的数值,我们需要根据实际的屏幕产生的数据进行修改,

重点在于四角和中间点。 

分辨率一旦设置合适,屏幕鼠标也就会校准,该函数的作用类似于void QWSLinuxInputMousePrivate::readMouseData()函数中

调用的 pos = m_handler->transform(pos)。transform()函数会根据/etc/pointercal来进行校准,如果你没有运行过校准程序

默认会没有该文件的。(QT自带的例子里面有一个校准程序:qt\examples\qws\mousecalibration。但是,由于不同的嵌入式

平台采用的芯片差异性很大,所以,这个校准程序往往无法使用,所以,才会自己编写一个adjuest()函数来调整原始坐标值。)

2. 触摸屏的降噪和去抖动

      由于触摸屏本身的原因导致每次产生的数据并不是都准确和正确的,所以,我们需要对坐标进行一些处理,

主要目的在于尽量消除误差,提高触摸屏的准确度。由于不用硬件会有不同的情况,我们需要变通的处理。这一点也是比较

让人头疼的地方。下面就简单的贴出代码:
#include "qmouselinuxinput_qws.h"
#include <QScreen>
#include <QSocketNotifier>
#include <qplatformdefs.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
#include <errno.h>
#include <linux/input.h>

QT_BEGIN_NAMESPACE

class QWSLinuxInputMousePrivate : public QObject
{
Q_OBJECT
public:
QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *, const QString &);
~QWSLinuxInputMousePrivate();

void enable(bool on);
void setButton(int num){m_buttons = num;}

private Q_SLOTS:
void readMouseData();

private:
QWSLinuxInputMouseHandler *m_handler;
QSocketNotifier *          m_notify;
int                        m_fd;
int                        m_x, m_y;
int                        m_buttons;
};

QWSLinuxInputMouseHandler::QWSLinuxInputMouseHandler(const QString &device)
: QWSCalibratedMouseHandler(device)
{
printf("Enter QWSLinuxInputMouseHandler \n");
d = new QWSLinuxInputMousePrivate(this, device);
}

QWSLinuxInputMouseHandler::~QWSLinuxInputMouseHandler()
{
delete d;
}

void QWSLinuxInputMouseHandler::suspend()
{
d->enable(false);
}

void QWSLinuxInputMouseHandler::resume()
{
d->enable(true);
}

QWSLinuxInputMousePrivate::QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *h, const QString &device)
: m_handler(h), m_notify(0), m_x(0), m_y(0), m_buttons(0)
{
setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler"));

QString dev = QLatin1String("/dev/event0");
if (device.startsWith(QLatin1String("/dev/")))
dev = device;

m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
if (m_fd >= 0) {
m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
} else {
qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno));
return;
}
}

QWSLinuxInputMousePrivate::~QWSLinuxInputMousePrivate()
{
if (m_fd >= 0)
QT_CLOSE(m_fd);
}

void QWSLinuxInputMousePrivate::enable(bool on)
{
if (m_notify)
m_notify->setEnabled(on);
}
void adjuest(int* pX,int* pY)
{
//* pX = 1280.0f / 1248 * (2272 - *pX); // 中间版本
////* pY = 720.0f / 700 * (*pY - 1030);

////* pX = (int)(1280.0f / 4062 * (*pX - 7)); // 最旧版本
////* pY = (int)(720.0f / 4071 * (*pY));
*pX = (int)((*pX)*1280.0f/4050);
*pY = (int)((*pY)*720.0f/4080);

////* pX = (int)((*pX)*1280.0f/4095); // 最新版本
////* pY = (int)((*pY)*720.0f/4095);
}

void QWSLinuxInputMousePrivate::readMouseData()
{
if (!qt_screen)
return;

struct ::input_event buffer[32];
int n = 0;
static bool setXflag = 0;
static bool setYflag = 0;

forever {
n += QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);

if (n == 0) {
qWarning("Got EOF from the input device.");
return;
} else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
qWarning("Could not read from input device: %s", strerror(errno));
return;
} else if (n % sizeof(buffer[0]) == 0) {
break;
}
}

n /= sizeof(buffer[0]);

for (int i = 0; i < n; ++i) {
struct ::input_event *data = &buffer[i];

bool unknown = false;
if (data->type == EV_ABS) {
if (data->code == ABS_X && !setXflag) {
m_x = data->value;
setXflag = 1;
} else if (data->code == ABS_Y && !setYflag) {
m_y = data->value;
setYflag = 1;
} else {
unknown = true;
}
} else if (data->type == EV_SYN && data->code == SYN_REPORT && setXflag && setYflag) {
adjuest(&m_x, &m_y);
printf("########### X=%d Y=%d\n", m_x, m_y);
QPoint pos(m_x, m_y);
//pos = m_handler->transform(pos);
//m_handler->limitToScreen(pos);
setButton(3);
m_handler->mouseChanged(pos, m_buttons);
setXflag = setYflag = 0;
setButton(0);
usleep(1000);
m_handler->mouseChanged(pos, m_buttons);
return;
} else if (data->type == EV_MSC && data->code == MSC_SCAN) {
// kernel encountered an unmapped key - just ignore it
continue;
} else {
unknown = true;
}
if (unknown) {
qWarning("unknown mouse event type=%x, code=%x, value=%x", data->type, data->code, data->value);
}
}
}

QT_END_NAMESPACE
#include "qmouselinuxinput_qws.moc"


                
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息