summaryrefslogtreecommitdiff
path: root/libdbus-qeventloop
diff options
context:
space:
mode:
authorMartin Wolf <ext-martin.2.wolf@nokia.com>2010-02-03 10:13:44 +0200
committerMartin Wolf <ext-martin.2.wolf@nokia.com>2010-02-03 10:13:44 +0200
commit06644af1a621f2afbd42957afc9cfda24056df54 (patch)
treedac557aab7a7bff21ad7b7c0ccc877bf42f5303e /libdbus-qeventloop
parent8bff62c335842b4c850cc09716e79c2f556247c7 (diff)
Added debian packaging info and libdbus-qeventloop library
Diffstat (limited to 'libdbus-qeventloop')
-rw-r--r--libdbus-qeventloop/dbusconnectioneventloop.cpp259
-rw-r--r--libdbus-qeventloop/dbusconnectioneventloop.h62
-rw-r--r--libdbus-qeventloop/libdbus-qeventloop.pro29
3 files changed, 350 insertions, 0 deletions
diff --git a/libdbus-qeventloop/dbusconnectioneventloop.cpp b/libdbus-qeventloop/dbusconnectioneventloop.cpp
new file mode 100644
index 0000000..16f4a24
--- /dev/null
+++ b/libdbus-qeventloop/dbusconnectioneventloop.cpp
@@ -0,0 +1,259 @@
+#include <QCoreApplication>
+#include <QSocketNotifier>
+#include <QTimer>
+#include <QTimerEvent>
+
+#include "dbusconnectioneventloop.h"
+#include <stdio.h>
+
+DBUSConnectionEventLoop::DBUSConnectionEventLoop() : QObject()
+{
+}
+
+DBUSConnectionEventLoop::~DBUSConnectionEventLoop()
+{
+}
+
+// Handle a socket being ready to read.
+void DBUSConnectionEventLoop::readSocket(int fd)
+{
+ Watchers::const_iterator it = watchers.find(fd);
+
+ while( it != watchers.end() && it.key() == fd )
+ {
+ const Watcher &watcher = it.value();
+
+ if( watcher.read && watcher.read->isEnabled() )
+ {
+ watcher.read->setEnabled(false);
+ dbus_watch_handle(watcher.watch, DBUS_WATCH_READABLE);
+ watcher.read->setEnabled(true);
+ break;
+ }
+
+ ++it;
+ }
+
+ dispatch();
+}
+
+// Handle a socket being ready to write.
+void DBUSConnectionEventLoop::writeSocket(int fd)
+{
+ Watchers::const_iterator it = watchers.find(fd);
+
+ while( it != watchers.end() && it.key() == fd )
+ {
+ const Watcher &watcher = it.value();
+
+ if( watcher.write && watcher.write->isEnabled() )
+ {
+ watcher.write->setEnabled(false);
+ dbus_watch_handle(watcher.watch, DBUS_WATCH_WRITABLE);
+ watcher.write->setEnabled(true);
+ break;
+ }
+
+ ++it;
+ }
+}
+
+void DBUSConnectionEventLoop::dispatch()
+{
+ for( Connections::const_iterator it = connections.constBegin(); it != connections.constEnd(); ++it )
+ while( dbus_connection_dispatch(*it) == DBUS_DISPATCH_DATA_REMAINS )
+ ;
+}
+
+// Handle timer events.
+void DBUSConnectionEventLoop::timerEvent(QTimerEvent *e)
+{
+ DBusTimeout *timeout = timeouts.value(e->timerId());
+
+ if( timeout )
+ dbus_timeout_handle(timeout);
+}
+
+dbus_bool_t DBUSConnectionEventLoop::addWatch(DBusWatch *watch, void *data)
+{
+ DBUSConnectionEventLoop *loop = reinterpret_cast<DBUSConnectionEventLoop *>(data);
+
+ int fd = dbus_watch_get_unix_fd(watch);
+ unsigned int flags = dbus_watch_get_flags(watch);
+ dbus_bool_t enabled = dbus_watch_get_enabled(watch);
+
+ DBUSConnectionEventLoop::Watcher watcher;
+ watcher.watch = watch;
+
+ if( flags & DBUS_WATCH_READABLE )
+ {
+ watcher.read = new QSocketNotifier(fd, QSocketNotifier::Read, loop);
+ watcher.read->setEnabled(enabled);
+ loop->connect(watcher.read, SIGNAL(activated(int)), SLOT(readSocket(int)));
+ }
+
+ if( flags & DBUS_WATCH_WRITABLE )
+ {
+ watcher.write = new QSocketNotifier(fd, QSocketNotifier::Write, loop);
+ watcher.write->setEnabled(enabled);
+ loop->connect(watcher.write, SIGNAL(activated(int)), SLOT(writeSocket(int)));
+ }
+
+ loop->watchers.insertMulti(fd, watcher);
+
+ return true;
+}
+
+void DBUSConnectionEventLoop::removeWatch(DBusWatch *watch, void *data)
+{
+ DBUSConnectionEventLoop *loop = reinterpret_cast<DBUSConnectionEventLoop *>(data);
+
+ int fd = dbus_watch_get_unix_fd(watch);
+
+ DBUSConnectionEventLoop::Watchers::iterator it = loop->watchers.find(fd);
+
+ while( it != loop->watchers.end() && it.key() == fd )
+ {
+ DBUSConnectionEventLoop::Watcher &watcher = it.value();
+
+ if( watcher.watch == watch )
+ {
+ if( watcher.read )
+ delete watcher.read;
+
+ if( watcher.write )
+ delete watcher.write;
+
+ loop->watchers.erase(it);
+
+ return;
+ }
+
+ ++it;
+ }
+}
+
+void DBUSConnectionEventLoop::toggleWatch(DBusWatch *watch, void *data)
+{
+ DBUSConnectionEventLoop *loop = reinterpret_cast<DBUSConnectionEventLoop *>(data);
+
+ int fd = dbus_watch_get_unix_fd(watch);
+ unsigned int flags = dbus_watch_get_flags(watch);
+ dbus_bool_t enabled = dbus_watch_get_enabled(watch);
+
+ DBUSConnectionEventLoop::Watchers::const_iterator it = loop->watchers.find(fd);
+
+ while( it != loop->watchers.end() && it.key() == fd )
+ {
+ const DBUSConnectionEventLoop::Watcher &watcher = it.value();
+
+ if( watcher.watch == watch )
+ {
+ if( flags & DBUS_WATCH_READABLE && watcher.read )
+ watcher.read->setEnabled(enabled);
+
+ if( flags & DBUS_WATCH_WRITABLE && watcher.write )
+ watcher.write->setEnabled(enabled);
+
+ return;
+ }
+
+ ++it;
+ }
+}
+
+dbus_bool_t DBUSConnectionEventLoop::addTimeout(DBusTimeout *timeout, void *data)
+{
+ // Nothing to do if the timeout is disabled.
+ if( !dbus_timeout_get_enabled(timeout) )
+ return true;
+
+ // Pretend it is successful if there is no application instance.
+ if( !QCoreApplication::instance() )
+ return true;
+
+ DBUSConnectionEventLoop *loop = reinterpret_cast<DBUSConnectionEventLoop *>(data);
+
+ int id = loop->startTimer(dbus_timeout_get_interval(timeout));
+
+ if( !id )
+ return false;
+
+ loop->timeouts[id] = timeout;
+
+ return true;
+}
+
+void DBUSConnectionEventLoop::removeTimeout(DBusTimeout *timeout, void *data)
+{
+ DBUSConnectionEventLoop *loop = reinterpret_cast<DBUSConnectionEventLoop *>(data);
+
+ DBUSConnectionEventLoop::Timeouts::iterator it = loop->timeouts.begin();
+
+ while( it != loop->timeouts.end() )
+ {
+ if( it.value() == timeout )
+ {
+ loop->killTimer(it.key());
+ it = loop->timeouts.erase(it);
+ }
+ else
+ ++it;
+ }
+}
+
+void DBUSConnectionEventLoop::toggleTimeout(DBusTimeout *timeout, void *data)
+{
+ DBUSConnectionEventLoop::removeTimeout(timeout, data);
+ DBUSConnectionEventLoop::addTimeout(timeout, data);
+}
+
+void DBUSConnectionEventLoop::wakeupMain(void *data)
+{
+ DBUSConnectionEventLoop *loop = reinterpret_cast<DBUSConnectionEventLoop *>(data);
+
+ QTimer::singleShot(0, loop, SLOT(dispatch()));
+}
+
+// The initialization point
+bool DBUSConnectionEventLoop::initConnection(DBusConnection* conn)
+{
+ bool rc;
+
+ if( conn == NULL )
+ {
+ return false;
+ }
+
+ connections.append(conn);
+
+ if(
+ !dbus_connection_set_watch_functions(conn,
+ DBUSConnectionEventLoop::addWatch,
+ DBUSConnectionEventLoop::removeWatch,
+ DBUSConnectionEventLoop::toggleWatch,
+ this, 0)
+ )
+ {
+ rc = false;
+ }
+ else if(
+ !dbus_connection_set_timeout_functions(conn,
+ DBUSConnectionEventLoop::addTimeout,
+ DBUSConnectionEventLoop::removeTimeout,
+ DBUSConnectionEventLoop::toggleTimeout,
+ this, 0)
+ )
+ {
+ rc = false;
+ }
+ else
+ {
+ rc = true;
+ }
+
+ dbus_connection_set_wakeup_main_function(conn, DBUSConnectionEventLoop::wakeupMain, this, 0);
+
+ return rc;
+}
+
diff --git a/libdbus-qeventloop/dbusconnectioneventloop.h b/libdbus-qeventloop/dbusconnectioneventloop.h
new file mode 100644
index 0000000..ef46ea2
--- /dev/null
+++ b/libdbus-qeventloop/dbusconnectioneventloop.h
@@ -0,0 +1,62 @@
+#ifndef DBUSCONNECTIONEVENTLOOP_H
+#define DBUSCONNECTIONEVENTLOOP_H
+
+#include <QObject>
+#include <QList>
+#include <QMultiHash>
+#include <QHash>
+
+#include <dbus/dbus.h>
+
+class QSocketNotifier;
+class QTimerEvent;
+
+class DBUSConnectionEventLoop : public QObject
+{
+ Q_OBJECT
+private:
+ Q_DISABLE_COPY(DBUSConnectionEventLoop)
+
+public:
+ DBUSConnectionEventLoop();
+ virtual ~DBUSConnectionEventLoop();
+
+public:
+ bool initConnection(DBusConnection* conn);
+
+ class Watcher
+ {
+ public:
+ Watcher() : watch(0), read(0), write(0) {}
+
+ DBusWatch* watch;
+ QSocketNotifier* read;
+ QSocketNotifier* write;
+ };
+
+ typedef QMultiHash<int, Watcher> Watchers;
+ typedef QHash<int, DBusTimeout*> Timeouts;
+ typedef QList<DBusConnection*> Connections;
+
+ Watchers watchers;
+ Timeouts timeouts;
+ Connections connections;
+
+public slots:
+ void readSocket(int fd);
+ void writeSocket(int fd);
+ void dispatch();
+
+protected:
+ void timerEvent(QTimerEvent *e);
+
+ static dbus_bool_t addWatch(DBusWatch *watch, void *data);
+ static void removeWatch(DBusWatch *watch, void *data);
+ static void toggleWatch(DBusWatch *watch, void *data);
+ static dbus_bool_t addTimeout(DBusTimeout *timeout, void *data);
+ static void removeTimeout(DBusTimeout *timeout, void *data);
+ static void toggleTimeout(DBusTimeout *timeout, void *data);
+ static void wakeupMain(void *data);
+};
+
+#endif // DBUSCONNECTIONEVENTLOOP_H
diff --git a/libdbus-qeventloop/libdbus-qeventloop.pro b/libdbus-qeventloop/libdbus-qeventloop.pro
new file mode 100644
index 0000000..7aa22b1
--- /dev/null
+++ b/libdbus-qeventloop/libdbus-qeventloop.pro
@@ -0,0 +1,29 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2010-01-18T16:28:34
+#
+#-------------------------------------------------
+
+
+TARGET = dbus-qeventloop
+TEMPLATE = lib
+VERSION = 0.1
+DESTDIR = build
+MOC_DIR = .moc
+OBJECTS_DIR = .obj
+
+DEFINES += LIBDBUSQEVENTLOOP_LIBRARY
+SOURCES += dbusconnectioneventloop.cpp
+
+HEADERS += dbusconnectioneventloop.h
+
+QT = core
+CONFIG += qt link_pkgconfig dll
+PKGCONFIG += dbus-1
+
+# Install directives
+headers.files = $$HEADERS
+INSTALLBASE = /usr
+target.path = $$INSTALLBASE/lib
+headers.path = $$INSTALLBASE/include/resource/qt4
+INSTALLS = target headers