mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 20:27:59 +02:00
Merge the changes to the bindings from the KDE Subversion server.
This is a major change: library is source- and binary-incompatible to what it used to be. All testcases are green, functionality is preserved. It is not feature-complete. Development will continue in the branch in the Subversion server for a while.
This commit is contained in:
parent
120d4ae484
commit
c2432800b1
36 changed files with 5769 additions and 491 deletions
|
|
@ -6,11 +6,19 @@ dbusincludedir=$(includedir)/dbus-1.0/dbus
|
|||
lib_LTLIBRARIES=libdbus-qt4-1.la
|
||||
|
||||
dbusinclude_HEADERS= \
|
||||
qdbuserror.h \
|
||||
qdbusmessage.h \
|
||||
qdbusserver.h \
|
||||
qdbusmacros.h \
|
||||
qdbuserror.h \
|
||||
qdbusmessage.h \
|
||||
qdbusserver.h \
|
||||
qdbusconnection.h \
|
||||
qdbusvariant.h
|
||||
qdbusvariant.h \
|
||||
qdbusobject.h \
|
||||
qdbusinterface.h \
|
||||
qdbustype.h \
|
||||
qdbusstandardinterfaces.h \
|
||||
qdbusutil.h \
|
||||
qdbusintrospection.h \
|
||||
qdbusabstractadaptor.h
|
||||
|
||||
libdbus_qt4_1_la_SOURCES = \
|
||||
$(top_srcdir)/qt/qdbusconnection.cpp \
|
||||
|
|
@ -19,29 +27,46 @@ libdbus_qt4_1_la_SOURCES = \
|
|||
$(top_srcdir)/qt/qdbusmarshall.cpp \
|
||||
$(top_srcdir)/qt/qdbusmessage.cpp \
|
||||
$(top_srcdir)/qt/qdbusserver.cpp \
|
||||
$(top_srcdir)/qt/qdbusconnection.h \
|
||||
$(top_srcdir)/qt/qdbuserror.h \
|
||||
$(top_srcdir)/qt/qdbusmessage.h \
|
||||
$(top_srcdir)/qt/qdbusserver.h \
|
||||
$(top_srcdir)/qt/qdbusconnection_p.h \
|
||||
$(top_srcdir)/qt/qdbustype.cpp \
|
||||
$(top_srcdir)/qt/qdbusobject.cpp \
|
||||
$(top_srcdir)/qt/qdbusinterface.cpp \
|
||||
$(top_srcdir)/qt/qdbusstandardinterfaces.cpp \
|
||||
$(top_srcdir)/qt/qdbusxmlparser.cpp \
|
||||
$(top_srcdir)/qt/qdbusutil.cpp \
|
||||
$(top_srcdir)/qt/qdbusintrospection.cpp \
|
||||
$(top_srcdir)/qt/qdbusabstractadaptor.cpp \
|
||||
$(top_srcdir)/qt/qdbusthread.cpp \
|
||||
\
|
||||
$(top_srcdir)/dbus/qdbus.h \
|
||||
$(top_srcdir)/qt/qdbusabstractadaptor.h \
|
||||
$(top_srcdir)/qt/qdbusconnection.h \
|
||||
$(top_srcdir)/qt/qdbusconnection_p.h \
|
||||
$(top_srcdir)/qt/qdbuserror.h \
|
||||
$(top_srcdir)/qt/qdbusinterface.h \
|
||||
$(top_srcdir)/qt/qdbusinterface_p.h \
|
||||
$(top_srcdir)/qt/qdbusintrospection.h \
|
||||
$(top_srcdir)/qt/qdbusmacros.h \
|
||||
$(top_srcdir)/qt/qdbusmarshall.h \
|
||||
$(top_srcdir)/qt/qdbusmessage.h \
|
||||
$(top_srcdir)/qt/qdbusmessage_p.h \
|
||||
$(top_srcdir)/qt/qdbusvariant.h
|
||||
$(top_srcdir)/qt/qdbusobject.h \
|
||||
$(top_srcdir)/qt/qdbusobject_p.h \
|
||||
$(top_srcdir)/qt/qdbusserver.h \
|
||||
$(top_srcdir)/qt/qdbusstandardinterfaces.
|
||||
$(top_srcdir)/qt/qdbustype.h \
|
||||
$(top_srcdir)/qt/qdbusvariant.h \
|
||||
$(top_srcdir)/qt/qdbusxmlparser_p.h
|
||||
|
||||
|
||||
$(top_srcdir)/qt/qdbusserver.cpp: qdbusserver.moc
|
||||
$(top_srcdir)/qt/qdbusconnection.cpp: qdbusconnection.moc
|
||||
$(top_srcdir)/qt/qdbusabstractadaptor.lo: qdbusabstractadaptor.moc
|
||||
$(top_srcdir)/qt/qdbusserver.lo: qdbusserver.moc
|
||||
$(top_srcdir)/qt/qdbusconnection.lo: qdbusconnection_p.moc
|
||||
|
||||
CLEANFILES=qdbusserver.moc qdbusconnection.moc
|
||||
CLEANFILES=qdbusabstractadaptor.moc qdbusserver.moc qdbusconnection.moc
|
||||
|
||||
libdbus_qt4_1_la_LIBADD= $(DBUS_QT_LIBS) $(top_builddir)/dbus/libdbus-1.la
|
||||
libdbus_qt4_1_la_LDFLAGS= -version-info 1:0 -no-undefined
|
||||
|
||||
# _p.h files are a exception
|
||||
qdbusconnection.moc: qdbusconnection_p.h
|
||||
$(QT_MOC) -o qdbusconnection.moc $(top_srcdir)/qt/qdbusconnection_p.h
|
||||
|
||||
%.moc: %.h
|
||||
$(QT_MOC) $< > $@
|
||||
endif
|
||||
|
|
|
|||
10
qt/README
Normal file
10
qt/README
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
These are the Qt4 D-Bus bindings.
|
||||
|
||||
They are being maintained by Trolltech AS. As we are currently
|
||||
considering placing this code in a future version of Qt, we would like
|
||||
to ask any contributors to contact us before submitting code to this
|
||||
repository.
|
||||
|
||||
|
||||
For more information, please contact
|
||||
Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
64
qt/qdbusabstractadaptor.cpp
Normal file
64
qt/qdbusabstractadaptor.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- mode: C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusabstractadaptor.h"
|
||||
|
||||
#include <QtCore/qmetaobject.h>
|
||||
#include <QtCore/qtimer.h>
|
||||
|
||||
QDBusAbstractAdaptor::QDBusAbstractAdaptor(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
QTimer::singleShot(0, this, SLOT(polish()));
|
||||
}
|
||||
|
||||
QDBusAbstractAdaptor::~QDBusAbstractAdaptor()
|
||||
{
|
||||
}
|
||||
|
||||
void QDBusAbstractAdaptor::setAutoRelaySignals(bool enable)
|
||||
{
|
||||
const QMetaObject *us = metaObject();
|
||||
for (int idx = staticMetaObject.methodCount(); idx < us->methodCount(); ++idx) {
|
||||
QMetaMethod mm = us->method(idx);
|
||||
|
||||
if (mm.methodType() != QMetaMethod::Signal)
|
||||
continue;
|
||||
|
||||
// try to connect/disconnect to a signal on the parent that has the same method signature
|
||||
QByteArray sig = mm.signature();
|
||||
sig.prepend(QSIGNAL_CODE + '0');
|
||||
if (enable)
|
||||
connect(parent(), sig, sig);
|
||||
else
|
||||
parent()->disconnect(sig, this, sig);
|
||||
}
|
||||
}
|
||||
|
||||
void QDBusAbstractAdaptor::polish()
|
||||
{
|
||||
// future work:
|
||||
// connect every signal in this adaptor to a slot that will relay them into D-Bus
|
||||
}
|
||||
|
||||
#include "qdbusabstractadaptor.moc"
|
||||
44
qt/qdbusabstractadaptor.h
Normal file
44
qt/qdbusabstractadaptor.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- mode: C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSABSTRACTADAPTOR_H
|
||||
#define QDBUSABSTRACTADAPTOR_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
#include "qdbusmacros.h"
|
||||
|
||||
class QDBUS_EXPORT QDBusAbstractAdaptor: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QDBusAbstractAdaptor(QObject* parent);
|
||||
~QDBusAbstractAdaptor();
|
||||
|
||||
protected:
|
||||
void setAutoRelaySignals(bool enable);
|
||||
|
||||
private slots:
|
||||
void polish();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusconnection.cpp
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,16 +17,21 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <qdebug.h>
|
||||
#include <qcoreapplication.h>
|
||||
|
||||
#include "qdbusconnection.h"
|
||||
#include "qdbuserror.h"
|
||||
#include "qdbusmessage.h"
|
||||
#include "qdbusconnection_p.h"
|
||||
#include "qdbusinterface_p.h"
|
||||
#include "qdbusobject_p.h"
|
||||
#include "qdbusutil.h"
|
||||
|
||||
QT_STATIC_CONST_IMPL char *QDBusConnection::default_connection_name = "qt_dbus_default_connection";
|
||||
|
||||
|
|
@ -197,14 +204,7 @@ bool QDBusConnection::send(const QDBusMessage &message) const
|
|||
{
|
||||
if (!d || !d->connection)
|
||||
return false;
|
||||
|
||||
DBusMessage *msg = message.toDBusMessage();
|
||||
if (!msg)
|
||||
return false;
|
||||
|
||||
bool isOk = dbus_connection_send(d->connection, msg, 0);
|
||||
dbus_message_unref(msg);
|
||||
return isOk;
|
||||
return d->send(message);
|
||||
}
|
||||
|
||||
int QDBusConnection::sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
|
||||
|
|
@ -221,57 +221,98 @@ QDBusMessage QDBusConnection::sendWithReply(const QDBusMessage &message) const
|
|||
if (!d || !d->connection)
|
||||
return QDBusMessage::fromDBusMessage(0);
|
||||
|
||||
DBusMessage *msg = message.toDBusMessage();
|
||||
if (!msg)
|
||||
return QDBusMessage::fromDBusMessage(0);
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(d->connection, msg,
|
||||
-1, &d->error);
|
||||
d->handleError();
|
||||
dbus_message_unref(msg);
|
||||
if (!QCoreApplication::instance()) {
|
||||
DBusMessage *msg = message.toDBusMessage();
|
||||
if (!msg)
|
||||
return QDBusMessage::fromDBusMessage(0);
|
||||
|
||||
return QDBusMessage::fromDBusMessage(reply);
|
||||
DBusMessage *reply = dbus_connection_send_with_reply_and_block(d->connection, msg,
|
||||
-1, &d->error);
|
||||
d->handleError();
|
||||
dbus_message_unref(msg);
|
||||
|
||||
if (lastError().isValid())
|
||||
return QDBusMessage::fromError(lastError());
|
||||
|
||||
return QDBusMessage::fromDBusMessage(reply);
|
||||
} else {
|
||||
QDBusReplyWaiter waiter;
|
||||
if (d->sendWithReplyAsync(message, &waiter, SLOT(reply(const QDBusMessage&))) > 0) {
|
||||
// enter the event loop and wait for a reply
|
||||
waiter.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents);
|
||||
|
||||
d->lastError = waiter.replyMsg; // set or clear error
|
||||
return waiter.replyMsg;
|
||||
}
|
||||
|
||||
return QDBusMessage::fromDBusMessage(0);
|
||||
}
|
||||
}
|
||||
|
||||
bool QDBusConnection::connect(const QString &path, const QString &interface,
|
||||
bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
|
||||
const QString &name, QObject *receiver, const char *slot)
|
||||
{
|
||||
return connect(service, path, interface, name, QString(), receiver, slot);
|
||||
}
|
||||
|
||||
bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
|
||||
const QString &name, const QString &signature,
|
||||
QObject *receiver, const char *slot)
|
||||
{
|
||||
if (!receiver || !slot || !d || !d->connection)
|
||||
return false;
|
||||
|
||||
QDBusConnectionPrivate::SignalHook hook;
|
||||
QString source = getNameOwner(service);
|
||||
if (source.isEmpty())
|
||||
return false;
|
||||
source += path;
|
||||
|
||||
// check the slot
|
||||
QDBusConnectionPrivate::SignalHook hook;
|
||||
if ((hook.midx = QDBusConnectionPrivate::findSlot(receiver, slot + 1, hook.params)) == -1)
|
||||
return false;
|
||||
|
||||
hook.interface = interface;
|
||||
hook.name = name;
|
||||
hook.signature = signature;
|
||||
hook.obj = QPointer<QObject>(receiver);
|
||||
if (!hook.setSlot(slot + 1))
|
||||
return false;
|
||||
|
||||
d->signalHooks.insertMulti(path, hook);
|
||||
d->signalHooks.insertMulti(source, hook);
|
||||
d->connect(receiver, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QDBusConnection::registerObject(const QString &path, const QString &interface,
|
||||
QObject *object)
|
||||
bool QDBusConnection::registerObject(const QString &path, QObject *object, RegisterOptions options)
|
||||
{
|
||||
if (!d || !d->connection || !object || path.isEmpty() || interface.isEmpty())
|
||||
return registerObject(path, QString(), object, options);
|
||||
}
|
||||
|
||||
bool QDBusConnection::registerObject(const QString &path, const QString &interface,
|
||||
QObject *object, RegisterOptions options)
|
||||
{
|
||||
if (!d || !d->connection || !object || !options || !QDBusUtil::isValidObjectPath(path))
|
||||
return false;
|
||||
|
||||
QDBusConnectionPrivate::ObjectHook hook;
|
||||
hook.interface = interface;
|
||||
hook.obj = object;
|
||||
QString iface = interface;
|
||||
if (options & ExportForAnyInterface)
|
||||
iface.clear();
|
||||
|
||||
QDBusConnectionPrivate::ObjectHookHash::iterator it = d->objectHooks.find(path);
|
||||
while (it != d->objectHooks.end() && it.key() == path) {
|
||||
if (it.value().interface == interface) {
|
||||
d->objectHooks.erase(it);
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
QDBusConnectionPrivate::ObjectDataHash& hook = d->objectHooks[path];
|
||||
|
||||
d->objectHooks.insert(path, hook);
|
||||
// if we're replacing and matching any interface, then we're replacing every interface
|
||||
// this catches ExportAdaptors | Reexport too
|
||||
if (( options & ( ExportForAnyInterface | Reexport )) == ( ExportForAnyInterface | Reexport ))
|
||||
hook.clear();
|
||||
|
||||
// we're not matching any interface, but if we're not replacing, make sure it doesn't exist yet
|
||||
else if (( options & Reexport ) == 0 && hook.find(iface) != hook.end())
|
||||
return false;
|
||||
|
||||
QDBusConnectionPrivate::ObjectData& data = hook[iface];
|
||||
|
||||
data.flags = options;
|
||||
data.obj = object;
|
||||
|
||||
d->connect(object, SIGNAL(destroyed(QObject*)), SLOT(objectDestroyed(QObject*)));
|
||||
qDebug("REGISTERED FOR %s", path.toLocal8Bit().constData());
|
||||
|
|
@ -284,10 +325,45 @@ void QDBusConnection::unregisterObject(const QString &path)
|
|||
if (!d || !d->connection)
|
||||
return;
|
||||
|
||||
// TODO - check interfaces
|
||||
d->objectHooks.remove(path);
|
||||
}
|
||||
|
||||
QDBusInterface QDBusConnection::findInterface(const QString& service, const QString& path,
|
||||
const QString& interface)
|
||||
{
|
||||
// create one
|
||||
QDBusInterfacePrivate *priv = new QDBusInterfacePrivate;
|
||||
priv->conn = *this;
|
||||
|
||||
if (!QDBusUtil::isValidObjectPath(path) || !QDBusUtil::isValidInterfaceName(interface))
|
||||
return QDBusInterface(priv);
|
||||
|
||||
// check if it's there first
|
||||
QString owner = getNameOwner(service);
|
||||
if (owner.isEmpty())
|
||||
return QDBusInterface(priv);
|
||||
|
||||
// getNameOwner returns empty if d is 0
|
||||
Q_ASSERT(d);
|
||||
priv->service = owner;
|
||||
priv->path = path;
|
||||
priv->data = d->findInterface(interface).constData();
|
||||
|
||||
return QDBusInterface(priv); // will increment priv's refcount
|
||||
}
|
||||
|
||||
QDBusObject QDBusConnection::findObject(const QString& service, const QString& path)
|
||||
{
|
||||
QDBusObjectPrivate* priv = 0;
|
||||
if (d && QDBusUtil::isValidObjectPath(path)) {
|
||||
QString owner = getNameOwner(service);
|
||||
|
||||
if (!owner.isEmpty())
|
||||
priv = new QDBusObjectPrivate(d, owner, path);
|
||||
}
|
||||
return QDBusObject(priv, *this);
|
||||
}
|
||||
|
||||
bool QDBusConnection::isConnected( ) const
|
||||
{
|
||||
return d && d->connection && dbus_connection_get_is_connected(d->connection);
|
||||
|
|
@ -307,21 +383,38 @@ QString QDBusConnection::baseService() const
|
|||
|
||||
bool QDBusConnection::requestName(const QString &name, NameRequestMode mode)
|
||||
{
|
||||
//FIXME: DBUS_NAME_FLAGS_* are bit fields not enumeration
|
||||
static const int DBusModes[] = { 0, DBUS_NAME_FLAG_ALLOW_REPLACEMENT,
|
||||
DBUS_NAME_FLAG_REPLACE_EXISTING };
|
||||
Q_ASSERT(mode == 0 || mode == AllowReplace ||
|
||||
mode == ReplaceExisting );
|
||||
static const int DBusModes[] = { DBUS_NAME_FLAG_ALLOW_REPLACEMENT, 0,
|
||||
DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_ALLOW_REPLACEMENT};
|
||||
|
||||
DBusError error;
|
||||
dbus_error_init (&error);
|
||||
dbus_bus_request_name(d->connection, name.toUtf8(), DBusModes[mode], &error);
|
||||
if (dbus_error_is_set (&error)) {
|
||||
qDebug("Error %s\n", error.message);
|
||||
dbus_error_free (&error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
int retval = dbus_bus_request_name(d->connection, name.toUtf8(), DBusModes[mode], &d->error);
|
||||
d->handleError();
|
||||
return retval == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER ||
|
||||
retval == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER;
|
||||
}
|
||||
|
||||
#include "qdbusconnection.moc"
|
||||
bool QDBusConnection::releaseName(const QString &name)
|
||||
{
|
||||
int retval = dbus_bus_release_name(d->connection, name.toUtf8(), &d->error);
|
||||
d->handleError();
|
||||
if (lastError().isValid())
|
||||
return false;
|
||||
return retval == DBUS_RELEASE_NAME_REPLY_RELEASED;
|
||||
}
|
||||
|
||||
QString QDBusConnection::getNameOwner(const QString& name)
|
||||
{
|
||||
if (QDBusUtil::isValidUniqueConnectionName(name))
|
||||
return name;
|
||||
if (!d || !QDBusUtil::isValidBusName(name))
|
||||
return QString();
|
||||
|
||||
QDBusMessage msg = QDBusMessage::methodCall(DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS, "GetNameOwner");
|
||||
msg << name;
|
||||
QDBusMessage reply = sendWithReply(msg);
|
||||
if (!lastError().isValid() && reply.type() == QDBusMessage::ReplyMessage)
|
||||
return reply.first().toString();
|
||||
return QString();
|
||||
}
|
||||
|
||||
#include "qdbusconnection_p.moc"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusconnection.h QDBusConnection object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,18 +17,21 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSCONNECTION_H
|
||||
#define QDBUSCONNECTION_H
|
||||
|
||||
#include "dbus/qdbus.h"
|
||||
#include "qdbusmacros.h"
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
class QDBusConnectionPrivate;
|
||||
class QDBusXmlParser;
|
||||
class QDBusObject;
|
||||
class QDBusInterface;
|
||||
class QDBusError;
|
||||
class QDBusMessage;
|
||||
class QByteArray;
|
||||
|
|
@ -46,8 +51,11 @@ public:
|
|||
bool isConnected() const;
|
||||
QDBusError lastError() const;
|
||||
|
||||
enum NameRequestMode { NoReplace = 0, AllowReplace = 1, ReplaceExisting = 2 };
|
||||
enum NameRequestMode { NoReplace = 0, ProhibitReplace = 1, ReplaceExisting = 2 };
|
||||
bool requestName(const QString &name, NameRequestMode mode = NoReplace);
|
||||
bool releaseName(const QString& name);
|
||||
QString getNameOwner(const QString& name);
|
||||
|
||||
|
||||
QString baseService() const;
|
||||
|
||||
|
|
@ -56,13 +64,42 @@ public:
|
|||
int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
|
||||
const char *slot) const;
|
||||
|
||||
bool connect(const QString &path, const QString &interface,
|
||||
bool connect(const QString &service, const QString &path, const QString &interface,
|
||||
const QString &name, QObject *receiver, const char *slot);
|
||||
bool connect(const QString &service, const QString &path, const QString &interface,
|
||||
const QString &name, const QString& signature,
|
||||
QObject *receiver, const char *slot);
|
||||
|
||||
bool registerObject(const QString &path, const QString &interface,
|
||||
QObject *object);
|
||||
enum RegisterOption {
|
||||
ExportForAnyInterface = 0x01,
|
||||
ExportAdaptors = 0x03,
|
||||
|
||||
ExportOwnSlots = 0x10,
|
||||
ExportOwnSignals = 0x20,
|
||||
ExportOwnProperties = 0x40,
|
||||
ExportOwnContents = 0xf0,
|
||||
|
||||
ExportNonScriptableSlots = 0x100,
|
||||
ExportNonScriptableSignals = 0x200,
|
||||
ExportNonScriptableProperties = 0x400,
|
||||
ExportNonScriptables = 0xf00,
|
||||
|
||||
ExportChildObjects = 0x1000,
|
||||
|
||||
Reexport = 0x100000,
|
||||
};
|
||||
Q_DECLARE_FLAGS(RegisterOptions, RegisterOption);
|
||||
|
||||
bool registerObject(const QString &path, const QString &interface, QObject *object,
|
||||
RegisterOptions options = ExportOwnContents);
|
||||
bool registerObject(const QString &path, QObject *object,
|
||||
RegisterOptions options = ExportAdaptors);
|
||||
void unregisterObject(const QString &path);
|
||||
|
||||
QDBusObject findObject(const QString& service, const QString& path);
|
||||
QDBusInterface findInterface(const QString& service, const QString& path, const QString& interface);
|
||||
|
||||
|
||||
static QDBusConnection addConnection(BusType type,
|
||||
const QString &name = QLatin1String(default_connection_name));
|
||||
static QDBusConnection addConnection(const QString &address,
|
||||
|
|
@ -72,7 +109,9 @@ public:
|
|||
QT_STATIC_CONST char *default_connection_name;
|
||||
|
||||
private:
|
||||
friend class QDBusObject;
|
||||
QDBusConnectionPrivate *d;
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::RegisterOptions)
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusconnection_p.h QDBusConnection private object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,8 +17,8 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -38,16 +40,24 @@
|
|||
#include "qdbuserror.h"
|
||||
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtCore/qeventloop.h>
|
||||
#include <QtCore/qmutex.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "qdbusmessage.h"
|
||||
#include "qdbusintrospection.h"
|
||||
|
||||
class QDBusMessage;
|
||||
class QSocketNotifier;
|
||||
class QTimerEvent;
|
||||
class QDBusObjectPrivate;
|
||||
class CallDeliveryEvent;
|
||||
|
||||
typedef struct DBusConnection;
|
||||
typedef struct DBusServer;
|
||||
|
|
@ -56,6 +66,43 @@ class QDBusConnectionPrivate: public QObject
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// structs and enums
|
||||
enum ConnectionMode { InvalidMode, ServerMode, ClientMode };
|
||||
|
||||
struct Watcher
|
||||
{
|
||||
Watcher(): watch(0), read(0), write(0) {}
|
||||
DBusWatch *watch;
|
||||
QSocketNotifier *read;
|
||||
QSocketNotifier *write;
|
||||
};
|
||||
|
||||
struct SignalHook
|
||||
{
|
||||
QString interface, name, signature;
|
||||
QPointer<QObject> obj;
|
||||
int midx;
|
||||
QList<int> params;
|
||||
};
|
||||
|
||||
struct ObjectData
|
||||
{
|
||||
QPointer<QObject> obj;
|
||||
int flags;
|
||||
};
|
||||
|
||||
public:
|
||||
// typedefs
|
||||
typedef QMultiHash<int, Watcher> WatcherHash;
|
||||
typedef QHash<int, DBusTimeout *> TimeoutHash;
|
||||
typedef QMultiHash<QString, SignalHook> SignalHookHash;
|
||||
typedef QHash<QString, ObjectData> ObjectDataHash;
|
||||
typedef QHash<QString, ObjectDataHash> ObjectHookHash;
|
||||
typedef QHash<QString, QSharedDataPointer<QDBusIntrospection::Interface> > KnownInterfacesHash;
|
||||
typedef QHash<QString, QDBusIntrospection::Object* > KnownObjectsHash;
|
||||
|
||||
public:
|
||||
// public methods
|
||||
QDBusConnectionPrivate(QObject *parent = 0);
|
||||
~QDBusConnectionPrivate();
|
||||
|
||||
|
|
@ -66,66 +113,81 @@ public:
|
|||
void closeConnection();
|
||||
void timerEvent(QTimerEvent *e);
|
||||
|
||||
bool handleSignal(DBusMessage *msg) const;
|
||||
bool handleObjectCall(DBusMessage *message) const;
|
||||
bool handleSignal(const QString &path, const QDBusMessage &msg);
|
||||
bool send(const QDBusMessage &message) const;
|
||||
int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
|
||||
const char *method) const;
|
||||
|
||||
bool handleSignal(const QDBusMessage &msg);
|
||||
bool handleObjectCall(const QDBusMessage &message);
|
||||
bool handleError();
|
||||
|
||||
void disposeOfLocked(QDBusIntrospection::Object* obj);
|
||||
void disposeOf(QDBusObjectPrivate* obj);
|
||||
QSharedDataPointer<QDBusIntrospection::Interface> findInterface(const QString& name);
|
||||
QDBusIntrospection::Object* findObject(const QString& service,
|
||||
const QString& path);
|
||||
|
||||
bool activateReply(QObject *object, int idx, const QList<int>& metaTypes,
|
||||
const QDBusMessage &msg);
|
||||
bool activateSignal(const SignalHook& hook, const QDBusMessage &msg);
|
||||
bool activateCall(QObject* object, int flags, const QDBusMessage &msg);
|
||||
bool activateAdaptor(QObject *object, int flags, const QDBusMessage &msg);
|
||||
bool activateObject(const ObjectData& data, const QDBusMessage &msg);
|
||||
void deliverCall(const CallDeliveryEvent &data) const;
|
||||
|
||||
protected:
|
||||
virtual void customEvent(QEvent *event);
|
||||
|
||||
public slots:
|
||||
// public slots
|
||||
void socketRead(int);
|
||||
void socketWrite(int);
|
||||
void objectDestroyed(QObject *o);
|
||||
|
||||
public:
|
||||
// public member variables
|
||||
DBusError error;
|
||||
QDBusError lastError;
|
||||
|
||||
enum ConnectionMode { InvalidMode, ServerMode, ClientMode };
|
||||
|
||||
QAtomic ref;
|
||||
QMutex mutex;
|
||||
ConnectionMode mode;
|
||||
DBusConnection *connection;
|
||||
DBusServer *server;
|
||||
|
||||
static int messageMetaType;
|
||||
static int registerMessageMetaType();
|
||||
bool handleSignal(const QString &path, const QDBusMessage &msg) const;
|
||||
int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
|
||||
const char *method) const;
|
||||
|
||||
struct Watcher
|
||||
{
|
||||
Watcher(): watch(0), read(0), write(0) {}
|
||||
DBusWatch *watch;
|
||||
QSocketNotifier *read;
|
||||
QSocketNotifier *write;
|
||||
};
|
||||
typedef QMultiHash<int, Watcher> WatcherHash;
|
||||
WatcherHash watchers;
|
||||
|
||||
typedef QHash<int, DBusTimeout *> TimeoutHash;
|
||||
TimeoutHash timeouts;
|
||||
|
||||
struct SignalHook
|
||||
{
|
||||
QString interface, name;
|
||||
QPointer<QObject> obj;
|
||||
int midx;
|
||||
QVarLengthArray<int, 10> params;
|
||||
|
||||
bool setSlot(const char *slotName);
|
||||
};
|
||||
|
||||
typedef QMultiHash<QString, SignalHook> SignalHookHash;
|
||||
SignalHookHash signalHooks;
|
||||
|
||||
struct ObjectHook
|
||||
{
|
||||
QString interface;
|
||||
QPointer<QObject> obj;
|
||||
};
|
||||
typedef QMultiHash<QString, ObjectHook> ObjectHookHash;
|
||||
ObjectHookHash objectHooks;
|
||||
QList<DBusTimeout *> pendingTimeouts;
|
||||
|
||||
public:
|
||||
// public mutable member variables
|
||||
mutable KnownInterfacesHash knownInterfaces;
|
||||
mutable KnownObjectsHash knownObjects;
|
||||
|
||||
public:
|
||||
// static methods
|
||||
static int messageMetaType;
|
||||
static int registerMessageMetaType();
|
||||
static int findSlot(QObject *obj, const char *slotName, QList<int>& params);
|
||||
};
|
||||
|
||||
class QDBusReplyWaiter: public QEventLoop
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QDBusMessage replyMsg;
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
int level;
|
||||
int exec(ProcessEventsFlags flags);
|
||||
void exit(int = 0);
|
||||
#endif
|
||||
|
||||
public slots:
|
||||
void reply(const QDBusMessage &msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbuserror.h QDBusError object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,16 +17,17 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbuserror.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <qdebug.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
#include "qdbusmessage.h"
|
||||
|
||||
QDBusError::QDBusError(const DBusError *error)
|
||||
{
|
||||
|
|
@ -35,6 +38,16 @@ QDBusError::QDBusError(const DBusError *error)
|
|||
msg = QString::fromUtf8(error->message);
|
||||
}
|
||||
|
||||
QDBusError::QDBusError(const QDBusMessage &qdmsg)
|
||||
{
|
||||
if (qdmsg.type() != QDBusMessage::ErrorMessage)
|
||||
return;
|
||||
|
||||
nm = qdmsg.name();
|
||||
if (qdmsg.count())
|
||||
msg = qdmsg[0].toString();
|
||||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, const QDBusError &msg)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbuserror.h QDBusError object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,23 +17,25 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSERROR_H
|
||||
#define QDBUSERROR_H
|
||||
|
||||
#include "dbus/qdbus.h"
|
||||
#include "qdbusmacros.h"
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
struct DBusError;
|
||||
class QDBusMessage;
|
||||
|
||||
class QDBUS_EXPORT QDBusError
|
||||
{
|
||||
public:
|
||||
QDBusError(const DBusError *error = 0);
|
||||
QDBusError(const QDBusMessage& msg);
|
||||
|
||||
inline QString name() const { return nm; }
|
||||
inline QString message() const { return msg; }
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
256
qt/qdbusinterface.cpp
Normal file
256
qt/qdbusinterface.cpp
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusinterface.h"
|
||||
#include "qdbusobject.h"
|
||||
#include "qdbusstandardinterfaces.h"
|
||||
|
||||
#include "qdbusinterface_p.h"
|
||||
|
||||
QDBusInterface::QDBusInterface(QDBusInterfacePrivate* p)
|
||||
: d(p)
|
||||
{
|
||||
d->ref.ref();
|
||||
}
|
||||
|
||||
QDBusInterface::QDBusInterface(const QDBusObject& obj, const QString& name)
|
||||
: d(0)
|
||||
{
|
||||
*this = obj.connection().findInterface(obj.service(), obj.path(), name);
|
||||
}
|
||||
|
||||
QDBusInterface::QDBusInterface(QDBusConnection& conn, const QString& service, const QString& path,
|
||||
const QString& name)
|
||||
: d(0)
|
||||
{
|
||||
*this = conn.findInterface(service, path, name);
|
||||
}
|
||||
|
||||
QDBusInterface::~QDBusInterface()
|
||||
{
|
||||
if (!d->ref.deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
QDBusInterface& QDBusInterface::operator=(const QDBusInterface& other)
|
||||
{
|
||||
other.d->ref.ref();
|
||||
QDBusInterfacePrivate* old = qAtomicSetPtr(&d, other.d);
|
||||
if (old && !old->ref.deref())
|
||||
delete old;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDBusConnection QDBusInterface::connection() const
|
||||
{
|
||||
return d->conn;
|
||||
}
|
||||
|
||||
QString QDBusInterface::service() const
|
||||
{
|
||||
return d->service;
|
||||
}
|
||||
|
||||
QString QDBusInterface::path() const
|
||||
{
|
||||
return d->path;
|
||||
}
|
||||
|
||||
QString QDBusInterface::interface() const
|
||||
{
|
||||
return d->data->name;
|
||||
}
|
||||
|
||||
QString QDBusInterface::introspectionData() const
|
||||
{
|
||||
d->introspect();
|
||||
return d->data->introspection;
|
||||
}
|
||||
|
||||
const QDBusIntrospection::Interface& QDBusInterface::interfaceData() const
|
||||
{
|
||||
d->introspect();
|
||||
return *d->data;
|
||||
}
|
||||
|
||||
const QDBusIntrospection::Annotations& QDBusInterface::annotationData() const
|
||||
{
|
||||
d->introspect();
|
||||
return d->data->annotations;
|
||||
}
|
||||
|
||||
const QDBusIntrospection::Methods& QDBusInterface::methodData() const
|
||||
{
|
||||
d->introspect();
|
||||
return d->data->methods;
|
||||
}
|
||||
|
||||
const QDBusIntrospection::Signals& QDBusInterface::signalData() const
|
||||
{
|
||||
d->introspect();
|
||||
return d->data->signals_;
|
||||
}
|
||||
|
||||
const QDBusIntrospection::Properties& QDBusInterface::propertyData() const
|
||||
{
|
||||
d->introspect();
|
||||
return d->data->properties;
|
||||
}
|
||||
|
||||
QDBusMessage QDBusInterface::callWithArgs(const QDBusIntrospection::Method& method,
|
||||
const QList<QVariant>& a_args,
|
||||
CallMode mode)
|
||||
{
|
||||
QString signature(""); // empty, not null
|
||||
QVariantList args = a_args;
|
||||
|
||||
if (!method.inputArgs.isEmpty())
|
||||
{
|
||||
// go over the list of parameters for the method
|
||||
QDBusIntrospection::Arguments::const_iterator it = method.inputArgs.begin(),
|
||||
end = method.inputArgs.end();
|
||||
int arg;
|
||||
for (arg = 0; it != end; ++it, ++arg)
|
||||
{
|
||||
// find the marshalled name for this type
|
||||
QString typeSig = QLatin1String(it->type.dbusSignature());
|
||||
signature += typeSig;
|
||||
}
|
||||
}
|
||||
else
|
||||
args.clear();
|
||||
|
||||
if (method.annotations.contains(ANNOTATION_NO_WAIT))
|
||||
mode = NoWaitForReply;
|
||||
|
||||
return callWithArgs(method.name, signature, args, mode);
|
||||
}
|
||||
|
||||
QDBusMessage QDBusInterface::callWithArgs(const QString& method, const QList<QVariant>& args,
|
||||
CallMode mode)
|
||||
{
|
||||
QString m = method, sig;
|
||||
// split out the signature from the method
|
||||
int pos = method.indexOf('.');
|
||||
if (pos != -1) {
|
||||
m.truncate(pos);
|
||||
sig = method.mid(pos + 1);
|
||||
}
|
||||
return callWithArgs(m, sig, args, mode);
|
||||
}
|
||||
|
||||
QDBusMessage QDBusInterface::callWithArgs(const QString& method, const QString& signature,
|
||||
const QList<QVariant>& args, CallMode mode)
|
||||
{
|
||||
QDBusMessage msg = QDBusMessage::methodCall(service(), path(), interface(), method, signature);
|
||||
msg.QList<QVariant>::operator=(args);
|
||||
|
||||
QDBusMessage reply;
|
||||
if (mode == WaitForReply)
|
||||
reply = d->conn.sendWithReply(msg);
|
||||
else
|
||||
d->conn.send(msg);
|
||||
|
||||
d->lastError = reply; // will clear if reply isn't an error
|
||||
|
||||
// ensure that there is at least one element
|
||||
if (reply.isEmpty())
|
||||
reply << QVariant();
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
bool QDBusInterface::connect(const QDBusIntrospection::Signal& sig, QObject* obj, const char *slot)
|
||||
{
|
||||
QString signature(""); // empty, not null
|
||||
|
||||
if (!sig.outputArgs.isEmpty())
|
||||
{
|
||||
// go over the list of parameters for the method
|
||||
QDBusIntrospection::Arguments::const_iterator it = sig.outputArgs.begin(),
|
||||
end = sig.outputArgs.end();
|
||||
int arg;
|
||||
for (arg = 0; it != end; ++it, ++arg)
|
||||
{
|
||||
// find the marshalled name for this type
|
||||
QString typeSig = QLatin1String(it->type.dbusSignature());
|
||||
signature += typeSig;
|
||||
}
|
||||
}
|
||||
|
||||
return connect(sig.name, signature, obj, slot);
|
||||
}
|
||||
|
||||
bool QDBusInterface::connect(const QString& signalName, QObject* obj, const char *slot)
|
||||
{
|
||||
QString s = signalName, sig;
|
||||
// split out the signature from the name
|
||||
int pos = signalName.indexOf('.');
|
||||
if (pos != -1) {
|
||||
s.truncate(pos);
|
||||
sig = signalName.mid(pos + 1);
|
||||
}
|
||||
return connect(s, sig, obj, slot);
|
||||
}
|
||||
|
||||
bool QDBusInterface::connect(const QString& signalName, const QString& signature,
|
||||
QObject* obj, const char *slot)
|
||||
{
|
||||
return d->conn.connect(service(), path(), interface(), signalName, signature, obj, slot);
|
||||
}
|
||||
|
||||
QVariant QDBusInterface::propertyGet(const QDBusIntrospection::Property& prop)
|
||||
{
|
||||
// sanity checking
|
||||
if (prop.access == QDBusIntrospection::Property::Write)
|
||||
return QVariant(); // write-only prop
|
||||
|
||||
QDBusPropertiesInterface pi(object());
|
||||
return pi.get(interface(), prop.name);
|
||||
}
|
||||
|
||||
QVariant QDBusInterface::propertyGet(const QString& propName)
|
||||
{
|
||||
// can't do sanity checking
|
||||
QDBusPropertiesInterface pi(object());
|
||||
return pi.get(interface(), propName);
|
||||
}
|
||||
|
||||
void QDBusInterface::propertySet(const QDBusIntrospection::Property& prop, QVariant newValue)
|
||||
{
|
||||
// sanity checking
|
||||
if (prop.access == QDBusIntrospection::Property::Read)
|
||||
return;
|
||||
|
||||
QDBusPropertiesInterface pi(object());
|
||||
pi.set(interface(), prop.name, newValue);
|
||||
}
|
||||
|
||||
void QDBusInterface::propertySet(const QString& propName, QVariant newValue)
|
||||
{
|
||||
// can't do sanity checking
|
||||
QDBusPropertiesInterface pi(object());
|
||||
pi.set(interface(), propName, newValue);
|
||||
}
|
||||
310
qt/qdbusinterface.h
Normal file
310
qt/qdbusinterface.h
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSINTERFACE_H
|
||||
#define QDBUSINTERFACE_H
|
||||
|
||||
#include "qdbusmessage.h"
|
||||
#include "qdbusobject.h"
|
||||
#include "qdbusintrospection.h"
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qlist.h>
|
||||
|
||||
class QDBusConnection;
|
||||
|
||||
class QDBusInterfacePrivate;
|
||||
/**
|
||||
* Base class for all DBUS interfaces in the QtDBUS binding.
|
||||
*/
|
||||
class QDBUS_EXPORT QDBusInterface
|
||||
{
|
||||
friend class QDBusConnection;
|
||||
|
||||
public:
|
||||
enum CallMode {
|
||||
WaitForReply,
|
||||
NoWaitForReply
|
||||
};
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct an interface of the given name
|
||||
*/
|
||||
QDBusInterface(const QDBusObject& obj, const QString& name);
|
||||
|
||||
/**
|
||||
* @overload.
|
||||
* Construct an interface of the given name
|
||||
*/
|
||||
QDBusInterface(QDBusConnection& conn, const QString& service, const QString& path, const QString& name);
|
||||
|
||||
/**
|
||||
* Construct a copy of the interface.
|
||||
*/
|
||||
QDBusInterface(const QDBusInterface&);
|
||||
|
||||
/**
|
||||
* Destructs this interface.
|
||||
*/
|
||||
virtual ~QDBusInterface();
|
||||
|
||||
/**
|
||||
* Copy the interface.
|
||||
*/
|
||||
QDBusInterface& operator=(const QDBusInterface&);
|
||||
|
||||
/**
|
||||
* Returns the object associated with this interface.
|
||||
*/
|
||||
inline QDBusObject object()
|
||||
{ return QDBusObject(*this); }
|
||||
|
||||
inline const QDBusObject object() const
|
||||
{ return QDBusObject(*this); }
|
||||
|
||||
/**
|
||||
* Returns the connection this interface is on.
|
||||
*/
|
||||
QDBusConnection connection() const;
|
||||
|
||||
/**
|
||||
* Returns the name of the service this interface is associated with.
|
||||
*/
|
||||
QString service() const;
|
||||
|
||||
/**
|
||||
* Returns the object path that this interface is associated with.
|
||||
*/
|
||||
QString path() const;
|
||||
|
||||
/**
|
||||
* Returns the name of this interface.
|
||||
*/
|
||||
QString interface() const;
|
||||
|
||||
/**
|
||||
* Returns the introspection XML fragment data of this interface.
|
||||
*/
|
||||
virtual QString introspectionData() const;
|
||||
|
||||
/**
|
||||
* Returns the interface data for this interface.
|
||||
*/
|
||||
const QDBusIntrospection::Interface& interfaceData() const;
|
||||
|
||||
/**
|
||||
* Returns the annotations present in this interface, if any.
|
||||
*/
|
||||
const QDBusIntrospection::Annotations& annotationData() const;
|
||||
|
||||
/**
|
||||
* List all methods in this interface.
|
||||
*/
|
||||
const QDBusIntrospection::Methods& methodData() const;
|
||||
|
||||
/**
|
||||
* List all signals in this interface.
|
||||
*/
|
||||
const QDBusIntrospection::Signals& signalData() const;
|
||||
|
||||
/**
|
||||
* List all properties in this interface.
|
||||
*/
|
||||
const QDBusIntrospection::Properties& propertyData() const;
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
QDBusMessage callWithArgs(const QDBusIntrospection::Method& method,
|
||||
const QList<QVariant>& args = QList<QVariant>(),
|
||||
CallMode mode = WaitForReply);
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
QDBusMessage callWithArgs(const QString& method, const QList<QVariant>& args = QList<QVariant>(),
|
||||
CallMode mode = WaitForReply);
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
QDBusMessage callWithArgs(const QString& method, const QString& signature,
|
||||
const QList<QVariant>& args = QList<QVariant>(),
|
||||
CallMode mode = WaitForReply);
|
||||
|
||||
/**
|
||||
* Connects the DBUS signal to the given slot.
|
||||
*/
|
||||
bool connect(const QDBusIntrospection::Signal&, QObject* obj, const char *slot);
|
||||
|
||||
/**
|
||||
* Connects the DBUS signal to the given slot.
|
||||
*/
|
||||
bool connect(const QString& signalName, QObject* obj, const char *slot);
|
||||
|
||||
/**
|
||||
* Connects the DBUS signal to the given slot.
|
||||
*/
|
||||
bool connect(const QString& signalName, const QString& signature,
|
||||
QObject* obj, const char *slot);
|
||||
|
||||
/**
|
||||
* Gets the value of the given property.
|
||||
*/
|
||||
QVariant propertyGet(const QDBusIntrospection::Property&);
|
||||
|
||||
/**
|
||||
* Gets the value of the given property.
|
||||
*/
|
||||
QVariant propertyGet(const QString& property);
|
||||
|
||||
/**
|
||||
* Sets the value of the given property.
|
||||
*/
|
||||
void propertySet(const QDBusIntrospection::Property&, QVariant newValue);
|
||||
|
||||
/**
|
||||
* Sets the value of the given property.
|
||||
*/
|
||||
void propertySet(const QString& property, QVariant newValue);
|
||||
|
||||
/**
|
||||
* Casts to QDBusObject.
|
||||
*/
|
||||
inline operator QDBusObject()
|
||||
{ return QDBusObject(*this); }
|
||||
|
||||
/**
|
||||
* Casts to const QDBusObject.
|
||||
*/
|
||||
inline operator const QDBusObject() const
|
||||
{ return QDBusObject(*this); }
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType>
|
||||
inline QDBusMessage call(MethodType m)
|
||||
{
|
||||
return callWithArgs(m);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1>
|
||||
inline QDBusMessage call(MethodType m, T1 t1)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1, typename T2>
|
||||
inline QDBusMessage call(MethodType m, T1 t1, T2 t2)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1 << t2;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1, typename T2, typename T3>
|
||||
inline QDBusMessage call(MethodType m, T1 t1, T2 t2, T3 t3)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1 << t2 << t3;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1, typename T2, typename T3, typename T4>
|
||||
inline QDBusMessage call(MethodType m, T1 t1, T2 t2, T3 t3, T4 t4)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1 << t2 << t3 << t4;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||
inline QDBusMessage call(MethodType m, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1 << t2 << t3 << t4 << t5;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6>
|
||||
inline QDBusMessage call(MethodType m, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1 << t2 << t3 << t4 << t5 << t6;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7>
|
||||
inline QDBusMessage call(MethodType m, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1 << t2 << t3 << t4 << t5 << t6 << t7;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call the given method.
|
||||
*/
|
||||
template<typename MethodType, typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8>
|
||||
inline QDBusMessage call(MethodType m, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
|
||||
{
|
||||
QList<QVariant> args;
|
||||
args << t1 << t2 << t3 << t4 << t5 << t6 << t7 << t8;
|
||||
return callWithArgs(m, args);
|
||||
}
|
||||
|
||||
private:
|
||||
QDBusInterface(QDBusInterfacePrivate*);
|
||||
QDBusInterfacePrivate *d;
|
||||
};
|
||||
|
||||
#endif
|
||||
67
qt/qdbusinterface_p.h
Normal file
67
qt/qdbusinterface_p.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2006 Thiago José Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the public API. This header file may
|
||||
// change from version to version without notice, or even be
|
||||
// removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef QDBUSINTERFACEPRIVATE_H
|
||||
#define QDBUSINTERFACEPRIVATE_H
|
||||
|
||||
#include "qdbusobject.h"
|
||||
#include "qdbusinterface.h"
|
||||
#include "qdbusconnection.h"
|
||||
#include "qdbuserror.h"
|
||||
|
||||
#define ANNOTATION_NO_WAIT "com.trolltech.DBus.NoWaitForReply"
|
||||
|
||||
class QDBusInterfacePrivate
|
||||
{
|
||||
public:
|
||||
QAtomic ref;
|
||||
QDBusConnection conn;
|
||||
QString service;
|
||||
QString path;
|
||||
QDBusError lastError;
|
||||
|
||||
//QConstSharedDataPointer<QDBusIntrospection::Interface> data;
|
||||
const QDBusIntrospection::Interface* data;
|
||||
|
||||
inline bool needsIntrospection() const
|
||||
{ return data->introspection.isNull(); }
|
||||
|
||||
inline void introspect()
|
||||
{ if (needsIntrospection()) QDBusObject(conn, service, path).introspect(); }
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
380
qt/qdbusintrospection.cpp
Normal file
380
qt/qdbusintrospection.cpp
Normal file
|
|
@ -0,0 +1,380 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusintrospection.h"
|
||||
#include "qdbusxmlparser_p.h"
|
||||
|
||||
/*!
|
||||
\class QDBusIntrospection
|
||||
\brief Information about introspected objects and interfaces on D-Bus.
|
||||
|
||||
This class provides structures and methods for parsing the XML introspection data for D-Bus.
|
||||
Normally, you don't have to use the methods provided here: QDBusInterface and QDBusObject will
|
||||
do that for you.
|
||||
|
||||
But they may prove useful if the XML data was obtained through other means (like parsing a file).
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDBusIntrospection::Argument
|
||||
\brief One argument to a D-Bus method or signal.
|
||||
|
||||
This struct represents one argument passed to a method or received from a method or signal in
|
||||
D-Bus. The struct does not contain information on the direction (input or output).
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Argument::type
|
||||
The argument type.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Argument::name
|
||||
The argument name. The argument name is optional, so this may be a null QString.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDBusIntrospection::Method
|
||||
\brief Information about one method.
|
||||
|
||||
This struct represents one method discovered through introspection. A method is composed of
|
||||
its \a name, its input arguments, its output arguments, and, optionally, annotations. There are no
|
||||
"in-out" arguments.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Method::name
|
||||
The method's name.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Method::inputArgs
|
||||
A list of the method's input arguments.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Method::outputArgs
|
||||
A list of the method's output arguments (i.e., return values).
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Method::annotations
|
||||
The annotations associated with the method. Each annotation is a pair of strings, where the key
|
||||
is of the same format as a D-Bus interface name. The value is arbitrary.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDBusIntrospection::Signal
|
||||
\brief Information about one signal.
|
||||
|
||||
This struct represents one signal discovered through introspection. A signal is composed of
|
||||
its \a name, its output arguments, and, optionally, annotations.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Signal::outputArgs
|
||||
A list of the signal's arguments.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Signal::annotations
|
||||
The annotations associated with the signal. Each annotation is a pair of strings, where the key
|
||||
is of the same format as a D-Bus interface name. The value is arbitrary.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDBusIntrospection::Property
|
||||
\brief Information about one property.
|
||||
|
||||
This struct represents one property discovered through introspection. A property is composed of
|
||||
its \a name, its \a type, its \a access rights, and, optionally, annotations.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Property::name
|
||||
The property's name.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Property::type
|
||||
The property's type.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\enum QDBusIntrospection::Property::Access
|
||||
The possible access rights for a property:
|
||||
- Read
|
||||
- Write
|
||||
- ReadWrite
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Property::access
|
||||
The property's access rights.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Property::annotations
|
||||
The annotations associated with the property. Each annotation is a pair of strings, where the key
|
||||
is of the same format as a D-Bus interface name. The value is arbitrary.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDBusIntrospection::Interface
|
||||
\brief Information about one interface on the bus.
|
||||
|
||||
Each interface on D-Bus has an unique \a name, identifying where that interface was defined.
|
||||
Interfaces may have annotations, methods, signals and properties, but none are mandatory.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Interface::name
|
||||
The interface's name.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Interface::introspection
|
||||
The XML document fragment describing this interface.
|
||||
|
||||
If parsed again through parseInterface, the object returned should have the same contents as
|
||||
this object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Interface::annotations
|
||||
The annotations associated with the interface. Each annotation is a pair of strings, where the key
|
||||
is of the same format as a D-Bus interface name. The value is arbitrary.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Interface::methods
|
||||
The methods available in this interface. Note that method names are not unique (i.e., methods
|
||||
can be overloaded with multiple arguments types).
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Interface::signals_
|
||||
The signals available in this interface. Note that signal names are not unique (i.e., signals
|
||||
can be overloaded with multiple argument types).
|
||||
|
||||
This member is called "signals_" because "signals" is a reserved keyword in Qt.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Interface::properties
|
||||
The properties available in this interface. Property names are unique.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDBusIntrospection::Object
|
||||
\brief Information about one object on the bus.
|
||||
|
||||
An object on the D-Bus bus is represented by its service and path on the service but, unlike
|
||||
interfaces, objects are mutable. That is, their contents can change with time. Therefore,
|
||||
while the (service, path) pair uniquely identifies an object, the information contained in
|
||||
this struct may no longer represent the object.
|
||||
|
||||
An object can contain interfaces and child (sub) objects.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Object::service
|
||||
The object's service name.
|
||||
|
||||
\sa parseObject, parseObjectTree
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Object::path
|
||||
The object's path on the service. This is an absolute path.
|
||||
|
||||
\sa parseObject, parseObjectTree
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Object::introspection
|
||||
The XML document fragment describing this object, its interfaces and sub-objects at the time
|
||||
of the parsing.
|
||||
|
||||
The result of parseObject with this XML data should be the same as the Object struct.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Object::interfaces
|
||||
The list of interface names in this object.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::Object::childObjects
|
||||
The list of child object names in this object. Note that this is a relative name, not an
|
||||
absolute path. To obtain the absolute path, concatenate with \ref path.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\struct QDBusIntrospection::ObjectTree
|
||||
\brief Complete information about one object node and its descendency.
|
||||
This struct contains the same data as QDBusIntrospection::Object, plus the actual data for the
|
||||
interfaces and child (sub) objects that was available in the XML document.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::ObjectTree::interfaceData
|
||||
A map of interfaces and their names.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\var QDBusIntrospection::ObjectTree::childObjectData
|
||||
A map of object paths and their data. The map key contains the relative path to the object.
|
||||
|
||||
Note this map contains only the child notes that do have information about the sub-object's
|
||||
contents. If the XML data did not contain the information, only the object name will be listed
|
||||
in childObjects, but not in childObjectData.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QDBusIntrospection::Annotations
|
||||
Contains a QMap of an annotation pair. The annotation's name is stored in the QMap key and
|
||||
must be unique. The annotation's value is stored in the QMap's value and is arbitrary.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QDBusIntrospection::Arguments
|
||||
Contains a list of arguments to either a Method or a Signal. The arguments' order is important.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QDBusIntrospection::Methods
|
||||
Contains a QMap of methods and their names. The method's name is stored in the map's key and
|
||||
is not necessarily unique. The order in which multiple methods with the same name are stored
|
||||
in this map is undefined.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QDBusIntrospection::Signals
|
||||
Contains a QMap of signals and their names. The signal's name is stored in the map's key and
|
||||
is not necessarily unique. The order in which multiple signals with the same name are stored
|
||||
in this map is undefined.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QDBusIntrospection::Properties
|
||||
Contains a QMap of properties and their names. Each property must have a unique name.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QDBusIntrospection::Interfaces
|
||||
Contains a QMap of interfaces and their names. Each interface has a unique name.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\typedef QDBusIntrospection::Objects
|
||||
Contains a QMap of objects and their paths relative to their immediate parent.
|
||||
|
||||
\sa parseObjectTree
|
||||
*/
|
||||
|
||||
/*!
|
||||
Parses the XML document fragment containing one interface.
|
||||
|
||||
The first element tag in this XML data must be either <node> or <interface>. If it is
|
||||
<node>, then the <interface> tag must be a child tag of the <node> one.
|
||||
|
||||
If there are multiple interfaces in this XML data, it is undefined which one will be
|
||||
returned.
|
||||
|
||||
\param xml the XML data to be parsed
|
||||
\returns the parsed interface
|
||||
*/
|
||||
QDBusIntrospection::Interface
|
||||
QDBusIntrospection::parseInterface(const QString &xml)
|
||||
{
|
||||
// be lazy
|
||||
Interfaces ifs = parseInterfaces(xml);
|
||||
if (ifs.isEmpty())
|
||||
return Interface();
|
||||
|
||||
// return the first in map order (probably alphabetical order)
|
||||
return *ifs.constBegin().value();
|
||||
}
|
||||
|
||||
/*!
|
||||
Parses the XML document fragment containing several interfaces.
|
||||
|
||||
If the first element tag in this document fragment is <node>, the interfaces parsed will
|
||||
be those found as child elements of the <node> tag.
|
||||
|
||||
\param xml the XML data to be parsed
|
||||
\returns the parsed interfaces
|
||||
*/
|
||||
QDBusIntrospection::Interfaces
|
||||
QDBusIntrospection::parseInterfaces(const QString &xml)
|
||||
{
|
||||
QDBusXmlParser parser(QString(), QString(), xml);
|
||||
return parser.interfaces();
|
||||
}
|
||||
|
||||
/*!
|
||||
Parses the XML document fragment containing one object.
|
||||
|
||||
The first element tag in this document must be <node>. If that tag does not contain
|
||||
a name attribute, the \a path argument will be used to determine the path of this
|
||||
object node.
|
||||
|
||||
This function does not parse the interfaces contained in the node, nor sub-object's contents.
|
||||
It will only list their names. If you need to know their contents, use parseObjectTree.
|
||||
|
||||
\param xml the XML data to be parsed
|
||||
\param service the service where this object is found
|
||||
\param path the absolute path to this node on the remote service
|
||||
\returns the parsed object
|
||||
*/
|
||||
QDBusIntrospection::Object
|
||||
QDBusIntrospection::parseObject(const QString &xml, const QString &service, const QString &path)
|
||||
{
|
||||
QDBusXmlParser parser(service, path, xml);
|
||||
QSharedDataPointer<QDBusIntrospection::Object> retval = parser.object();
|
||||
if (!retval)
|
||||
return QDBusIntrospection::Object();
|
||||
return *retval;
|
||||
}
|
||||
|
||||
/*!
|
||||
Parses the XML document fragment containing one object node and returns all the information
|
||||
about the interfaces and sub-objects.
|
||||
|
||||
The Objects map returned will contain the absolute path names in the key.
|
||||
|
||||
\param xml the XML data to be parsed
|
||||
\param service the service where this object is found
|
||||
\param path the absolute path to this node on the remote service
|
||||
\returns the parsed objects and interfaces
|
||||
*/
|
||||
QDBusIntrospection::ObjectTree
|
||||
QDBusIntrospection::parseObjectTree(const QString &xml, const QString &service, const QString &path)
|
||||
{
|
||||
QDBusXmlParser parser(service, path, xml);
|
||||
QSharedDataPointer<QDBusIntrospection::ObjectTree> retval = parser.objectTree();
|
||||
if (!retval)
|
||||
return QDBusIntrospection::ObjectTree();
|
||||
return *retval;
|
||||
}
|
||||
148
qt/qdbusintrospection.h
Normal file
148
qt/qdbusintrospection.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSINTROSPECTION_H
|
||||
#define QDBUSINTROSPECTION_H
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include "qdbustype.h"
|
||||
#include "qdbusmacros.h"
|
||||
|
||||
class QDBUS_EXPORT QDBusIntrospection
|
||||
{
|
||||
public:
|
||||
// forward declarations
|
||||
struct Argument;
|
||||
struct Method;
|
||||
struct Signal;
|
||||
struct Property;
|
||||
struct Interface;
|
||||
struct Object;
|
||||
struct ObjectTree;
|
||||
|
||||
// typedefs
|
||||
typedef QMap<QString, QString> Annotations;
|
||||
typedef QList<Argument> Arguments;
|
||||
typedef QMultiMap<QString, Method> Methods;
|
||||
typedef QMultiMap<QString, Signal> Signals;
|
||||
typedef QMap<QString, Property> Properties;
|
||||
typedef QMap<QString, QSharedDataPointer<Interface> > Interfaces;
|
||||
typedef QMap<QString, QSharedDataPointer<ObjectTree> > Objects;
|
||||
|
||||
public:
|
||||
// the structs
|
||||
|
||||
struct Argument
|
||||
{
|
||||
QDBusType type;
|
||||
QString name;
|
||||
|
||||
inline bool operator==(const Argument& other) const
|
||||
{ return name == other.name && type == other.type; }
|
||||
};
|
||||
|
||||
struct Method
|
||||
{
|
||||
QString name;
|
||||
Arguments inputArgs;
|
||||
Arguments outputArgs;
|
||||
Annotations annotations;
|
||||
|
||||
inline bool operator==(const Method& other) const
|
||||
{ return name == other.name && annotations == other.annotations &&
|
||||
inputArgs == other.inputArgs && outputArgs == other.outputArgs; }
|
||||
};
|
||||
|
||||
struct Signal
|
||||
{
|
||||
QString name;
|
||||
Arguments outputArgs;
|
||||
Annotations annotations;
|
||||
|
||||
inline bool operator==(const Signal& other) const
|
||||
{ return name == other.name && annotations == other.annotations &&
|
||||
outputArgs == other.outputArgs; }
|
||||
};
|
||||
|
||||
struct Property
|
||||
{
|
||||
enum Access { Read, Write, ReadWrite };
|
||||
QString name;
|
||||
QDBusType type;
|
||||
Access access;
|
||||
Annotations annotations;
|
||||
|
||||
inline bool operator==(const Property& other) const
|
||||
{ return access == other.access && name == other.name &&
|
||||
annotations == other.annotations && type == other.type; }
|
||||
};
|
||||
|
||||
struct Interface: public QSharedData
|
||||
{
|
||||
QString name;
|
||||
QString introspection;
|
||||
|
||||
Annotations annotations;
|
||||
Methods methods;
|
||||
Signals signals_;
|
||||
Properties properties;
|
||||
|
||||
inline bool operator==(const Interface &other) const
|
||||
{ return name == other.name; }
|
||||
};
|
||||
|
||||
struct Object: public QSharedData
|
||||
{
|
||||
QString service;
|
||||
QString path;
|
||||
QString introspection;
|
||||
|
||||
QStringList interfaces;
|
||||
QStringList childObjects;
|
||||
};
|
||||
|
||||
struct ObjectTree: public Object
|
||||
{
|
||||
Interfaces interfaceData;
|
||||
Objects childObjectData;
|
||||
};
|
||||
|
||||
public:
|
||||
static Interface parseInterface(const QString &xml);
|
||||
static Interfaces parseInterfaces(const QString &xml);
|
||||
static Object parseObject(const QString &xml, const QString &service = QString(),
|
||||
const QString &path = QString());
|
||||
static ObjectTree parseObjectTree(const QString &xml,
|
||||
const QString &service,
|
||||
const QString &path);
|
||||
|
||||
private:
|
||||
QDBusIntrospection();
|
||||
};
|
||||
|
||||
#endif
|
||||
36
qt/qdbusmacros.h
Normal file
36
qt/qdbusmacros.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* qdbusmessage.h QDBusMessage object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSMACROS_H
|
||||
#define QDBUSMACROS_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef QDBUS_EXPORT
|
||||
#ifdef QDBUS_MAKEDLL
|
||||
# define QDBUS_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define QDBUS_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusmarshall.cpp
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,21 +17,22 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusmarshall.h"
|
||||
#include "qdbustype.h"
|
||||
#include "qdbusvariant.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qvarlengtharray.h>
|
||||
#include <QtCore/qvector.h>
|
||||
#include <qdebug.h>
|
||||
#include <qvariant.h>
|
||||
#include <qlist.h>
|
||||
#include <qmap.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qvarlengtharray.h>
|
||||
#include <qvector.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
|
|
@ -60,6 +63,10 @@ static QVariant qFetchParameter(DBusMessageIter *it)
|
|||
switch (dbus_message_iter_get_arg_type(it)) {
|
||||
case DBUS_TYPE_BYTE:
|
||||
return qIterGet<unsigned char>(it);
|
||||
case DBUS_TYPE_INT16:
|
||||
return qIterGet<dbus_int16_t>(it);
|
||||
case DBUS_TYPE_UINT16:
|
||||
return qIterGet<dbus_uint16_t>(it);
|
||||
case DBUS_TYPE_INT32:
|
||||
return qIterGet<dbus_int32_t>(it);
|
||||
case DBUS_TYPE_UINT32:
|
||||
|
|
@ -78,15 +85,26 @@ static QVariant qFetchParameter(DBusMessageIter *it)
|
|||
return QString::fromUtf8(qIterGet<char *>(it));
|
||||
case DBUS_TYPE_ARRAY: {
|
||||
int arrayType = dbus_message_iter_get_element_type(it);
|
||||
if (arrayType == DBUS_TYPE_STRING || arrayType == DBUS_TYPE_OBJECT_PATH) {
|
||||
if (arrayType == DBUS_TYPE_STRING || arrayType == DBUS_TYPE_OBJECT_PATH ||
|
||||
arrayType == DBUS_TYPE_SIGNATURE) {
|
||||
return qFetchStringList(it);
|
||||
} else if (arrayType == DBUS_TYPE_BYTE) {
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_recurse(it, &sub);
|
||||
int len = dbus_message_iter_get_array_len(&sub);
|
||||
char* data;
|
||||
dbus_message_iter_get_fixed_array(&sub,&data,&len);
|
||||
return QByteArray(data,len);
|
||||
} else if (arrayType == DBUS_TYPE_DICT_ENTRY) {
|
||||
// ### support other types of maps?
|
||||
QMap<QString, QVariant> map;
|
||||
DBusMessageIter sub;
|
||||
|
||||
dbus_message_iter_recurse(it, &sub);
|
||||
if (!dbus_message_iter_has_next(&sub))
|
||||
// empty map
|
||||
return map;
|
||||
|
||||
do {
|
||||
DBusMessageIter itemIter;
|
||||
dbus_message_iter_recurse(&sub, &itemIter);
|
||||
|
|
@ -96,43 +114,30 @@ static QVariant qFetchParameter(DBusMessageIter *it)
|
|||
map.insertMulti(key, qFetchParameter(&itemIter));
|
||||
} while (dbus_message_iter_next(&sub));
|
||||
return map;
|
||||
} else {
|
||||
QList<QVariant> list;
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_recurse(it, &sub);
|
||||
if (!dbus_message_iter_has_next(&sub))
|
||||
return list;
|
||||
do {
|
||||
list.append(qFetchParameter(&sub));
|
||||
} while (dbus_message_iter_next(&sub));
|
||||
return list;
|
||||
}
|
||||
break; }
|
||||
}
|
||||
// fall through
|
||||
// common handling for structs and lists
|
||||
case DBUS_TYPE_STRUCT: {
|
||||
QList<QVariant> list;
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_recurse(it, &sub);
|
||||
if (!dbus_message_iter_has_next(&sub))
|
||||
return list;
|
||||
do {
|
||||
list.append(qFetchParameter(&sub));
|
||||
} while (dbus_message_iter_next(&sub));
|
||||
return list;
|
||||
}
|
||||
case DBUS_TYPE_VARIANT: {
|
||||
QDBusVariant dvariant;
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_recurse(it, &sub);
|
||||
dvariant.signature = QString::fromUtf8(dbus_message_iter_get_signature(&sub));
|
||||
dvariant.type = QDBusType(dbus_message_iter_get_signature(&sub));
|
||||
dvariant.value = qFetchParameter(&sub);
|
||||
return qVariantFromValue(dvariant);
|
||||
}
|
||||
#if 0
|
||||
case DBUS_TYPE_DICT: {
|
||||
QMap<QString, QVariant> map;
|
||||
DBusMessageIter sub;
|
||||
dbus_message
|
||||
if (dbus_message_iter_init_dict_iterator(it, &dictIt)) {
|
||||
do {
|
||||
map[QString::fromUtf8(dbus_message_iter_get_dict_key(&dictIt))] =
|
||||
qFetchParameter(&dictIt);
|
||||
} while (dbus_message_iter_next(&dictIt));
|
||||
}
|
||||
return map;
|
||||
break; }
|
||||
case DBUS_TYPE_CUSTOM:
|
||||
return qGetCustomValue(it);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
qWarning("Don't know how to handle type %d '%c'", dbus_message_iter_get_arg_type(it), dbus_message_iter_get_arg_type(it));
|
||||
return QVariant();
|
||||
|
|
@ -153,148 +158,305 @@ void QDBusMarshall::messageToList(QList<QVariant> &list, DBusMessage *message)
|
|||
} while (dbus_message_iter_next(&it));
|
||||
}
|
||||
|
||||
#define DBUS_APPEND(type,dtype,var) \
|
||||
type dtype##v=(var); \
|
||||
dbus_message_append_args(msg, dtype, &dtype##v, DBUS_TYPE_INVALID)
|
||||
#define DBUS_APPEND_LIST(type,dtype,var,size) \
|
||||
type dtype##v=(var); \
|
||||
dbus_message_append_args(msg, DBUS_TYPE_ARRAY, dtype, &dtype##v, size, DBUS_TYPE_INVALID)
|
||||
|
||||
|
||||
static void qAppendToMessage(DBusMessageIter *it, const QString &str)
|
||||
// convert the variant to the given type and return true if it worked.
|
||||
// if the type is not known, guess it from the variant and set.
|
||||
// return false if conversion failed.
|
||||
static bool checkType(QVariant &var, QDBusType &type)
|
||||
{
|
||||
QByteArray ba = str.toUtf8();
|
||||
const char *cdata = ba.constData();
|
||||
dbus_message_iter_append_basic(it, DBUS_TYPE_STRING, &cdata);
|
||||
}
|
||||
|
||||
static QVariant::Type qVariantListType(const QList<QVariant> &list)
|
||||
{
|
||||
// TODO - catch lists that have a list as first parameter
|
||||
QVariant::Type tp = list.value(0).type();
|
||||
if (tp < QVariant::Int || tp > QVariant::Double)
|
||||
return QVariant::Invalid;
|
||||
|
||||
for (int i = 1; i < list.count(); ++i) {
|
||||
const QVariant &var = list.at(i);
|
||||
if (var.type() != tp
|
||||
&& (var.type() != QVariant::List || qVariantListType(var.toList()) != tp))
|
||||
return QVariant::Invalid;
|
||||
if (!type.isValid()) {
|
||||
// guess it from the variant
|
||||
type = QDBusType::guessFromVariant(var);
|
||||
return true;
|
||||
}
|
||||
return tp;
|
||||
}
|
||||
|
||||
static const char *qDBusListType(const QList<QVariant> &list)
|
||||
{
|
||||
static const char *DBusArgs[] = { 0, 0, DBUS_TYPE_INT32_AS_STRING, DBUS_TYPE_UINT32_AS_STRING,
|
||||
DBUS_TYPE_INT64_AS_STRING, DBUS_TYPE_UINT64_AS_STRING, DBUS_TYPE_DOUBLE_AS_STRING };
|
||||
// only catch the conversions that won't work
|
||||
// let QVariant do the hard work
|
||||
|
||||
// QVariant can't convert QDBusVariant:
|
||||
if (var.userType() == qMetaTypeId<QDBusVariant>()) {
|
||||
if (type.dbusType() == DBUS_TYPE_VARIANT)
|
||||
return true; // no change
|
||||
|
||||
return DBusArgs[qVariantListType(list)];
|
||||
}
|
||||
// convert manually
|
||||
QDBusVariant dvariant = qvariant_cast<QDBusVariant>(var);
|
||||
var = dvariant.value;
|
||||
return checkType(var, type);
|
||||
}
|
||||
|
||||
if (type.dbusType() == DBUS_TYPE_VARIANT) {
|
||||
// variant can handle anything. Let it pass
|
||||
return true;
|
||||
}
|
||||
|
||||
static void qListToIterator(DBusMessageIter *it, const QList<QVariant> &list);
|
||||
|
||||
static void qVariantToIterator(DBusMessageIter *it, const QVariant &var)
|
||||
{
|
||||
static const int Variant2DBus[] = { DBUS_TYPE_INVALID,
|
||||
DBUS_TYPE_BOOLEAN, DBUS_TYPE_INT32, DBUS_TYPE_UINT32,
|
||||
DBUS_TYPE_INT64, DBUS_TYPE_UINT64, DBUS_TYPE_DOUBLE };
|
||||
|
||||
// these really are static asserts
|
||||
Q_ASSERT(QVariant::Invalid == 0);
|
||||
Q_ASSERT(QVariant::Int == 2);
|
||||
Q_ASSERT(QVariant::Double == 6);
|
||||
|
||||
switch (var.type()) {
|
||||
switch (var.userType()) {
|
||||
case QMetaType::Short:
|
||||
case QMetaType::UShort:
|
||||
case QMetaType::UChar:
|
||||
case QVariant::Int:
|
||||
case QVariant::UInt:
|
||||
case QVariant::LongLong:
|
||||
case QVariant::ULongLong:
|
||||
case QVariant::Double:
|
||||
dbus_message_iter_append_basic(it, Variant2DBus[var.type()],
|
||||
var.constData());
|
||||
break;
|
||||
case QVariant::String:
|
||||
qAppendToMessage(it, var.toString());
|
||||
break;
|
||||
if (type.isBasic())
|
||||
// QVariant can handle this on its own
|
||||
return true;
|
||||
|
||||
// cannot handle this
|
||||
qWarning("Invalid conversion from %s to '%s'", var.typeName(),
|
||||
type.dbusSignature().constData());
|
||||
var.clear();
|
||||
return false;
|
||||
|
||||
case QVariant::ByteArray:
|
||||
// make sure it's an "ARRAY of BYTE"
|
||||
if (type.qvariantType() != QVariant::ByteArray) {
|
||||
qWarning("Invalid conversion from %s to '%s'", var.typeName(),
|
||||
type.dbusSignature().constData());
|
||||
var.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case QVariant::StringList:
|
||||
// make sure it's "ARRAY of STRING"
|
||||
if (type.qvariantType() != QVariant::StringList) {
|
||||
qWarning("Invalid conversion from %s to '%s'", var.typeName(),
|
||||
type.dbusSignature().constData());
|
||||
var.clear();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
case QVariant::List:
|
||||
// could be either struct or array
|
||||
if (type.dbusType() != DBUS_TYPE_ARRAY && type.dbusType() != DBUS_TYPE_STRUCT) {
|
||||
qWarning("Invalid conversion from %s to '%s'", var.typeName(),
|
||||
type.dbusSignature().constData());
|
||||
var.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case QVariant::Map:
|
||||
if (!type.isMap()) {
|
||||
qWarning("Invalid conversion from %s to '%s'", var.typeName(),
|
||||
type.dbusSignature().constData());
|
||||
var.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case QVariant::Invalid:
|
||||
// create an empty variant
|
||||
var.convert(type.qvariantType());
|
||||
break;
|
||||
}
|
||||
|
||||
qWarning("Found unknown QVariant type %d (%s) when converting to DBus", (int)var.type(),
|
||||
var.typeName());
|
||||
var.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
static void qVariantToIteratorInternal(DBusMessageIter *it, const QVariant &var,
|
||||
const QDBusType &type);
|
||||
|
||||
static void qListToIterator(DBusMessageIter *it, const QList<QVariant> &list,
|
||||
const QDBusTypeList &list);
|
||||
|
||||
template<typename T>
|
||||
static void qIterAppend(DBusMessageIter *it, const QDBusType &type, T arg)
|
||||
{
|
||||
dbus_message_iter_append_basic(it, type.dbusType(), &arg);
|
||||
}
|
||||
|
||||
static void qAppendArrayToMessage(DBusMessageIter *it, const QDBusType &subType,
|
||||
const QVariant &var)
|
||||
{
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, subType.dbusSignature(), &sub);
|
||||
|
||||
switch (var.type())
|
||||
{
|
||||
case QVariant::StringList: {
|
||||
const QStringList list = var.toStringList();
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY,
|
||||
DBUS_TYPE_STRING_AS_STRING, &sub);
|
||||
for (int s = 0; s < list.count(); ++s)
|
||||
qAppendToMessage(&sub, list.at(s));
|
||||
dbus_message_iter_close_container(it, &sub);
|
||||
foreach (QString str, list)
|
||||
qIterAppend(&sub, subType, str.toUtf8().constData());
|
||||
break;
|
||||
}
|
||||
case QVariant::List: {
|
||||
const QList<QVariant> &list = var.toList();
|
||||
const char *listType = qDBusListType(list);
|
||||
if (!listType) {
|
||||
qWarning("Don't know how to marshall list.");
|
||||
break;
|
||||
}
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, listType, &sub);
|
||||
qListToIterator(&sub, list);
|
||||
dbus_message_iter_close_container(it, &sub);
|
||||
|
||||
case QVariant::ByteArray: {
|
||||
const QByteArray array = var.toByteArray();
|
||||
const char* cdata = array.constData();
|
||||
dbus_message_iter_append_fixed_array(&sub, DBUS_TYPE_BYTE, &cdata, array.length());
|
||||
break;
|
||||
}
|
||||
|
||||
case QVariant::Map: {
|
||||
// ### TODO - marshall more than qstring/qstring maps
|
||||
const QMap<QString, QVariant> &map = var.toMap();
|
||||
DBusMessageIter sub;
|
||||
QVarLengthArray<char, 16> sig;
|
||||
sig.append(DBUS_DICT_ENTRY_BEGIN_CHAR);
|
||||
sig.append(DBUS_TYPE_STRING);
|
||||
sig.append(DBUS_TYPE_STRING);
|
||||
sig.append(DBUS_DICT_ENTRY_END_CHAR);
|
||||
sig.append('\0');
|
||||
qDebug() << QString::fromAscii(sig.constData());
|
||||
dbus_message_iter_open_container(it, DBUS_TYPE_ARRAY, sig.constData(), &sub);
|
||||
const QVariantMap map = var.toMap();
|
||||
const QDBusTypeList& subTypes = subType.subTypes();
|
||||
for (QMap<QString, QVariant>::const_iterator mit = map.constBegin();
|
||||
mit != map.constEnd(); ++mit) {
|
||||
DBusMessageIter itemIterator;
|
||||
dbus_message_iter_open_container(&sub, DBUS_TYPE_DICT_ENTRY, 0, &itemIterator);
|
||||
qAppendToMessage(&itemIterator, mit.key());
|
||||
qAppendToMessage(&itemIterator, mit.value().toString());
|
||||
|
||||
// let the string be converted to QVariant
|
||||
qVariantToIteratorInternal(&itemIterator, mit.key(), subTypes[0]);
|
||||
qVariantToIteratorInternal(&itemIterator, mit.value(), subTypes[1]);
|
||||
|
||||
dbus_message_iter_close_container(&sub, &itemIterator);
|
||||
}
|
||||
dbus_message_iter_close_container(it, &sub);
|
||||
break;
|
||||
}
|
||||
case QVariant::UserType: {
|
||||
if (var.userType() == QMetaTypeId<QDBusVariant>::qt_metatype_id()) {
|
||||
DBusMessageIter sub;
|
||||
QDBusVariant dvariant = qvariant_cast<QDBusVariant>(var);
|
||||
dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT,
|
||||
dvariant.signature.toUtf8().constData(), &sub);
|
||||
qVariantToIterator(&sub, dvariant.value);
|
||||
dbus_message_iter_close_container(it, &sub);
|
||||
break;
|
||||
}
|
||||
|
||||
case QVariant::List: {
|
||||
const QVariantList list = var.toList();
|
||||
foreach (QVariant v, list)
|
||||
qVariantToIteratorInternal(&sub, v, subType);
|
||||
break;
|
||||
}
|
||||
// fall through
|
||||
|
||||
default:
|
||||
qWarning("Don't know how to handle type %s", var.typeName());
|
||||
qFatal("qAppendArrayToMessage got unknown type!");
|
||||
break;
|
||||
}
|
||||
|
||||
dbus_message_iter_close_container(it, &sub);
|
||||
}
|
||||
|
||||
static void qAppendStructToMessage(DBusMessageIter *it, const QDBusTypeList &typeList,
|
||||
const QVariantList &list)
|
||||
{
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_open_container(it, DBUS_TYPE_STRUCT, NULL, &sub);
|
||||
qListToIterator(&sub, list, typeList);
|
||||
dbus_message_iter_close_container(it, &sub);
|
||||
}
|
||||
|
||||
static void qAppendVariantToMessage(DBusMessageIter *it, const QDBusType & /* type */,
|
||||
const QVariant &var)
|
||||
{
|
||||
QVariant v;
|
||||
QDBusType t;
|
||||
|
||||
if (var.userType() == qMetaTypeId<QDBusVariant>()) {
|
||||
QDBusVariant dvariant = qvariant_cast<QDBusVariant>(var);
|
||||
v = dvariant.value;
|
||||
t = dvariant.type;
|
||||
}
|
||||
else {
|
||||
v = var;
|
||||
t = QDBusType::guessFromVariant(v);
|
||||
}
|
||||
|
||||
// now add this variant
|
||||
DBusMessageIter sub;
|
||||
dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, t.dbusSignature(), &sub);
|
||||
qVariantToIteratorInternal(&sub, v, t);
|
||||
dbus_message_iter_close_container(it, &sub);
|
||||
}
|
||||
|
||||
static void qVariantToIterator(DBusMessageIter *it, QVariant var, QDBusType type)
|
||||
{
|
||||
if (var.isNull() && !type.isValid())
|
||||
return; // cannot add a null like this
|
||||
if (!checkType(var, type))
|
||||
return; // type checking failed
|
||||
|
||||
qVariantToIteratorInternal(it, var, type);
|
||||
}
|
||||
|
||||
static void qVariantToIteratorInternal(DBusMessageIter *it, const QVariant &var,
|
||||
const QDBusType &type)
|
||||
{
|
||||
switch (type.dbusType()) {
|
||||
case DBUS_TYPE_BYTE:
|
||||
qIterAppend( it, type, static_cast<unsigned char>(var.toUInt()) );
|
||||
break;
|
||||
case DBUS_TYPE_BOOLEAN:
|
||||
qIterAppend( it, type, static_cast<dbus_bool_t>(var.toBool()) );
|
||||
break;
|
||||
case DBUS_TYPE_INT16:
|
||||
qIterAppend( it, type, static_cast<dbus_int16_t>(var.toInt()) );
|
||||
break;
|
||||
case DBUS_TYPE_UINT16:
|
||||
qIterAppend( it, type, static_cast<dbus_uint16_t>(var.toUInt()) );
|
||||
break;
|
||||
case DBUS_TYPE_INT32:
|
||||
qIterAppend( it, type, static_cast<dbus_int32_t>(var.toInt()) );
|
||||
break;
|
||||
case DBUS_TYPE_UINT32:
|
||||
qIterAppend( it, type, static_cast<dbus_uint32_t>(var.toUInt()) );
|
||||
break;
|
||||
case DBUS_TYPE_INT64:
|
||||
qIterAppend( it, type, static_cast<dbus_int64_t>(var.toLongLong()) );
|
||||
break;
|
||||
case DBUS_TYPE_UINT64:
|
||||
qIterAppend( it, type, static_cast<dbus_uint64_t>(var.toULongLong()) );
|
||||
break;
|
||||
case DBUS_TYPE_DOUBLE:
|
||||
qIterAppend( it, type, var.toDouble() );
|
||||
break;
|
||||
case DBUS_TYPE_STRING:
|
||||
case DBUS_TYPE_OBJECT_PATH:
|
||||
case DBUS_TYPE_SIGNATURE:
|
||||
qIterAppend( it, type, var.toString().toUtf8().constData() );
|
||||
break;
|
||||
|
||||
// compound types:
|
||||
case DBUS_TYPE_ARRAY:
|
||||
// could be many things
|
||||
qAppendArrayToMessage( it, type.arrayElement(), var );
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_VARIANT:
|
||||
qAppendVariantToMessage( it, type, var );
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_STRUCT:
|
||||
qAppendStructToMessage( it, type.subTypes(), var.toList() );
|
||||
break;
|
||||
|
||||
case DBUS_TYPE_DICT_ENTRY:
|
||||
qFatal("qVariantToIterator got a DICT_ENTRY!");
|
||||
break;
|
||||
|
||||
default:
|
||||
qWarning("Found unknown DBus type '%s'", type.dbusSignature().constData());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void qListToIterator(DBusMessageIter *it, const QList<QVariant> &list)
|
||||
{
|
||||
if (list.isEmpty())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < list.count(); ++i)
|
||||
qVariantToIterator(it, list.at(i));
|
||||
qVariantToIterator(it, list.at(i), QDBusType());
|
||||
}
|
||||
|
||||
void QDBusMarshall::listToMessage(const QList<QVariant> &list, DBusMessage *msg)
|
||||
void qListToIterator(DBusMessageIter *it, const QList<QVariant> &list, const QDBusTypeList &types)
|
||||
{
|
||||
int min = qMin(list.count(), types.count());
|
||||
for (int i = 0; i < min; ++i)
|
||||
qVariantToIterator(it, list.at(i), types.at(i));
|
||||
|
||||
for (int i = min; i < types.count(); ++i)
|
||||
// we're missing a few arguments, so add default parameters
|
||||
qVariantToIterator(it, QVariant(), types.at(i));
|
||||
}
|
||||
|
||||
void QDBusMarshall::listToMessage(const QList<QVariant> &list, DBusMessage *msg,
|
||||
const QString &signature)
|
||||
{
|
||||
Q_ASSERT(msg);
|
||||
DBusMessageIter it;
|
||||
dbus_message_iter_init_append(msg, &it);
|
||||
qListToIterator(&it, list);
|
||||
|
||||
if (signature.isEmpty())
|
||||
qListToIterator(&it, list);
|
||||
else
|
||||
qListToIterator(&it, list, QDBusTypeList(signature.toUtf8()));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusmarshall.h QDBusMarshall object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,8 +17,8 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -25,14 +27,15 @@
|
|||
|
||||
struct DBusMessage;
|
||||
|
||||
template <typename T> class QList;
|
||||
class QVariant;
|
||||
template <typename T>
|
||||
class QList;
|
||||
class QString;
|
||||
|
||||
class QDBusMarshall
|
||||
{
|
||||
public:
|
||||
static void listToMessage(const QList<QVariant> &list, DBusMessage *message);
|
||||
static void listToMessage(const QList<QVariant> &list, DBusMessage *message,
|
||||
const QString& signature);
|
||||
static void messageToList(QList<QVariant> &list, DBusMessage *message);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusmessage.cpp
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,19 +17,20 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusmessage.h"
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <qdebug.h>
|
||||
#include <qstringlist.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "qdbusmarshall.h"
|
||||
#include "qdbuserror.h"
|
||||
#include "qdbusmessage_p.h"
|
||||
|
||||
QDBusMessagePrivate::QDBusMessagePrivate(QDBusMessage *qq)
|
||||
|
|
@ -44,8 +47,31 @@ QDBusMessagePrivate::~QDBusMessagePrivate()
|
|||
}
|
||||
|
||||
///////////////
|
||||
/*!
|
||||
\class QDBusMessage
|
||||
\brief Represents one message sent or received over the DBus bus.
|
||||
|
||||
This object can represent any of four different types of messages possible on the bus
|
||||
(see MessageType)
|
||||
- Method calls
|
||||
- Method return values
|
||||
- Signal emissions
|
||||
- Error codes
|
||||
|
||||
Objects of this type are created with the four static functions signal, methodCall,
|
||||
methodReply and error.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Constructs a new DBus message representing a signal emission. A DBus signal is emitted
|
||||
from one application and is received by all applications that are listening for that signal
|
||||
from that interface.
|
||||
|
||||
\param path the path of the object that is emitting the signal
|
||||
\param interface the interface that is emitting the signal
|
||||
\param name the name of the signal (a.k.a. method name)
|
||||
\returns a QDBusMessage object that can be sent with with QDBusConnection::send
|
||||
*/
|
||||
QDBusMessage QDBusMessage::signal(const QString &path, const QString &interface,
|
||||
const QString &name)
|
||||
{
|
||||
|
|
@ -58,19 +84,58 @@ QDBusMessage QDBusMessage::signal(const QString &path, const QString &interface,
|
|||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new DBus message representing a method call. A method call always informs
|
||||
its destination address (service, path, interface and method).
|
||||
|
||||
The DBus bus allows calling a method on a given remote object without specifying the
|
||||
destination interface, if the method name is unique. However, if two interfaces on the
|
||||
remote object export the same method name, the result is undefined (one of the two may be
|
||||
called or an error may be returned).
|
||||
|
||||
When using DBus in a peer-to-peer context (i.e., not on a bus), the service parameter is
|
||||
optional.
|
||||
|
||||
Optionally, a signature parameter can be passed, indicating the type of the parameters to
|
||||
be marshalled over the bus. If there are more arguments thanentries in the signature, the
|
||||
tailing arguments will be silently dropped and not sent. If there are less arguments,
|
||||
default values will be inserted (default values are those created by QVariant::convert
|
||||
when a variant of type QVariant::Invalid is converted to the type).
|
||||
|
||||
The QDBusObject and QDBusInterface classes provide a simpler abstraction to synchronous
|
||||
method calling.
|
||||
|
||||
\param service the remote service to be called (can be a well-known name, a bus
|
||||
address or null)
|
||||
\param path the path of the object on the remote service to be called
|
||||
\param interface the remote interface that is wanted (can be null)
|
||||
\param method the remote method to be called (a.k.a., name)
|
||||
\param sig the DBus signature (set to null to discard processing and guess the
|
||||
method signature from the arguments; empty means no arguments)
|
||||
\returns a QDBusMessage object that can be sent with QDBusConnection::send,
|
||||
QDBusConnection::sendWithReply, or QDBusConnection::sendWithReplyAsync
|
||||
*/
|
||||
QDBusMessage QDBusMessage::methodCall(const QString &service, const QString &path,
|
||||
const QString &interface, const QString &method)
|
||||
const QString &interface, const QString &method,
|
||||
const QString &sig)
|
||||
{
|
||||
QDBusMessage message;
|
||||
message.d->type = DBUS_MESSAGE_TYPE_METHOD_CALL;
|
||||
message.d->service = service;
|
||||
message.d->path = path;
|
||||
message.d->interface = interface;
|
||||
message.d->method = method;
|
||||
message.d->name = method;
|
||||
message.d->signature = sig;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a new DBus message representing the return values from a called method.
|
||||
|
||||
\param other the method call DBus message that this is a reply to
|
||||
\returns a QDBusMessage object that can be sent with QDBusConnection::send
|
||||
*/
|
||||
QDBusMessage QDBusMessage::methodReply(const QDBusMessage &other)
|
||||
{
|
||||
Q_ASSERT(other.d->msg);
|
||||
|
|
@ -82,11 +147,63 @@ QDBusMessage QDBusMessage::methodReply(const QDBusMessage &other)
|
|||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a DBus message representing an error condition.
|
||||
|
||||
\param other the QDBusMessage object that generated this error
|
||||
\param name the DBus error name (error names must follow the same convention that
|
||||
interface names do)
|
||||
\param msg the error message
|
||||
\return a QDBusMessage object that can be sent with QDBusMessage::send
|
||||
*/
|
||||
QDBusMessage QDBusMessage::error(const QDBusMessage &other, const QString &name,
|
||||
const QString &msg)
|
||||
{
|
||||
Q_ASSERT(other.d->msg);
|
||||
|
||||
QDBusMessage message;
|
||||
message.d->type = DBUS_MESSAGE_TYPE_ERROR;
|
||||
message.d->name = name;
|
||||
message.d->message = msg;
|
||||
message.d->reply = dbus_message_ref(other.d->msg);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
\overload
|
||||
Constructs a DBus message representing an error condition.
|
||||
|
||||
\param other the QDBusMessage object that generated this error
|
||||
\param error the QDBusError object representing this error
|
||||
\return a QDBusMessage object that can be sent with QDBusMessage::send
|
||||
*/
|
||||
QDBusMessage QDBusMessage::error(const QDBusMessage &other, const QDBusError &error)
|
||||
{
|
||||
Q_ASSERT(other.d->msg);
|
||||
|
||||
QDBusMessage message;
|
||||
message.d->type = DBUS_MESSAGE_TYPE_ERROR;
|
||||
message.d->name = error.name();
|
||||
message.d->message = error.message();
|
||||
message.d->reply = dbus_message_ref(other.d->msg);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs an empty, invalid QDBusMessage object.
|
||||
|
||||
\sa methodCall, methodReply, signal, error
|
||||
*/
|
||||
QDBusMessage::QDBusMessage()
|
||||
{
|
||||
d = new QDBusMessagePrivate(this);
|
||||
}
|
||||
|
||||
/*!
|
||||
Constructs a copy of the other object.
|
||||
*/
|
||||
QDBusMessage::QDBusMessage(const QDBusMessage &other)
|
||||
: QList<QVariant>(other)
|
||||
{
|
||||
|
|
@ -94,12 +211,18 @@ QDBusMessage::QDBusMessage(const QDBusMessage &other)
|
|||
d->ref.ref();
|
||||
}
|
||||
|
||||
/*!
|
||||
Disposes of the object and frees any resources that were being held.
|
||||
*/
|
||||
QDBusMessage::~QDBusMessage()
|
||||
{
|
||||
if (!d->ref.deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
/*!
|
||||
Copies the contents of the other object.
|
||||
*/
|
||||
QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
|
||||
{
|
||||
QList<QVariant>::operator=(other);
|
||||
|
|
@ -107,14 +230,20 @@ QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
|
|||
return *this;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Constructs a DBusMessage object from this object. The returned value must be de-referenced
|
||||
with dbus_message_unref.
|
||||
*/
|
||||
DBusMessage *QDBusMessage::toDBusMessage() const
|
||||
{
|
||||
DBusMessage *msg = 0;
|
||||
|
||||
switch (d->type) {
|
||||
case DBUS_MESSAGE_TYPE_METHOD_CALL:
|
||||
msg = dbus_message_new_method_call(d->service.toUtf8().constData(),
|
||||
d->path.toUtf8().constData(), d->interface.toUtf8().constData(),
|
||||
d->method.toUtf8().constData());
|
||||
d->name.toUtf8().constData());
|
||||
break;
|
||||
case DBUS_MESSAGE_TYPE_SIGNAL:
|
||||
msg = dbus_message_new_signal(d->path.toUtf8().constData(),
|
||||
|
|
@ -123,14 +252,22 @@ DBusMessage *QDBusMessage::toDBusMessage() const
|
|||
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
|
||||
msg = dbus_message_new_method_return(d->reply);
|
||||
break;
|
||||
case DBUS_MESSAGE_TYPE_ERROR:
|
||||
msg = dbus_message_new_error(d->reply, d->name.toUtf8().constData(),
|
||||
d->message.toUtf8().constData());
|
||||
break;
|
||||
}
|
||||
if (!msg)
|
||||
return 0;
|
||||
|
||||
QDBusMarshall::listToMessage(*this, msg);
|
||||
QDBusMarshall::listToMessage(*this, msg, d->signature);
|
||||
return msg;
|
||||
}
|
||||
|
||||
/*!
|
||||
\internal
|
||||
Constructs a QDBusMessage by parsing the given DBusMessage object.
|
||||
*/
|
||||
QDBusMessage QDBusMessage::fromDBusMessage(DBusMessage *dmsg)
|
||||
{
|
||||
QDBusMessage message;
|
||||
|
|
@ -140,40 +277,94 @@ QDBusMessage QDBusMessage::fromDBusMessage(DBusMessage *dmsg)
|
|||
message.d->type = dbus_message_get_type(dmsg);
|
||||
message.d->path = QString::fromUtf8(dbus_message_get_path(dmsg));
|
||||
message.d->interface = QString::fromUtf8(dbus_message_get_interface(dmsg));
|
||||
message.d->name = QString::fromUtf8(dbus_message_get_member(dmsg));
|
||||
message.d->sender = QString::fromUtf8(dbus_message_get_sender(dmsg));
|
||||
message.d->name = message.d->type == DBUS_MESSAGE_TYPE_ERROR ?
|
||||
QString::fromUtf8(dbus_message_get_error_name(dmsg)) :
|
||||
QString::fromUtf8(dbus_message_get_member(dmsg));
|
||||
message.d->service = QString::fromUtf8(dbus_message_get_sender(dmsg));
|
||||
message.d->signature = QString::fromUtf8(dbus_message_get_signature(dmsg));
|
||||
message.d->msg = dbus_message_ref(dmsg);
|
||||
|
||||
QDBusMarshall::messageToList(message, dmsg);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
Creates a QDBusMessage that represents the same error as the QDBusError object.
|
||||
*/
|
||||
QDBusMessage QDBusMessage::fromError(const QDBusError &error)
|
||||
{
|
||||
QDBusMessage message;
|
||||
message.d->type = DBUS_MESSAGE_TYPE_ERROR;
|
||||
message.d->name = error.name();
|
||||
message << error.message();
|
||||
return message;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the path of the object that this message is being sent to (in the case of a
|
||||
method call) or being received from (for a signal).
|
||||
*/
|
||||
QString QDBusMessage::path() const
|
||||
{
|
||||
return d->path;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the interface of the method being called (in the case of a method call) or of
|
||||
the signal being received from.
|
||||
*/
|
||||
QString QDBusMessage::interface() const
|
||||
{
|
||||
return d->interface;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the name of the signal that was emitted or the name of the error that was
|
||||
received.
|
||||
\sa member
|
||||
*/
|
||||
QString QDBusMessage::name() const
|
||||
{
|
||||
return d->name;
|
||||
}
|
||||
|
||||
QString QDBusMessage::sender() const
|
||||
/*!
|
||||
\fn QDBusMessage::member
|
||||
Returns the name of the method being called.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn QDBusMessage::method
|
||||
\overload
|
||||
Returns the name of the method being called.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Returns the name of the service or the bus address of the remote method call.
|
||||
*/
|
||||
QString QDBusMessage::service() const
|
||||
{
|
||||
return d->sender;
|
||||
return d->service;
|
||||
}
|
||||
|
||||
/*!
|
||||
\fn QDBusMessage::sender
|
||||
Returns the unique name of the remote sender.
|
||||
*/
|
||||
|
||||
/*!
|
||||
Returns the timeout (in milliseconds) for this message to be processed.
|
||||
*/
|
||||
int QDBusMessage::timeout() const
|
||||
{
|
||||
return d->timeout;
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets the timeout for this message to be processed.
|
||||
|
||||
\param ms the time, in milliseconds
|
||||
*/
|
||||
void QDBusMessage::setTimeout(int ms)
|
||||
{
|
||||
d->timeout = ms;
|
||||
|
|
@ -205,6 +396,18 @@ int QDBusMessage::replySerialNumber() const
|
|||
return dbus_message_get_reply_serial(d->msg);
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the signature of the signal that was received or for the output arguments
|
||||
of a method call.
|
||||
*/
|
||||
QString QDBusMessage::signature() const
|
||||
{
|
||||
return d->signature;
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the message type.
|
||||
*/
|
||||
QDBusMessage::MessageType QDBusMessage::type() const
|
||||
{
|
||||
switch (d->type) {
|
||||
|
|
@ -222,11 +425,32 @@ QDBusMessage::MessageType QDBusMessage::type() const
|
|||
}
|
||||
|
||||
#ifndef QT_NO_DEBUG
|
||||
QDebug operator<<(QDebug dbg, QDBusMessage::MessageType t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case QDBusMessage::MethodCallMessage:
|
||||
return dbg << "MethodCall";
|
||||
case QDBusMessage::ReplyMessage:
|
||||
return dbg << "MethodReturn";
|
||||
case QDBusMessage::SignalMessage:
|
||||
return dbg << "Signal";
|
||||
case QDBusMessage::ErrorMessage:
|
||||
return dbg << "Error";
|
||||
default:
|
||||
return dbg << "Invalid";
|
||||
}
|
||||
}
|
||||
|
||||
QDebug operator<<(QDebug dbg, const QDBusMessage &msg)
|
||||
{
|
||||
dbg.nospace() << "QDBusMessage(" << msg.path() << ", " << msg.interface() << ", "
|
||||
<< msg.name() << ", " << msg.sender() << ", "
|
||||
<< static_cast<QList<QVariant> >(msg) << ")";
|
||||
dbg.nospace() << "QDBusMessage(type=" << msg.type()
|
||||
<< ", service=" << msg.service()
|
||||
<< ", path=" << msg.path()
|
||||
<< ", interface=" << msg.interface()
|
||||
<< ", name=" << msg.name()
|
||||
<< ", signature=" << msg.signature()
|
||||
<< ", contents=" << static_cast<QList<QVariant> >(msg) << ")";
|
||||
return dbg.space();
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusmessage.h QDBusMessage object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,22 +17,22 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSMESSAGE_H
|
||||
#define QDBUSMESSAGE_H
|
||||
|
||||
#include "dbus/qdbus.h"
|
||||
|
||||
#include "qdbusmacros.h"
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
class QDBusMessagePrivate;
|
||||
class QDBusError;
|
||||
struct DBusMessage;
|
||||
|
||||
class QDBUS_EXPORT QDBusMessage: public QList<QVariant>
|
||||
|
|
@ -49,23 +51,32 @@ public:
|
|||
|
||||
static QDBusMessage signal(const QString &path, const QString &interface,
|
||||
const QString &name);
|
||||
static QDBusMessage methodCall(const QString &service, const QString &path,
|
||||
const QString &interface, const QString &method);
|
||||
static QDBusMessage methodCall(const QString &destination, const QString &path,
|
||||
const QString &interface, const QString &method,
|
||||
const QString &signature = QString());
|
||||
static QDBusMessage methodReply(const QDBusMessage &other);
|
||||
static QDBusMessage error(const QDBusMessage &other, const QString &name,
|
||||
const QString &message = QString());
|
||||
static QDBusMessage error(const QDBusMessage &other, const QDBusError &error);
|
||||
|
||||
QString path() const;
|
||||
QString interface() const;
|
||||
QString name() const; //rename to member?
|
||||
QString sender() const; //rename to service?
|
||||
QString name() const;
|
||||
inline QString member() const { return name(); }
|
||||
inline QString method() const { return name(); }
|
||||
QString service() const;
|
||||
inline QString sender() const { return service(); }
|
||||
MessageType type() const;
|
||||
|
||||
int timeout() const;
|
||||
void setTimeout(int ms);
|
||||
|
||||
QString signature() const;
|
||||
|
||||
//protected:
|
||||
DBusMessage *toDBusMessage() const;
|
||||
static QDBusMessage fromDBusMessage(DBusMessage *dmsg);
|
||||
static QDBusMessage fromError(const QDBusError& error);
|
||||
int serialNumber() const;
|
||||
int replySerialNumber() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusmessage.h QDBusMessage private object
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,17 +17,16 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSMESSAGE_P_H
|
||||
#define QDBUSMESSAGE_P_H
|
||||
|
||||
#include <QtCore/qatomic.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
#include <qatomic.h>
|
||||
#include <qstring.h>
|
||||
struct DBusMessage;
|
||||
|
||||
class QDBusMessagePrivate
|
||||
|
|
@ -34,7 +35,7 @@ public:
|
|||
QDBusMessagePrivate(QDBusMessage *qq);
|
||||
~QDBusMessagePrivate();
|
||||
|
||||
QString path, interface, name, service, method, sender;
|
||||
QString service, path, interface, name, message, signature;
|
||||
DBusMessage *msg;
|
||||
DBusMessage *reply;
|
||||
QDBusMessage *q;
|
||||
|
|
|
|||
173
qt/qdbusobject.cpp
Normal file
173
qt/qdbusobject.cpp
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusmessage.h"
|
||||
#include "qdbusconnection.h"
|
||||
#include "qdbusobject.h"
|
||||
#include "qdbusinterface.h"
|
||||
#include "qdbusstandardinterfaces.h"
|
||||
#include "qdbuserror.h"
|
||||
|
||||
#include "qdbusxmlparser_p.h"
|
||||
#include "qdbusobject_p.h"
|
||||
#include "qdbusutil.h"
|
||||
|
||||
QDBusObject::QDBusObject(QDBusObjectPrivate* p, const QDBusConnection& conn)
|
||||
:d(p), m_conn(conn)
|
||||
{
|
||||
}
|
||||
|
||||
QDBusObject::QDBusObject(const QDBusConnection& conn, const QString& service, const QString& path)
|
||||
: m_conn(conn)
|
||||
{
|
||||
*this = m_conn.findObject(service, path);
|
||||
}
|
||||
|
||||
QDBusObject::QDBusObject(const QDBusInterface& iface)
|
||||
: m_conn(iface.connection())
|
||||
{
|
||||
*this = m_conn.findObject(iface.service(), iface.path());
|
||||
}
|
||||
|
||||
QDBusObject::QDBusObject(const QDBusObject& other)
|
||||
: d(other.d), m_conn(other.m_conn)
|
||||
{
|
||||
}
|
||||
|
||||
QDBusObject::~QDBusObject()
|
||||
{
|
||||
}
|
||||
|
||||
QDBusObject& QDBusObject::operator=(const QDBusObject& other)
|
||||
{
|
||||
#if 0
|
||||
if (other.d)
|
||||
other.d->ref.ref();
|
||||
|
||||
QDBusObjectPrivate* old = qAtomicSetPtr(&d, other.d);
|
||||
if (old && !old->ref.deref())
|
||||
m_conn.d->disposeOf(d);
|
||||
#endif
|
||||
d = other.d;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QDBusConnection QDBusObject::connection() const
|
||||
{
|
||||
return m_conn;
|
||||
}
|
||||
|
||||
QString QDBusObject::service() const
|
||||
{
|
||||
return d ? d->data->service : QString();
|
||||
}
|
||||
|
||||
QString QDBusObject::path() const
|
||||
{
|
||||
return d ? d->data->path : QString();
|
||||
}
|
||||
|
||||
QString QDBusObject::introspect() const
|
||||
{
|
||||
if (!d)
|
||||
// not connected
|
||||
return QString();
|
||||
|
||||
if (d->data->introspection.isNull()) {
|
||||
// Try to introspect
|
||||
QDBusIntrospectableInterface iface = *this;
|
||||
QString xml = iface.introspect();
|
||||
|
||||
if (!m_conn.lastError().isValid()) {
|
||||
// this will change the contents of d->data
|
||||
QDBusXmlParser::parse(d, xml);
|
||||
}
|
||||
}
|
||||
return d->data->introspection;
|
||||
}
|
||||
|
||||
QSharedDataPointer<QDBusIntrospection::Object> QDBusObject::introspectionData() const
|
||||
{
|
||||
QSharedDataPointer<QDBusIntrospection::Object> retval;
|
||||
if (d)
|
||||
retval = const_cast<QDBusIntrospection::Object*>(d->data);
|
||||
return retval;
|
||||
}
|
||||
|
||||
QStringList QDBusObject::interfaces() const
|
||||
{
|
||||
introspect();
|
||||
return d ? d->data->interfaces : QStringList();
|
||||
}
|
||||
|
||||
QMap<QString, QDBusObject> QDBusObject::children() const
|
||||
{
|
||||
QMap<QString, QDBusObject> retval;
|
||||
#if 0
|
||||
if (!d)
|
||||
return retval;
|
||||
|
||||
QString prefix = d->path;
|
||||
if (!prefix.endsWith('/'))
|
||||
prefix.append('/');
|
||||
foreach (QString sub, d->childObjects)
|
||||
retval.insert(sub, QDBusObject( m_conn.d->findObject(d->path, prefix + sub), m_conn ));
|
||||
|
||||
return retval;
|
||||
#endif
|
||||
qFatal("fixme!");
|
||||
return retval;
|
||||
}
|
||||
|
||||
bool QDBusObject::isValid() const
|
||||
{
|
||||
return d && m_conn.isConnected() && QDBusUtil::isValidBusName(d->data->service) &&
|
||||
QDBusUtil::isValidObjectPath(d->data->path);
|
||||
}
|
||||
|
||||
#if 0 // we don't have a way of determining if an object exists or not
|
||||
bool QDBusObject::exists() const
|
||||
{
|
||||
if (!isValid())
|
||||
return false;
|
||||
|
||||
// call a non-existant interface/method
|
||||
QDBusMessage msg = QDBusMessage::methodCall(d->service, d->path,
|
||||
"org.freedesktop.DBus.NonExistant", "NonExistant");
|
||||
QDBusMessage reply = m_conn.sendWithReply(msg);
|
||||
// ignore the reply
|
||||
|
||||
QDBusError err = m_conn.lastError();
|
||||
if (!err.isValid()) {
|
||||
qWarning("D-Bus call to %s:%s on a supposedly non-existant interface worked!",
|
||||
qPrintable(d->service), qPrintable(d->path));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (err.name == DBUS_ERROR_SERVICE_UNKNOWN ||
|
||||
err.name == DBUS_ERROR_BAD_ADDRESS
|
||||
return !m_conn.lastError().isValid();
|
||||
}
|
||||
#endif
|
||||
161
qt/qdbusobject.h
Normal file
161
qt/qdbusobject.h
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSOBJECT_H
|
||||
#define QDBUSOBJECT_H
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
|
||||
#include "qdbusconnection.h"
|
||||
#include "qdbusintrospection.h"
|
||||
|
||||
class QDBusInterface;
|
||||
class QDBusObject;
|
||||
|
||||
template<class Interface>
|
||||
inline Interface qdbus_cast(QDBusObject& obj, Interface * = 0);
|
||||
|
||||
template<class Interface>
|
||||
inline const Interface qdbus_cast(const QDBusObject& obj, Interface * = 0);
|
||||
|
||||
class QDBusObjectPrivate;
|
||||
/**
|
||||
* QDBusObject
|
||||
* Base object for DBUS objects imported and exported.
|
||||
*/
|
||||
class QDBUS_EXPORT QDBusObject
|
||||
{
|
||||
friend class QDBusConnection;
|
||||
public:
|
||||
// public constructors
|
||||
/**
|
||||
* Construct a QDBusObject referencing the remote object given.
|
||||
*/
|
||||
QDBusObject(const QDBusConnection& conn, const QString& service, const QString& path);
|
||||
|
||||
/**
|
||||
* Copy constructor.
|
||||
*/
|
||||
QDBusObject(const QDBusObject& other);
|
||||
|
||||
/**
|
||||
* Construct from an interface.
|
||||
*/
|
||||
QDBusObject(const QDBusInterface& iface);
|
||||
|
||||
// public destructors
|
||||
/**
|
||||
* Destructor.
|
||||
*/
|
||||
~QDBusObject();
|
||||
|
||||
public:
|
||||
// public functions
|
||||
|
||||
/**
|
||||
* Assignment operator
|
||||
*/
|
||||
QDBusObject& operator=(const QDBusObject&);
|
||||
|
||||
/**
|
||||
* Returns the connection this object is bound to.
|
||||
*/
|
||||
QDBusConnection connection() const;
|
||||
|
||||
/**
|
||||
* Returns the service this object is associated to.
|
||||
*/
|
||||
QString service() const;
|
||||
|
||||
/**
|
||||
* Returns the path on the service this object is on.
|
||||
*/
|
||||
QString path() const;
|
||||
|
||||
/**
|
||||
* Returns the introspection XML data of this object node.
|
||||
*/
|
||||
QString introspect() const;
|
||||
|
||||
/**
|
||||
* Returns the introspection data for this object node.
|
||||
*/
|
||||
QSharedDataPointer<QDBusIntrospection::Object> introspectionData() const;
|
||||
|
||||
/**
|
||||
* Returns all the interfaces in this object.
|
||||
*/
|
||||
QStringList interfaces() const;
|
||||
|
||||
/**
|
||||
* Returns all the children object in this object.
|
||||
*/
|
||||
QMap<QString, QDBusObject> children() const;
|
||||
|
||||
/**
|
||||
* Returns true if the object being referenced exists.
|
||||
*/
|
||||
//bool exists() const;
|
||||
|
||||
/**
|
||||
* Returns true if we're referencing a valid object.
|
||||
*/
|
||||
bool isValid() const;
|
||||
|
||||
/**
|
||||
* Cast this object to an interface, if possible.
|
||||
*/
|
||||
template<typename Interface>
|
||||
inline operator Interface()
|
||||
{ return qdbus_cast<Interface>(*this); }
|
||||
|
||||
/**
|
||||
* Cast this object to an interface, if possible.
|
||||
*/
|
||||
template<typename Interface>
|
||||
inline operator const Interface() const
|
||||
{ return qdbus_cast<Interface>(*this); }
|
||||
|
||||
private:
|
||||
QDBusObject(QDBusObjectPrivate*, const QDBusConnection& conn);
|
||||
QSharedDataPointer<QDBusObjectPrivate> d;
|
||||
QDBusConnection m_conn;
|
||||
};
|
||||
|
||||
template<class Interface>
|
||||
inline Interface qdbus_cast(QDBusObject& obj, Interface *)
|
||||
{
|
||||
return Interface(obj);
|
||||
}
|
||||
|
||||
template<class Interface>
|
||||
inline const Interface qdbus_cast(const QDBusObject& obj, Interface *)
|
||||
{
|
||||
return Interface(obj);
|
||||
}
|
||||
|
||||
#endif // QDBUSOBJECT_H
|
||||
69
qt/qdbusobject_p.h
Normal file
69
qt/qdbusobject_p.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the public API. This header file may
|
||||
// change from version to version without notice, or even be
|
||||
// removed.
|
||||
//
|
||||
// We mean it.
|
||||
//
|
||||
//
|
||||
|
||||
#ifndef QDBUSOBJECTPRIVATE_H
|
||||
#define QDBUSOBJECTPRIVATE_H
|
||||
|
||||
#include "QtCore/qatomic.h"
|
||||
#include "QtCore/qstringlist.h"
|
||||
#include "qdbusobject.h"
|
||||
#include "qdbusinterface.h"
|
||||
#include "qdbusconnection_p.h"
|
||||
|
||||
class QDBusObject;
|
||||
class QDBusInterface;
|
||||
class QDBusXmlParser;
|
||||
|
||||
class QDBusObjectPrivate: public QSharedData
|
||||
{
|
||||
public:
|
||||
inline QDBusObjectPrivate(QDBusConnectionPrivate* ptr, const QString &service,
|
||||
const QString &path)
|
||||
: parent(ptr),
|
||||
data( )
|
||||
{
|
||||
QDBusIntrospection::Object * d = ptr->findObject(service, path);
|
||||
d->ref.ref();
|
||||
data = d;
|
||||
}
|
||||
|
||||
inline ~QDBusObjectPrivate()
|
||||
{ parent->disposeOf(this); }
|
||||
|
||||
QDBusConnectionPrivate* parent;
|
||||
const QDBusIntrospection::Object* data;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusserver.cpp
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,8 +17,8 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef QDBUSSERVER_H
|
||||
#define QDBUSSERVER_H
|
||||
|
||||
#include "dbus/qdbus.h"
|
||||
#include "qdbusmacros.h"
|
||||
#include <QtCore/qobject.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
|
|
|
|||
114
qt/qdbusstandardinterfaces.cpp
Normal file
114
qt/qdbusstandardinterfaces.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusstandardinterfaces.h"
|
||||
|
||||
QDBusPeerInterface::~QDBusPeerInterface()
|
||||
{
|
||||
}
|
||||
|
||||
QDBusIntrospectableInterface::~QDBusIntrospectableInterface()
|
||||
{
|
||||
}
|
||||
|
||||
QDBusPropertiesInterface::~QDBusPropertiesInterface()
|
||||
{
|
||||
}
|
||||
|
||||
QDBusBusInterface::~QDBusBusInterface()
|
||||
{
|
||||
}
|
||||
|
||||
const char* QDBusBusInterface::staticIntrospectionData()
|
||||
{
|
||||
// FIXME!
|
||||
// This should be auto-generated!
|
||||
|
||||
return
|
||||
"<interface name=\"org.freedesktop.DBus\">"
|
||||
"<method name=\"RequestName\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"in\" type=\"u\"/>"
|
||||
"<arg direction=\"out\" type=\"u\"/>"
|
||||
"</method>"
|
||||
"<method name=\"ReleaseName\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"out\" type=\"u\"/>"
|
||||
"</method>"
|
||||
"<method name=\"StartServiceByName\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"in\" type=\"u\"/>"
|
||||
"<arg direction=\"out\" type=\"u\"/>"
|
||||
"</method>"
|
||||
"<method name=\"Hello\">"
|
||||
"<arg direction=\"out\" type=\"s\"/>"
|
||||
"</method>"
|
||||
"<method name=\"NameHasOwner\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"out\" type=\"b\"/>"
|
||||
"</method>"
|
||||
"<method name=\"ListNames\">"
|
||||
"<arg direction=\"out\" type=\"as\"/>"
|
||||
"</method>"
|
||||
"<method name=\"AddMatch\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"</method>"
|
||||
"<method name=\"RemoveMatch\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"</method>"
|
||||
"<method name=\"GetNameOwner\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"out\" type=\"s\"/>"
|
||||
"</method>"
|
||||
"<method name=\"ListQueuedOwners\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"out\" type=\"as\"/>"
|
||||
"</method>"
|
||||
"<method name=\"GetConnectionUnixUser\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"out\" type=\"u\"/>"
|
||||
"</method>"
|
||||
"<method name=\"GetConnectionUnixProcessID\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"out\" type=\"u\"/>"
|
||||
"</method>"
|
||||
"<method name=\"GetConnectionSELinuxSecurityContext\">"
|
||||
"<arg direction=\"in\" type=\"s\"/>"
|
||||
"<arg direction=\"out\" type=\"ay\"/>"
|
||||
"</method>"
|
||||
"<method name=\"ReloadConfig\">"
|
||||
"</method>"
|
||||
"<signal name=\"NameOwnerChanged\">"
|
||||
"<arg type=\"s\"/>"
|
||||
"<arg type=\"s\"/>"
|
||||
"<arg type=\"s\"/>"
|
||||
"</signal>"
|
||||
"<signal name=\"NameLost\">"
|
||||
"<arg type=\"s\"/>"
|
||||
"</signal>"
|
||||
"<signal name=\"NameAcquired\">"
|
||||
"<arg type=\"s\"/>"
|
||||
"</signal>"
|
||||
"</interface>";
|
||||
}
|
||||
218
qt/qdbusstandardinterfaces.h
Normal file
218
qt/qdbusstandardinterfaces.h
Normal file
|
|
@ -0,0 +1,218 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUS_STANDARD_INTERFACES_H
|
||||
#define QDBUS_STANDARD_INTERFACES_H
|
||||
|
||||
#include "qdbusinterface.h"
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
class QDBusConnection;
|
||||
|
||||
class QDBUS_EXPORT QDBusPeerInterface: public QDBusInterface
|
||||
{
|
||||
public:
|
||||
static inline const char* staticInterfaceName()
|
||||
{ return DBUS_INTERFACE_PEER; }
|
||||
|
||||
static inline const char* staticIntrospectionData()
|
||||
{
|
||||
return
|
||||
"<interface name=\"org.freedesktop.DBus.Peer\">"
|
||||
"<method name=\"Ping\" />"
|
||||
"</interface>";
|
||||
}
|
||||
|
||||
public:
|
||||
explicit QDBusPeerInterface(const QDBusObject& obj)
|
||||
: QDBusInterface(obj, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
QDBusPeerInterface(QDBusConnection& conn, const QString& service, const QString& path)
|
||||
: QDBusInterface(conn, service, path, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
~QDBusPeerInterface();
|
||||
|
||||
inline virtual QString introspectionData() const
|
||||
{ return staticIntrospectionData(); }
|
||||
|
||||
inline void ping()
|
||||
{ call(QLatin1String("Ping")); }
|
||||
};
|
||||
|
||||
class QDBUS_EXPORT QDBusIntrospectableInterface: public QDBusInterface
|
||||
{
|
||||
public:
|
||||
static inline const char* staticInterfaceName()
|
||||
{ return DBUS_INTERFACE_INTROSPECTABLE; }
|
||||
|
||||
static inline const char* staticIntrospectionData()
|
||||
{
|
||||
return
|
||||
"<interface name=\"org.freedesktop.DBus.Introspectable\">"
|
||||
"<method name=\"Introspect\">"
|
||||
"<arg name=\"xml_data\" type=\"s\" direction=\"out\" />"
|
||||
"</method>"
|
||||
"</interface>";
|
||||
}
|
||||
public:
|
||||
explicit QDBusIntrospectableInterface(const QDBusObject& obj)
|
||||
: QDBusInterface(obj, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
QDBusIntrospectableInterface(QDBusConnection& conn, const QString& service, const QString& path)
|
||||
: QDBusInterface(conn, service, path, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
~QDBusIntrospectableInterface();
|
||||
|
||||
inline virtual QString introspectionData() const
|
||||
{ return staticIntrospectionData(); }
|
||||
|
||||
inline QString introspect()
|
||||
{ return call(QLatin1String("Introspect")).at(0).toString(); }
|
||||
};
|
||||
|
||||
class QDBUS_EXPORT QDBusPropertiesInterface: public QDBusInterface
|
||||
{
|
||||
public:
|
||||
static inline const char* staticInterfaceName()
|
||||
{ return DBUS_INTERFACE_PROPERTIES; }
|
||||
|
||||
static inline const char* staticIntrospectionData()
|
||||
{
|
||||
return
|
||||
"<interface name=\"org.freedesktop.DBus.Properties\">"
|
||||
"<method name=\"Get\">"
|
||||
"<arg name=\"interface_name\" type=\"s\" direction=\"in\"/>"
|
||||
"<arg name=\"property_name\" type=\"s\" direction=\"in\"/>"
|
||||
"<arg name=\"value\" type=\"v\" direction=\"out\"/>"
|
||||
"</method>"
|
||||
"<method name=\"Set\">"
|
||||
"<arg name=\"interface_name\" type=\"s\" direction=\"in\"/>"
|
||||
"<arg name=\"property_name\" type=\"s\" direction=\"in\"/>"
|
||||
"<arg name=\"value\" type=\"v\" direction=\"in\"/>"
|
||||
"</method>";
|
||||
}
|
||||
public:
|
||||
explicit QDBusPropertiesInterface(const QDBusObject& obj)
|
||||
: QDBusInterface(obj, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
QDBusPropertiesInterface(QDBusConnection& conn, const QString& service, const QString& path)
|
||||
: QDBusInterface(conn, service, path, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
~QDBusPropertiesInterface();
|
||||
|
||||
inline virtual QString introspectionData() const
|
||||
{ return staticIntrospectionData(); }
|
||||
|
||||
inline void set(const QString& interfaceName, const QString& propertyName, QVariant value)
|
||||
{ call(QLatin1String("Set.ssv"), interfaceName, propertyName, value); }
|
||||
|
||||
inline QVariant get(const QString& interfaceName, const QString& propertyName)
|
||||
{ return call(QLatin1String("Get.ss"), interfaceName, propertyName).at(0); }
|
||||
};
|
||||
|
||||
class QDBUS_EXPORT QDBusBusInterface: public QDBusInterface
|
||||
{
|
||||
public:
|
||||
static inline const char* staticInterfaceName()
|
||||
{ return DBUS_INTERFACE_DBUS; }
|
||||
|
||||
static const char* staticIntrospectionData();
|
||||
|
||||
public:
|
||||
explicit QDBusBusInterface(const QDBusObject& obj)
|
||||
: QDBusInterface(obj, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
QDBusBusInterface(QDBusConnection& conn, const QString& service, const QString& path)
|
||||
: QDBusInterface(conn, service, path, staticInterfaceName())
|
||||
{ }
|
||||
|
||||
~QDBusBusInterface();
|
||||
|
||||
inline virtual QString introspectionData() const
|
||||
{ return staticIntrospectionData(); }
|
||||
|
||||
inline unsigned requestName(const QString& name, unsigned flags)
|
||||
{ return call(QLatin1String("RequestName.su"), name, flags).at(0).toUInt(); }
|
||||
|
||||
inline unsigned releaseName(const QString& name)
|
||||
{ return call(QLatin1String("ReleaseName.s"), name).at(0).toUInt(); }
|
||||
|
||||
inline unsigned startServiceByName(const QString& name, unsigned flags)
|
||||
{ return call(QLatin1String("StartServiceByName.su"), name, flags).at(0).toUInt(); }
|
||||
|
||||
inline QString Hello()
|
||||
{ return call(QLatin1String("Hello")).at(0).toString(); }
|
||||
|
||||
inline bool nameHasOwner(const QString& name)
|
||||
{ return call(QLatin1String("NameHasOwner.s"), name).at(0).toBool(); }
|
||||
|
||||
inline QStringList listNames()
|
||||
{ return call(QLatin1String("ListNames")).at(0).toStringList(); }
|
||||
|
||||
inline void addMatch(const QString& rule)
|
||||
{ call(QLatin1String("AddMatch"), rule); }
|
||||
|
||||
inline void removeMatch(const QString& rule)
|
||||
{ call(QLatin1String("RemoveMatch"), rule); }
|
||||
|
||||
inline QString getNameOwner(const QString& name)
|
||||
{ return call(QLatin1String("GetNameOwner.s"), name).at(0).toString(); }
|
||||
|
||||
inline QStringList listQueuedOwners(const QString& name)
|
||||
{ return call(QLatin1String("ListQueuedOwners.s"), name).at(0).toStringList(); }
|
||||
|
||||
inline quint32 getConnectionUnixUser(const QString& connectionName)
|
||||
{ return call(QLatin1String("GetConnectionUnixUser.s"), connectionName).at(0).toUInt(); }
|
||||
|
||||
inline quint32 getConnectionUnixProcessID(const QString& connectionName)
|
||||
{ return call(QLatin1String("GetConnectionUnixProcessID.s"), connectionName).at(0).toUInt(); }
|
||||
|
||||
inline QByteArray getConnectionSELinuxSecurityContext(const QString& connectionName)
|
||||
{ return call(QLatin1String("GetConnectionSELinuxSecurityContext.s"), connectionName).at(0).toByteArray(); }
|
||||
|
||||
inline void reloadConfig()
|
||||
{ call(QLatin1String("ReloadConfig")); }
|
||||
};
|
||||
|
||||
|
||||
namespace org {
|
||||
namespace freedesktop {
|
||||
namespace DBus {
|
||||
typedef ::QDBusPeerInterface Peer;
|
||||
typedef ::QDBusIntrospectableInterface Introspectable;
|
||||
typedef ::QDBusPropertiesInterface Properties;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
116
qt/qdbusthread.cpp
Normal file
116
qt/qdbusthread.cpp
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/* qdbusintegrator.cpp QDBusConnection private implementation
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
#include <QtCore/qwaitcondition.h>
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
struct DBusMutex: public QMutex
|
||||
{
|
||||
inline DBusMutex()
|
||||
: QMutex( QMutex::NonRecursive )
|
||||
{ }
|
||||
|
||||
static DBusMutex* mutex_new()
|
||||
{
|
||||
return new DBusMutex;
|
||||
}
|
||||
|
||||
static void mutex_free(DBusMutex *mutex)
|
||||
{
|
||||
delete mutex;
|
||||
}
|
||||
|
||||
static dbus_bool_t mutex_lock(DBusMutex *mutex)
|
||||
{
|
||||
mutex->lock();
|
||||
return true;
|
||||
}
|
||||
|
||||
static dbus_bool_t mutex_unlock(DBusMutex *mutex)
|
||||
{
|
||||
mutex->unlock();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct DBusCondVar: public QWaitCondition
|
||||
{
|
||||
inline DBusCondVar()
|
||||
{ }
|
||||
|
||||
static DBusCondVar* condvar_new()
|
||||
{
|
||||
return new DBusCondVar;
|
||||
}
|
||||
|
||||
static void condvar_free(DBusCondVar *cond)
|
||||
{
|
||||
delete cond;
|
||||
}
|
||||
|
||||
static void condvar_wait(DBusCondVar *cond, DBusMutex *mutex)
|
||||
{
|
||||
cond->wait(mutex);
|
||||
}
|
||||
|
||||
static dbus_bool_t condvar_wait_timeout(DBusCondVar *cond, DBusMutex *mutex, int msec)
|
||||
{
|
||||
return cond->wait(mutex, msec);
|
||||
}
|
||||
|
||||
static void condvar_wake_one(DBusCondVar *cond)
|
||||
{
|
||||
cond->wakeOne();
|
||||
}
|
||||
|
||||
static void condvar_wake_all(DBusCondVar *cond)
|
||||
{
|
||||
cond->wakeAll();
|
||||
}
|
||||
};
|
||||
|
||||
bool qDBusInitThreads()
|
||||
{
|
||||
static DBusThreadFunctions fcn = {
|
||||
DBUS_THREAD_FUNCTIONS_ALL_MASK,
|
||||
DBusMutex::mutex_new,
|
||||
DBusMutex::mutex_free,
|
||||
DBusMutex::mutex_lock,
|
||||
DBusMutex::mutex_unlock,
|
||||
DBusCondVar::condvar_new,
|
||||
DBusCondVar::condvar_free,
|
||||
DBusCondVar::condvar_wait,
|
||||
DBusCondVar::condvar_wait_timeout,
|
||||
DBusCondVar::condvar_wake_one,
|
||||
DBusCondVar::condvar_wake_all,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
dbus_threads_init(&fcn);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
1151
qt/qdbustype.cpp
Normal file
1151
qt/qdbustype.cpp
Normal file
File diff suppressed because it is too large
Load diff
119
qt/qdbustype.h
Normal file
119
qt/qdbustype.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSTYPE_H
|
||||
#define QDBUSTYPE_H
|
||||
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include "qdbusmacros.h"
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
// forward declaration
|
||||
class QDBusTypeList;
|
||||
|
||||
class QDBusTypePrivate;
|
||||
class QDBUS_EXPORT QDBusType
|
||||
{
|
||||
public:
|
||||
enum StringFormat
|
||||
{
|
||||
ConventionalNames,
|
||||
QtNames,
|
||||
QVariantNames
|
||||
};
|
||||
|
||||
QDBusType();
|
||||
explicit QDBusType(int type);
|
||||
explicit QDBusType(QVariant::Type type);
|
||||
explicit QDBusType(const char* signature);
|
||||
explicit QDBusType(DBusSignatureIter*);
|
||||
explicit QDBusType(const QString& str);
|
||||
explicit QDBusType(const QByteArray& str);
|
||||
QDBusType(const QDBusType& other);
|
||||
|
||||
~QDBusType();
|
||||
|
||||
QDBusType& operator=(const QDBusType& other);
|
||||
|
||||
QVariant::Type qvariantType() const;
|
||||
|
||||
int dbusType() const;
|
||||
QByteArray dbusSignature() const;
|
||||
bool isValid() const;
|
||||
bool isBasic() const;
|
||||
bool isContainer() const;
|
||||
|
||||
QDBusTypeList subTypes() const;
|
||||
|
||||
bool isArray() const;
|
||||
QDBusType arrayElement() const;
|
||||
|
||||
bool isMap() const;
|
||||
QDBusType mapKey() const;
|
||||
QDBusType mapValue() const;
|
||||
|
||||
bool operator==(const QDBusType& other) const;
|
||||
|
||||
QString toString(StringFormat = QtNames) const;
|
||||
|
||||
static QVariant::Type qvariantType(int type);
|
||||
static QVariant::Type qvariantType(const char* signature);
|
||||
static int dbusType(QVariant::Type);
|
||||
static const char* dbusSignature(QVariant::Type);
|
||||
|
||||
enum VariantListMode {
|
||||
ListIsArray,
|
||||
ListIsStruct
|
||||
};
|
||||
static QDBusType guessFromVariant(const QVariant &variant, VariantListMode = ListIsArray);
|
||||
|
||||
private:
|
||||
QSharedDataPointer<QDBusTypePrivate> d;
|
||||
};
|
||||
|
||||
class QDBUS_EXPORT QDBusTypeList: public QList<QDBusType>
|
||||
{
|
||||
public:
|
||||
inline QDBusTypeList() { }
|
||||
inline QDBusTypeList(const QDBusTypeList& other)
|
||||
: QList<QDBusType>(other)
|
||||
{ }
|
||||
inline QDBusTypeList(const QList<QDBusType>& other)
|
||||
: QList<QDBusType>(other)
|
||||
{ }
|
||||
QDBusTypeList(const char* signature);
|
||||
QDBusTypeList(DBusSignatureIter*);
|
||||
|
||||
bool canBeMap() const;
|
||||
|
||||
inline QDBusTypeList& operator<<(const QDBusType& item)
|
||||
{ QList<QDBusType>::operator<<(item); return *this; }
|
||||
|
||||
QByteArray dbusSignature() const;
|
||||
};
|
||||
|
||||
#endif // QDBUSTYPE_H
|
||||
133
qt/qdbusutil.cpp
Normal file
133
qt/qdbusutil.cpp
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusutil.h"
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include <QtCore/qstringlist.h>
|
||||
#include <QtCore/qregexp.h>
|
||||
|
||||
namespace QDBusUtil
|
||||
{
|
||||
|
||||
bool isValidInterfaceName(const QString& ifaceName)
|
||||
{
|
||||
if (ifaceName.isEmpty() || ifaceName.length() > DBUS_MAXIMUM_NAME_LENGTH)
|
||||
return false;
|
||||
|
||||
QStringList parts = ifaceName.split('.');
|
||||
if (parts.count() < 2)
|
||||
return false; // at least two parts
|
||||
|
||||
foreach (QString part, parts)
|
||||
if (!isValidMemberName(part))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidUniqueConnectionName(const QString &connName)
|
||||
{
|
||||
if (connName.isEmpty() || connName.length() > DBUS_MAXIMUM_NAME_LENGTH ||
|
||||
!connName.startsWith(':'))
|
||||
return false;
|
||||
|
||||
QStringList parts = connName.mid(1).split('.');
|
||||
if (parts.count() < 1)
|
||||
return false;
|
||||
|
||||
QRegExp regex("[a-zA-Z0-9_-]+");
|
||||
foreach (QString part, parts)
|
||||
if (!regex.exactMatch(part))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidBusName(const QString &busName)
|
||||
{
|
||||
if (busName.isEmpty() || busName.length() > DBUS_MAXIMUM_NAME_LENGTH)
|
||||
return false;
|
||||
|
||||
if (busName.startsWith(':'))
|
||||
return isValidUniqueConnectionName(busName);
|
||||
|
||||
QStringList parts = busName.split('.');
|
||||
if (parts.count() < 1)
|
||||
return false;
|
||||
|
||||
QRegExp regex("[a-zA-Z_-][a-zA-Z0-9_-]*");
|
||||
foreach (QString part, parts)
|
||||
if (!regex.exactMatch(part))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidMemberName(const QString &memberName)
|
||||
{
|
||||
if (memberName.isEmpty() || memberName.length() > DBUS_MAXIMUM_NAME_LENGTH)
|
||||
return false;
|
||||
|
||||
QRegExp regex("[a-zA-Z0-9_]+");
|
||||
return regex.exactMatch(memberName);
|
||||
}
|
||||
|
||||
bool isValidErrorName(const QString &errorName)
|
||||
{
|
||||
return isValidInterfaceName(errorName);
|
||||
}
|
||||
|
||||
bool isValidObjectPath(const QString &path)
|
||||
{
|
||||
if (path == QLatin1String("/"))
|
||||
return true;
|
||||
|
||||
if (!path.startsWith('/') || path.indexOf(QLatin1String("//")) != -1 ||
|
||||
path.endsWith('/'))
|
||||
return false;
|
||||
|
||||
QStringList parts = path.split('/');
|
||||
Q_ASSERT(parts.count() >= 1);
|
||||
parts.removeFirst(); // it starts with /, so we get an empty first part
|
||||
|
||||
QRegExp regex("[a-zA-Z0-9_]+");
|
||||
foreach (QString part, parts)
|
||||
if (!regex.exactMatch(part))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isValidSignature(const QString &signature)
|
||||
{
|
||||
return dbus_signature_validate(signature.toUtf8(), 0);
|
||||
}
|
||||
|
||||
bool isValidSingleSignature(const QString &signature)
|
||||
{
|
||||
return dbus_signature_validate_single(signature.toUtf8(), 0);
|
||||
}
|
||||
|
||||
} // namespace QDBusUtil
|
||||
50
qt/qdbusutil.h
Normal file
50
qt/qdbusutil.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSUTIL_H
|
||||
#define QDBUSUTIL_H
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
#include "qdbusmacros.h"
|
||||
|
||||
namespace QDBusUtil
|
||||
{
|
||||
bool isValidInterfaceName(const QString &ifaceName) QDBUS_EXPORT;
|
||||
|
||||
bool isValidUniqueConnectionName(const QString &busName) QDBUS_EXPORT;
|
||||
|
||||
bool isValidBusName(const QString &busName) QDBUS_EXPORT;
|
||||
|
||||
bool isValidMemberName(const QString &memberName) QDBUS_EXPORT;
|
||||
|
||||
bool isValidErrorName(const QString &errorName) QDBUS_EXPORT;
|
||||
|
||||
bool isValidObjectPath(const QString &path) QDBUS_EXPORT;
|
||||
|
||||
bool isValidSignature(const QString &signature) QDBUS_EXPORT;
|
||||
|
||||
bool isValidSingleSignature(const QString &signature) QDBUS_EXPORT;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
/* qdbusvariant.h DBUS variant struct
|
||||
*
|
||||
* Copyright (C) 2005 Harald Fernengel <harry@kdevelop.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
|
|
@ -15,23 +17,21 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* along with this program; if not, write to the Free Software Foundation
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSVARIANT_H
|
||||
#define QDBUSVARIANT_H
|
||||
|
||||
#include "dbus/qdbus.h"
|
||||
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include "qdbusmacros.h"
|
||||
#include "qdbustype.h"
|
||||
#include <qvariant.h>
|
||||
|
||||
struct QDBUS_EXPORT QDBusVariant
|
||||
{
|
||||
QString signature;
|
||||
QDBusType type;
|
||||
QVariant value;
|
||||
};
|
||||
Q_DECLARE_METATYPE(QDBusVariant)
|
||||
|
|
|
|||
347
qt/qdbusxmlparser.cpp
Normal file
347
qt/qdbusxmlparser.cpp
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "qdbusxmlparser_p.h"
|
||||
#include "qdbusinterface.h"
|
||||
#include "qdbusinterface_p.h"
|
||||
#include "qdbusconnection_p.h"
|
||||
#include "qdbusobject_p.h"
|
||||
|
||||
#include <QtXml/qdom.h>
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qvariant.h>
|
||||
#include <QtCore/qtextstream.h>
|
||||
|
||||
static QDBusIntrospection::Annotations
|
||||
parseAnnotations(const QDomElement& elem)
|
||||
{
|
||||
QDBusIntrospection::Annotations retval;
|
||||
QDomNodeList list = elem.elementsByTagName("annotation");
|
||||
for (int i = 0; i < list.count(); ++i)
|
||||
{
|
||||
QDomElement ann = list.item(i).toElement();
|
||||
if (ann.isNull())
|
||||
continue;
|
||||
|
||||
QString name = ann.attribute("name"),
|
||||
value = ann.attribute("value");
|
||||
|
||||
if (name.isEmpty())
|
||||
continue;
|
||||
|
||||
retval.insert(name, value);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static QDBusType
|
||||
parseType(const QString& type)
|
||||
{
|
||||
if (type.isEmpty())
|
||||
return QDBusType();
|
||||
return QDBusType(type);
|
||||
}
|
||||
|
||||
static QDBusIntrospection::Arguments
|
||||
parseArgs(const QDomElement& elem, const QLatin1String& direction, bool acceptEmpty = false)
|
||||
{
|
||||
QDBusIntrospection::Arguments retval;
|
||||
QDomNodeList list = elem.elementsByTagName("arg");
|
||||
for (int i = 0; i < list.count(); ++i)
|
||||
{
|
||||
QDomElement arg = list.item(i).toElement();
|
||||
if (arg.isNull())
|
||||
continue;
|
||||
|
||||
if ((acceptEmpty && !arg.hasAttribute("direction")) ||
|
||||
arg.attribute("direction") == direction) {
|
||||
|
||||
QDBusIntrospection::Argument argData;
|
||||
if (arg.hasAttribute("name"))
|
||||
argData.name = arg.attribute("name"); // can be empty
|
||||
argData.type = parseType(arg.attribute("type"));
|
||||
|
||||
if (!argData.type.isValid())
|
||||
continue;
|
||||
|
||||
retval << argData;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path,
|
||||
const QString& xmlData, QDBusConnectionPrivate* store)
|
||||
: m_service(service), m_path(path), m_store(store)
|
||||
{
|
||||
QDomDocument doc;
|
||||
doc.setContent(xmlData);
|
||||
m_node = doc.firstChildElement("node");
|
||||
}
|
||||
|
||||
QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path,
|
||||
const QDomElement& node, QDBusConnectionPrivate* store)
|
||||
: m_service(service), m_path(path), m_node(node), m_store(store)
|
||||
{
|
||||
}
|
||||
|
||||
void QDBusXmlParser::parse(const QDBusObjectPrivate* d, const QString &xml)
|
||||
{
|
||||
QDBusXmlParser parser(d->data->service, d->data->path, xml, d->parent);
|
||||
parser.object();
|
||||
parser.interfaces();
|
||||
}
|
||||
|
||||
QDBusIntrospection::Interfaces
|
||||
QDBusXmlParser::interfaces() const
|
||||
{
|
||||
QDBusIntrospection::Interfaces retval;
|
||||
|
||||
if (m_node.isNull())
|
||||
return retval;
|
||||
|
||||
QDomNodeList interfaces = m_node.elementsByTagName("interface");
|
||||
for (int i = 0; i < interfaces.count(); ++i)
|
||||
{
|
||||
QDomElement iface = interfaces.item(i).toElement();
|
||||
QString ifaceName = iface.attribute("name");
|
||||
if (iface.isNull() || ifaceName.isEmpty())
|
||||
continue; // for whatever reason
|
||||
|
||||
QDBusIntrospection::Interface *ifaceData;
|
||||
if (m_store) {
|
||||
QSharedDataPointer<QDBusIntrospection::Interface> knownData =
|
||||
m_store->findInterface(ifaceName);
|
||||
if (!knownData.constData()->introspection.isEmpty()) {
|
||||
// it's already known
|
||||
// we don't have to re-parse
|
||||
retval.insert(ifaceName, knownData);
|
||||
continue;
|
||||
}
|
||||
|
||||
// ugly, but ok
|
||||
// we don't want to detach
|
||||
// we *WANT* to modify the shared data
|
||||
ifaceData = const_cast<QDBusIntrospection::Interface*>( knownData.constData() );
|
||||
}
|
||||
else {
|
||||
ifaceData = new QDBusIntrospection::Interface;
|
||||
ifaceData->name = ifaceName;
|
||||
}
|
||||
|
||||
{
|
||||
// save the data
|
||||
QTextStream ts(&ifaceData->introspection);
|
||||
iface.save(ts,2);
|
||||
}
|
||||
|
||||
// parse annotations
|
||||
ifaceData->annotations = parseAnnotations(iface);
|
||||
|
||||
// parse methods
|
||||
QDomNodeList list = iface.elementsByTagName("method");
|
||||
for (int j = 0; j < list.count(); ++j)
|
||||
{
|
||||
QDomElement method = list.item(j).toElement();
|
||||
QString methodName = method.attribute("name");
|
||||
if (method.isNull() || methodName.isEmpty())
|
||||
continue;
|
||||
|
||||
QDBusIntrospection::Method methodData;
|
||||
methodData.name = methodName;
|
||||
|
||||
// parse arguments
|
||||
methodData.inputArgs = parseArgs(method, QLatin1String("in"));
|
||||
methodData.outputArgs = parseArgs(method, QLatin1String("out"));
|
||||
methodData.annotations = parseAnnotations(method);
|
||||
|
||||
// add it
|
||||
ifaceData->methods.insert(methodName, methodData);
|
||||
}
|
||||
|
||||
// parse signals
|
||||
list = iface.elementsByTagName("signal");
|
||||
for (int j = 0; j < list.count(); ++j)
|
||||
{
|
||||
QDomElement signal = list.item(j).toElement();
|
||||
QString signalName = signal.attribute("name");
|
||||
if (signal.isNull() || signalName.isEmpty())
|
||||
continue;
|
||||
|
||||
QDBusIntrospection::Signal signalData;
|
||||
signalData.name = signalName;
|
||||
|
||||
// parse data
|
||||
signalData.outputArgs = parseArgs(signal, QLatin1String("out"), true);
|
||||
signalData.annotations = parseAnnotations(signal);
|
||||
|
||||
// add it
|
||||
ifaceData->signals_.insert(signalName, signalData);
|
||||
}
|
||||
|
||||
// parse properties
|
||||
list = iface.elementsByTagName("property");
|
||||
for (int j = 0; j < list.count(); ++j)
|
||||
{
|
||||
QDomElement property = list.item(j).toElement();
|
||||
QString propertyName = property.attribute("name");
|
||||
if (property.isNull() || propertyName.isEmpty())
|
||||
continue;
|
||||
|
||||
QDBusIntrospection::Property propertyData;
|
||||
|
||||
// parse data
|
||||
propertyData.name = propertyName;
|
||||
propertyData.type = parseType(property.attribute("type"));
|
||||
propertyData.annotations = parseAnnotations(property);
|
||||
|
||||
if (!propertyData.type.isValid())
|
||||
// cannot be!
|
||||
continue;
|
||||
|
||||
QString access = property.attribute("access");
|
||||
if (access.isEmpty())
|
||||
// can't be empty either!
|
||||
continue;
|
||||
else if (access == QLatin1String("read"))
|
||||
propertyData.access = QDBusIntrospection::Property::Read;
|
||||
else if (access == QLatin1String("write"))
|
||||
propertyData.access = QDBusIntrospection::Property::Write;
|
||||
else if (access == QLatin1String("readwrite"))
|
||||
propertyData.access = QDBusIntrospection::Property::ReadWrite;
|
||||
else
|
||||
continue; // invalid one!
|
||||
|
||||
// add it
|
||||
ifaceData->properties.insert(propertyName, propertyData);
|
||||
}
|
||||
|
||||
// add it
|
||||
retval.insert(ifaceName, QSharedDataPointer<QDBusIntrospection::Interface>(ifaceData));
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
QSharedDataPointer<QDBusIntrospection::Object>
|
||||
QDBusXmlParser::object() const
|
||||
{
|
||||
QSharedDataPointer<QDBusIntrospection::Object> retval;
|
||||
|
||||
if (m_node.isNull())
|
||||
return retval;
|
||||
|
||||
// check if the store knows about this one
|
||||
QDBusIntrospection::Object* objData;
|
||||
if (m_store) {
|
||||
retval = objData = m_store->findObject(m_service, m_path);
|
||||
}
|
||||
else {
|
||||
objData = new QDBusIntrospection::Object;
|
||||
objData->service = m_service;
|
||||
objData->path = m_path;
|
||||
}
|
||||
|
||||
// check if we have anything to process
|
||||
if (objData->introspection.isNull() && !m_node.firstChild().isNull()) {
|
||||
// yes, introspect this object
|
||||
QTextStream ts(&objData->introspection);
|
||||
m_node.save(ts,2);
|
||||
|
||||
QDomNodeList objects = m_node.elementsByTagName("node");
|
||||
for (int i = 0; i < objects.count(); ++i) {
|
||||
QDomElement obj = objects.item(i).toElement();
|
||||
QString objName = obj.attribute("name");
|
||||
if (obj.isNull() || objName.isEmpty())
|
||||
continue; // for whatever reason
|
||||
|
||||
objData->childObjects.append(objName);
|
||||
}
|
||||
|
||||
QDomNodeList interfaces = m_node.elementsByTagName("interface");
|
||||
for (int i = 0; i < interfaces.count(); ++i) {
|
||||
QDomElement iface = interfaces.item(i).toElement();
|
||||
QString ifaceName = iface.attribute("name");
|
||||
if (iface.isNull() || ifaceName.isEmpty())
|
||||
continue;
|
||||
|
||||
objData->interfaces.append(ifaceName);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
QSharedDataPointer<QDBusIntrospection::ObjectTree>
|
||||
QDBusXmlParser::objectTree() const
|
||||
{
|
||||
QSharedDataPointer<QDBusIntrospection::ObjectTree> retval;
|
||||
|
||||
if (m_node.isNull())
|
||||
return retval;
|
||||
|
||||
retval = new QDBusIntrospection::ObjectTree;
|
||||
|
||||
retval->service = m_service;
|
||||
retval->path = m_path;
|
||||
|
||||
QTextStream ts(&retval->introspection);
|
||||
m_node.save(ts,2);
|
||||
|
||||
// interfaces are easy:
|
||||
retval->interfaceData = interfaces();
|
||||
retval->interfaces = retval->interfaceData.keys();
|
||||
|
||||
// sub-objects are slightly more difficult:
|
||||
QDomNodeList objects = m_node.elementsByTagName("node");
|
||||
for (int i = 0; i < objects.count(); ++i) {
|
||||
QDomElement obj = objects.item(i).toElement();
|
||||
QString objName = obj.attribute("name");
|
||||
if (obj.isNull() || objName.isEmpty())
|
||||
continue; // for whatever reason
|
||||
|
||||
// check if we have anything to process
|
||||
if (!obj.firstChild().isNull()) {
|
||||
// yes, introspect this object
|
||||
QString xml;
|
||||
QTextStream ts(&xml);
|
||||
obj.save(ts,0);
|
||||
|
||||
// parse it
|
||||
QString objAbsName = m_path;
|
||||
if (!objAbsName.endsWith('/'))
|
||||
objAbsName.append('/');
|
||||
objAbsName += objName;
|
||||
|
||||
QDBusXmlParser parser(m_service, objAbsName, obj, m_store);
|
||||
retval->childObjectData.insert(objName, parser.objectTree());
|
||||
}
|
||||
|
||||
retval->childObjects << objName;
|
||||
}
|
||||
|
||||
return QSharedDataPointer<QDBusIntrospection::ObjectTree>( retval );
|
||||
}
|
||||
|
||||
59
qt/qdbusxmlparser_p.h
Normal file
59
qt/qdbusxmlparser_p.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- C++ -*-
|
||||
*
|
||||
* Copyright (C) 2005 Thiago Macieira <thiago@kde.org>
|
||||
* Copyright (C) 2006 Trolltech AS. All rights reserved.
|
||||
* Author: Thiago Macieira <thiago.macieira@trolltech.com>
|
||||
*
|
||||
* Licensed under the Academic Free License version 2.1
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef QDBUSXMLPARSER_H
|
||||
#define QDBUSXMLPARSER_H
|
||||
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtXml/qdom.h>
|
||||
#include "qdbusmacros.h"
|
||||
#include "qdbusintrospection.h"
|
||||
|
||||
class QDBusConnectionPrivate;
|
||||
class QDBusObjectPrivate;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class QDBusXmlParser
|
||||
{
|
||||
QString m_service;
|
||||
QString m_path;
|
||||
QDomElement m_node;
|
||||
QDBusConnectionPrivate* m_store;
|
||||
|
||||
public:
|
||||
QDBusXmlParser(const QString& service, const QString& path,
|
||||
const QString& xmlData, QDBusConnectionPrivate* store = 0);
|
||||
QDBusXmlParser(const QString& service, const QString& path,
|
||||
const QDomElement& node, QDBusConnectionPrivate* store = 0);
|
||||
|
||||
QDBusIntrospection::Interfaces interfaces() const;
|
||||
QSharedDataPointer<QDBusIntrospection::Object> object() const;
|
||||
QSharedDataPointer<QDBusIntrospection::ObjectTree> objectTree() const;
|
||||
|
||||
static void parse(const QDBusObjectPrivate* d, const QString &xml);
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue