[meego-commits] 8093: Changes to MeeGo:1.1:Core:Testing/meegotouch-feedbackreactionmaps

Fathi Boudra no_reply at build.meego.com
Tue Oct 5 10:36:51 UTC 2010


Hi,
I have made the following changes to meegotouch-feedbackreactionmaps in project MeeGo:1.1:Core:Testing. Please review and accept ASAP.

Thank You,
Fathi Boudra

[This message was auto-generated]

---

Request #8093:

  submit:   devel:qt-mtf:MeeGo:1.1/meegotouch-feedbackreactionmaps(r2) -> MeeGo:1.1:Core:Testing/meegotouch-feedbackreactionmaps


Message:
    * Wed Sep 29 2010 Fathi Boudra <fathi.boudra at nokia.com> - 0.14.0.5
- Add disable_tests_build.patch: tests should be shipped in their own package
   and the build is actually broken (fixed in newer version). (BMC#7913)
- Remove patches:
  0002-Fix-build-breakage-caused-by-missing-stdint.h-includ.patch - useless
  meegotouchfeedbackreactionmaps-0.14.0-remove-evdev.patch - useless
- Various cleanup in the packaging
- Cleanup build requirements
- Use qmake builder
- Set project URL
* Wed Sep 08 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.5
- Update to release tag 0.14.0-5
* Mon Jul 26 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.1
* Thu Jul 08 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.1
* Wed Jun 16 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.1

State:   new          2010-10-05T03:36:50 boudra
Comment: None



changes files:
--------------
--- meegotouch-feedbackreactionmaps.changes
+++ meegotouch-feedbackreactionmaps.changes
@@ -1 +1,15 @@
-* Mon Jul 26 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> 0.14.0.1
+* Wed Sep 29 2010 Fathi Boudra <fathi.boudra at nokia.com> - 0.14.0.5
+- Add disable_tests_build.patch: tests should be shipped in their own package
+   and the build is actually broken (fixed in newer version). (BMC#7913)
+- Remove patches:
+  0002-Fix-build-breakage-caused-by-missing-stdint.h-includ.patch - useless
+  meegotouchfeedbackreactionmaps-0.14.0-remove-evdev.patch - useless
+- Various cleanup in the packaging
+- Cleanup build requirements
+- Use qmake builder
+- Set project URL
+
+* Wed Sep 08 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.5
+- Update to release tag 0.14.0-5
+
+* Mon Jul 26 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.1
@@ -5 +19 @@
-* Thu Jul 08 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> 0.14.0.1
+* Thu Jul 08 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.1
@@ -10 +24 @@
-* Wed Jun 16 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> 0.14.0.1
+* Wed Jun 16 2010 Kaitlin Rupert <kaitlin.rupert at intel.com> - 0.14.0.1
@@ -23 +36,0 @@
-

old:
----
  0002-Fix-build-breakage-caused-by-missing-stdint.h-includ.patch
  meegotouch-feedbackreactionmaps-0.14.0.1.tar.bz2
  meegotouchfeedbackreactionmaps-0.14.0-remove-evdev.patch

new:
----
  disable_tests_build.patch
  meegotouch-feedbackreactionmaps-0.14.0.5.tar.bz2

spec files:
-----------
--- meegotouch-feedbackreactionmaps.spec
+++ meegotouch-feedbackreactionmaps.spec
@@ -1,45 +1,31 @@
 # 
-# Do not Edit! Generated by:
-# spectacle version 0.18
+# Do NOT Edit the Auto-generated Part!
+# Generated by: spectacle version 0.20
 # 
 # >> macros
 # << macros
 
 Name:       meegotouch-feedbackreactionmaps
-Summary:    MeeGo Feedback ReactionMap Plugin
-Version:    0.14.0.1
+Summary:    MeeGo Touch Feedback ReactionMaps Plugin
+Version:    0.14.0.5
 Release:    1
 Group:      System/Libraries
-License:    LGPL v2.1
-URL:        http://www.meego.com
+License:    LGPLv2.1
+URL:        http://meego.gitorious.org/meegotouch/meegotouch-feedbackreactionmaps
 Source0:    %{name}-%{version}.tar.bz2
 Source100:  meegotouch-feedbackreactionmaps.yaml
-Patch0:     0002-Fix-build-breakage-caused-by-missing-stdint.h-includ.patch
-Patch1:     meegotouchfeedbackreactionmaps-0.14.0-remove-evdev.patch
+Patch0:     disable_tests_build.patch
 Requires(post): /sbin/ldconfig
 Requires(postun): /sbin/ldconfig
-BuildRequires:  pkgconfig(QtCore) >= 4.6.0
-BuildRequires:  pkgconfig(QtDBus)
-BuildRequires:  pkgconfig(QtOpenGL)
-BuildRequires:  pkgconfig(QtNetwork)
 BuildRequires:  pkgconfig(QtGui)
+BuildRequires:  pkgconfig(meegotouch-feedback)
 BuildRequires:  pkgconfig(meegotouch)
-BuildRequires:  pkgconfig(gstreamer-0.10)
-BuildRequires:  pkgconfig(gstreamer-base-0.10)
-BuildRequires:  pkgconfig(gstreamer-plugins-base-0.10)
-BuildRequires:  pkgconfig(dbus-1)
 BuildRequires:  pkgconfig(xdamage)
-BuildRequires:  pkgconfig(icu)
 BuildRequires:  pkgconfig(x11)
-BuildRequires:  pkgconfig(contextprovider-1.0)
-BuildRequires:  pkgconfig(gl)
-BuildRequires:  pkgconfig(libpulse)
-BuildRequires:  pkgconfig(libpulse-simple)
-BuildRequires:  pkgconfig(libpulse-mainloop-glib)
-BuildRequires:  pkgconfig(libpulse-browse)
-BuildRequires:  pkgconfig(meegotouch-feedback)
-BuildRequires:  pkgconfig(xi)
 BuildRequires:  pkgconfig(xext)
+BuildRequires:  pkgconfig(xi)
+BuildRequires:  pkgconfig(xtst)
+BuildRequires:  pkgconfig(xorg-evdev)
 BuildRequires:  fdupes
 Provides:   meegotouchfeedbackreactionmaps > 0.14.0
 Provides:   duifeedback-reactionmaps > 0.14.0
@@ -48,34 +34,33 @@
 
 
 %description
-MeeGo Feedback Reactionmap Plugin
+This package contains the MeeGo Touch Feedback Reactionmaps plugin.
+
 
 
 %package devel
-Summary:    Feedback Reactionmap Deveopment Package
+Summary:    MeeGo Touch Feedback Reactionmaps development files
 Group:      Development/Libraries
 Requires:   %{name} = %{version}-%{release}
 
 %description devel
-This package contains the reactionmaps feedback plugin
+This package contains the MeeGo Feedback Reactionmaps plugin development files.
+
 
 
 %prep
 %setup -q -n %{name}-%{version}
 
-# 0002-Fix-build-breakage-caused-by-missing-stdint.h-includ.patch
+# disable_tests_build.patch
 %patch0 -p1
-# meegotouchfeedbackreactionmaps-0.14.0-remove-evdev.patch
-%patch1 -p1
 # >> setup
 # << setup
 
 %build
 # >> build pre
-export PATH=$PATH:/usr/lib/qt4/bin
-qmake
 # << build pre
 
+%qmake 
 
 make %{?jobs:-j%jobs}
 
@@ -84,30 +69,26 @@
 %install
 rm -rf %{buildroot}
 # >> install pre
-export INSTALL_ROOT=%{buildroot}
 # << install pre
-%make_install 
+%qmake_install
 
 # >> install post
-%fdupes %{buildroot}%{_datadir}
-
-# meegotouchfeedbackreactionmaps.pc
 mkdir -p %{buildroot}%{_libdir}/pkgconfig
-cat >%{buildroot}%{_libdir}/pkgconfig/meegotouch-feedbackreactionmaps.pc<<EOF
+cat > %{buildroot}%{_libdir}/pkgconfig/meegotouch-feedbackreactionmaps.pc << EOF
 prefix=/usr
 exec_prefix=${prefix}
 libdir=${exec_prefix}/lib
 includedir=${prefix}/include/meegoreactionmap
 
 Name: meegotouch-feedbackreactionmaps
-Description: MeeGo Feedback ReactionMap Plugin
+Description: MeeGo Touch Feedback ReactionMaps plugin
 Version: %{version}
 Requires: QtGui
 Cflags: -I${includedir}
 Libs: -L${libdir} -lmeegoreactionmap
 EOF
-
 # << install post
+%fdupes  %{buildroot}/%{_datadir}
 
 
 
@@ -122,10 +103,10 @@
 %files
 %defattr(-,root,root,-)
 # >> files
-%defattr(-, root, root, -)
-%config /etc/meegofeedbackd/reactionmaps.conf
+%config %{_sysconfdir}/meegofeedbackd/reactionmaps.conf
 %{_bindir}/meegoreactionmap-viewer
 %{_libdir}/meegofeedbackd/libmeegofeedback-reactionmap.so
+%{_libdir}/meegofeedbackd/libmeegofeedback-reactionmap-xrecord.so
 %{_libdir}/*.so.*
 # << files
 
@@ -133,14 +114,9 @@
 %files devel
 %defattr(-,root,root,-)
 # >> files devel
-%defattr(-, root, root, -)
 %{_datadir}/qt4/mkspecs/features/*.prf
 %{_includedir}/meegoreactionmap
 %{_libdir}/*.so
-%{_libdir}/libmeegoreactionmap-tests
-%{_datadir}/libmeegoreactionmap-tests
-%{_libdir}/libmeegoreactionmap-mcompositor-tests
-%{_datadir}/libmeegoreactionmap-mcompositor-tests
 %{_libdir}/pkgconfig/meegotouch-feedbackreactionmaps.pc
 # << files devel
 

other changes:
--------------

++++++ disable_tests_build.patch (new)
--- disable_tests_build.patch
+++ disable_tests_build.patch
+Description: disable tests build
+Author: Fathi Boudra <fathi.boudra at nokia.com>
+--- a/meegofeedback-reactionmaps.pro
++++ b/meegofeedback-reactionmaps.pro
+@@ -1,8 +1,6 @@
+ CONFIG += ordered
+ TEMPLATE    = subdirs
+ SUBDIRS     = src \
+-              tests \
+-	      mcompositor-tests \
+               tools
+ 
+ include (conf/conf.pri)

++++++ meegotouch-feedbackreactionmaps-0.14.0.1.tar.bz2 -> meegotouch-feedbackreactionmaps-0.14.0.5.tar.bz2
--- debian/api
+++ debian/api
+interface: libmeegoreactionmap
+type: library
+scope: Platform 
+state: unstable 
+libs-pkg: libmeegoreactionmap0
+dev-pkg: libmeegoreactionmap-dev
+
--- debian/changelog
+++ debian/changelog
@@ -1,3 +1,16 @@
+meegofeedback-reactionmaps (0.14.0-5) unstable; urgency=low
+
+  * Fix for a memory leak similar to NB#182656 in meegofeedbackd daemon
+  * Fix a bug in MReactionMap::fillItemBoundRect()
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com>  Mon, 02 Aug 2010 14:31:32 +0200
+
+meegofeedback-reactionmaps (0.14.0-4) unstable; urgency=low
+
+  * Fix NB#182188 - meegofeedback-reactionmaps is not buildable with cs2009q3 (hardfp) toolchain
+
+ -- Csaba Kertesz <csaba.kertesz at vincit.fi>  Wed, 28 Jul 2010 00:13:46 +0200
+
 meegofeedback-reactionmaps (0.14.0-3) unstable; urgency=low
 
   * Modified documentation to comply with guidelines
--- debian/control
+++ debian/control
@@ -2,14 +2,14 @@
 Section: libs
 Priority: optional
 Maintainer: Csaba Kertesz <csaba.kertesz at vincit.fi>
-Build-Depends: debhelper (>= 4.0.0), libmeegofeedback-dev (>= 0.9.1), libqt4-dev (>= 4.6) | libqt4-maemo5-dev (>= 4.6), libmeegotouch-dev, libx11-dev, libxi-dev, libexpat1-dev, libxext-dev, xserver-xorg-input-evdev-dev | no-evdev-dev, pkg-config (>= 0.22), zlib1g-dev
+Build-Depends: debhelper (>= 4.0.0), libmeegofeedback-dev (>= 0.9.1), libqt4-dev (>= 4.6) | libqt4-maemo5-dev (>= 4.6), libmeegotouch-dev, libx11-dev, libxi-dev, libexpat1-dev, libxext-dev, xserver-xorg-input-evdev-dev | no-evdev-dev, pkg-config (>= 0.22), zlib1g-dev, libxtst-dev
 Standards-Version: 3.6.1
 
 Package: meegofeedback-reactionmap
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}, libmeegoreactionmap0 (= ${Source-Version})
-Replaces: duifeedback-reactionmap
-Conflicts: duifeedback-reactionmap
+Replaces: duifeedback-reactionmap, meegofeedback-reactionmap-xrecord
+Conflicts: duifeedback-reactionmap, meegofeedback-reactionmap-xrecord
 Description: meegofeedbackd source that reacts to touchscreen events
  meegofeedback-reactionmap is a meegofeedbackd source that listens to events coming
  from the kernel input subsystem and plays the corresponding feedbacks
@@ -20,10 +20,29 @@
 Architecture: any
 Section: devel
 Depends: meegofeedback-reactionmap (= ${Source-Version}), ${shlibs:Depends}
-Replaces: duifeedback-reactionmap-dbg
+Replaces: duifeedback-reactionmap-dbg, meegofeedback-reactionmap-xrecord-dbg
 Description: meegofeedback-reactionmap debug package
  meegofeedback-reactionmap debug symbols.
 
+Package: meegofeedback-reactionmap-xrecord
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libmeegoreactionmap0 (= ${Source-Version})
+Replaces: duifeedback-reactionmap, meegofeedback-reactionmap
+Conflicts: duifeedback-reactionmap, meegofeedback-reactionmap
+Description: meegofeedbackd source that reacts to button press and release events from X server
+ meegofeedback-reactionmap is a meegofeedbackd source that listens to button press
+ and release events coming from the X server using XRecord extension and plays the
+ corresponding feedbacks according to its reaction maps painted by client applications
+ using libmeegoreactionmap0. NOTE: This package is meant for testing purposes only.
+
+Package: meegofeedback-reactionmap-xrecord-dbg
+Architecture: any
+Section: devel
+Depends: meegofeedback-reactionmap-xrecord (= ${Source-Version}), ${shlibs:Depends}
+Replaces: duifeedback-reactionmap-dbg, meegofeedback-reactionmap-dbg
+Description: meegofeedback-reactionmap-xrecord debug package
+ meegofeedback-reactionmap-xrecord debug symbols.
+
 Package: libmeegoreactionmap0
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}
--- debian/meegofeedback-reactionmap-xrecord.dirs
+++ debian/meegofeedback-reactionmap-xrecord.dirs
+/usr/lib/meegofeedbackd
+/etc/meegofeedbackd
--- debian/meegofeedback-reactionmap-xrecord.install
+++ debian/meegofeedback-reactionmap-xrecord.install
+/usr/lib/meegofeedbackd/libmeegofeedback-reactionmap-xrecord.so
+/etc/meegofeedbackd/*
--- debian/meegofeedback-reactionmap-xrecord.postinst
+++ debian/meegofeedback-reactionmap-xrecord.postinst
+#! /bin/sh
+# postinst script for MeeGo Touch Feedback Framework reaction maps source
+
+set -e
+
+case "$1" in
+	configure)
+        mkdir -p /usr/lib/meegofeedbackd/sources
+	if ! [ -e "/usr/lib/meegofeedbackd/sources/libmeegofeedback-reactionmap-xrecord.so" ]; then
+		ln -s /usr/lib/meegofeedbackd/libmeegofeedback-reactionmap-xrecord.so /usr/lib/meegofeedbackd/sources/libmeegofeedback-reactionmap-xrecord.so
+	fi
+	;;
+	abort-upgrade|abort-remove|abort-deconfigure)
+	;;
+	*)
+	echo "postinst called with unknown argument \`$1'" >&2
+	exit 1
+	;;
+esac
+
+exit 0
--- debian/meegofeedback-reactionmap-xrecord.postrm
+++ debian/meegofeedback-reactionmap-xrecord.postrm
+#!/bin/sh
+set -e
+
+if [ "$1" = "remove" ] ; then
+	rm -f /usr/lib/meegofeedbackd/sources/libmeegofeedback-reactionmap-xrecord.so
+fi
+
+#DEBHELPER#
+
+exit 0
+
--- debian/meegofeedback-reactionmap.install
+++ debian/meegofeedback-reactionmap.install
@@ -1,2 +1,2 @@
-/usr/lib/meegofeedbackd/*
+/usr/lib/meegofeedbackd/libmeegofeedback-reactionmap.so
 /etc/meegofeedbackd/*
--- debian/rules
+++ debian/rules
@@ -98,7 +98,8 @@
 #	dh_installman
 	dh_link
 	dh_strip --dbg-package=libmeegoreactionmap0 -Xmeegofeedback-reactionmap
-	dh_strip --dbg-package=meegofeedback-reactionmap
+	dh_strip --dbg-package=meegofeedback-reactionmap -Xmeegofeedback-reactionmap-xrecord
+	dh_strip --dbg-package=meegofeedback-reactionmap-xrecord
 	dh_compress
 	dh_fixperms
 #	dh_perl
--- doc/doc.pri
+++ doc/doc.pri
@@ -8,7 +8,7 @@
 } else {
     system( mkdir -p $${OUT_PWD}/doc/html )
 
-    doc.commands = ( sed -e \"s:\@MEEGOREACTIONMAP_SRC_DIR\@:$${IN_PWD}:g\" \
+    doc.commands = ( sed -e \"s:@MEEGOREACTIONMAP_SRC_DIR@:$${IN_PWD}:g\" \
                          $${IN_PWD}/mdoxy.cfg.in > doc/mdoxy.cfg );
 
     doc.commands+= ( $${DOXYGEN_BIN} doc/mdoxy.cfg );
--- mcompositor-tests/ft_windowstacking/mwindowstack.cpp
+++ mcompositor-tests/ft_windowstacking/mwindowstack.cpp
@@ -18,13 +18,18 @@
 #include <QTimer>
 #include <MApplicationPage>
 #include <MApplicationWindow>
+#include <MButton>
 #include <MLabel>
 #include <MTextEdit>
 #include <QString>
 
+#include <QGraphicsView>
+#include <QGraphicsLinearLayout>
+#include <QDebug>
+
 #include "mwindowstack.h"
 
-MWindowStack::MWindowStack(int argc, char **argv)
+MWindowStack::MWindowStack(int &argc, char **argv)
     : MApplication(argc, argv)
 {
     currentlyVisible = -1;
@@ -46,6 +51,7 @@
         windowName.append(QString::number(window->winId(), 16));
 
         page = new MApplicationPage();
+        page->setWindowTitle(QString("Page #%1").arg(i));
 
         new MLabel(windowName, page->centralWidget());
 
@@ -53,10 +59,7 @@
         pageList << page;
     }
 
-    QTimer *timer;
-    timer = new QTimer(this);
-    connect(timer, SIGNAL(timeout()), this, SLOT(runTest()));
-    timer->start(0);
+    QTimer::singleShot(0, this, SLOT(runTest()));
 }
 
 MWindowStack::~MWindowStack()
@@ -123,9 +126,71 @@
         }
     }
 
+    vkbTest();
     qDebug() << "Test was successful.";
 
     quit();
 }
 
+void MWindowStack::vkbTest()
+{
+    QString str;
+
+    MApplicationWindow *window = new MApplicationWindow;
+    MApplicationPage *page = new MApplicationPage;
+    QGraphicsLinearLayout layout(Qt::Horizontal, page->centralWidget());
+    MTextEdit *text = new MTextEdit(MTextEditModel::SingleLine, "freetext");
+    MButton* button = new MButton();
+
+    layout.addItem(text);
+    layout.addItem(button);
+    page->centralWidget()->setLayout(&layout);
+    page->setWindowTitle(QString("Test Page"));
+
+    windowList << window;
+    pageList << page;
+
+    window->show();
+    window->raise();
+    page->appear(window);
+
+    text->setFocus();
+
+    // Make sure events will be processed to get the window really on top
+    flush();
+    processEvents();
+    syncX();
+
+    usleep(1000000);
+
+    int timeout = 0;
+    while (true) {
+        if (xStack.hasChanged() == true) {
+            timeout = 0;
+        }
+        if (timeout > 100) {
+            break;
+        }
+        timeout++;
+        usleep(10000);
+    }
+
+    // Get current actual stacking order
+    const QList<quint32> actualOrder(xStack.getWindowOrder());
+
+    for (int i = 0; i < actualOrder.size(); ++i){
+        str = xStack.Display_Window_Id(actualOrder[i], false);
+        qDebug() << __PRETTY_FUNCTION__ << str;
+    }
+
+    str = xStack.Display_Window_Id(actualOrder[0], false);
+    qDebug() << __PRETTY_FUNCTION__ << str;
+
+    if(str != "MInputMethod"){
+        qWarning() << "the topmost is NOT vkb.";
+    }
+    // Set the focus to something else to close the VKB
+    button->setFocus();
+    processEvents();
+}
 
--- mcompositor-tests/ft_windowstacking/mwindowstack.h
+++ mcompositor-tests/ft_windowstacking/mwindowstack.h
@@ -29,7 +29,7 @@
     Q_OBJECT
 
 public:
-    MWindowStack(int argc, char **argv);
+    MWindowStack(int &argc, char **argv);
     virtual ~MWindowStack();
 
 public slots:
@@ -42,6 +42,7 @@
     QList<quint32> windowListStackOrder;
     QList<MApplicationPage*> pageList;
     XWindowStack xStack;
+    void vkbTest();
 };
 
 #endif
--- mcompositor-tests/ft_windowstacking/xwindowstack.cpp
+++ mcompositor-tests/ft_windowstacking/xwindowstack.cpp
@@ -19,6 +19,16 @@
 #include <QDebug>
 #include <X11/Xatom.h>
 
+#include <QString>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/extensions/shape.h>
+#include <X11/Xlocale.h>
+#include <stdio.h>
+#include <stdlib.h>
+
 XWindowStack::XWindowStack()
     : display(NULL),
       netClientListStackingAtom(None),
@@ -160,6 +170,41 @@
     return ret;
 }
 
+QString XWindowStack::Display_Window_Id(Window window, bool newline_wanted)
+{
+    XTextProperty tp;
+    QString str("");
+
+    if (!window) {
+    printf(" (none)");
+    }
+    if (!XGetWMName(display, window, &tp)) { /* Get window name if any */
+        str = "no_name";
+        } else if (tp.nitems > 0) {
+            {
+                int count = 0, i, ret;
+                char **list = NULL;
+                ret = XmbTextPropertyToTextList(display, &tp, &list, &count);
+                if((ret == Success || ret > 0) && list != NULL){
+                    for(i=0; i<count; i++)
+                        //printf("%s", list[i]);
+                        str.append(list[i]);
+                    XFreeStringList(list);
+                } else {
+                    printf("%s", tp.value);
+                }
+            }
+    } else {
+        str = "no_name";
+    }
+
+    if (newline_wanted)
+    printf("\n");
+
+    return str;
+}
+
+
 bool XWindowStack::verifyStackingOrder(const QList<quint32> &expectedOrder)
 {
     QList<quint32> actualOrder;
@@ -220,14 +265,21 @@
 
 void XWindowStack::printStacks(const QList<quint32> &expectedOrder, const QList<quint32> &actualOrder)
 {
+    //QString str_expected("");
+    //QString str_actual("");
+
     qCritical() << "Expected order:";
     for (int i = 0; i < expectedOrder.size(); ++i) {
         qCritical() << i << ":" << hex << expectedOrder[i];
+        //str_expected = Display_Window_Id(expectedOrder[i], false);
+        //qDebug("%s",str_expected.toAscii().data());
     }
     qCritical() << "---";
     qCritical() << "Actual order:";
     for (int i = 0; i < actualOrder.size(); ++i) {
         qCritical() << i << ":" << hex << actualOrder[i];
+        //str_actual = Display_Window_Id(actualOrder[i], false);
+        //qDebug("%s",str_actual.toAscii().data());
     }
     qCritical() << "===";
 }
--- mcompositor-tests/ft_windowstacking/xwindowstack.h
+++ mcompositor-tests/ft_windowstacking/xwindowstack.h
@@ -18,6 +18,9 @@
 #define XWINDOWSTACK_H
 
 #include <QList>
+
+#include <QString>
+
 // The next three files must be included before the X include files
 #include <QDataStream>
 #include <QTextStream>
@@ -35,12 +38,12 @@
     // Returns true if stacking has changed since last call
     bool hasChanged();
 
-    bool verifyStackingOrder(const QList<quint32> &expectedOrder);
-
-private:
     QList<quint32> getWindowOrder();
+    bool verifyStackingOrder(const QList<quint32> &expectedOrder);
+    QString Display_Window_Id(Window window, bool newline_wanted);
     void printStacks(const QList<quint32> &expectedOrder, const QList<quint32> &actualOrder);
 
+private:
     Display* display;
     Window rootWindow;
     Atom netClientListStackingAtom;
--- meegofeedback-reactionmaps.pro
+++ meegofeedback-reactionmaps.pro
@@ -4,6 +4,7 @@
               tests \
 	      mcompositor-tests \
               tools
+
 include (conf/conf.pri)
 include (shared.pri)
 
@@ -12,6 +13,7 @@
 } else {
     IS_OUT_OF_SOURCE = 1
 }
+
 include (doc/doc.pri)
 
 QMAKE_EXTRA_TARGETS += setup
--- src/client/mreactionmap.cpp
+++ src/client/mreactionmap.cpp
@@ -21,6 +21,7 @@
 #include <QCoreApplication>
 #include <QGraphicsItem>
 #include <QGraphicsScene>
+#include <QGraphicsView>
 #include <QWidget>
 
 #include <mfsettings.h>
@@ -155,11 +156,29 @@
 
 void MReactionMap::fillItemBoundRect(QGraphicsItem *item)
 {
-    if (!item) {
+    if (!item || !item->scene() || item->scene()->views().isEmpty()) {
         return;
     }
 
-    fillRectangle(item->boundingRect());
+    // Find the view that is associated with this reaction map
+    int viewIndex = -1;
+    for (int i = 0; i < item->scene()->views().size(); ++i) {
+        if (d->topLevelWidget == item->scene()->views()[i]) {
+            viewIndex = i;
+            break;
+        }
+    }
+
+    // If a view associated with this reaction map was found, use that
+    // view's transformation to draw to this reaction map.
+    if (viewIndex >= 0) {
+        QTransform currentTransform = d->transform;
+        QRectF rect = item->boundingRect();
+
+        setTransform(item, item->scene()->views()[viewIndex]);
+        fillRectangle(rect);
+        d->setTransform(currentTransform);
+    }
 }
 
 void MReactionMap::fillItemBoundRect(QGraphicsItem *item,
@@ -169,14 +188,12 @@
     if (!item || !item->scene() || item->scene()->views().isEmpty()) {
         return;
     }
+
     quint8 currentDrawingValue = d->drawingValue;
-    QTransform currentTransform = d->transform;
 
-    setTransform(item, item->scene()->views()[0]);
     setDrawingValue(pressFeedback, releaseFeedback);
     fillItemBoundRect(item);
     d->drawingValue = currentDrawingValue;
-    d->transform = currentTransform;
 }
 
 int MReactionMap::width() const
--- src/client/mreactionmap.h
+++ src/client/mreactionmap.h
@@ -350,8 +350,9 @@
     /*!
      * @brief Draws a filled bound rectangle for a graphics item.
      *
-     * @details Draws a filled bound rectangle for a graphics item for the
-     * first view of the item with the active drawing value.
+     * @details Draws a filled bound rectangle of a graphics item in the
+     * view that is associated with the reaction map instance that this
+     * function is called from.
      *
      * @param item A graphics item to be drawn.
      *
@@ -362,10 +363,11 @@
     /*!
      * @brief Draws a filled bound rectangle for a graphics item.
      *
-     * @details Draws a filled bound rectangle for a graphics item for the
-     * first view of the item with the specified drawing values. Even though
-     * the specified values override the currently set drawing value, the
-     * currently set drawing value itself won't be changed by this method.
+     * @details Draws a filled bound rectangle of a graphics item in the
+     * view that is associated with the reaction map instance that this
+     * function is called from. Even though the specified drawing values
+     * override the currently set drawing values, the currently set drawing
+     * value itself won't be changed by this method.
      *
      * @param item A graphics item to be drawn.
      * @param pressFeedback Name of feedback to be played when screen is pressed.
--- src/client/mreactionmap_p.cpp
+++ src/client/mreactionmap_p.cpp
@@ -33,8 +33,8 @@
 QMap<QWidget *, MReactionMap *> MReactionMapPrivate::reactionMaps;
 
 MReactionMapPrivate::MReactionMapPrivate(QWidget *topLevelWidget,
-                                             const QString& applicationName,
-                                             QObject *parent)
+                                         const QString& applicationName,
+                                         QObject *parent)
     : QObject(parent), palette(0)
 {
     this->topLevelWidget = topLevelWidget;
--- src/client/mreactionmapconnection.cpp
+++ src/client/mreactionmapconnection.cpp
@@ -20,7 +20,6 @@
 #include <QCoreApplication>
 #include <QTimer>
 #include <QDebug>
-#include <QLocalSocket>
 
 static const QString gSocketFilePath("/tmp/mfeedbackd/reactionmaps.sock");
 
--- src/client/mreactionmapconnection.h
+++ src/client/mreactionmapconnection.h
@@ -23,7 +23,6 @@
 
 #include <mfcommondata.h>
 
-class QLocalSocket;
 class MReactionMapPrivate;
 
 //! \internal
--- src/mfsource/mfconnection.cpp
+++ src/mfsource/mfconnection.cpp
@@ -28,6 +28,9 @@
     : QObject(parent), state(StateClientInit), socket(connection),
       stack(stack), clientPid(0)
 {
+    // Reparent QLocalSocket to have it deleted once MfConnection gets deleted
+    socket->setParent(this);
+
     connect(socket, SIGNAL(readyRead()), SLOT(readSocketData()));
     connect(socket, SIGNAL(disconnected()), SLOT(deleteLater()));
 
--- src/mfsource/mfconnection.h
+++ src/mfsource/mfconnection.h
@@ -19,6 +19,7 @@
 
 #include <QObject>
 #include <QMap>
+#include <QPointer>
 
 class QLocalSocket;
 class MfReactionMapStack;
@@ -46,7 +47,7 @@
         StateDoomed
     } state;
 
-    QLocalSocket *socket;
+    QPointer<QLocalSocket> socket;
     MfReactionMapStack *stack;
     QMap <quint32, MfReactionMap *> reactionMaps;
     qint64 clientPid;
--- src/mfsource/mfkernelthread.cpp
+++ src/mfsource/mfkernelthread.cpp
@@ -23,6 +23,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <stdint.h>
 
 #include <QtDebug>
 
--- src/mfsource/mfsource.pro
+++ src/mfsource/mfsource.pro
@@ -1,97 +1,34 @@
+include(mfsource_common.pri)
+
 TEMPLATE = lib
 DESTDIR = ../..
 TARGET = meegofeedback-reactionmap
 
-DEPENDPATH += .
-INCLUDEPATH += . \
-    ../common
-CONFIG += link_pkgconfig plugin \
-    meegofeedback
-QT += network
-PKGCONFIG += xi xorg-evdev
-QMAKE_CXXFLAGS += -finline-functions -fno-strict-aliasing
-CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
-else:DEFINES += MF_DEBUG
-
-contains( COV_OPTION, on ) {
-    include(../coverage.pri)
-}
-
-# Input
-HEADERS += \
-    mfreactionmap.h \
-    mfreactionmapstack.h \
-    mfreactorsource.h \
-    mfserver.h \
-    mftouchscreenlistener.h \
-    mftouchscreentranslator.h \
-    mfxcalib.h \
-    mfxlistener_p.h \
-    mfxlistener.h \
-    mfconnection.h \
-    ../common/mfsettings.h \
-    ../common/mfcommondata.h
-
-SOURCES += \
-    mfreactionmap.cpp \
-    mfreactionmapstack.cpp \
-    mfreactorsource.cpp \
-    mfserver.cpp \
-    mfxcalib.cpp \
-    mfxlistener_p.cpp \
-    mfxlistener.cpp \
-    mfconnection.cpp \
-    ../common/mfsettings.cpp
-
 # Find out which implementation of MfTouchScreenListener to use
-contains(TOUCHSCREEN_LISTENER_IMPL, xrecord) {
-    message(Using *xrecord* implementation of MfTouchScreenListener)
-    CONFIG += x11
-    PKGCONFIG += xtst
-    SOURCES += \
-    mftouchscreenlistener_xrecord.cpp \
-    mfxrecordthread.cpp
-    HEADERS += \
-    mfxrecordthread.h
+# NOTE: XRecord version is built separately in ../mfsource_xrecord
+contains(TOUCHSCREEN_LISTENER_IMPL, dummy) {
+    message(Using *dummy* implementation of MfTouchScreenListener)
+    SOURCES += mftouchscreenlistener_dummy.cpp
 }
 else {
-    contains(TOUCHSCREEN_LISTENER_IMPL, dummy) {
-        message(Using *dummy* implementation of MfTouchScreenListener)
-        SOURCES += mftouchscreenlistener_dummy.cpp
-        }
-else {
-    contains(TOUCHSCREEN_LISTENER_IMPL, xcore) {
+   contains(TOUCHSCREEN_LISTENER_IMPL, xcore) {
         message(Using *core X* implementation of MfTouchScreenListener)
         CONFIG += x11
         SOURCES += \
-    mftouchscreenlistener_xcore.cpp \
-    mfxcorethread.cpp
+        mftouchscreenlistener_xcore.cpp \
+        mfxcorethread.cpp
         HEADERS += \
-    mfxcorethread.h
+        mfxcorethread.h
     }
     else {
         # defaults to kernel input event
         message(Using *kernel input event* implementation of MfTouchScreenListener)
         SOURCES += \
-    mfkernelthread.cpp \
-    mftouchscreenlistener_kernel.cpp \
-    mfdefaulttranslator.cpp \
-
+        mfkernelthread.cpp \
+        mftouchscreenlistener_kernel.cpp \
+        mfdefaulttranslator.cpp
         HEADERS += \
         mfkernelthread.h \
-    mfdefaulttranslator.h \
-
+        mfdefaulttranslator.h
     }
 }
-}
-
-QMAKE_EXTRA_TARGETS += check
-check.depends = $$DESTDIR/lib$${TARGET}.so
-check.commands = $$system(true)
-
-QMAKE_EXTRA_TARGETS += check-xml
-check-xml.depends = $$DESTDIR/lib$${TARGET}.so
-check-xml.commands = $$system(true)
-
-target.path = /usr/lib/meegofeedbackd
-INSTALLS += target
--- src/mfsource/mfsource_common.pri
+++ src/mfsource/mfsource_common.pri
+DEPENDPATH += .
+INCLUDEPATH += . \
+    ../common
+CONFIG += link_pkgconfig plugin meegofeedback
+QT += network
+PKGCONFIG += xi xorg-evdev
+QMAKE_CXXFLAGS += -finline-functions -fno-strict-aliasing
+CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
+else:DEFINES += MF_DEBUG
+
+contains( COV_OPTION, on ) {
+    include(../coverage.pri)
+}
+
+# Input
+HEADERS += \
+    ../mfsource/mfreactionmap.h \
+    ../mfsource/mfreactionmapstack.h \
+    ../mfsource/mfreactorsource.h \
+    ../mfsource/mfserver.h \
+    ../mfsource/mftouchscreenlistener.h \
+    ../mfsource/mftouchscreentranslator.h \
+    ../mfsource/mfxcalib.h \
+    ../mfsource/mfxlistener_p.h \
+    ../mfsource/mfxlistener.h \
+    ../mfsource/mfconnection.h \
+    ../common/mfsettings.h \
+    ../common/mfcommondata.h
+
+SOURCES += \
+    ../mfsource/mfreactionmap.cpp \
+    ../mfsource/mfreactionmapstack.cpp \
+    ../mfsource/mfreactorsource.cpp \
+    ../mfsource/mfserver.cpp \
+    ../mfsource/mfxcalib.cpp \
+    ../mfsource/mfxlistener_p.cpp \
+    ../mfsource/mfxlistener.cpp \
+    ../mfsource/mfconnection.cpp \
+    ../common/mfsettings.cpp
+
+QMAKE_EXTRA_TARGETS += check
+check.depends = $$DESTDIR/lib$${TARGET}.so
+check.commands = $$system(true)
+
+QMAKE_EXTRA_TARGETS += check-xml
+check-xml.depends = $$DESTDIR/lib$${TARGET}.so
+check-xml.commands = $$system(true)
+
+target.path = /usr/lib/meegofeedbackd
+INSTALLS += target
+
--- src/mfsource/mftouchscreenlistener_xcore.cpp
+++ src/mfsource/mftouchscreenlistener_xcore.cpp
@@ -21,16 +21,15 @@
 class MfTouchScreenListenerPriv
 {
     public:
-    MfReactionMap **currReactionMap;
     MfXCoreThread xcoreThread;
 };
 
-MfTouchScreenListener::MfTouchScreenListener(MfReactionMap **currReactionMap,
+MfTouchScreenListener::MfTouchScreenListener(MfReactionMapStack *reactionMapStack,
                                              QObject *parent)
     : QObject(parent)
 {
+    Q_UNUSED(reactionMapStack);
     d = new MfTouchScreenListenerPriv();
-    d->currReactionMap = currReactionMap;
 }
 
 MfTouchScreenListener::~MfTouchScreenListener()
--- src/mfsource/mftouchscreenlistener_xrecord.cpp
+++ src/mfsource/mftouchscreenlistener_xrecord.cpp
@@ -15,34 +15,189 @@
  */
 
 #include "mftouchscreenlistener.h"
-
 #include "mfxrecordthread.h"
 
+#include <X11/Xlib.h>
+#include <X11/extensions/record.h>
+#include <X11/Xproto.h>
+
+// Local function prototypes
+static int *xerrorHandler(Display *display, XErrorEvent *errorEvent);
+
 class MfTouchScreenListenerPriv
 {
     public:
-    MfReactionMap **currReactionMap;
+    MfTouchScreenListenerPriv();
+
     MfXRecordThread xrecordThread;
+    MfReactionMapStack *reactionMapStack;
+    Display *controlDisplay, *dataDisplay;
+    XRecordContext context;
 };
 
-MfTouchScreenListener::MfTouchScreenListener(MfReactionMap **currReactionMap,
+MfTouchScreenListenerPriv::MfTouchScreenListenerPriv()
+    : reactionMapStack(NULL), controlDisplay(NULL), dataDisplay(NULL), context(0)
+{
+}
+
+MfTouchScreenListener::MfTouchScreenListener(MfReactionMapStack *reactionMapStack,
                                              QObject *parent)
     : QObject(parent)
 {
     d = new MfTouchScreenListenerPriv();
-    d->currReactionMap = currReactionMap;
+    d->reactionMapStack = reactionMapStack;
 }
 
 MfTouchScreenListener::~MfTouchScreenListener()
 {
-    if (d) {
-        delete d;
-        d = NULL;
+    if (!d) {
+        return;
+    }
+
+    if (d->xrecordThread.isRunning()) {
+        stopListening();
     }
+
+    delete d;
+    d = NULL;
 }
 
 bool MfTouchScreenListener::startListening()
 {
+    char *displayName = NULL;
+    int recMajor, recMinor;
+    XRecordRange *range = NULL;
+    XRecordClientSpec clientSpec;
+
+    // Init X to support threading
+    if (!XInitThreads()) {
+        qCritical("MfTouchScreenListener: Cannot initialize X to support threads.");
+    }
+
+    displayName = XDisplayName(NULL);
+    if (displayName == NULL) {
+        qCritical("MfTouchScreenListener: Cannot get display name.");
+        return false;
+    }
+
+    // Open control display
+    d->controlDisplay = XOpenDisplay(displayName);
+    if (d->controlDisplay == NULL) {
+        qCritical("MfTouchScreenListener: Cannot open display \"%s\".", displayName);
+        return false;
+    }
+
+    // Open data display
+    d->dataDisplay = XOpenDisplay(displayName);
+    if (d->dataDisplay == NULL) {
+        qCritical("MfTouchScreenListener: Cannot open display \"%s\".", displayName);
+        goto CLEANUP;
+    }
+
+    XSetErrorHandler((XErrorHandler) xerrorHandler);
+
+    // Synchronize control display
+    XSynchronize(d->controlDisplay, true);
+
+    if (!XRecordQueryVersion (d->controlDisplay, &recMajor, &recMinor)) {
+        qCritical("MfTouchScreenListener: X server uses different XRecord version: (%d,%d)",
+                  recMajor, recMinor);
+        goto CLEANUP;
+    }
+
+    // Create XRecord context using control display
+    range = XRecordAllocRange ();
+    if (!range) {
+        qCritical("MfTouchScreenListener: Cannot allocate range");
+        goto CLEANUP;
+    }
+
+    range->device_events.first = ButtonPress;
+    range->device_events.last = ButtonRelease;
+
+    clientSpec = XRecordAllClients;
+
+    d->context = XRecordCreateContext(d->controlDisplay,     /* display  */
+                                      0,           /* datum_flags */
+                                      &clientSpec, /* clients */
+                                      1,           /* nclients */
+                                      &range,     /* ranges */
+                                      1);          /* nranges */
+
+    if (!d->context) {
+        qCritical("MfTouchScreenListener: Could not create XRecord context");
+        goto CLEANUP;
+    }
+
+    XFree(range);
+    range = NULL;
+
+    // Prepare thread and run it
+    d->xrecordThread.init(d->reactionMapStack, d->dataDisplay, d->context);
     d->xrecordThread.start();
+
     return true;
+
+    CLEANUP:
+        if (range) {
+            XFree(range);
+            range = NULL;
+        }
+
+        if (d->dataDisplay) {
+            XCloseDisplay(d->dataDisplay);
+            d->dataDisplay = NULL;
+        }
+
+        if (d->controlDisplay) {
+            XCloseDisplay(d->controlDisplay);
+            d->controlDisplay = NULL;
+        }
+
+        return false;
 }
+
+bool MfTouchScreenListener::stopListening()
+{
+    if (!d->xrecordThread.isRunning()) {
+        // Nothing to be done
+        return true;
+    }
+
+    // Disable XRecord context
+    if (!XRecordDisableContext(d->controlDisplay, d->context)) {
+        qCritical("MfTouchScreenListener: Cannot disable XRecord context");
+    }
+
+    // Wait until tread stops nicely or else use brute force
+    if (!d->xrecordThread.wait(1000)) {
+        // Ok, let's use brute force
+        d->xrecordThread.terminate();
+        d->xrecordThread.wait();
+    }
+
+    // Cleanup
+    // Free context
+    XRecordFreeContext(d->controlDisplay, d->context);
+    d->context = 0;
+
+    // Close data display
+    XCloseDisplay(d->dataDisplay);
+    d->dataDisplay = NULL;
+
+    // Close control display
+    XCloseDisplay(d->controlDisplay);
+    d->controlDisplay = NULL;
+
+    qDebug("MfTouchScreenListener: Stopped nicely");
+    return true;
+}
+
+static int *xerrorHandler(Display *display, XErrorEvent *errorEvent)
+{
+    Q_UNUSED(display);
+    Q_UNUSED(errorEvent);
+    qCritical("MfXRecordThread: Error from X");
+    return NULL;
+}
+
--- src/mfsource/mfxcalib.cpp
+++ src/mfsource/mfxcalib.cpp
@@ -270,3 +270,43 @@
             continue;
     }
 }
+
+bool MfXCalib::axisCalibration() const
+{
+    return tsAxisCalib;
+}
+
+qint32 MfXCalib::minX() const
+{
+    return tsMinX;
+}
+
+qint32 MfXCalib::minY() const
+{
+    return tsMinY;
+}
+
+qint32 MfXCalib::maxX() const
+{
+    return tsMaxX;
+}
+
+qint32 MfXCalib::maxY() const
+{
+    return tsMaxY;
+}
+
+int MfXCalib::invertedAxisX() const
+{
+    return tsAxisX;
+}
+
+int MfXCalib::invertedAxisY() const
+{
+    return tsAxisY;
+}
+
+int MfXCalib::swapAxes() const
+{
+    return tsAxesSwap;
+}
--- src/mfsource/mfxcalib.h
+++ src/mfsource/mfxcalib.h
@@ -34,30 +34,14 @@
 private:
     bool getCalibrationValues();
 public:
-    inline bool axisCalibration() const {
-        return tsAxisCalib;
-    }
-    inline qint32 minX() const {
-        return tsMinX;
-    }
-    inline qint32 minY() const {
-        return tsMinY;
-    }
-    inline qint32 maxX() const {
-        return tsMaxX;
-    }
-    inline qint32 maxY() const {
-        return tsMaxY;
-    }
-    inline int invertedAxisX() const {
-        return tsAxisX;
-    }
-    inline int invertedAxisY() const {
-        return tsAxisY;
-    }
-    inline int swapAxes() const {
-        return tsAxesSwap;
-    }
+    bool axisCalibration() const;
+    qint32 minX() const;
+    qint32 minY() const;
+    qint32 maxX() const;
+    qint32 maxY() const;
+    int invertedAxisX() const;
+    int invertedAxisY() const;
+    int swapAxes() const;
 
 private:
 
--- src/mfsource/mfxcorethread.cpp
+++ src/mfsource/mfxcorethread.cpp
@@ -69,33 +69,32 @@
 {
     XEvent e;
 
-    XGrabButton (display, AnyButton, AnyModifier, DefaultRootWindow(display),
-                 True, ButtonPressMask | ButtonReleaseMask,
-                 GrabModeSync, GrabModeAsync, None, None);
+    XGrabButton(display, AnyButton, AnyModifier, DefaultRootWindow(display),
+                True, ButtonPressMask | ButtonReleaseMask,
+                GrabModeSync, GrabModeAsync, None, None);
 
     while (true) {
-        XNextEvent (display, &e);
-
+        XNextEvent(display, &e);
         switch (e.type) {
             case ButtonPress:
                 if (e.xbutton.button <= 3) {
                     /* Now trigger a sound event, the quick version */
                 }
 
-                qDebug("ButtonPress: %u %u/%u\n",
-                       e.xbutton.button,
-                       e.xbutton.x, e.xbutton.y);
+                fprintf(stderr, "ButtonPress: %u %u/%u\n",
+                        e.xbutton.button,
+                        e.xbutton.x, e.xbutton.y);
                 break;
 
             case ButtonRelease:
-                qDebug("ButtonRelease: %u %u/%u\n",
-                       e.xbutton.button,
-                       e.xbutton.x, e.xbutton.y);
+                fprintf(stderr, "ButtonRelease: %u %u/%u\n",
+                        e.xbutton.button,
+                        e.xbutton.x, e.xbutton.y);
                 break;
         }
 
-        //XSendEvent (e.xbutton.display, InputFocus, False, e.type, &e);
-        XAllowEvents (e.xbutton.display, ReplayPointer, CurrentTime);
+//      XSendEvent(e.xbutton.display, InputFocus, False, e.type, &e);
+        XAllowEvents(e.xbutton.display, ReplayPointer, CurrentTime);
     }
 
     return true;
--- src/mfsource/mfxrecordthread.cpp
+++ src/mfsource/mfxrecordthread.cpp
@@ -14,10 +14,13 @@
  * of this file.
  */
 
+#include "mfreactionmapstack.h"
 #include "mfxrecordthread.h"
+#include "mfsettings.h"
 
 /**
- * From xnee: this typedef should, according to XRecord,
+ * From xnee (libxnee/include/libxnee/xnee.h):
+ * this typedef should, according to XRecord,
  * specification be defined in <X11/extensions/record.h>
  * ... can't find .... errrh?
  */
@@ -31,115 +34,112 @@
 } XRecordDatum;
 
 // Local function prototypes
-static int *xerrorHandler(Display *display, XErrorEvent *errorEvent);
 static void xrecordInterceptCallback(XPointer closure, XRecordInterceptData *recordedData);
 
+static MfXRecordThread *gInstance = NULL;
+
 MfXRecordThread::MfXRecordThread(QObject *parent)
     : QThread(parent), display(NULL), context(NULL)
 {
+    if (gInstance) {
+        qFatal("MfXRecordThread: Trying to create a second instance of MfXRecordThread");
+    }
+
+    gInstance = this;
 }
 
-void MfXRecordThread::run()
+MfXRecordThread::~MfXRecordThread()
 {
-    char *displayName = NULL;
-    int recMajor, recMinor;
-    int ok;
-
-    displayName = XDisplayName(NULL);
-    if (displayName == NULL) {
-        qCritical("MfXRecordThread: Cannot get display name.");
-    }
+    gInstance = NULL;
+}
 
-    display = XOpenDisplay(displayName);
-    if (display == NULL) {
-        qCritical("MfXRecordThread: Cannot open display \"%s\".", displayName);
-        goto CLEANUP;
-    }
+MfXRecordThread *MfXRecordThread::instance()
+{
+    return gInstance;
+}
 
-    XSetErrorHandler((XErrorHandler) xerrorHandler);
+QPoint MfXRecordThread::calcPixelCoords(int x, int y)
+{
+    QPoint result;
 
-    if (!XRecordQueryVersion (display, &recMajor, &recMinor)) {
-        qCritical("MfXRecordThread: X server uses different XRecord version: (%d,%d)",
-                  recMajor, recMinor);
-        goto CLEANUP;
-    }
+    // Make sure no out-of-bounds values are created
+    qBound(0, x, (displayWidth-1));
+    qBound(0, y, (displayHeight-1));
 
-    if (!createContext()) {
-        goto CLEANUP;
-    }
+    // Calculate coordinates in reaction map
+    result.rx() = ( MfSettings::reactionMapWidth() * x ) / (displayWidth);
+    result.ry() = ( MfSettings::reactionMapHeight() * y ) / (displayHeight);
 
-    ok = XRecordEnableContext (display, context, xrecordInterceptCallback, (XPointer) this);
-    if (!ok) {
-        qCritical("MfXRecordThread: Cannot enable XRecord context.");
-    }
+    return result;
+}
 
- CLEANUP:
-    if (context) {
-        XRecordFreeContext(display, context);
-        context = NULL;
-    }
+void MfXRecordThread::screenPressed(int x, int y)
+{
+    QPoint mapPoint;
 
-    if (display) {
-        XCloseDisplay(display);
-        display = NULL;
-    }
+    mapPoint = calcPixelCoords(x, y);
+    reactionMapStack->pressed(mapPoint);
 }
 
-bool MfXRecordThread::createContext()
+void MfXRecordThread::screenReleased(int x, int y)
 {
-    XRecordRange *range = NULL;
-    XRecordClientSpec clientSpec;
+    QPoint mapPoint;
 
-    Q_ASSERT(display != NULL);
+    mapPoint = calcPixelCoords(x, y);
+    reactionMapStack->released(mapPoint);
+}
 
-    range = XRecordAllocRange ();
-    if (range == NULL) {
+bool MfXRecordThread::init(MfReactionMapStack *reactionMapStack,
+                           Display *display, XRecordContext context)
+{
+    if (!reactionMapStack || !display || !context) {
         return false;
     }
 
-    range->device_events.first = ButtonPress;
-    range->device_events.last = ButtonRelease;
-
-    clientSpec = XRecordAllClients;
-
-    context = XRecordCreateContext(display,     /* display  */
-                                   0,           /* datum_flags */
-                                   &clientSpec, /* clients */
-                                   1,           /* nclients */
-                                   &range,     /* ranges */
-                                   1);          /* nranges */
+    this->reactionMapStack = reactionMapStack;
+    this->display = display;
+    this->context = context;
+
+    // Get screen resolution
+    displayWidth = XDisplayWidth(display, 0);
+    displayHeight = XDisplayHeight(display, 0);
 
-    // Cleanup
-    XFree(range);
-    range = NULL;
-
-    return (context != 0);
+    return true;
 }
 
-static int *xerrorHandler(Display *display, XErrorEvent *errorEvent)
+void MfXRecordThread::run()
 {
-    Q_UNUSED(display);
-    Q_UNUSED(errorEvent);
-    qCritical("MfXRecordThread: Error from X");
-    return NULL;
+    // Start listening
+    if (!XRecordEnableContext (display, context, xrecordInterceptCallback, (XPointer) this)) {
+        qCritical("MfXRecordThread: Cannot enable XRecord context.");
+    }
 }
 
 static void xrecordInterceptCallback(XPointer closure, XRecordInterceptData *recordedData)
 {
-    MfXRecordThread *xRecordThread = (MfXRecordThread*) closure;
+    Q_UNUSED(closure);
+    unsigned int x, y;
     XRecordDatum *datum = NULL;
-
     datum = (XRecordDatum *) recordedData->data;
 
-    qDebug("xrecordInterceptCallback");
-    /* FIXME: ? */
-    if (recordedData->category != XRecordFromServer)
+    if (recordedData->category != XRecordFromServer) {
         goto CLEANUP;
-    if (datum == NULL)
+    }
+
+    if (datum == NULL) {
         goto CLEANUP;
+    }
 
     if (datum->event.u.u.type == ButtonPress) {
-        qDebug("Button Event %d", datum->event.u.u.detail);
+        x = datum->event.u.keyButtonPointer.rootX;
+        y = datum->event.u.keyButtonPointer.rootY;
+        MfXRecordThread::instance()->screenPressed(x, y);
+    } else if (datum->event.u.u.type == ButtonRelease) {
+        x = datum->event.u.keyButtonPointer.rootX;
+        y = datum->event.u.keyButtonPointer.rootY;
+        MfXRecordThread::instance()->screenReleased(x, y);
+    } else {
+        qCritical("MfXRecordThread: Unknown event.");
     }
 
  CLEANUP:
--- src/mfsource/mfxrecordthread.h
+++ src/mfsource/mfxrecordthread.h
@@ -18,25 +18,43 @@
 #define MFXRECORDTHREAD_H
 
 #include <QThread>
+#include <QPoint>
 
 #include <X11/Xlib.h>
 #include <X11/extensions/record.h>
 #include <X11/Xproto.h>
 
+class MfReactionMapStack;
+
 class MfXRecordThread : public QThread
 {
     Q_OBJECT
 public:
     MfXRecordThread(QObject *parent = 0);
+    ~MfXRecordThread();
+
+    static MfXRecordThread *instance();
+
+    bool init(MfReactionMapStack *reactionMapStack,
+              Display *display, XRecordContext context);
+
+public slots:
+    void screenPressed(int x, int y);
+    void screenReleased(int x, int y);
 
 protected:
     void run();
 
 private:
     bool createContext();
+    QPoint calcPixelCoords(int x, int y);
 
     Display *display;
     XRecordContext context;
+    MfReactionMapStack *reactionMapStack;
+    int displayWidth, displayHeight;
+
+    Q_DISABLE_COPY(MfXRecordThread)
 };
 
 #endif
--- src/mfsource_xrecord
+++ src/mfsource_xrecord
+(directory)
--- src/mfsource_xrecord/mfsource_xrecord.pro
+++ src/mfsource_xrecord/mfsource_xrecord.pro
+include(../mfsource/mfsource_common.pri)
+
+TEMPLATE = lib
+DESTDIR = ../..
+TARGET = meegofeedback-reactionmap-xrecord
+
+# Use XRecord implementation of MfTouchScreenListener
+message(Using *XRecord* implementation of MfTouchScreenListener)
+CONFIG += x11
+PKGCONFIG += xtst
+SOURCES += \
+           ../mfsource/mftouchscreenlistener_xrecord.cpp \
+           ../mfsource/mfxrecordthread.cpp
+HEADERS += \
+           ../mfsource/mfxrecordthread.h
+
--- src/src.pro
+++ src/src.pro
@@ -1,5 +1,7 @@
 TEMPLATE=subdirs
-SUBDIRS=mfsource client
+SUBDIRS=mfsource \
+        mfsource_xrecord \
+        client
 
 check.target = check
 check.CONFIG = recursive
--- tests/ut_mfreactionmapstack/mfxcalib_mock.cpp
+++ tests/ut_mfreactionmapstack/mfxcalib_mock.cpp
+/* This file is part of meegofeedback-reactionmaps
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * All rights reserved.
+ * Contact: Nokia Corporation (directui at nokia.com)
+ *
+ * If you have questions regarding the use of this file, please contact
+ * Nokia at directui at nokia.com.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1 as published by the Free Software Foundation
+ * and appearing in the file LICENSE.LGPL included in the packaging
+ * of this file.
+ */
+
+#include "mfxcalib_mock.h"
+
+bool MfXCalib::init() {
+    return true;
+}
+
+bool MfXCalib::getCalibrationValues()
+{
+    return true;
+}
+
+bool MfXCalib::axisCalibration() const
+{
+    return false;
+}
--- tests/ut_mfreactionmapstack/mfxcalib_mock.h
+++ tests/ut_mfreactionmapstack/mfxcalib_mock.h
@@ -27,9 +27,9 @@
 
     virtual ~MfXCalib() {}
 
-    bool init() { return true; }
-    bool getCalibrationValues() { return true; }
-
+    bool init();
+    bool getCalibrationValues();
+    bool axisCalibration() const;
 };
 
 #endif
--- tests/ut_mfreactionmapstack/ut_mfreactionmapstack.pro
+++ tests/ut_mfreactionmapstack/ut_mfreactionmapstack.pro
@@ -7,6 +7,7 @@
     ../../src/mfsource/mfreactionmap.cpp \
     ../../src/common/mfsettings.cpp \
     mfutil_mock.cpp \
+    mfxcalib_mock.cpp \
     $$TEST_SOURCES
 HEADERS += ut_mfreactionmapstack.h \
     mfutil.h \
--- tests/ut_mreactionmap/ut_mreactionmap.cpp
+++ tests/ut_mreactionmap/ut_mreactionmap.cpp
@@ -22,6 +22,7 @@
 #include "mfeedbackpalette_mock.cpp"
 #include <mfsettings.h>
 #include <QDesktopWidget>
+#include <QGraphicsRectItem>
 
 class MReactionMapTest : public MReactionMap
 {
@@ -76,6 +77,9 @@
     widget2 = new QGraphicsView(scene);
     reactionMap1 = new MReactionMapTest(widget1, "reactionMap1");
     reactionMap2 = new MReactionMapTest(widget2, "reactionMap2");
+
+    item = new QGraphicsRectItem(10, 10, 100, 50);
+    scene->addItem(item);
 }
 
 void Ut_MReactionMap::cleanup()
@@ -92,8 +96,14 @@
     delete widget2;
     widget2 = 0;
 
+    delete item;
+    item = 0;
+
     delete scene;
     scene = 0;
+
+    delete MReactionMapConnection::reactionMapConnection;
+    MReactionMapConnection::reactionMapConnection = 0;
 }
 
 /*
@@ -376,6 +386,58 @@
 }
 
 /*
+ * Draw a bounding rectangle of a QGraphicsItem and check that
+ * the resulting reaction map is correct.
+ */
+void Ut_MReactionMap::drawBoundingRectangle1()
+{
+    QTransform transform;
+    QRectF reactionMapRect;
+
+    item->setPos(50,25);
+
+    reactionMap1->setReactiveDrawingValue();
+    reactionMap1->fillItemBoundRect(item);
+
+    transform = item->sceneTransform() * reactionMap1->transform() * widget1->viewportTransform();
+    reactionMapRect = transform.mapRect(item->rect());
+
+    QCOMPARE(checkArea(reactionMap1, 2, qRound(reactionMapRect.x()), qRound(reactionMapRect.y()),
+                       qRound(reactionMapRect.width()), qRound(reactionMapRect.height())), true);
+
+    QCOMPARE(reactionMap2->getImage(), (uchar*)NULL);
+}
+
+/*
+ * Draw a bounding rectangle of a QGraphicsItem and check that
+ * the resulting reaction map is correct. Also check that the
+ * temporary drawing value is not permanently stored.
+ */
+void Ut_MReactionMap::drawBoundingRectangle2()
+{
+    QTransform transform;
+    QRectF reactionMapRect;
+
+    item->setPos(5,5);
+
+    widget2->scale(2,2);
+    widget2->centerOn(0,0);
+
+    reactionMap2->setReactiveDrawingValue();
+    reactionMap2->fillItemBoundRect(item, "foo", "bar");
+
+    transform = item->sceneTransform() * reactionMap2->transform() * widget2->viewportTransform();
+    reactionMapRect = transform.mapRect(item->rect());
+
+    QCOMPARE(checkArea(reactionMap2, 3, qRound(reactionMapRect.x()), qRound(reactionMapRect.y()),
+                       qRound(reactionMapRect.width()), qRound(reactionMapRect.height())), true);
+
+    QCOMPARE(reactionMap1->getImage(), (uchar*)NULL);
+
+    QCOMPARE(reactionMap2->getDrawingValue(), static_cast<quint8>(2));
+}
+
+/*
  * Check that reaction map width and height are reported correctly.
  */
 void Ut_MReactionMap::dimensions()
--- tests/ut_mreactionmap/ut_mreactionmap.h
+++ tests/ut_mreactionmap/ut_mreactionmap.h
@@ -23,6 +23,7 @@
 #include <QGraphicsView>
 
 class MReactionMapTest;
+class QGraphicsRectItem;
 
 class Ut_MReactionMap : public QObject
 {
@@ -49,6 +50,8 @@
     void drawRectangle5();
     void drawInvalidRectangle1();
     void drawInvalidRectangle2();
+    void drawBoundingRectangle1();
+    void drawBoundingRectangle2();
     void dimensions();
     void clear();
     void windowIdChange();
@@ -65,6 +68,7 @@
     QGraphicsView *widget1;
     QGraphicsView *widget2;
     QWidget *childOfWidget1;
+    QGraphicsRectItem *item;
     MReactionMapTest *reactionMap1;
     MReactionMapTest *reactionMap2;
 };
--- tests/ut_mreactionmapconnection/ut_mreactionmapconnection.cpp
+++ tests/ut_mreactionmapconnection/ut_mreactionmapconnection.cpp
@@ -23,6 +23,8 @@
 
 QTEST_MAIN(Ut_MReactionMapConnection)
 
+QLocalSocket *Socket;
+
 Ut_MReactionMapConnection::Ut_MReactionMapConnection(QObject *parent)
     : QObject(parent)
 {
@@ -34,6 +36,9 @@
 
 void Ut_MReactionMapConnection::cleanup()
 {
+    // Can't be done because of these are private functions
+//    delete MReactionMapConnection::reactionMapConnection;
+//    MReactionMapConnection::reactionMapConnection = NULL;
 }
 
 void Ut_MReactionMapConnection::addReactionMap()

++++++ meegotouch-feedbackreactionmaps.yaml
--- meegotouch-feedbackreactionmaps.yaml
+++ meegotouch-feedbackreactionmaps.yaml
@@ -1,55 +1,38 @@
 Name: meegotouch-feedbackreactionmaps
-Summary: MeeGo Feedback ReactionMap Plugin
-Version: 0.14.0.1
+Summary: MeeGo Touch Feedback ReactionMaps Plugin
+Version: 0.14.0.5
 Release: 1
 Group: System/Libraries
-License: LGPL v2.1
-URL: http://www.meego.com
+License: LGPLv2.1
+URL: http://meego.gitorious.org/meegotouch/meegotouch-feedbackreactionmaps
 Sources:
     - "%{name}-%{version}.tar.bz2"
 Patches:
-    - 0002-Fix-build-breakage-caused-by-missing-stdint.h-includ.patch
-    - meegotouchfeedbackreactionmaps-0.14.0-remove-evdev.patch
-Description: MeeGo Feedback Reactionmap Plugin
-
-PkgBR:
-   - fdupes
+    - disable_tests_build.patch
+Description: |
+    This package contains the MeeGo Touch Feedback Reactionmaps plugin.
 PkgConfigBR:
-    - QtCore >= 4.6.0
-    - QtDBus
-    - QtOpenGL
-    - QtNetwork
     - QtGui
-    - meegotouch 
-    - gstreamer-0.10
-    - gstreamer-base-0.10
-    - gstreamer-plugins-base-0.10
-    - dbus-1
+    - meegotouch-feedback
+    - meegotouch
     - xdamage
-    - icu
     - x11
-    - contextprovider-1.0
-    - gl
-    - libpulse
-    - libpulse-simple
-    - libpulse-mainloop-glib
-    - libpulse-browse
-    - meegotouch-feedback
-    - xi
     - xext
-
+    - xi
+    - xtst
+    - xorg-evdev
 Provides:
     - meegotouchfeedbackreactionmaps > 0.14.0
     - duifeedback-reactionmaps > 0.14.0
 Obsoletes:
     - meegotouchfeedbackreactionmaps <= 0.14.0
     - duifeedback-reactionmaps <= 0.14.0
-
 Configure: none
-Builder: make
+Builder: qmake
+RunFdupes: "%{_datadir}"
 SubPackages:
     - Name: devel
-      Summary: Feedback Reactionmap Deveopment Package
+      Summary: MeeGo Touch Feedback Reactionmaps development files
       Group: Development/Libraries
-      Description: This package contains the reactionmaps feedback plugin
-
+      Description: |
+          This package contains the MeeGo Feedback Reactionmaps plugin development files.

++++++ deleted files:
--- 0002-Fix-build-breakage-caused-by-missing-stdint.h-includ.patch
--- meegotouchfeedbackreactionmaps-0.14.0-remove-evdev.patch




More information about the MeeGo-commits mailing list