[meego-commits] 11130: Changes to devel:qt-mtf/meegotouch-feedbackreactionmaps
araujo
no_reply at build.meego.com
Tue Dec 21 14:48:19 UTC 2010
Hi,
I have made the following changes to meegotouch-feedbackreactionmaps in project devel:qt-mtf. Please review and accept ASAP.
Thank You,
araujo
[This message was auto-generated]
---
Request #11130:
submit: home:araujo:branches:devel:qt-mtf/meegotouch-feedbackreactionmaps(r4)(cleanup) -> devel:qt-mtf/meegotouch-feedbackreactionmaps
Message:
Update to release tag 0.14.1-6
State: new 2010-12-21T06:48:18 araujo
Comment: None
changes files:
--------------
--- meegotouch-feedbackreactionmaps.changes
+++ meegotouch-feedbackreactionmaps.changes
@@ -0,0 +1,5 @@
+* Tue Dec 21 2010 Luis Araujo <luis.araujo at collabora.co.uk> - 0.14.1.6
+- Update to release tag 0.14.1-6 (BMC#11612)
+- Remove patch and use 'sed' expression
+- Add needed package versions to BuildRequires dependencies
+
old:
----
disable_tests_build.patch
meegotouch-feedbackreactionmaps-0.14.0.5.tar.bz2
new:
----
meegotouch-feedbackreactionmaps-0.14.1.6.tar.bz2
spec files:
-----------
--- meegotouch-feedbackreactionmaps.spec
+++ meegotouch-feedbackreactionmaps.spec
@@ -7,17 +7,16 @@
Name: meegotouch-feedbackreactionmaps
Summary: MeeGo Touch Feedback ReactionMaps Plugin
-Version: 0.14.0.5
+Version: 0.14.1.6
Release: 1
Group: System/Libraries
License: LGPLv2.1
URL: http://meego.gitorious.org/meegotouch/meegotouch-feedbackreactionmaps
Source0: %{name}-%{version}.tar.bz2
Source100: meegotouch-feedbackreactionmaps.yaml
-Patch0: disable_tests_build.patch
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
-BuildRequires: pkgconfig(QtGui)
+BuildRequires: pkgconfig(QtGui) >= 4.7
BuildRequires: pkgconfig(meegotouch-feedback)
BuildRequires: pkgconfig(meegotouch)
BuildRequires: pkgconfig(xdamage)
@@ -26,6 +25,8 @@
BuildRequires: pkgconfig(xi)
BuildRequires: pkgconfig(xtst)
BuildRequires: pkgconfig(xorg-evdev)
+BuildRequires: pkgconfig(xcb)
+BuildRequires: pkgconfig(zlib)
BuildRequires: fdupes
Provides: meegotouchfeedbackreactionmaps > 0.14.0
Provides: duifeedback-reactionmaps > 0.14.0
@@ -51,8 +52,8 @@
%prep
%setup -q -n %{name}-%{version}
-# disable_tests_build.patch
-%patch0 -p1
+# Disable tests
+sed '/tests\ \\/d' -i $RPM_BUILD_DIR/%{name}-%{version}/meegofeedback-reactionmaps.pro
# >> setup
# << setup
other changes:
--------------
++++++ meegotouch-feedbackreactionmaps-0.14.0.5.tar.bz2 -> meegotouch-feedbackreactionmaps-0.14.1.6.tar.bz2
--- debian/api
+++ debian/api
@@ -1,7 +1,7 @@
interface: libmeegoreactionmap
type: library
-scope: Platform
-state: unstable
+scope: Platform
+state: stable
libs-pkg: libmeegoreactionmap0
dev-pkg: libmeegoreactionmap-dev
--- debian/changelog
+++ debian/changelog
@@ -1,3 +1,53 @@
+meegofeedback-reactionmaps (0.14.1-6) unstable; urgency=low
+
+ * Removed obsolete libmeegoreactionmap-mcompositor-tests package
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com> Tue, 07 Dec 2010 11:12:13 +0200
+
+meegofeedback-reactionmaps (0.14.1-5) unstable; urgency=low
+
+ * Refactored MfXListener to use xcb instead of Xlib
+ * Removed X calibration data reading
+ * Added --as-needed to linker flags to avoid unnecessary linking
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com> Fri, 03 Dec 2010 15:56:57 +0200
+
+meegofeedback-reactionmaps (0.14.1-4) unstable; urgency=low
+
+ * Fixes: NB#202538 - meegofeedbackd dumps core when Xorg is killed with SIGKILL signal
+ * Minor changes to window ID handling
+ * Fixed issue of not using optimization flags when building package
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com> Wed, 17 Nov 2010 09:36:07 +0200
+
+meegofeedback-reactionmaps (0.14.1-3) unstable; urgency=low
+
+ * Fixes: NB#199731 - COREWEB: /usr/bin/meegofeedbackd '_Unwind_VRS_Pop...
+ * Changed testrunner dependency to testrunner-lite
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com> Fri, 22 Oct 2010 15:47:58 +0200
+
+meegofeedback-reactionmaps (0.14.1-2) unstable; urgency=low
+
+ * Updated debian dependencies
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com> Mon, 11 Oct 2010 15:25:51 +0200
+
+meegofeedback-reactionmaps (0.14.1-1) unstable; urgency=low
+
+ * Implemented: SWP#FEFRA-449, SWP#FEFRA-441, SWP#FEFRA-440
+
+ -- Csaba Kertesz <csaba.kertesz at vincit.fi> Thu, 07 Oct 2010 12:23:51 +0200
+
+meegofeedback-reactionmaps (0.14.0-6) unstable; urgency=low
+
+ * Touch Screen kernel interface is closed when screen is dimmed or off
+ * Touch Screen kernel interface is closed when no reactionmaps active
+ * Added functional test for above cases
+ * Documentation improved and proof-read
+
+ -- Antti Pulakka <ext-antti.j.pulakka at nokia.com> Mon, 23 Aug 2010 16:16:32 +0200
+
meegofeedback-reactionmaps (0.14.0-5) unstable; urgency=low
* Fix for a memory leak similar to NB#182656 in meegofeedbackd daemon
--- debian/control
+++ debian/control
@@ -2,7 +2,7 @@
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, libxtst-dev
+Build-Depends: debhelper (>= 4.0.0), libmeegofeedback-dev (>= 0.10.5), libqt4-dev (>= 4.7), libmeegotouch-dev, libx11-dev, libxext-dev, pkg-config (>= 0.22), zlib1g-dev, libxtst-dev, libxcb1-dev
Standards-Version: 3.6.1
Package: meegofeedback-reactionmap
@@ -92,7 +92,7 @@
Package: libmeegoreactionmap-tests
Section: extra
Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libmeegoreactionmap0 (= ${Source-Version}), libqtgui4, testrunner, ci-testing
+Depends: ${shlibs:Depends}, ${misc:Depends}, libmeegoreactionmap0 (= ${Source-Version}), libqtgui4, testrunner-lite, ci-testing
XB-Maemo-CI-Packages: libmeegoreactionmap0
XB-Maemo-CI-Stage: fast, staging, acceptance
Description: libmeegoreactionmap unit tests
@@ -103,15 +103,3 @@
Architecture: all
Description: API documentation for libmeegoreactionmap
-Package: libmeegoreactionmap-mcompositor-tests
-Section: extra
-Architecture: any
-Depends: ${shlibs:Depends}, ${misc:Depends}, libqtgui4, mcompositor, testrunner, ci-testing
-XB-Maemo-CI-Packages: mcompositor
-XB-Maemo-CI-Stage: staging, acceptance, validation
-Description: Test to make sure that window stacking works properly
- This test makes sure that mcompositor updates the window stacking property
- (_NET_CLIENT_LIST_STACKING) properly. MReactionMaps rely on this information
- to function poperly and this test acts as an indicator for any problems in the
- window stacking.
-
--- debian/rules
+++ debian/rules
@@ -9,6 +9,12 @@
# Uncomment this to turn on verbose mode.
export DH_VERBOSE=1
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ OPT_FLAG=-O0
+else
+ OPT_FLAG=-O2
+endif
+
ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
RELEASE_TYPE=debug
else
@@ -37,7 +43,7 @@
configure-stamp:
dh_testdir
# Add here commands to configure the package.
- qmake -recursive CONFIG+=${RELEASE_TYPE} $(QMAKE_OPTIONS)
+ qmake -recursive CONFIG+=${RELEASE_TYPE} QMAKE_CXXFLAGS+="-g ${OPT_FLAG}" $(QMAKE_OPTIONS)
sed -e 's|QT_INSTALL_DATA|${QT_INSTALL_DATA}|' > debian/libmeegoreactionmap-dev.install < debian/libmeegoreactionmap-dev.install.in
touch configure-stamp
@@ -49,7 +55,9 @@
# Add here commands to compile the package.
$(MAKE) $(PARALLEL_MAKEFLAGS)
- #docbook-to-man debian/meegofeedback-reactionmaps.sgml > meegofeedback-reactionmaps.1
+
+ # libmeegoreactionmap-doc package
+ $(MAKE) doc
touch build-stamp
@@ -69,9 +77,6 @@
dh_clean -k
dh_installdirs
- # libmeegoreactionmap-doc package
- make $(PARALLEL_MAKEFLAGS) doc
-
# Add here commands to install the package into debian/meegofeedback-reactionmaps.
INSTALL_ROOT=$(CURDIR)/debian/tmp make $(PARALLEL_MAKEFLAGS) install
--- doc/doc.pri
+++ doc/doc.pri
@@ -18,7 +18,7 @@
# Install rules
htmldocs.files = $${OUT_PWD}/doc/html/
- htmldocs.path = /usr/share/doc/meegofeedback-reactionmap
+ htmldocs.path = /usr/share/doc/libmeegoreactionmap-doc
htmldocs.CONFIG += no_check_exist
INSTALLS += htmldocs
}
--- doc/mdoxy.cfg.in
+++ doc/mdoxy.cfg.in
@@ -85,7 +85,7 @@
TOC_EXPAND = YES
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
-GENERATE_TREEVIEW = YES
+GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 200
--- doc/src/mainpage.dox
+++ doc/src/mainpage.dox
@@ -1,9 +1,21 @@
-/*! @mainpage MeeGo Touch Input Method Framework Documentation
+/*! @mainpage libmeegoreactionmap documentation
- at section general General documentation
+ at section Introduction
+
+This library provides a way for the developer to add triggers for specific non-visual feedback in an application when the user touches a defined part of the screen. Non-visual feedback in this context includes haptics (vibration), sounds and effects using the device lights. Feedback is most often used to confirm to the user that the application interface has received their input.
+
+Specifically, the main class of the library, MReactionMap, enables the developer to place an invisible reaction map on top of the application screen. Using screen coordinates, the developer can then define sections in this reaction map and assign each one a trigger for a specific feedback. This map enables widgets (application components, such as buttons) to trigger feedback when they are pressed or released, as long as their coordinates are defined in the reactionmap.
+
+ at section basicusage Basic Usage:
+
+<B>Main classes:</B>
+
+- MReactionMap : to add triggers for low latency haptic feedback to applications
+
+ at section Section2 General documentation
- <a href="tutorial.html">Tutorial for MReactionMap</a>
- at section api API reference
+ at section Section3 API reference
<a href="classes.html">All Classes</a>
*/
--- doc/src/tutorial.dox
+++ doc/src/tutorial.dox
@@ -1,26 +1,26 @@
/*! @page tutorial Tutorial for MReactionMap
@section Overview
-This tutorial shows how to make a simple "Hello World!" application based on QGraphicsView use meegoreactiomap to get its haptic input feedback.
+This tutorial shows how to make a simple "Hello World!" application based on QGraphicsView and use mreactiomap to add haptic input feedback to it.
-What's described here also works for MeeGo Touch applications since MeeGo Touch is built on top of QGraphicsView,
+What is described here also works for MeeGo Touch applications since MeeGo Touch is built on top of QGraphicsView.
@section Section1 Packages needed
Make sure you have the following packages installed in your scratchbox i386 target:
-- @c meegofeedback-reactionmap (version >= 0.14.0)
-- @c libmeegoreactionmap0 (version >= 0.14.0)
-- @c libmeegoreactionmap-dev (version >= 0.14.0)
-- @c libmeegoreactionmap-viewer (version >= 0.14.0)
-- @c libmeegofeedback0 (version >= 0.10.0)
-- @c meegofeedbackd (version >= 0.10.0)
-- @c meegofeedback-dummy (version >= 0.10.0)
+- @c meegofeedback-reactionmap
+- @c libmeegoreactionmap0
+- @c libmeegoreactionmap-dev
+- @c libmeegoreactionmap-viewer
+- @c libmeegofeedback0
+- @c meegofeedbackd
+- @c meegofeedback-dummy
- at c meegofeedback-dummy is a dummy backend for meegofeedbackd. It has to be installed it since we can't use (or need) a real backend in scratchbox.
+ at c meegofeedback-dummy is a dummy backend for the meegofeedbackd daemon. It has to be installed it since we cannot use (or need) a real hardware for haptic feedback in scratchbox.
@section Section2 The "Hello World!" sample application
-This sample application just displays two reactangles. One containing the word "Hello" and the other one, "World".
-It's hardcoded to be displayed on a 864x480 screen.
+This sample application displays two rectangles. One containing the word "Hello" and the other one, "World".
+It is hardcoded to be displayed on a 864x480 screen.
When you run it in scratchbox you should see the following in your Xephyr window:
@@ -85,92 +85,75 @@
@section Section3 Using libmeegoreactionmap
-Now let's make this sample application use libmeegoreactionmap. The objective is to make the "Hello" box give a "press" haptic feedback when user puts his finger on it and a "release" haptic feedback when user lifts his finger from it.
+Now let us make this sample application use libmeegoreactionmap. The objective is to make the "Hello" box give a "press" haptic feedback when the user puts their finger on it and a "release" haptic feedback when the user lifts their finger off it.
-The "World" box will stay without any haptic feedback.
+No haptic feedback is assigned to the "World" box in this tutorial.
@subsection Subsection31 Modifying reactionmaptutorialapp.pro file
-To make the application link against libmeegoreactionmap add the following line:
+To make the application link against libmeegoreactionmap, add the following line:
@code
CONFIG += meegoreactionmap
@endcode
@subsection Subsection32 Modifying main.cpp
-In the beginning of the file, include libfeedbackreactor header file:
+In the beginning of the file, include MReactionMap header file:
@code
#include <mreactionmap.h>
@endcode
-This header defines MReactionMap class.
+This header defines the MReactionMap class.
-Now let's create a reaction map for our application. A reaction map contains the description of all reactive areas of an application window. In other words: it says which (if any) haptic input feedback should be given when the screen is touched for every single part of the screen.
+Now let us create a reaction map for our application. A reaction map contains the description of all reactive areas of an application window. In other words: it states which (if any) haptic input feedback should be given when the screen is touched for every single part of the screen.
An application may only have one reaction map per top-level window. This means that if an application has more than one top-level window, there can be only one reaction map defined for each top-level window. Reaction map must be created after the top-level window in question has been created.
In our case, there is only one top-level window and it is the QGraphicsView itself.
-MReactionMap constructor takes two parameters. The first parameter is mandatory and it is the pointer to the top-level window. The actual pointer points to class QWidget which the QGraphicsView inherits. The second parameter is an optional name/identifier of the application. This information is used to locate and load all custom haptic input feedbacks that the application may have installed.
+MReactionMap constructor takes two parameters. The first parameter is mandatory as it is the pointer to the top-level window. It points to class QWidget which the QGraphicsView inherits. The second parameter is an optional name/identifier of the application. This information is used to locate and load all custom haptic input feedbacks that the application may have installed.
-Let's create our reaction map. Put the following line after @c mainWindow creation:
+Let us create our reaction map. Add the following line after @c mainWindow creation:
@code
MReactionMap reactionMap(&mainWindow, "reactionmaptutorial");
@endcode
-Next, add a function that draws a rectangular reactive area for a given QGraphicsItem.
+Using MReactionMap::setReactiveDrawingValue() method sets the default "press" feedback when finger touches the screen and the default "release" feedback when finger is lifted from the screen:
@code
-static void drawReactionMap(QGraphicsItem *item)
-{
- QList<QGraphicsView *> viewList = item->scene()->views();
-
- for (int i = 0; i < viewList.size(); ++i) {
- MReactionMap *reactionMap = MReactionMap::instance(viewList[i]);
-
- if (reactionMap == 0) {
- continue;
- }
-
- reactionMap->setTransform(item, viewList[i]);
- reactionMap->setReactiveDrawingValue();
- reactionMap->fillRectangle(item->boundingRect());
- }
-}
+ reactionMap.setReactiveDrawingValue();
@endcode
-Using MReactionMap::setTransform() causes the following rectangle drawing to use a transformation matrix that maps from item coordinates to reaction map coordinates.
-<br /><b>Warning:</b> The only supported transformations are scaling and translating. Undefined results will follow if the item is sheared or rotated.
-<br />Using MReactionMap::setReactiveDrawingValue() method sets the standard "press" feedback when finger touches the screen and the standard "release" feedback when finger is lifted from the screen.
-<br />Finally using MReactionMap::fillRectangle() method will draw the reactive area to the reaction map.
-Now add a line to draw the reactive area of the "Hello" box. To do this, put the following line before calling mainWindow.showFullScreen()
+Now add a function call to draw a rectangular reactive area around a given QGraphicsItem:
@code
- drawReactionMap(&helloRect);
+ reactionMap.fillItemBoundRect(&helloRect);
@endcode
+<b>Warning:</b> The only supported transformations are scaling and translating for the graphics items. Undefined results will follow if the item is sheared or rotated.
+
@section Section4 Running and testing in scratchbox
-How can you tell that your reaction map drawing code is really working? For that we use the @c meegoreactionmap-viewer tool.
+How can you tell that your reaction map drawing code is really working? For that we use the @c meegoreactionmap-viewer tool.
Follow these steps:
-- Run @c meegofeedbackd daemon
-- Run @c reactionmaptutorialapp
-- Open a new Xephyr window in, for instance, DISPLAY=:3
+-# Run @c meegofeedbackd daemon
+-# Run @c reactionmaptutorialapp
+-# Open a new Xephyr window in, for instance, DISPLAY=:3
- at c meegoreactionmap-viewer will run in this separate Xephyr window you just created. @c meegoreactionmap-viewer can take several parameters but the only mandatory one is the process id of the application whose reaction map you want to visualize.
+ at c meegoreactionmap-viewer will run in this separate Xephyr window you just created. @c meegoreactionmap-viewer can take several parameters but the only mandatory one is the process id of the application whose reaction map you want to visualize.
Run @c meegoreactionmap-viewer without any parameter to get information on its usage.
-For example: If the process id of your @c reactionmaptutorialapp instance is @c 6655 and the extra Xephyr window is on DISPLAY 3, the resulting command line would look like that:
+For example: If the process id of your @c reactionmaptutorialapp instance is @c 6655 and the extra Xephyr window is on DISPLAY 3, the resulting command line would look like this in scratchbox:
@code
$ DISPLAY=:3 meegoreactionmap-viewer 6655
@endcode
-Your extra Xephyr window should then look like the following:
+Your extra Xephyr window should then look similar to the following screenshot:
<img width="450" alt="meegoreactionmaptutorial2.png" src="meegoreactionmaptutorial2.png" height="260"></img>
-There you can see that the only part of the screen that gives haptic feedback is the one occupied by the "Hello" box. Since you didn't provide a color mapping file, the color red was used to represent areas that give "press" feedback when finger touches it and "release" feedback when finger is lifted from it. For information on color mapping files, run @c meegoreactionmap-viewer without any parameters.
+In the screenshot above you can see that the only part of the screen that gives haptic feedback is the one occupied by the "Hello" box. Since you did not provide a color mapping file, the color red is used to represent the area that gives "press" feedback when touched with a finger and "release" feedback when the finger is lifted from it. For information on color mapping files, run @c meegoreactionmap-viewer without any parameters.
@subsection Subsection41 Resulting main.cpp
@code
@@ -183,14 +166,15 @@
#include <QGraphicsRectItem>
#include <QGraphicsSimpleTextItem>
-static void drawReactionMap(QGraphicsItem *item);
-
int main (int argc, char **argv)
{
QApplication app(argc, argv);
QGraphicsView mainWindow;
mainWindow.setWindowFlags(Qt::FramelessWindowHint);
+
+ //Create reaction map for mainWindow
MReactionMap reactionMap(&mainWindow, "reactionmaptutorial");
+
QFont font;
QGraphicsScene scene;
@@ -218,29 +202,17 @@
mainWindow.setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
mainWindow.setAlignment(Qt::AlignLeft | Qt::AlignTop);
- drawReactionMap(&helloRect);
+ // Set the standard "press" feedback when finger touches the screen and
+ // the standard "release" feedback when finger is lifted from the screen
+ reactionMap.setReactiveDrawingValue();
+
+ // Draw a rectangular reactive area for "helloRect" QGraphicsItem:
+ reactionMap.fillItemBoundRect(&helloRect);
mainWindow.showFullScreen();
return app.exec();
}
-
-static void drawReactionMap(QGraphicsItem *item)
-{
- QList<QGraphicsView *> viewList = item->scene()->views();
-
- for (int i = 0; i < viewList.size(); ++i) {
- MReactionMap *reactionMap = MReactionMap::instance(viewList[i]);
-
- if (reactionMap == 0) {
- continue;
- }
-
- reactionMap->setTransform(item, viewList[i]);
- reactionMap->setReactiveDrawingValue();
- reactionMap->fillRectangle(item->boundingRect());
- }
-}
@endcode
@subsection Subsection42 Resulting reactionmaptutorialapp.pro
--- mcompositor-tests
+++ mcompositor-tests
-(directory)
--- mcompositor-tests/ft_windowstacking
+++ mcompositor-tests/ft_windowstacking
-(directory)
--- mcompositor-tests/ft_windowstacking/ft_windowstacking.pro
+++ mcompositor-tests/ft_windowstacking/ft_windowstacking.pro
-TEMPLATE = app
-TARGET = ft_windowstacking
-
-CONFIG += meegotouch link_pkgconfig
-
-PKGCONFIG += xi xorg-evdev
-
-# Input
-SOURCES += \
- main.cpp \
- windowstack.cpp \
- mwindowstack.cpp \
- xwindowstack.cpp
-
-HEADERS += \
- windowstack.h \
- mwindowstack.h \
- xwindowstack.h
-
-target.path = $$[QT_INSTALL_LIBS]/libmeegoreactionmap-mcompositor-tests
-INSTALLS += target
-
-QMAKE_EXTRA_TARGETS += check
-check.depends = $$TARGET
-check.commands = $$system(true)
-
-QMAKE_EXTRA_TARGETS += check-xml
-check-xml.depends = $$TARGET
-check-xml.commands = $$system(true)
--- mcompositor-tests/ft_windowstacking/main.cpp
+++ mcompositor-tests/ft_windowstacking/main.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 <QApplication>
-#include <QDebug>
-#include <QString>
-
-#include "windowstack.h"
-#include "mwindowstack.h"
-
-int main (int argc, char **argv)
-{
- bool runMApp = true;
- bool framelessWindow = false;
-
- if (argc >= 2) {
- if (QString(argv[1]) == "-qtapp") {
- runMApp = false;
- } else if (QString(argv[1]) == "-qtappframeless") {
- runMApp = false;
- framelessWindow = true;
- }
- }
-
- // Run either M application or plain QT application
- if (runMApp == true) {
- qDebug() << "Running test in MApplication mode.";
- MWindowStack *tester;
- tester = new MWindowStack(argc, argv);
- return tester->exec();
- } else {
- if (framelessWindow == true) {
- qDebug() << "Running test in QApplication frameless window mode.";
- } else {
- qDebug() << "Running test in QApplication mode.";
- }
- WindowStack *tester;
- tester = new WindowStack(framelessWindow, argc, argv);
- return tester->exec();
- }
-}
-
-
--- mcompositor-tests/ft_windowstacking/mwindowstack.cpp
+++ mcompositor-tests/ft_windowstacking/mwindowstack.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 <QDebug>
-#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)
- : MApplication(argc, argv)
-{
- currentlyVisible = -1;
- visibleWindowCount = 0;
-
- // Initialize X window stacking
- xStack.init();
-
- // Create top-level windows with application pages
- for (int i = 0; i < 3; ++i) {
- MApplicationWindow *window;
- MApplicationPage *page;
- QString windowName;
-
- window = new MApplicationWindow();
- windowName = "Window ";
- windowName.append(QString::number(i));
- windowName.append(" ID: ");
- windowName.append(QString::number(window->winId(), 16));
-
- page = new MApplicationPage();
- page->setWindowTitle(QString("Page #%1").arg(i));
-
- new MLabel(windowName, page->centralWidget());
-
- windowList << window;
- pageList << page;
- }
-
- QTimer::singleShot(0, this, SLOT(runTest()));
-}
-
-MWindowStack::~MWindowStack()
-{
- for (int i = 0; i < windowList.size(); ++i) {
- delete windowList[i];
- delete pageList[i];
- }
- windowList.clear();
- pageList.clear();
-}
-
-// Make each window visible and topmost and see that window
-// stacking is as expected. When every window is visible,
-// cycle through them once.
-void MWindowStack::runTest()
-{
- for (int i = 0; i < (2*windowList.size()); ++i) {
- currentlyVisible++;
- if (currentlyVisible >= windowList.size()) {
- currentlyVisible = 0;
- }
-
- qCritical() << "About to raise window:" << currentlyVisible << hex << windowList[currentlyVisible]->winId();
-
- xStack.hasChanged();
-
- // Show page in window in first cycle
- if (visibleWindowCount < windowList.size()) {
- windowList[currentlyVisible]->show();
- pageList[currentlyVisible]->appear(windowList[currentlyVisible]);
- windowListStackOrder.prepend(windowList[currentlyVisible]->winId());
- visibleWindowCount++;
- }
-
- // Make window topmost
- windowList[currentlyVisible]->raise();
- windowListStackOrder.move(windowListStackOrder.indexOf(windowList[currentlyVisible]->winId()), 0);
-
- // Make sure events will be processed to get the window really on top
- flush();
- processEvents();
- syncX();
-
- // Wait until it appears that there is no longer window
- // stacking going on. If there hasn't been any X stack
- // activity within 1000ms of the previous stack activity
- // it is determined that widows have reached stable state.
- // NOTE: This is a ugly and hacky way to do this.
- int timeout = 0;
- while (true) {
- if (xStack.hasChanged() == true) {
- timeout = 0;
- }
- if (timeout > 100) {
- break;
- }
- timeout++;
- usleep(10000);
- }
-
- if (xStack.verifyStackingOrder(windowListStackOrder) == false) {
- qFatal("Test failed.");
- }
- }
-
- 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
-/* 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.
- */
-
-#ifndef MWINDOWSTACK_H
-#define MWINDOWSTACK_H
-
-#include <MApplication>
-#include <QList>
-#include "xwindowstack.h"
-
-class MApplicationWindow;
-class MApplicationPage;
-
-class MWindowStack : public MApplication
-{
- Q_OBJECT
-
-public:
- MWindowStack(int &argc, char **argv);
- virtual ~MWindowStack();
-
-public slots:
- void runTest();
-
-private:
- int currentlyVisible;
- int visibleWindowCount;
- QList<MApplicationWindow*> windowList;
- QList<quint32> windowListStackOrder;
- QList<MApplicationPage*> pageList;
- XWindowStack xStack;
- void vkbTest();
-};
-
-#endif
--- mcompositor-tests/ft_windowstacking/windowstack.cpp
+++ mcompositor-tests/ft_windowstacking/windowstack.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 "windowstack.h"
-
-#include <QGraphicsScene>
-#include <QGraphicsView>
-#include <QMainWindow>
-#include <QString>
-
-#include <QTimer>
-#include <QDebug>
-
-WindowStack::WindowStack(bool framelessWindow, int argc, char **argv)
- : QApplication(argc, argv)
-{
- currentlyVisible = -1;
- visibleWindowCount = 0;
-
- // Initialize X window stacking
- xStack.init();
-
- // Create top-level windows
- for (int i = 0; i < 3; i++) {
- QMainWindow *window;
- QGraphicsScene *scene;
- QGraphicsView *view;
- QString windowName;
-
- if (framelessWindow == true) {
- window = new QMainWindow(0, Qt::FramelessWindowHint);
- } else {
- window = new QMainWindow(0);
- }
-
- scene = new QGraphicsScene(window);
-
- view = new QGraphicsView(window);
- view->setScene(scene);
-
- windowName = "Window ";
- windowName.append(QString::number(i));
- windowName.append("\nID: ");
- windowName.append(QString::number(window->winId(), 16));
- windowName.append("\nWindow: ");
- windowName.append(QString::number(window->window()->winId(), 16));
- scene->addText(windowName);
-
- window->setCentralWidget(view);
-
- windowList << window;
- }
-
- QTimer *timer;
- timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(runTest()));
- timer->start(0);
-}
-
-WindowStack::~WindowStack()
-{
- for (int i = 0; i < windowList.size(); ++i) {
- delete windowList[i];
- }
- windowList.clear();
-}
-
-// Make each window visible and topmost and see that window
-// stacking is as expected. When every window is visible,
-// cycle through them once.
-void WindowStack::runTest() {
- for (int i = 0; i < (2*windowList.size()); ++i) {
- currentlyVisible++;
- if (currentlyVisible >= windowList.size()) {
- currentlyVisible = 0;
- }
-
- qCritical() << "About to raise window:" << currentlyVisible << hex << windowList[currentlyVisible]->winId();
-
- // Show page in window in first cycle
- if (visibleWindowCount < windowList.size()) {
- windowList[currentlyVisible]->show();
- windowListStackOrder.prepend(windowList[currentlyVisible]->winId());
- visibleWindowCount++;
- }
-
- // Make window topmost
- windowList[currentlyVisible]->raise();
- windowListStackOrder.move(windowListStackOrder.indexOf(windowList[currentlyVisible]->winId()), 0);
-
- // Make sure events will be processed to get the window really on top
- flush();
- processEvents();
- syncX();
-
- // Wait until it appears that there is no longer window
- // stacking going on. If there hasn't been any X stack
- // activity within 1000ms of the previous stack activity
- // it is determined that widows have reached stable state.
- // NOTE: This is a ugly and hacky way to do this.
- int timeout = 0;
- while (true) {
- if (xStack.hasChanged() == true) {
- timeout = 0;
- }
- if (timeout > 100) {
- break;
- }
- timeout++;
- usleep(10000);
- }
-
- if (xStack.verifyStackingOrder(windowListStackOrder) == false) {
- qFatal("Test failed.");
- }
- }
-
- qDebug() << "Test was successful.";
-
- quit();
-}
-
--- mcompositor-tests/ft_windowstacking/windowstack.h
+++ mcompositor-tests/ft_windowstacking/windowstack.h
-/* 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.
- */
-
-#ifndef WINDOWSTACK_H
-#define WINDOWSTACK_H
-
-#include <QApplication>
-#include <QList>
-#include "xwindowstack.h"
-
-class QMainWindow;
-
-class WindowStack : public QApplication
-{
- Q_OBJECT
-
-public:
- WindowStack(bool framelessWindow, int argc, char **argv);
- virtual ~WindowStack();
-
-public slots:
- void runTest();
-
-private:
- int currentlyVisible;
- int visibleWindowCount;
- QList<QMainWindow*> windowList;
- QList<quint32> windowListStackOrder;
- XWindowStack xStack;
-};
-
-#endif
--- mcompositor-tests/ft_windowstacking/xwindowstack.cpp
+++ mcompositor-tests/ft_windowstacking/xwindowstack.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 "xwindowstack.h"
-
-#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),
- stackedWindows(NULL),
- stackedWindowsSize(0)
-{
-}
-
-XWindowStack::~XWindowStack()
-{
- if (stackedWindows != NULL) {
- XFree(stackedWindows);
- stackedWindows = NULL;
- stackedWindowsSize = 0;
- }
-
- if (display) {
- XCloseDisplay(display);
- display = NULL;
- }
-}
-
-bool XWindowStack::init()
-{
- int status;
- const char* displayString;
-
- displayString = qgetenv("DISPLAY");
- if (!displayString) {
- displayString = ":0";
- }
-
- display = XOpenDisplay(displayString);
-
- if (!display) {
- qWarning("Cannot connect to X server at %s", displayString);
- return false;
- }
-
- rootWindow = DefaultRootWindow(display);
-
- netClientListStackingAtom = XInternAtom(display, "_NET_CLIENT_LIST_STACKING", False);
- if (netClientListStackingAtom == None) {
- qCritical("Failed to intern atom _NET_CLIENT_LIST_STACKING.");
- return false;
- }
-
- status = XSelectInput(display, rootWindow, PropertyChangeMask);
- if (status == BadWindow) {
- return false;
- }
-
- return true;
-}
-
-QList<quint32> XWindowStack::getWindowOrder()
-{
- Atom actual_type;
- int actual_format;
- unsigned long nitems;
- unsigned long bytesAfterReturn;
- Window *stackedWindowsReturned = NULL;
- int status;
- QList<quint32> windowList;
-
- status = XGetWindowProperty(
- display,
- rootWindow,
- netClientListStackingAtom,
- 0, // long_offset
- (~0L), // long_length
- False, // delete
- XA_WINDOW, // required type
- &actual_type,
- &actual_format,
- &nitems,
- &bytesAfterReturn,
- (unsigned char**)&stackedWindowsReturned);
-
- if (status != Success) {
- qCritical() << "MfXListener: Failed to get property from root window. Status"
- << status;
- goto ERROR;
- }
-
- if (actual_type == None) {
- qWarning("MfXListener: Root window does not have"
- " _NET_CLIENT_LIST_STACKING property");
- goto ERROR;
- }
-
- if (bytesAfterReturn != 0) {
- // Maybe not be so lazy and just read those missing bytes.
- fprintf(stderr, "Unexpected behaviour: %lu bytes still unread after return.\n",
- bytesAfterReturn);
- goto ERROR;
- }
-
- // Free our current stackedWindows
- if (stackedWindows) {
- XFree(stackedWindows);
- stackedWindows = NULL;
- stackedWindowsSize = 0;
- }
-
- // Update it
- stackedWindows = stackedWindowsReturned;
- stackedWindowsSize = nitems;
-
- for (unsigned long i = 0; i < stackedWindowsSize; i++) {
- windowList.prepend(stackedWindows[i]);
- }
-
- return windowList;
-
- ERROR:
- if (stackedWindowsReturned) {
- XFree(stackedWindowsReturned);
- }
- return windowList;
-}
-
-bool XWindowStack::hasChanged()
-{
- XEvent event;
- bool ret = false;
-
- while (XPending(display)) {
- XNextEvent(display, &event);
-
- if (event.type != PropertyNotify)
- continue;
-
- if (event.xproperty.atom == netClientListStackingAtom) {
- ret = true;
- }
- }
-
- 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;
- int topIndex;
-
- if (expectedOrder.size() <= 0) {
- qWarning() << "verifyStackingOrder: Empty expected stacking list provided.";
- return false;
- }
-
- // Get current actual stacking order
- actualOrder = getWindowOrder();
-
- // Make sure expected topmost window is really the first or
- // second in actual stacking list. If virtual keyboard has
- // been visible, it's window ID will remain the topmost in
- // the actual stacking list.
- // NOTE: In this test we assume that if there is a window on
- // top of our expected window, it must be the virtual
- // keyboard.
- topIndex = actualOrder.indexOf(expectedOrder[0]);
- if (topIndex < 0) {
- qWarning() << "verifyStackingOrder: Expected topmost window was not found from actual stacking list.";
- printStacks(expectedOrder, actualOrder);
- return false;
- } else if (topIndex > 0) {
- qWarning() << "verifyStackingOrder: Expected topmost window was not first in actual stacking list.";
- printStacks(expectedOrder, actualOrder);
- return false;
- }
-
- // Make sure other windows are listed in the actual stacking
- // list, but they must not be on top of the expected top
- // window.
- // NOTE: Mcompositor makes sure that mhome will be the
- // window right after the topmost visible window
- // (excluding virtual keyboard). We don't care about
- // the order of windows behind mhome since mhome
- // is not transparent and at least for now it doesn't
- // use reaction maps.
- for (int i = 1; i < expectedOrder.size(); ++i) {
- int index = actualOrder.indexOf(expectedOrder[i]);
- if (index < 0) {
- qWarning() << "verifyStackingOrder: Some expected window was not found from actual stacking list.";
- printStacks(expectedOrder, actualOrder);
- return false;
- } else if (index < topIndex) {
- qWarning() << "verifyStackingOrder: Some expected window was on top of expected topmost window.";
- printStacks(expectedOrder, actualOrder);
- return false;
- }
- }
-
- printStacks(expectedOrder, actualOrder);
-
- return true;
-}
-
-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
-/* 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.
- */
-
-#ifndef XWINDOWSTACK_H
-#define XWINDOWSTACK_H
-
-#include <QList>
-
-#include <QString>
-
-// The next three files must be included before the X include files
-#include <QDataStream>
-#include <QTextStream>
-#include <QMetaType>
-#include <X11/Xlib.h>
-
-class XWindowStack
-{
-public:
- XWindowStack();
- virtual ~XWindowStack();
-
- bool init();
-
- // Returns true if stacking has changed since last call
- bool hasChanged();
-
- 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;
-
- Window *stackedWindows;
- unsigned long stackedWindowsSize;
-};
-
-#endif
--- mcompositor-tests/mcompositor-tests.pro
+++ mcompositor-tests/mcompositor-tests.pro
-TEMPLATE = subdirs
-
-ARCH = $$system(uname -m)
-
-SUBDIRS += \
- ft_windowstacking
-
-QMAKE_STRIP = echo
-include(shell.pri)
-
-check.target = check
-check.CONFIG = recursive
-QMAKE_EXTRA_TARGETS += check
-
-check-xml.target = check-xml
-check-xml.CONFIG = recursive
-QMAKE_EXTRA_TARGETS += check-xml
-
-QMAKE_CLEAN += **/*.log.xml ./coverage.log.xml **/*.log
--- mcompositor-tests/runtests.sh
+++ mcompositor-tests/runtests.sh
-#!/bin/sh
-
-export DISPLAY=:0
-
-TESTSDIR=/usr/lib/libmeegoreactionmap-tests
-OUTDIR=/tmp/libmeegoreactionmap-tests
-
-mkdir -p ${OUTDIR}
-
-EXIT_CODE=0
-for TEST in `ls ${TESTSDIR}/?t_*`; do
- $TEST -xml -o "${OUTDIR}/$(basename $TEST)".xml
- if [ $? -ne 0 ]; then
- EXIT_CODE=$((EXIT_CODE+1))
- fi
-done
-exit $EXIT_CODE
-
--- mcompositor-tests/shell.pri
+++ mcompositor-tests/shell.pri
-shell_scripts.commands += $$system(touch tests.xml)
-shell_scripts.files += runtests.sh tests.xml
-
-# fixed path required by TATAM
-shell_scripts.path += /usr/share/libmeegoreactionmap-mcompositor-tests
-shell_scripts.depends = FORCE
-
-INSTALLS += \
- shell_scripts
--- mcompositor-tests/tests.xml
+++ mcompositor-tests/tests.xml
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<testdefinition version="1.0">
- <suite name="libmeegoreactionmap-mcompositor-tests" domain="Application framework">
- <description>Functional tests to make sure that window stacking of mcompositor is done correctly. MReactionMaps rely on window stacking information to function poperly and these tests act as an indicator for any problems in the window stacking. </description>
- <set name="window_stacking_tests" feature="Window stacking of mcompositor" level="Component" type="Integration">
- <description>Window stacking tests for mcompositor</description>
-
- <case name="stacking_mapplication" description="Window stacking of mapplication" requirement="" timeout="60">
- <step expected_result="0">/usr/lib/libmeegoreactionmap-mcompositor-tests/ft_windowstacking</step>
- </case>
-
- <case name="stacking_qapplication1" description="Window stacking of qapplication" requirement="" timeout="60">
- <step expected_result="0">/usr/lib/libmeegoreactionmap-mcompositor-tests/ft_windowstacking -qtapp</step>
- </case>
-
- <case name="stacking_qapplication2" description="Window stacking of qapplication with frameless window" requirement="" timeout="60">
- <step expected_result="0">/usr/lib/libmeegoreactionmap-mcompositor-tests/ft_windowstacking -qtappframeless</step>
- </case>
-
- <environments>
- <scratchbox>false</scratchbox>
- <hardware>true</hardware>
- </environments>
-
- </set>
- </suite>
-</testdefinition>
--- meegofeedback-reactionmaps.pro
+++ meegofeedback-reactionmaps.pro
@@ -2,7 +2,6 @@
TEMPLATE = subdirs
SUBDIRS = src \
tests \
- mcompositor-tests \
tools
include (conf/conf.pri)
--- src/client/client.pro
+++ src/client/client.pro
@@ -10,6 +10,7 @@
QT += network
CONFIG += meegofeedback
QMAKE_CXXFLAGS_RELEASE += -finline-functions
+QMAKE_LFLAGS += "-Wl,--as-needed"
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
VERSION = 0.13.0
PUBLIC_HEADERS = mreactionmap.h
--- src/client/mreactionmap.cpp
+++ src/client/mreactionmap.cpp
@@ -106,6 +106,10 @@
void MReactionMap::setTransform(QGraphicsItem *item, QGraphicsView *view)
{
+ if (!item || !view) {
+ return;
+ }
+
d->setTransform(item, view);
}
@@ -156,27 +160,30 @@
void MReactionMap::fillItemBoundRect(QGraphicsItem *item)
{
- if (!item || !item->scene() || item->scene()->views().isEmpty()) {
+ if (!item) {
return;
}
- // 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;
- }
- }
+ QList<QGraphicsView*> views = d->findViewForItem(item);
// If a view associated with this reaction map was found, use that
// view's transformation to draw to this reaction map.
- if (viewIndex >= 0) {
+ if (!views.isEmpty()) {
QTransform currentTransform = d->transform;
- QRectF rect = item->boundingRect();
-
- setTransform(item, item->scene()->views()[viewIndex]);
- fillRectangle(rect);
+ QRectF itemRect = item->boundingRect();
+ // Fill the bounding rectangle in every view
+ for (int i = 0; i < views.size(); ++i) {
+ // Don't draw ouside the view, only draw the part of item
+ // that is currently visible inside the view.
+ QRectF viewRect = item->deviceTransform(views[i]->viewportTransform()).inverted().mapRect(views[i]->rect());
+ QRectF resultRect = viewRect.intersected(itemRect);
+
+ // Don't try to draw empty rectangels
+ if (!resultRect.isEmpty()) {
+ setTransform(item, views[i]);
+ fillRectangle(resultRect);
+ }
+ }
d->setTransform(currentTransform);
}
}
@@ -185,7 +192,7 @@
const QString &pressFeedback,
const QString &releaseFeedback)
{
- if (!item || !item->scene() || item->scene()->views().isEmpty()) {
+ if (!item) {
return;
}
--- src/client/mreactionmap_p.cpp
+++ src/client/mreactionmap_p.cpp
@@ -39,7 +39,7 @@
{
this->topLevelWidget = topLevelWidget;
this->topLevelWidget->installEventFilter(this);
- topLevelWidgetWinId = this->topLevelWidget->winId();
+ topLevelWidgetWinId = this->topLevelWidget->effectiveWinId();
image = 0;
isImageTemporary = false;
@@ -114,7 +114,7 @@
newSharedMemoryAddress = shmat(id, 0, 0);
- if ((int)newSharedMemoryAddress == -1) {
+ if ((qptrdiff)newSharedMemoryAddress == -1) {
qCritical() << "Unable to get shared memory address for"
<< tempFilePath;
newSharedMemoryAddress = 0;
@@ -169,6 +169,35 @@
transform = screenToReactionMapTransform;
}
+QList<QGraphicsView*> MReactionMapPrivate::findViewForItem(QGraphicsItem *item)
+{
+ QList<QGraphicsView*> retVal;
+ if (!item || !item->scene() || item->scene()->views().isEmpty()) {
+ return retVal;
+ }
+
+ // Go through all views of the items and find out which view(s)
+ // have a reaction map associated with the view (or the view's
+ // parent top level widget)
+ for (int i = 0; i < item->scene()->views().size(); ++i) {
+ // Find the top level widget
+ QWidget *parentWidget = item->scene()->views()[i];
+ while (parentWidget && parentWidget->parentWidget()) {
+ if (parentWidget->parentWidget()) {
+ parentWidget = parentWidget->parentWidget();
+ } else {
+ break;
+ }
+ }
+
+ if (topLevelWidget == parentWidget) {
+ retVal << item->scene()->views()[i];
+ }
+ }
+
+ return retVal;
+}
+
void MReactionMapPrivate::setTransform(QGraphicsItem *item, QGraphicsView *view)
{
// From item's local coordinate system to scene coordinate system
@@ -188,7 +217,7 @@
viewPosScreenCoords = view->mapToGlobal(QPoint(0,0));
viewToScreenTransform =
- QTransform::fromTranslate(-viewPosScreenCoords.x(), -viewPosScreenCoords.y());
+ QTransform::fromTranslate(viewPosScreenCoords.x(), viewPosScreenCoords.y());
// It's itemToScene followed by sceneToView, viewToScreen and finally by screenToReactionMap
transform =
@@ -337,10 +366,10 @@
bool MReactionMapPrivate::eventFilter(QObject *obj, QEvent *event)
{
- if (event->type() == QEvent::Show) {
+ if (event->type() == QEvent::WinIdChange) {
// If window ID of the top level widget has changed, inform server.
- if (topLevelWidget->winId() != topLevelWidgetWinId) {
- topLevelWidgetWinId = topLevelWidget->winId();
+ if (topLevelWidget->effectiveWinId() != topLevelWidgetWinId) {
+ topLevelWidgetWinId = topLevelWidget->effectiveWinId();
reactionMapConnection->updateReactionMapWindowId(this);
}
}
--- src/client/mreactionmap_p.h
+++ src/client/mreactionmap_p.h
@@ -19,6 +19,7 @@
#include <QTransform>
#include <QObject>
+#include <QList>
#include "mfeedbackpalette.h"
#include "mreactionmapconnection.h"
@@ -48,6 +49,7 @@
// path to a temp file.
bool buildSharedMemoryImage(const QString& tempFilePath);
+ QList<QGraphicsView*> findViewForItem(QGraphicsItem *item);
void setTransform(QGraphicsItem *item, QGraphicsView *view);
void setTransform(QTransform transform);
// Build screenToReactionMapTransform attribute
--- src/mfsource/mfconnection.cpp
+++ src/mfsource/mfconnection.cpp
@@ -18,8 +18,10 @@
#include "mfsession.h"
#include <mfcommondata.h>
-#include <QLocalSocket>
+
+#include <QCoreApplication>
#include <QDebug>
+#include <QLocalSocket>
#include "mfreactionmap.h"
#include "mfreactionmapstack.h"
@@ -50,6 +52,7 @@
// Remove all existing reaction maps
QMap<quint32, MfReactionMap *>::iterator i = reactionMaps.begin();
while (i != reactionMaps.end()) {
+ stack->remove(i.value());
delete i.value();
i = reactionMaps.erase(i);
}
@@ -72,6 +75,33 @@
}
}
+void MfConnection::sessionSetupReady()
+{
+ MfReactionMap *newReactionMap = new MfReactionMap(sessions[0].session, sessions[0].windowId, clientPid, this);
+
+ if (reactionMaps.contains(sessions[0].id) == false &&
+ newReactionMap->init() == true) {
+ QDataStream socketStream(socket);
+
+ stack->add(newReactionMap);
+ reactionMaps.insert(sessions[0].id, newReactionMap);
+
+ // Send back information needed by the client to attach himself to the
+ // newly created shared memory
+ socketStream << sessions[0].id;
+ socketStream << newReactionMap->tempFilePath();
+
+ // Reaction map creation has ended
+ qDebug() << "MfConnection: finished adding reaction map for client"
+ << sessions[0].clientName;
+ sessions[0].session = NULL;
+ sessions.remove(0);
+ } else {
+ // We are doomed.
+ goDoomed();
+ }
+}
+
void MfConnection::init()
{
QDataStream socketStream (socket);
@@ -84,42 +114,24 @@
void MfConnection::readRequest()
{
quint8 requestType;
- QDataStream socketStream (socket);
+ QDataStream socketStream(socket);
socketStream >> requestType;
switch (requestType) {
case MF_REQUEST_ADD:
{
- quint32 identifier;
- QString clientName;
- quint32 windowId;
- MfReactionMap *newReactionMap;
+ SessionData newSession;
// Requested new reaction map
- socketStream >> identifier;
- socketStream >> clientName;
- socketStream >> windowId;
-
- newReactionMap = new MfReactionMap(new MfSession(clientName), windowId, clientPid, this);
-
- if (reactionMaps.contains(identifier) == false &&
- newReactionMap->init() == true) {
- stack->add(newReactionMap);
- reactionMaps.insert(identifier, newReactionMap);
-
- // Send back information needed by the client to attach himself to the
- // newly created shared memory
- socketStream << identifier;
- socketStream << newReactionMap->tempFilePath();
-
- // Reaction map creation has ended
- qDebug() << "MfConnection: finished adding reaction map for client"
- << clientName;
- } else {
- // We are doomed.
- goDoomed();
- }
+ socketStream >> newSession.id;
+ socketStream >> newSession.clientName;
+ socketStream >> newSession.windowId;
+
+ newSession.session = new MfSession(newSession.clientName);
+ sessions.prepend(newSession);
+ connect(newSession.session, SIGNAL(setupReady()), this, SLOT(sessionSetupReady()),
+ Qt::QueuedConnection);
}
break;
--- src/mfsource/mfconnection.h
+++ src/mfsource/mfconnection.h
@@ -19,11 +19,21 @@
#include <QObject>
#include <QMap>
+#include <QVector>
#include <QPointer>
class QLocalSocket;
class MfReactionMapStack;
class MfReactionMap;
+class MfSession;
+
+struct SessionData
+{
+ quint32 id;
+ QString clientName;
+ quint32 windowId;
+ MfSession* session;
+};
class MfConnection : public QObject
{
@@ -35,6 +45,7 @@
private slots:
void readSocketData();
+ void sessionSetupReady();
private:
void init();
@@ -51,6 +62,7 @@
MfReactionMapStack *stack;
QMap <quint32, MfReactionMap *> reactionMaps;
qint64 clientPid;
+ QVector<SessionData> sessions;
};
#endif
--- src/mfsource/mfkernelthread.cpp
+++ src/mfsource/mfkernelthread.cpp
@@ -26,13 +26,16 @@
#include <stdint.h>
#include <QtDebug>
+#include <QString>
#include "mfdefaulttranslator.h"
#include "mfreactionmapstack.h"
#include "mfsettings.h"
+static QString touchScreenDevicePath("/dev/input/ts");
+
MfKernelThread::MfKernelThread(MfReactionMapStack *reactionMapStack, QObject *parent) :
- QThread(parent), reactionMapStack(reactionMapStack)
+ QThread(parent), reactionMapStack(reactionMapStack), isActive(true)
{
}
@@ -60,24 +63,27 @@
{
bool ok = true;
int result;
- int nfsd;
// We must have at least one touch device
Q_ASSERT(touchDevicesVector.size() > 0);
- nfsd = computeNFSD();
+ nfds = computeNFDS();
do {
- ok = waitForEvent(nfsd);
+ ok = waitForEvent();
} while (ok);
- // Close all input event files
+ // Close all open input event file descriptors
for (int i = 0; i < touchDevicesVector.size(); ++i) {
- result = close(touchDevicesVector[i]->fd);
- if (result == -1) {
- qWarning("MfKernelThread: Failed to close input event fd.");
+ if (touchDevicesVector[i]->fd >= 0) {
+ result = close(touchDevicesVector[i]->fd);
+ touchDevicesVector[i]->fd = -1;
+ if (result == -1) {
+ qWarning("MfKernelThread: Failed to close input event fd.");
+ }
}
}
+
// Is it a right place to do the clean up?
qDeleteAll(touchDevicesVector);
touchDevicesVector.clear();
@@ -87,7 +93,60 @@
return true;
}
-bool MfKernelThread::waitForEvent(int nfsd)
+bool MfKernelThread::readHostMessage()
+{
+ bool ret = true;
+ int bytes;
+ char buf[1];
+
+ bytes = read(communicationSocketFd, buf, 1);
+ if (bytes < 1) {
+ qWarning("MfKernelThread: Failed to read a message from host at readHostMessage");
+ return ret;
+ }
+
+ switch (buf[0]) {
+ case MF_KERNEL_THREAD_STOP:
+ // Return false to break from the loop and end thread
+ ret = false;
+ break;
+
+ case MF_KERNEL_THREAD_PAUSE:
+ // Mark status as inactive and close all kernel interfaces
+ isActive = false;
+ for (int i = 0; i < touchDevicesVector.size(); ++i) {
+ MfTouchDevice *touchDevice = touchDevicesVector[i];
+ if (touchDevice->fd >= 0) {
+ close(touchDevice->fd);
+ touchDevice->fd = -1;
+ }
+ }
+ nfds = computeNFDS();
+ break;
+
+ case MF_KERNEL_THREAD_RESUME:
+ // Mark status as active and reopen all kernel interfaces
+ isActive = true;
+ for (int i = 0; i < touchDevicesVector.size(); ++i) {
+ MfTouchDevice *touchDevice = touchDevicesVector[i];
+ if (touchDevice->fd < 0) {
+ if ((touchDevice->fd = open(touchScreenDevicePath.toAscii().constData(), O_RDONLY)) < 0) {
+ touchDevice->fd = -errno;
+ qWarning("MfKernelThread: open error");
+ }
+ }
+ }
+ nfds = computeNFDS();
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+bool MfKernelThread::waitForEvent()
{
fd_set readFdSet;
int ret = 0;
@@ -96,22 +155,30 @@
// Build the file descriptors set
FD_ZERO(&readFdSet);
- FD_SET(stopListeningSocketFd, &readFdSet);
- for (i = 0; i < touchDevicesVector.size(); ++i) {
- FD_SET(touchDevicesVector[i]->fd, &readFdSet);
+ FD_SET(communicationSocketFd, &readFdSet);
+
+ // Only add touchsceen file descriptors if display is active
+ if (isActive) {
+ for (i = 0; i < touchDevicesVector.size(); ++i) {
+ if (touchDevicesVector[i]->fd >= 0) {
+ FD_SET(touchDevicesVector[i]->fd, &readFdSet);
+ }
+ }
}
- ret = select(nfsd, &readFdSet, NULL/*writefds*/, NULL/*exceptfds*/, NULL);
+
+ ret = select(nfds, &readFdSet, NULL/*writefds*/, NULL/*exceptfds*/, NULL);
if (ret == -1) {
qCritical("MfKernelThread: Error in select()");
ok = false;
- } else if (FD_ISSET(stopListeningSocketFd, &readFdSet)) {
- // It's time to exit
- ok = false;
- } else {
+ } else if (FD_ISSET(communicationSocketFd, &readFdSet)) {
+ ok = readHostMessage();
+ } else if (isActive) {
for (i = 0; i < touchDevicesVector.size(); ++i) {
- MfTouchDevice *touchDevice = touchDevicesVector[i];
- if (FD_ISSET(touchDevice->fd, &readFdSet)) {
- touchDevice->processEvents();
+ if (touchDevicesVector[i]->fd >= 0) {
+ MfTouchDevice *touchDevice = touchDevicesVector[i];
+ if (FD_ISSET(touchDevice->fd, &readFdSet)) {
+ touchDevice->processEvents();
+ }
}
}
}
@@ -122,10 +189,8 @@
bool MfKernelThread::scanInputDevices()
{
- // Loop until we find both touch points or we finished
- // scanning all available event files
int fd;
- fd = checkInputDevice("/dev/input/ts");
+ fd = checkInputDevice(touchScreenDevicePath.toAscii().constData());
if (fd == -ENOENT)
return false;
@@ -208,15 +273,19 @@
return highestFd;
}
-int MfKernelThread::computeNFSD()
+int MfKernelThread::computeNFDS()
{
- int highestFd;
+ int highestFd = -1;
+
+ // Only consider touch screen fd if screen is active
+ if (isActive) {
+ highestFd = findHighestTouchPointFd();
+ }
- highestFd = findHighestTouchPointFd();
- if (highestFd > stopListeningSocketFd) {
+ if (highestFd > communicationSocketFd) {
return highestFd + 1;
} else {
- return stopListeningSocketFd + 1;
+ return communicationSocketFd + 1;
}
}
--- src/mfsource/mfkernelthread.h
+++ src/mfsource/mfkernelthread.h
@@ -23,6 +23,12 @@
#include <QThread>
#include <QVector>
+// Define communication protocol between MfKernelThread
+// and MfTouchScreenListener (kernel implementation)
+#define MF_KERNEL_THREAD_STOP 0
+#define MF_KERNEL_THREAD_PAUSE 1
+#define MF_KERNEL_THREAD_RESUME 2
+
class MfReactionMapStack;
class MfTouchScreenTranslator;
@@ -65,7 +71,7 @@
QObject *parent = 0);
~MfKernelThread();
- int stopListeningSocketFd;
+ int communicationSocketFd;
protected:
@@ -75,18 +81,20 @@
bool setup();
bool listen();
+ bool readHostMessage();
bool scanInputDevices();
int checkInputDevice(const char *name);
- bool waitForEvent(int nfsd);
+ bool waitForEvent();
int findHighestTouchPointFd();
- // compute nfsd parameter used in select() function call
- int computeNFSD();
+ // Compute nfds parameter used in select() function call
+ int computeNFDS();
QVector<MfTouchDevice*> touchDevicesVector;
-
MfReactionMapStack *reactionMapStack;
+ int nfds;
+ bool isActive;
};
#endif
--- src/mfsource/mfreactionmap.cpp
+++ src/mfsource/mfreactionmap.cpp
@@ -224,8 +224,9 @@
int width = MfSettings::reactionMapWidth();
int height = MfSettings::reactionMapHeight();
- if (session)
+ if (session) {
buildFeedbackList(session->feedbackHash);
+ }
#ifdef FR_LOCAL_REACTIONMAP
// Allocate memory for image. No shared memory involved.
@@ -277,7 +278,7 @@
sharedMemoryAddress = shmat(sharedMemoryId, 0, 0);
- if ((int)sharedMemoryAddress == -1) {
+ if ((qptrdiff)sharedMemoryAddress == -1) {
qCritical() << "Unable to get shared memory address for"
<< tempFileName;
return false;
--- src/mfsource/mfreactionmapstack.cpp
+++ src/mfsource/mfreactionmapstack.cpp
@@ -23,32 +23,17 @@
#include <mfutil.h>
#include "mfreactionmap.h"
-#include "mfxcalib.h"
MfReactionMapStack::MfReactionMapStack(bool ignoreStacking, QObject *parent)
- : QObject(parent), ignoreStacking(ignoreStacking), calibration(0)
+ : QObject(parent), ignoreStacking(ignoreStacking), reactiveOnTop(false)
{
if (ignoreStacking) {
qDebug("MfReactionMapStack: Ignoring window stacking.");
}
- if (!calibration) {
- calibration = new MfXCalib();
- calibration->init();
- if (!calibration->axisCalibration())
- {
- qDebug("MfReactionMapStack: No axis calibration data for the touchscreen.");
- } else {
- qCritical("MfReactionMapStack: Using axis calibration data is not implemented yet.");
- }
- }
}
MfReactionMapStack::~MfReactionMapStack()
{
- if (calibration) {
- delete calibration;
- calibration = 0;
- }
}
void MfReactionMapStack::add(MfReactionMap *reactionMap)
@@ -68,9 +53,6 @@
{
QMutexLocker locker(&mutex);
- Q_ASSERT(reactionMapHash.contains(reactionMap->windowId()));
- Q_ASSERT(reactionMapList.contains(reactionMap));
-
if (reactionMapHash.remove(reactionMap->windowId())) {
reactionMapList.removeOne(reactionMap);
rebuildStack();
@@ -156,10 +138,22 @@
rebuildStack();
}
+bool MfReactionMapStack::hasWindowReactionMap(quint32 windowId) {
+ QMutexLocker locker(&mutex);
+
+ return reactionMapHash.contains(windowId);
+}
+
+bool MfReactionMapStack::isReactiveWindowOnTop() const
+{
+ return reactiveOnTop;
+}
+
void MfReactionMapStack::rebuildStack()
{
stack.clear();
quint32 windowId;
+ bool onTop = false;
for (int i = windowList.size() - 1; i >= 0; i--) {
windowId = windowList[i];
@@ -170,6 +164,16 @@
}
}
+ // Send signal when a topmost window that uses reaction maps
+ // appears or disappears.
+ if (!windowList.isEmpty()) {
+ onTop = reactionMapHash.contains(windowList.last());
+ }
+ if (onTop != reactiveOnTop) {
+ reactiveOnTop = onTop;
+ emit reactiveWindowOnTop(reactiveOnTop);
+ }
+
#ifdef MF_DEBUG
print();
#endif
--- src/mfsource/mfreactionmapstack.h
+++ src/mfsource/mfreactionmapstack.h
@@ -24,7 +24,6 @@
#include <QHash>
class MfReactionMap;
-class MfXCalib;
class MfReactionMapStack : public QObject
{
@@ -46,6 +45,13 @@
*/
void released(const QPoint &position);
+ bool hasWindowReactionMap(quint32 windowId);
+
+ bool isReactiveWindowOnTop() const;
+
+signals:
+ void reactiveWindowOnTop(bool state);
+
public slots:
/* Reorder reaction maps according to their window ids.
* @param window Current X Window ID stack, ordered bottom-to-top.
@@ -90,8 +96,8 @@
// Just use the first reaction map we happen to have
bool ignoreStacking;
- // Calibration instance for X coordinates
- MfXCalib *calibration;
+ // Tells if the topmost window uses reaction map
+ bool reactiveOnTop;
};
#endif
--- src/mfsource/mfreactorsource.cpp
+++ src/mfsource/mfreactorsource.cpp
@@ -16,11 +16,14 @@
#include "mfreactorsource.h"
#include "mfserver.h"
+#include "mftouchscreenlistener.h"
+#include "mfxlistener.h"
#include <mfsettings.h>
MfReactorSource::MfReactorSource()
- : touchScreenListener(0), reactionMapStack(MfSettings::ignoreStacking())
+ : touchScreenListener(NULL), reactionMapStack(MfSettings::ignoreStacking()),
+ reactionMapActive(true), displayActive(true), initialized(false)
{
}
@@ -28,12 +31,17 @@
{
if (server) {
delete server;
- server = 0;
+ server = NULL;
}
if (touchScreenListener) {
delete touchScreenListener;
- touchScreenListener = 0;
+ touchScreenListener = NULL;
+ }
+
+ if (xListener) {
+ delete xListener;
+ xListener = NULL;
}
}
@@ -41,23 +49,76 @@
{
bool ok;
- ok = reactionMapStack.connect(&xListener,
+ if (initialized) {
+ return true;
+ }
+
+ xListener = new MfXListener(&reactionMapStack);
+
+ ok = reactionMapStack.connect(xListener,
SIGNAL(windowStackChanged(QList<quint32>)),
SLOT(reorder(QList<quint32>)));
if (!ok) return false;
- ok = xListener.startListening();
+ ok = connect(&reactionMapStack, SIGNAL(reactiveWindowOnTop(bool)),
+ this, SLOT(updateState()));
+ if (!ok) return false;
+
+ ok = xListener->startListening();
if (!ok) return false;
touchScreenListener = new MfTouchScreenListener(&reactionMapStack);
ok = touchScreenListener->startListening();
if (!ok) return false;
+ ok = connect(this, SIGNAL(stateChanged(bool)),
+ touchScreenListener, SLOT(setActive(bool)));
+ if (!ok) return false;
+
server = new MfServer(&reactionMapStack, this);
ok = server->init();
if (!ok) return false;
+ initialized = true;
+
+ // Get the real state after initalization
+ updateState();
+
return true;
}
+bool MfReactorSource::isActive() const
+{
+ return reactionMapActive;
+}
+
+void MfReactorSource::updateState()
+{
+ bool oldVal = reactionMapActive, reactiveOnTop;
+
+ if (!initialized) {
+ return;
+ }
+
+ reactiveOnTop = reactionMapStack.isReactiveWindowOnTop();
+
+ reactionMapActive = reactiveOnTop && displayActive;
+
+ if (oldVal != reactionMapActive) {
+ emit stateChanged(reactionMapActive);
+ }
+}
+
+void MfReactorSource::deviceStateChanged(const QMap<QString, QString> &newState)
+{
+ if (newState.contains("display")) {
+ if (newState["display"] == "off") {
+ displayActive = false;
+ } else {
+ displayActive = true;
+ }
+ updateState();
+ }
+}
+
Q_EXPORT_PLUGIN2(meegofeedback-reactionmaps, MfReactorSource);
--- src/mfsource/mfreactorsource.h
+++ src/mfsource/mfreactorsource.h
@@ -18,28 +18,46 @@
#define MFREACTORSOURCE_H
#include <QObject>
-#include <mfsourceinterface.h>
+#include <mfsourcebase.h>
#include "mfreactionmapstack.h"
-#include "mftouchscreenlistener.h"
-#include "mfxlistener.h"
class MfServer;
+class MfXListener;
+class MfTouchScreenListener;
-class MfReactorSource : public QObject, MfSourceInterface
+class MfReactorSource : public MfSourceBase
{
Q_OBJECT
Q_INTERFACES(MfSourceInterface)
public:
MfReactorSource();
virtual ~MfReactorSource();
+
+ // Exported method (defined in MfSourceBase)
bool init();
+ // Internal method
+ bool isActive() const;
+
+public slots:
+ // Exported method (defined in MfSourceBase)
+ void deviceStateChanged(const QMap<QString, QString> &newState);
+
+signals:
+ void stateChanged(bool active);
+
+private slots:
+ void updateState();
+
private:
MfTouchScreenListener *touchScreenListener;
MfServer *server;
MfReactionMapStack reactionMapStack;
- MfXListener xListener;
+ MfXListener *xListener;
+ bool reactionMapActive;
+ bool displayActive;
+ bool initialized;
};
#endif
--- src/mfsource/mfsource_common.pri
+++ src/mfsource/mfsource_common.pri
@@ -2,9 +2,10 @@
INCLUDEPATH += . \
../common
CONFIG += link_pkgconfig plugin meegofeedback
-QT += network
-PKGCONFIG += xi xorg-evdev
+QT += network dbus
+PKGCONFIG += xcb
QMAKE_CXXFLAGS += -finline-functions -fno-strict-aliasing
+QMAKE_LFLAGS += "-Wl,--as-needed"
CONFIG(release, debug|release):DEFINES += QT_NO_DEBUG_OUTPUT
else:DEFINES += MF_DEBUG
@@ -20,7 +21,6 @@
../mfsource/mfserver.h \
../mfsource/mftouchscreenlistener.h \
../mfsource/mftouchscreentranslator.h \
- ../mfsource/mfxcalib.h \
../mfsource/mfxlistener_p.h \
../mfsource/mfxlistener.h \
../mfsource/mfconnection.h \
@@ -32,7 +32,6 @@
../mfsource/mfreactionmapstack.cpp \
../mfsource/mfreactorsource.cpp \
../mfsource/mfserver.cpp \
- ../mfsource/mfxcalib.cpp \
../mfsource/mfxlistener_p.cpp \
../mfsource/mfxlistener.cpp \
../mfsource/mfconnection.cpp \
--- src/mfsource/mftouchscreenlistener.h
+++ src/mfsource/mftouchscreenlistener.h
@@ -33,6 +33,11 @@
bool startListening();
bool stopListening();
+ bool isActive();
+
+public slots:
+ void setActive(bool active);
+
private:
MfTouchScreenListenerPriv *d;
};
--- src/mfsource/mftouchscreenlistener_dummy.cpp
+++ src/mfsource/mftouchscreenlistener_dummy.cpp
@@ -36,3 +36,13 @@
{
return true;
}
+
+bool MfTouchScreenListener::isActive()
+{
+ return true;
+}
+
+void MfTouchScreenListener::setActive(bool active)
+{
+ Q_UNUSED(active);
+}
--- src/mfsource/mftouchscreenlistener_kernel.cpp
+++ src/mfsource/mftouchscreenlistener_kernel.cpp
@@ -28,14 +28,16 @@
// 0 - Used by MfTouchScreenListener on main thread
// 1 - Used by MfKernelThread on listener thread
- int stopListeningSocketFdPair[2];
+ int communicationSocketFdPair[2];
+
+ bool isActive;
};
MfTouchScreenListenerPriv::MfTouchScreenListenerPriv(MfReactionMapStack *reactionMapStack)
- : kernelThread(reactionMapStack)
+ : kernelThread(reactionMapStack), isActive(true)
{
- stopListeningSocketFdPair[0] = -1;
- stopListeningSocketFdPair[1] = -1;
+ communicationSocketFdPair[0] = -1;
+ communicationSocketFdPair[1] = -1;
}
MfTouchScreenListener::MfTouchScreenListener(MfReactionMapStack *reactionMapStack,
@@ -61,28 +63,30 @@
bool MfTouchScreenListener::startListening()
{
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, d->stopListeningSocketFdPair)) {
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, d->communicationSocketFdPair)) {
qCritical("MfTouchScreenListener: Failed to create socket pair");
return false;
}
- d->kernelThread.stopListeningSocketFd = d->stopListeningSocketFdPair[1];
+ d->kernelThread.communicationSocketFd = d->communicationSocketFdPair[1];
+ // Set the stack size quite low to avoid too much memory mappings
+ d->kernelThread.setStackSize(512*1024);
d->kernelThread.start();
return true;
}
bool MfTouchScreenListener::stopListening()
{
- char msg = 1;
+ char msg = MF_KERNEL_THREAD_STOP;
if (!d->kernelThread.isRunning()) {
// Nothing to be done
return true;
}
- // Just send something
- if (write(d->stopListeningSocketFdPair[0], &msg, sizeof(char)) != sizeof(char)) {
+ // Send MF_KERNEL_THREAD_STOP to thread
+ if (write(d->communicationSocketFdPair[0], &msg, sizeof(char)) != sizeof(char)) {
qWarning("MfTouchScreenListener: Failed to send thread stop msg.");
}
@@ -92,16 +96,39 @@
d->kernelThread.wait();
}
- if (close(d->stopListeningSocketFdPair[0]) == -1) {
+ if (close(d->communicationSocketFdPair[0]) == -1) {
qWarning("MfTouchScreenListener: Failed to close stopListening socket");
}
- d->stopListeningSocketFdPair[0] = -1;
+ d->communicationSocketFdPair[0] = -1;
- if (close(d->stopListeningSocketFdPair[1]) == -1) {
+ if (close(d->communicationSocketFdPair[1]) == -1) {
qWarning("MfTouchScreenListener: Failed to close stopListening socket");
}
- d->stopListeningSocketFdPair[1] = -1;
+ d->communicationSocketFdPair[1] = -1;
qDebug("MfTouchScreenListener: Stopped nicely");
return true;
}
+
+bool MfTouchScreenListener::isActive()
+{
+ return d->isActive;
+}
+
+void MfTouchScreenListener::setActive(bool active)
+{
+ if (active != d->isActive) {
+ char msg;
+ if (active) {
+ msg = MF_KERNEL_THREAD_RESUME;
+ } else {
+ msg = MF_KERNEL_THREAD_PAUSE;
+ }
+
+ if (write(d->communicationSocketFdPair[0], &msg, sizeof(char)) != sizeof(char)) {
+ qWarning("MfTouchScreenListener: Failed to send control message to MfKernelThread.");
+ }
+
+ d->isActive = active;
+ }
+}
--- src/mfsource/mftouchscreenlistener_xcore.cpp
+++ src/mfsource/mftouchscreenlistener_xcore.cpp
@@ -45,3 +45,13 @@
d->xcoreThread.start();
return true;
}
+
+bool MfTouchScreenListener::isActive()
+{
+ return true;
+}
+
+void MfTouchScreenListener::setActive(bool active)
+{
+ Q_UNUSED(active);
+}
--- src/mfsource/mftouchscreenlistener_xrecord.cpp
+++ src/mfsource/mftouchscreenlistener_xrecord.cpp
@@ -201,3 +201,12 @@
return NULL;
}
+bool MfTouchScreenListener::isActive()
+{
+ return true;
+}
+
+void MfTouchScreenListener::setActive(bool active)
+{
+ Q_UNUSED(active);
+}
--- src/mfsource/mfxcalib.cpp
+++ src/mfsource/mfxcalib.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.h"
-
-#include <X11/Xatom.h>
-#include <X11/Xproto.h>
-#include <X11/extensions/XInput.h>
-
-#ifdef NO_EVDEV
-#define EVDEV_PROP_INVERT_AXES "Evdev Axis Inversion"
-#define EVDEV_PROP_CALIBRATION "Evdev Axis Calibration"
-
-/* Swap x and y axis. */
-#define EVDEV_PROP_SWAP_AXES "Evdev Axes Swap"
-#else
-#include <evdev-properties.h>
-#endif // NO_EVDEV
-
-#include <QDebug>
-
-MfXCalib::MfXCalib()
- : display(NULL), tsAxisCalib(false), tsMinX(0), tsMinY(0),
- tsMaxX(0), tsMaxY(0)
-{
-}
-
-MfXCalib::~MfXCalib()
-{
- if (display) {
- XCloseDisplay(display);
- display = NULL;
- }
-}
-
-bool MfXCalib::getCalibrationValues()
-{
- // Device list variables
- XDeviceInfo *deviceList = 0;
- XDevice *device = 0;
- int numDevices = 0;
- int touchDevice = -1;
- Atom prop;
- Atom actualType;
- int actualFormat;
- unsigned long nItems;
- unsigned long bytesAfterReturn;
- qint32 *dimensions = 0;
- bool invert[2] = {false, false};
- bool swapping = false;
- int status;
- bool ret = false;
-
- // Get the input device list
- deviceList = XListInputDevices(display, &numDevices);
- if (!deviceList) {
- qCritical("MfXCalib: Failed to get the input device list from the X.");
- goto ERROR;
- }
- if (numDevices <= 0) {
- qCritical("MfXCalib: No input devices in the X.");
- goto ERROR;
- }
- prop = XInternAtom(display, XI_TOUCHSCREEN, False);
- if (prop == None) {
- qCritical("MfXCalib: Failed to intern atom XI_TOUCHSCREEN.");
- goto ERROR;
- }
-
- // Get the touch screen device
- for (int i = 0; i < numDevices && touchDevice == -1; i++) {
- if (deviceList[i].type == prop) {
- touchDevice = i;
- }
- }
- if (touchDevice == -1) {
- qCritical("MfXCalib: Unable to find the touch screen device.");
- goto ERROR;
- }
- device = XOpenDevice(display, deviceList[touchDevice].id);
- if (!device) {
- qCritical("MfXCalib: Unable to get the touch screen device from the X.");
- goto ERROR;
- }
-
- // Get the calibrated dimensions
- prop = XInternAtom(display, EVDEV_PROP_CALIBRATION, False);
- if (prop == None) {
- qCritical("MfXCalib: Failed to intern atom EVDEV_PROP_CALIBRATION.");
- goto ERROR;
- }
- status = XGetDeviceProperty(
- display,
- device,
- prop,
- 0,
- 1,
- False,
- XA_INTEGER,
- &actualType,
- &actualFormat,
- &nItems,
- &bytesAfterReturn,
- (unsigned char**)&dimensions);
- if (status != Success) {
- qCritical() << "MfXCalib: Failed to get EVDEV_PROP_CALIBRATION from the device. Status"
- << status;
- goto ERROR;
- }
- if (actualType == None) {
- qWarning("MfXCalib: The device does not have EVDEV_PROP_CALIBRATION property");
- goto ERROR;
- }
- if (bytesAfterReturn != 0) {
- // Maybe not be so lazy and just read those missing bytes.
- qCritical("MfXCalib: Unexpected behaviour: %lu bytes still unread after return.",
- bytesAfterReturn);
- goto ERROR;
- }
- if (nItems > 0)
- {
- tsAxisCalib = true;
- tsMinX = dimensions[0];
- tsMinY = dimensions[1];
- tsMaxX = dimensions[2];
- tsMaxY = dimensions[3];
- }
-
- // Get the calibrated axes info
- prop = XInternAtom(display, EVDEV_PROP_INVERT_AXES, False);
- if (prop == None) {
- qCritical("MfXCalib: Failed to intern atom EVDEV_PROP_INVERT_AXES.");
- goto ERROR;
- }
- status = XGetDeviceProperty(
- display,
- device,
- prop,
- 0,
- 1,
- False,
- XA_INTEGER,
- &actualType,
- &actualFormat,
- &nItems,
- &bytesAfterReturn,
- (unsigned char**)&dimensions);
- if (status != Success) {
- qCritical() << "MfXCalib: Failed to get EVDEV_PROP_INVERT_AXES from the device. Status"
- << status;
- goto ERROR;
- }
- if (actualType == None) {
- qWarning("MfXCalib: The device does not have EVDEV_PROP_INVERT_AXES property");
- goto ERROR;
- }
- if (bytesAfterReturn != 0) {
- // Maybe not be so lazy and just read those missing bytes.
- qCritical("MfXCalib: Unexpected behaviour: %lu bytes still unread after return.",
- bytesAfterReturn);
- goto ERROR;
- }
- if (nItems > 0)
- {
- tsAxisX = (int)invert[0];
- tsAxisY = (int)invert[1];
- } else {
- tsAxisX = -1;
- tsAxisY = -1;
- }
-
- // Get the calibrated axes swap
- prop = XInternAtom(display, EVDEV_PROP_SWAP_AXES, False);
- if (prop == None) {
- qCritical("MfXCalib: Failed to intern atom EVDEV_PROP_SWAP_AXES.");
- goto ERROR;
- }
- status = XGetDeviceProperty(
- display,
- device,
- prop,
- 0,
- 1,
- False,
- XA_INTEGER,
- &actualType,
- &actualFormat,
- &nItems,
- &bytesAfterReturn,
- (unsigned char**)&dimensions);
- if (status != Success) {
- qCritical() << "MfXCalib: Failed to get EVDEV_PROP_INVERT_AXES from the device. Status"
- << status;
- goto ERROR;
- }
- if (actualType == None) {
- qWarning("MfXCalib: The device does not have EVDEV_PROP_INVERT_AXES property");
- goto ERROR;
- }
- if (bytesAfterReturn != 0) {
- // Maybe not be so lazy and just read those missing bytes.
- qCritical("MfXCalib: Unexpected behaviour: %lu bytes still unread after return.",
- bytesAfterReturn);
- goto ERROR;
- }
- if (nItems > 0)
- {
- tsAxesSwap = (int)swapping;
- } else {
- tsAxesSwap = -1;
- }
-
- ret = true;
- ERROR:
- if (deviceList) {
- XFreeDeviceList(deviceList);
- }
- if (device) {
- XCloseDevice(display, device);
- }
- if (dimensions) {
- XFree(dimensions);
- }
- return ret;
-}
-
-
-bool MfXCalib::init()
-{
- QByteArray displayString;
-
- // Try to get the DISPLAY environment variable. If it is not
- // defined, default to :0 and try to open that.
- displayString = qgetenv("DISPLAY");
- if (displayString.isEmpty() == true) {
- displayString = ":0";
- }
-
- display = XOpenDisplay(displayString.constData());
-
- if (!display) {
- qWarning("Cannot connect to X server");
- return false;
- }
-
- return getCalibrationValues();
-}
-
-void MfXCalib::processXEvents()
-{
- XEvent event;
-
- while (XPending(display)) {
- XNextEvent(display, &event);
-
- if (event.type != PropertyNotify)
- 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
-/* 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.
- */
-
-#ifndef MFXCALIB_H
-#define MFXCALIB_H
-
-// The next two files must be included before the X include files
-#include <QDataStream>
-#include <QTextStream>
-#include <QObject>
-#include <X11/Xlib.h>
-
-class MfXCalib : public QObject {
- Q_OBJECT
-public:
- MfXCalib();
- ~MfXCalib();
-
- bool init();
- void processXEvents();
-private:
- bool getCalibrationValues();
-public:
- 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:
-
- Display* display;
- bool tsAxisCalib;
- qint32 tsMinX;
- qint32 tsMinY;
- qint32 tsMaxX;
- qint32 tsMaxY;
- // 0 = false, 1 = true, -1 = not available
- int tsAxisX;
- // 0 = false, 1 = true, -1 = not available
- int tsAxisY;
- // 0 = false, 1 = true, -1 = not available
- int tsAxesSwap;
-
-signals:
- void calibrationChanged();
-};
-
-#endif
--- src/mfsource/mfxlistener.cpp
+++ src/mfsource/mfxlistener.cpp
@@ -19,13 +19,13 @@
#include <stdio.h>
#include <sys/socket.h>
-
-#include <X11/Xlib.h>
+#include <sys/types.h>
+#include <signal.h>
#include <QDebug>
-MfXListener::MfXListener(QObject *parent)
- : QThread(parent)
+MfXListener::MfXListener(MfReactionMapStack *reactionMapStack, QObject *parent)
+ : QThread(parent), reactionMapStack(reactionMapStack)
{
qRegisterMetaType< QList<quint32> >("QList<quint32>");
}
@@ -88,13 +88,15 @@
void MfXListener::run()
{
bool ok = true;
+ bool terminate = false;
int x11Fd;
int nfds;
fd_set readFdSet;
int ret = 0;
// MfXListenerPriv object belongs to the listener thread
- d = new MfXListenerPriv();
+ d = new MfXListenerPriv(reactionMapStack);
+
ok = QObject::connect(d, SIGNAL(windowStackChanged(QList<quint32>)),
this, SIGNAL(windowStackChanged(QList<quint32>)));
if (!ok) {
@@ -102,10 +104,12 @@
}
if (!d->init()) {
+ // Cannot work without connection to X server
+ kill(getpid(), SIGTERM);
return;
}
- x11Fd = ConnectionNumber(d->display);
+ x11Fd = xcb_get_file_descriptor(d->getConnection());
if (x11Fd > stopListeningSocketFdPair[1]) {
nfds = x11Fd + 1;
@@ -119,24 +123,29 @@
FD_SET(x11Fd, &readFdSet);
FD_SET(stopListeningSocketFdPair[1], &readFdSet);
- // Flush it before waiting for incoming stuff otherwise we might get stuck since
- // X socket buffer might be already full and, therefore, will never receive anything
- // new again.
- XFlush(d->display);
+ xcb_flush(d->getConnection());
ret = select(nfds, &readFdSet, NULL/*writefds*/, NULL/*exceptfds*/, NULL);
if (ret == -1) {
qCritical() << __PRETTY_FUNCTION__ << "Error in select()";
ok = false;
+ terminate = true;
} else if (FD_ISSET(stopListeningSocketFdPair[1], &readFdSet)) {
- qDebug() << __PRETTY_FUNCTION__ << "Stopping nicely...";
- // It's time to exit
- ok = false;
+ qDebug() << __PRETTY_FUNCTION__ << "Stopping nicely...";
+ // It's time to exit
+ ok = false;
} else if (FD_ISSET(x11Fd, &readFdSet)) {
- d->processXEvents();
+ ok = d->processXEvents();
+ terminate = true;
}
}
delete d;
d = 0;
+
+ if (terminate) {
+ // Terminate program if stopping the thread was not
+ // intentional.
+ kill(getpid(), SIGTERM);
+ }
}
--- src/mfsource/mfxlistener.h
+++ src/mfsource/mfxlistener.h
@@ -19,12 +19,13 @@
#include <QPointer>
#include <QThread>
-// The next three files must be included before the X include files
+
#include <QDataStream>
#include <QTextStream>
#include <QMetaType>
class MfXListenerPriv;
+class MfReactionMapStack;
/*!
* Listens for X events in a separate thread, emitting signals when
@@ -36,7 +37,7 @@
class MfXListener : public QThread {
Q_OBJECT
public:
- MfXListener(QObject *parent = 0);
+ MfXListener(MfReactionMapStack *reactionMapStack, QObject *parent = 0);
virtual ~MfXListener();
// Start listening for X events.
@@ -64,6 +65,8 @@
// 0 - Used on main thread side
// 1 - Used on listener thread side
int stopListeningSocketFdPair[2];
+
+ MfReactionMapStack *reactionMapStack;
};
#endif
--- src/mfsource/mfxlistener_p.cpp
+++ src/mfsource/mfxlistener_p.cpp
@@ -15,163 +15,237 @@
*/
#include "mfxlistener_p.h"
-
-#include <X11/Xatom.h>
+#include "mfreactionmapstack.h"
#include <QDebug>
-MfXListenerPriv::MfXListenerPriv()
- : display(NULL),
- netClientListStackingAtom(None),
- stackedWindows(NULL),
- stackedWindowsSize(0)
+namespace {
+ static xcb_connection_t* connection = NULL;
+}
+
+MfXListenerPriv::MfXListenerPriv(MfReactionMapStack *reactionMapStack)
+ : rootWindow(0), netClientListStackingAtom(0), netWindowTypeAtom(0),
+ netWindowTypeNotificationAtom(0), reactionMapStack(reactionMapStack)
{
}
MfXListenerPriv::~MfXListenerPriv()
{
- if (stackedWindows != NULL) {
- XFree(stackedWindows);
- stackedWindows = NULL;
- stackedWindowsSize = 0;
+ if (connection) {
+ xcb_disconnect(connection);
+ connection = NULL;
}
+}
- if (display) {
- XCloseDisplay(display);
- display = NULL;
- }
+xcb_connection_t* MfXListenerPriv::getConnection()
+{
+ return connection;
}
-bool MfXListenerPriv::checkNetClientListStackingProperty()
+bool MfXListenerPriv::isWindowIgnored(quint32 windowId)
{
- Atom actual_type;
- int actual_format;
- unsigned long nitems;
- unsigned long bytesAfterReturn;
- Window *stackedWindowsReturned = NULL;
- int status;
- bool stackedWindowsChanged = false;
-
- status = XGetWindowProperty(
- display,
- rootWindow,
- netClientListStackingAtom,
- 0, // long_offset
- (~0L), // long_length
- False, // delete
- XA_WINDOW, // required type
- &actual_type,
- &actual_format,
- &nitems,
- &bytesAfterReturn,
- (unsigned char**)&stackedWindowsReturned);
-
- if (status != Success) {
- qCritical() << "MfXListener: Failed to get property from root window. Status"
- << status;
- goto ERROR;
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *propertyReply = NULL;
+ xcb_atom_t *windowTypeData = NULL;
+ int nitems = 0;
+ bool retVal = false;
+
+ cookie = xcb_get_property(connection, 0, windowId, netWindowTypeAtom, XCB_ATOM_ATOM, 0, (uint32_t)-1);
+ propertyReply = xcb_get_property_reply(connection, cookie, NULL);
+
+ if (propertyReply) {
+ if (propertyReply->response_type == XCB_NONE) {
+ // Window must be ignored since it no longer exists
+ nitems = 0;
+ retVal = true;
+ } else if (propertyReply->type != XCB_ATOM_ATOM ||
+ propertyReply->bytes_after > 0) {
+ qCritical("MfXListener: Error reading reply for _NET_WM_WINDOW_TYPE "
+ "property request for window ID 0x%08x", windowId);
+ nitems = 0;
+ } else {
+ windowTypeData = (xcb_atom_t*)xcb_get_property_value(propertyReply);
+ nitems = xcb_get_property_value_length(propertyReply) / 4;
+ }
+ } else {
+ qWarning("MfXListener: Could not get _NET_WM_WINDOW_TYPE property for "
+ "window ID 0x%08x", windowId);
}
- if (actual_type == None) {
- qWarning("MfXListener: Root window does not have"
- " _NET_CLIENT_LIST_STACKING property");
- goto ERROR;
+ // Ignore window if it is of type _NET_WM_WINDOW_TYPE_NOTIFICATION
+ for (int i = 0; i < nitems; ++i) {
+ if (windowTypeData[i] == netWindowTypeNotificationAtom) {
+ retVal = true;
+ break;
+ }
}
- if (bytesAfterReturn != 0) {
- // Maybe not be so lazy and just read those missing bytes.
- fprintf(stderr, "Unexpected behaviour: %lu bytes still unread after return.\n",
- bytesAfterReturn);
- goto ERROR;
+ if (propertyReply) {
+ free(propertyReply);
+ propertyReply = NULL;
}
- if (nitems == stackedWindowsSize) {
- if (nitems > 0 &&
- memcmp(stackedWindowsReturned, stackedWindows, sizeof(Window)*nitems) != 0) {
+ return retVal;
+}
+
+xcb_screen_t* MfXListenerPriv::screenOfDisplay(xcb_connection_t *conn, int screen)
+{
+ xcb_screen_iterator_t iter;
- stackedWindowsChanged = true;
+ iter = xcb_setup_roots_iterator(xcb_get_setup (conn));
+ for (; iter.rem; --screen, xcb_screen_next(&iter)) {
+ if (screen == 0) {
+ return iter.data;
}
+ }
+
+ return NULL;
+}
+
+bool MfXListenerPriv::checkNetClientListStackingProperty()
+{
+ quint32 *stackedWindowsReturned = NULL;
+ int windowCount = 0;
+ QList<quint32> stackedWindowsNew;
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *propertyReply = NULL;
+
+ cookie = xcb_get_property(connection, 0, rootWindow, netClientListStackingAtom, XCB_ATOM_WINDOW, 0, (uint32_t)-1);
+ propertyReply = xcb_get_property_reply(connection, cookie, NULL);
+
+ if (propertyReply) {
+ if (propertyReply->response_type == XCB_NONE) {
+ qCritical("MfXListener: Root window does not have"
+ " _NET_CLIENT_LIST_STACKING property");
+ goto ERROR;
+ } else if (propertyReply->type != XCB_ATOM_WINDOW) {
+ qCritical("MfXListener: _NET_CLIENT_LIST_STACKING property type"
+ "is not XCB_ATOM_WINDOW");
+ goto ERROR;
+ } else if (propertyReply->bytes_after > 0) {
+ qCritical() << "MfXListener: Unexpected behaviour:" << propertyReply->bytes_after
+ << "bytes still unread after return.\n";
+ goto ERROR;
+ }
+
+ stackedWindowsReturned = (quint32*)xcb_get_property_value(propertyReply);
+ windowCount = xcb_get_property_value_length(propertyReply) / 4;
} else {
- stackedWindowsChanged = true;
+ qCritical("MfXListener: Could not get _NET_CLIENT_LIST_STACKING property");
+ goto ERROR;
}
- // Free our current stackedWindows
- if (stackedWindows) {
- XFree(stackedWindows);
- stackedWindows = NULL;
- stackedWindowsSize = 0;
+ for (unsigned int i = windowCount; i > 0; --i) {
+ // Skip windows with certain type
+ if (isWindowIgnored(stackedWindowsReturned[i-1]) == false) {
+ // Add window to the beginning of stack
+ stackedWindowsNew.prepend(stackedWindowsReturned[i-1]);
+
+ // Stop adding windows when first window without reaction map
+ // is encountered. The list ends with first window without
+ // associated reaction map.
+ if (reactionMapStack->hasWindowReactionMap(stackedWindowsReturned[i-1]) == false) {
+ break;
+ }
+ }
}
- // Update it
- stackedWindows = stackedWindowsReturned;
- stackedWindowsSize = nitems;
+ // Notify about changed stacking order
+ if (stackedWindowsNew != stackedWindows) {
+ stackedWindows = stackedWindowsNew;
+ emit windowStackChanged(stackedWindows);
+ }
- if (stackedWindowsChanged) {
- QList<quint32> windowList;
- for (unsigned long i = 0; i < stackedWindowsSize; i++) {
- windowList.append(stackedWindows[i]);
- }
- emit windowStackChanged(windowList);
+ // Free returned data
+ if (propertyReply) {
+ free(propertyReply);
+ propertyReply = NULL;
}
return true;
+
ERROR:
- if (stackedWindowsReturned) {
- XFree(stackedWindowsReturned);
+ if (propertyReply) {
+ free(propertyReply);
+ propertyReply = NULL;
}
return false;
}
bool MfXListenerPriv::init()
{
- int status;
- QByteArray displayString;
-
- // Try to get the DISPLAY environment variable. If it is not
- // defined, default to :0 and try to open that.
- displayString = qgetenv("DISPLAY");
- if (displayString.isEmpty() == true) {
- displayString = ":0";
- }
+ const static uint32_t valueList[] = { XCB_EVENT_MASK_PROPERTY_CHANGE };
+ const char *atomNames[3] = { "_NET_CLIENT_LIST_STACKING", "_NET_WM_WINDOW_TYPE", "_NET_WM_WINDOW_TYPE_NOTIFICATION" };
+ xcb_atom_t atoms[3];
+ xcb_intern_atom_cookie_t cookies[3];
+ int screen_num = 0;
+ xcb_screen_t *screen;
+ xcb_generic_error_t *error;
+ xcb_void_cookie_t reply;
- display = XOpenDisplay(displayString.constData());
+ connection = xcb_connect(NULL, &screen_num);
- if (!display) {
- qWarning("Cannot connect to X server");
+ if (xcb_connection_has_error(connection)) {
+ qWarning("MfXListener: Cannot connect to X server");
return false;
}
- rootWindow = DefaultRootWindow(display);
-
- netClientListStackingAtom = XInternAtom(display, "_NET_CLIENT_LIST_STACKING", False);
- if (netClientListStackingAtom == None) {
- qCritical("Failed to intern atom _NET_CLIENT_LIST_STACKING.");
+ screen = screenOfDisplay(connection, screen_num);
+ if (screen) {
+ rootWindow = screen->root;
+ } else {
+ qWarning("MfXListener: Cannot find default screen");
+ xcb_disconnect(connection);
return false;
}
- status = XSelectInput(display, rootWindow, PropertyChangeMask);
- if (status == BadWindow) {
+ for (int i = 0; i < 3; ++i) {
+ cookies[i] = xcb_intern_atom(connection, 0, strlen(atomNames[i]), atomNames[i]);
+ }
+ for (int i = 0; i < 3; ++i) {
+ xcb_intern_atom_reply_t *atomReply = NULL;
+ atomReply = xcb_intern_atom_reply(connection, cookies[i], NULL);
+ if (atomReply) {
+ atoms[i] = atomReply->atom;
+ free (atomReply);
+ } else {
+ qCritical("MfXListener: Failed to intern atoms.");
+ xcb_disconnect(connection);
+ return false;
+ }
+ }
+
+ netClientListStackingAtom = atoms[0];
+ netWindowTypeAtom = atoms[1];
+ netWindowTypeNotificationAtom = atoms[2];
+
+ reply = xcb_change_window_attributes_checked(connection, rootWindow, XCB_CW_EVENT_MASK, valueList);
+ error = xcb_request_check(connection, reply);
+ if (error) {
+ qCritical("MfXListener: Failed to change root window attributes.");
+ xcb_disconnect(connection);
return false;
}
// Get the initial value and emit change signal for the first time.
checkNetClientListStackingProperty();
- return true;
+ return !xcb_connection_has_error(connection);
}
-void MfXListenerPriv::processXEvents()
+bool MfXListenerPriv::processXEvents()
{
- XEvent event;
-
- while (XPending(display)) {
- XNextEvent(display, &event);
+ xcb_generic_event_t *event = NULL;
- if (event.type != PropertyNotify)
- continue;
-
- if (event.xproperty.atom == netClientListStackingAtom) {
- checkNetClientListStackingProperty();
+ while ((event = xcb_poll_for_event(connection)) != NULL) {
+ if (event->response_type == XCB_PROPERTY_NOTIFY) {
+ xcb_property_notify_event_t *prop = (xcb_property_notify_event_t*)event;
+ if (prop->atom == netClientListStackingAtom) {
+ checkNetClientListStackingProperty();
+ }
}
+ free(event);
}
+
+ return !xcb_connection_has_error(connection);
}
--- src/mfsource/mfxlistener_p.h
+++ src/mfsource/mfxlistener_p.h
@@ -18,29 +18,36 @@
#define MFXLISTENER_P_H
#include <QObject>
-// The next three files must be included before the X include files
#include <QDataStream>
#include <QTextStream>
#include <QMetaType>
+#include <QList>
-#include <X11/Xlib.h>
+#include <xcb/xcb.h>
+#include <xcb/xproto.h>
+
+class MfReactionMapStack;
class MfXListenerPriv : public QObject {
Q_OBJECT
public:
- MfXListenerPriv();
+ MfXListenerPriv(MfReactionMapStack *reactionMapStack);
~MfXListenerPriv();
bool init();
- void processXEvents();
+ bool processXEvents();
bool checkNetClientListStackingProperty();
+ bool isWindowIgnored(quint32 windowId);
+ xcb_connection_t* getConnection();
+ xcb_screen_t* screenOfDisplay(xcb_connection_t *conn, int screen);
+
+ xcb_window_t rootWindow;
+ xcb_atom_t netClientListStackingAtom;
+ xcb_atom_t netWindowTypeAtom;
+ xcb_atom_t netWindowTypeNotificationAtom;
- Display* display;
- Window rootWindow;
- Atom netClientListStackingAtom;
-
- Window *stackedWindows;
- unsigned long stackedWindowsSize;
+ QList<quint32> stackedWindows;
+ MfReactionMapStack *reactionMapStack;
signals:
void windowStackChanged(QList<quint32> newWindowStack);
--- tests/common_top.pri
+++ tests/common_top.pri
@@ -4,6 +4,7 @@
#DEPENDPATH = $$INCLUDEPATH
CONFIG += debug
QT += testlib
+QMAKE_LFLAGS += "-Wl,--as-needed"
TEMPLATE = app
# DEFINES += QT_NO_DEBUG_OUTPUT
target.path = /usr/lib/tests/meegofeedback-reactionmaps-tests
--- tests/ft_clientqtapp/ft_clientqtapp.pro
+++ tests/ft_clientqtapp/ft_clientqtapp.pro
@@ -2,6 +2,8 @@
TARGET =
DEPENDPATH += .
+QMAKE_LFLAGS += "-Wl,--as-needed"
+
#INCLUDEPATH += /usr/include/meegofeedback-reactionmaps
#LIBS += -lmeegofeedback-reactionmaps
--- tests/ft_clientqtapp/main.cpp
+++ tests/ft_clientqtapp/main.cpp
@@ -25,15 +25,10 @@
int main (int argc, char **argv)
{
- if (argc != 2) {
- qDebug() << "Missing application name parameter";
- return 1;
- }
-
QApplication app(argc, argv);
- QPushButton mainWindow(argv[1]);
+ QPushButton mainWindow("Test button");
mainWindow.setWindowFlags(Qt::FramelessWindowHint);
- MReactionMap reactionMap(&mainWindow, argv[1]);
+ MReactionMap reactionMap(&mainWindow);
paintReaction(&mainWindow);
--- tests/ft_mfxlistener/ft_mfxlistener.pro
+++ tests/ft_mfxlistener/ft_mfxlistener.pro
@@ -1,20 +1,36 @@
TARGET = ft_mfxlistener
-INCLUDEPATH += ../../src/mfsource
-CONFIG += x11
+INCLUDEPATH += ../../src/mfsource ../../src/common
+CONFIG += link_pkgconfig
+PKGCONFIG += xcb
QMAKE_CXXFLAGS += -fno-strict-aliasing
+QMAKE_LFLAGS += "-Wl,--as-needed"
SOURCES += \
main.cpp \
logger.cpp \
+ mfutil_mock.cpp \
../../src/mfsource/mfxlistener.cpp \
../../src/mfsource/mfxlistener_p.cpp \
+ ../../src/mfsource/mfreactionmapstack.cpp \
+ ../../src/mfsource/mfreactionmap.cpp \
+ ../../src/common/mfsettings.cpp
HEADERS += \
logger.h \
+ mfutil.h \
+ mfutil_mock.h \
+ mffeedback.h \
+ mffeedback_mock.h \
+ mfsession.h \
+ mfsession_mock.h \
../../src/mfsource/mfxlistener.h \
../../src/mfsource/mfxlistener_p.h \
+ ../../src/mfsource/mfreactionmapstack.h \
+ ../../src/mfsource/mfreactionmap.h \
+ ../../src/common/mfcommondata.h \
+ ../../src/common/mfsettings.h
target.path = $$[QT_INSTALL_LIBS]/libmeegoreactionmap-tests
INSTALLS += target
--- tests/ft_mfxlistener/main.cpp
+++ tests/ft_mfxlistener/main.cpp
@@ -28,7 +28,7 @@
{
QCoreApplication app(argc, argv);
Logger logger;
- MfXListener xListener;
+ MfXListener xListener(NULL);
bool ok;
bool nonstop = false;
--- tests/ft_mfxlistener/mffeedback.h
+++ tests/ft_mfxlistener/mffeedback.h
+/* 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.
+ */
+
+#ifndef MFFEEDBACK_H
+#define MFFEEDBACK_H
+
+#include "mffeedback_mock.h"
+
+#endif
--- tests/ft_mfxlistener/mffeedback_mock.h
+++ tests/ft_mfxlistener/mffeedback_mock.h
+/* 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.
+ */
+
+#ifndef MFFEEDBACK_MOCK_H
+#define MFFEEDBACK_MOCK_H
+
+#include <QObject>
+#include <QString>
+
+class MfFeedback : public QObject {
+ Q_OBJECT
+
+public:
+ MfFeedback(const QString &name) : QObject(0) { Q_UNUSED(name); }
+ virtual ~MfFeedback() {}
+
+ QString name() const {return QString();}
+
+ bool operator== (const MfFeedback &other) const { Q_UNUSED(other); return true;}
+
+ void emitPlay(qint64 timestamp) { Q_UNUSED(timestamp); }
+
+private slots:
+ void play(qint64 timestamp) { Q_UNUSED(timestamp); }
+
+};
+
+#endif
--- tests/ft_mfxlistener/mfsession.h
+++ tests/ft_mfxlistener/mfsession.h
+/* 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.
+ */
+
+#ifndef MFSESSION_H
+#define MFSESSION_H
+
+#include "mfsession_mock.h"
+
+#endif
--- tests/ft_mfxlistener/mfsession_mock.h
+++ tests/ft_mfxlistener/mfsession_mock.h
+/* 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.
+ */
+
+#ifndef MFSESSION_MOCK_H
+#define MFSESSION_MOCK_H
+
+#include <QObject>
+#include <QString>
+#include <QHash>
+
+class MfFeedback;
+
+class MfSession : public QObject
+{
+ Q_OBJECT
+public:
+ MfSession(const QString &applicationName, QObject *parent = 0)
+ : QObject(parent), _applicationName(applicationName) {}
+
+ virtual ~MfSession() {}
+
+ QHash<QString, MfFeedback*> feedbackHash;
+
+ const QString &applicationName() {return _applicationName;}
+private:
+ QString _applicationName;
+};
+
+#endif
--- tests/ft_mfxlistener/mfutil.h
+++ tests/ft_mfxlistener/mfutil.h
+/* 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.
+ */
+
+#ifndef MFUTIL_H
+#define MFUTIL_H
+
+#include "mfutil_mock.h"
+
+#endif
--- tests/ft_mfxlistener/mfutil_mock.cpp
+++ tests/ft_mfxlistener/mfutil_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 "mfutil_mock.h"
+
+QString mfTempDir()
+{
+ return QString();
+}
+
+qint64 getTimestamp()
+{
+ return 0;
+}
+
--- tests/ft_mfxlistener/mfutil_mock.h
+++ tests/ft_mfxlistener/mfutil_mock.h
+/* 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.
+ */
+
+#ifndef MFUTILMOCK_H
+#define MFUTILMOCK_H
+
+#include <QString>
+
+QString mfTempDir();
+
+qint64 getTimestamp();
+
+#endif
--- tests/ft_multiplemainwindowqtapp/ft_multiplemainwindowqtapp.pro
+++ tests/ft_multiplemainwindowqtapp/ft_multiplemainwindowqtapp.pro
@@ -2,6 +2,8 @@
TARGET =
DEPENDPATH += .
+QMAKE_LFLAGS += "-Wl,--as-needed"
+
INCLUDEPATH += ../../src/client
LIBS += ../../libmeegoreactionmap.so
--- tests/ft_multipleviewqtapp
+++ tests/ft_multipleviewqtapp
+(directory)
--- tests/ft_multipleviewqtapp/ft_multipleviewqtapp.pro
+++ tests/ft_multipleviewqtapp/ft_multipleviewqtapp.pro
+TEMPLATE = app
+TARGET =
+DEPENDPATH += .
+
+QMAKE_LFLAGS += "-Wl,--as-needed"
+
+INCLUDEPATH += ../../src/client
+LIBS += ../../libmeegoreactionmap.so
+
+# Input
+SOURCES += main.cpp testapplication.cpp
+HEADERS += testapplication.h
+
+QMAKE_EXTRA_TARGETS += check
+check.depends = $$TARGET
+check.commands = $$system(true)
+
+QMAKE_EXTRA_TARGETS += check-xml
+check-xml.depends = $$TARGET
+check-xml.commands = $$system(true)
--- tests/ft_multipleviewqtapp/main.cpp
+++ tests/ft_multipleviewqtapp/main.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 "testapplication.h"
+
+int main(int argc, char *argv[])
+{
+ TestApplication app(argc, argv);
+ return app.exec();
+}
--- tests/ft_multipleviewqtapp/testapplication.cpp
+++ tests/ft_multipleviewqtapp/testapplication.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 "testapplication.h"
+
+#include <QDebug>
+#include <QTimer>
+
+TestApplication::~TestApplication()
+{
+ delete mainWindow;
+ mainWindow = NULL;
+
+ delete reactionMap;
+ reactionMap = NULL;
+}
+
+void TestApplication::drawReactionMap()
+{
+ MReactionMap *mapmap = MReactionMap::instance(view1);
+
+ mapmap->clear();
+ mapmap->setReactiveDrawingValue();
+ mapmap->fillItemBoundRect(bigRect);
+ mapmap->fillItemBoundRect(smallRect);
+}
+
+TestApplication::TestApplication(int argc, char **argv)
+ : QApplication(argc, argv)
+{
+ Q_UNUSED(argc);
+ Q_UNUSED(argv);
+
+ mainWindow = new QWidget();
+ view1 = new QGraphicsView();
+ view2 = new QGraphicsView();
+ bigRect = new QGraphicsRectItem(0, 0, 100, 100);
+ smallRect = new QGraphicsRectItem(0, 0, 50, 50);
+ screenRect = new QGraphicsRectItem(0, 0, 1000, 1000);
+ layout = new QGridLayout();
+ scene = new QGraphicsScene();
+
+ reactionMap = new MReactionMap(mainWindow);
+
+ // Put bigger rectangle in place
+ bigRect->setPos(10, 50);
+ scene->addItem(bigRect);
+
+ // Put smaller rectangle in place
+ smallRect->setPos(900, 900);
+ scene->addItem(smallRect);
+ scene->addItem(screenRect);
+
+ view1->setScene(scene);
+ view1->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+
+ // Zoom in the other view a bit
+ view2->setScene(scene);
+ view2->setAlignment(Qt::AlignLeft | Qt::AlignTop);
+ view2->scale(1.5, 1.5);
+
+ // Add views to the layout
+ layout->addWidget(view1, 0, 0);
+ layout->addWidget(view2, 0, 1);
+
+ mainWindow->setLayout(layout);
+ mainWindow->show();
+
+ // Redraw reaction map on slider value changes
+ connect(view1->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(drawReactionMap()));
+ connect(view1->horizontalScrollBar(), SIGNAL(valueChanged(int)), SLOT(drawReactionMap()));
+ connect(view2->verticalScrollBar(), SIGNAL(valueChanged(int)), SLOT(drawReactionMap()));
+ connect(view2->horizontalScrollBar(), SIGNAL(valueChanged(int)), SLOT(drawReactionMap()));
+
+ // Move views to suitable places
+ view1->verticalScrollBar()->setSliderPosition(0);
+ view1->horizontalScrollBar()->setSliderPosition(0);
+ view2->verticalScrollBar()->setSliderPosition(0);
+ view2->horizontalScrollBar()->setSliderPosition(110);
+
+ // Draw initial reaction map after everything has appeared
+ QTimer::singleShot(100, this, SLOT(drawReactionMap()));
+}
+
--- tests/ft_multipleviewqtapp/testapplication.h
+++ tests/ft_multipleviewqtapp/testapplication.h
+/* 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.
+ */
+
+#ifndef TESTAPPLICATION_H
+#define TESTAPPLICATION_H
+
+#include <QApplication>
+#include <QGridLayout>
+#include <QGraphicsView>
+#include <QGraphicsScene>
+#include <QGraphicsRectItem>
+#include <QWidget>
+#include <QScrollBar>
+#include <QObject>
+#include <mreactionmap.h>
+#include <stdio.h>
+
+class TestApplication : public QApplication
+{
+ Q_OBJECT
+
+public:
+ TestApplication(int argc, char **argv);
+ virtual ~TestApplication();
+
+public slots:
+ void drawReactionMap();
+
+private:
+ QGraphicsView *view1, *view2;
+ QGraphicsScene *scene;
+ QGraphicsRectItem *bigRect;
+ QGraphicsRectItem *smallRect;
+ QGraphicsRectItem *screenRect;
+ QWidget *mainWindow;
+ QGridLayout *layout;
+ MReactionMap *reactionMap;
+};
+
+#endif
+
--- tests/ft_touchscreenmanaging
+++ tests/ft_touchscreenmanaging
+(directory)
--- tests/ft_touchscreenmanaging/ft_touchscreenmanaging.pro
+++ tests/ft_touchscreenmanaging/ft_touchscreenmanaging.pro
+include(../common_top.pri)
+
+TEMPLATE = app
+CONFIG += console meegofeedback link_pkgconfig
+QT += network
+PKGCONFIG += xcb
+TARGET = ft_touchscreenmanaging
+INCLUDEPATH += ../../src/mfsource ../../src/common
+SRCDIR = ../../src
+
+SOURCES += \
+ main.cpp \
+ mftouchscreenlistener_mock.cpp \
+ mfxlistener_mock.cpp \
+ mfserver_mock.cpp \
+ $$SRCDIR/mfsource/mfreactorsource.cpp \
+ $$SRCDIR/mfsource/mfreactionmap.cpp \
+ $$SRCDIR/mfsource/mfreactionmapstack.cpp \
+ $$SRCDIR/common/mfsettings.cpp
+
+HEADERS += \
+ mftouchscreenlistener_mock.h \
+ mfxlistener_mock.h \
+ mfserver_mock.h \
+ $$SRCDIR/mfsource/mftouchscreenlistener.h \
+ $$SRCDIR/mfsource/mfreactorsource.h \
+ $$SRCDIR/mfsource/mfreactionmap.h \
+ $$SRCDIR/mfsource/mfreactionmapstack.h \
+ $$SRCDIR/mfsource/mfserver.h \
+ $$SRCDIR/mfsource/mfxlistener.h \
+ $$SRCDIR/common/mfsettings.h
+
+target.path = $$[QT_INSTALL_LIBS]/libmeegoreactionmap-tests
+INSTALLS += target
+
+include(../common_bot.pri)
--- tests/ft_touchscreenmanaging/main.cpp
+++ tests/ft_touchscreenmanaging/main.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 <QCoreApplication>
+#include <QDebug>
+#include <mfreactorsource.h>
+
+#include "mftouchscreenlistener_mock.h"
+#include "mfxlistener_mock.h"
+#include "mfserver_mock.h"
+
+bool verifyStatuses(MfReactorSource *src, bool reactionMapActive,
+ bool touchScreenListenerActive,
+ int touchScreenListenerSetActiveCalled)
+{
+ bool retVal = true;
+
+ if (!src) {
+ qCritical() << "verifyStatuses: NULL MfReactorSource provided!";
+ return false;
+ }
+
+ if (src->isActive() != reactionMapActive) {
+ qCritical() << "verifyStatuses: MfReactorSource::isActive:" << src->isActive()
+ << "Expected:" << reactionMapActive;
+ retVal = false;
+ }
+
+ if (isTouchScreenListenerActive != touchScreenListenerActive) {
+ qCritical() << "verifyStatuses: isTouchScreenListenerActive:" << isTouchScreenListenerActive
+ << "Expected:" << touchScreenListenerActive;
+ retVal = false;
+ }
+
+ if (touchScreenListenerSetActiveCallCount != touchScreenListenerSetActiveCalled) {
+ qCritical() << "verifyStatuses: touchScreenListenerSetActiveCallCount:" << touchScreenListenerSetActiveCallCount
+ << "Expected:" << touchScreenListenerSetActiveCalled;
+ retVal = false;
+ }
+
+ return retVal;
+}
+
+int main(int argc, char **argv)
+{
+ QCoreApplication fooApp(argc, argv);
+ QList<quint32> windowList;
+ QMap<QString, QString> deviceState;
+
+ // Create a window list, top to bottom: 3, 2, 1, 0
+ windowList << 0; // Does not have a reaction map
+ windowList << 1; // Does have a reaction map
+ windowList << 2; // Does have a reaction map
+ windowList << 3; // Does not have a reaction map
+
+ MfReactorSource *src = new MfReactorSource();
+
+ src->init();
+
+ // Report initial window stacking to MfReactionMapStack
+ touchScreenListenerSetActiveCallCount = 0;
+ stackEmitter.emitWindowStackChanged(windowList);
+ fooApp.processEvents();
+
+ // After initalization MfReactorSource should be inactive,
+ // MfTouchScreenListener should be inactive and
+ // MfTouchScreenListener::setActive()
+ // should not have been called
+ if (!verifyStatuses(src, false, false, 0)) {
+ qFatal("Test FAILED.");
+ }
+
+ // Go through all possible states
+ // 1. Reaction map on top and display is off
+ touchScreenListenerSetActiveCallCount = 0;
+ // Rearrange windows so that reactive is on top
+ windowList.move(2, 3); // 2, 3, 1, 0
+ stackEmitter.emitWindowStackChanged(windowList);
+ fooApp.processEvents();
+ // Notify display is "off"
+ deviceState["display"] = "off";
+ src->deviceStateChanged(deviceState);
+ fooApp.processEvents();
+ if (!verifyStatuses(src, false, false, 2)) {
+ qFatal("Test FAILED.");
+ }
+
+ // 2. Reaction map on top and display is on
+ touchScreenListenerSetActiveCallCount = 0;
+ // Notify display is "on"
+ deviceState["display"] = "on";
+ src->deviceStateChanged(deviceState);
+ fooApp.processEvents();
+ if (!verifyStatuses(src, true, true, 1)) {
+ qFatal("Test FAILED.");
+ }
+
+ // 3. Reaction map not on top and display is off
+ touchScreenListenerSetActiveCallCount = 0;
+ // Notify display is "off"
+ deviceState["display"] = "off";
+ src->deviceStateChanged(deviceState);
+ // Rearrange windows so that reactive is not on top
+ windowList.move(2, 3); // 3, 2, 1, 0
+ stackEmitter.emitWindowStackChanged(windowList);
+ fooApp.processEvents();
+ if (!verifyStatuses(src, false, false, 1)) {
+ qFatal("Test FAILED.");
+ }
+
+ // 4. Reaction map not on top and display is on
+ touchScreenListenerSetActiveCallCount = 0;
+ // Notify display is "off"
+ deviceState["display"] = "on";
+ src->deviceStateChanged(deviceState);
+ fooApp.processEvents();
+ if (!verifyStatuses(src, false, false, 0)) {
+ qFatal("Test FAILED.");
+ }
+
+ delete src;
+
+ qCritical() << "Test SUCCESSFUL";
+
+ return 0;
+}
+
--- tests/ft_touchscreenmanaging/mfserver_mock.cpp
+++ tests/ft_touchscreenmanaging/mfserver_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 "mfserver_mock.h"
+#include <mfserver.h>
+#include <mfreactionmapstack.h>
+#include <mfreactionmap.h>
+
+#include <QDebug>
+
+MfServer::MfServer(MfReactionMapStack *stack, QObject *parent)
+ : QObject(parent), stack(stack)
+{
+}
+
+bool MfServer::init()
+{
+ MfReactionMap *map;
+
+ // Create two reaction maps with window id's 1 and 2 and
+ // add them to the reactionmap stack.
+ map = new MfReactionMap(NULL, 1, 1, this);
+ stack->add(map);
+
+ map = new MfReactionMap(NULL, 2, 2, this);
+ stack->add(map);
+
+ return true;
+}
+
+void MfServer::removePreExistingSharedMemory()
+{
+}
+
+void MfServer::onNewConnection()
+{
+}
--- tests/ft_touchscreenmanaging/mfserver_mock.h
+++ tests/ft_touchscreenmanaging/mfserver_mock.h
+/* 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.
+ */
+
+#ifndef MFSERVERMOCK_H
+#define MFSERVERMOCK_H
+
+#endif
--- tests/ft_touchscreenmanaging/mftouchscreenlistener_mock.cpp
+++ tests/ft_touchscreenmanaging/mftouchscreenlistener_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 "mftouchscreenlistener_mock.h"
+#include <mftouchscreenlistener.h>
+
+bool isTouchScreenListenerActive = true;
+int touchScreenListenerSetActiveCallCount = 0;
+
+MfTouchScreenListener::MfTouchScreenListener(MfReactionMapStack *reactionMapStack,
+ QObject *parent)
+ : QObject(parent)
+{
+ Q_UNUSED(reactionMapStack);
+}
+
+MfTouchScreenListener::~MfTouchScreenListener()
+{
+}
+
+bool MfTouchScreenListener::startListening()
+{
+ return true;
+}
+
+bool MfTouchScreenListener::stopListening()
+{
+ return true;
+}
+
+bool MfTouchScreenListener::isActive()
+{
+ return isTouchScreenListenerActive;
+}
+
+void MfTouchScreenListener::setActive(bool active)
+{
+ isTouchScreenListenerActive = active;
+ touchScreenListenerSetActiveCallCount++;
+}
--- tests/ft_touchscreenmanaging/mftouchscreenlistener_mock.h
+++ tests/ft_touchscreenmanaging/mftouchscreenlistener_mock.h
+/* This file is part of meegofeedbackd
+ *
+ * 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.
+ */
+
+#ifndef MFTOUCHSCREENLISTENERMOCK_H
+#define MFTOUCHSCREENLISTENERMOCK_H
+
+extern bool isTouchScreenListenerActive;
+extern int touchScreenListenerSetActiveCallCount;
+
+#endif
--- tests/ft_touchscreenmanaging/mfxlistener_mock.cpp
+++ tests/ft_touchscreenmanaging/mfxlistener_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 "mfxlistener_mock.h"
+#include <mfxlistener.h>
+#include <QDebug>
+
+MfXListenerMock stackEmitter(NULL);
+
+void MfXListenerMock::emitWindowStackChanged(QList<quint32> newWindowStack)
+{
+ emit windowStackChanged(newWindowStack);
+}
+
+MfXListener::MfXListener(MfReactionMapStack *reactionMapStack, QObject *parent)
+ : QThread(parent)
+{
+ Q_UNUSED(reactionMapStack);
+}
+
+MfXListener::~MfXListener()
+{
+ stopListening();
+}
+
+bool MfXListener::startListening()
+{
+ bool ok;
+ ok = connect(&stackEmitter, SIGNAL(windowStackChanged(QList<quint32>)),
+ SIGNAL(windowStackChanged(QList<quint32>)));
+ if (!ok) {
+ qCritical("Failed to connect MfXListener signal");
+ }
+
+ start(QThread::NormalPriority);
+
+ return true;
+}
+
+bool MfXListener::stopListening()
+{
+ if (!isRunning()) {
+ // Nothing to be done
+ return true;
+ }
+
+ exit();
+
+ if (!wait(500)) {
+ // Ok, let's use brute force
+ qCritical() << "Terminating by force";
+ terminate();
+ wait();
+ }
+
+ return true;
+}
+
+void MfXListener::run()
+{
+ exec();
+}
--- tests/ft_touchscreenmanaging/mfxlistener_mock.h
+++ tests/ft_touchscreenmanaging/mfxlistener_mock.h
+/* This file is part of meegofeedbackd
+ *
+ * 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.
+ */
+
+#ifndef MFXLISTENERMOCK_H
+#define MFXLISTENERMOCK_H
+
+#include <QObject>
+#include <QList>
+
+class MfReactionMapStack;
+
+class MfXListenerMock : public QObject
+{
+ Q_OBJECT
+
+public:
+ MfXListenerMock(MfReactionMapStack *reactionMapStack, QObject *parent = 0) : QObject(parent) { Q_UNUSED(reactionMapStack); };
+ virtual ~MfXListenerMock() {};
+
+signals:
+ void windowStackChanged(QList<quint32> newWindowStack);
+
+public slots:
+ void emitWindowStackChanged(QList<quint32> newWindowStack);
+};
+
+extern MfXListenerMock stackEmitter;
+
+#endif
--- tests/tests.pro
+++ tests/tests.pro
@@ -10,7 +10,9 @@
ut_mreactionmap \
ft_clientqtapp \
ft_mfxlistener \
- ft_multiplemainwindowqtapp
+ ft_multiplemainwindowqtapp \
+ ft_touchscreenmanaging \
+ ft_multipleviewqtapp
QMAKE_STRIP = echo
include(shell.pri)
--- tests/tests.xml
+++ tests/tests.xml
@@ -31,6 +31,9 @@
<case name="ft_mfxlistener" description="ft_mfxlistener" requirement="" timeout="60">
<step expected_result="0">/usr/lib/libmeegoreactionmap-tests/ft_mfxlistener</step>
</case>
+ <case name="ft_touchscreenmanaging" description="ft_touchscreenmanaging" requirement="" timeout="60">
+ <step expected_result="0">/usr/lib/libmeegoreactionmap-tests/ft_touchscreenmanaging</step>
+ </case>
<environments>
<scratchbox>false</scratchbox>
--- tests/ut_mfreactionmapstack/mfxcalib.h
+++ tests/ut_mfreactionmapstack/mfxcalib.h
-/* 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.
- */
-
-#ifndef MFXCALIB_H
-#define MFXCALIB_H
-
-#include "mfxcalib_mock.h"
-
-#endif
--- 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
-/* 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.
- */
-
-#ifndef MFXCALIB_MOCK_H
-#define MFXCALIB_MOCK_H
-
-#include <QObject>
-
-class MfXCalib : public QObject
-{
- Q_OBJECT
-public:
- MfXCalib() {}
-
- virtual ~MfXCalib() {}
-
- bool init();
- bool getCalibrationValues();
- bool axisCalibration() const;
-};
-
-#endif
--- tests/ut_mfreactionmapstack/ut_mfreactionmapstack.cpp
+++ tests/ut_mfreactionmapstack/ut_mfreactionmapstack.cpp
@@ -21,7 +21,6 @@
#include "mfreactionmapstack.h"
#include "mfsession_mock.h"
-#include "mfxcalib_mock.h"
QTEST_MAIN(Ut_MfReactionMapStack)
@@ -59,11 +58,6 @@
delete vkbReactionMap;
vkbReactionMap = 0;
-
- // Dummy variable to avoid linking error, why does it need? D'oh
- MfXCalib calib;
- calib.init();
- calib.getCalibrationValues();
}
/*
--- tests/ut_mfreactionmapstack/ut_mfreactionmapstack.pro
+++ tests/ut_mfreactionmapstack/ut_mfreactionmapstack.pro
@@ -7,7 +7,6 @@
../../src/mfsource/mfreactionmap.cpp \
../../src/common/mfsettings.cpp \
mfutil_mock.cpp \
- mfxcalib_mock.cpp \
$$TEST_SOURCES
HEADERS += ut_mfreactionmapstack.h \
mfutil.h \
@@ -16,8 +15,6 @@
mfsession_mock.h \
mffeedback.h \
mffeedback_mock.h \
- mfxcalib.h \
- mfxcalib_mock.h \
ut_mfreactionmapstack.h \
../../src/mfsource/mfreactionmapstack.h \
../../src/mfsource/mfreactionmap.h \
--- tests/ut_mreactionmap/mreactionmapconnection_mock.cpp
+++ tests/ut_mreactionmap/mreactionmapconnection_mock.cpp
@@ -93,7 +93,7 @@
}
sharedMemoryAddress = shmat(sharedMemoryId, 0, 0);
- if ((int)sharedMemoryAddress == -1) {
+ if ((qptrdiff)sharedMemoryAddress == -1) {
qCritical() << "MReactionMapConnection: Unable to get shared memory address for"
<< shmPath;
return false;
--- tests/ut_mreactionmap/ut_mreactionmap.cpp
+++ tests/ut_mreactionmap/ut_mreactionmap.cpp
@@ -475,7 +475,7 @@
oldWindowId = testConnection->reactionMaps[reactionMap1->getPrivatePtr()].topLevelWidgetWinId;
// Make sure window ID's match
- QCOMPARE(oldWindowId, static_cast<quint32>(widget1->winId()));
+ QCOMPARE(oldWindowId, static_cast<quint32>(widget1->effectiveWinId()));
// Set FramelessWindowHint, this will change the window ID of this widget
widget1->setWindowFlags(Qt::FramelessWindowHint);
@@ -487,7 +487,7 @@
newWindowId = testConnection->reactionMaps[reactionMap1->getPrivatePtr()].topLevelWidgetWinId;
// Make sure window ID's match
- QCOMPARE(newWindowId, static_cast<quint32>(widget1->winId()));
+ QCOMPARE(newWindowId, static_cast<quint32>(widget1->effectiveWinId()));
// Make sure window ID really changed
QVERIFY(oldWindowId != newWindowId);
--- tools/meegoreactionmap-viewer/meegoreactionmap-viewer.pro
+++ tools/meegoreactionmap-viewer/meegoreactionmap-viewer.pro
@@ -2,6 +2,8 @@
INCLUDEPATH += ../../src/common \
../../src/client
+QMAKE_LFLAGS += "-Wl,--as-needed"
+
# Use pkg-config or something instead of hardcoded paths
INCLUDEPATH += /usr/include/meegofeedback
LIBS += -lmeegofeedback
--- tools/meegoreactionmap-viewer/mreactionmapviewer.cpp
+++ tools/meegoreactionmap-viewer/mreactionmapviewer.cpp
@@ -211,7 +211,7 @@
sharedMemoryAddress = shmat(id, 0, 0);
- if ((int)sharedMemoryAddress == -1) {
+ if ((qptrdiff)sharedMemoryAddress == -1) {
qCritical() << "Unable to get shared memory address for"
<< tempFilePath;
sharedMemoryAddress = 0;
++++++ meegotouch-feedbackreactionmaps.yaml
--- meegotouch-feedbackreactionmaps.yaml
+++ meegotouch-feedbackreactionmaps.yaml
@@ -1,18 +1,16 @@
Name: meegotouch-feedbackreactionmaps
Summary: MeeGo Touch Feedback ReactionMaps Plugin
-Version: 0.14.0.5
+Version: 0.14.1.6
Release: 1
Group: System/Libraries
License: LGPLv2.1
URL: http://meego.gitorious.org/meegotouch/meegotouch-feedbackreactionmaps
Sources:
- "%{name}-%{version}.tar.bz2"
-Patches:
- - disable_tests_build.patch
Description: |
This package contains the MeeGo Touch Feedback Reactionmaps plugin.
PkgConfigBR:
- - QtGui
+ - QtGui >= 4.7
- meegotouch-feedback
- meegotouch
- xdamage
@@ -21,6 +19,8 @@
- xi
- xtst
- xorg-evdev
+ - xcb
+ - zlib
Provides:
- meegotouchfeedbackreactionmaps > 0.14.0
- duifeedback-reactionmaps > 0.14.0
++++++ deleted files:
--- disable_tests_build.patch
More information about the MeeGo-commits
mailing list