⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qdbusintegrator.cpp

📁 QT 开发环境里面一个很重要的文件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    }#if USE_OUTSIDE_DISPATCH    dbus_connection_add_filter_outside(connection, qDBusSignalFilter, qDBusSignalFilterOutside, this, 0);#else    dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0);#endif    //qDebug("base service: %s", service);    // schedule a dispatch:    QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection);}extern "C"{static void qDBusResultReceived(DBusPendingCall *pending, void *user_data){    QDBusConnectionPrivate::messageResultReceived(pending, user_data);}}void QDBusConnectionPrivate::messageResultReceived(DBusPendingCall *pending, void *user_data){    QDBusPendingCall *call = reinterpret_cast<QDBusPendingCall *>(user_data);    QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection);    Q_ASSERT(call->pending == pending);    if (!call->receiver.isNull() && call->methodIdx != -1) {        DBusMessage *reply = dbus_pending_call_steal_reply(pending);        // Deliver the return values of a remote function call.        //        // There is only one connection and it is specified by idx        // The slot must have the same parameter types that the message does        // The slot may have less parameters than the message        // The slot may optionally have one final parameter that is QDBusMessage        // The slot receives read-only copies of the message (i.e., pass by value or by const-ref)        QDBusMessage msg = QDBusMessagePrivate::fromDBusMessage(reply);        qDBusDebug() << "got message: " << msg;        CallDeliveryEvent *e = prepareReply(call->receiver, call->methodIdx, call->metaTypes, msg);        if (e)            connection->postCallDeliveryEvent(e);        else            qDBusDebug() << "Deliver failed!";    }    dbus_pending_call_unref(pending);    delete call;}int QDBusConnectionPrivate::send(const QDBusMessage& message) const{    DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message);    if (!msg) {        if (message.type() == QDBusMessage::MethodCallMessage)            qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"",                     qPrintable(message.service()), qPrintable(message.path()),                     qPrintable(message.interface()), qPrintable(message.member()));        else if (message.type() == QDBusMessage::SignalMessage)            qWarning("QDBusConnection: error: could not send signal path \"%s\" interface \"%s\" member \"%s\"",                     qPrintable(message.path()), qPrintable(message.interface()),                     qPrintable(message.member()));        else            qWarning("QDBusConnection: error: could not send %s message to service \"%s\"",                     message.type() == QDBusMessage::ReplyMessage ? "reply" :                     message.type() == QDBusMessage::ErrorMessage ? "error" :                     "invalid", qPrintable(message.service()));        return 0;    }    dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything    qDBusDebug() << "sending message:" << message;    bool isOk = dbus_connection_send(connection, msg, 0);    int serial = 0;    if (isOk)        serial = dbus_message_get_serial(msg);    dbus_message_unref(msg);    return serial;}QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,                                                   int sendMode, int timeout){    // special case for synchronous local calls    const bool localBlockingCall = ((sendMode == QDBus::BlockWithGui || sendMode == QDBus::Block)                                    && isServiceRegisteredByThread(message.service()));    if (!QCoreApplication::instance() || sendMode == QDBus::Block || localBlockingCall) {        DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message);        if (!msg) {            qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"",                     qPrintable(message.service()), qPrintable(message.path()),                     qPrintable(message.interface()), qPrintable(message.member()));            return QDBusMessage();        }        if (localBlockingCall) {	  QDBusMessage messageWithSignature = QDBusMessagePrivate::updateSignature(message, msg);	  QDBusMessagePrivate::setLocal(&messageWithSignature, true);	  bool handled = false;            int type = dbus_message_get_type(msg);	  if (type == DBUS_MESSAGE_TYPE_SIGNAL)	      handled = handleSignal(messageWithSignature);	  else if (type == DBUS_MESSAGE_TYPE_METHOD_CALL)	      handled = handleObjectCall(messageWithSignature);	  if (!handled)                handled = activateInternalFilters(&rootNode, message);            if (handled) {                return messageWithSignature;            } else {                return QDBusMessage::createError(                        QString::fromLocal8Bit("InternalError"),                        QString::fromLocal8Bit("the sender and receiver are in the same thread"));            }        } else {	  QDBusMessage amsg;	  qDBusDebug() << "sending message:" << message;            DBusMessage *reply = dbus_connection_send_with_reply_and_block(connection, msg, timeout, &error);            handleError();            dbus_message_unref(msg);            if (lastError.isValid())                return QDBusMessagePrivate::fromError(lastError);            amsg = QDBusMessagePrivate::fromDBusMessage(reply);            dbus_message_unref(reply);            qDBusDebug() << "got message:" << amsg;            if (dbus_connection_get_dispatch_status(connection) == DBUS_DISPATCH_DATA_REMAINS)                QMetaObject::invokeMethod(this, "doDispatch", Qt::QueuedConnection);            return amsg;        }    } else { // use the event loop        QDBusReplyWaiter waiter;        if (sendWithReplyAsync(message, &waiter, SLOT(reply(QDBusMessage)), timeout) > 0) {            // enter the event loop and wait for a reply            waiter.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents);            lastError = waiter.replyMsg; // set or clear error            return waiter.replyMsg;        }        return QDBusMessage();    }}int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,                                               const char *method, int timeout){    if (!receiver || !method || !*method) {        // would not be able to deliver a reply        qWarning("QDBusConnection::sendWithReplyAsync: error: cannot deliver a reply to %s::%s (%s)",                 receiver ? receiver->metaObject()->className() : "(null)",                 method ? method + 1 : "(null)",                 receiver ? qPrintable(receiver->objectName()) : "no name");        return send(message);    }    int slotIdx = -1;    QList<int> metaTypes;    slotIdx = findSlot(receiver, method + 1, metaTypes);    if (slotIdx == -1) {        QByteArray normalizedName = QMetaObject::normalizedSignature(method + 1);        slotIdx = findSlot(receiver, normalizedName, metaTypes);    }    if (slotIdx == -1) {        // would not be able to deliver a reply        qWarning("QDBusConnection::sendWithReplyAsync: error: cannot deliver a reply to %s::%s (%s)",                 receiver->metaObject()->className(),                 method + 1, qPrintable(receiver->objectName()));        return send(message);    }    DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message);    if (!msg) {        qWarning("QDBusConnection: error: could not send message to service \"%s\" path \"%s\" interface \"%s\" member \"%s\"",                 qPrintable(message.service()), qPrintable(message.path()),                 qPrintable(message.interface()), qPrintable(message.member()));        return 0;    }    qDBusDebug() << "sending message:" << message;    DBusPendingCall *pending = 0;    if (dbus_connection_send_with_reply(connection, msg, &pending, timeout)) {        int serial = dbus_message_get_serial(msg);        dbus_message_unref(msg);        QDBusPendingCall *pcall = new QDBusPendingCall;        pcall->receiver = receiver;        pcall->metaTypes = metaTypes;        pcall->methodIdx = slotIdx;        pcall->connection = this;        pcall->pending = pending;        dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0);        return serial;    }    dbus_message_unref(msg);    return 0;}void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook &hook){    signalHooks.insertMulti(key, hook);    connect(hook.obj, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*)));}void QDBusConnectionPrivate::disconnectSignal(const QString &key, const SignalHook &hook){    hook.obj->disconnect(SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*)));    signalHooks.remove(key);}void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node){    connect(node->obj, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*)));    if (node->flags & (QDBusConnection::ExportAdaptors                       | QDBusConnection::ExportScriptableSignals                       | QDBusConnection::ExportNonScriptableSignals)) {        QDBusAdaptorConnector *connector = qDBusCreateAdaptorConnector(node->obj);        if (node->flags & (QDBusConnection::ExportScriptableSignals                           | QDBusConnection::ExportNonScriptableSignals)) {            connector->disconnectAllSignals(node->obj);            connector->connectAllSignals(node->obj);        }        // disconnect and reconnect to avoid duplicates        connector->disconnect(SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)),                              this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList)));        connect(connector, SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)),                this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList)));    }}void QDBusConnectionPrivate::connectRelay(const QString &service, const QString &path,                                          const QString &interface,                                          QDBusAbstractInterface *receiver,                                          const char *signal){    // this function is called by QDBusAbstractInterface when one of its signals is connected    // we set up a relay from D-Bus into it    SignalHook hook;    QString key;    QString owner = getNameOwner(service);    if (!prepareHook(hook, key, service, owner, path, interface, QString(), receiver, signal,                     QDBusAbstractInterface::staticMetaObject.methodCount(), true))        return;                 // don't connect    // add it to our list:    QWriteLocker locker(&lock);    SignalHookHash::ConstIterator it = signalHooks.find(key);    SignalHookHash::ConstIterator end = signalHooks.constEnd();    for ( ; it != end && it.key() == key; ++it) {        const SignalHook &entry = it.value();        if (entry.service == hook.service &&            entry.owner == hook.owner &&            entry.path == hook.path &&            entry.signature == hook.signature &&            entry.obj == hook.obj &&            entry.midx == hook.midx)            return;             // already there, no need to re-add    }    connectSignal(key, hook);}void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QString &path,                                             const QString &interface,                                             QDBusAbstractInterface *receiver,                                             const char *signal){    // this function is called by QDBusAbstractInterface when one of its signals is disconnected    // we remove relay from D-Bus into it    SignalHook hook;    QString key;    QString owner = getNameOwner(service);    if (!prepareHook(hook, key, service, owner, path, interface, QString(), receiver, signal,                     QDBusAbstractInterface::staticMetaObject.methodCount(), true))        return;                 // don't connect    // remove it from our list:    QWriteLocker locker(&lock);    SignalHookHash::Iterator it = signalHooks.find(key);    SignalHookHash::Iterator end = signalHooks.end();    for ( ; it != end && it.key() == key; ++it) {        const SignalHook &entry = it.value();        if (entry.service == hook.service &&            entry.owner == hook.owner &&            entry.path == hook.path &&            entry.signature == hook.signature &&            entry.obj == hook.obj &&            entry.midx == hook.midx) {            // found it            signalHooks.erase(it);            return;        }    }    qWarning("QDBusConnectionPrivate::disconnectRelay called for a signal that was not found");}QString QDBusConnectionPrivate::getNameOwner(const QString& serviceName){    if (QDBusUtil::isValidUniqueConnectionName(serviceName))        return serviceName;    if (!connection || !QDBusUtil::isValidBusName(serviceName))        return QString();    QDBusMessage msg = QDBusMessage::createMethodCall(QLatin1String(DBUS_SERVICE_DBUS),            QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS),            QLatin1String("GetNameOwner"));    msg << serviceName;    QDBusMessage reply = sendWithReply(msg, QDBus::Block);    if (!lastError.isValid() && reply.type() == QDBusMessage::ReplyMessage)        return reply.arguments().at(0).toString();    return QString();}struct qdbus_Introspect{    QString xml;    inline void operator()(QDBusConnectionPrivate::ObjectTreeNode *node)  { xml = qDBusIntrospectObject(node); }};QDBusMetaObject *QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &path,                                       const QString &interface){    // service must be a unique connection name    if (!interface.isEmpty()) {        QReadLocker locker(&lock);        QDBusMetaObject *mo = cachedMetaObjects.value(interface, 0);        if (mo)            return mo;    }    if (service == QLatin1String(dbus_bus_get_unique_name(connection))) {        // it's one of our own        QWriteLocker locker(&lock);        QDBusMetaObject *mo = 0;        if (!interface.isEmpty())            mo = cachedMetaObjects.value(interface, 0);        if (mo)            // maybe it got created when we switched from read to write lock            return mo;        qdbus_Introspect apply;        if (!applyForObject(&rootNode, path, apply)) {            lastError = QDBusError(QDBusError::InvalidArgs,                                   QString(QLatin1String("No object at %1")).arg(path));            return 0;           // no object at path        }        // release the lock and return        return QDBusMetaObject::createMetaObject(interface, apply.xml, cachedMetaObjects, lastError);    }    // not local: introspect the target object:    QDBusMessage msg = QDBusMessage::createMethodCall(service, path,                                                QLatin1String(DBUS_INTERFACE_INTROSPECTABLE),                                                QLatin1String("Introspect"));    QDBusMessage reply = sendWithReply(msg, QDBus::Block);    // it doesn't exist yet, we have to create it    QWriteLocker locker(&lock);    QDBusMetaObject *mo = 0;    if (!interface.isEmpty())        mo = cachedMetaObjects.value(interface, 0);    if (mo)        // maybe it got created when we switched from read to write lock        return mo;    QString xml;    if (reply.type() == QDBusMessage::ReplyMessage)        // fetch the XML description        xml = reply.arguments().at(0).toString();    else {        lastError = reply;        if (reply.type() != QDBusMessage::ErrorMessage || lastError.type() != QDBusError::UnknownMethod)            return 0; // error    }    // release the lock and return    return QDBusMetaObject::createMetaObject(interface, xml, cachedMetaObjects, lastError);}void QDBusConnectionPrivate::registerService(const QString &serviceName){    qDBusServicesRegisteredByThread()->append(serviceName);}void QDBusConnectionPrivate::unregisterService(const QString &serviceName){    qDBusServicesRegisteredByThread()->removeAll(serviceName);}bool QDBusConnectionPrivate::isServiceRegisteredByThread(const QString &serviceName) const{    return (serviceName == baseService() || qDBusServicesRegisteredByThread()->contains(serviceName));}QString QDBusConnectionPrivate::baseService() const{    return connection ?           QString::fromUtf8(dbus_bus_get_unique_name(connection))           : QString();}void QDBusReplyWaiter::reply(const QDBusMessage &msg){    replyMsg = msg;    quit();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -