Meego Wiki
Views
From MeeGo wiki
Revision as of 23:50, 7 December 2010 by Jketreno (Talk | contribs)
Jump to: navigation, search

Random tidbits of information about projects I'm hacking on...

Contents

multi-point-touch

During the MeeGo Conference I gave a presentation on multi-point-touch support on MeeGo (overview and video slides). As mentioned during that presentation, to add multi-point-touch to Qt applications running on top of MeeGo 1.1 requires a few changes.

The components that need to be changed are:

  • Kernel -- You need kernel touch drivers that are in sync with upstream
  • Qt -- You need a version of Qt that does not have the RX71 code path enabled

New components:

  • mtdev -- Library to translate kernel protocol A and B to protocol B, adding tracking information
  • xf86-input-mtev -- X input driver that communicates with mtdev to obtain multi-point data from the kernel
  • multipointtouchplugin -- in-application plugin which hooks to the Qt input event filter to process XInput events sent from xf86-input-mtev and injects QTouchEvent's into the Qt event queue

To get the above, you can add my home project:

cd /etc/zypp/repos.d
sudo wget http://download.meego.com/live/home:/jketreno/Trunk/home:jketreno.repo
sudo sed -i -e 's,^gpg,#gpg,g' home:jketreno.repo
zypper refresh

Next, force a re-installation of the packages provided from my home project:

zypper install -f --from=home_jketreno kernel_netbook libqt* qt-qmlviewer mtdev \
       xf86-input-mtev multipointtouchplugin

It will prompt you to switch to the versions of the various packages provided from the above repository. Accept the changes, and reboot.

enabling a native application

The mechanism to talk to the xf86-input-mtev driver is not merged into the Qt package itself. Until that occurs, applications interested in working with touch events need to add the following to the beginning of their application, within the main() function:

foreach (QString path, QCoreApplication::libraryPaths()) {
    QPluginLoader loader(path + "/libmultipointtouchplugin.so");
    loader.load();
    if (loader.isLoaded()) {
        loader.instance();
        break;
    }
}

At the beginning of the file, you also need to include QPluginLoader:

#include <QPluginLoader>

And that's it.

enabling a QML application

The version of qmlviewer built and installed with the Qt package in my home project has the above code enabled, providing Touch events into qml applications run within qmlviewer. If you are loading your QML application using your own native loader, you will need to follow the steps above for enabling a native applications.

qml-gesturearea

As Frederik Gladhorn indicated during his talk at the MeeGo Conference in Dublin, the folks over at Qt have been working on an improved QML GestureArea component.

You can pull and play with what they're cooking as follows:

git clone git://gitorious.org/qt-labs/qml-gesturearea.git
git clone git://gitorious.org/qt-labs/qml-gestures-examples.git

To build qml-gesturearea, you may need to patch it (I did):

cd qml-gesturearea
sed -i -e 's,q->timeout(),700,g' qdeclarativegesturerecognizers.cpp
qmake
make && sudo make install

Assuming you are using the qmlviewer provided with qt-qmlviewer in my home project, you should then be able to run the following:

qmlviewer ../qml-gestures-examples/dashboard/MainWidget.qml

and interact with the example.

how multipointouchplugin works

The multi-point touch plugin is intended to proof out multi-point touch interaction with Qt, without having to make invasive changes to Qt 4.7 itself. Ultimately, by MeeGo 1.2, we need to create a patch to Qt deployed on MeeGo such that each application does not have to load the plugin.

Internally, the plug-in (in the MultiPointTouch constructor) first make sure the XInput extension exists and supports version 2.0 of the protocol. It then walks through all of the available input devices looking for any that expose a valuator with the "Abs MT Tracking ID" label. For each device found, it subscribes to button press, release, and motion events.

The plugin then inserts itself into the QCoreApplication's event filter via setEventFilter().

The plugin's registered eventFilter does a few checks to determine that an inbound event is the correct type, and if so, it then calls a method to translate the event to Touch events (translateEvent)

Within translateEvent, the valuators are parsed, scaled, and set onto list of active QTouchEvent::TouchPoint's. This is where the hack comes in...

Currently if each touch point is immediately fed into the Qt input queue, via qt_translateRawTouchEvent, input becomes very laggy and the Qt application behaves very sluggishly. So, each of the TouchPoints is instead placed into a pending queue and then a singleShot timer is fired off to process the touch points at some point later. Within that timer, if there are pending events in the QCoreApplication event queue, the timer is re-scheduled.

Basically the plugin needs to defer passing the touch events into Qt until there are no more input events coming from X. I don't know the right way to do this. If the singleShot() is scheduled without any timeout value (0), then the code falls back to only sending one touch point at a time again, which causes the sluggish behavior. Hard coding 10ms into the singleShot is definitely not the way this should be done.

Personal tools