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

📄 qdbusintegrator.cpp

📁 QT 开发环境里面一个很重要的文件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), QLatin1String(interface),                                                      QLatin1String(memberName));    message.setArguments(args);    DBusMessage *msg = QDBusMessagePrivate::toDBusMessage(message);    if (!msg) {        qWarning("QDBusConnection: Could not emit signal %s.%s", interface, memberName.constData());        return;    }    //qDBusDebug() << "Emitting signal" << message;    //qDBusDebug() << "for paths:";    dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything    huntAndEmit(connection, msg, obj, &rootNode, isScriptable, isAdaptor);    dbus_message_unref(msg);}void QDBusConnectionPrivate::_q_serviceOwnerChanged(const QString &name,                                                    const QString &oldOwner, const QString &newOwner){    Q_UNUSED(oldOwner);    if (isServiceRegisteredByThread(oldOwner))        unregisterService(name);    if (isServiceRegisteredByThread(newOwner))        registerService(name);    QMutableHashIterator<QString, SignalHook> it(signalHooks);    it.toFront();    while (it.hasNext())        if (it.next().value().service == name)            it.value().owner = newOwner;}int QDBusConnectionPrivate::findSlot(QObject* obj, const QByteArray &normalizedName,                                     QList<int> &params){    int midx = obj->metaObject()->indexOfMethod(normalizedName);    if (midx == -1)        return -1;    int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params);    if ( inputCount == -1 || inputCount + 1 != params.count() )        return -1;              // failed to parse or invalid arguments or output arguments    return midx;}bool QDBusConnectionPrivate::prepareHook(QDBusConnectionPrivate::SignalHook &hook, QString &key,                                         const QString &service, const QString &owner,                                         const QString &path, const QString &interface, const QString &name,                                         QObject *receiver, const char *signal, int minMIdx,                                         bool buildSignature){    QByteArray normalizedName = signal + 1;    hook.midx = findSlot(receiver, signal + 1, hook.params);    if (hook.midx == -1) {        normalizedName = QMetaObject::normalizedSignature(signal + 1);        hook.midx = findSlot(receiver, normalizedName, hook.params);    }    if (hook.midx < minMIdx) {        if (hook.midx == -1)            ;//qWarning("No such slot '%s' while connecting D-Bus", normalizedName.constData());        return false;    }    hook.service = service;    hook.owner = owner; // we don't care if the service has an owner yet    hook.path = path;    hook.obj = receiver;    // build the D-Bus signal name and signature    // This should not happen for QDBusConnection::connect, use buildSignature here, since    // QDBusConnection::connect passes false and everything else uses true    QString mname = name;    if (buildSignature && mname.isNull()) {        normalizedName.truncate(normalizedName.indexOf('('));        mname = QString::fromUtf8(normalizedName);    }    key = mname;    key.reserve(interface.length() + 1 + mname.length());    key += QLatin1Char(':');    key += interface;    if (buildSignature) {        hook.signature.clear();        for (int i = 1; i < hook.params.count(); ++i)            if (hook.params.at(i) != QDBusMetaTypeId::message)                hook.signature += QLatin1String( QDBusMetaType::typeToSignature( hook.params.at(i) ) );    }    return true;                // connect to this signal}bool QDBusConnectionPrivate::activateInternalFilters(const ObjectTreeNode *node, const QDBusMessage &msg){    // object may be null    if (msg.interface().isEmpty() || msg.interface() == QLatin1String(DBUS_INTERFACE_INTROSPECTABLE)) {        if (msg.member() == QLatin1String("Introspect") && msg.signature().isEmpty()) {            //qDebug() << "QDBusConnectionPrivate::activateInternalFilters introspect" << msg.d_ptr->msg;            QDBusMessage reply = msg.createReply(qDBusIntrospectObject(node));            if (QDBusMessagePrivate::isLocal(msg)) {                QDBusMessagePrivate::setType(&msg, reply.type());                QDBusMessagePrivate::setArguments(&msg, QVariantList() << qDBusIntrospectObject(node));            } else {                send(reply);            }        }        if (msg.interface() == QLatin1String(DBUS_INTERFACE_INTROSPECTABLE))            return true;    }    if (node->obj && (msg.interface().isEmpty() ||                      msg.interface() == QLatin1String(DBUS_INTERFACE_PROPERTIES))) {        //qDebug() << "QDBusConnectionPrivate::activateInternalFilters properties" << msg.d_ptr->msg;        if (msg.member() == QLatin1String("Get") && msg.signature() == QLatin1String("ss")) {            QDBusMessage reply = qDBusPropertyGet(node, msg);            if (QDBusMessagePrivate::isLocal(msg)) {                QDBusMessagePrivate::setType(&msg, reply.type());                QDBusMessagePrivate::setArguments(&msg, reply.arguments());            } else {                send(reply);            }        } else if (msg.member() == QLatin1String("Set") && msg.signature() == QLatin1String("ssv")) {            QDBusMessage reply = qDBusPropertySet(node, msg);            if (QDBusMessagePrivate::isLocal(msg)) {                QDBusMessagePrivate::setType(&msg, reply.type());                QDBusMessagePrivate::setArguments(&msg, reply.arguments());            } else {                send(reply);            }        }        if (msg.interface() == QLatin1String(DBUS_INTERFACE_PROPERTIES))            return true;    }    return false;}bool QDBusConnectionPrivate::activateObject(const ObjectTreeNode *node, const QDBusMessage &msg){    // This is called by QDBusConnectionPrivate::handleObjectCall to place a call to a slot    // on the object.    //    // The call is routed through the adaptor sub-objects if we have any    // object may be null    QDBusAdaptorConnector *connector;    if (node->flags & QDBusConnection::ExportAdaptors &&        (connector = qDBusFindAdaptorConnector(node->obj))) {        int newflags = node->flags | QDBusConnection::ExportNonScriptableSlots;        if (msg.interface().isEmpty()) {            // place the call in all interfaces            // let the first one that handles it to work            QDBusAdaptorConnector::AdaptorMap::ConstIterator it =                connector->adaptors.constBegin();            QDBusAdaptorConnector::AdaptorMap::ConstIterator end =                connector->adaptors.constEnd();            for ( ; it != end; ++it)                if (activateCall(it->adaptor, newflags, msg))                    return true;        } else {            // check if we have an interface matching the name that was asked:            QDBusAdaptorConnector::AdaptorMap::ConstIterator it;            it = qLowerBound(connector->adaptors.constBegin(), connector->adaptors.constEnd(),                             msg.interface());            if (it != connector->adaptors.constEnd() && msg.interface() == QLatin1String(it->interface))                if (activateCall(it->adaptor, newflags, msg))                return true;        }    }    // no adaptors matched or were exported    // try our standard filters    if (activateInternalFilters(node, msg))        return true;    // try the object itself:    if (node->flags & (QDBusConnection::ExportScriptableSlots|QDBusConnection::ExportNonScriptableSlots) &&        activateCall(node->obj, node->flags, msg)) {        return true;    }#if 0    // nothing matched    qDebug("Call failed: no match for %s%s%s at %s",           qPrintable(msg.interface()), msg.interface().isEmpty() ? "" : ".",           qPrintable(msg.signature()),           qPrintable(msg.path()));#endif    return false;}template<typename Func>static bool applyForObject(QDBusConnectionPrivate::ObjectTreeNode *root, const QString &fullpath,                           Func& functor){    // walk the object tree    QStringList path = fullpath.split(QLatin1Char('/'));    if (path.last().isEmpty())        path.removeLast();      // happens if path is "/"    int i = 1;    QDBusConnectionPrivate::ObjectTreeNode *node = root;    // try our own tree first    while (node && !(node->flags & QDBusConnection::ExportChildObjects) ) {        if (i == path.count()) {            // found our object            functor(node);            return true;        }        QVector<QDBusConnectionPrivate::ObjectTreeNode::Data>::ConstIterator it =            qLowerBound(node->children.constBegin(), node->children.constEnd(), path.at(i));        if (it != node->children.constEnd() && it->name == path.at(i))            // match            node = it->node;        else            node = 0;        ++i;    }    // any object in the tree can tell us to switch to its own object tree:    if (node && node->flags & QDBusConnection::ExportChildObjects) {        QObject *obj = node->obj;        while (obj) {            if (i == path.count()) {                // we're at the correct level                QDBusConnectionPrivate::ObjectTreeNode fakenode(*node);                fakenode.obj = obj;                functor(&fakenode);                return true;            }            const QObjectList children = obj->children();            // find a child with the proper name            QObject *next = 0;            QObjectList::ConstIterator it = children.constBegin();            QObjectList::ConstIterator end = children.constEnd();            for ( ; it != end; ++it)                if ((*it)->objectName() == path.at(i)) {                    next = *it;                    break;                }            if (!next)                break;            ++i;            obj = next;        }    }    // object not found    return false;}#if 0struct qdbus_callObject{    QDBusConnectionPrivate *self;    const QDBusMessage &msg;    bool returnVal;    inline qdbus_callObject(QDBusConnectionPrivate *s, const QDBusMessage &m)        : self(s), msg(m), returnVal(false)    { }    inline void operator()(QDBusConnectionPrivate::ObjectTreeNode *node)    { }};bool QDBusConnectionPrivate::doDirectObjectCall(const QDBusMessage &msg){    QReadLocker locker(&lock);    qdbus_callObject call(this, msg);    if (applyForObject(&rootNode, msg.path(), call))        return call.returnVal;    // qDebug("Call failed: no object found at %s", qPrintable(msg.path()));    return false;}#endifstruct qdbus_activateObject{    QDBusConnectionPrivate *self;    const QDBusMessage &msg;    bool returnVal;    inline qdbus_activateObject(QDBusConnectionPrivate *s, const QDBusMessage &m)        : self(s), msg(m), returnVal(false)    { }    inline void operator()(QDBusConnectionPrivate::ObjectTreeNode *node)    { returnVal = self->activateObject(node, msg); }};bool QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg){    QReadLocker locker(&lock);    qdbus_activateObject apply(this, msg);    if (applyForObject(&rootNode, msg.path(), apply))        return apply.returnVal;    // qDebug("Call failed: no object found at %s", qPrintable(msg.path()));    return false;}bool QDBusConnectionPrivate::handleSignal(const QString &key, const QDBusMessage& msg){    bool result = false;    SignalHookHash::const_iterator it = signalHooks.find(key);    SignalHookHash::const_iterator end = signalHooks.constEnd();    //qDebug("looking for: %s", path.toLocal8Bit().constData());    //qDBusDebug() << signalHooks.keys();    for ( ; it != end && it.key() == key; ++it) {        const SignalHook &hook = it.value();        if (!hook.owner.isEmpty() && hook.owner != msg.service())            continue;        if (!hook.path.isEmpty() && hook.path != msg.path())            continue;        if (!hook.signature.isEmpty() && hook.signature != msg.signature())            continue;        if (hook.signature.isEmpty() && !hook.signature.isNull() && !msg.signature().isEmpty())            continue;        // yes, |=        result |= activateSignal(hook, msg);    }    return result;}bool QDBusConnectionPrivate::handleSignal(const QDBusMessage& msg){    // We call handlesignal(QString, QDBusMessage) three times:    //  one with member:interface    //  one with member:    //  one with :interface    // This allows us to match signals with wildcards on member or interface    // (but not both)    QString key = msg.member();    key.reserve(key.length() + 1 + msg.interface().length());    key += QLatin1Char(':');    key += msg.interface();    QReadLocker locker(&lock);    bool result = handleSignal(key, msg);    // one try    key.truncate(msg.member().length() + 1); // keep the ':'    result |= handleSignal(key, msg);        // second try    key = QLatin1Char(':');    key += msg.interface();    result |= handleSignal(key, msg);        // third try    return result;}static dbus_int32_t server_slot = -1;void QDBusConnectionPrivate::setServer(DBusServer *s){    if (!server) {        handleError();        return;    }    server = s;    mode = ServerMode;    dbus_server_allocate_data_slot(&server_slot);    if (server_slot < 0)        return;    dbus_server_set_watch_functions(server, qDBusAddWatch, qDBusRemoveWatch,                                    qDBusToggleWatch, this, 0); // ### check return type?    dbus_server_set_timeout_functions(server, qDBusAddTimeout, qDBusRemoveTimeout,                                      qDBusToggleTimeout, this, 0);    dbus_server_set_new_connection_function(server, qDBusNewConnection, this, 0);    dbus_server_set_data(server, server_slot, this, 0);}void QDBusConnectionPrivate::setConnection(DBusConnection *dbc){    if (!dbc) {        handleError();        return;    }    connection = dbc;    mode = ClientMode;    dbus_connection_set_exit_on_disconnect(connection, false);    dbus_connection_set_watch_functions(connection, qDBusAddWatch, qDBusRemoveWatch,                                        qDBusToggleWatch, this, 0);    dbus_connection_set_timeout_functions(connection, qDBusAddTimeout, qDBusRemoveTimeout,                                          qDBusToggleTimeout, this, 0);//    dbus_bus_add_match(connection, "type='signal',interface='com.trolltech.dbus.Signal'", &error);//    dbus_bus_add_match(connection, "type='signal'", &error);    dbus_bus_add_match(connection, "type='signal'", &error);    if (handleError()) {        closeConnection();        return;    }    const char *service = dbus_bus_get_unique_name(connection);    if (service) {        QVarLengthArray<char, 56> filter;        filter.append("destination='", 13);        filter.append(service, qstrlen(service));        filter.append("\'\0", 2);        dbus_bus_add_match(connection, filter.constData(), &error);        if (handleError()) {            closeConnection();            return;        }    } else {        qWarning("QDBusConnectionPrivate::SetConnection: Unable to get base service");

⌨️ 快捷键说明

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