歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 修改Embedded QT鼠標驅動支持IRTOUCH觸摸屏

修改Embedded QT鼠標驅動支持IRTOUCH觸摸屏

日期:2017/3/1 10:24:48   编辑:Linux編程
背景知識:
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. 觸摸屏的降噪和去抖動
由於觸摸屏本身的原因導致每次產生的數據並不是都准確和正確的,所以,我們需要對坐標進行一些處理,
主要目的在於盡量消除誤差,提高觸摸屏的准確度。由於不用硬件會有不同的情況,我們需要變通的處理。這一點也是比較
讓人頭疼的地方。下面就簡單的貼出代碼:
  1. #include "qmouselinuxinput_qws.h"
  2. #include <QScreen>
  3. #include <QSocketNotifier>
  4. #include <qplatformdefs.h>
  5. #include <private/qcore_unix_p.h> // overrides QT_OPEN
  6. #include <errno.h>
  7. #include <linux/input.h>
  8. QT_BEGIN_NAMESPACE
  9. class QWSLinuxInputMousePrivate : public QObject
  10. {
  11. Q_OBJECT
  12. public:
  13. QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *, const QString &);
  14. ~QWSLinuxInputMousePrivate();
  15. void enable(bool on);
  16. void setButton(int num){m_buttons = num;}
  17. private Q_SLOTS:
  18. void readMouseData();
  19. private:
  20. QWSLinuxInputMouseHandler *m_handler;
  21. QSocketNotifier * m_notify;
  22. int m_fd;
  23. int m_x, m_y;
  24. int m_buttons;
  25. };
  26. QWSLinuxInputMouseHandler::QWSLinuxInputMouseHandler(const QString &device)
  27. : QWSCalibratedMouseHandler(device)
  28. {
  29. printf("Enter QWSLinuxInputMouseHandler \n");
  30. d = new QWSLinuxInputMousePrivate(this, device);
  31. }
  32. QWSLinuxInputMouseHandler::~QWSLinuxInputMouseHandler()
  33. {
  34. delete d;
  35. }
  36. void QWSLinuxInputMouseHandler::suspend()
  37. {
  38. d->enable(false);
  39. }
  40. void QWSLinuxInputMouseHandler::resume()
  41. {
  42. d->enable(true);
  43. }
  44. QWSLinuxInputMousePrivate::QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *h, const QString &device)
  45. : m_handler(h), m_notify(0), m_x(0), m_y(0), m_buttons(0)
  46. {
  47. setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler"));
  48. QString dev = QLatin1String("/dev/event0");
  49. if (device.startsWith(QLatin1String("/dev/")))
  50. dev = device;
  51. m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
  52. if (m_fd >= 0) {
  53. m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
  54. connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
  55. } else {
  56. qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno));
  57. return;
  58. }
  59. }
  60. QWSLinuxInputMousePrivate::~QWSLinuxInputMousePrivate()
  61. {
  62. if (m_fd >= 0)
  63. QT_CLOSE(m_fd);
  64. }
  65. void QWSLinuxInputMousePrivate::enable(bool on)
  66. {
  67. if (m_notify)
  68. m_notify->setEnabled(on);
  69. }
  70. void adjuest(int* pX,int* pY)
  71. {
  72. //* pX = 1280.0f / 1248 * (2272 - *pX); // 中間版本
  73. ////* pY = 720.0f / 700 * (*pY - 1030);
  74. ////* pX = (int)(1280.0f / 4062 * (*pX - 7)); // 最舊版本
  75. ////* pY = (int)(720.0f / 4071 * (*pY));
  76. *pX = (int)((*pX)*1280.0f/4050);
  77. *pY = (int)((*pY)*720.0f/4080);
  78. ////* pX = (int)((*pX)*1280.0f/4095); // 最新版本
  79. ////* pY = (int)((*pY)*720.0f/4095);
  80. }
  81. void QWSLinuxInputMousePrivate::readMouseData()
  82. {
  83. if (!qt_screen)
  84. return;
  85. struct ::input_event buffer[32];
  86. int n = 0;
  87. static bool setXflag = 0;
  88. static bool setYflag = 0;
  89. forever {
  90. n += QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
  91. if (n == 0) {
  92. qWarning("Got EOF from the input device.");
  93. return;
  94. } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
  95. qWarning("Could not read from input device: %s", strerror(errno));
  96. return;
  97. } else if (n % sizeof(buffer[0]) == 0) {
  98. break;
  99. }
  100. }
  101. n /= sizeof(buffer[0]);
  102. for (int i = 0; i < n; ++i) {
  103. struct ::input_event *data = &buffer[i];
  104. bool unknown = false;
  105. if (data->type == EV_ABS) {
  106. if (data->code == ABS_X && !setXflag) {
  107. m_x = data->value;
  108. setXflag = 1;
  109. } else if (data->code == ABS_Y && !setYflag) {
  110. m_y = data->value;
  111. setYflag = 1;
  112. } else {
  113. unknown = true;
  114. }
  115. } else if (data->type == EV_SYN && data->code == SYN_REPORT && setXflag && setYflag) {
  116. adjuest(&m_x, &m_y);
  117. printf("########### X=%d Y=%d\n", m_x, m_y);
  118. QPoint pos(m_x, m_y);
  119. //pos = m_handler->transform(pos);
  120. //m_handler->limitToScreen(pos);
  121. setButton(3);
  122. m_handler->mouseChanged(pos, m_buttons);
  123. setXflag = setYflag = 0;
  124. setButton(0);
  125. usleep(1000);
  126. m_handler->mouseChanged(pos, m_buttons);
  127. return;
  128. } else if (data->type == EV_MSC && data->code == MSC_SCAN) {
  129. // kernel encountered an unmapped key - just ignore it
  130. continue;
  131. } else {
  132. unknown = true;
  133. }
  134. if (unknown) {
  135. qWarning("unknown mouse event type=%x, code=%x, value=%x", data->type, data->code, data->value);
  136. }
  137. }
  138. }
  139. QT_END_NAMESPACE
  140. #include "qmouselinuxinput_qws.moc"
Copyright © Linux教程網 All Rights Reserved