觸摸屏啓用VNC後校準異常

QT4.8

問題描述:1920x1080的觸摸屏硬件180°旋轉,所以軟件也要旋轉180°才能正常顯示,但是部署vnc後進行校準,結果觸摸時觸點與界面剛好相反旋轉180°

部署vnc前環境變量QWS_DISPLAY="Transformed:Rot180:Linuxfb:/dev/fb0:depth=24:0"

部署vnc後環境變量

QWS_DISPLAY="Multi:Transformed:Rot180:Linuxfb:/dev/fb0:depth=24:0 VNC:paintonscreen:size=1920x1080:depth=24:1"

1、分析校準程序

從現象來看校準後觸摸點與界面剛好相反旋轉180°,懷疑配置旋轉180°在校驗時失效,調試程序打印qt_screen->transformOrientation()旋轉度數

   發現打印出來是0°,說明旋轉無效。 

  qt_screen->classId()打印其id查看類型結果是QScreen::MultiClass類型

QScreen::MultiClass類型繼承QScreen但是沒有重新實現transformOrientation函數,所以相當於調用QScreen的transformOrientation函數,其實現直接返回0,如下;

int QScreen::transformOrientation() const
{
    return 0;
}

2、將vnc配置還原重新調試qt_screen->classId()是QScreen::TransformedClassl類型,其實現了重新實現transformOrientation函數,能正常返回旋轉角度。

3、爲什麼qt_screen類型不一樣,他是怎麼初始化的?

查看代碼實在構造QApplication時候調用d->construct();裏面的qt_init進行初始化的

QApplication::QApplication(int &argc, char **argv, int _internal)
    : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient, _internal))
{ Q_D(QApplication); d->construct(); }

這裏需要注意的是我們的qt_init/qt4.8.7/src/gui/kernel/qapplication_qws.cpp裏面的函數。

繼續分析找到init_display

qt_fbdpy = new QWSDisplay();

QWSDisplay::QWSDisplay()
{
    d = new Data(0, qws_single_process);
}

 

QWSDisplay::Data::Data(QObject* parent, bool singleProcess)
{
#ifdef QT_NO_QWS_MULTIPROCESS
    Q_UNUSED(parent);
    Q_UNUSED(singleProcess);
#else
    if (singleProcess)
        csocket = 0;
    else {
        csocket = new QWSSocket(parent);
        QObject::connect(csocket, SIGNAL(disconnected()),
                         qApp, SLOT(quit()));
    }
    clientLock = 0;
#endif
    init();
}

void QWSDisplay::Data::init()函數裏面找到qt_get_screen,qt_screen就是在這裏初始化的

QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());

從代碼分析,qt_screen就是根據QWS_DISPLAY配置的第一個冒號前面的驅動名稱創建的

所以配置vnc前創建的qt_screen是QTransformedScreen類型的,配置後是QMultiScreen類型的。

然後連接的時候QMultiScreen會繼續將後面的配置驅動添加到自己的子類下面

 

知道了qt_screen是怎麼來的,就知道怎麼解決:如下

修改校準程序處理:先保存原始qt_screen, old_qt_screen=qt_screen;,然後將其子類TransformedClass的類賦值給qt_screen,使用校準完成後再賦值回去qt_screen=old_qt_screen;

    if(qt_screen->classId()==QScreen::MultiClass)
    {
        QMultiScreen* p=dynamic_cast<QMultiScreen*>(qt_screen);
        if(p)
        {
            QList<QScreen*>tmp= p->subScreens();
            for(int i=0;i<tmp.size();i++)
            {
                if(tmp.at(i)->classId()==QScreen::TransformedClass)
                {
                    qt_screen=tmp.at(i);
                    break;
                }
            }
        }
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章