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

📄 qdbusintegrator.cpp

📁 QT 开发环境里面一个很重要的文件
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the tools applications of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <qcoreapplication.h>#include <qcoreevent.h>#include <qdebug.h>#include <qmetaobject.h>#include <qobject.h>#include <qsocketnotifier.h>#include <qstringlist.h>#include <qtimer.h>#include "qdbusargument.h"#include "qdbusconnection_p.h"#include "qdbusinterface_p.h"#include "qdbusmessage.h"#include "qdbusmetatype.h"#include "qdbusmetatype_p.h"#include "qdbusabstractadaptor.h"#include "qdbusabstractadaptor_p.h"#include "qdbusutil_p.h"#include "qdbusmessage_p.h"static bool isDebugging;#define qDBusDebug              if (!::isDebugging); else qDebug#ifndef USE_OUTSIDE_DISPATCH# define USE_OUTSIDE_DISPATCH    0#endiftypedef void (*QDBusSpyHook)(const QDBusMessage&);typedef QVarLengthArray<QDBusSpyHook, 4> QDBusSpyHookList;Q_GLOBAL_STATIC(QDBusSpyHookList, qDBusSpyHookList)Q_GLOBAL_STATIC(QStringList, qDBusServicesRegisteredByThread)struct QDBusPendingCall{    QPointer<QObject> receiver;    QList<int> metaTypes;    int methodIdx;    DBusPendingCall *pending;    const QDBusConnectionPrivate *connection;};class CallDeliveryEvent: public QEvent{public:    CallDeliveryEvent()        : QEvent(QEvent::User), object(0), flags(0), slotIdx(-1)        { }    const QDBusConnectionPrivate *conn;    QPointer<QObject> object;    QDBusMessage message;    QList<int> metaTypes;    int flags;    int slotIdx;};static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data){    Q_ASSERT(timeout);    Q_ASSERT(data);  //  qDebug("addTimeout %d", dbus_timeout_get_interval(timeout));    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);    if (!dbus_timeout_get_enabled(timeout))        return true;    if (!QCoreApplication::instance()) {        d->pendingTimeouts.append(timeout);        return true;    }    int timerId = d->startTimer(dbus_timeout_get_interval(timeout));    if (!timerId)        return false;    d->timeouts[timerId] = timeout;    return true;}static void qDBusRemoveTimeout(DBusTimeout *timeout, void *data){    Q_ASSERT(timeout);    Q_ASSERT(data);  //  qDebug("removeTimeout");    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);    d->pendingTimeouts.removeAll(timeout);    QDBusConnectionPrivate::TimeoutHash::iterator it = d->timeouts.begin();    while (it != d->timeouts.end()) {        if (it.value() == timeout) {            d->killTimer(it.key());            it = d->timeouts.erase(it);        } else {            ++it;        }    }}static void qDBusToggleTimeout(DBusTimeout *timeout, void *data){    Q_ASSERT(timeout);    Q_ASSERT(data);    //qDebug("ToggleTimeout");    qDBusRemoveTimeout(timeout, data);    qDBusAddTimeout(timeout, data);}static dbus_bool_t qDBusAddWatch(DBusWatch *watch, void *data){    Q_ASSERT(watch);    Q_ASSERT(data);    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);    int flags = dbus_watch_get_flags(watch);    int fd = dbus_watch_get_fd(watch);    QDBusConnectionPrivate::Watcher watcher;    if (flags & DBUS_WATCH_READABLE) {        //qDebug("addReadWatch %d", fd);        watcher.watch = watch;        if (QCoreApplication::instance()) {            watcher.read = new QSocketNotifier(fd, QSocketNotifier::Read, d);            watcher.read->setEnabled(dbus_watch_get_enabled(watch));            d->connect(watcher.read, SIGNAL(activated(int)), SLOT(socketRead(int)));        }    }    if (flags & DBUS_WATCH_WRITABLE) {        //qDebug("addWriteWatch %d", fd);        watcher.watch = watch;        if (QCoreApplication::instance()) {            watcher.write = new QSocketNotifier(fd, QSocketNotifier::Write, d);            watcher.write->setEnabled(dbus_watch_get_enabled(watch));            d->connect(watcher.write, SIGNAL(activated(int)), SLOT(socketWrite(int)));        }    }    d->watchers.insertMulti(fd, watcher);    return true;}static void qDBusRemoveWatch(DBusWatch *watch, void *data){    Q_ASSERT(watch);    Q_ASSERT(data);    //qDebug("remove watch");    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);    int fd = dbus_watch_get_fd(watch);    QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);    while (i != d->watchers.end() && i.key() == fd) {        if (i.value().watch == watch) {            delete i.value().read;            delete i.value().write;            d->watchers.erase(i);            return;        }        ++i;    }}static void qDBusToggleWatch(DBusWatch *watch, void *data){    Q_ASSERT(watch);    Q_ASSERT(data);    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);    int fd = dbus_watch_get_fd(watch);    QDBusConnectionPrivate::WatcherHash::iterator i = d->watchers.find(fd);    while (i != d->watchers.end() && i.key() == fd) {        if (i.value().watch == watch) {            bool enabled = dbus_watch_get_enabled(watch);            int flags = dbus_watch_get_flags(watch);            //qDebug("toggle watch %d to %d (write: %d, read: %d)", dbus_watch_get_fd(watch), enabled, flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE);            if (flags & DBUS_WATCH_READABLE && i.value().read)                i.value().read->setEnabled(enabled);            if (flags & DBUS_WATCH_WRITABLE && i.value().write)                i.value().write->setEnabled(enabled);            return;        }        ++i;    }}static void qDBusNewConnection(DBusServer *server, DBusConnection *c, void *data){    Q_ASSERT(data); Q_ASSERT(server); Q_ASSERT(c);    Q_UNUSED(data); Q_UNUSED(server); Q_UNUSED(c);    qDebug("SERVER: GOT A NEW CONNECTION"); // TODO}extern QDBUS_EXPORT void qDBusAddSpyHook(QDBusSpyHook);void qDBusAddSpyHook(QDBusSpyHook hook){    qDBusSpyHookList()->append(hook);}#if USE_OUTSIDE_DISPATCH# define HANDLED     DBUS_HANDLER_RESULT_HANDLED_OUTSIDE_DISPATCHstatic DBusHandlerResult qDBusSignalFilterOutside(DBusConnection *connection,                                                  DBusMessage *message, void *data){    Q_ASSERT(data);    Q_UNUSED(connection);    Q_UNUSED(message);    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);    if (d->mode == QDBusConnectionPrivate::InvalidMode)        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; // internal error, actually    CallDeliveryEvent *e = d->postedCallDeliveryEvent();    d->deliverCall(*e);    delete e;    return DBUS_HANDLER_RESULT_HANDLED;}#else# define HANDLED     DBUS_HANDLER_RESULT_HANDLED#endifextern "C" {static DBusHandlerResultqDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data){    return QDBusConnectionPrivate::messageFilter(connection, message, data);}}DBusHandlerResult QDBusConnectionPrivate::messageFilter(DBusConnection *connection,                                                        DBusMessage *message, void *data){    Q_ASSERT(data);    Q_UNUSED(connection);    QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);    if (d->mode == QDBusConnectionPrivate::InvalidMode)        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;    QDBusMessage amsg = QDBusMessagePrivate::fromDBusMessage(message);    qDBusDebug() << "got message:" << amsg;    const QDBusSpyHookList *list = qDBusSpyHookList();    for (int i = 0; i < list->size(); ++i) {        qDBusDebug() << "calling the message spy hook";        (*(*list)[i])(amsg);    }    bool handled = false;    int msgType = dbus_message_get_type(message);    if (msgType == DBUS_MESSAGE_TYPE_SIGNAL) {        handled = d->handleSignal(amsg);    } else if (msgType == DBUS_MESSAGE_TYPE_METHOD_CALL) {        handled = d->handleObjectCall(amsg);    }    return handled ? HANDLED :        DBUS_HANDLER_RESULT_NOT_YET_HANDLED;}static void huntAndDestroy(QObject *needle, QDBusConnectionPrivate::ObjectTreeNode *haystack){    QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it = haystack->children.constBegin();    QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator end = haystack->children.constEnd();    for ( ; it != end; ++it)        huntAndDestroy(needle, it->node);    if (needle == haystack->obj) {        haystack->obj = 0;        haystack->flags = 0;    }}static void huntAndEmit(DBusConnection *connection, DBusMessage *msg,                        QObject *needle, QDBusConnectionPrivate::ObjectTreeNode *haystack,                        bool isScriptable, bool isAdaptor, const QString &path = QString()){    QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it = haystack->children.constBegin();    QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator end = haystack->children.constEnd();    for ( ; it != end; ++it)        huntAndEmit(connection, msg, needle, it->node, isScriptable, isAdaptor, path + QLatin1String("/") + it->name);    if (needle == haystack->obj) {        // is this a signal we should relay?        if (isAdaptor && (haystack->flags & QDBusConnection::ExportAdaptors) == 0)            return;             // no: it comes from an adaptor and we're not exporting adaptors        else if (!isAdaptor) {            int mask = isScriptable                       ? QDBusConnection::ExportScriptableSignals                       : QDBusConnection::ExportNonScriptableSignals;            if ((haystack->flags & mask) == 0)                return;         // signal was not exported        }        QByteArray p = path.toLatin1();        if (p.isEmpty())            p = "/";        qDBusDebug() << "Emitting signal at " << p;        DBusMessage *msg2 = dbus_message_copy(msg);        dbus_message_set_path(msg2, p);        dbus_connection_send(connection, msg2, 0);        dbus_message_unref(msg2);    }}static int findSlot(const QMetaObject *mo, const QByteArray &name, int flags,                    const QString &signature_, QList<int>& metaTypes){    QByteArray msgSignature = signature_.toLatin1();    for (int idx = mo->methodCount() - 1 ; idx >= QObject::staticMetaObject.methodCount(); --idx) {        QMetaMethod mm = mo->method(idx);        // check access:        if (mm.access() != QMetaMethod::Public)            continue;        // check type:        // unnecessary, since signals are never public:        //if (mm.methodType() != QMetaMethod::Slot)        //    continue;        // check name:        QByteArray slotname = mm.signature();        int paren = slotname.indexOf('(');        if (paren != name.length() || !slotname.startsWith(name))            continue;        int returnType = qDBusNameToTypeId(mm.typeName());        bool isAsync = qDBusCheckAsyncTag(mm.tag());        bool isScriptable = mm.attributes() & QMetaMethod::Scriptable;        // consistency check:        if (isAsync && returnType != QMetaType::Void)            continue;        int inputCount = qDBusParametersForMethod(mm, metaTypes);        if (inputCount == -1)            continue;           // problem parsing        metaTypes[0] = returnType;        bool hasMessage = false;        if (inputCount > 0 &&            metaTypes.at(inputCount) == QDBusMetaTypeId::message) {            // "no input parameters" is allowed as long as the message meta type is there            hasMessage = true;            --inputCount;        }        // try to match the parameters        int i;        QByteArray reconstructedSignature;        for (i = 1; i <= inputCount; ++i) {            const char *typeSignature = QDBusMetaType::typeToSignature( metaTypes.at(i) );            if (!typeSignature)                break;          // invalid            reconstructedSignature += typeSignature;            if (!msgSignature.startsWith(reconstructedSignature))                break;        }        if (reconstructedSignature != msgSignature)            continue;           // we didn't match them all        if (hasMessage)            ++i;        // make sure that the output parameters have signatures too        if (returnType != 0 && QDBusMetaType::typeToSignature(returnType) == 0)            continue;        bool ok = true;        for (int j = i; ok && j < metaTypes.count(); ++j)            if (QDBusMetaType::typeToSignature(metaTypes.at(i)) == 0)                ok = false;        if (!ok)            continue;        // consistency check:        if (isAsync && metaTypes.count() > i + 1)            continue;        if (isScriptable && (flags & QDBusConnection::ExportScriptableSlots) == 0)            continue;           // not exported        if (!isScriptable && (flags & QDBusConnection::ExportNonScriptableSlots) == 0)            continue;           // not exported        // if we got here, this slot matched        return idx;    }    // no slot matched    return -1;

⌨️ 快捷键说明

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