DBus-1-TQt  1.0
tqdbusconnection.cpp
Go to the documentation of this file.
00001 /* qdbusconnection.cpp
00002  *
00003  * Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
00004  * Copyright (C) 2005-2007 Kevin Krammer <kevin.krammer@gmx.at>
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
00021  * USA.
00022  *
00023  */
00024 
00025 #include <tqapplication.h>
00026 
00027 #include "tqdbusconnection.h"
00028 #include "tqdbuserror.h"
00029 #include "tqdbusmessage.h"
00030 #include "tqdbusconnection_p.h"
00031 
00032 #include "tqdbusmessage_p.h"
00033 
00034 QT_STATIC_CONST_IMPL char *TQT_DBusConnection::default_connection_name = "qt_dbus_default_connection";
00035 
00036 class TQT_DBusConnectionManager
00037 {
00038 public:
00039     TQT_DBusConnectionManager(): default_connection(0) {}
00040     ~TQT_DBusConnectionManager();
00041     void bindToApplication();
00042     TQT_DBusConnectionPrivate *connection(const TQString &name) const;
00043     void removeConnection(const TQString &name);
00044     void setConnection(const TQString &name, TQT_DBusConnectionPrivate *c);
00045 
00046     static TQT_DBusConnectionManager* instance() {
00047         if (managerInstance == 0) managerInstance = new TQT_DBusConnectionManager();
00048         return managerInstance;
00049     }
00050 
00051 private:
00052     TQT_DBusConnectionPrivate *default_connection;
00053     // FIXME-QT4 TQHash<TQString, TQT_DBusConnectionPrivate *> connectionHash;
00054     typedef TQMap<TQString, TQT_DBusConnectionPrivate*> ConnectionHash;
00055     ConnectionHash connectionHash;
00056 
00057     static TQT_DBusConnectionManager* managerInstance;
00058 };
00059 
00060 // FIXME-QT4 TQ_GLOBAL_STATIC(TQT_DBusConnectionManager, manager);
00061 TQT_DBusConnectionManager* TQT_DBusConnectionManager::managerInstance = 0;
00062 TQT_DBusConnectionManager* manager() {
00063     return TQT_DBusConnectionManager::instance();
00064 }
00065 
00066 TQT_DBusConnectionPrivate *TQT_DBusConnectionManager::connection(const TQString &name) const
00067 {
00068     if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name))
00069         return default_connection;
00070 
00071     ConnectionHash::const_iterator it = connectionHash.find(name);
00072 
00073     return (it != connectionHash.end() ? it.data() : 0);
00074 }
00075 
00076 void TQT_DBusConnectionManager::removeConnection(const TQString &name)
00077 {
00078     TQT_DBusConnectionPrivate *d = 0;
00079     if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name)) {
00080         d = default_connection;
00081         default_connection = 0;
00082     } else {
00083         ConnectionHash::iterator it = connectionHash.find(name);
00084         if (it == connectionHash.end())
00085             return;
00086 
00087         d = it.data();
00088         connectionHash.erase(it);
00089     }
00090     if (!d->ref.deref())
00091         delete d;
00092 }
00093 
00094 TQT_DBusConnectionManager::~TQT_DBusConnectionManager()
00095 {
00096     if (default_connection) {
00097         delete default_connection;
00098         default_connection = 0;
00099     }
00100 /* FIXME-QT4
00101     for (TQHash<TQString, TQT_DBusConnectionPrivate *>::const_iterator it = connectionHash.constBegin();
00102          it != connectionHash.constEnd(); ++it) {
00103              delete it.value();
00104     }*/
00105     for (ConnectionHash::const_iterator it = connectionHash.constBegin();
00106          it != connectionHash.constEnd(); ++it)
00107     {
00108         delete it.data();
00109     }
00110     connectionHash.clear();
00111 }
00112 
00113 void TQT_DBusConnectionManager::bindToApplication()
00114 {
00115     if (default_connection) {
00116         default_connection->bindToApplication();
00117     }
00118 /* FIXME-QT4
00119     for (TQHash<TQString, TQT_DBusConnectionPrivate *>::const_iterator it = connectionHash.constBegin();
00120          it != connectionHash.constEnd(); ++it) {
00121              (*it)->bindToApplication();
00122     }*/
00123     for (ConnectionHash::const_iterator it = connectionHash.constBegin();
00124          it != connectionHash.constEnd(); ++it)
00125     {
00126         it.data()->bindToApplication();
00127     }
00128 }
00129 
00130 void qDBusBindToApplication()
00131 {
00132     manager()->bindToApplication();
00133 }
00134 
00135 void TQT_DBusConnectionManager::setConnection(const TQString &name, TQT_DBusConnectionPrivate *c)
00136 {
00137     if (name == TQString::fromLatin1(TQT_DBusConnection::default_connection_name))
00138         default_connection = c;
00139     else
00140         connectionHash[name] = c;
00141 }
00142 
00143 
00144 TQT_DBusConnection::TQT_DBusConnection() : d(0)
00145 {
00146 }
00147 
00148 TQT_DBusConnection::TQT_DBusConnection(const TQString &name)
00149 {
00150     d = manager()->connection(name);
00151     if (d)
00152         d->ref.ref();
00153 }
00154 
00155 TQT_DBusConnection::TQT_DBusConnection(const TQT_DBusConnection &other)
00156 {
00157     d = other.d;
00158     if (d)
00159         d->ref.ref();
00160 }
00161 
00162 TQT_DBusConnection::~TQT_DBusConnection()
00163 {
00164     if (d && !d->ref.deref())
00165         delete d;
00166 }
00167 
00168 TQT_DBusConnection &TQT_DBusConnection::operator=(const TQT_DBusConnection &other)
00169 {
00170     if (other.d)
00171         other.d->ref.ref();
00172 /* FIXME-QT4
00173     TQT_DBusConnectionPrivate *old = static_cast<TQT_DBusConnectionPrivate *>(
00174             q_atomic_set_ptr(&d, other.d));*/
00175     TQT_DBusConnectionPrivate* old = d;
00176     d = other.d;
00177     if (old && !old->ref.deref())
00178         delete old;
00179 
00180     return *this;
00181 }
00182 
00183 TQT_DBusConnection TQT_DBusConnection::sessionBus()
00184 {
00185     return addConnection(TQT_DBusConnection::SessionBus);
00186 }
00187 
00188 TQT_DBusConnection TQT_DBusConnection::systemBus()
00189 {
00190     return addConnection(TQT_DBusConnection::SystemBus);
00191 }
00192 
00193 TQT_DBusConnection TQT_DBusConnection::addConnection(BusType type, const TQString &name)
00194 {
00195 //    Q_ASSERT_X(TQCoreApplication::instance(), "TQT_DBusConnection::addConnection",
00196 //               "Cannot create connection without a Q[Core]Application instance");
00197 
00198     TQT_DBusConnectionPrivate *d = manager()->connection(name);
00199     if (d)
00200         return TQT_DBusConnection(name);
00201 
00202     d = new TQT_DBusConnectionPrivate;
00203     DBusConnection *c = 0;
00204     switch (type) {
00205         case SystemBus:
00206             c = dbus_bus_get(DBUS_BUS_SYSTEM, &d->error);
00207             break;
00208         case SessionBus:
00209             c = dbus_bus_get(DBUS_BUS_SESSION, &d->error);
00210             break;
00211         case ActivationBus:
00212             c = dbus_bus_get(DBUS_BUS_STARTER, &d->error);
00213             break;
00214     }
00215     d->setConnection(c); //setConnection does the error handling for us
00216 
00217     manager()->setConnection(name, d);
00218 
00219     return TQT_DBusConnection(name);
00220 }
00221 
00222 TQT_DBusConnection TQT_DBusConnection::addConnection(const TQString &address,
00223                     const TQString &name)
00224 {
00225 //    Q_ASSERT_X(TQCoreApplication::instance(), "TQT_DBusConnection::addConnection",
00226 //               "Cannot create connection without a Q[Core]Application instance");
00227 
00228     TQT_DBusConnectionPrivate *d = manager()->connection(name);
00229     if (d)
00230         return TQT_DBusConnection(name);
00231 
00232     d = new TQT_DBusConnectionPrivate;
00233     // setConnection does the error handling for us
00234     d->setConnection(dbus_connection_open(address.utf8().data(), &d->error));
00235 
00236     manager()->setConnection(name, d);
00237 
00238     return TQT_DBusConnection(name);
00239 }
00240 
00241 void TQT_DBusConnection::closeConnection(const TQString &name)
00242 {
00243     manager()->removeConnection(name);
00244 }
00245 
00246 void TQT_DBusConnectionPrivate::timerEvent(TQTimerEvent *e)
00247 {
00248     DBusTimeout *timeout = timeouts[e->timerId()];
00249     dbus_timeout_handle(timeout);
00250 }
00251 
00252 bool TQT_DBusConnection::send(const TQT_DBusMessage &message) const
00253 {
00254     if (!d || !d->connection)
00255         return false;
00256 
00257     DBusMessage *msg = message.toDBusMessage();
00258     if (!msg)
00259         return false;
00260 
00261     bool isOk = dbus_connection_send(d->connection, msg, 0);
00262     dbus_message_unref(msg);
00263     return isOk;
00264 }
00265 
00266 int TQT_DBusConnection::sendWithAsyncReply(const TQT_DBusMessage &message, TQObject *receiver,
00267         const char *method) const
00268 {
00269     if (!d || !d->connection)
00270         return 0;
00271 
00272     return d->sendWithReplyAsync(message, receiver, method);
00273 }
00274 
00275 TQT_DBusMessage TQT_DBusConnection::sendWithReply(const TQT_DBusMessage &message, TQT_DBusError *error) const
00276 {
00277     if (!d || !d->connection)
00278         return TQT_DBusMessage::fromDBusMessage(0);
00279 
00280     DBusMessage *msg = message.toDBusMessage();
00281     if (!msg)
00282         return TQT_DBusMessage::fromDBusMessage(0);
00283 
00284     DBusMessage *reply = dbus_connection_send_with_reply_and_block(d->connection, msg, -1, &d->error);
00285 
00286     if (d->handleError() && error)
00287         *error = d->lastError;
00288 
00289     dbus_message_unref(msg);
00290 
00291     TQT_DBusMessage ret = TQT_DBusMessage::fromDBusMessage(reply);
00292     if (reply) {
00293         dbus_message_unref(reply);
00294     }
00295 
00296     bool dbus_error_set = dbus_error_is_set(&d->error);
00297     ret.d->error.setDBUSError(dbus_error_set);
00298     if (error) error->setDBUSError(dbus_error_set);
00299 
00300     return ret;
00301 }
00302 
00303 void TQT_DBusConnection::flush() const
00304 {
00305     if (!d || !d->connection) return;
00306 
00307     d->flush();
00308 }
00309 
00310 void TQT_DBusConnection::dispatch() const
00311 {
00312     if (!d || !d->connection) return;
00313 
00314     d->dispatch();
00315 }
00316 
00317 void TQT_DBusConnection::scheduleDispatch() const
00318 {
00319     if (!d || !d->connection) return;
00320 
00321     d->scheduleDispatch();
00322 }
00323 
00324 bool TQT_DBusConnection::connect(TQObject* object, const char* slot)
00325 {
00326     if (!d || !d->connection || !object || !slot)
00327         return false;
00328 
00329     bool ok = object->connect(d, TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&)), slot);
00330 
00331     return ok;
00332 }
00333 
00334 bool TQT_DBusConnection::disconnect(TQObject* object, const char* slot)
00335 {
00336     if (!d || !d->connection || !object || !slot)
00337         return false;
00338 
00339     bool ok = d->disconnect(object, slot);
00340 
00341     return ok;
00342 }
00343 
00344 bool TQT_DBusConnection::registerObject(const TQString& path, TQT_DBusObjectBase* object)
00345 {
00346     if (!d || !d->connection || !object || path.isEmpty())
00347         return false;
00348 
00349     TQT_DBusConnectionPrivate::ObjectMap::const_iterator it = d->registeredObjects.find(path);
00350     if (it != d->registeredObjects.end())
00351         return false;
00352 
00353     d->registeredObjects.insert(path, object);
00354 
00355     return true;
00356 }
00357 
00358 void TQT_DBusConnection::unregisterObject(const TQString &path)
00359 {
00360     if (!d || !d->connection || path.isEmpty())
00361         return;
00362 
00363     TQT_DBusConnectionPrivate::ObjectMap::iterator it = d->registeredObjects.find(path);
00364     if (it == d->registeredObjects.end())
00365         return ;
00366 
00367     d->registeredObjects.erase(it);
00368 }
00369 
00370 bool TQT_DBusConnection::isConnected( ) const
00371 {
00372     return d && d->connection && dbus_connection_get_is_connected(d->connection);
00373 }
00374 
00375 TQT_DBusError TQT_DBusConnection::lastError() const
00376 {
00377     return d ? d->lastError : TQT_DBusError();
00378 }
00379 
00380 TQString TQT_DBusConnection::uniqueName() const
00381 {
00382     return d && d->connection ?
00383             TQString::fromUtf8(dbus_bus_get_unique_name(d->connection))
00384             : TQString();
00385 }
00386 
00387 bool TQT_DBusConnection::requestName(const TQString &name, int modeFlags)
00388 {
00389     Q_ASSERT(modeFlags >= 0);
00390 
00391     if (!d || !d->connection)
00392         return false;
00393 
00394     if (modeFlags < 0)
00395         return false;
00396 
00397     int dbusFlags = 0;
00398     if (modeFlags & AllowReplace)
00399         dbusFlags |= DBUS_NAME_FLAG_ALLOW_REPLACEMENT;
00400     if (modeFlags & ReplaceExisting)
00401         dbusFlags |= DBUS_NAME_FLAG_REPLACE_EXISTING;
00402 
00403     dbus_bus_request_name(d->connection, name.utf8(), dbusFlags, &d->error);
00404 
00405     return !d->handleError();
00406 }
00407 
00408 #include "tqdbusconnection.moc"
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines