|
DBus-1-TQt
1.0
|
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"