summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Fernengel <harald.fernengel@nokia.com>2010-02-24 11:42:07 +0100
committerHarald Fernengel <harald.fernengel@nokia.com>2010-02-24 11:42:07 +0100
commita3a2e7e57e29c35127be7776548a8a0f07a0efee (patch)
treef4b95da0b17d88b75246080d2920bd6c9e60c7f6
Initial version of Qt for Maemo 5 homescreen widget loader + example
-rw-r--r--README42
-rw-r--r--debian/changelog12
-rw-r--r--debian/compat1
-rw-r--r--debian/control38
-rw-r--r--debian/qt4-maemo5-homescreen-example.install3
-rw-r--r--debian/qt4-maemo5-homescreen-loader.install1
-rwxr-xr-xdebian/rules43
-rw-r--r--qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.cpp287
-rw-r--r--qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h90
-rw-r--r--qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri4
-rw-r--r--qt-homescreen-example/main.cpp59
-rw-r--r--qt-homescreen-example/qt-homescreen-example.desktop9
-rw-r--r--qt-homescreen-example/qt-homescreen-example.pro12
-rw-r--r--qt-homescreen-example/testwidget.h90
-rw-r--r--qt4-maemo5-homescreen.pro2
-rw-r--r--qtpluginloader/hd-plugin-loader-qt.c394
-rw-r--r--qtpluginloader/hd-plugin-loader-qt.h104
-rw-r--r--qtpluginloader/qtpluginloader.pro13
18 files changed, 1204 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..e4502dc
--- /dev/null
+++ b/README
@@ -0,0 +1,42 @@
+This example shows how to create desktop widgets with Qt for Maemo 5.
+
+Desktop widgets require a two step approach. First, a special loader is
+required in order to load Qt based home screen widgets. This loader only
+has to be installed once, and usually, the Debian packaging system should
+be used to make sure it is installed.
+
+In your home screen widget's Debian package, make sure you depend on the
+package qt4-maemo5-homescreen-loader. An example "Depends" line could look like:
+
+Depends: libqt4-maemo5-core (>= 4.6.1), libqt4-maemo5-gui (>= 4.6.1), qt4-maemo5-homescreen-loader
+
+The source code for the special Qt home screen loader can be found in the
+qtpluginloader directory of this package.
+
+
+In order to flag a toplevel widget as home screen widgets, some special
+X11 attributes must be set. The QMaemo5HomescreenAdaptor class handles all
+the special behavior, and also enables home screen applets to have their
+own settings dialog.
+
+In order to use the QMaemo5HomscreenAdaptor class, add the qmaemo5homescreenadaptor.cpp and
+qmaemo5homescreenadaptor.h files to your project. For qmake based projects, you can also
+include the qmaemo5homescreenadaptor.pri file from your project path, e.g. with
+
+include (/path/to/adaptor/qmaemo5homescreenadaptor.pri)
+
+Please refer to qmaemo5homescreenadaptor.cpp for documentation on how to use the class.
+
+The directory qt-homescreen-example contains a small example on how to make a
+semi-transparent home screen widget that contains a settings dialog. Note that both
+the resulting Qt binary and the corresponding desktop file need to be installed,
+as outlined in the Maemo 5 Developer Guide:
+
+ http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Application_Development/Writing_Desktop_Widgets
+
+Note that the following line must be present in the desktop file in order for
+the special Qt plugin loader to recognize the home screen widget:
+
+Type=qt
+
+Please refer to qt-homescreen-example for an example desktop file.
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000..ce70308
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,12 @@
+qt4-maemo5-homescreen (4.6.2~git20100224-4maemo1) unstable; urgency=low
+
+ * Fix dependencies
+
+ -- Qt Development Frameworks <qt-info@nokia.com> Wed, 24 Feb 2010 14:29:01 +0200
+
+qt4-maemo5-homescreen (4.6.2~git20100223-4maemo1) unstable; urgency=low
+
+ * Initial package
+
+ -- Qt Development Frameworks <qt-info@nokia.com> Tue, 23 Feb 2010 14:29:01 +0200
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000..b8626c4
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+4
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000..ffe525d
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,38 @@
+Source: qt4-maemo5-homescreen
+Section: libs
+Priority: optional
+Maintainer: Qt Development Frameworks <qt-info@nokia.com>
+Uploaders: Harald Fernengel <harald.fernengel@nokia.com>
+Build-Depends: libqt4-maemo5-dev, libhildon1-dev, libhildondesktop1-dev
+Standards-Version: 3.7.3
+
+Package: qt4-maemo5-homescreen-loader
+Architecture: any
+Section: devel
+Depends: libhildondesktop1
+Description: Qt 4 homescreen widget loader
+ Qt is a cross-platform C++ application framework. Qt's primary feature
+ is its rich set of widgets that provide standard GUI functionality.
+ .
+ This package provides a loader for loading Qt homescreen widgets
+
+Package: qt4-maemo5-homescreen-loader-dbg
+Priority: extra
+Architecture: any
+Section: devel
+Depends: qt4-maemo5-homescreen-loader
+Description: Qt 4 library debugging symbols
+ Qt is a cross-platform C++ application framework. Qt's primary feature
+ is its rich set of widgets that provide standard GUI functionality.
+ .
+ This packages contains the debugging symbols for the Qt 4 homescreen loader
+
+Package: qt4-maemo5-homescreen-example
+Architecture: any
+Section: devel
+Depends: libqt4-maemo5-core (>= 4.6.1), libqt4-maemo5-gui (>= 4.6.1), qt4-maemo5-homescreen-loader
+Description: Qt 4 Declarative development files
+ Qt is a cross-platform C++ application framework. Qt's primary feature
+ is its rich set of widgets that provide standard GUI functionality.
+ .
+ This package contains an example homescreen widget done with Qt 4
diff --git a/debian/qt4-maemo5-homescreen-example.install b/debian/qt4-maemo5-homescreen-example.install
new file mode 100644
index 0000000..ce57662
--- /dev/null
+++ b/debian/qt4-maemo5-homescreen-example.install
@@ -0,0 +1,3 @@
+/usr/lib/hildon-desktop/qt-homescreen-example
+/usr/share/applications/hildon-home/qt-homescreen-example.desktop
+
diff --git a/debian/qt4-maemo5-homescreen-loader.install b/debian/qt4-maemo5-homescreen-loader.install
new file mode 100644
index 0000000..2cfcfde
--- /dev/null
+++ b/debian/qt4-maemo5-homescreen-loader.install
@@ -0,0 +1 @@
+/usr/lib/hildon-desktop/loaders/libqtpluginloader.so
diff --git a/debian/rules b/debian/rules
new file mode 100755
index 0000000..9389de5
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,43 @@
+#!/usr/bin/make -f
+
+export DH_VERBOSE=1
+
+# Only present in official source package
+#QTVERSION := $(shell ls changes-* | cut -f2 -d '-')
+CURRENTVERSION := $(shell head -1 debian/changelog | sed 's/[^(]*(\([^)]*\)).*/\1/')
+
+include /usr/share/cdbs/1/rules/debhelper.mk
+include /usr/share/cdbs/1/class/makefile.mk
+include /usr/share/cdbs/1/rules/utils.mk
+
+# Find out how many parallel threads to run
+comma := ,
+TMP_BUILD_OPTS = $(subst $(comma), ,$(DEB_BUILD_OPTIONS))
+ifneq (,$(filter parallel=%,$(TMP_BUILD_OPTS)))
+ NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(TMP_BUILD_OPTS)))
+ PARALLEL_MAKEFLAGS += -j$(NUMJOBS)
+endif
+
+DEB_MAKE_INVOKE := $(MAKE) $(PARALLEL_MAKEFLAGS)
+DEB_MAKE_BUILD_TARGET := all
+DEB_MAKE_INSTALL_TARGET := INSTALL_ROOT=$(DEB_DESTDIR) install
+DEB_DH_INSTALL_SOURCEDIR := debian/tmp
+DEB_DH_ALWAYS_EXCLUDE := .git
+
+# Ensure the *.debug files aren't included in any package other than libqt4-maemo5-dbg
+DEB_DH_INSTALL_ARGS := --exclude=.debug
+
+DEB_MAKE_CLEAN_TARGET := distclean
+
+# Shlibs of the current upstream version
+DEB_DH_MAKESHLIBS_ARGS_ALL := -V
+
+DEB_DH_STRIP_ARGS := --dbg-package=qt4-maemo5-homescreen-loader
+DEB_DH_SHLIBDEPS_ARGS_ALL := --exclude=.debug
+
+# Only present in official source package
+#DEB_INSTALL_CHANGELOGS_ALL := changes-$(QTVERSION)
+
+common-configure-arch::
+ /opt/qt4-maemo5/bin/qmake CONFIG+=separate_debug_info CONFIG+=separate_debug_info_nocopy QMAKE_CXXFLAGS+="-g" QMAKE_CFLAGS+="-g"
+
diff --git a/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.cpp b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.cpp
new file mode 100644
index 0000000..b473fea
--- /dev/null
+++ b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used 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. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmaemo5homescreenadaptor.h"
+
+#include <QtCore/qsocketnotifier.h>
+
+#include <QtGui/qapplication.h>
+#include <QtGui/qx11info_x11.h>
+#include <QtGui/qwidget.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+static QCoreApplication::EventFilter oldEventFilter;
+static QList<QMaemo5HomescreenAdaptor *> allDesktopItems;
+
+static Atom atomByName(const char *name)
+{
+ Atom atom = XInternAtom(QX11Info::display(), name, False);
+ if (!atom)
+ qWarning("Unable to obtain %s atom. This class requires a running Hildon session.", name);
+
+ return atom;
+}
+
+enum HomescreenAtoms
+{
+ HildonAppletId = 0,
+ NetWmWindowType = 1,
+ Utf8String = 2,
+ HildonTypeHomeApplet = 3,
+ HildonAppletSettings = 4,
+ HildonAppletShowSettings = 5,
+ HildonAppletOnCurrentDesktop = 6,
+ EnumCount = 7
+};
+
+static Atom hsAtoms[EnumCount] = { 0, 0, 0, 0, 0, 0, 0 };
+
+static void initAtoms()
+{
+ hsAtoms[HildonAppletId] = atomByName("_HILDON_APPLET_ID");
+ hsAtoms[NetWmWindowType] = atomByName("_NET_WM_WINDOW_TYPE");
+ hsAtoms[Utf8String] = atomByName("UTF8_STRING");
+ hsAtoms[HildonTypeHomeApplet] = atomByName("_HILDON_WM_WINDOW_TYPE_HOME_APPLET");
+ hsAtoms[HildonAppletSettings] = atomByName("_HILDON_APPLET_SETTINGS");
+ hsAtoms[HildonAppletShowSettings] = atomByName("_HILDON_APPLET_SHOW_SETTINGS");
+ hsAtoms[HildonAppletOnCurrentDesktop] = atomByName("_HILDON_APPLET_ON_CURRENT_DESKTOP");
+}
+
+/*! \class QMaemo5HomescreenAdaptor
+
+ \brief The QMaemo5HomescreenAdaptor flags a top-level QWidget as homescreen widget
+
+ QMaemo5HomescreenAdaptor is used in conjunction with the Qt for Maemo homescreen
+ loader. It evaluates the two command line arguments "-plugin-id" and "-write-pipe"
+ to set up a Qt top-level widget as Maemo 5 homescreen widget.
+
+ Note: By default, the widget will have a black background. In order to make the
+ widget transparent, set the Qt::WA_TranslucentBackground widget attribute.
+
+ Example:
+
+ \code
+ QLabel *label = new QLabel("Hello Homescreen");
+ new QMaemo5HomescreenAdaptor(label);
+ label->show();
+ \endcode
+
+ Maemo 5 supports homescreen widgets with settings dialogs. To use it, set
+ the settingsAvailable() property and show a settings dialog when the
+ settingsRequested() signal is emitted.
+
+ Maemo 5 supports more than one homescreen. In order to determine whether
+ the homescreen widget is on the currently visible homescreen, connect to
+ the homescreenChanged() signal.
+*/
+
+/*! \property QMaemo5HomescreenAdaptor::settingsAvailable
+
+ Set this property to true if the widget can make use of a settings dialog,
+ otherwise to false. When this property is set to true, the Maemo 5 homescreen
+ renders a small settings icon on top of the homescreen widget when the
+ user enters the desktop menu. When the user clicks that settings icon, the
+ settingsRequested() signal is emitted.
+
+ The default is false.
+
+ \sa settingsRequested()
+ */
+
+/*! \fn void settingsRequested()
+
+ This signal is emitted every time the homescreen widget's settings icon is
+ invoked by the user. Note that this icon is only visible when the settingsAvailable()
+ property is set.
+
+ \sa settingsAvailable()
+ */
+
+/*! \fn void homescreenChanged(bool isOnCurrentHomescreen)
+
+ This is signal is emitted when current homescreen changes and the homescreen
+ widget becomes visible or invisible. The \a isOnCurrentHomescreen argument
+ indicates whether the homescreen widget is on the current homescreen or not.
+
+ This signal can be used to start/stop background processing in order to save
+ battery life.
+ */
+
+/*!
+ Constructs a new QMaemo5HomescreenAdaptor for the given \a widget.
+
+ Note: The widget must be a top-level widget, and must not be reparented
+ during the lifetime of this adaptor.
+
+ Note: \a widget is also the parent of this class, if the widget is destroyed,
+ so is this adaptor.
+ */
+QMaemo5HomescreenAdaptor::QMaemo5HomescreenAdaptor(QWidget *widget)
+ : QObject(widget),
+ hasSettings(false)
+{
+ Q_ASSERT(widget->isWindow());
+
+ if (!hsAtoms[0])
+ initAtoms();
+
+ Display *display = QX11Info::display();
+
+ const QStringList args = QApplication::arguments();
+
+ // parse the command line arguments.
+ int idx;
+ if ((idx = args.indexOf(QLatin1String("-plugin-id"))) != -1) {
+ appletId = args.value(idx + 1);
+ const QByteArray pluginId = appletId.toUtf8();
+ if (!pluginId.isEmpty()) {
+ XChangeProperty(display,
+ widget->winId(),
+ hsAtoms[HildonAppletId],
+ hsAtoms[Utf8String], 8, PropModeReplace,
+ reinterpret_cast<const unsigned char *>(pluginId.constData()),
+ pluginId.length());
+ }
+ }
+ if ((idx = args.indexOf(QLatin1String("-write-pipe"))) != -1) {
+ bool ok;
+ int sockId = args.value(idx + 1).toInt(&ok);
+ if (ok) {
+ socketNotifier = new QSocketNotifier(sockId, QSocketNotifier::Exception, this);
+ connect(socketNotifier, SIGNAL(activated(int)), this, SLOT(socketException()));
+ }
+ }
+
+ // set the X11 atoms to flag our widget as homescreen widget
+ if (!appletId.isEmpty()) {
+ XChangeProperty(display,
+ widget->winId(),
+ hsAtoms[NetWmWindowType],
+ XA_ATOM, 32, PropModeReplace,
+ reinterpret_cast<const unsigned char *>(&hsAtoms[HildonTypeHomeApplet]),
+ 1);
+
+ updateStatus();
+
+ // --- make this window a child of root
+ XSetTransientForHint(display, widget->winId(),
+ RootWindow(display, widget->x11Info().screen()));
+
+ // --- add an x11 event filter
+ if (!oldEventFilter)
+ oldEventFilter = QCoreApplication::instance()->setEventFilter(applicationEventFilter);
+
+ allDesktopItems.append(this);
+ }
+}
+
+QMaemo5HomescreenAdaptor::~QMaemo5HomescreenAdaptor()
+{
+ allDesktopItems.removeOne(this);
+}
+
+/*! \internal */
+void QMaemo5HomescreenAdaptor::updateStatus()
+{
+ if (appletId.isEmpty())
+ return;
+
+ Display *display = QX11Info::display();
+
+ // Set or remove settings property
+ if (hasSettings)
+ XChangeProperty(display,
+ appletWidget()->winId(),
+ hsAtoms[HildonAppletSettings],
+ XA_CARDINAL, 32, PropModeReplace,
+ (const unsigned char *) &(hasSettings), 1);
+ else
+ XDeleteProperty(display,
+ appletWidget()->winId(),
+ hsAtoms[HildonAppletSettings]);
+}
+
+/*! \internal */
+void QMaemo5HomescreenAdaptor::socketException()
+{
+ socketNotifier->setEnabled(false);
+ appletWidget()->close();
+}
+
+/*! \internal */
+bool QMaemo5HomescreenAdaptor::applicationEventFilter(void *message, long *result)
+{
+ bool retval = false;
+
+ if (oldEventFilter)
+ retval = oldEventFilter(message, result);
+
+ if (allDesktopItems.isEmpty())
+ return retval;
+
+ XEvent *ev = reinterpret_cast<XEvent *>(message);
+
+ if (ev->type == ClientMessage) {
+ XClientMessageEvent *cm = (XClientMessageEvent *)message;
+ if (cm->message_type == hsAtoms[HildonAppletShowSettings]) {
+ for (int i = 0; i < allDesktopItems.count(); ++i) {
+ if (allDesktopItems.at(i)->appletWidget()->winId() == ev->xproperty.window) {
+ emit allDesktopItems.at(i)->settingsRequested();
+ retval = true;
+ }
+ }
+ }
+ } else if (ev->type == PropertyNotify) {
+ if (ev->xproperty.atom == hsAtoms[HildonAppletOnCurrentDesktop]) {
+ for (int i = 0; i < allDesktopItems.count(); ++i) {
+ if (allDesktopItems.at(i)->appletWidget()->winId() == ev->xproperty.window) {
+ emit allDesktopItems.at(i)->homescreenChanged(ev->xproperty.window == 0);
+ retval = true;
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
diff --git a/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h
new file mode 100644
index 0000000..68c4d5b
--- /dev/null
+++ b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used 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. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMAEMO5HOMESCREENADAPTOR_H
+#define QMAEMO5HOMESCREENADAPTOR_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qwidget.h>
+
+class QWidget;
+class QSocketNotifier;
+
+class QMaemo5HomescreenAdaptor : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(bool settingsAvailable READ settingsAvailable WRITE setSettingsAvailable)
+
+public:
+ QMaemo5HomescreenAdaptor(QWidget *widget);
+ ~QMaemo5HomescreenAdaptor();
+
+ inline void setSettingsAvailable(bool available)
+ {
+ hasSettings = available;
+ updateStatus();
+ }
+
+ inline bool settingsAvailable() const
+ {
+ return hasSettings;
+ }
+
+Q_SIGNALS:
+ void settingsRequested();
+ void homescreenChanged(bool isOnCurrentHomescreen);
+
+private Q_SLOTS:
+ void socketException();
+
+private:
+ inline QWidget *appletWidget() const { return static_cast<QWidget *>(parent()); }
+
+ void updateStatus();
+
+ static bool applicationEventFilter(void *message, long *result);
+
+ bool hasSettings;
+ QString appletId;
+ QSocketNotifier *socketNotifier;
+};
+
+#endif
diff --git a/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri
new file mode 100644
index 0000000..73d41c3
--- /dev/null
+++ b/qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri
@@ -0,0 +1,4 @@
+HEADERS += $$PWD/qmaemo5homescreenadaptor.h
+SOURCES += $$PWD/qmaemo5homescreenadaptor.cpp
+
+INCLUDEPATH += $$PWD
diff --git a/qt-homescreen-example/main.cpp b/qt-homescreen-example/main.cpp
new file mode 100644
index 0000000..56d10b3
--- /dev/null
+++ b/qt-homescreen-example/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used 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. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmaemo5homescreenadaptor.h"
+#include "testwidget.h"
+
+#include <QtGui>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ TestWidget w;
+ QMaemo5HomescreenAdaptor *adaptor = new QMaemo5HomescreenAdaptor(&w);
+ adaptor->setSettingsAvailable(true);
+ QObject::connect(adaptor, SIGNAL(settingsRequested()), &w, SLOT(showSettingsDialog()));
+ w.show();
+
+ app.exec();
+}
+
diff --git a/qt-homescreen-example/qt-homescreen-example.desktop b/qt-homescreen-example/qt-homescreen-example.desktop
new file mode 100644
index 0000000..7b2b52d
--- /dev/null
+++ b/qt-homescreen-example/qt-homescreen-example.desktop
@@ -0,0 +1,9 @@
+[Desktop Entry]
+Name=Qt Desktop Example
+Comment=An example home desktop item
+Type=qt
+X-Path=qt-homescreen-example
+X-Multiple-Instances=false
+X-home-applet-minwidth=100
+X-home-applet-minheight=72
+Name[en_US]=Example Qt Desktop Item
diff --git a/qt-homescreen-example/qt-homescreen-example.pro b/qt-homescreen-example/qt-homescreen-example.pro
new file mode 100644
index 0000000..3ef254f
--- /dev/null
+++ b/qt-homescreen-example/qt-homescreen-example.pro
@@ -0,0 +1,12 @@
+TEMPLATE = app
+
+SOURCES += main.cpp
+HEADERS += testwidget.h
+
+include(../qmaemo5homescreenadaptor/qmaemo5homescreenadaptor.pri)
+
+desktop.path = /usr/share/applications/hildon-home
+desktop.files = qt-homescreen-example.desktop
+
+target.path = /usr/lib/hildon-desktop
+INSTALLS += target desktop
diff --git a/qt-homescreen-example/testwidget.h b/qt-homescreen-example/testwidget.h
new file mode 100644
index 0000000..9aa5a78
--- /dev/null
+++ b/qt-homescreen-example/testwidget.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used 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. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TESTWIDGET_H
+#define TESTWIDGET_H
+
+#include <QtGui/qlabel.h>
+#include <QtGui/qinputdialog.h>
+#include <QtGui/qpainter.h>
+
+class TestWidget : public QLabel
+{
+ Q_OBJECT
+
+public:
+ TestWidget()
+ : QLabel(tr("Hello World"))
+ {
+ setAlignment(Qt::AlignCenter);
+ setAttribute(Qt::WA_TranslucentBackground);
+ }
+
+ QSize sizeHint() const
+ {
+ return 2 * QLabel::sizeHint();
+ }
+
+public slots:
+ void showSettingsDialog()
+ {
+ bool isOk;
+ QString newText = QInputDialog::getText(this, tr("New Text"),
+ tr("Please enter a new text:"), QLineEdit::Normal,
+ text(), &isOk);
+ if (isOk)
+ setText(newText);
+ }
+
+protected:
+ void paintEvent(QPaintEvent *event)
+ {
+ QPainter p(this);
+ p.setBrush(QColor(0, 0, 0, 128));
+ p.setPen(Qt::NoPen);
+ p.drawRoundedRect(rect(), 25, 25);
+ p.end();
+
+ QLabel::paintEvent(event);
+ }
+};
+
+#endif
diff --git a/qt4-maemo5-homescreen.pro b/qt4-maemo5-homescreen.pro
new file mode 100644
index 0000000..3ecb1b4
--- /dev/null
+++ b/qt4-maemo5-homescreen.pro
@@ -0,0 +1,2 @@
+TEMPLATE = subdirs
+SUBDIRS = qt-homescreen-example qtpluginloader
diff --git a/qtpluginloader/hd-plugin-loader-qt.c b/qtpluginloader/hd-plugin-loader-qt.c
new file mode 100644
index 0000000..912d6c2
--- /dev/null
+++ b/qtpluginloader/hd-plugin-loader-qt.c
@@ -0,0 +1,394 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used 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. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <libhildondesktop/libhildondesktop.h>
+
+#include "hd-plugin-loader-qt.h"
+
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <gdk/gdkx.h>
+
+#ifndef HD_PLUGIN_MODULE_PATH
+#define HD_PLUGIN_MODULE_PATH "/usr/lib/hildon-desktop"
+#endif
+
+/* those come from hd-config.h */
+#define HD_PLUGIN_CONFIG_GROUP "Desktop Entry"
+#define HD_PLUGIN_CONFIG_KEY_TYPE "Type"
+#define HD_PLUGIN_CONFIG_KEY_PATH "X-Path"
+#define HD_PLUGIN_CONFIG_KEY_TEXT_DOMAIN "X-Text-Domain"
+
+#define QT_ABSTRACT_HOME_ITEM_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), QT_TYPE_ABSTRACT_HOME_ITEM, QtAbstractHomeItemPrivate))
+
+struct _QtAbstractHomeItemPrivate
+{
+ GIOChannel *gio_read;
+
+ gchar realized;
+ gchar *executable_path;
+};
+
+G_DEFINE_TYPE (QtAbstractHomeItem, qt_abstract_home_item, HD_TYPE_HOME_PLUGIN_ITEM);
+
+static void
+qt_abstract_home_item_init (QtAbstractHomeItem *object)
+{
+ object->priv = QT_ABSTRACT_HOME_ITEM_GET_PRIVATE (object);
+
+ QtAbstractHomeItemPrivate *priv = object->priv;
+ priv->gio_read = NULL;
+
+ priv->realized = FALSE;
+ priv->executable_path = 0;
+
+}
+
+static void
+qt_abstract_home_item_finalize (GObject *object)
+{
+ QtAbstractHomeItemPrivate *priv = QT_ABSTRACT_HOME_ITEM (object)->priv;
+
+ if (priv->gio_read)
+ {
+ g_io_channel_unref(priv->gio_read);
+ priv->gio_read = NULL;
+ }
+
+ g_free (priv->executable_path);
+
+ G_OBJECT_CLASS (qt_abstract_home_item_parent_class)->finalize (object);
+}
+
+static gboolean
+qt_abstract_home_item_gio_in (GIOChannel *gio, GIOCondition condition, gpointer data)
+{
+ /*
+ GIOStatus ret;
+ gchar *msg;
+ gsize len;
+ GError *err = NULL; */
+ GdkEvent *gdk_delete_event;
+ QtAbstractHomeItem *object = data;
+ GtkWidget *widget = GTK_WIDGET(object);
+
+ (void) gio; // unused
+
+ if (condition & G_IO_HUP) {
+ /* send a delete event so that hildon-home get's notified that our item was closed */
+ gdk_delete_event = gdk_event_new (GDK_DELETE);
+ gdk_delete_event->any.window = widget->window;
+ gdk_delete_event->any.send_event = TRUE;
+ gtk_main_do_event (gdk_delete_event);
+ gdk_event_free (gdk_delete_event);
+
+ return FALSE;
+ }
+
+ /* we are using the pipe only to check the life state of qt */
+ /*
+ ret = g_io_channel_read_line (gio, &msg, &len, NULL, &err);
+ if (ret == G_IO_STATUS_ERROR)
+ g_critical ("Error reading: %s", err->message);
+
+ g_warning ("Read %u bytes: %s", len, msg);
+
+ g_free (msg);
+ */
+ return TRUE;
+}
+
+static GError*
+qt_abstract_home_item_error_new (const char *literal)
+{
+ GError *error = g_error_new_literal (g_quark_from_static_string("qt-loader-execute"),
+ QT_LOADER_EXECUTE_ERROR,
+ literal);
+ return error;
+}
+
+static GError*
+qt_abstract_home_item_execute (QtAbstractHomeItem *object)
+{
+ int qtToGtkPipe[2];
+ int ret;
+ QtAbstractHomeItemPrivate *priv = QT_ABSTRACT_HOME_ITEM (object)->priv;
+
+ /* --- open the communication pipe */
+ ret = pipe (qtToGtkPipe);
+ if (ret == -1)
+ return qt_abstract_home_item_error_new("Creating pipe failed.");
+
+ /* --- Fork and exec the new application */
+ pid_t pid = fork();
+ if (pid < 0) {
+ return qt_abstract_home_item_error_new("Unable do fork new process.");
+
+ } else if (pid) {
+ /* I am the original process */
+ close( qtToGtkPipe[1] );
+
+ priv->gio_read = g_io_channel_unix_new (qtToGtkPipe[0]);
+ if (!priv->gio_read)
+ return qt_abstract_home_item_error_new("Cannot create new GIOChannel!");
+
+ if (!g_io_add_watch (priv->gio_read, G_IO_IN | G_IO_HUP,
+ qt_abstract_home_item_gio_in, object))
+ return qt_abstract_home_item_error_new("Cannot add watch on GIOChannel!");
+
+ } else {
+ /* I am the forked process */
+ char *appletId;
+ char writePipeStr[20];
+
+ close( qtToGtkPipe[0] );
+
+ appletId = hd_home_plugin_item_get_applet_id (HD_HOME_PLUGIN_ITEM (object));
+ snprintf( writePipeStr, 19, "%d", qtToGtkPipe[1]);
+
+ char *newargv[] = { priv->executable_path,
+ "-plugin-id", appletId,
+ "-write-pipe", writePipeStr,
+ NULL };
+
+ // note: old file descriptors are still open
+ execv(newargv[0], newargv);
+
+ // we should not run through here...
+ g_free (appletId);
+ }
+
+ return 0;
+}
+
+static void
+qt_abstract_home_item_realize (GtkWidget *widget)
+{
+ GdkDisplay *display;
+ QtAbstractHomeItem *item = QT_ABSTRACT_HOME_ITEM (widget);
+ QtAbstractHomeItemPrivate *priv = item->priv;
+
+ GTK_WIDGET_CLASS (qt_abstract_home_item_parent_class)->realize (widget);
+
+ /* Remove the applet id atom again. we have our own */
+ display = gdk_drawable_get_display (widget->window);
+ XDeleteProperty (GDK_WINDOW_XDISPLAY (widget->window),
+ GDK_WINDOW_XID (widget->window),
+ gdk_x11_get_xatom_by_name_for_display (display,
+ "_HILDON_APPLET_ID"));
+
+ if (!priv->realized) {
+ GError *error = NULL;
+ priv->realized = TRUE;
+ error = qt_abstract_home_item_execute (item);
+ if (error) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ }
+ }
+}
+
+static void
+qt_abstract_home_item_show (GtkWidget *widget)
+{
+ /* Do not call the gtk show. keep the gtk window hidden */
+ (void) widget; // unused
+}
+
+static void
+qt_abstract_home_item_class_init (QtAbstractHomeItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = qt_abstract_home_item_finalize;
+
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+ widget_class->realize = qt_abstract_home_item_realize;
+ widget_class->show = qt_abstract_home_item_show;
+
+ g_type_class_add_private (klass, sizeof (QtAbstractHomeItemPrivate));
+}
+
+/*
+static void
+qt_abstract_home_item_class_finalize (QtAbstractHomeItemClass *klass)
+{
+}
+*/
+
+// client event with hildon settings
+// client notify event...
+
+
+#define HD_PLUGIN_LOADER_QT_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HD_TYPE_PLUGIN_LOADER_QT, HDPluginLoaderQtPrivate))
+
+G_DEFINE_TYPE (HDPluginLoaderQt, hd_plugin_loader_qt, HD_TYPE_PLUGIN_LOADER);
+
+struct _HDPluginLoaderQtPrivate
+{
+ GHashTable *registry;
+};
+
+
+static GObject *
+hd_plugin_loader_qt_load (HDPluginLoader *loader,
+ const gchar *plugin_id,
+ GKeyFile *keyfile,
+ GError **error)
+{
+ GObject *object = NULL;
+
+ g_return_val_if_fail (loader, NULL);
+
+ if (!keyfile)
+ {
+ g_set_error (error,
+ hd_plugin_loader_error_quark (),
+ HD_PLUGIN_LOADER_ERROR_KEYFILE,
+ "A keyfile required to load plugins");
+
+ return NULL;
+ }
+
+ /* construct a new proxy object */
+ object = g_object_new (QT_TYPE_ABSTRACT_HOME_ITEM,
+ "plugin-id", plugin_id,
+ NULL);
+
+ /* --- get the executable path */
+ {
+ QtAbstractHomeItemPrivate *priv = QT_ABSTRACT_HOME_ITEM (object)->priv;
+ GError *keyfile_error = NULL;
+ gchar *executable_file = NULL;
+
+ executable_file = g_key_file_get_string (keyfile,
+ HD_PLUGIN_CONFIG_GROUP,
+ HD_PLUGIN_CONFIG_KEY_PATH,
+ &keyfile_error);
+ g_strstrip (executable_file);
+
+ if (keyfile_error)
+ {
+ g_propagate_error (error, keyfile_error);
+ return NULL;
+ }
+
+ if (g_path_is_absolute (executable_file))
+ {
+ priv->executable_path = executable_file;
+ }
+ else
+ {
+ priv->executable_path = g_build_filename (HD_PLUGIN_MODULE_PATH,
+ executable_file,
+ NULL);
+
+ g_free (executable_file);
+ }
+ }
+
+ return object;
+}
+
+ static void
+hd_plugin_loader_qt_finalize (GObject *loader)
+{
+ HDPluginLoaderQtPrivate *priv;
+
+ g_return_if_fail (loader != NULL);
+ g_return_if_fail (HD_IS_PLUGIN_LOADER_QT (loader));
+
+ priv = HD_PLUGIN_LOADER_QT (loader)->priv;
+
+ if (priv->registry != NULL)
+ {
+ g_hash_table_destroy (priv->registry);
+ priv->registry = NULL;
+ }
+
+ G_OBJECT_CLASS (hd_plugin_loader_qt_parent_class)->finalize (loader);
+}
+
+static void
+hd_plugin_loader_qt_init (HDPluginLoaderQt *loader)
+{
+ loader->priv = HD_PLUGIN_LOADER_QT_GET_PRIVATE (loader);
+
+ loader->priv->registry = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ NULL);
+}
+
+static void
+hd_plugin_loader_qt_class_init (HDPluginLoaderQtClass *class)
+{
+ GObjectClass *object_class;
+ HDPluginLoaderClass *loader_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = hd_plugin_loader_qt_finalize;
+
+ // widget_class = GTK_WIDGET_CLASS (class);
+
+ loader_class = HD_PLUGIN_LOADER_CLASS (class);
+ loader_class->load = hd_plugin_loader_qt_load;
+
+ g_type_class_add_private (object_class, sizeof (HDPluginLoaderQtPrivate));
+}
+
+G_MODULE_EXPORT gchar *
+hd_plugin_loader_module_type (void)
+{
+ return "qt";
+}
+
+G_MODULE_EXPORT HDPluginLoader *
+hd_plugin_loader_module_get_instance (void)
+{
+ return g_object_new (HD_TYPE_PLUGIN_LOADER_QT, NULL);
+}
+
+
+
diff --git a/qtpluginloader/hd-plugin-loader-qt.h b/qtpluginloader/hd-plugin-loader-qt.h
new file mode 100644
index 0000000..a0c4188
--- /dev/null
+++ b/qtpluginloader/hd-plugin-loader-qt.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used 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. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef __HD_PLUGIN_LOADER_QT_H__
+#define __HD_PLUGIN_LOADER_QT_H__
+
+#include <libhildondesktop/libhildondesktop.h>
+
+G_BEGIN_DECLS
+
+#define QT_LOADER_EXECUTE_ERROR 1
+
+#define QT_TYPE_ABSTRACT_HOME_ITEM (qt_abstract_home_item_get_type ())
+#define QT_ABSTRACT_HOME_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), QT_TYPE_ABSTRACT_HOME_ITEM, QtAbstractHomeItem))
+#define QT_ABSTRACT_HOME_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), QT_TYPE_ABSTRACT_HOME_ITEM, QtAbstractHomeItemClass))
+#define QT_IS_ABSTRACT_HOME_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), QT_TYPE_ABSTRACT_HOME_ITEM))
+#define QT_IS_ABSTRACT_HOME_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), QT_TYPE_ABSTRACT_HOME_ITEM))
+#define QT_ABSTRACT_HOME_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), QT_TYPE_ABSTRACT_HOME_ITEM, QtAbstractHomeItemClass))
+
+typedef struct _QtAbstractHomeItem QtAbstractHomeItem;
+typedef struct _QtAbstractHomeItemClass QtAbstractHomeItemClass;
+typedef struct _QtAbstractHomeItemPrivate QtAbstractHomeItemPrivate;
+
+struct _QtAbstractHomeItem
+{
+ HDHomePluginItem parent;
+
+ QtAbstractHomeItemPrivate *priv;
+};
+
+struct _QtAbstractHomeItemClass
+{
+ HDHomePluginItemClass parent;
+};
+
+GType qt_abstract_home_item_get_type (void);
+
+
+typedef struct _HDPluginLoaderQt HDPluginLoaderQt;
+typedef struct _HDPluginLoaderQtClass HDPluginLoaderQtClass;
+typedef struct _HDPluginLoaderQtPrivate HDPluginLoaderQtPrivate;
+
+#define HD_TYPE_PLUGIN_LOADER_QT (hd_plugin_loader_qt_get_type ())
+#define HD_PLUGIN_LOADER_QT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HD_TYPE_PLUGIN_LOADER_QT, HDPluginLoaderQt))
+#define HD_IS_PLUGIN_LOADER_QT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), HD_TYPE_PLUGIN_LOADER_QT))
+#define HD_PLUGIN_LOADER_QT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), HD_TYPE_PLUGIN_LOADER_QT_CLASS, HDPluginLoaderQtClass))
+#define HD_IS_PLUGIN_LOADER_QT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), HD_TYPE_PLUGIN_LOADER_QT_CLASS))
+#define HD_PLUGIN_LOADER_QT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), HD_TYPE_PLUGIN_LOADER_QT, HDPluginLoaderQtClass))
+
+struct _HDPluginLoaderQt
+{
+ HDPluginLoader parent;
+
+ HDPluginLoaderQtPrivate *priv;
+};
+
+struct _HDPluginLoaderQtClass
+{
+ HDPluginLoaderClass parent_class;
+};
+
+GType hd_plugin_loader_qt_get_type (void);
+
+G_END_DECLS
+
+#endif /* __HD_PLUGIN_LOADER_QT_H__ */
diff --git a/qtpluginloader/qtpluginloader.pro b/qtpluginloader/qtpluginloader.pro
new file mode 100644
index 0000000..0398280
--- /dev/null
+++ b/qtpluginloader/qtpluginloader.pro
@@ -0,0 +1,13 @@
+TARGET = qtpluginloader
+
+TEMPLATE = lib
+CONFIG += plugin
+SOURCES = hd-plugin-loader-qt.c
+HEADERS = hd-plugin-loader-qt.h
+
+CONFIG += link_pkgconfig
+PKGCONFIG += hildon-1 libhildondesktop-1
+
+# install
+target.path = /usr/lib/hildon-desktop/loaders
+INSTALLS += target