dbus/qt Makefile.am, 1.18, 1.19 dbusidl2cpp.cpp, 1.1,
1.2 qdbusabstractadaptor.cpp, 1.2,
1.3 qdbusabstractinterface.cpp, NONE,
1.1 qdbusabstractinterface.h, NONE,
1.1 qdbusabstractinterface_p.h, NONE, 1.1 qdbusbus.cpp, NONE,
1.1 qdbusbus.h, NONE, 1.1 qdbusconnection.cpp, 1.5,
1.6 qdbusconnection.h, 1.5, 1.6 qdbusconnection_p.h, 1.6,
1.7 qdbuserror.cpp, 1.3, 1.4 qdbuserror.h, 1.4,
1.5 qdbusintegrator.cpp, 1.4, 1.5 qdbusinterface.cpp, 1.3,
1.4 qdbusinterface.h, 1.2, 1.3 qdbusinterface_p.h, 1.3,
1.4 qdbusinternalfilters.cpp, 1.1, 1.2 qdbusintrospection.cpp,
1.2, 1.3 qdbusintrospection.h, 1.2,
NONE qdbusintrospection_p.h, NONE, 1.1 qdbusmacros.h, 1.4,
1.5 qdbusmarshall.cpp, 1.4, 1.5 qdbusmessage.cpp, 1.4,
1.5 qdbusmessage.h, 1.5, 1.6 qdbusmessage_p.h, 1.4,
1.5 qdbusmetaobject.cpp, NONE, 1.1 qdbusmetaobject_p.h, NONE,
1.1 qdbusobject.cpp, 1.2, NONE qdbusobject.h, 1.2,
NONE qdbusobject_p.h, 1.1, NONE qdbusreply.h, 1.1,
1.2 qdbusstandardinterfaces.cpp, 1.2,
NONE qdbusstandardinterfaces.h, 1.2, NONE qdbustype.cpp, 1.2,
1.3 qdbustype.h, 1.2, NONE qdbustype_p.h, NONE,
1.1 qdbustypehelper_p.h, NONE, 1.1 qdbusutil.cpp, 1.2,
1.3 qdbusutil.h, 1.1, 1.2 qdbusvariant.h, 1.4,
NONE qdbusxmlparser.cpp, 1.2, 1.3 qdbusxmlparser_p.h, 1.1,
1.2 qt-dbus.qdocconf, NONE, 1.1
Thiago J. Macieira
thiago at kemper.freedesktop.org
Tue Mar 28 10:56:10 PST 2006
Update of /cvs/dbus/dbus/qt
In directory kemper:/tmp/cvs-serv23055/qt
Modified Files:
Makefile.am dbusidl2cpp.cpp qdbusabstractadaptor.cpp
qdbusconnection.cpp qdbusconnection.h qdbusconnection_p.h
qdbuserror.cpp qdbuserror.h qdbusintegrator.cpp
qdbusinterface.cpp qdbusinterface.h qdbusinterface_p.h
qdbusinternalfilters.cpp qdbusintrospection.cpp qdbusmacros.h
qdbusmarshall.cpp qdbusmessage.cpp qdbusmessage.h
qdbusmessage_p.h qdbusreply.h qdbustype.cpp qdbusutil.cpp
qdbusutil.h qdbusxmlparser.cpp qdbusxmlparser_p.h
Added Files:
qdbusabstractinterface.cpp qdbusabstractinterface.h
qdbusabstractinterface_p.h qdbusbus.cpp qdbusbus.h
qdbusintrospection_p.h qdbusmetaobject.cpp qdbusmetaobject_p.h
qdbustype_p.h qdbustypehelper_p.h qt-dbus.qdocconf
Removed Files:
qdbusintrospection.h qdbusobject.cpp qdbusobject.h
qdbusobject_p.h qdbusstandardinterfaces.cpp
qdbusstandardinterfaces.h qdbustype.h qdbusvariant.h
Log Message:
* qt/*:
* dbus/qdbus.h: Sync with KDE Subversion revision
523647. Hopefully, this will be the last of the
source-incompatible changes. Documentation has been improved;
support for QList<basic-types> has been added; QDBusObject is
gone; QDBus(Abstract)Interface is now a QObject with
auto-generated meta-object; QDBusIntrospection is marked
private, since QMetaObject can be used now; lots of bugfixes.
Index: Makefile.am
===================================================================
RCS file: /cvs/dbus/dbus/qt/Makefile.am,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- Makefile.am 6 Mar 2006 15:27:56 -0000 1.18
+++ Makefile.am 28 Mar 2006 18:56:08 -0000 1.19
@@ -1,80 +1,72 @@
if HAVE_QT
INCLUDES=-I$(top_srcdir) $(DBUS_CLIENT_CFLAGS) $(DBUS_QT_CFLAGS) -DDBUS_COMPILATION
-dbusincludedir=$(includedir)/dbus-1.0/dbus
-
lib_LTLIBRARIES=libdbus-qt4-1.la
-dbusinclude_HEADERS= \
- qdbusmacros.h \
- qdbuserror.h \
- qdbusmessage.h \
- qdbusserver.h \
- qdbusconnection.h \
- qdbusvariant.h \
- qdbusobject.h \
- qdbusinterface.h \
- qdbustype.h \
- qdbusstandardinterfaces.h \
- qdbusutil.h \
- qdbusintrospection.h \
- qdbusabstractadaptor.h \
- qdbusreply.h
+dbusincludedir=$(includedir)/dbus-1.0/dbus
+dbusinclude_HEADERS= \
+ qdbus.h \
+ qdbusbus.h \
+ qdbusmacros.h \
+ qdbuserror.h \
+ qdbusmessage.h \
+ qdbusserver.h \
+ qdbusconnection.h \
+ qdbusabstractinterface.h \
+ qdbusinterface.h \
+ qdbusutil.h \
+ qdbusabstractadaptor.h \
+ qdbusreply.h \
+ qdbustypehelper_p.h
-libdbus_qt4_1_la_SOURCES = \
- qdbusconnection.cpp \
- qdbuserror.cpp \
- qdbusintegrator.cpp \
- qdbusinternalfilters.cpp \
- qdbusmarshall.cpp \
- qdbusmessage.cpp \
- qdbusserver.cpp \
- qdbustype.cpp \
- qdbusobject.cpp \
- qdbusinterface.cpp \
- qdbusstandardinterfaces.cpp \
- qdbusxmlparser.cpp \
- qdbusutil.cpp \
- qdbusintrospection.cpp \
- qdbusabstractadaptor.cpp \
- qdbusthread.cpp \
- \
- qdbusabstractadaptor.h \
+noinst_HEADERS= \
qdbusabstractadaptor_p.h \
- qdbusconnection.h \
+ qdbusabstractinterface_p.h \
qdbusconnection_p.h \
- qdbuserror.h \
- qdbusinterface.h \
qdbusinterface_p.h \
- qdbusintrospection.h \
- qdbusmacros.h \
+ qdbusintrospection_p.h \
qdbusmarshall_p.h \
- qdbusmessage.h \
qdbusmessage_p.h \
- qdbusobject.h \
- qdbusobject_p.h \
- qdbusreply.h \
- qdbusserver.h \
- qdbusstandardinterfaces.h \
- qdbustype.h \
- qdbusvariant.h \
- qdbusxmlparser_p.h
+ qdbusmetaobject_p.h \
+ qdbustype_p.h \
+ qdbusxmlparser_p.h
+
+libdbus_qt4_1_la_SOURCES = \
+ qdbusbus.cpp \
+ qdbusconnection.cpp \
+ qdbuserror.cpp \
+ qdbusintegrator.cpp \
+ qdbusmarshall.cpp \
+ qdbusmessage.cpp \
+ qdbusserver.cpp \
+ qdbustype.cpp \
+ qdbusabstractinterface.cpp \
+ qdbusinterface.cpp \
+ qdbusxmlparser.cpp \
+ qdbusutil.cpp \
+ qdbusintrospection.cpp \
+ qdbusabstractadaptor.cpp \
+ qdbusthread.cpp \
+ qdbusinternalfilters.cpp \
+ qdbusmetaobject.cpp
bin_PROGRAMS = dbusidl2cpp
dbusidl2cpp_SOURCES = dbusidl2cpp.cpp
-dbusidl2cpp_LDFLAGS = $(all_libraries) -no-undefined
-dbusidl2cpp_LDADD = $(LIB_QTCORE) libdbus-qt4-1.la
+dbusidl2cpp_LDFLAGS = -no-undefined
+dbusidl2cpp_LDADD = $(DBUS_QT_LIBS) libdbus-qt4-1.la
qdbusabstractadaptor.lo: qdbusabstractadaptor.moc qdbusabstractadaptor_p.moc
+qdbusabstractinterface.lo: qdbusabstractinterface.moc
+qdbusbus.lo: qdbusbus.moc
qdbusserver.lo: qdbusserver.moc
qdbusconnection.lo: qdbusconnection_p.moc
-CLEANFILES=qdbusabstractadaptor.moc qdbusserver.moc qdbusconnection.moc qdbusabstractadaptor_p.moc
+CLEANFILES=qdbusabstractadaptor.moc qdbusserver.moc qdbusconnection.moc qdbusconnection_p.moc qdbusabstractadaptor_p.moc qdbusbus.moc qdbusabstractinterface.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
-EXTRA_DIST = Doxyfile
+EXTRA_DIST = qt-dbus.qdocconf
%.moc: %.h
$(QT_MOC) $< > $@
Index: dbusidl2cpp.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/dbusidl2cpp.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- dbusidl2cpp.cpp 6 Mar 2006 15:27:56 -0000 1.1
+++ dbusidl2cpp.cpp 28 Mar 2006 18:56:08 -0000 1.2
@@ -28,23 +28,28 @@
#include <QtCore/qdatetime.h>
#include <QtCore/qfile.h>
#include <QtCore/qstring.h>
+#include <QtCore/qstringlist.h>
#include <QtCore/qtextstream.h>
#include <QtCore/qset.h>
#include <dbus/qdbus.h>
+#include "qdbusmetaobject_p.h"
+#include "qdbusintrospection_p.h"
#define PROGRAMNAME "dbusidl2cpp"
-#define PROGRAMVERSION "0.1"
+#define PROGRAMVERSION "0.3"
#define PROGRAMCOPYRIGHT "Copyright (C) 2006 Trolltech AS. All rights reserved."
#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
-static const char cmdlineOptions[] = "a:h:Np:vV";
+static const char cmdlineOptions[] = "a:c:hmNp:vV";
+static const char *globalClassName;
static const char *proxyFile;
static const char *adaptorFile;
static const char *inputFile;
static bool skipNamespaces;
static bool verbose;
+static bool includeMocs;
static QStringList wantedInterfaces;
static const char help[] =
@@ -54,7 +59,9 @@
"\n"
"Options:\n"
" -a <filename> Write the adaptor code to <filename>\n"
+ " -c <classname> Use <classname> as the class name for the generated classes\n"
" -h Show this information\n"
+ " -m Generate #include \"filename.moc\" statements in the .cpp files\n"
" -N Don't use namespaces\n"
" -p <filename> Write the proxy code to <filename>\n"
" -v Be verbose.\n"
@@ -63,6 +70,22 @@
"If the file name given to the options -a and -p does not end in .cpp or .h, the\n"
"program will automatically append the suffixes and produce both files.\n";
+static const char includeList[] =
+ "#include <QtCore/QByteArray>\n"
+ "#include <QtCore/QList>\n"
+ "#include <QtCore/QMap>\n"
+ "#include <QtCore/QString>\n"
+ "#include <QtCore/QStringList>\n"
+ "#include <QtCore/QVariant>\n";
+
+static const char forwardDeclarations[] =
+ "class QByteArray;\n"
+ "template<class T> class QList;\n"
+ "template<class Key, class Value> class QMap;\n"
+ "class QString;\n"
+ "class QStringList;\n"
+ "class QVariant;\n";
+
static void showHelp()
{
printf("%s", help);
@@ -86,11 +109,19 @@
case 'a':
adaptorFile = optarg;
break;
+
+ case 'c':
+ globalClassName = optarg;
+ break;
case 'v':
verbose = true;
break;
+ case 'm':
+ includeMocs = true;
+ break;
+
case 'N':
skipNamespaces = true;
break;
@@ -123,7 +154,7 @@
static QDBusIntrospection::Interfaces readInput()
{
QFile input(QFile::decodeName(inputFile));
- if (inputFile)
+ if (inputFile && QLatin1String("-") != inputFile)
input.open(QIODevice::ReadOnly);
else
input.open(stdin, QIODevice::ReadOnly);
@@ -201,6 +232,9 @@
enum ClassType { Proxy, Adaptor };
static QString classNameForInterface(const QString &interface, ClassType classType)
{
+ if (globalClassName)
+ return QLatin1String(globalClassName);
+
QStringList parts = interface.split('.');
QString retval;
@@ -222,53 +256,34 @@
return retval;
}
-static QString templateArg(const QString &arg)
+static QByteArray qtTypeName(const QString &signature)
{
- if (!arg.endsWith('>'))
- return arg;
-
- return arg + ' ';
+ QVariant::Type type = QDBusUtil::signatureToType(signature);
+ if (type == QVariant::Invalid)
+ qFatal("Got unknown type `%s'", qPrintable(signature));
+
+ return QVariant::typeToName(type);
}
-static QString constRefArg(const QString &arg)
+static QString nonConstRefArg(const QByteArray &arg)
{
- if (!arg.startsWith('Q'))
- return arg + ' ';
- else
- return QString("const %1 &").arg(arg);
+ return QLatin1String(arg + " &");
}
-static QString makeQtName(const QString &dbusName)
+static QString templateArg(const QByteArray &arg)
{
- QString name = dbusName;
- if (name.length() > 3 && name.startsWith("Get"))
- name = name.mid(3); // strip Get from GetXXXX
-
- // recapitalize the name
- QChar *p = name.data();
- while (!p->isNull()) {
- // capitalized letter
- // leave it
- if (!p->isNull())
- ++p;
-
- // lowercase all the next capital letters, except for the last one
- while (!p->isNull() && p->isUpper()) {
- if (!p[1].isNull() && p[1].isUpper())
- *p = p->toLower();
- ++p;
- }
-
- if (p->isUpper())
- ++p;
+ if (!arg.endsWith('>'))
+ return QLatin1String(arg);
- // non capital letters: skip them
- while (!p->isNull() && !p->isUpper())
- ++p;
- }
+ return QLatin1String(arg + ' ');
+}
- name[0] = name[0].toLower(); // lowercase the first one
- return name;
+static QString constRefArg(const QByteArray &arg)
+{
+ if (!arg.startsWith('Q'))
+ return QLatin1String(arg + ' ');
+ else
+ return QString("const %1 &").arg( QLatin1String(arg) );
}
static QStringList makeArgNames(const QDBusIntrospection::Arguments &inputArgs,
@@ -306,7 +321,7 @@
int argPos = 0;
for (int i = 0; i < inputArgs.count(); ++i) {
const QDBusIntrospection::Argument &arg = inputArgs.at(i);
- QString type = constRefArg(arg.type.toString(QDBusType::QVariantNames));
+ QString type = constRefArg(qtTypeName(arg.type));
if (!first)
ts << ", ";
@@ -324,7 +339,7 @@
if (!first)
ts << ", ";
- ts << arg.type.toString(QDBusType::QVariantNames) << " &" << argNames.at(argPos++);
+ ts << nonConstRefArg(qtTypeName(arg.type)) << argNames.at(argPos++);
first = false;
}
}
@@ -348,22 +363,25 @@
static void writeProxy(const char *proxyFile, const QDBusIntrospection::Interfaces &interfaces)
{
// open the file
- QString name = header(proxyFile);
- QFile file(name);
- if (!name.isEmpty())
+ QString headerName = header(proxyFile);
+ QFile file(headerName);
+ if (!headerName.isEmpty())
file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
else
file.open(stdout, QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream hs(&file);
- QTextStream ts(&file);
+ QString cppName = cpp(proxyFile);
+ QByteArray cppData;
+ QTextStream cs(&cppData);
// write the header:
- writeHeader(ts, true);
+ writeHeader(hs, true);
// include guards:
QString includeGuard;
- if (!name.isEmpty()) {
- includeGuard = name.toUpper().replace(QChar('.'), QChar('_'));
+ if (!headerName.isEmpty()) {
+ includeGuard = headerName.toUpper().replace(QChar('.'), QChar('_'));
int pos = includeGuard.lastIndexOf('/');
if (pos != -1)
includeGuard = includeGuard.mid(pos + 1);
@@ -374,54 +392,42 @@
.arg(includeGuard)
.arg(getpid())
.arg(QDateTime::currentDateTime().toTime_t());
- ts << "#ifndef " << includeGuard << endl
+ hs << "#ifndef " << includeGuard << endl
<< "#define " << includeGuard << endl
<< endl;
// include our stuff:
- ts << "#include <QtCore/QObject>" << endl
+ hs << "#include <QtCore/QObject>" << endl
+ << includeList
<< "#include <dbus/qdbus.h>" << endl
<< endl;
+ if (cppName != headerName) {
+ writeHeader(cs, false);
+ cs << "#include \"" << headerName << "\"" << endl
+ << endl;
+ }
+
foreach (const QDBusIntrospection::Interface *interface, interfaces) {
+ QString className = classNameForInterface(interface->name, Proxy);
+
// comment:
- ts << "/*" << endl
+ hs << "/*" << endl
<< " * Proxy class for interface " << interface->name << endl
<< " */" << endl;
+ cs << "/*" << endl
+ << " * Implementation of interface class " << className << endl
+ << " */" << endl
+ << endl;
// class header:
- QString className = classNameForInterface(interface->name, Proxy);
- ts << "class " << className << ": public QDBusInterface" << endl
+ hs << "class " << className << ": public QDBusAbstractInterface" << endl
<< "{" << endl
- << "public:" << endl
- << " static inline const char *staticInterfaceName()" << endl
- << " { return \"" << interface->name << "\"; }" << endl
- << endl
- << " static inline const char *staticIntrospectionData()" << endl
- << " { return \"\"" << endl
- << stringify(interface->introspection)
- << " \"\"; }" << endl
- << endl;
-
- // constructors/destructors:
- ts << "public:" << endl
- << " explicit inline " << className << "(const QDBusObject &obj)" << endl
- << " : QDBusInterface(obj, staticInterfaceName())" << endl
- << " { }" << endl
- << endl
- << " inline ~" << className << "()" << endl
- << " { }" << endl
- << endl;
-
- // the introspection virtual:
- ts << " inline virtual QString introspectionData() const" << endl
- << " { return QString::fromUtf8(staticIntrospectionData()); }" << endl
- << endl;
-
+ << " Q_OBJECT" << endl;
+
// properties:
- ts << "public: // PROPERTIES" << endl;
foreach (const QDBusIntrospection::Property &property, interface->properties) {
- QString type = property.type.toString(QDBusType::QVariantNames);
+ QByteArray type = qtTypeName(property.type);
QString templateType = templateArg(type);
QString constRefType = constRefArg(type);
QString getter = property.name;
@@ -429,42 +435,46 @@
getter[0] = getter[0].toLower();
setter[3] = setter[3].toUpper();
+ hs << " Q_PROPERTY(" << type << " " << property.name;
+
// getter:
- if (property.access != QDBusIntrospection::Property::Write) {
- ts << " inline QDBusReply<" << templateType << "> " << getter << "() const" << endl
- << " {" << endl
- << " QDBusReply<QDBusVariant> retval = QDBusPropertiesInterface(object())" << endl
- << " .get(QLatin1String(\"" << interface->name << "\"), QLatin1String(\""
- << property.name << "\"));" << endl
- << " return QDBusReply<" << templateType << ">::fromVariant(retval);" << endl
- << " }" << endl;
- }
+ if (property.access != QDBusIntrospection::Property::Write)
+ // it's readble
+ hs << " READ" << getter;
// setter
- if (property.access != QDBusIntrospection::Property::Read) {
- ts << " inline QDBusReply<void> " << setter << "(" << constRefType << "value)" << endl
- << " {" << endl
- << " QDBusVariant v(value, QDBusType(";
-
- QString sig = property.type.dbusSignature();
- if (sig.length() == 1)
- ts << "'" << sig.at(0) << "'";
- else
- ts << "\"" << sig << "\"";
-
- ts << "));" << endl
- << " return QDBusPropertiesInterface(object())" << endl
- << " .set(QLatin1String(\"" << interface->name << "\"), QLatin1String(\""
- << property.name << "\"), v);" << endl
- << " }" << endl;
- }
+ if (property.access != QDBusIntrospection::Property::Read)
+ // it's writeable
+ hs << " WRITE" << setter;
- ts << endl;
+ hs << ")" << endl;
}
+
+ // the interface name
+ hs << "public:" << endl
+ << " static inline const char *staticInterfaceName()" << endl
+ << " { return \"" << interface->name << "\"; }" << endl
+ << endl;
+ // constructors/destructors:
+ hs << "public:" << endl
+ << " explicit " << className << "(QDBusAbstractInterfacePrivate *p);" << endl
+ << endl
+ << " ~" << className << "();" << endl
+ << endl;
+ cs << className << "::" << className << "(QDBusAbstractInterfacePrivate *p)" << endl
+ << " : QDBusAbstractInterface(p)" << endl
+ << "{" << endl
+ << "}" << endl
+ << endl
+ << className << "::~" << className << "()" << endl
+ << "{" << endl
+ << "}" << endl
+ << endl;
+
// methods:
- ts << "public: // METHODS" << endl;
+ hs << "public slots: // METHODS" << endl;
foreach (const QDBusIntrospection::Method &method, interface->methods) {
bool isAsync = method.annotations.value(ANNOTATION_NO_WAIT) == "true";
if (isAsync && !method.outputArgs.isEmpty()) {
@@ -473,72 +483,83 @@
continue;
}
- ts << " inline ";
-
- QString returnType;
+ hs << " inline ";
if (method.annotations.value("org.freedesktop.DBus.Deprecated") == "true")
- ts << "Q_DECL_DEPRECATED ";
+ hs << "Q_DECL_DEPRECATED ";
if (isAsync)
- ts << "Q_ASYNC void ";
+ hs << "Q_ASYNC void ";
else if (method.outputArgs.isEmpty())
- ts << "QDBusReply<void> ";
+ hs << "QDBusReply<void> ";
else {
- returnType = method.outputArgs.first().type.toString(QDBusType::QVariantNames);
- ts << "QDBusReply<" << templateArg(returnType) << "> ";
+ hs << "QDBusReply<" << templateArg(qtTypeName(method.outputArgs.first().type)) << "> ";
}
- QString name = makeQtName(method.name);
- ts << name << "(";
+ hs << method.name << "(";
QStringList argNames = makeArgNames(method.inputArgs, method.outputArgs);
- writeArgList(ts, argNames, method.inputArgs, method.outputArgs);
+ writeArgList(hs, argNames, method.inputArgs, method.outputArgs);
- ts << ")" << endl
+ hs << ")" << endl
<< " {" << endl;
if (method.outputArgs.count() > 1)
- ts << " QDBusMessage reply = call(QLatin1String(\"";
+ hs << " QDBusMessage reply = call(QLatin1String(\"";
else if (!isAsync)
- ts << " return call(QLatin1String(\"";
+ hs << " return call(QLatin1String(\"";
else
- ts << " callAsync(QLatin1String(\"";
+ hs << " callAsync(QLatin1String(\"";
+ // rebuild the method input signature:
QString signature = QChar('.');
foreach (const QDBusIntrospection::Argument &arg, method.inputArgs)
- signature += arg.type.dbusSignature();
+ signature += arg.type;
if (signature.length() == 1)
signature.clear();
- ts << method.name << signature << "\")";
+ hs << method.name << signature << "\")";
int argPos = 0;
for (int i = 0; i < method.inputArgs.count(); ++i)
- ts << ", " << argNames.at(argPos++);
+ hs << ", " << argNames.at(argPos++);
// close the QDBusIntrospection::call/callAsync call
- ts << ");" << endl;
+ hs << ");" << endl;
argPos++;
if (method.outputArgs.count() > 1) {
- ts << " if (reply.type() == QDBusMessage::ReplyMessage) {" << endl;
+ hs << " if (reply.type() == QDBusMessage::ReplyMessage) {" << endl;
// yes, starting from 1
for (int i = 1; i < method.outputArgs.count(); ++i)
- ts << " " << argNames.at(argPos++) << " = qvariant_cast<"
- << templateArg(method.outputArgs.at(i).type.toString(QDBusType::QVariantNames))
+ hs << " " << argNames.at(argPos++) << " = qvariant_cast<"
+ << templateArg(qtTypeName(method.outputArgs.at(i).type))
<< ">(reply.at(" << i << "));" << endl;
- ts << " }" << endl
+ hs << " }" << endl
<< " return reply;" << endl;
}
// close the function:
- ts << " }" << endl
+ hs << " }" << endl
<< endl;
}
+ hs << "signals: // SIGNALS" << endl;
+ foreach (const QDBusIntrospection::Signal &signal, interface->signals_) {
+ hs << " ";
+ if (signal.annotations.value("org.freedesktop.DBus.Deprecated") == "true")
+ hs << "Q_DECL_DEPRECATED ";
+
+ hs << "void " << signal.name << "(";
+
+ QStringList argNames = makeArgNames(signal.outputArgs);
+ writeArgList(hs, argNames, signal.outputArgs);
+
+ hs << ");" << endl; // finished for header
+ }
+
// close the class:
- ts << "};" << endl
+ hs << "};" << endl
<< endl;
}
@@ -561,15 +582,15 @@
// i parts matched
// close last.count() - i namespaces:
for (int j = i; j < last.count(); ++j)
- ts << QString((last.count() - j - 1 + i) * 2, ' ') << "}" << endl;
+ hs << QString((last.count() - j - 1 + i) * 2, ' ') << "}" << endl;
// open current.count() - i namespaces
for (int j = i; j < current.count(); ++j)
- ts << QString(j * 2, ' ') << "namespace " << current.at(j) << " {" << endl;
+ hs << QString(j * 2, ' ') << "namespace " << current.at(j) << " {" << endl;
// add this class:
if (!name.isEmpty()) {
- ts << QString(current.count() * 2, ' ')
+ hs << QString(current.count() * 2, ' ')
<< "typedef ::" << classNameForInterface(it->constData()->name, Proxy)
<< " " << name << ";" << endl;
}
@@ -582,7 +603,22 @@
}
// close the include guard
- ts << "#endif" << endl;
+ hs << "#endif" << endl;
+
+ if (includeMocs)
+ cs << endl
+ << "#include \"" << proxyFile << ".moc\"" << endl;
+
+ cs.flush();
+ hs.flush();
+ if (headerName == cppName)
+ file.write(cppData);
+ else {
+ // write to cpp file
+ QFile f(cppName);
+ f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
+ f.write(cppData);
+ }
}
static void writeAdaptor(const char *adaptorFile, const QDBusIntrospection::Interfaces &interfaces)
@@ -624,17 +660,23 @@
// include our stuff:
hs << "#include <QtCore/QObject>" << endl;
if (cppName == headerName)
- hs << "#include <QtCore/QMetaObject>" << endl;
- hs << "#include <dbus/qdbus.h>" << endl
- << endl;
-
+ hs << "#include <QtCore/QMetaObject>" << endl
+ << "#include <QtCore/QVariant>" << endl;
+ hs << "#include <dbus/qdbus.h>" << endl;
+
if (cppName != headerName) {
writeHeader(cs, false);
cs << "#include \"" << headerName << "\"" << endl
<< "#include <QtCore/QMetaObject>" << endl
+ << includeList
<< endl;
+ hs << forwardDeclarations;
+ } else {
+ hs << includeList;
}
+ hs << endl;
+
foreach (const QDBusIntrospection::Interface *interface, interfaces) {
QString className = classNameForInterface(interface->name, Adaptor);
@@ -676,14 +718,14 @@
hs << "public: // PROPERTIES" << endl;
foreach (const QDBusIntrospection::Property &property, interface->properties) {
- QString type = property.type.toString(QDBusType::QVariantNames);
+ QByteArray type = qtTypeName(property.type);
QString constRefType = constRefArg(type);
QString getter = property.name;
QString setter = "set" + property.name;
getter[0] = getter[0].toLower();
setter[3] = setter[3].toUpper();
- hs << " Q_PROPERTY(" << type << " " << getter;
+ hs << " Q_PROPERTY(" << type << " " << property.name;
if (property.access != QDBusIntrospection::Property::Write)
hs << " READ " << getter;
if (property.access != QDBusIntrospection::Property::Read)
@@ -728,20 +770,21 @@
hs << " ";
if (method.annotations.value("org.freedesktop.DBus.Deprecated") == "true")
hs << "Q_DECL_DEPRECATED ";
-
+
+ QByteArray returnType;
if (isAsync) {
hs << "Q_ASYNC void ";
- cs << "Q_ASYNC void ";
+ cs << "void ";
} else if (method.outputArgs.isEmpty()) {
hs << "void ";
cs << "void ";
} else {
- QString type = method.outputArgs.first().type.toString(QDBusType::QVariantNames);
- hs << type << " ";
- cs << type << " ";
+ returnType = qtTypeName(method.outputArgs.first().type);
+ hs << returnType << " ";
+ cs << returnType << " ";
}
- QString name = makeQtName(method.name);
+ QString name = method.name;
hs << name << "(";
cs << className << "::" << name << "(";
@@ -756,8 +799,8 @@
// create the return type
int j = method.inputArgs.count();
- cs << " " << method.outputArgs.at(0).type.toString(QDBusType::QVariantNames)
- << " " << argNames.at(j) << ";" << endl;
+ if (!returnType.isEmpty())
+ cs << " " << returnType << " " << argNames.at(j) << ";" << endl;
// make the call
if (method.inputArgs.count() <= 10 && method.outputArgs.count() <= 1) {
@@ -767,14 +810,14 @@
if (!method.outputArgs.isEmpty())
cs << ", Q_RETURN_ARG("
- << method.outputArgs.at(0).type.toString(QDBusType::QVariantNames)
+ << qtTypeName(method.outputArgs.at(0).type)
<< ", "
<< argNames.at(method.inputArgs.count())
<< ")";
for (int i = 0; i < method.inputArgs.count(); ++i)
cs << ", Q_ARG("
- << method.inputArgs.at(i).type.toString(QDBusType::QVariantNames)
+ << qtTypeName(method.inputArgs.at(i).type)
<< ", "
<< argNames.at(i)
<< ")";
@@ -814,8 +857,7 @@
if (signal.annotations.value("org.freedesktop.DBus.Deprecated") == "true")
hs << "Q_DECL_DEPRECATED ";
- QString name = makeQtName(signal.name);
- hs << "void " << name << "(";
+ hs << "void " << signal.name << "(";
QStringList argNames = makeArgNames(signal.outputArgs);
writeArgList(hs, argNames, signal.outputArgs);
@@ -830,6 +872,10 @@
// close the include guard
hs << "#endif" << endl;
+
+ if (includeMocs)
+ cs << endl
+ << "#include \"" << adaptorFile << ".moc\"" << endl;
cs.flush();
hs.flush();
@@ -859,23 +905,22 @@
}
/*!
- \page dbusidl2cpp QtDBus IDL compiler (dbusidl2cpp)
+ \page dbusidl2cpp.html
+ \title QtDBus IDL compiler (dbusidl2cpp)
The QtDBus IDL compiler is a tool that can be used to parse interface descriptions and produce
static code representing those interfaces, which can then be used to make calls to remote
objects or implement said interfaces.
- \p %dbusidl2dcpp has two modes of operation, that correspond to the two possible outputs it can
- produce: the interface (proxy) class or the adaptor class. The former is similar to the
- \ref StandardInterfaces classes that are part of the QtDBus API and consists of a single .h file,
- which should not be edited. The latter consists of both a C++ header and a source file, which
- are meant to be edited and adapted to your needs.
+ \c dbusidl2dcpp has two modes of operation, that correspond to the two possible outputs it can
+ produce: the interface (proxy) class or the adaptor class.The latter consists of both a C++
+ header and a source file, which are meant to be edited and adapted to your needs.
- The \p %dbusidl2dcpp tool is not meant to be run every time you compile your
+ The \c dbusidl2dcpp tool is not meant to be run every time you compile your
application. Instead, it's meant to be used when developing the code or when the interface
changes.
- The adaptor classes generated by \p %dbusidl2cpp are just a skeleton that must be completed. It
+ The adaptor classes generated by \c dbusidl2cpp are just a skeleton that must be completed. It
generates, by default, calls to slots with the same name on the object the adaptor is attached
to. However, you may modify those slots or the property accessor functions to suit your needs.
*/
Index: qdbusabstractadaptor.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusabstractadaptor.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbusabstractadaptor.cpp 6 Mar 2006 14:29:39 -0000 1.2
+++ qdbusabstractadaptor.cpp 28 Mar 2006 18:56:08 -0000 1.3
@@ -31,9 +31,6 @@
#include "qdbusconnection_p.h" // for qDBusParametersForMethod
#include "qdbusabstractadaptor_p.h"
-/*!
- \internal
-*/
struct QDBusAdaptorInit
{
QSignalSpyCallbackSet callbacks;
@@ -91,477 +88,8 @@
}
/*!
- \page UsingAdaptors Using Adaptors
-
- Adaptors are special classes that are attached to any QObject-derived class and provide the
- interface to the external world using D-Bus. Adaptors are intended to be light-weight classes
- whose main purpose is to relay calls to and from the real object, possibly validating or
- converting the input from the external world and, thus, protecting the real object.
-
- Unlike multiple inheritance, adaptors can be added at any time to any object (but not removed),
- which allows for greater flexibility when exporting existing classes. Another advantage of
- adaptors is to provide similar but not identical functionality in methods of the same name in
- different interfaces, a case which can be quite common when adding a new version of a standard
- interface to an object.
-
- In order to use an adaptor, one must create a class which inherits QDBusAbstractAdaptor. Since
- that is a standard QObject-derived class, the Q_OBJECT macro must appear in the declaration and
- the source file must be processed with the \link moc \endlink tool. The class must also contain
- one or more Q_CLASSINFO entries with the "D-Bus Interface" name, declaring which interfaces it
- is exporting.
-
- Any public slot in the class will be accessible through the bus over messages of the MethodCall
- type. (See \link DeclaringSlots \endlink for more information). Signals in the class will be
- automatically relayed over D-Bus. However, not all types are allowed signals or slots' parameter
- lists: see \link AllowedParameters \endlink for more information.
-
- Also, any property declared with Q_PROPERTY will be automatically exposed over the Properties
- interface on D-Bus. Since the QObject property system does not allow for non-readable
- properties, it is not possible to declare write-only properties using adaptors.
-
- More information:
- - \subpage DeclaringSlots
- - \subpage DeclaringSignals
- - \subpage AllowedParameters
- - \subpage UsingAnnotations
- - \subpage AdaptorExample
-
- \sa QDBusAbstractAdaptor
-*/
-
-/*!
- \page AdaptorExample Example of an interface implemented with an adaptor
-
- A sample usage of QDBusAbstractAdaptor is as follows:
- \code
- class MainApplicationAdaptor: public QDBusAbstractAdaptor
- {
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "com.example.DBus.MainApplication")
- Q_CLASSINFO("D-Bus Interface", "org.kde.DBus.MainApplication")
- Q_PROPERTY(QString caption READ caption WRITE setCaption)
- Q_PROPERTY(QString organizationName READ organizationName)
- Q_PROPERTY(QString organizationDomain READ organizationDomain)
-
- private:
- MyApplication *app;
-
- public:
- MyInterfaceAdaptor(MyApplication *application)
- : QDBusAbstractAdaptor(application), app(application)
- {
- connect(application, SIGNAL(aboutToQuit()), SIGNAL(aboutToQuit());
- connect(application, SIGNAL(focusChanged(QWidget*, QWidget*)),
- SLOT(focusChangedSlot(QWidget*, QWidget*)));
- }
-
- QString caption()
- {
- if (app->hasMainWindow())
- return app->mainWindow()->caption();
- return QString();
- }
-
- void setCaption(const QString &newCaption)
- {
- if (app->hasMainWindow())
- app->mainWindow()->setCaption(newCaption);
- }
-
- QString organizationName()
- {
- return app->organizationName();
- }
-
- QString organizationDomain()
- {
- return app->organizationDomain();
- }
-
- public slots:
- async void quit()
- { app->quit(); }
-
- void reparseConfiguration()
- { app->reparseConfiguration(); }
-
- QString mainWindowObject()
- {
- if (app->hasMainWindow())
- return QString("/%1/mainwindow").arg(app->applicationName());
- return QString();
- }
-
- void setSessionManagement(bool enable)
- {
- if (enable)
- app->enableSessionManagement();
- else
- app->disableSessionManagement();
- }
-
- private slots:
- void focusChangedSlot(QWidget *, QWidget *now)
- {
- if (now == app->mainWindow())
- emit mainWindowHasFocus();
- }
-
- signals:
- void aboutToQuit();
- void mainWindowHasFocus();
- };
- \endcode
-
- The code above would create an interface that could be represented more or less in the following
- canonical representation:
- \code
- interface com.example.DBus.MainApplication
- {
- property readwrite STRING caption
- property read STRING organizationName
- property read STRING organizationDomain
-
- method quit() annotation("org.freedesktop.DBus.Method.NoReply", "true")
- method reparseConfiguration()
- method mainWindowObject(out STRING)
- method disableSessionManagement(in BOOLEAN enable)
-
- signal aboutToQuit()
- signal mainWindowHasFocus()
- }
-
- interface org.kde.DBus.MainApplication
- {
- ....
- }
- \endcode
-
- This adaptor could be used in the application's constructor as follows:
- \code
- MyApplication::MyApplication()
- {
- [...]
-
- // create the MainApplication adaptor:
- new MainApplicationAdaptor(this);
-
- // connect to D-Bus:
- QDBusConnection connection = QDBusConnection::addConnection(QDBusConnection::SessionBus);
-
- // register us as an object:
- connection.registerObject("/MainApplication", this);
-
- [...]
- }
- \endcode
-
- Break-down analysis:
- - \subpage AdaptorExampleHeader
- - \subpage AdaptorExampleProperties
- - \subpage AdaptorExampleConstructor
- - \subpage AdaptorExampleSlots
- - \subpage AdaptorExampleSignals
-*/
-
-/*!
- \page AdaptorExampleHeader The header
-
- The header of the example is:
- \code
- class MainApplicationAdaptor: public QDBusAbstractAdaptor
- {
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "com.example.DBus.MainApplication")
- Q_CLASSINFO("D-Bus Interface", "org.kde.DBus.MainApplication")
- \endcode
-
- The code does the following:
- - it declares the adaptor MainApplicationAdaptor, which descends from QDBusAbstractAdaptor
- - it declares the Qt Meta Object data using the #Q_OBJECT macro
- - it declares the names of two D-Bus interfaces it implements. Those interfaces are equal in all
- aspects.
-*/
-
-/*!
- \page AdaptorExampleProperties The properties
-
- The properties are declared as follows:
- \code
- Q_PROPERTY(QString caption READ caption WRITE setCaption)
- Q_PROPERTY(QString organizationName READ organizationName)
- Q_PROPERTY(QString organizationDomain READ organizationDomain)
- \endcode
-
- And are implemented as follows:
- \code
- QString caption()
- {
- if (app->hasMainWindow())
- return app->mainWindow()->caption();
- return QString();
- }
-
- void setCaption(const QString &newCaption)
- {
- if (app->hasMainWindow())
- app->mainWindow()->setCaption(newCaption);
- }
-
- QString organizationName()
- {
- return app->organizationName();
- }
-
- QString organizationDomain()
- {
- return app->organizationDomain();
- }
- \endcode
-
- The code declares three properties: one of them is a read-write property called "caption" of
- string type. The other two are read-only, also of the string type.
-
- The properties organizationName and organizationDomain are simple relays of the app object's
- organizationName and organizationDomain properties. However, the caption property requires
- verifying if the application has a main window associated with it: if there isn't any, the
- caption property is empty. Note how it is possible to access data defined in other objects
- through the getter/setter functions.
- */
-
-/*!
- \page AdaptorExampleConstructor The constructor
-
- The constructor:
- \code
- MyInterfaceAdaptor(MyApplication *application)
- : QDBusAbstractAdaptor(application), app(application)
- {
- connect(application, SIGNAL(aboutToQuit()), SIGNAL(aboutToQuit());
- connect(application, SIGNAL(focusChanged(QWidget*, QWidget*)),
- SLOT(focusChangedSlot(QWidget*, QWidget*)));
- }
- \endcode
-
- The constructor does the following:
- - it initialises its base class (QDBusAbstractAdaptor) with the parent object it is related to.
- - it stores the app pointer in a member variable. Note that it would be possible to access the
- same object using the QDBusAbstractAdaptor::object() function, but it would be necessary to
- use \a static_cast<> to properly access the methods in MyApplication that are not part of
- QObject.
- - it connects the application's signal \a aboutToQuit to its own signal \a aboutToQuit.
- - it connects the application's signal \a focusChanged to a private slot to do some further
- processing before emitting a D-Bus signal.
-
- Note that there is no destructor in the example. An eventual destructor could be used to emit
- one last signal before the object is destroyed, for instance.
-*/
-
-/*!
- \page AdaptorExampleSlots Slots/methods
-
- The public slots in the example (which will be exported as D-Bus methods) are the following:
- \code
- public slots:
- async void quit()
- { app->quit(); }
-
- void reparseConfiguration()
- { app->reparseConfiguration(); }
-
- QString mainWindowObject()
- {
- if (app->hasMainWindow())
- return QString("/%1/mainwindow").arg(app->applicationName());
- return QString();
- }
-
- void setSessionManagement(bool enable)
- {
- if (enable)
- app->enableSessionManagement();
- else
- app->disableSessionManagement();
- }
- \endcode
-
- This snippet of code defines 4 methods with different properties each:
- - \p quit: this method takes no parameters and is defined to be asynchronous. That is, callers
- are expected to use "fire-and-forget" mechanism when calling this method, since it provides no
- useful reply. This is represented in D-Bus by the use of the
- org.freedesktop.DBus.Method.NoReply annotation. See #Q_ASYNC for more information on
- asynchronous methods
-
- - \p reparseConfiguration: this simple method, with no input or output arguments simply relays
- the call to the application's reparseConfiguration member function.
-
- - \p mainWindowObject: this method takes no input parameter, but returns one string output
- argument, containing the path to the main window object (if the application has a main
- window), or an empty string if it has no main window. Note that this method could have also
- been written: void mainWindowObject(QString &path).
-
- - \p setSessionManagement: this method takes one input argument (a boolean) and, depending on
- its value, it calls one function or another in the application.
-
- \sa #Q_ASYNC
-*/
-
-/*!
- \page AdaptorExampleSignals Signals
-
- The signals in this example are defined as follows:
- \code
- signals:
- void aboutToQuit();
- void mainWindowHasFocus();
- \endcode
-
- However, signal definition isn't enough: signals have to be emitted. One simple way of emitting
- signals is to connect another signal to them, so that Qt's signal handling system chains them
- automatically. This is what is done for the \a aboutToQuit signal (see \ref
- AdaptorExampleConstructor).
-
- When this is the case, one can use the QDBusAbstractAdaptor::setAutoRelaySignals to
- automatically connect every signal from the real object to the adaptor.
-
- When simple signal-to-signal connection isn't enough, one can use a private slot do do some
- work. This is what was done for the mainWindowHasFocus signal:
- \code
- private slots:
- void focusChangedSlot(QWidget *, QWidget *now)
- {
- if (now == app->mainWindow())
- emit mainWindowHasFocus();
- }
- \endcode
-
- This private slot (which will not be exported as a method via D-Bus) was connected to the
- \a focusChanged signal in the adaptor's constructor. It is therefore able to shape the
- application's signal into what the interface expects it to be.
-*/
-
-/*!
- \page DeclaringSlots Declaring slots
-
- Slots in D-Bus adaptors are declared just like normal, public slots, but their parameters must
- follow certain rules (see \ref AllowedParameters for more information). Slots whose parameters
- do not follow those rules or that are not public will not be accessible via D-Bus.
-
- Slots can be of three kinds:
- -# Asynchronous
- -# Input-only
- -# Input-and-output
-
- \par Asynchronous slots
- Asynchronous slots are those that do not normally return any reply to the caller. For that
- reason, they cannot take any output parameters. In most cases, by the time the first line
- of the slot is run, the caller function has already resumed working.
-
- \par
- However, slots must rely on that behavior. Scheduling and message-dispatching issues could
- change the order in which the slot is run. Code intending to synchronize with the caller
- should provide its own method of synchronization.
-
- \par
- Asynchronous slots are marked by the keyword \p #async or \p #Q_ASYNC in the method
- signature, before the \p void return type and the slot name. (See the \p quit slot in the
- \ref AdaptorExample "adaptor example").
-
- \par Input-only slots
- Input-only slots are normal slots that take parameters passed by value or by constant
- reference. However, unlike asynchronous slots, the caller is usually waiting for completion
- of the callee before resuming operation. Therefore, non-asynchronous slots should not block
- or should state it its documentation that they may do so.
-
- \par
- Input-only slots have no special marking in their signature, except that they take only
- parameters passed by value or by constant reference. Optionally, slots can take a
- QDBusMessage parameter as a last parameter, which can be used to perform additional
- analysis of the method call message.
-
- \par Input and output slots
- Like input-only slots, input-and-output slots are those that the caller is waiting for a
- reply. Unlike input-only ones, though, this reply will contain data. Slots that output data
- may contain non-constant references and may return a value as well. However, the output
- parameters must all appear at the end of the argument list and may not have input arguments
- interleaved. Optionally, a QDBusMessage argument may appear between the input and the
- output arguments.
-
- \note When a caller places a method call and waits for a reply, it will only wait for so long.
- Slots intending to take a long time to complete should make that fact clear in
- documentation so that callers properly set higher timeouts.
-
- Method replies are generated automatically with the contents of the output parameters (if there
- were any) by the QtDBus implementation. Slots need not worry about constructing proper
- QDBusMessage objects and sending them over the connection.
-
- However, the possibility of doing so remains there. Should the slot find out it needs to send a
- special reply or even an error, it can do so by using QDBusMessage::methodReply or
- QDBusMessage::error on the QDBusMessage parameter and send it with QDBusConnection::send. The
- QtDBus implementation will not generate any reply if the slot did so.
-
- \sa \ref UsingAdaptors, \ref DeclaringSignals, \ref AllowedParameters, QDBusConnection,
- QDBusMessage
-*/
-
-/*!
- \page DeclaringSignals Declaring signals
-
- Any signal in a class derived from QDBusAbstractAdaptor will be automatically relayed into
- D-Bus, provided that the signal's parameters conform to certain rules (see \ref
- AllowedParameters for more information). No special code is necessary to make this relay.
-
- However, signals must still be emitted. The easiest way to emit an adaptor signal is to connect
- another signal to it, so that the Qt signal/slot mechanism automatically emits the adaptor
- signal too. This can be done in the adaptor's constructor, as has been done in the \ref
- AdaptorExample "adaptor example".
-
- The convenience function QDBusAbstractAdaptor::setAutoRelaySignals can also be used to connect
- or disconnect every signal in the real object to the same signal in the adaptor. It will inspect
- the list of signals in both classes and connect those that have exact parameter match.
-
- \sa \ref UsingAdaptors, \ref DeclaringSlots, \ref AllowedParameters, QDBusAbstractAdaptor
-*/
-
-/*!
- \page AllowedParameters Allowed parameter types
-
- D-Bus has a very limited set of types that can be sent and received over the bus. They are
- listed below, along with the D-Bus type they relate to:
- - unsigned char / uchar (BYTE)
- - short (INT16)
- - unsigned short / ushort (UINT16)
- - int (INT32)
- - unsigned int / uint (UINT32)
- - qlonglong (INT64)
- - qulonglong (UINT64)
- - bool (BOOLEAN)
- - double (DOUBLE)
- - QString (STRING)
- - QByteArray (ARRAY of BYTE)
- - QStringList (ARRAY of STRING)
- - QVariant / QDBusVariant (VARIANT)
- - QVariantList (ARRAY of VARIANT)
- - QVariantMap (ARRAY of DICT_ENTRY of (STRING, VARIANT))
-
- The last two types may be used to receive any array (except string and byte arrays), any structs
- and any maps. However, it is currently not possible to generate external function definitions
- containing specific types of lists, structs and maps.
-
- All of the types above may be passed by value or by constant reference for input arguments to
- slots as well as the output arguments to signals. When used as output arguments for slots, they
- can all be used as non-constant references or the return type.
-
- Additionally, slots can have one parameter of type \p const \p QDBusMessage \p \&, which must
- appear at the end of the input parameter list, before any output parameters. Signals cannot have
- this parameter.
-
- \warning You may not use any type that is not on the list above, including \a typedefs to the
- types listed. This also includes QList<QVariant> and QMap<QString,QVariant>.
-*/
-
-/*!
- \page UsingAnnotations Using annotations in adaptors
+ \page usingannotations.html
+ \title Using annotations in adaptors
It is currently not possible to specify arbitrary annotations in adaptors.
*/
@@ -589,14 +117,12 @@
and must not be deleted by the user (they will be deleted automatically when the object they are
connected to is also deleted).
- \sa \ref UsingAdaptors, QDBusConnection
+ \sa {usingadaptors.html}{Using adaptors}, QDBusConnection
*/
/*!
Constructs a QDBusAbstractAdaptor with \a parent as the object we refer to.
- \param parent the real object we're the adaptor for
-
\warning Use object() to retrieve the object passed as \a parent to this constructor. The real
parent object (as retrieved by QObject::parent()) may be something else.
*/
@@ -636,12 +162,12 @@
Automatic signal relaying consists of signal-to-signal connection of the signals on the parent
that have the exact same method signatue in both classes.
- \param enable if set to true, connect the signals; if set to false, disconnect all signals
+ If \a enable is set to true, connect the signals; if set to false, disconnect all signals.
*/
void QDBusAbstractAdaptor::setAutoRelaySignals(bool enable)
{
const QMetaObject *us = metaObject();
- const QMetaObject *them = parent()->metaObject();
+ const QMetaObject *them = object()->metaObject();
for (int idx = staticMetaObject.methodCount(); idx < us->methodCount(); ++idx) {
QMetaMethod mm = us->method(idx);
@@ -655,7 +181,7 @@
sig.prepend(QSIGNAL_CODE + '0');
object()->disconnect(sig, this, sig);
if (enable)
- connect(object(), sig, sig, Qt::QueuedConnection);
+ connect(object(), sig, sig);
}
}
@@ -752,8 +278,7 @@
// break down the parameter list
QList<int> types;
- QByteArray signature = QMetaObject::normalizedSignature(mm.signature());
- int inputCount = qDBusParametersForMethod(signature, types);
+ int inputCount = qDBusParametersForMethod(mm, types);
if (inputCount == -1)
// invalid signal signature
// qDBusParametersForMethod has already complained
@@ -766,6 +291,7 @@
return;
}
+ QByteArray signature = QMetaObject::normalizedSignature(mm.signature());
signature.truncate(signature.indexOf('(')); // remove parameter decoration
QVariantList args;
--- NEW FILE: qdbusabstractinterface.cpp ---
/* -*- C++ -*-
*
* Copyright (C) 2005 Thiago Macieira <thiago at kde.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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 "qdbusabstractinterface.h"
#include "qdbusabstractinterface_p.h"
#include "qdbusmetaobject_p.h"
#include "qdbusconnection_p.h"
/*!
\class QDBusAbstractInterface
\brief Base class for all D-Bus interfaces in the QtDBus binding, allowing access to remote interfaces.
Generated-code classes also derive from QDBusAbstractInterface, all methods described here are also
valid for generated-code classes. In addition to those described here, generated-code classes
provide member functions for the remote methods, which allow for compile-time checking of the
correct parameters and return values, as well as property type-matching and signal
parameter-matching.
\sa {dbusidl2cpp.html}{The dbusidl2cpp compiler}, QDBusInterface
*/
/*!
\enum QDBusAbstractInterface::CallMode
Specifies how a call should be placed. The valid options are:
\value NoWaitForReply place the call but don't wait for the reply (the reply's contents
will be discarded)
\value NoUseEventLoop don't use an event loop to wait for a reply, but instead block on
network operations while waiting. This option means the
user-interface may not be updated for the duration of the call.
\value UseEventLoop use the Qt event loop to wait for a reply. This option means the
user-interface will update, but it also means other events may
happen, like signal delivery and other D-Bus method calls.
When using UseEventLoop, applications must be prepared for reentrancy in any function.
*/
/*!
\internal
*/
QDBusAbstractInterface::QDBusAbstractInterface(QDBusAbstractInterfacePrivate* d)
#if QT_VERSION < 0x040200
: d_ptr(d)
{
d_ptr->q_ptr = this;
}
#endif
/*!
Releases this object's resources.
*/
QDBusAbstractInterface::~QDBusAbstractInterface()
{
delete d_ptr;
}
/*!
Returns the connection this interface is assocated with.
*/
QDBusConnection QDBusAbstractInterface::connection() const
{
return d_func()->conn;
}
/*!
Returns the name of the service this interface is associated with.
*/
QString QDBusAbstractInterface::service() const
{
return d_func()->service;
}
/*!
Returns the object path that this interface is associated with.
*/
QString QDBusAbstractInterface::path() const
{
return d_func()->path;
}
/*!
Returns the name of this interface.
*/
QString QDBusAbstractInterface::interface() const
{
return d_func()->interface;
}
/*!
Returns the error the last operation produced, or an invalid error if the last operation did not
produce an error.
*/
QDBusError QDBusAbstractInterface::lastError() const
{
return d_func()->lastError;
}
/*!
\threadsafe
Places a call to the remote method specified by \a method on this interface, using \a args as
arguments. This function returns the message that was received as a reply, which can be a normal
QDBusMessage::ReplyMessage (indicating success) or QDBusMessage::ErrorMessage (if the call
failed). The \a mode parameter specifies how this call should be placed.
If the call succeeds, lastError() will be cleared; otherwise, it will contain the error this
call produced.
Normally, you should place calls using call().
\warning If you use \c UseEventLoop, your code must be prepared to deal with any reentrancy:
other method calls and signals may be delivered before this function returns, as well
as other Qt queued signals and events.
*/
QDBusMessage QDBusAbstractInterface::callWithArgs(const QString& method, const QList<QVariant>& args,
CallMode mode)
{
Q_D(QDBusAbstractInterface);
QString m = method, sig;
// split out the signature from the method
int pos = method.indexOf(QLatin1Char('.'));
if (pos != -1) {
m.truncate(pos);
sig = method.mid(pos + 1);
}
QDBusMessage msg = QDBusMessage::methodCall(service(), path(), interface(), m);
msg.setSignature(sig);
msg.QList<QVariant>::operator=(args);
QDBusMessage reply;
if (mode != NoWaitForReply)
reply = d->conn.sendWithReply(msg, mode == UseEventLoop ?
QDBusConnection::UseEventLoop : QDBusConnection::NoUseEventLoop);
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;
}
/*!
\overload
Places a call to the remote method specified by \a method on this interface, using \a args as
arguments. This function will return immediately after queueing the call. The reply from the
remote function or any errors emitted by it will be delivered to the \a slot slot on object \a
receiver.
This function returns true if the queueing succeeded: it does not indicate that the call
succeeded. If it failed, the slot will be called with an error message. lastError() will not be
set under those circumstances.
\sa QDBusError, QDBusMessage
*/
bool QDBusAbstractInterface::callWithArgs(const QString &method, QObject *receiver, const char *slot,
const QList<QVariant> &args)
{
Q_D(QDBusAbstractInterface);
QString m = method, sig;
// split out the signature from the method
int pos = method.indexOf(QLatin1Char('.'));
if (pos != -1) {
m.truncate(pos);
sig = method.mid(pos + 1);
}
QDBusMessage msg = QDBusMessage::methodCall(service(), path(), interface(), m);
msg.setSignature(sig);
msg.QList<QVariant>::operator=(args);
d->lastError = 0; // clear
return d->conn.sendWithReplyAsync(msg, receiver, slot);
}
/*!
\internal
Catch signal connections.
*/
void QDBusAbstractInterface::connectNotify(const char *signal)
{
// someone connecting to one of our signals
Q_D(QDBusAbstractInterface);
d->connp->connectRelay(d->service, d->path, d->interface, this, signal);
}
/*!
\internal
Catch signal disconnections.
*/
void QDBusAbstractInterface::disconnectNotify(const char *signal)
{
// someone disconnecting from one of our signals
Q_D(QDBusAbstractInterface);
d->connp->disconnectRelay(d->service, d->path, d->interface, this, signal);
}
/*!
\overload
\fn QDBusMessage QDBusAbstractInterface::call(const QString &method)
Calls the method \a method on this interface and passes the parameters to this function to the
method.
The parameters to \c call are passed on to the remote function via D-Bus as input
arguments. Output arguments are returned in the QDBusMessage reply. If the reply is an error
reply, lastError() will also be set to the contents of the error message.
This function is implemented by actually 9 different function overloads called \c call, so you
can pass up to 8 parameters to your function call, which can be of any type accepted by QtDBus
(see the \l {allowedparameters.html}{allowed parameters} page for information on what types are
accepted).
It can be used the following way:
\code
QString value = retrieveValue();
QDBusMessage reply;
QDBusReply<int> api = interface->call(QLatin1String("GetAPIVersion"));
if (api >= 14)
reply = interface->call(QLatin1String("ProcessWorkUnicode"), value);
else
reply = interface->call(QLatin1String("ProcessWork"), QLatin1String("UTF-8"), value.toUtf8());
\endcode
This example illustrates function calling with 0, 1 and 2 parameters and illustrates different
parameter types passed in each (the first call to \c "ProcessWorkUnicode" will contain one
Unicode string, the second call to \c "ProcessWork" will contain one string and one byte array).
\warning This function reenters the Qt event loop in order to wait for the reply, excluding user
input. During the wait, it may deliver signals and other method calls to your
application. Therefore, it must be prepared to handle a reentrancy whenever a call is
placed with call().
*/
#include "qdbusabstractinterface.moc"
--- NEW FILE: qdbusabstractinterface.h ---
/* -*- C++ -*-
*
* Copyright (C) 2005 Thiago Macieira <thiago at kde.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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 QDBUSABSTRACTINTERFACE_H
#define QDBUSABSTRACTINTERFACE_H
#include <QtCore/qstring.h>
#include <QtCore/qvariant.h>
#include <QtCore/qlist.h>
#include <QtCore/qobject.h>
#include "qdbusmessage.h"
#include "qdbustypehelper_p.h"
class QDBusConnection;
class QDBusError;
class QDBusAbstractInterfacePrivate;
class QDBUS_EXPORT QDBusAbstractInterface: public QObject
{
Q_OBJECT
public:
enum CallMode {
NoWaitForReply,
UseEventLoop,
NoUseEventLoop
};
public:
virtual ~QDBusAbstractInterface();
QDBusConnection connection() const;
QString service() const;
QString path() const;
QString interface() const;
QDBusError lastError() const;
QDBusMessage callWithArgs(const QString &method, const QList<QVariant> &args = QList<QVariant>(),
CallMode mode = UseEventLoop);
bool callWithArgs(const QString &method, QObject *receiver, const char *slot,
const QList<QVariant> &args = QList<QVariant>());
inline QDBusMessage call(const QString &m)
{
return callWithArgs(m);
}
#ifndef Q_QDOC
private:
template<typename T> inline QVariant qvfv(const T &t)
{ return QDBusTypeHelper<T>::toVariant(t); }
public:
template<typename T1>
inline QDBusMessage call(const QString &m, const T1 &t1)
{
QList<QVariant> args;
args << qvfv(t1);
return callWithArgs(m, args);
}
template<typename T1, typename T2>
inline QDBusMessage call(const QString &m, const T1 &t1, const T2 &t2)
{
QList<QVariant> args;
args << qvfv(t1) << qvfv(t2);
return callWithArgs(m, args);
}
template<typename T1, typename T2, typename T3>
inline QDBusMessage call(const QString &m, const T1 &t1, const T2 &t2, const T3 &t3)
{
QList<QVariant> args;
args << qvfv(t1) << qvfv(t2) << qvfv(t3);
return callWithArgs(m, args);
}
template<typename T1, typename T2, typename T3, typename T4>
inline QDBusMessage call(const QString &m, const T1 &t1, const T2 &t2, const T3 &t3,
const T4 &t4)
{
QList<QVariant> args;
args << qvfv(t1) << qvfv(t2) << qvfv(t3)
<< qvfv(t4);
return callWithArgs(m, args);
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
inline QDBusMessage call(const QString &m, const T1 &t1, const T2 &t2, const T3 &t3,
const T4 &t4, const T5 &t5)
{
QList<QVariant> args;
args << qvfv(t1) << qvfv(t2) << qvfv(t3)
<< qvfv(t4) << qvfv(t5);
return callWithArgs(m, args);
}
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
inline QDBusMessage call(const QString &m, const T1 &t1, const T2 &t2, const T3 &t3,
const T4 &t4, const T5 &t5, const T6 &t6)
{
QList<QVariant> args;
args << qvfv(t1) << qvfv(t2) << qvfv(t3)
<< qvfv(t4) << qvfv(t5) << qvfv(t6);
return callWithArgs(m, args);
}
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
inline QDBusMessage call(const QString &m, const T1 &t1, const T2 &t2, const T3 &t3,
const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7)
{
QList<QVariant> args;
args << qvfv(t1) << qvfv(t2) << qvfv(t3)
<< qvfv(t4) << qvfv(t5) << qvfv(t6)
<< qvfv(t7);
return callWithArgs(m, args);
}
template<typename T1, typename T2, typename T3, typename T4, typename T5,
typename T6, typename T7, typename T8>
inline QDBusMessage call(const QString &m, const T1 &t1, const T2 &t2, const T3 &t3,
const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8)
{
QList<QVariant> args;
args << qvfv(t1) << qvfv(t2) << qvfv(t3)
<< qvfv(t4) << qvfv(t5) << qvfv(t6)
<< qvfv(t7) << qvfv(t8);
return callWithArgs(m, args);
}
#endif
protected:
QDBusAbstractInterface(QDBusAbstractInterfacePrivate *);
void connectNotify(const char *signal);
void disconnectNotify(const char *signal);
private:
friend class QDBusInterface;
QDBusAbstractInterfacePrivate *d_ptr; // remove for Qt 4.2.0
Q_DECLARE_PRIVATE(QDBusAbstractInterface)
Q_DISABLE_COPY(QDBusAbstractInterface)
};
#endif
--- NEW FILE: qdbusabstractinterface_p.h ---
/*
*
* Copyright (C) 2006 Thiago José Macieira <thiago at kde.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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 QDBUSABSTRACTINTERFACEPRIVATE_H
#define QDBUSABSTRACTINTERFACEPRIVATE_H
#include "qdbusabstractinterface.h"
#include "qdbusconnection.h"
#include "qdbuserror.h"
#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
class QDBusAbstractInterfacePrivate//: public QObjectPrivate
{
public:
Q_DECLARE_PUBLIC(QDBusAbstractInterface)
QDBusAbstractInterface *q_ptr; // remove in Qt 4.2
QDBusConnection conn;
QDBusConnectionPrivate *connp;
QString service;
QString path;
QString interface;
QDBusError lastError;
inline QDBusAbstractInterfacePrivate(const QDBusConnection& con, QDBusConnectionPrivate *conp,
const QString &serv, const QString &p, const QString &iface)
: conn(con), connp(conp), service(serv), path(p), interface(iface)
{ }
virtual ~QDBusAbstractInterfacePrivate() { }
};
#endif
--- NEW FILE: qdbusbus.cpp ---
/* -*- C++ -*-
*
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at trolltech.com>
*
* 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.
*
*/
/*
* This file was generated by dbusidl2cpp version 0.3
* when processing input file -
*
* dbusidl2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved.
*
* This file has been hand-edited! Be careful when re-generating it!
*
*/
#include "qdbusbus.h"
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
/*
* Implementation of interface class QDBusBusService
*/
/*!
\class QDBusBusService
\brief Provides access to the D-Bus bus daemon service.
*/
/*!
\enum QDBusBusService::RequestNameOption
Flags for requesting a name on the bus.
\value AllowReplacingName Allow another application requesting the same name to take the name
from this application.
\value ReplaceExistingName If another application already has the name and allows replacing,
take the name and assign it to us.
\value DoNotQueueName Without this flag, if an application requests a name that is already
owned and does not allow replacing, it will be queued until the
name is given up. If this flag is given, no queueing will be
performed and the requestName() call will simply fail.
*/
/*!
\enum QDBusBusService::RequestNameReply
The possible return values from requestName():
\value PrimaryOwnerReply The caller is now the primary owner of the name.
\value InQueueReply The caller is in queue for the name, but does not own it.
\value NameExistsReply The name exists and could not be replaced, or the caller did
specify DoNotQueueName.
\value AlreadyOwnerReply The caller tried to request a name that it already owns.
*/
/*!
\enum QDBusBusService::ReleaseNameReply
The possible return values from releaseName():
\value NameReleasedReply The caller released his claim on the name.
\value NameNonExistentReply The caller tried to release a name that did not exist.
\value NotOwnerReply The caller tried to release a name that it did not own or was not in
queue for.
*/
/*!
\enum QDBusBusService::StartServiceReply
The possible return values from startServiceByName():
\value Success The service was successfully started.
\value AlreadyRunning The service was already running.
*/
/*!
\internal
*/
const char *QDBusBusService::staticInterfaceName()
{ return "org.freedesktop.DBus"; }
/*!
\internal
*/
QDBusBusService::QDBusBusService(QDBusAbstractInterfacePrivate *p)
: QDBusAbstractInterface(p)
{
connect(this, SIGNAL(NameAcquired(QString)), this, SIGNAL(nameAcquired(QString)));
connect(this, SIGNAL(NameLost(QString)), this, SIGNAL(nameLost(QString)));
connect(this, SIGNAL(NameOwnerChanged(QString,QString,QString)),
this, SIGNAL(nameOwnerChanged(QString,QString,QString)));
}
/*!
\internal
*/
QDBusBusService::~QDBusBusService()
{
}
/*!
\fn QDBusBusService::hello()
\internal
Sends a "Hello" request to the bus service. You do not want to call this.
*/
QDBusReply<QString> QDBusBusService::Hello()
{
return call(QLatin1String("Hello"));
}
/*!
\fn QDBusBusService::nameOwner(const QString &name)
Returns the unique connection name of the primary owner of the name \a name. If the requested
name doesn't have an owner, returns a org.freedesktop.DBus.Error.NameHasNoOwner error.
*/
QDBusReply<QString> QDBusBusService::GetNameOwner(const QString &name)
{
return call(QLatin1String("GetNameOwner.s"), name);
}
/*!
\fn QDBusBusService::listNames()
Lists all names currently existing on the bus.
*/
QDBusReply<QStringList> QDBusBusService::ListNames()
{
return call(QLatin1String("ListNames"));
}
/*!
\fn QDBusBusService::listQueuedOwners(const QString &service)
Returns a list of all unique connection names in queue for the service name \a service.
*/
QDBusReply<QStringList> QDBusBusService::ListQueuedOwners(const QString &service)
{
return call(QLatin1String("ListQueuedOwners.s"), service);
}
/*!
\fn QDBusBusService::nameHasOwner(const QString &service)
Returns true if the service name \a service has an owner.
*/
QDBusReply<bool> QDBusBusService::NameHasOwner(const QString &service)
{
return call(QLatin1String("NameHasOwner.s"), service);
}
/*!
\fn QDBusBusService::addMatch(const QString &rule)
Adds the rule \a rule for requesting messages from the bus.
\sa removeMatch()
*/
QDBusReply<void> QDBusBusService::AddMatch(const QString &rule)
{
return call(QLatin1String("AddMatch.s"), rule);
}
/*!
\fn QDBusBusService::removeMatch(const QString &rule)
Removes the rule \a rule, that had previously been added with addMatch().
*/
QDBusReply<void> QDBusBusService::RemoveMatch(const QString &rule)
{
return call(QLatin1String("RemoveMatch.s"), rule);
}
/*!
\fn QDBusBusService::connectionSELinuxSecurityContext(const QString &service)
Returns the SELinux security context of the process currently holding the bus service \a
service.
*/
QDBusReply<QByteArray> QDBusBusService::GetConnectionSELinuxSecurityContext(const QString &service)
{
return call(QLatin1String("GetConnectionSELinuxSecurityContext.s"), service);
}
/*!
\fn QDBusBusService::connectionUnixProcessID(const QString &service)
Returns the Unix Process ID (PID) for the process currently holding the bus service \a service.
*/
QDBusReply<uint> QDBusBusService::GetConnectionUnixProcessID(const QString &service)
{
return call(QLatin1String("GetConnectionUnixProcessID.s"), service);
}
/*!
\fn QDBusBusService::connectionUnixUser(const QString &service)
Returns the Unix User ID (UID) for the process currently holding the bus service \a service.
*/
QDBusReply<uint> QDBusBusService::GetConnectionUnixUser(const QString &service)
{
return call(QLatin1String("GetConnectionUnixUser.s"), service);
}
/*!
\fn QDBusBusService::reloadConfig()
Asks the D-Bus server daemon to reload its configuration.
*/
QDBusReply<void> QDBusBusService::ReloadConfig()
{
return call(QLatin1String("ReloadConfig"));
}
inline QDBUS_EXPORT int qDBusMetaTypeId(QDBusBusService::StartServiceReply *)
{ return QVariant::Int; }
/*!
\fn QDBusBusService::startServiceByName(const QString &name, uint flags)
Requests that the bus start the service given by the name \a name.
The \a flags parameter is currently not used.
*/
QDBusReply<QDBusBusService::StartServiceReply>
QDBusBusService::StartServiceByName(const QString &name, uint flags)
{
return call(QLatin1String("StartServiceByName.su"), name, flags);
}
inline QDBUS_EXPORT int qDBusMetaTypeId(QDBusBusService::RequestNameReply *)
{ return QVariant::Int; }
/*!
\fn QDBusBusService::requestName(const QString &service, RequestNameOptions flags)
Requests the bus service name \a service from the bus. The \a flags parameter specifies how the
bus server daemon should act when the same name is requested by two different applications.
\sa releaseName()
*/
QDBusReply<QDBusBusService::RequestNameReply>
QDBusBusService::RequestName(const QString &service, RequestNameOptions flags)
{
return call(QLatin1String("RequestName.su"), service, uint(int(flags)));
}
inline QDBUS_EXPORT int qDBusMetaTypeId(QDBusBusService::ReleaseNameReply *)
{ return QVariant::Int; }
/*!
\fn QDBusBusService::releaseName(const QString &service)
Releases the claim on the bus service name \a service, that had been previously requested with
requestName(). If this application had ownership of the name, it will be released for other
applications to claim. If it only had the name queued, it gives up its position in the queue.
*/
QDBusReply<QDBusBusService::ReleaseNameReply>
QDBusBusService::ReleaseName(const QString &service)
{
return call(QLatin1String("ReleaseName.s"), service);
}
// signals
/*!
\fn QDBusBusService::nameAcquired(const QString &service)
This signal is emitted by the D-Bus bus server when the bus service name (unique connection name
or well-known service name) given by \a service is acquired by this application.
Name acquisition happens after the application requested a name using requestName().
*/
/*!
\fn QDBusBusService::nameLost(const QString &service)
This signal is emitted by the D-Bus bus server when the application loses ownership of the bus
service name given by \a service.
*/
/*!
\fn QDBusBusService::nameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
This signal is emitted by the D-Bus bus server whenever a name ownership change happens in the
bus, including apparition and disparition of names.
This signal means the application \a oldOwner lost ownership of bus name \a name to application
\a newOwner. If \a oldOwner is an empty string, it means the name \a name has just been created;
if \a newOwner is empty, the name \a name has no current owner.
*/
#include "qdbusbus.moc"
--- NEW FILE: qdbusbus.h ---
/* -*- C++ -*-
*
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at trolltech.com>
*
* 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.
*
*/
/*
* This file was generated by dbusidl2cpp version 0.3
* when processing input file -
*
* dbusidl2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved.
*
* This file has been hand-edited! Be careful when re-generating it!
*
*/
#ifndef QDBUSBUS_H
#define QDBUSBUS_H
#include <QtCore/qstringlist.h>
#include "qdbusabstractinterface.h"
#include "qdbusreply.h"
class QDBusConnection;
class QString;
class QByteArray;
/*
* Proxy class for interface org.freedesktop.DBus
*/
class QDBUS_EXPORT QDBusBusService: public QDBusAbstractInterface
{
Q_OBJECT
friend class QDBusConnection;
static inline const char *staticInterfaceName();
explicit QDBusBusService(QDBusAbstractInterfacePrivate *p);
~QDBusBusService();
public:
// taken out of http://dbus.freedesktop.org/doc/dbus-specification.html
// update if the standard updates
enum RequestNameOption {
AllowReplacingName = 0x1,
ReplaceExistingName = 0x2,
DoNotQueueName = 0x4
};
Q_DECLARE_FLAGS(RequestNameOptions, RequestNameOption)
enum RequestNameReply {
PrimaryOwnerReply = 1,
InQueueReply = 2,
NameExistsReply = 3,
AlreadyOwnerReply = 4
};
enum ReleaseNameReply {
NameReleasedReply = 1,
NameNonExistentReply = 2,
NotOwnerReply = 3
};
enum StartServiceReply {
Success = 1,
AlreadyRunning = 2
};
#ifndef Q_QDOC
// D-Bus names
public: // METHODS
QDBusReply<QString> Hello();
QDBusReply<void> ReloadConfig();
QDBusReply<QStringList> ListNames();
QDBusReply<bool> NameHasOwner(const QString &service);
QDBusReply<QString> GetNameOwner(const QString &name);
QDBusReply<ReleaseNameReply> ReleaseName(const QString &service);
QDBusReply<RequestNameReply> RequestName(const QString &service, RequestNameOptions flags);
QDBusReply<QStringList> ListQueuedOwners(const QString &service);
QDBusReply<void> AddMatch(const QString &rule);
QDBusReply<void> RemoveMatch(const QString &rule);
QDBusReply<QByteArray> GetConnectionSELinuxSecurityContext(const QString &service);
QDBusReply<uint> GetConnectionUnixProcessID(const QString &service);
QDBusReply<uint> GetConnectionUnixUser(const QString &service);
QDBusReply<StartServiceReply> StartServiceByName(const QString &name, uint flags);
signals: // SIGNALS
void NameAcquired(const QString &service);
void NameLost(const QString &service);
void NameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
#endif
// Qt-style naming
public slots:
QDBusReply<QString> hello()
{ return Hello(); }
QDBusReply<void> reloadConfig()
{ return ReloadConfig(); }
QDBusReply<QStringList> listNames()
{ return ListNames(); }
QDBusReply<bool> nameHasOwner(const QString &service)
{ return NameHasOwner(service); }
QDBusReply<QString> nameOwner(const QString &name)
{ return GetNameOwner(name); }
QDBusReply<ReleaseNameReply> releaseName(const QString &service)
{ return ReleaseName(service); }
QDBusReply<RequestNameReply> requestName(const QString &service, RequestNameOptions flags)
{ return RequestName(service, flags); }
QDBusReply<QStringList> listQueuedOwners(const QString &service)
{ return ListQueuedOwners(service); }
QDBusReply<void> addMatch(const QString &rule)
{ return AddMatch(rule); }
QDBusReply<void> removeMatch(const QString &rule)
{ return RemoveMatch(rule); }
QDBusReply<QByteArray> connectionSELinuxSecurityContext(const QString &service)
{ return GetConnectionSELinuxSecurityContext(service); }
QDBusReply<uint> connectionUnixProcessID(const QString &service)
{ return GetConnectionUnixProcessID(service); }
QDBusReply<uint> connectionUnixUser(const QString &service)
{ return GetConnectionUnixUser(service); }
QDBusReply<StartServiceReply> startServiceByName(const QString &name, uint flags)
{ return StartServiceByName(name, flags); }
signals:
void nameAcquired(const QString &service);
void nameLost(const QString &service);
void nameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusBusService::RequestNameOptions);
#endif
Index: qdbusconnection.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusconnection.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- qdbusconnection.cpp 6 Mar 2006 14:29:39 -0000 1.5
+++ qdbusconnection.cpp 28 Mar 2006 18:56:08 -0000 1.6
@@ -24,13 +24,14 @@
#include <qdebug.h>
#include <qcoreapplication.h>
+#include <qstringlist.h>
+#include "qdbusbus.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"
class QDBusConnectionManager
@@ -97,6 +98,7 @@
/*!
\fn QDBusConnection QDBus::sessionBus()
+ \relates QDBusConnection
Returns a QDBusConnection object opened with the session bus. The object reference returned
by this function is valid until the QCoreApplication's destructor is run, when the
@@ -104,6 +106,7 @@
*/
/*!
\fn QDBusConnection QDBus::systemBus()
+ \relates QDBusConnection
Returns a QDBusConnection object opened with the system bus. The object reference returned
by this function is valid until the QCoreApplication's destructor is run, when the
@@ -117,22 +120,22 @@
This class is the initial point in a D-Bus session. Using it, you can get access to remote
objects, interfaces; connect remote signals to your object's slots; register objects, etc.
- D-Bus connections are created using the QDBusConnection::addConnection function, which opens a
+ D-Bus connections are created using the QDBusConnection::addConnection() function, which opens a
connection to the server daemon and does the initial handshaking, associating that connection
with a name. Further attempts to connect using the same name will return the same
connection.
- The connection is then torn down using the QDBusConnection::closeConnection function.
+ The connection is then torn down using the QDBusConnection::closeConnection() function.
- As a convenience for the two most common connection types, the QDBus::sessionBus and
- QDBus::systemBus functions return open connections to the session server daemon and the system
+ As a convenience for the two most common connection types, the QDBus::sessionBus() and
+ QDBus::systemBus() functions return open connections to the session server daemon and the system
server daemon, respectively. Those connections are opened when first used and are closed when
the QCoreApplication destructor is run.
D-Bus also supports peer-to-peer connections, without the need for a bus server daemon. Using
this facility, two applications can talk to each other and exchange messages. This can be
- achieved by passing an address to QDBusConnection::addConnection(const QString &, const QString
- &) function, which was opened by another D-Bus application using QDBusServer.
+ achieved by passing an address to QDBusConnection::addConnection()
+ function, which was opened by another D-Bus application using QDBusServer.
*/
/*!
@@ -146,15 +149,23 @@
On the Session Bus, one can find other applications by the same user that are sharing the same
desktop session (hence the name). On the System Bus, however, processes shared for the whole
system are usually found.
-
- \todo Find out what the ActivationBus is for
*/
/*!
- \enum QDBusConnection::NameRequestMode
- Specifies the flags for when requesting a name in the bus.
+ \enum QDBusConnection::WaitMode
+ Specifies the call waiting mode.
- \bug Change the enum into flags and update with the new flags from the spec.
+ \value UseEventLoop use the Qt Event Loop to wait for the reply
+ \value NoUseEventLoop don't use the event loop
+
+ The \c UseEventLoop option allows for the application to continue to update its UI while the
+ call is performed, but it also opens up the possibility for reentrancy: socket notifiers may
+ fire, signals may be delivered and other D-Bus calls may be processed. The \c NoUseEventLoop
+ does not use the event loop, thus being safe from those problems, but it may block the
+ application for a noticeable period of time, in case the remote application fails to respond.
+
+ Also note that calls that go back to the local application can only be placed in \c UseEventLoop
+ mode.
*/
/*!
@@ -169,21 +180,21 @@
\value ExportContents shorthand form for ExportSlots | ExportSignals |
ExportProperties
- \value ExportNonScriptableSlots export all of this object's slots, including
+ \value ExportAllSlots export all of this object's slots, including
non-scriptable ones
- \value ExportNonScriptableSignals export all of this object's signals, including
+ \value ExportAllSignals export all of this object's signals, including
non-scriptable ones
- \value ExportNonScriptableProperties export all of this object's properties, including
+ \value ExportAllProperties export all of this object's properties, including
non-scriptable ones
- \value ExportNonScriptableContents export all of this object's slots, signals and
+ \value ExportAllContents export all of this object's slots, signals and
properties, including non-scriptable ones
\value ExportChildObjects export this object's child objects
- \note It is currently not possible to export signals from objects. If you pass the flag
- ExportSignals or ExportNonScriptableSignals, the registerObject() function will print a warning.
+ \warning It is currently not possible to export signals from objects. If you pass the flag
+ ExportSignals or ExportAllSignals, the registerObject() function will print a warning.
- \sa QDBusConnection::registerObject, QDBusAbstractAdaptor, \ref UsingAdaptors
+ \sa registerObject(), QDBusAbstractAdaptor, {usingadaptors.html}{Using adaptors}
*/
/*!
@@ -198,7 +209,7 @@
*/
/*!
- Creates a QDBusConnection object attached to the connection with name \p name.
+ Creates a QDBusConnection object attached to the connection with name \a name.
This does not open the connection. You have to call QDBusConnection::addConnection to open it.
*/
@@ -210,7 +221,7 @@
}
/*!
- Creates a copy of the \p other connection.
+ Creates a copy of the \a other connection.
*/
QDBusConnection::QDBusConnection(const QDBusConnection &other)
{
@@ -230,7 +241,7 @@
}
/*!
- Creates a copy of the connection \p other in this object. The connection this object referenced
+ Creates a copy of the connection \a other in this object. The connection this object referenced
before the copy is not spontaneously disconnected. See QDBusConnection::closeConnection for more
information.
*/
@@ -247,8 +258,8 @@
}
/*!
- Opens a connection of type \p type to one of the known busses and associate with it the
- connection name \p name. Returns a QDBusConnection object associated with that connection.
+ Opens a connection of type \a type to one of the known busses and associate with it the
+ connection name \a name. Returns a QDBusConnection object associated with that connection.
*/
QDBusConnection QDBusConnection::addConnection(BusType type, const QString &name)
{
@@ -276,12 +287,25 @@
manager()->setConnection(name, d);
- return QDBusConnection(name);
+ QDBusConnection retval(name);
+
+ // create the bus service
+ QDBusAbstractInterfacePrivate *p;
+ p = retval.findInterface_helper(QLatin1String(DBUS_SERVICE_DBUS),
+ QLatin1String(DBUS_PATH_DBUS),
+ QLatin1String(DBUS_INTERFACE_DBUS));
+ if (p) {
+ d->busService = new QDBusBusService(p);
+ d->busService->setParent(d); // auto-deletion
+ d->ref.deref(); // busService has a increased the refcounting to us
+ }
+
+ return retval;
}
/*!
- Opens a peer-to-peer connection on address \p address and associate with it the
- connection name \p name. Returns a QDBusConnection object associated with that connection.
+ Opens a peer-to-peer connection on address \a address and associate with it the
+ connection name \a name. Returns a QDBusConnection object associated with that connection.
*/
QDBusConnection QDBusConnection::addConnection(const QString &address,
const QString &name)
@@ -299,11 +323,24 @@
manager()->setConnection(name, d);
- return QDBusConnection(name);
+ QDBusConnection retval(name);
+
+ // create the bus service
+ QDBusAbstractInterfacePrivate *p;
+ p = retval.findInterface_helper(QLatin1String(DBUS_SERVICE_DBUS),
+ QLatin1String(DBUS_PATH_DBUS),
+ QLatin1String(DBUS_INTERFACE_DBUS));
+ if (p) {
+ d->busService = new QDBusBusService(p);
+ d->busService->setParent(d); // auto-deletion
+ d->ref.deref(); // busService has a increased the refcounting to us
+ }
+
+ return retval;
}
/*!
- Closes the connection of name \p name.
+ Closes the connection of name \a name.
Note that if there are still QDBusConnection objects associated with the same connection, the
connection will not be closed until all references are dropped. However, no further references
@@ -321,10 +358,10 @@
}
/*!
- Sends the message over this connection, without waiting for a reply. This is suitable for errors,
- signals, and return values as well as calls whose return values are not necessary.
+ Sends the \a message over this connection, without waiting for a reply. This is suitable for
+ errors, signals, and return values as well as calls whose return values are not necessary.
- \returns true if the message was queued successfully, false otherwise
+ Returns true if the message was queued successfully, false otherwise.
*/
bool QDBusConnection::send(const QDBusMessage &message) const
{
@@ -334,14 +371,14 @@
}
/*!
- Sends the message over this connection and returns immediately after queueing it. When the reply
- is received, the slot \p method is called in the object \p receiver. This function is suitable
- for method calls only.
+ Sends the \a message over this connection and returns immediately after queueing it. When the
+ reply is received, the slot \a method is called in the object \a receiver. This function is
+ suitable for method calls only.
This function guarantees that the slot will be called exactly once with the reply, as long as
the parameter types match. If they don't, the reply cannot be delivered.
- \returns true if the message was queued successfully, false otherwise.
+ Returns the identification of the message that was sent or 0 if nothing was sent.
*/
int QDBusConnection::sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
const char *method) const
@@ -353,67 +390,34 @@
}
/*!
- Sends the message over this connection and blocks, waiting for a reply. This function is
+ Sends the \a message over this connection and blocks, waiting for a reply. This function is
suitable for method calls only. It returns the reply message as its return value, which will be
either of type QDBusMessage::ReplyMessage or QDBusMessage::ErrorMessage.
See the QDBusInterface::call function for a more friendly way of placing calls.
- \warning This function reenters the Qt event loop in order to wait for the reply, excluding user
- input. During the wait, it may deliver signals and other method calls to your
- application. Therefore, it must be prepared to handle a reentrancy whenever a call is
- placed with sendWithReply().
+ \warning If \a mode is \c UseEventLoop, this function will reenter the Qt event loop in order to
+ wait for the reply. During the wait, it may deliver signals and other method calls to
+ your application. Therefore, it must be prepared to handle a reentrancy whenever a call
+ is placed with sendWithReply.
*/
-QDBusMessage QDBusConnection::sendWithReply(const QDBusMessage &message) const
+QDBusMessage QDBusConnection::sendWithReply(const QDBusMessage &message, WaitMode mode) const
{
if (!d || !d->connection)
- return QDBusMessage::fromDBusMessage(0, *this);
-
- if (!QCoreApplication::instance()) {
- DBusMessage *msg = message.toDBusMessage();
- if (!msg)
- return QDBusMessage::fromDBusMessage(0, *this);
-
- 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, *this);
- } 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, *this);
- }
+ return QDBusMessage();
+ return d->sendWithReply(message, mode);
}
/*!
- Connects the signal to the slot \p slot in object \p receiver.
-
- \param service the service that will emit the signal, or QString() to wait for the signal
- coming from any remote application
- \param path the path that will emit the signal, or QString() to wait for the signal
- coming from any object path (usually associated with an empty \p service)
- \param interface the name of the interface to for this signal
- \param name the name of the signal
- \param receiver the object to connect to
- \param slot the slot that will be invoked when the signal is emitted
- \returns true if the connection was successful
+ Connects the signal specified by the \a service, \a path, \a interface and \a name parameters to
+ the slot \a slot in object \a receiver. The arguments \a service and \a path can be empty,
+ denoting a connection to any signal of the \a interface - \a name pair, from any remote
+ application.
- \note The signal will only be delivered to the slot if the parameters match. This verification
- can be done only when the signal is received, not at connection time.
+ Returns true if the connection was successful.
- \bug does not allow an empty service
+ \warning The signal will only be delivered to the slot if the parameters match. This verification
+ can be done only when the signal is received, not at connection time.
*/
bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
const QString &name, QObject *receiver, const char *slot)
@@ -423,12 +427,10 @@
/*!
\overload
- Connects the signal to the slot \p slot in object \p receiver. Unlike the other
+ Connects the signal to the slot \a slot in object \a receiver. Unlike the other
QDBusConnection::connect overload, this function allows one to specify the parameter signature
- to be connected. The function will then verify that this signature can be delivered to the slot
- specified by \p slot and return false otherwise.
-
- \bug does not validate signature vs slot yet
+ to be connected using the \a signature variable. The function will then verify that this
+ signature can be delivered to the slot specified by \a slot and return false otherwise.
*/
bool QDBusConnection::connect(const QString &service, const QString &path, const QString& interface,
const QString &name, const QString &signature,
@@ -439,7 +441,7 @@
QString source;
if (!service.isEmpty()) {
- source = getNameOwner(service);
+ source = d->getNameOwner(service);
if (source.isEmpty())
return false;
}
@@ -456,6 +458,7 @@
hook.obj = receiver;
// avoid duplicating:
+ QWriteLocker locker(&d->lock);
QDBusConnectionPrivate::SignalHookHash::ConstIterator it = d->signalHooks.find(source);
for ( ; it != d->signalHooks.end() && it.key() == source; ++it) {
const QDBusConnectionPrivate::SignalHook &entry = it.value();
@@ -475,11 +478,12 @@
}
/*!
- Registers the object \p object at path \p path and returns true if the registration was
- successful.
+ Registers the object \a object at path \a path and returns true if the registration was
+ successful. The \a options parameter specifies how much of the object \a object will be exposed
+ through D-Bus.
This function does not replace existing objects: if there is already an object registered at
- path \p path, this function will return false. Use unregisterObject() to unregister it first.
+ path \a path, this function will return false. Use unregisterObject() to unregister it first.
You cannot register an object as a child object of an object that was registered with
QDBusConnection::ExportChildObjects.
@@ -552,8 +556,8 @@
}
/*!
- Unregisters an object that was registered with the registerObject() function and, if \p mode is
- QDBusConnection::UnregisterTree, all of its sub-objects too.
+ Unregisters an object that was registered with the registerObject() at the object path given by
+ \a path and, if \a mode is QDBusConnection::UnregisterTree, all of its sub-objects too.
Note that you cannot unregister objects that were not registered with registerObject().
*/
@@ -594,61 +598,81 @@
}
/*!
- Returns a QDBusInterface associated with the interface \p interface on object at path \p path on
- service \p service.
-*/
-QDBusInterface QDBusConnection::findInterface(const QString& service, const QString& path,
- const QString& interface)
-{
- // create one
- QDBusInterfacePrivate *priv = new QDBusInterfacePrivate(*this);
-
- if (!(interface.isEmpty() || QDBusUtil::isValidInterfaceName(interface)) ||
- !QDBusUtil::isValidObjectPath(path))
- return QDBusInterface(priv);
-
- // check if it's there first
- QString owner = getNameOwner(service);
- if (owner.isEmpty())
- return QDBusInterface(priv);
+ Returns a dynamic QDBusInterface associated with the interface \a interface on object at path \a
+ path on service \a service.
- // getNameOwner returns empty if d is 0
- Q_ASSERT(d);
- priv->service = owner;
- priv->path = path;
- priv->data = d->findInterface(interface).constData();
+ This function creates a new object. It is your resposibility to ensure it is properly deleted
+ (you can use all normal QObject deletion mechanisms, including the QObject::deleteLater() slot
+ and QObject::setParent()).
- return QDBusInterface(priv); // will increment priv's refcount
+ If the searching for this interface on the remote object failed, this function returns 0.
+*/
+QDBusInterface *QDBusConnection::findInterface(const QString& service, const QString& path,
+ const QString& interface)
+{
+ if (!d)
+ return 0;
+
+ QDBusInterfacePrivate *p = d->findInterface(service, path, interface);
+ if (!p)
+ return 0;
+ QDBusInterface *retval = new QDBusInterface(p);
+ retval->setParent(d);
+ return retval;
}
/*!
\fn QDBusConnection::findInterface(const QString &service, const QString &path)
- Returns an interface of type \p Interface associated with the object on path \p path at service
- \p service.
+ Returns an interface of type \c Interface associated with the object on path \a path at service
+ \a service.
- \p Interface must be a class derived from QDBusInterface.
+ \c Interface must be a class generated by \l {dbusidl2cpp.html}.
+
+ This function creates a new object. It is your resposibility to ensure it is properly deleted
+ (you can use all normal QObject deletion mechanisms, including the QObject::deleteLater() slot
+ and QObject::setParent()).
*/
/*!
- Returns a QDBusObject associated with the object on path \p path at service \p service.
+ Returns a QDBusBusService object that represents the D-Bus bus service on this connection.
+
+ This function returns 0 for peer-to-peer connections.
*/
-QDBusObject QDBusConnection::findObject(const QString& service, const QString& path)
+QDBusBusService *QDBusConnection::busService() const
{
- QDBusObjectPrivate* priv = 0;
- if (d && QDBusUtil::isValidObjectPath(path)) {
- QString owner = getNameOwner(service);
+ if (!d)
+ return 0;
+ return d->busService;
+};
- if (!owner.isEmpty())
- priv = new QDBusObjectPrivate(d, owner, path);
- }
- return QDBusObject(priv, *this);
-}
+QDBusAbstractInterfacePrivate *
+QDBusConnection::findInterface_helper(const QString &service, const QString &path,
+ const QString &interface)
+{
+ if (!d)
+ return 0;
+ if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface))
+ return 0;
+
+ QString owner;
+ if (!service.isEmpty()) {
+ if (!QDBusUtil::isValidObjectPath(path))
+ return 0;
+ // check if it's there first -- FIXME: add binding mode
+ owner = d->getNameOwner(service);
+ if (owner.isEmpty())
+ return 0;
+ } else if (!path.isEmpty())
+ return 0;
+
+ return new QDBusAbstractInterfacePrivate(*this, d, owner, path, interface);
+}
/*!
Returns true if this QDBusConnection object is connected.
- \note If it isn't connected, calling QDBusConnection::addConnection on the same connection name
+ If it isn't connected, calling QDBusConnection::addConnection on the same connection name
will not make be connected. You need to call the QDBusConnection constructor again.
*/
bool QDBusConnection::isConnected( ) const
@@ -686,130 +710,55 @@
: QString();
}
-/*!
- Sends a request to the D-Bus server daemon to request the service name \p name. The flags \p
- mode indicate how to proceed if the name is already taken or when another D-Bus client requests
- the same name.
-
- Service names are used to publish well-known services on the D-Bus bus, by associating a
- friendly name to this connection. Other D-Bus clients will then be able to contact this
- connection and the objects registered on it by using this name instead of the unique connection
- name (see baseService()). This also allows one application to always have the same name, while
- its unique connection name changes.
-
- This function has no meaning in peer-to-peer connections.
-
- This function returns true if the name is assigned to this connection now (including the case
- when it was already assigned).
-
- \todo probably move to the QObject representing the bus
- \todo update the NameRequestMode flags
-*/
-bool QDBusConnection::requestName(const QString &name, NameRequestMode mode)
-{
- static const int DBusModes[] = { DBUS_NAME_FLAG_ALLOW_REPLACEMENT, 0,
- DBUS_NAME_FLAG_REPLACE_EXISTING | DBUS_NAME_FLAG_ALLOW_REPLACEMENT};
-
- 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;
-}
-
-/*!
- Releases a name that had been requested using requestName(). This function returns true if the
- name has been released, false otherwise.
-
- This function has no meaning in peer-to-peer connections.
-
- You cannot cause a name owned by another application to be released using releaseName(). Use
- requestName() instead to assign it to your application.
-
- \todo probably move to the QObject representing the bus
-*/
-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;
-}
-
-/*!
- Returns the unique connection name of the client that currently has the \p name
- requested. Returns an empty QString in case there is no such name on the bus or if \p name is
- not a well-formed bus name.
+Q_GLOBAL_STATIC(QMutex, defaultBussesMutex);
+static const char sessionBusName[] = "qt_default_session_bus";
+static const char systemBusName[] = "qt_default_system_bus";
+static QDBusConnection *sessionBus = 0;
+static QDBusConnection *systemBus = 0;
- \todo probably move to the QObject representing the bus
-*/
-QString QDBusConnection::getNameOwner(const QString& name)
+static void closeConnections()
{
- if (QDBusUtil::isValidUniqueConnectionName(name))
- return name;
- if (!d || !QDBusUtil::isValidBusName(name))
- return QString();
-
- QDBusMessage msg = QDBusMessage::methodCall(QLatin1String(DBUS_SERVICE_DBUS),
- QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS),
- QLatin1String("GetNameOwner"));
- msg << name;
- QDBusMessage reply = sendWithReply(msg);
- if (!lastError().isValid() && reply.type() == QDBusMessage::ReplyMessage)
- return reply.first().toString();
- return QString();
+ QMutexLocker locker(defaultBussesMutex());
+ delete sessionBus;
+ delete systemBus;
+ QDBusConnection::closeConnection(QLatin1String(sessionBusName));
+ QDBusConnection::closeConnection(QLatin1String(systemBusName));
+ sessionBus = systemBus = 0;
}
-/*!
- \internal
-*/
-template<int type>
-struct DefaultBus
+static QDBusConnection *openConnection(QDBusConnection::BusType type)
{
- DefaultBus()
- {
- QDBusConnection con = QDBusConnection::addConnection(QDBusConnection::BusType(type),
- QLatin1String(busName));
- bus = new QDBusConnection(con);
- qAddPostRoutine(clear);
- }
-
- ~DefaultBus()
- {
- delete bus;
- }
-
- static void clear()
- {
- delete bus;
- bus = 0;
- QDBusConnection::closeConnection(QLatin1String(busName));
+ QMutexLocker locker(defaultBussesMutex());
+ qAddPostRoutine(closeConnections);
+
+ if (type == QDBusConnection::SystemBus) {
+ if (systemBus)
+ // maybe it got created before we locked the mutex
+ return systemBus;
+ systemBus = new QDBusConnection(QDBusConnection::addConnection(QDBusConnection::SystemBus,
+ QLatin1String(systemBusName)));
+ return systemBus;
+ } else {
+ if (sessionBus)
+ // maybe it got created before we locked the mutex
+ return sessionBus;
+ sessionBus = new QDBusConnection(QDBusConnection::addConnection(QDBusConnection::SessionBus,
+ QLatin1String(sessionBusName)));
+ return sessionBus;
}
-
- static QDBusConnection *bus;
- static const char busName[];
-};
-
-Q_GLOBAL_STATIC(DefaultBus<QDBusConnection::SessionBus>, sessionBusPtr);
-Q_GLOBAL_STATIC(DefaultBus<QDBusConnection::SystemBus>, systemBusPtr);
-
-template<>
-QT_STATIC_CONST_IMPL char DefaultBus<QDBusConnection::SessionBus>::busName[] = "qt_default_session_bus";
-template<>
-QT_STATIC_CONST_IMPL char DefaultBus<QDBusConnection::SystemBus>::busName[] = "qt_default_system_bus";
-
-template<> QDBusConnection *DefaultBus<QDBusConnection::SessionBus>::bus = 0;
-template<> QDBusConnection *DefaultBus<QDBusConnection::SystemBus>::bus = 0;
+}
namespace QDBus {
QDBusConnection &sessionBus()
{
- return *sessionBusPtr()->bus;
+ if (::sessionBus) return *::sessionBus;
+ return *openConnection(QDBusConnection::SessionBus);
}
QDBusConnection &systemBus()
{
- return *systemBusPtr()->bus;
+ if (::systemBus) return *::systemBus;
+ return *openConnection(QDBusConnection::SystemBus);
}
}
Index: qdbusconnection.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusconnection.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- qdbusconnection.h 6 Mar 2006 14:29:39 -0000 1.5
+++ qdbusconnection.h 28 Mar 2006 18:56:08 -0000 1.6
@@ -28,20 +28,19 @@
#include "qdbusmacros.h"
#include <QtCore/qstring.h>
-class QDBusConnectionPrivate;
-class QDBusXmlParser;
-class QDBusObject;
+class QDBusAbstractInterfacePrivate;
class QDBusInterface;
class QDBusError;
class QDBusMessage;
-class QByteArray;
+class QDBusBusService;
class QObject;
+class QDBusConnectionPrivate;
class QDBUS_EXPORT QDBusConnection
{
public:
enum BusType { SessionBus, SystemBus, ActivationBus };
- enum NameRequestMode { NoReplace = 0, ProhibitReplace = 1, ReplaceExisting = 2 };
+ enum WaitMode { UseEventLoop, NoUseEventLoop };
enum RegisterOption {
ExportAdaptors = 0x01,
@@ -50,10 +49,10 @@
ExportProperties = 0x40,
ExportContents = 0xf0,
- ExportNonScriptableSlots = 0x110,
- ExportNonScriptableSignals = 0x220,
- ExportNonScriptableProperties = 0x440,
- ExportNonScriptableContents = 0xff0,
+ ExportAllSlots = 0x110,
+ ExportAllSignals = 0x220,
+ ExportAllProperties = 0x440,
+ ExportAllContents = 0xff0,
ExportChildObjects = 0x1000
};
@@ -75,7 +74,7 @@
QDBusError lastError() const;
bool send(const QDBusMessage &message) const;
- QDBusMessage sendWithReply(const QDBusMessage &message) const;
+ QDBusMessage sendWithReply(const QDBusMessage &message, WaitMode mode = UseEventLoop) const;
int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
const char *slot) const;
@@ -87,42 +86,38 @@
bool registerObject(const QString &path, QObject *object,
RegisterOptions options = ExportAdaptors);
- void unregisterObject(const QString &path, UnregisterMode = UnregisterNode);
-
- QDBusObject findObject(const QString& service, const QString& path);
- QDBusInterface findInterface(const QString& service, const QString& path, const QString& interface);
+ void unregisterObject(const QString &path, UnregisterMode mode = UnregisterNode);
-#ifndef QT_NO_MEMBER_TEMPLATES
template<class Interface>
- inline Interface findInterface(const QString &service, const QString &path)
- { return Interface(findObject(service, path)); }
-#endif
+ inline Interface *findInterface(const QString &service, const QString &path);
+ QDBusInterface *findInterface(const QString& service, const QString& path,
+ const QString& interface = QString());
- bool requestName(const QString &name, NameRequestMode mode = NoReplace);
- bool releaseName(const QString& name);
- QString getNameOwner(const QString& name);
+ QDBusBusService *busService() const;
- static QDBusConnection addConnection(BusType type,
- const QString &name);
- static QDBusConnection addConnection(const QString &address,
- const QString &name);
+ static QDBusConnection addConnection(BusType type, const QString &name);
+ static QDBusConnection addConnection(const QString &address, const QString &name);
static void closeConnection(const QString &name);
private:
- friend class QDBusObject;
+ QDBusAbstractInterfacePrivate *findInterface_helper(const QString &, const QString &,
+ const QString&);
QDBusConnectionPrivate *d;
};
-namespace QDBus {
- QDBusConnection &sessionBus();
- QDBusConnection &systemBus();
-}
-
template<class Interface>
-inline Interface qDBusConnectionFindInterface(QDBusConnection &connection, const QString &service,
- const QString &path)
+inline Interface *QDBusConnection::findInterface(const QString &service, const QString &path)
{
- return Interface(connection.findObject(service, path));
+ register QDBusAbstractInterfacePrivate *d;
+ d = findInterface_helper(service, path, Interface::staticInterfaceName());
+ if (d)
+ return new Interface(d);
+ return 0;
+}
+
+namespace QDBus {
+ QDBUS_EXPORT QDBusConnection &sessionBus();
+ QDBUS_EXPORT QDBusConnection &systemBus();
}
Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::RegisterOptions)
Index: qdbusconnection_p.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusconnection_p.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- qdbusconnection_p.h 6 Mar 2006 14:29:39 -0000 1.6
+++ qdbusconnection_p.h 28 Mar 2006 18:56:08 -0000 1.7
@@ -52,13 +52,17 @@
#include <dbus/dbus.h>
#include "qdbusmessage.h"
-#include "qdbusintrospection.h"
class QDBusMessage;
class QSocketNotifier;
class QTimerEvent;
class QDBusObjectPrivate;
class CallDeliveryEvent;
+class QMetaMethod;
+class QDBusInterfacePrivate;
+class QDBusMetaObject;
+class QDBusAbstractInterface;
+class QDBusBusService;
typedef struct DBusConnection;
typedef struct DBusServer;
@@ -119,8 +123,7 @@
typedef QMultiHash<int, Watcher> WatcherHash;
typedef QHash<int, DBusTimeout *> TimeoutHash;
typedef QMultiHash<QString, SignalHook> SignalHookHash;
- typedef QHash<QString, QSharedDataPointer<QDBusIntrospection::Interface> > KnownInterfacesHash;
- typedef QHash<QString, QDBusIntrospection::Object* > KnownObjectsHash;
+ typedef QHash<QString, QDBusMetaObject* > MetaObjectHash;
public:
// public methods
@@ -134,23 +137,24 @@
void closeConnection();
void timerEvent(QTimerEvent *e);
+ QString getNameOwner(const QString &service);
+
bool send(const QDBusMessage &message) const;
+ QDBusMessage sendWithReply(const QDBusMessage &message, int mode);
int sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
- const char *method) const;
+ const char *method);
void connectSignal(const QString &key, const SignalHook &hook);
void registerObject(const ObjectTreeNode *node);
+ void connectRelay(const QString &service, const QString &path, const QString &interface,
+ QDBusAbstractInterface *receiver, const char *signal);
+ void disconnectRelay(const QString &service, const QString &path, const QString &interface,
+ QDBusAbstractInterface *receiver, const char *signal);
bool handleSignal(const QString &path, const QDBusMessage &msg);
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 activateSignal(const SignalHook& hook, const QDBusMessage &msg);
bool activateCall(QObject* object, int flags, const QDBusMessage &msg);
bool activateObject(const ObjectTreeNode *node, const QDBusMessage &msg);
@@ -160,9 +164,16 @@
CallDeliveryEvent *postedCallDeliveryEvent();
void deliverCall(const CallDeliveryEvent &data) const;
+ QDBusInterfacePrivate *findInterface(const QString &service, const QString &path,
+ const QString &interface);
+
protected:
virtual void customEvent(QEvent *event);
+private:
+ QDBusMetaObject *findMetaObject(const QString &service, const QString &path,
+ QString &interface);
+
public slots:
// public slots
void socketRead(int);
@@ -182,6 +193,7 @@
ConnectionMode mode;
DBusConnection *connection;
DBusServer *server;
+ QDBusBusService *busService;
WatcherHash watchers;
TimeoutHash timeouts;
@@ -189,20 +201,18 @@
QList<DBusTimeout *> pendingTimeouts;
ObjectTreeNode rootNode;
+ MetaObjectHash cachedMetaObjects;
QMutex callDeliveryMutex;
CallDeliveryEvent *callDeliveryState; // protected by the callDeliveryMutex mutex
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);
+ static DBusHandlerResult messageFilter(DBusConnection *, DBusMessage *, void *);
+ static void messageResultReceived(DBusPendingCall *, void *);
};
class QDBusReplyWaiter: public QEventLoop
@@ -215,7 +225,7 @@
void reply(const QDBusMessage &msg);
};
-extern int qDBusParametersForMethod(const QByteArray &sig, QList<int>& metaTypes);
+extern int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes);
extern int qDBusNameToTypeId(const char *name);
extern bool qDBusCheckAsyncTag(const char *tag);
Index: qdbuserror.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbuserror.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- qdbuserror.cpp 6 Mar 2006 14:29:39 -0000 1.3
+++ qdbuserror.cpp 28 Mar 2006 18:56:08 -0000 1.4
@@ -25,10 +25,73 @@
#include "qdbuserror.h"
#include <qdebug.h>
+#include <qvarlengtharray.h>
#include <dbus/dbus.h>
#include "qdbusmessage.h"
+struct ErrorMessageMapping
+{
+ ErrorMessageMapping();
+ QVarLengthArray<const char*, QDBusError::qKnownErrorsMax> messages;
+
+ inline const char *get(QDBusError::KnownErrors code) const
+ {
+ if (code <= QDBusError::Other || code > QDBusError::qKnownErrorsMax)
+ return messages[int(QDBusError::Other) - 1];
+ return messages[int(code) - 1];
+ }
+
+ inline QDBusError::KnownErrors get(const char *name) const
+ {
+ if (!name || !*name)
+ return QDBusError::NoError;
+ for (int i = QDBusError::Other; i <= QDBusError::qKnownErrorsMax; ++i)
+ if (strcmp(name, messages[i - 1]) == 0)
+ return QDBusError::KnownErrors(i);
+ return QDBusError::Other;
+ }
+};
+
+static const char errorMessages_string[] =
+ // in the same order as KnownErrors!
+ "other\0" // Other -- shouldn't happen
+ DBUS_ERROR_FAILED "\0" // Failed
+ DBUS_ERROR_NO_MEMORY "\0" // NoMemory
+ DBUS_ERROR_SERVICE_UNKNOWN "\0" // ServiceUnknown
+ DBUS_ERROR_NO_REPLY "\0" // NoReply
+ DBUS_ERROR_BAD_ADDRESS "\0" // BadAddress
+ DBUS_ERROR_NOT_SUPPORTED "\0" // NotSupported
+ DBUS_ERROR_LIMITS_EXCEEDED "\0" // LimitsExceeded
+ DBUS_ERROR_ACCESS_DENIED "\0" // AccessDenied
+ DBUS_ERROR_NO_SERVER "\0" // NoServer
+ DBUS_ERROR_TIMEOUT "\0" // Timeout
+ DBUS_ERROR_NO_NETWORK "\0" // NoNetwork
+ DBUS_ERROR_ADDRESS_IN_USE "\0" // AddressInUse
+ DBUS_ERROR_DISCONNECTED "\0" // Disconnected
+ DBUS_ERROR_INVALID_ARGS "\0" // InvalidArgs
+ DBUS_ERROR_UNKNOWN_METHOD "\0" // UnknownMethod
+ DBUS_ERROR_TIMED_OUT "\0" // TimedOut
+ DBUS_ERROR_INVALID_SIGNATURE "\0" // InvalidSignature
+ "com.trolltech.QtDBus.Error.UnknownInterface\0" // UnknownInterface
+ "com.trolltech.QtDBus.Error.InternalError\0" // InternalError
+ "\0";
+
+ErrorMessageMapping::ErrorMessageMapping()
+ : messages(int(QDBusError::qKnownErrorsMax))
+{
+ // create the list:
+ const char *p = errorMessages_string;
+ int i = 0;
+ while (*p) {
+ messages[i] = p;
+ p += strlen(p) + 1;
+ ++i;
+ }
+}
+
+Q_GLOBAL_STATIC(ErrorMessageMapping, errorMessages)
+
/*!
\class QDBusError
\brief Represents an error received from the D-Bus bus or from remote applications found in the bus.
@@ -46,7 +109,54 @@
remote applications. You should not create such objects yourself to signal error conditions when
called from D-Bus: instead, use QDBusMessage::error and QDBusConnection::send.
- \sa QDBusConnection::send, QDBusMessage, QDBusReply
+ \sa QDBusConnection::send(), QDBusMessage, QDBusReply
+*/
+
+/*!
+ \enum QDBusError::KnownErrors
+
+ In order to facilitate verification of the most common D-Bus errors generated by the D-Bus
+ implementation and by the bus daemon itself, QDBusError can be compared to a set of pre-defined
+ values:
+
+ \value NoError QDBusError is invalid (i.e., the call succeeded)
+ \value Other QDBusError contains an error that is one of the well-known ones
+ \value Failed The call failed (\c org.freedesktop.DBus.Error.Failed)
+ \value NoMemory Out of memory (\c org.freedesktop.DBus.Error.NoMemory)
+ \value ServiceUnknown The called service is not known
+ (\c org.freedesktop.DBus.Error.ServiceUnknown)
+ \value NoReply The called method did not reply within the specified timeout
+ (\c org.freedesktop.DBus.Error.NoReply)
+ \value BadAddress The address given is not valid
+ (\c org.freedesktop.DBus.Error.BadAddress)
+ \value NotSupported The call/operation is not supported
+ (\c org.freedesktop.DBus.Error.NotSupported)
+ \value LimitsExceeded The limits allocated to this process/call/connection exceeded the
+ pre-defined values (\c org.freedesktop.DBus.Error.LimitsExceeded)
+ \value AccessDenied The call/operation tried to access a resource it isn't allowed to
+ (\c org.freedesktop.DBus.Error.AccessDenied)
+ \value NoServer \i{Documentation doesn't say what this is for}
+ (\c org.freedesktop.DBus.Error.NoServer)
+ \value Timeout \i{Documentation doesn't say what this is for or how it's used}
+ (\c org.freedesktop.DBus.Error.Timeout)
+ \value NoNetwork \i{Documentation doesn't say what this is for}
+ (\c org.freedesktop.DBus.Error.NoNetwork)
+ \value AddressInUse QDBusServer tried to bind to an address that is already in use
+ (\c org.freedesktop.DBus.Error.AddressInUse)
+ \value Disconnected The call/process/message was sent after QDBusConnection disconnected
+ (\c org.freedesktop.DBus.Error.Disconnected)
+ \value InvalidArgs The arguments passed to this call/operation are not valid
+ (\c org.freedesktop.DBus.Error.InvalidArgs)
+ \value UnknownMethod The method called was not found in this object/interface with the
+ given parameters (\c org.freedesktop.DBus.Error.UnknownMethod)
+ \value TimedOut \i{Documentation doesn't say...}
+ (\c org.freedesktop.DBus.Error.TimedOut)
+ \value InvalidSignature The type signature is not valid or compatible
+ (\c org.freedesktop.DBus.Error.InvalidSignature)
+ \value UnknownInterface The interface is not known
+ \value InternalError An internal error occurred
+ (\c com.trolltech.QtDBus.Error.InternalError)
+
*/
/*!
@@ -54,10 +164,12 @@
Constructs a QDBusError from a DBusError structure.
*/
QDBusError::QDBusError(const DBusError *error)
+ : code(NoError)
{
if (!error || !dbus_error_is_set(error))
return;
+ code = errorMessages()->get(error->name);
nm = QString::fromUtf8(error->name);
msg = QString::fromUtf8(error->message);
}
@@ -67,6 +179,7 @@
Constructs a QDBusError from a QDBusMessage.
*/
QDBusError::QDBusError(const QDBusMessage &qdmsg)
+ : code(Other)
{
if (qdmsg.type() != QDBusMessage::ErrorMessage)
return;
@@ -74,14 +187,19 @@
nm = qdmsg.name();
if (qdmsg.count())
msg = qdmsg[0].toString();
+ code = errorMessages()->get(nm.toUtf8().constData());
}
/*!
- \fn QDBusError::QDBusError(const QString &name, const QString &message)
\internal
-
- Constructs an error by passing the name and message.
+ Constructs a QDBusError from a well-known error code
*/
+QDBusError::QDBusError(KnownErrors error, const QString &message)
+ : code(error)
+{
+ nm = errorMessages()->get(error);
+ msg = message;
+}
/*!
\fn QDBusError::name() const
@@ -101,6 +219,20 @@
Returns true if this is a valid error condition (i.e., if there was an error), false otherwise.
*/
+/*!
+ \fn QDBusError::operator==(KnownErrors error) const
+ Compares this QDBusError against the well-known error code \a error and returns true if they
+ match.
+*/
+
+/*!
+ \fn operator==(QDBusError::KnownErrors p1, const QDBusError &p2)
+ \relates QDBusError
+
+ Compares the QDBusError \a p2 against the well-known error code \a p1 and returns true if they
+ match.
+*/
+
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, const QDBusError &msg)
{
Index: qdbuserror.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbuserror.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbuserror.h 6 Mar 2006 14:29:39 -0000 1.4
+++ qdbuserror.h 28 Mar 2006 18:56:08 -0000 1.5
@@ -34,20 +34,58 @@
class QDBUS_EXPORT QDBusError
{
public:
+ enum KnownErrors {
+ NoError = 0,
+ Other = 1,
+ Failed,
+ NoMemory,
+ ServiceUnknown,
+ NoReply,
+ BadAddress,
+ NotSupported,
+ LimitsExceeded,
+ AccessDenied,
+ NoServer,
+ Timeout,
+ NoNetwork,
+ AddressInUse,
+ Disconnected,
+ InvalidArgs,
+ UnknownMethod,
+ TimedOut,
+ InvalidSignature,
+ UnknownInterface,
+ InternalError,
+
+#ifndef Q_QDOC
+ // don't use this one!
+ qKnownErrorsMax = InternalError
+#endif
+ };
+
QDBusError(const DBusError *error = 0);
QDBusError(const QDBusMessage& msg);
- inline QDBusError(const QString &name, const QString &message)
- : nm(name), msg(message)
- { }
+ QDBusError(KnownErrors error, const QString &message);
inline QString name() const { return nm; }
inline QString message() const { return msg; }
inline bool isValid() const { return !nm.isNull() && !msg.isNull(); }
+ inline bool operator==(KnownErrors error) const
+ { return code == error; }
+
private:
+ KnownErrors code;
QString nm, msg;
};
+inline bool operator==(QDBusError::KnownErrors p1, const QDBusError &p2)
+{ return p2 == p1; }
+inline bool operator!=(QDBusError::KnownErrors p1, const QDBusError &p2)
+{ return !(p2 == p1); }
+inline bool operator!=(const QDBusError &p1, QDBusError::KnownErrors p2)
+{ return !(p1 == p2); }
+
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug, const QDBusError &);
#endif
Index: qdbusintegrator.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusintegrator.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusintegrator.cpp 6 Mar 2006 14:29:39 -0000 1.4
+++ qdbusintegrator.cpp 28 Mar 2006 18:56:08 -0000 1.5
@@ -28,15 +28,17 @@
#include <qmetaobject.h>
#include <qobject.h>
#include <qsocketnotifier.h>
+#include <qstringlist.h>
#include <qtimer.h>
-#include "qdbusvariant.h"
#include "qdbusconnection_p.h"
#include "qdbusinterface_p.h"
-#include "qdbusobject_p.h"
#include "qdbusmessage.h"
#include "qdbusabstractadaptor.h"
#include "qdbusabstractadaptor_p.h"
+#include "qdbustypehelper_p.h"
+#include "qdbusutil.h"
+#include "qdbustype_p.h"
#ifndef USE_OUTSIDE_DISPATCH
# define USE_OUTSIDE_DISPATCH 0
@@ -44,9 +46,6 @@
int QDBusConnectionPrivate::messageMetaType = 0;
-/*!
- \internal
-*/
struct QDBusPendingCall
{
QPointer<QObject> receiver;
@@ -56,9 +55,6 @@
const QDBusConnectionPrivate *connection;
};
-/*!
- \internal
-*/
class CallDeliveryEvent: public QEvent
{
public:
@@ -75,18 +71,6 @@
int slotIdx;
};
-#if __BYTE_ORDER != __LITTLE_ENDIAN
-/*!
- \internal
-*/
-union integer
-{
- short s;
- unsigned short us;
- unsigned char uc;
-};
-#endif
-
static dbus_bool_t qDBusAddTimeout(DBusTimeout *timeout, void *data)
{
Q_ASSERT(timeout);
@@ -137,7 +121,7 @@
Q_ASSERT(timeout);
Q_ASSERT(data);
- qDebug("ToggleTimeout");
+ //qDebug("ToggleTimeout");
qDBusRemoveTimeout(timeout, data);
qDBusAddTimeout(timeout, data);
@@ -155,7 +139,7 @@
QDBusConnectionPrivate::Watcher watcher;
if (flags & DBUS_WATCH_READABLE) {
- qDebug("addReadWatch %d", fd);
+ //qDebug("addReadWatch %d", fd);
watcher.watch = watch;
if (QCoreApplication::instance()) {
watcher.read = new QSocketNotifier(fd, QSocketNotifier::Read, d);
@@ -164,7 +148,7 @@
}
}
if (flags & DBUS_WATCH_WRITABLE) {
- qDebug("addWriteWatch %d", fd);
+ //qDebug("addWriteWatch %d", fd);
watcher.watch = watch;
if (QCoreApplication::instance()) {
watcher.write = new QSocketNotifier(fd, QSocketNotifier::Write, d);
@@ -182,7 +166,7 @@
Q_ASSERT(watch);
Q_ASSERT(data);
- qDebug("remove watch");
+ //qDebug("remove watch");
QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
int fd = dbus_watch_get_fd(watch);
@@ -213,7 +197,7 @@
bool enabled = dbus_watch_get_enabled(watch);
int flags = dbus_watch_get_flags(watch);
- qDebug("toggle watch %d to %d (write: %d, read: %d)", dbus_watch_get_fd(watch), enabled, flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE);
+ //qDebug("toggle watch %d to %d (write: %d, read: %d)", dbus_watch_get_fd(watch), enabled, flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE);
if (flags & DBUS_WATCH_READABLE && i.value().read)
i.value().read->setEnabled(enabled);
@@ -228,6 +212,7 @@
static void qDBusNewConnection(DBusServer *server, DBusConnection *c, void *data)
{
Q_ASSERT(data); Q_ASSERT(server); Q_ASSERT(c);
+ Q_UNUSED(data); Q_UNUSED(server); Q_UNUSED(c);
qDebug("SERVER: GOT A NEW CONNECTION"); // TODO
}
@@ -256,8 +241,16 @@
# define HANDLED DBUS_HANDLER_RESULT_HANDLED
#endif
-static DBusHandlerResult qDBusSignalFilter(DBusConnection *connection,
- DBusMessage *message, void *data)
+extern "C" {
+static DBusHandlerResult
+qDBusSignalFilter(DBusConnection *connection, DBusMessage *message, void *data)
+{
+ return QDBusConnectionPrivate::messageFilter(connection, message, data);
+}
+}
+
+DBusHandlerResult QDBusConnectionPrivate::messageFilter(DBusConnection *connection,
+ DBusMessage *message, void *data)
{
Q_ASSERT(data);
Q_UNUSED(connection);
@@ -303,7 +296,7 @@
QByteArray p = path.toLatin1();
if (p.isEmpty())
p = "/";
- qDebug() << p;
+ //qDebug() << p;
DBusMessage *msg2 = dbus_message_copy(msg);
dbus_message_set_path(msg2, p);
dbus_connection_send(connection, msg2, 0);
@@ -319,39 +312,21 @@
const char *p = strstr(tag, "async");
if (p != NULL &&
(p == tag || *(p-1) == ' ') &&
- (p[6] == '\0' || p[6] == ' '))
+ (p[5] == '\0' || p[5] == ' '))
return true;
p = strstr(tag, "Q_ASYNC");
if (p != NULL &&
(p == tag || *(p-1) == ' ') &&
- (p[8] == '\0' || p[8] == ' '))
+ (p[7] == '\0' || p[7] == ' '))
return true;
return false;
}
-static QList<QByteArray> splitParameters(const char *p)
-{
- QList<QByteArray> retval;
- ++p;
- const char *e = p;
- while (*e != ')') {
- while (*e != ')' && *e != ',')
- ++e;
-
- // found the end of this parameter
- retval += QByteArray(p, e - p);
-
- if (*e != ')')
- p = ++e;
- }
- return retval;
-}
-
-static bool typesMatch(int metaId, QVariant::Type variantType)
+static bool typesMatch(int metaId, int variantType)
{
- if (metaId == (int)variantType)
+ if (metaId == int(variantType))
return true;
if (variantType == QVariant::Int && metaId == QMetaType::Short)
@@ -361,6 +336,18 @@
metaId == QMetaType::UChar))
return true;
+ if (variantType == QVariant::List) {
+ if (metaId == QDBusTypeHelper<bool>::listId() ||
+ metaId == QDBusTypeHelper<short>::listId() ||
+ metaId == QDBusTypeHelper<ushort>::listId() ||
+ metaId == QDBusTypeHelper<int>::listId() ||
+ metaId == QDBusTypeHelper<uint>::listId() ||
+ metaId == QDBusTypeHelper<qlonglong>::listId() ||
+ metaId == QDBusTypeHelper<qulonglong>::listId() ||
+ metaId == QDBusTypeHelper<double>::listId())
+ return true;
+ }
+
return false; // no match
}
@@ -392,7 +379,15 @@
return id;
default:
- if (id == qMetaTypeId<QDBusVariant>() || id == QDBusConnectionPrivate::messageMetaType)
+ if (id == QDBusConnectionPrivate::messageMetaType ||
+ id == QDBusTypeHelper<QVariant>::id() ||
+ id == QDBusTypeHelper<bool>::listId() ||
+ id == QDBusTypeHelper<short>::listId() ||
+ id == QDBusTypeHelper<ushort>::listId() ||
+ id == QDBusTypeHelper<int>::listId() ||
+ id == QDBusTypeHelper<qlonglong>::listId() ||
+ id == QDBusTypeHelper<qulonglong>::listId() ||
+ id == QDBusTypeHelper<double>::listId())
return id;
return 0; // invalid
@@ -411,16 +406,9 @@
// metaTypes.count() >= retval + 1 in all cases
//
// sig must be the normalised signature for the method
-int qDBusParametersForMethod(const QByteArray &sig, QList<int>& metaTypes)
+int qDBusParametersForMethod(const QMetaMethod &mm, QList<int>& metaTypes)
{
- if (sig.indexOf('<') != -1) {
- qWarning("Could not parse the method '%s'", sig.constData());
- // there's no type with templates that we can handle
- return -1;
- }
-
- int paren = sig.indexOf('(');
- QList<QByteArray> parameterTypes = splitParameters(sig.data() + paren);
+ QList<QByteArray> parameterTypes = mm.parameterTypes();
metaTypes.clear();
metaTypes.append(0); // return type
@@ -428,7 +416,7 @@
bool seenMessage = false;
foreach (QByteArray type, parameterTypes) {
if (type.endsWith('*')) {
- qWarning("Could not parse the method '%s'", sig.constData());
+ qWarning("Could not parse the method '%s'", mm.signature());
// pointer?
return -1;
}
@@ -437,7 +425,7 @@
type.truncate(type.length() - 1);
int id = qDBusNameToTypeId(type);
if (id == 0) {
- qWarning("Could not parse the method '%s'", sig.constData());
+ qWarning("Could not parse the method '%s'", mm.signature());
// invalid type in method parameter list
return -1;
}
@@ -448,14 +436,14 @@
}
if (seenMessage) { // && !type.endsWith('&')
- qWarning("Could not parse the method '%s'", sig.constData());
+ qWarning("Could not parse the method '%s'", mm.signature());
// non-output parameters after message or after output params
return -1; // not allowed
}
int id = qDBusNameToTypeId(type);
if (id == 0) {
- qWarning("Could not parse the method '%s'", sig.constData());
+ qWarning("Could not parse the method '%s'", mm.signature());
// invalid type in method parameter list
return -1;
}
@@ -478,7 +466,7 @@
super != &QDBusAbstractAdaptor::staticMetaObject)
super = super->superClass();
- int attributeMask = (flags & QDBusConnection::ExportNonScriptableSlots) ?
+ int attributeMask = (flags & QDBusConnection::ExportAllSlots) ?
0 : QMetaMethod::Scriptable;
for (int idx = super->methodCount() ; idx <= mo->methodCount(); ++idx) {
@@ -506,7 +494,7 @@
if (isAsync && returnType != QMetaType::Void)
continue;
- int inputCount = qDBusParametersForMethod(sig, metaTypes);
+ int inputCount = qDBusParametersForMethod(mm, metaTypes);
if (inputCount == -1)
continue; // problem parsing
@@ -630,12 +618,13 @@
{
const QMetaObject *mo = object->metaObject();
QDBusTypeList typeList(msg.signature().toUtf8());
+ QByteArray name = msg.name().toUtf8();
// find a slot that matches according to the rules above
- idx = ::findSlot(mo, msg.name().toUtf8(), flags, typeList, metaTypes);
+ idx = ::findSlot(mo, name, flags, typeList, metaTypes);
if (idx == -1) {
// try with no parameters, but with a QDBusMessage
- idx = ::findSlot(mo, msg.name().toUtf8(), flags, QDBusTypeList(), metaTypes);
+ idx = ::findSlot(mo, name, flags, QDBusTypeList(), metaTypes);
if (metaTypes.count() != 2 || metaTypes.at(1) != messageMetaType)
return false;
}
@@ -692,9 +681,7 @@
QVarLengthArray<void *, 10> params;
params.reserve(metaTypes.count());
-#if __BYTE_ORDER != __LITTLE_ENDIAN
- QVarLengthArray<integer, 4> auxParameters;
-#endif
+ QVarLengthArray<QVariant, 4> auxParameters;
// let's create the parameter list
// first one is the return type -- add it below
@@ -707,25 +694,65 @@
if (id == QDBusConnectionPrivate::messageMetaType)
break;
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- params.append(const_cast<void *>( msg.at(i - 1).constData() ));
-#else
- if (id == int(msg.at(i).type()))
+ if (id == int(msg.at(i - 1).userType()))
+ // no conversion needed
params.append(const_cast<void *>( msg.at(i - 1).constData() ));
else {
- // need some help
- integer aux;
- const QVariant &var = msg.at(i - 1);
- if (id == QMetaType::Short)
- aux.s = var.toInt();
- else if (id == QMetaType::UShort)
- aux.us = var.toUInt();
- else
- aux.uc = var.toUInt();
- auxParameters.append(aux);
- params.append( &auxParameters[auxParameters.count()] );
+ // convert to what the function expects
+ auxParameters.append(QVariant());
+
+ const QVariant &in = msg.at(i - 1);
+ QVariant &out = auxParameters[auxParameters.count() - 1];
+
+ bool error = false;
+ if (id == QVariant::List) {
+ int mid = in.userType();
+ // the only conversion possible here is from a specialised QList<T> to QVariantList
+ if (mid == QDBusTypeHelper<bool>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<bool>::toVariantList(in));
+ else if (mid == QDBusTypeHelper<short>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<short>::toVariantList(in));
+ else if (mid == QDBusTypeHelper<ushort>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<ushort>::toVariantList(in));
+ else if (mid == QDBusTypeHelper<int>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<int>::toVariantList(in));
+ else if (mid == QDBusTypeHelper<uint>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<uint>::toVariantList(in));
+ else if (mid == QDBusTypeHelper<qlonglong>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<qlonglong>::toVariantList(in));
+ else if (mid == QDBusTypeHelper<qulonglong>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<qulonglong>::toVariantList(in));
+ else if (mid == QDBusTypeHelper<double>::listId())
+ out = qVariantFromValue(QDBusTypeHelper<double>::toVariantList(in));
+ else
+ error = true;
+ } else if (in.type() == QVariant::UInt) {
+ if (id == QMetaType::UChar) {
+ uchar uc = in.toUInt();
+ out = qVariantFromValue(uc);
+ } else if (id == QMetaType::UShort) {
+ ushort us = in.toUInt();
+ out = qVariantFromValue(us);
+ } else {
+ error = true;
+ }
+ } else if (in.type() == QVariant::Int) {
+ if (id == QMetaType::Short) {
+ short s = in.toInt();
+ out = qVariantFromValue(s);
+ } else {
+ error = true;
+ }
+ } else {
+ error = true;
+ }
+
+ if (error)
+ qFatal("Internal error: got invalid meta type %d when trying to convert to meta type %d",
+ in.userType(), id);
+
+ params.append( const_cast<void *>(out.constData()) );
}
-#endif
}
bool takesMessage = false;
@@ -740,13 +767,13 @@
void *null = 0;
if (metaTypes[0] != QMetaType::Void) {
QVariant arg(metaTypes[0], null);
- params.append( arg.data() );
outputArgs.append( arg );
+ params[0] = const_cast<void*>(outputArgs.at( outputArgs.count() - 1 ).constData());
}
for ( ; i < metaTypes.count(); ++i) {
QVariant arg(metaTypes[i], null);
- params.append( arg.data() );
outputArgs.append( arg );
+ params.append( const_cast<void*>(outputArgs.at( outputArgs.count() - 1 ).constData()) );
}
// make call:
@@ -770,10 +797,9 @@
}
else {
// generate internal error
- QDBusMessage reply = QDBusMessage::error(msg,
- QLatin1String("com.trolltech.QtDBus.InternalError"),
- QLatin1String("Failed to deliver message"));
- qDebug("Internal error: Failed to deliver message");
+ QDBusMessage reply = QDBusMessage::error(msg, QDBusError(QDBusError::InternalError,
+ QLatin1String("Failed to deliver message")));
+ qWarning("Internal error: Failed to deliver message");
send(reply);
}
}
@@ -793,14 +819,16 @@
}
QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *parent)
- : QObject(parent), ref(1), mode(InvalidMode), connection(0), server(0)
+ : QObject(parent), ref(1), mode(InvalidMode), connection(0), server(0), busService(0)
{
extern bool qDBusInitThreads();
static const int msgType = registerMessageMetaType();
static const bool threads = qDBusInitThreads();
+ static const bool metatypes = QDBusMetaTypeId::innerInitialize();
Q_UNUSED(msgType);
Q_UNUSED(threads);
+ Q_UNUSED(metatypes);
dbus_error_init(&error);
@@ -809,23 +837,12 @@
QDBusConnectionPrivate::~QDBusConnectionPrivate()
{
- Q_ASSERT(knownObjects.isEmpty());
-
if (dbus_error_is_set(&error))
dbus_error_free(&error);
closeConnection();
-
- KnownInterfacesHash::iterator it = knownInterfaces.begin();
- while (it != knownInterfaces.end()) {
- const QSharedDataPointer<QDBusIntrospection::Interface>& item = *it;
-
- const_cast<QDBusIntrospection::Interface*>(item.constData())->ref.deref();
-
- it = knownInterfaces.erase(it);
- }
-
rootNode.clear(); // free resources
+ qDeleteAll(cachedMetaObjects);
}
void QDBusConnectionPrivate::closeConnection()
@@ -933,8 +950,8 @@
return;
}
- qDebug() << "Emitting signal" << message;
- qDebug() << "for paths:";
+ //qDebug() << "Emitting signal" << message;
+ //qDebug() << "for paths:";
dbus_message_set_no_reply(msg, true); // the reply would not be delivered to anything
huntAndEmit(connection, msg, obj, &rootNode);
dbus_message_unref(msg);
@@ -956,7 +973,7 @@
return -1;
}
- int inputCount = qDBusParametersForMethod(normalizedName, params);
+ int inputCount = qDBusParametersForMethod(obj->metaObject()->method(midx), params);
if ( inputCount == -1 || inputCount + 1 != params.count() )
return -1; // failed to parse or invalid arguments or output arguments
@@ -996,7 +1013,7 @@
QDBusAdaptorConnector *connector;
if (node->flags & QDBusConnection::ExportAdaptors &&
(connector = qDBusFindAdaptorConnector(node->obj))) {
- int newflags = node->flags | QDBusConnection::ExportNonScriptableSlots;
+ int newflags = node->flags | QDBusConnection::ExportAllSlots;
if (msg.interface().isEmpty()) {
// place the call in all interfaces
@@ -1023,12 +1040,13 @@
// try the object itself:
if (node->flags & QDBusConnection::ExportSlots && activateCall(node->obj, node->flags, msg))
return true;
-
+#if 0
// nothing matched
qDebug("Call failed: no match for %s%s%s at %s",
qPrintable(msg.interface()), msg.interface().isEmpty() ? "" : ".",
qPrintable(msg.name()),
qPrintable(msg.path()));
+#endif
return false;
}
@@ -1101,8 +1119,8 @@
bool result = false;
SignalHookHash::const_iterator it = signalHooks.find(path);
- qDebug("looking for: %s", path.toLocal8Bit().constData());
- qDebug() << signalHooks.keys();
+ //qDebug("looking for: %s", path.toLocal8Bit().constData());
+ //qDebug() << signalHooks.keys();
for ( ; it != signalHooks.constEnd() && it.key() == path; ++ it) {
const SignalHook &hook = it.value();
if ( !hook.name.isEmpty() && hook.name != msg.name() )
@@ -1197,11 +1215,17 @@
dbus_connection_add_filter(connection, qDBusSignalFilter, this, 0);
#endif
- qDebug("base service: %s", service);
+ //qDebug("base service: %s", service);
}
+extern "C"
static void qDBusResultReceived(DBusPendingCall *pending, void *user_data)
{
+ QDBusConnectionPrivate::messageResultReceived(pending, user_data);
+}
+
+void QDBusConnectionPrivate::messageResultReceived(DBusPendingCall *pending, void *user_data)
+{
QDBusPendingCall *call = reinterpret_cast<QDBusPendingCall *>(user_data);
QDBusConnectionPrivate *connection = const_cast<QDBusConnectionPrivate *>(call->connection);
Q_ASSERT(call->pending == pending);
@@ -1216,11 +1240,14 @@
// The slot may have less parameters than the message
// The slot may optionally have one final parameter that is QDBusMessage
// The slot receives read-only copies of the message (i.e., pass by value or by const-ref)
- CallDeliveryEvent *e = prepareReply(call->receiver, call->methodIdx, call->metaTypes,
- QDBusMessage::fromDBusMessage(reply,
- QDBusConnection(connection->name)));
+
+ QDBusMessage msg = QDBusMessage::fromDBusMessage(reply, QDBusConnection(connection->name));
+ qDebug() << "got message: " << msg;
+ CallDeliveryEvent *e = prepareReply(call->receiver, call->methodIdx, call->metaTypes, msg);
if (e)
connection->deliverCall(*e);
+ else
+ qDebug() << "Deliver failed!";
delete e;
}
dbus_pending_call_unref(pending);
@@ -1241,8 +1268,39 @@
return isOk;
}
+QDBusMessage QDBusConnectionPrivate::sendWithReply(const QDBusMessage &message,
+ int mode)
+{
+ if (!QCoreApplication::instance() || mode == QDBusConnection::NoUseEventLoop) {
+ DBusMessage *msg = message.toDBusMessage();
+ if (!msg)
+ return QDBusMessage();
+
+ DBusMessage *reply = dbus_connection_send_with_reply_and_block(connection, msg,
+ -1, &error);
+ handleError();
+ dbus_message_unref(msg);
+
+ if (lastError.isValid())
+ return QDBusMessage::fromError(lastError);
+
+ return QDBusMessage::fromDBusMessage(reply, QDBusConnection(name));
+ } else { // use the event loop
+ QDBusReplyWaiter waiter;
+ if (sendWithReplyAsync(message, &waiter, SLOT(reply(const QDBusMessage&))) > 0) {
+ // enter the event loop and wait for a reply
+ waiter.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents);
+
+ lastError = waiter.replyMsg; // set or clear error
+ return waiter.replyMsg;
+ }
+
+ return QDBusMessage();
+ }
+}
+
int QDBusConnectionPrivate::sendWithReplyAsync(const QDBusMessage &message, QObject *receiver,
- const char *method) const
+ const char *method)
{
DBusMessage *msg = message.toDBusMessage();
if (!msg)
@@ -1286,76 +1344,192 @@
QDBusAdaptorConnector *connector = qDBusCreateAdaptorConnector(node->obj);
// disconnect and reconnect to avoid duplicates
- connector->disconnect(SIGNAL(relaySignal(QObject *,const char*, const char*,QVariantList)),
- this, SLOT(relaySignal(QObject*, const char*, const char*,QVariantList)));
- connect(connector, SIGNAL(relaySignal(QObject *,const char*, const char*,QVariantList)),
- SLOT(relaySignal(QObject*, const char*, const char*,QVariantList)));
+ connector->disconnect(SIGNAL(relaySignal(QObject*,const char*,const char*,QVariantList)),
+ this, SLOT(relaySignal(QObject*,const char*,const char*,QVariantList)));
+ connect(connector, SIGNAL(relaySignal(QObject*,const char*,const char*,QVariantList)),
+ SLOT(relaySignal(QObject*,const char*,const char*,QVariantList)));
}
}
-QSharedDataPointer<QDBusIntrospection::Interface>
-QDBusConnectionPrivate::findInterface(const QString& name)
+void QDBusConnectionPrivate::connectRelay(const QString &service, const QString &path,
+ const QString &interface,
+ QDBusAbstractInterface *receiver,
+ const char *signal)
{
- QWriteLocker locker(&lock);
- QSharedDataPointer<QDBusIntrospection::Interface> data = knownInterfaces.value(name);
- if (!data) {
- data = new QDBusIntrospection::Interface;
- data->name = name;
- data->ref.ref(); // don't delete
+ // this function is called by QDBusAbstractInterface when one of its signals is connected
+ // we set up a relay from D-Bus into it
- knownInterfaces.insert(name, data);
+ // similar to QDBusConnectionPrivate::findSlot! Merge!
+ QByteArray normalizedName = QMetaObject::normalizedSignature(signal + 1);
+ SignalHook hook;
+ hook.midx = receiver->metaObject()->indexOfSignal(normalizedName);
+ Q_ASSERT(hook.midx != -1); // cannot happen
+ if (hook.midx < QDBusAbstractInterface::staticMetaObject.methodCount())
+ return; // don't connect to this signal
+
+ int inputCount = qDBusParametersForMethod(receiver->metaObject()->method(hook.midx), hook.params);
+ if ( inputCount == -1 || inputCount + 1 != hook.params.count() )
+ return; // failed to parse or invalid arguments or output arguments
+
+ // build the D-Bus signal name and signature
+ QString source = service;
+ source += path;
+ normalizedName.truncate(normalizedName.indexOf('('));
+ hook.name = QString::fromUtf8(normalizedName);
+ hook.interface = interface;
+ hook.obj = receiver;
+ for (int i = 1; i <= inputCount; ++i)
+ if (hook.params.at(i) != messageMetaType)
+ hook.signature += QLatin1String( QDBusType::dbusSignature( QVariant::Type(hook.params.at(i)) ) );
+
+ // add it to our list:
+ QWriteLocker locker(&lock);
+ SignalHookHash::ConstIterator it = signalHooks.find(source);
+ SignalHookHash::ConstIterator end = signalHooks.end();
+ for ( ; it != end && it.key() == source; ++it) {
+ const SignalHook &entry = it.value();
+ if (entry.interface == hook.interface &&
+ entry.name == hook.name &&
+ entry.signature == hook.signature &&
+ entry.obj == hook.obj &&
+ entry.midx == hook.midx)
+ return; // already there, no need to re-add
}
- return data;
+
+ connectSignal(source, hook);
}
-QDBusIntrospection::Object*
-QDBusConnectionPrivate::findObject(const QString& service, const QString& path)
+void QDBusConnectionPrivate::disconnectRelay(const QString &service, const QString &path,
+ const QString &interface,
+ QDBusAbstractInterface *receiver,
+ const char *signal)
{
- QWriteLocker locker(&lock);
- QDBusIntrospection::Object* data = knownObjects.value(service + path);
- if (!data) {
- data = new QDBusIntrospection::Object;
- data->service = service;
- data->path = path;
+ // this function is called by QDBusAbstractInterface when one of its signals is disconnected
+ // we remove relay from D-Bus into it
- knownObjects.insert(service + path, data);
+ // similar to QDBusConnectionPrivate::findSlot! Merge!
+ QByteArray normalizedName = QMetaObject::normalizedSignature(signal + 1);
+ SignalHook hook;
+ hook.midx = receiver->metaObject()->indexOfSignal(normalizedName);
+ Q_ASSERT(hook.midx != -1); // cannot happen
+ if (hook.midx < QDBusAbstractInterface::staticMetaObject.methodCount())
+ return; // we won't find it, so don't bother
+
+ int inputCount = qDBusParametersForMethod(receiver->metaObject()->method(hook.midx), hook.params);
+ if ( inputCount == -1 || inputCount + 1 != hook.params.count() )
+ return; // failed to parse or invalid arguments or output arguments
+
+ // build the D-Bus signal name and signature
+ QString source = service;
+ source += path;
+ normalizedName.truncate(normalizedName.indexOf('('));
+ hook.name = QString::fromUtf8(normalizedName);
+ hook.interface = interface;
+ hook.obj = receiver;
+ for (int i = 1; i <= inputCount; ++i)
+ if (hook.params.at(i) != messageMetaType)
+ hook.signature += QLatin1String( QDBusType::dbusSignature( QVariant::Type(hook.params.at(i)) ) );
+
+ // remove it from our list:
+ QWriteLocker locker(&lock);
+ SignalHookHash::Iterator it = signalHooks.find(source);
+ SignalHookHash::Iterator end = signalHooks.end();
+ for ( ; it != end && it.key() == source; ++it) {
+ const SignalHook &entry = it.value();
+ if (entry.interface == hook.interface &&
+ entry.name == hook.name &&
+ entry.signature == hook.signature &&
+ entry.obj == hook.obj &&
+ entry.midx == hook.midx) {
+ // found it
+ signalHooks.erase(it);
+ return;
+ }
}
- return data;
+ qWarning("QDBusConnectionPrivate::disconnectRelay called for a signal that was not found");
}
-void QDBusConnectionPrivate::disposeOfLocked(QDBusIntrospection::Object* p)
+QString QDBusConnectionPrivate::getNameOwner(const QString& name)
{
- if (p && !p->ref.deref()) { // ref--
- // no one else is using it
- // get rid of the reference
- QString objName = p->service + p->path;
+ if (QDBusUtil::isValidUniqueConnectionName(name))
+ return name;
+ if (!connection || !QDBusUtil::isValidBusName(name))
+ return QString();
-#ifndef QT_NO_DEBUG
- // debug code
- Q_ASSERT(p == knownObjects.take(objName));
-#else
- // non-debug
- knownObjects.remove(objName);
-#endif
+ QDBusMessage msg = QDBusMessage::methodCall(QLatin1String(DBUS_SERVICE_DBUS),
+ QLatin1String(DBUS_PATH_DBUS), QLatin1String(DBUS_INTERFACE_DBUS),
+ QLatin1String("GetNameOwner"));
+ msg << name;
+ QDBusMessage reply = sendWithReply(msg, QDBusConnection::NoUseEventLoop);
+ if (!lastError.isValid() && reply.type() == QDBusMessage::ReplyMessage)
+ return reply.first().toString();
+ return QString();
+}
- // remove sub-objects too
- if (!objName.endsWith(QLatin1Char('/')))
- objName.append(QLatin1Char('/'));
- foreach (QString subObjName, p->childObjects)
- disposeOfLocked(knownObjects.value(objName + subObjName));
+QDBusInterfacePrivate *
+QDBusConnectionPrivate::findInterface(const QString &service,
+ const QString &path,
+ const QString &interface)
+{
+
+ if (!connection || !QDBusUtil::isValidObjectPath(path))
+ return 0;
+ if (!interface.isEmpty() && !QDBusUtil::isValidInterfaceName(interface))
+ return 0;
- delete p;
- }
+ // check if it's there first -- FIXME: add binding mode
+ QString owner = getNameOwner(service);
+ if (owner.isEmpty())
+ return 0;
+
+ QString tmp(interface);
+ QDBusMetaObject *mo = findMetaObject(owner, path, tmp);
+ if (mo)
+ return new QDBusInterfacePrivate(QDBusConnection(name), this, owner, path, tmp, mo);
+ return 0; // error has been set
}
-void QDBusConnectionPrivate::disposeOf(QDBusObjectPrivate* p)
+QDBusMetaObject *
+QDBusConnectionPrivate::findMetaObject(const QString &service, const QString &path,
+ QString &interface)
{
- // We're called from QDBusConnectionPrivate's destructor
- // that means the object it represents is going out of scope
+ if (!interface.isEmpty()) {
+ QReadLocker locker(&lock);
+ QDBusMetaObject *mo = cachedMetaObjects.value(interface, 0);
+ if (mo)
+ return mo;
+ }
+
+ // introspect the target object:
+ QDBusMessage msg = QDBusMessage::methodCall(service, path,
+ QLatin1String(DBUS_INTERFACE_INTROSPECTABLE),
+ QLatin1String("Introspect"));
+
+ // we have to spin the event loop because the call could be targetting ourselves
+ QDBusMessage reply = sendWithReply(msg, QDBusConnection::UseEventLoop);
+ // it doesn't exist yet, we have to create it
QWriteLocker locker(&lock);
- disposeOfLocked( const_cast<QDBusIntrospection::Object*>(p->data) );
+ QDBusMetaObject *mo = 0;
+ if (!interface.isEmpty())
+ mo = cachedMetaObjects.value(interface, 0);
+ if (mo)
+ // maybe it got created when we switched from read to write lock
+ return mo;
+
+ QString xml;
+ if (reply.type() == QDBusMessage::ReplyMessage)
+ // fetch the XML description
+ xml = reply.first().toString();
+ else {
+ lastError = reply;
+ if (reply.type() != QDBusMessage::ErrorMessage || lastError != QDBusError::UnknownMethod)
+ return 0; // error
+ }
+
+ // release the lock and return
+ return QDBusMetaObject::createMetaObject(interface, xml, cachedMetaObjects, lastError);
}
void QDBusReplyWaiter::reply(const QDBusMessage &msg)
@@ -1363,4 +1537,5 @@
replyMsg = msg;
QTimer::singleShot(0, this, SLOT(quit()));
}
+
#include "qdbusconnection_p.moc"
Index: qdbusinterface.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinterface.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- qdbusinterface.cpp 6 Mar 2006 14:29:39 -0000 1.3
+++ qdbusinterface.cpp 28 Mar 2006 18:56:08 -0000 1.4
@@ -1,6 +1,5 @@
/* -*- C++ -*-
*
- * Copyright (C) 2005 Thiago Macieira <thiago at kde.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at trolltech.com>
*
@@ -23,485 +22,219 @@
*/
#include "qdbusinterface.h"
-#include "qdbusobject.h"
-#include "qdbusstandardinterfaces.h"
-
-#include "qdbusinterface_p.h"
-
-/*!
- \internal
-*/
-struct EmptyInterfaceInitializer
-{
- QDBusIntrospection::Interface *data;
- EmptyInterfaceInitializer()
- {
- data = new QDBusIntrospection::Interface;
- data->ref = 1;
- data->introspection = QLatin1String("");
- }
- ~EmptyInterfaceInitializer()
- {
- Q_ASSERT(data->ref == 1);
- delete data;
- data = 0;
- }
-};
-
-Q_GLOBAL_STATIC(EmptyInterfaceInitializer, emptyDataInit);
+#include <dbus/dbus.h>
+#include <QtCore/qpointer.h>
-const QDBusIntrospection::Interface*
-QDBusInterfacePrivate::emptyData()
-{
- return emptyDataInit()->data;
-}
+#include "qdbusinterface_p.h"
+#include "qdbusconnection_p.h"
/*!
\class QDBusInterface
- \brief Base class for all D-Bus interfaces in the QtDBus binding, allowing access to remote interfaces.
+ \brief Proxy class for interfaces on remote objects.
QDBusInterface is a generic accessor class that is used to place calls to remote objects,
connect to signals exported by remote objects and get/set the value of remote properties. This
class is useful for dynamic access to remote objects: that is, when you do not have a generated
code that represents the remote interface.
- Generated-code classes also derive from QDBusInterface, all methods described here are also
- valid for generated-code classes. In addition to those described here, generated-code classes
- provide member functions for the remote methods, which allow for compile-time checking of the
- correct parameters and return values, as well as property type-matching and signal
- parameter-matching.
-
Calls are usually placed by using the call() function, which constructs the message, sends it
over the bus, waits for the reply and decodes the reply. Signals are connected to by using the
- connect() family of functions, whose behavior is similar to QObject::connect(). Finally,
- properties are accessed using the property() and setProperty() functions, whose behaviour is
- also similar to QObject::property() and QObject::setProperty().
-
- \sa \ref StandardInterfaces, \ref dbusidl2cpp
-*/
-
-/*!
- \enum QDBusInterface::CallMode
- \todo turn this into flags and add UseEventLoop/NoUseEventLoop
-
- Specifies how a call should be placed. The valid options are:
- \value NoWaitForReply place the call but don't wait for the reply (the reply's contents
- will be discarded)
- \value WaitForReply place the call and wait for the method to finish before returning
- (the reply's contents will be returned)
- \value NoUseEventLoop don't use an event loop to wait for a reply, but instead block on
- network operations while waiting. This option means the
- user-interface may not be updated for the duration of the call.
- \value UseEventLoop use the Qt event loop to wait for a reply. This option means the
- user-interface will update, but it also means other events may
- happen, like signal delivery and other D-Bus method calls.
-
- When using UseEventLoop, applications must be prepared for reentrancy in any function.
-*/
-
-QDBusInterface::QDBusInterface(QDBusInterfacePrivate* p)
- : d(p)
-{
- d->ref.ref();
-}
-
-/*!
- Constructs a QDBusInterface object by associating it with the interface \p name in the remote
- object \p obj.
+ normal QObject::connect() function. Finally, properties are accessed using the
+ QObject::property() and QObject::setProperty() functions.
*/
-QDBusInterface::QDBusInterface(const QDBusObject& obj, const QString& name)
- : d(0)
-{
- *this = obj.connection().findInterface(obj.service(), obj.path(), name);
-}
-/*!
- Constructs a copy QDBusInterface object.
-*/
-QDBusInterface::QDBusInterface(const QDBusInterface &other)
- : d(0)
+QDBusInterface::QDBusInterface(QDBusInterfacePrivate *p)
+ : QDBusAbstractInterface(p)
{
- *this = other;
}
/*!
- Releases this object's resources.
+ Destroy the object interface and frees up any resource used.
*/
QDBusInterface::~QDBusInterface()
{
- if (!d->ref.deref())
- delete d;
-}
-
-/*!
- Constructs a copy QDBusInterface object.
-*/
-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;
+ // resources are freed in QDBusInterfacePrivate::~QDBusInterfacePrivate()
}
/*!
- \fn QDBusInterface::object()
- Returns the object associated with this interface.
-*/
-
-/*!
- \fn QDBusInterface::object() const
- \overload
- Returns the object associated with this interface.
-*/
-
-/*!
- \fn "QDBusInterface::operator QDBusObject"
- \overload
- Returns the object associated with this interface.
-*/
-
-/*!
- \fn "QDBusInterface::operator const QDBusObject"
- \overload
- Returns the object associated with this interface.
-*/
-
-/*!
- Returns the connection this interface is assocated with.
+ \internal
+ Overrides QObject::metaObject to return our own copy.
*/
-QDBusConnection QDBusInterface::connection() const
+const QMetaObject *QDBusInterface::metaObject() const
{
- return d->conn;
+ return d_func()->metaObject;
}
/*!
- Returns the name of the service this interface is associated with.
+ \internal
+ Override QObject::qt_metacast to catch the interface name too.
*/
-QString QDBusInterface::service() const
+void *QDBusInterface::qt_metacast(const char *_clname)
{
- return d->service;
+ if (!_clname) return 0;
+ if (!strcmp(_clname, "QDBusInterface"))
+ return static_cast<void*>(const_cast<QDBusInterface*>(this));
+ if (d_func()->interface == _clname)
+ return static_cast<void*>(const_cast<QDBusInterface*>(this));
+ return QDBusAbstractInterface::qt_metacast(_clname);
}
/*!
- Returns the object path that this interface is associated with.
+ \internal
+ Dispatch the call through the private.
*/
-QString QDBusInterface::path() const
+int QDBusInterface::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
- return d->path;
+ _id = QDBusAbstractInterface::qt_metacall(_c, _id, _a);
+ if (_id < 0)
+ return _id;
+ return d_func()->metacall(_c, _id, _a);
}
-/*!
- Returns the name of this interface.
-*/
-QString QDBusInterface::interface() const
+int QDBusInterfacePrivate::metacall(QMetaObject::Call c, int id, void **argv)
{
- return d->data->name;
-}
+ Q_Q(QDBusInterface);
+
+ if (c == QMetaObject::InvokeMetaMethod) {
+ int offset = metaObject->methodOffset();
+ QMetaMethod mm = metaObject->method(id + offset);
+
+ if (mm.methodType() == QMetaMethod::Signal) {
+ // signal relay from D-Bus world to Qt world
+ QMetaObject::activate(q, metaObject, id, argv);
+
+ } else if (mm.methodType() == QMetaMethod::Slot) {
+ // method call relay from Qt world to D-Bus world
+ // get D-Bus equivalent signature
+ QString methodName = metaObject->dbusNameForMethod(id);
+ const int *inputTypes = metaObject->inputTypesForMethod(id);
+ const int *outputTypes = metaObject->outputTypesForMethod(id);
-/*!
- Returns the XML document fragment that describes the introspection of this interface. This is
- the raw XML form of the structures returned by interfaceData().
- */
-QString QDBusInterface::introspectionData() const
-{
- d->introspect();
- return d->data->introspection;
-}
+ int inputTypesCount = *inputTypes;
+ int outputTypesCount = *outputTypes++;
-/*!
- Returns the interface data for this interface. This is the parsed form of the XML introspection
- data, as returned by introspectionData().
- */
-const QDBusIntrospection::Interface& QDBusInterface::interfaceData() const
-{
- d->introspect();
- return *d->data;
-}
+ // we will assume that the input arguments were passed correctly
+ QVariantList args;
+ for (int i = 1; i <= inputTypesCount; ++i)
+ args << QVariant(inputTypes[i], argv[i]);
-/*!
- Returns the annotations present in this interface, if any.
- This information can also be found in the data returned by interfaceData().
-*/
-const QDBusIntrospection::Annotations& QDBusInterface::annotationData() const
-{
- d->introspect();
- return d->data->annotations;
-}
+ // make the call
+ QPointer<QDBusInterface> qq = q;
+ QDBusMessage reply = q->callWithArgs(methodName, args);
+ args.clear();
-/*!
- Returns a map of all the methods found in this interface.
- This information can also be found in the data returned by interfaceData().
-*/
-const QDBusIntrospection::Methods& QDBusInterface::methodData() const
-{
- d->introspect();
- return d->data->methods;
-}
+ // access to "this" or to "q" below this point must check for "qq"
+ // we may have been deleted!
-/*!
- Returns a map of all the signals found in this interface.
- This information can also be found in the data returned by interfaceData().
-*/
-const QDBusIntrospection::Signals& QDBusInterface::signalData() const
-{
- d->introspect();
- return d->data->signals_;
-}
+ // check if we got the right number of parameters back:
+ bool success = false;
+ if (reply.count() == outputTypesCount) {
+ // copy the values out
+ for (int i = 0; i < outputTypesCount; ++i) {
+ // treat the return value specially, since it may be null:
+ if (i == 0 && argv[0] == 0)
+ continue;
-/*!
- Returns a map of all the properties found in this interface.
- This information can also be found in the data returned by interfaceData().
-*/
-const QDBusIntrospection::Properties& QDBusInterface::propertyData() const
-{
- d->introspect();
- return d->data->properties;
-}
+ // ensure that the types are correct:
+ const QVariant &item = reply.at(i);
+ if (outputTypes[i] != item.userType()) {
+ success = false;
+ break;
+ }
-/*!
- Places a call to the remote method specified by \p method on this interface, using \p a_args as
- arguments.
+ if (i == 0)
+ QDBusMetaObject::assign(argv[0], item);
+ else
+ QDBusMetaObject::assign(argv[inputTypesCount + i], item);
+ }
+ }
- Normally, you should place calls using call().
-*/
-QDBusMessage QDBusInterface::callWithArgs(const QDBusIntrospection::Method& method,
- const QList<QVariant>& a_args,
- CallMode mode)
-{
- QString signature = QLatin1String(""); // empty, not null
- QVariantList args = a_args;
+ // bail out, something weird happened
+ if (!success && !qq.isNull()) {
+ QString errmsg = QLatin1String("Invalid signature `%1' in return from call to %2.%3");
+ lastError = QDBusError(QDBusError::InvalidSignature,
+ errmsg.arg(reply.signature(), interface, methodName));
+ }
- 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;
+ // done
+ return -1;
}
- }
- else
- args.clear();
-
- if (method.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true"))
- mode = NoWaitForReply;
-
- return callWithArgs(method.name, signature, args, mode);
-}
-
-/*!
- \overload
- Places a call to the remote method specified by \p method on this interface, using \p args as
- arguments.
-
- Normally, you should place calls using call().
-*/
-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(QLatin1Char('.'));
- if (pos != -1) {
- m.truncate(pos);
- sig = method.mid(pos + 1);
- }
- return callWithArgs(m, sig, args, mode);
-}
-
-/*!
- \overload
- Places a call to the remote method specified by \p method on this interface, using \p args as
- arguments. The \p signature parameter specifies how the arguments should be marshalled over the
- connection. (It also serves to distinguish between overloading of remote methods by name)
-
- Normally, you should place calls using call().
-*/
-QDBusMessage QDBusInterface::callWithArgs(const QString& method, const QString& signature,
- const QList<QVariant>& args, CallMode mode)
-{
- QDBusMessage msg = QDBusMessage::methodCall(service(), path(), interface(), method);
- msg.setSignature(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
+ } else if (c == QMetaObject::ReadProperty) {
+ // Qt doesn't support non-readable properties
+ // we have to re-check
+ QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset());
+ if (!mp.isReadable())
+ return -1; // don't read
- // ensure that there is at least one element
- if (reply.isEmpty())
- reply << QVariant();
+ // try to read this property
+ QDBusMessage msg = QDBusMessage::methodCall(service, path, DBUS_INTERFACE_PROPERTIES,
+ QLatin1String("Get"));
+ msg << interface << QString::fromUtf8(mp.name());
- return reply;
-}
+ QPointer<QDBusAbstractInterface> qq = q;
+ QDBusMessage reply = connp->sendWithReply(msg, QDBusConnection::UseEventLoop);
-/*!
- Connects the D-Bus signal specified by \p sig to the given slot \p slot in the object \p obj.
+ // access to "this" or to "q" below this point must check for "qq"
+ // we may have been deleted!
- This function is similar to QObject::connect.
-*/
-bool QDBusInterface::connect(const QDBusIntrospection::Signal& sig, QObject* obj, const char *slot)
-{
- QString signature = QLatin1String(""); // empty, not null
+ if (reply.type() == QDBusMessage::ReplyMessage && reply.count() == 1 &&
+ reply.signature() == QLatin1String("v")) {
+ QVariant value = QDBusTypeHelper<QVariant>::fromVariant(reply.at(0));
- 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;
+ // make sure the type is right
+ if (strcmp(mp.typeName(), value.typeName()) == 0) {
+ if (mp.type() == QVariant::LastType)
+ // QVariant is special in this context
+ *reinterpret_cast<QVariant *>(argv[0]) = value;
+ else
+ QDBusMetaObject::assign(argv[0], value);
+ return -1;
+ }
}
- }
-
- return connect(sig.name, signature, obj, slot);
-}
-
-/*!
- \overload
- Connects the D-Bus signal specified by \p signalName to the given slot \p slot in the object \p
- obj.
-
- This function is similar to QObject::connect.
-*/
-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(QLatin1Char('.'));
- if (pos != -1) {
- s.truncate(pos);
- sig = QLatin1String("") + signalName.mid(pos + 1);
- }
- return connect(s, sig, obj, slot);
-}
-/*!
- \overload
- Connects the D-Bus signal specified by \p signalName to the given slot \p slot in the object \p
- obj. The \p signature parameter allows one to connect to the signal only if it is emitted with
- the parameters matching the given type signature.
-
- This function is similar to QObject::connect.
-*/
-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);
-}
-
-/*!
- Retrieves the value of the property \p prop in the remote object. This function returns an error
- if you try to read the value of a write-only property.
-*/
-QDBusReply<QDBusVariant> QDBusInterface::property(const QDBusIntrospection::Property& prop)
-{
- // sanity checking
- if (prop.access == QDBusIntrospection::Property::Write)
- // write-only prop
- return QDBusError(QLatin1String(DBUS_ERROR_ACCESS_DENIED),
- QString::fromLatin1("Property %1 in interface %2 in object %3 is write-only")
- .arg(prop.name, interface(), path()));
-
- QDBusPropertiesInterface pi(object());
- return pi.get(interface(), prop.name);
-}
-
-/*!
- \overload
- Retrieves the value of the property \p propname in the remote object. This function returns an
- error if you try to read the value of a write-only property.
-*/
-QDBusReply<QDBusVariant> QDBusInterface::property(const QString& propName)
-{
- // can't do sanity checking
- QDBusPropertiesInterface pi(object());
- return pi.get(interface(), propName);
-}
+ // got an error
+ if (qq.isNull())
+ return -1; // bail out
-/*!
- Sets the value of the property \p prop to \p newValue in the remote object. This function
- automatically changes the type of \p newValue to the property's type, but the call will fail if
- the types don't match.
+ if (reply.type() == QDBusMessage::ErrorMessage)
+ lastError = reply;
+ else if (reply.signature() != QLatin1String("v")) {
+ QString errmsg = QLatin1String("Invalid signature `%1' in return from call to "
+ DBUS_INTERFACE_PROPERTIES);
+ lastError = QDBusError(QDBusError::InvalidSignature, errmsg.arg(reply.signature()));
+ } else {
+ QString errmsg = QLatin1String("Unexpected type `%1' when retrieving property "
+ "`%2 %3.%4'");
+ lastError = QDBusError(QDBusError::InvalidSignature,
+ errmsg.arg(QLatin1String(reply.at(0).typeName()),
+ QLatin1String(mp.typeName()),
+ interface, QString::fromUtf8(mp.name())));
+ }
+ return -1;
+ } else if (c == QMetaObject::WriteProperty) {
+ // QMetaProperty::write has already checked that we're writable
+ // it has also checked that the type is right
+ QVariant value(metaObject->propertyMetaType(id), argv[0]);
+ QMetaProperty mp = metaObject->property(id + metaObject->propertyOffset());
- This function returns an error if the property is read-only.
-*/
-QDBusReply<void> QDBusInterface::setProperty(const QDBusIntrospection::Property& prop,
- const QDBusVariant &newValue)
-{
- // sanity checking
- if (prop.access == QDBusIntrospection::Property::Read)
- // read-only prop
- return QDBusError(QLatin1String(DBUS_ERROR_ACCESS_DENIED),
- QString::fromLatin1("Property %1 in interface %2 in object %3 is read-only")
- .arg(prop.name, interface(), path()));
+ // send the value
+ QDBusMessage msg = QDBusMessage::methodCall(service, path, DBUS_INTERFACE_PROPERTIES,
+ QLatin1String("Set"));
+ msg.setSignature(QLatin1String("ssv"));
+ msg << interface << QString::fromUtf8(mp.name()) << value;
- // set the property type
- QDBusVariant value = newValue;
- value.type = prop.type;
+ QPointer<QDBusAbstractInterface> qq = q;
+ QDBusMessage reply = connp->sendWithReply(msg, QDBusConnection::UseEventLoop);
- QDBusPropertiesInterface pi(object());
- return pi.set(interface(), prop.name, value);
-}
+ // access to "this" or to "q" below this point must check for "qq"
+ // we may have been deleted!
-/*!
- \overload
- Sets the value of the property \p propName to \p newValue in the remote object. This function
- will not change \p newValue's type to match the property, so it is your responsibility to make
- sure it is of the correct type.
+ if (!qq.isNull() && reply.type() != QDBusMessage::ReplyMessage)
+ lastError = reply;
- This function returns an error if the property is read-only.
-*/
-QDBusReply<void> QDBusInterface::setProperty(const QString& propName, const QDBusVariant &newValue)
-{
- // can't do sanity checking
- QDBusPropertiesInterface pi(object());
- return pi.set(interface(), propName, newValue);
+ return -1;
+ }
+ return id;
}
-/*!
- \fn QDBusMessage QDBusInterface::call(const QDBusIntrospection::Method &method, ...)
-
- Calls the method \p method on this interface and passes the parameters to this function to the
- method.
-
- The parameters to \a call are passed on to the remote function via D-Bus as input
- arguments. Output arguments are returned in the QDBusMessage reply.
-
- \warning This function reenters the Qt event loop in order to wait for the reply, excluding user
- input. During the wait, it may deliver signals and other method calls to your
- application. Therefore, it must be prepared to handle a reentrancy whenever a call is
- placed with call().
-*/
-
-/*!
- \overload
- \fn QDBusMessage QDBusInterface::call(const QString &method, ...)
-
- Calls the method \p method on this interface and passes the parameters to this function to the
- method.
-
- The parameters to \a call are passed on to the remote function via D-Bus as input
- arguments. Output arguments are returned in the QDBusMessage reply.
-
- \warning This function reenters the Qt event loop in order to wait for the reply, excluding user
- input. During the wait, it may deliver signals and other method calls to your
- application. Therefore, it must be prepared to handle a reentrancy whenever a call is
- placed with call().
-*/
Index: qdbusinterface.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinterface.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbusinterface.h 6 Mar 2006 14:29:39 -0000 1.2
+++ qdbusinterface.h 28 Mar 2006 18:56:08 -0000 1.3
@@ -1,6 +1,5 @@
/* -*- C++ -*-
*
- * Copyright (C) 2005 Thiago Macieira <thiago at kde.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at trolltech.com>
*
@@ -25,163 +24,23 @@
#ifndef QDBUSINTERFACE_H
#define QDBUSINTERFACE_H
-#include "qdbusmessage.h"
-#include "qdbusobject.h"
-#include "qdbusintrospection.h"
-#include "qdbusreply.h"
-#include "qdbusvariant.h"
-#include <QtCore/qstring.h>
-#include <QtCore/qvariant.h>
-#include <QtCore/qlist.h>
-
-class QDBusConnection;
+#include "qdbusabstractinterface.h"
class QDBusInterfacePrivate;
-class QDBUS_EXPORT QDBusInterface
+class QDBUS_EXPORT QDBusInterface: public QDBusAbstractInterface
{
friend class QDBusConnection;
-
-public:
- enum CallMode {
- WaitForReply,
- NoWaitForReply
- };
-
-public:
- QDBusInterface(const QDBusObject& obj, const QString& name);
- QDBusInterface(const QDBusInterface&);
- virtual ~QDBusInterface();
-
- QDBusInterface& operator=(const QDBusInterface&);
-
- inline QDBusObject object()
- { return QDBusObject(*this); }
-
- inline const QDBusObject object() const
- { return QDBusObject(*this); }
-
- inline operator QDBusObject()
- { return QDBusObject(*this); }
-
- inline operator const QDBusObject() const
- { return QDBusObject(*this); }
-
+private:
+ QDBusInterface(QDBusInterfacePrivate *p);
- QDBusConnection connection() const;
-
- QString service() const;
- QString path() const;
- QString interface() const;
-
- virtual QString introspectionData() const;
- const QDBusIntrospection::Interface& interfaceData() const;
- const QDBusIntrospection::Annotations& annotationData() const;
- const QDBusIntrospection::Methods& methodData() const;
- const QDBusIntrospection::Signals& signalData() const;
- const QDBusIntrospection::Properties& propertyData() const;
-
- QDBusMessage callWithArgs(const QDBusIntrospection::Method& method,
- const QList<QVariant>& args = QList<QVariant>(),
- CallMode mode = WaitForReply);
- QDBusMessage callWithArgs(const QString& method, const QList<QVariant>& args = QList<QVariant>(),
- CallMode mode = WaitForReply);
- QDBusMessage callWithArgs(const QString& method, const QString& signature,
- const QList<QVariant>& args = QList<QVariant>(),
- CallMode mode = WaitForReply);
-
- bool connect(const QDBusIntrospection::Signal&, QObject* obj, const char *slot);
- bool connect(const QString& signalName, QObject* obj, const char *slot);
- bool connect(const QString& signalName, const QString& signature,
- QObject* obj, const char *slot);
-
- QDBusReply<QDBusVariant> property(const QDBusIntrospection::Property&);
- QDBusReply<QDBusVariant> property(const QString& property);
-
- QDBusReply<void> setProperty(const QDBusIntrospection::Property&, const QDBusVariant& newValue);
- QDBusReply<void> setProperty(const QString& property, const QDBusVariant& newValue);
-
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
- template<typename MethodType>
- inline QDBusMessage call(MethodType m)
- {
- return callWithArgs(m);
- }
-
- template<typename MethodType, typename T1>
- inline QDBusMessage call(MethodType m, T1 t1)
- {
- QList<QVariant> args;
- args << t1;
- return callWithArgs(m, args);
- }
-
- 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);
- }
-
- 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);
- }
-
- 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);
- }
-
- 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);
- }
-
- 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);
- }
-
- 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);
- }
-
- 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);
- }
-#else
- // fool Doxygen
- inline QDBusMessage call(const QDBusIntrospection::Method &method, ...);
- inline QDBusMessage call(const QString &method, ...);
-#endif
+public:
+ ~QDBusInterface();
+ virtual const QMetaObject *metaObject() const;
+ virtual void *qt_metacast(const char *);
+ virtual int qt_metacall(QMetaObject::Call, int, void **);
private:
- QDBusInterface(QDBusInterfacePrivate*);
- QDBusInterfacePrivate *d;
+ Q_DECLARE_PRIVATE(QDBusInterface);
};
#endif
Index: qdbusinterface_p.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinterface_p.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- qdbusinterface_p.h 6 Mar 2006 14:29:39 -0000 1.3
+++ qdbusinterface_p.h 28 Mar 2006 18:56:08 -0000 1.4
@@ -1,6 +1,5 @@
/*
*
- * Copyright (C) 2006 Thiago José Macieira <thiago at kde.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at trolltech.com>
*
@@ -37,36 +36,30 @@
#ifndef QDBUSINTERFACEPRIVATE_H
#define QDBUSINTERFACEPRIVATE_H
-#include "qdbusobject.h"
+#include "qdbusabstractinterface_p.h"
+#include "qdbusmetaobject_p.h"
#include "qdbusinterface.h"
-#include "qdbusconnection.h"
-#include "qdbuserror.h"
-#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
-
-class QDBusInterfacePrivate
+class QDBusInterfacePrivate: public QDBusAbstractInterfacePrivate
{
public:
- QAtomic ref;
- QDBusConnection conn;
- QString service;
- QString path;
- QDBusError lastError;
-
- //QConstSharedDataPointer<QDBusIntrospection::Interface> data;
- const QDBusIntrospection::Interface* data;
-
- inline QDBusInterfacePrivate(const QDBusConnection &other) : conn(other), data(emptyData())
- { }
+ Q_DECLARE_PUBLIC(QDBusInterface)
- inline bool needsIntrospection() const
- { return data && data->introspection.isNull(); }
+ QDBusMetaObject *metaObject;
- inline void introspect()
- { if (needsIntrospection()) conn.findObject(service, path).introspect(); }
+ inline QDBusInterfacePrivate(const QDBusConnection &con, QDBusConnectionPrivate *conp,
+ const QString &serv, const QString &p, const QString &iface,
+ QDBusMetaObject *mo = 0)
+ : QDBusAbstractInterfacePrivate(con, conp, serv, p, iface), metaObject(mo)
+ {
+ }
+ ~QDBusInterfacePrivate()
+ {
+ if (!metaObject->cached)
+ delete metaObject;
+ }
- static const QDBusIntrospection::Interface *emptyData();
+ int metacall(QMetaObject::Call c, int id, void **argv);
};
-
#endif
Index: qdbusinternalfilters.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusinternalfilters.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- qdbusinternalfilters.cpp 6 Mar 2006 14:29:39 -0000 1.1
+++ qdbusinternalfilters.cpp 28 Mar 2006 18:56:08 -0000 1.2
@@ -26,26 +26,38 @@
#include <dbus/dbus.h>
#include <QtCore/qcoreapplication.h>
#include <QtCore/qmetaobject.h>
+#include <QtCore/qstringlist.h>
-#include "qdbusstandardinterfaces.h"
#include "qdbusabstractadaptor.h"
#include "qdbusabstractadaptor_p.h"
#include "qdbusinterface_p.h" // for ANNOTATION_NO_WAIT
#include "qdbusmessage.h"
-#include "qdbustype.h"
-#include "qdbusvariant.h"
+#include "qdbusutil.h"
+
+static const char introspectableInterfaceXml[] =
+ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n"
+ " <method name=\"Introspect\">\n"
+ " <arg name=\"xml_data\" type=\"s\" direction=\"out\"/>\n"
+ " </method>\n"
+ " </interface>\n";
+
+static const char propertiesInterfaceXml[] =
+ " <interface name=\"org.freedesktop.DBus.Properties\">\n"
+ " <method name=\"Get\">\n"
+ " <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+ " <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
+ " <arg name=\"value\" type=\"v\" direction=\"out\"/>\n"
+ " </method>\n"
+ " <method name=\"Set\">\n"
+ " <arg name=\"interface_name\" type=\"s\" direction=\"in\"/>\n"
+ " <arg name=\"property_name\" type=\"s\" direction=\"in\"/>\n"
+ " <arg name=\"value\" type=\"v\" direction=\"in\"/>\n"
+ " </method>\n"
+ " </interface>\n";
// implement the D-Bus org.freedesktop.DBus.Introspectable interface
// we do that by analysing the metaObject of all the adaptor interfaces
-static inline QString dbusMemberName(const char *qtMemberName)
-{
- QString retval = QLatin1String(qtMemberName);
- if (!retval.isEmpty())
- retval[0] = retval[0].toUpper();
- return retval;
-}
-
static QString generateInterfaceXml(const QMetaObject *mo, int flags, int methodOffset, int propOffset)
{
QString retval;
@@ -57,8 +69,8 @@
QMetaProperty mp = mo->property(i);
- if (!mp.isScriptable() && (flags & QDBusConnection::ExportNonScriptableProperties) !=
- QDBusConnection::ExportNonScriptableProperties)
+ if (!mp.isScriptable() && (flags & QDBusConnection::ExportAllProperties) !=
+ QDBusConnection::ExportAllProperties)
continue;
int access = 0;
@@ -72,8 +84,8 @@
continue;
retval += QString(QLatin1String(" <property name=\"%1\" type=\"%2\" access=\"%3\" />\n"))
- .arg(dbusMemberName(mp.name()))
- .arg(QLatin1String(QDBusType::dbusSignature( QVariant::Type(typeId) )))
+ .arg(mp.name())
+ .arg(QLatin1String( QDBusUtil::typeToSignature( QVariant::Type(typeId) )))
.arg(QLatin1String( accessvalues[access] ));
}
}
@@ -99,20 +111,19 @@
QString xml = QString(QLatin1String(" <%1 name=\"%2\">\n"))
.arg(isSignal ? QLatin1String("signal") : QLatin1String("method"))
- .arg(dbusMemberName(signature.left(paren)));
+ .arg(QLatin1String(signature.left(paren)));
// check the return type first
int typeId = qDBusNameToTypeId(mm.typeName());
if (typeId)
xml += QString(QLatin1String(" <arg type=\"%1\" direction=\"out\"/>\n"))
- .arg(QLatin1String(QDBusType::dbusSignature( QVariant::Type(typeId) )));
+ .arg(QLatin1String(QDBusUtil::typeToSignature( QVariant::Type(typeId) )));
else if (*mm.typeName())
continue; // wasn't a valid type
QList<QByteArray> names = mm.parameterNames();
QList<int> types;
- int inputCount = qDBusParametersForMethod(QMetaObject::normalizedSignature(signature),
- types);
+ int inputCount = qDBusParametersForMethod(mm, types);
if (inputCount == -1)
continue; // invalid form
if (isSignal && inputCount + 1 != types.count())
@@ -137,12 +148,12 @@
xml += QString(QLatin1String(" <arg %1type=\"%2\" direction=\"%3\"/>\n"))
.arg(name)
- .arg(QLatin1String(QDBusType::dbusSignature( QVariant::Type(types.at(j)) )))
+ .arg(QLatin1String(QDBusUtil::typeToSignature( QVariant::Type(types.at(j)) )))
.arg(isOutput ? QLatin1String("out") : QLatin1String("in"));
}
if (!isScriptable &&
- !(flags & (QDBusConnection::ExportNonScriptableSlots | QDBusConnection::ExportNonScriptableSignals)))
+ !(flags & (QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals)))
continue;
if (qDBusCheckAsyncTag(mm.tag()))
@@ -194,7 +205,7 @@
else
xml = generateInterfaceXml(mo, flags, base->methodCount(), base->propertyCount());
- return QString(QLatin1String(" <interface name=\"%1\">\n%2 </interface>"))
+ return QString(QLatin1String(" <interface name=\"%1\">\n%2 </interface>\n"))
.arg(interface, xml);
}
@@ -219,9 +230,6 @@
xml_data += QLatin1String("<node>\n");
if (node->obj) {
- xml_data += QLatin1String( QDBusIntrospectableInterface::staticIntrospectionData() );
- xml_data += QLatin1String( QDBusPropertiesInterface::staticIntrospectionData() );
-
if (node->flags & QDBusConnection::ExportContents) {
const QMetaObject *mo = node->obj->metaObject();
for ( ; mo != &QObject::staticMetaObject; mo = mo->superClass())
@@ -244,7 +252,7 @@
// add the interface's contents:
ifaceXml += generateMetaObjectXml(it->interface, it->metaObject,
&QDBusAbstractAdaptor::staticMetaObject,
- QDBusConnection::ExportNonScriptableContents);
+ QDBusConnection::ExportAllContents);
QDBusAbstractAdaptorPrivate::saveIntrospectionXml(it->adaptor, ifaceXml);
}
@@ -252,6 +260,9 @@
xml_data += ifaceXml;
}
}
+
+ xml_data += QLatin1String( introspectableInterfaceXml );
+ xml_data += QLatin1String( propertiesInterfaceXml );
}
if (node->flags & QDBusConnection::ExportChildObjects) {
@@ -308,8 +319,8 @@
int pidx = node->obj->metaObject()->indexOfProperty(property_name);
if (pidx != -1) {
QMetaProperty mp = node->obj->metaObject()->property(pidx);
- if (mp.isScriptable() || (node->flags & QDBusConnection::ExportNonScriptableProperties) ==
- QDBusConnection::ExportNonScriptableProperties)
+ if (mp.isScriptable() || (node->flags & QDBusConnection::ExportAllProperties) ==
+ QDBusConnection::ExportAllProperties)
value = mp.read(node->obj);
}
}
@@ -331,7 +342,7 @@
Q_ASSERT(msg.count() == 3);
QString interface_name = msg.at(0).toString();
QByteArray property_name = msg.at(1).toString().toUtf8();
- QVariant value = msg.at(2).value<QDBusVariant>();
+ QVariant value = QDBusTypeHelper<QVariant>::fromVariant(msg.at(2));
QDBusAdaptorConnector *connector;
if (node->flags & QDBusConnection::ExportAdaptors &&
@@ -353,8 +364,8 @@
int pidx = node->obj->metaObject()->indexOfProperty(property_name);
if (pidx != -1) {
QMetaProperty mp = node->obj->metaObject()->property(pidx);
- if (mp.isScriptable() || (node->flags & QDBusConnection::ExportNonScriptableProperties) ==
- QDBusConnection::ExportNonScriptableProperties) {
+ if (mp.isScriptable() || (node->flags & QDBusConnection::ExportAllProperties) ==
+ QDBusConnection::ExportAllProperties) {
if (mp.write(node->obj, value)) {
msg.connection().send(QDBusMessage::methodReply(msg));
Index: qdbusintrospection.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusintrospection.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbusintrospection.cpp 6 Mar 2006 14:29:39 -0000 1.2
+++ qdbusintrospection.cpp 28 Mar 2006 18:56:08 -0000 1.3
@@ -21,12 +21,13 @@
*
*/
-#include "qdbusintrospection.h"
+#include "qdbusintrospection_p.h"
#include "qdbusxmlparser_p.h"
/*!
\class QDBusIntrospection
\brief Information about introspected objects and interfaces on D-Bus.
+ \internal
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
@@ -36,7 +37,7 @@
*/
/*!
- \struct QDBusIntrospection::Argument
+ \class 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
@@ -54,12 +55,12 @@
*/
/*!
- \fn QDBusIntrospection::Argument::operator==
- Compares this object against \p other and return true if they are the same.
+ \fn QDBusIntrospection::Argument::operator==(const Argument &other) const
+ Compares this object against \a other and return true if they are the same.
*/
/*!
- \struct QDBusIntrospection::Method
+ \class QDBusIntrospection::Method
\brief Information about one method.
This struct represents one method discovered through introspection. A method is composed of
@@ -89,12 +90,12 @@
*/
/*!
- \fn QDBusIntrospection::Method::operator==
- Compares this object against \p other and return true if they are the same.
+ \fn QDBusIntrospection::Method::operator==(const Method &other) const
+ Compares this object against \a other and return true if they are the same.
*/
/*!
- \struct QDBusIntrospection::Signal
+ \class QDBusIntrospection::Signal
\brief Information about one signal.
This struct represents one signal discovered through introspection. A signal is composed of
@@ -118,12 +119,12 @@
*/
/*!
- \fn QDBusIntrospection::Signal::operator==
- Compares this object against \p other and return true if they are the same.
+ \fn QDBusIntrospection::Signal::operator==(const Signal& other) const
+ Compares this object against \a other and return true if they are the same.
*/
/*!
- \struct QDBusIntrospection::Property
+ \class QDBusIntrospection::Property
\brief Information about one property.
This struct represents one property discovered through introspection. A property is composed of
@@ -143,9 +144,9 @@
/*!
\enum QDBusIntrospection::Property::Access
The possible access rights for a property:
- - Read
- - Write
- - ReadWrite
+ \value Read
+ \value Write
+ \value ReadWrite
*/
/*!
@@ -160,12 +161,12 @@
*/
/*!
- \fn QDBusIntrospection::Property::operator==
- Compares this object against \p other and return true if they are the same.
+ \fn QDBusIntrospection::Property::operator==(const Property &other) const
+ Compares this object against \a other and return true if they are the same.
*/
/*!
- \struct QDBusIntrospection::Interface
+ \class 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.
@@ -211,15 +212,15 @@
*/
/*!
- \fn QDBusIntrospection::Interface::operator==
- Compares this object against \p other and return true if they are the same.
+ \fn QDBusIntrospection::Interface::operator==(const Interface &other) const
+ Compares this object against \a other and return true if they are the same.
Note that two interfaces are considered to be the same if they have the same name. The internal
structures in the objects are not compared.
*/
/*!
- \struct QDBusIntrospection::Object
+ \class 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
@@ -234,14 +235,14 @@
\var QDBusIntrospection::Object::service
The object's service name.
- \sa parseObject, parseObjectTree
+ \sa parseObject(), parseObjectTree()
*/
/*!
\var QDBusIntrospection::Object::path
The object's path on the service. This is an absolute path.
- \sa parseObject, parseObjectTree
+ \sa parseObject(), parseObjectTree()
*/
/*!
@@ -260,11 +261,12 @@
/*!
\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.
+ absolute path. To obtain the absolute path, concatenate with \l
+ {QDBusIntrospection::Object::path}{path}.
*/
/*!
- \struct QDBusIntrospection::ObjectTree
+ \class 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
@@ -324,20 +326,17 @@
\typedef QDBusIntrospection::Objects
Contains a QMap of objects and their paths relative to their immediate parent.
- \sa parseObjectTree
+ \sa parseObjectTree()
*/
/*!
- Parses the XML document fragment containing one interface.
+ Parses the XML document fragment (given by \a xml) 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)
@@ -352,23 +351,22 @@
}
/*!
- Parses the XML document fragment containing several interfaces.
+ Parses the XML document fragment (given by \a xml) 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);
+ QString null;
+ QDBusXmlParser parser(null, null, xml);
return parser.interfaces();
}
/*!
- Parses the XML document fragment containing one object.
+ Parses the XML document fragment (given by \a xml) containing one object, found at the service
+ \a service and path \a path.
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
@@ -376,11 +374,6 @@
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)
@@ -393,15 +386,11 @@
}
/*!
- Parses the XML document fragment containing one object node and returns all the information
- about the interfaces and sub-objects.
+ Parses the XML document fragment (given by \a xml) containing one object node and returns all
+ the information about the interfaces and sub-objects, found at the service \a service and path
+ \a path.
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)
--- qdbusintrospection.h DELETED ---
--- NEW FILE: qdbusintrospection_p.h ---
/* -*- C++ -*-
*
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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 "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
{
QString 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;
QString 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.isEmpty() && 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
Index: qdbusmacros.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusmacros.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusmacros.h 6 Mar 2006 14:29:39 -0000 1.4
+++ qdbusmacros.h 28 Mar 2006 18:56:08 -0000 1.5
@@ -30,46 +30,23 @@
#define QDBUSMACROS_H
#include <QtCore/qglobal.h>
+#include <QtCore/qmetatype.h>
+#include <QtCore/qvariant.h>
-#ifdef DBUS_COMPILATION
-/// \internal
+#ifdef QT_NO_MEMBER_TEMPLATES
+# error Sorry, you need a compiler with support for template member functions to compile QtDBus.
+#endif
+
+#if defined(DBUS_COMPILATION) && defined(QDBUS_MAKEDLL)
# define QDBUS_EXPORT Q_DECL_EXPORT
#else
-/// \internal
# define QDBUS_EXPORT Q_DECL_IMPORT
#endif
#ifndef Q_MOC_RUN
-/*!
- \relates QDBusAbstractAdaptor
- \brief Marks a method as "asynchronous"
-
- The Q_ASYNC macro can be used to mark a method to be called and not wait for it to finish
- processing before returning from QDBusInterface::call. The called method cannot return any
- output arguments and, if it does, any such arguments will be discarded.
-
- You can use this macro in your own adaptors by placing it before your method's return value
- (which must be "void") in the class declaration, as shown in the example:
- \code
- Q_ASYNC void myMethod();
- \endcode
-
- Its presence in the method implementation (outside the class declaration) is optional.
-
- \sa #async, \ref UsingAdaptors
-*/
# define Q_ASYNC
#endif
#ifndef QT_NO_KEYWORDS
-
-/*!
- \relates QDBusAbstractAdaptor
- \brief Marks a method as "asynchronous"
-
- This macro is the same as #Q_ASYNC and is provided as a shorthand. However, it is not defined if
- QT_NO_KEYWORDS is defined, which makes Qt not use its extensions to the C++ language (keywords
- emit, signals, slots).
-*/
# define async Q_ASYNC
#endif
Index: qdbusmarshall.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusmarshall.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusmarshall.cpp 6 Mar 2006 14:29:39 -0000 1.4
+++ qdbusmarshall.cpp 28 Mar 2006 18:56:08 -0000 1.5
@@ -23,8 +23,8 @@
*/
#include "qdbusmarshall_p.h"
-#include "qdbustype.h"
-#include "qdbusvariant.h"
+#include "qdbustype_p.h"
+#include "qdbustypehelper_p.h"
#include <qdebug.h>
#include <qvariant.h>
@@ -36,6 +36,8 @@
#include <dbus/dbus.h>
+static QVariant qFetchParameter(DBusMessageIter *it);
+
template <typename T>
inline T qIterGet(DBusMessageIter *it)
{
@@ -44,6 +46,32 @@
return t;
}
+template<>
+inline QVariant qIterGet(DBusMessageIter *it)
+{
+ DBusMessageIter sub;
+ dbus_message_iter_recurse(it, &sub);
+ return QDBusTypeHelper<QVariant>::toVariant(qFetchParameter(&sub));
+}
+
+template <typename DBusType, typename QtType>
+inline QVariant qFetchList(DBusMessageIter *arrayIt)
+{
+ QList<QtType> list;
+
+ DBusMessageIter it;
+ dbus_message_iter_recurse(arrayIt, &it);
+
+ if (!dbus_message_iter_has_next(&it))
+ return QDBusTypeHelper<QList<QtType> >::toVariant(list);
+
+ do {
+ list.append( static_cast<QtType>( qIterGet<DBusType>(&it) ) );
+ } while (dbus_message_iter_next(&it));
+
+ return QDBusTypeHelper<QList<QtType> >::toVariant(list);
+}
+
static QStringList qFetchStringList(DBusMessageIter *arrayIt)
{
QStringList list;
@@ -51,6 +79,9 @@
DBusMessageIter it;
dbus_message_iter_recurse(arrayIt, &it);
+ if (!dbus_message_iter_has_next(&it))
+ return list;
+
do {
list.append(QString::fromUtf8(qIterGet<char *>(&it)));
} while (dbus_message_iter_next(&it));
@@ -62,11 +93,11 @@
{
switch (dbus_message_iter_get_arg_type(it)) {
case DBUS_TYPE_BYTE:
- return qIterGet<unsigned char>(it);
+ return qVariantFromValue(qIterGet<unsigned char>(it));
case DBUS_TYPE_INT16:
- return qIterGet<dbus_int16_t>(it);
+ return qVariantFromValue(qIterGet<dbus_int16_t>(it));
case DBUS_TYPE_UINT16:
- return qIterGet<dbus_uint16_t>(it);
+ return qVariantFromValue(qIterGet<dbus_uint16_t>(it));
case DBUS_TYPE_INT32:
return qIterGet<dbus_int32_t>(it);
case DBUS_TYPE_UINT32:
@@ -74,7 +105,7 @@
case DBUS_TYPE_DOUBLE:
return qIterGet<double>(it);
case DBUS_TYPE_BOOLEAN:
- return qIterGet<dbus_bool_t>(it);
+ return bool(qIterGet<dbus_bool_t>(it));
case DBUS_TYPE_INT64:
return static_cast<qlonglong>(qIterGet<dbus_int64_t>(it));
case DBUS_TYPE_UINT64:
@@ -83,19 +114,44 @@
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_SIGNATURE:
return QString::fromUtf8(qIterGet<char *>(it));
+ case DBUS_TYPE_VARIANT:
+ return qIterGet<QVariant>(it);
case DBUS_TYPE_ARRAY: {
int arrayType = dbus_message_iter_get_element_type(it);
- if (arrayType == DBUS_TYPE_STRING || arrayType == DBUS_TYPE_OBJECT_PATH ||
- arrayType == DBUS_TYPE_SIGNATURE) {
- return qFetchStringList(it);
- } else if (arrayType == DBUS_TYPE_BYTE) {
+ switch (arrayType)
+ {
+ case DBUS_TYPE_BYTE: {
+ // QByteArray
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) {
+ }
+ case DBUS_TYPE_INT16:
+ return qFetchList<dbus_int16_t, short>(it);
+ case DBUS_TYPE_UINT16:
+ return qFetchList<dbus_uint16_t, ushort>(it);
+ case DBUS_TYPE_INT32:
+ return qFetchList<dbus_int32_t, int>(it);
+ case DBUS_TYPE_UINT32:
+ return qFetchList<dbus_uint32_t, uint>(it);
+ case DBUS_TYPE_BOOLEAN:
+ return qFetchList<dbus_bool_t, bool>(it);
+ case DBUS_TYPE_DOUBLE:
+ return qFetchList<double, double>(it);
+ case DBUS_TYPE_INT64:
+ return qFetchList<dbus_int64_t, qlonglong>(it);
+ case DBUS_TYPE_UINT64:
+ return qFetchList<dbus_uint64_t, qulonglong>(it);
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE:
+ return qFetchStringList(it);
+ case DBUS_TYPE_VARIANT:
+ return qFetchList<QVariant, QVariant>(it);
+ case DBUS_TYPE_DICT_ENTRY: {
// ### support other types of maps?
QMap<QString, QVariant> map;
DBusMessageIter sub;
@@ -115,9 +171,10 @@
} while (dbus_message_iter_next(&sub));
return map;
}
+ }
}
// fall through
- // common handling for structs and lists
+ // common handling for structs and lists of lists (for now)
case DBUS_TYPE_STRUCT: {
QList<QVariant> list;
DBusMessageIter sub;
@@ -129,14 +186,6 @@
} while (dbus_message_iter_next(&sub));
return list;
}
- case DBUS_TYPE_VARIANT: {
- QDBusVariant dvariant;
- DBusMessageIter sub;
- dbus_message_iter_recurse(it, &sub);
- dvariant.type = QDBusType(dbus_message_iter_get_signature(&sub));
- dvariant.value = qFetchParameter(&sub);
- return qVariantFromValue(dvariant);
- }
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));
@@ -169,26 +218,20 @@
return true;
}
- // 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
-
- // convert manually
- QDBusVariant dvariant = qvariant_cast<QDBusVariant>(var);
- var = dvariant.value;
- return checkType(var, type);
- }
+ int id = var.userType();
if (type.dbusType() == DBUS_TYPE_VARIANT) {
- // variant can handle anything. Let it pass
+ // this is a non symmetrical operation:
+ // nest a QVariant if we want variant and it isn't so
+ if (id != QDBusTypeHelper<QVariant>::id()) {
+ QVariant tmp = var;
+ var = QDBusTypeHelper<QVariant>::toVariant(tmp);
+ }
return true;
}
- switch (var.userType()) {
+ switch (id) {
+ case QVariant::Bool:
case QMetaType::Short:
case QMetaType::UShort:
case QMetaType::UChar:
@@ -249,10 +292,35 @@
return true;
- case QVariant::Invalid:
+ case QVariant::Invalid: {
// create an empty variant
- var.convert(type.qvariantType());
- break;
+ void *null = 0;
+ var = QVariant(type.qvariantType(), null);
+ break;
+ }
+
+ default:
+ if (id == QDBusTypeHelper<QVariant>::id()) {
+ // if we got here, it means the match above for DBUS_TYPE_VARIANT didn't work
+ qWarning("Invalid conversion from nested variant to '%s'",
+ type.dbusSignature().constData());
+ return false;
+ } else if (type.dbusType() == DBUS_TYPE_ARRAY) {
+ int subType = type.arrayElement().dbusType();
+ if ((id == QDBusTypeHelper<bool>::listId() && subType == DBUS_TYPE_BOOLEAN) ||
+ (id == QDBusTypeHelper<short>::listId() && subType == DBUS_TYPE_INT16) ||
+ (id == QDBusTypeHelper<ushort>::listId() && subType == DBUS_TYPE_UINT16) ||
+ (id == QDBusTypeHelper<int>::listId() && subType == DBUS_TYPE_INT32) ||
+ (id == QDBusTypeHelper<uint>::listId() && subType == DBUS_TYPE_UINT32) ||
+ (id == QDBusTypeHelper<qlonglong>::listId() && subType == DBUS_TYPE_INT64) ||
+ (id == QDBusTypeHelper<qulonglong>::listId() && subType == DBUS_TYPE_UINT64) ||
+ (id == QDBusTypeHelper<double>::listId() && subType == DBUS_TYPE_DOUBLE))
+ return true;
+ }
+
+ qWarning("Invalid conversion from %s to '%s'", var.typeName(),
+ type.dbusSignature().constData());
+ return false;
}
qWarning("Found unknown QVariant type %d (%s) when converting to DBus", (int)var.type(),
@@ -271,7 +339,16 @@
static void qIterAppend(DBusMessageIter *it, const QDBusType &type, T arg)
{
dbus_message_iter_append_basic(it, type.dbusType(), &arg);
-}
+}
+
+template<typename DBusType, typename QtType>
+static void qAppendListToMessage(DBusMessageIter *it, const QDBusType &subType,
+ const QVariant &var)
+{
+ QList<QtType> list = QDBusTypeHelper<QList<QtType> >::fromVariant(var);
+ foreach (const QtType &item, list)
+ qIterAppend(it, subType, static_cast<DBusType>(item));
+}
static void qAppendArrayToMessage(DBusMessageIter *it, const QDBusType &subType,
const QVariant &var)
@@ -319,10 +396,33 @@
break;
}
- default:
- qFatal("qAppendArrayToMessage got unknown type!");
+ default: {
+ int id = var.userType();
+ if (id == QDBusTypeHelper<bool>::listId())
+ qAppendListToMessage<dbus_bool_t,bool>(&sub, subType, var);
+ else if (id == QDBusTypeHelper<short>::listId())
+ qAppendListToMessage<dbus_int16_t,short>(&sub, subType, var);
+ else if (id == QDBusTypeHelper<ushort>::listId())
+ qAppendListToMessage<dbus_uint16_t,ushort>(&sub, subType, var);
+ else if (id == QDBusTypeHelper<int>::listId())
+ qAppendListToMessage<dbus_int32_t,int>(&sub, subType, var);
+ else if (id == QDBusTypeHelper<uint>::listId())
+ qAppendListToMessage<dbus_uint32_t,uint>(&sub, subType, var);
+ else if (id == QDBusTypeHelper<qlonglong>::listId())
+ qAppendListToMessage<dbus_int64_t,qlonglong>(&sub, subType, var);
+ else if (id == QDBusTypeHelper<qulonglong>::listId())
+ qAppendListToMessage<dbus_uint64_t,qulonglong>(&sub, subType, var);
+ else if (id == QDBusTypeHelper<double>::listId())
+ qAppendListToMessage<double,double>(&sub, subType, var);
+#if 0 // never reached, since QVariant::List mached
+ else if (id == QDBusTypeHelper<QVariant>::listId())
+ qAppendListToMessage<QVariant,QVariant>(&sub, subType, var);
+#endif
+ else
+ qFatal("qAppendArrayToMessage got unknown type!");
break;
}
+ }
dbus_message_iter_close_container(it, &sub);
}
@@ -336,28 +436,21 @@
dbus_message_iter_close_container(it, &sub);
}
-static void qAppendVariantToMessage(DBusMessageIter *it, const QDBusType & /* type */,
+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;
- }
+ Q_UNUSED(type); // type is 'v'
- if (!t.isValid())
- t = QDBusType::guessFromVariant(v);
+ QVariant arg = var;
+ if (var.userType() == QDBusTypeHelper<QVariant>::id())
+ arg = QDBusTypeHelper<QVariant>::fromVariant(var); // extract the inner variant
+
+ QDBusType t = QDBusType::guessFromVariant(arg);
// now add this variant
DBusMessageIter sub;
dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, t.dbusSignature(), &sub);
- qVariantToIteratorInternal(&sub, v, t);
+ qVariantToIteratorInternal(&sub, arg, t);
dbus_message_iter_close_container(it, &sub);
}
@@ -376,16 +469,16 @@
{
switch (type.dbusType()) {
case DBUS_TYPE_BYTE:
- qIterAppend( it, type, static_cast<unsigned char>(var.toUInt()) );
+ qIterAppend( it, type, QDBusTypeHelper<uchar>::fromVariant(var) );
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()) );
+ qIterAppend( it, type, QDBusTypeHelper<short>::fromVariant(var) );
break;
case DBUS_TYPE_UINT16:
- qIterAppend( it, type, static_cast<dbus_uint16_t>(var.toUInt()) );
+ qIterAppend( it, type, QDBusTypeHelper<ushort>::fromVariant(var) );
break;
case DBUS_TYPE_INT32:
qIterAppend( it, type, static_cast<dbus_int32_t>(var.toInt()) );
@@ -461,4 +554,3 @@
else
qListToIterator(&it, list, QDBusTypeList(signature.toUtf8()));
}
-
Index: qdbusmessage.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusmessage.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusmessage.cpp 6 Mar 2006 14:29:39 -0000 1.4
+++ qdbusmessage.cpp 28 Mar 2006 18:56:08 -0000 1.5
@@ -32,9 +32,10 @@
#include "qdbuserror.h"
#include "qdbusmarshall_p.h"
#include "qdbusmessage_p.h"
+#include "qdbustypehelper_p.h"
-QDBusMessagePrivate::QDBusMessagePrivate(QDBusMessage *qq)
- : connection(QString()), msg(0), reply(0), q(qq), type(DBUS_MESSAGE_TYPE_INVALID),
+QDBusMessagePrivate::QDBusMessagePrivate()
+ : connection(QString()), msg(0), reply(0), type(DBUS_MESSAGE_TYPE_INVALID),
timeout(-1), ref(1), repliedTo(false)
{
}
@@ -54,10 +55,12 @@
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
+ \list
+ \o Method calls
+ \o Method return values
+ \o Signal emissions
+ \o Error codes
+ \endlist
Objects of this type are created with the four static functions signal, methodCall,
methodReply and error.
@@ -79,128 +82,112 @@
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
+ The signal will be constructed to represent a signal coming from the path \a path, interface \a
+ interface and signal name \a name.
+
+ The QDBusMessage object that is returned can be sent with QDBusConnection::send().
*/
QDBusMessage QDBusMessage::signal(const QString &path, const QString &interface,
const QString &name)
{
QDBusMessage message;
- message.d->type = DBUS_MESSAGE_TYPE_SIGNAL;
- message.d->path = path;
- message.d->interface = interface;
- message.d->name = name;
+ message.d_ptr->type = DBUS_MESSAGE_TYPE_SIGNAL;
+ message.d_ptr->path = path;
+ message.d_ptr->interface = interface;
+ message.d_ptr->name = name;
return message;
}
/*!
Constructs a new DBus message representing a method call. A method call always informs
- its destination address (service, path, interface and method).
+ its destination address (\a service, \a path, \a interface and \a 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
+ When using DBus in a peer-to-peer context (i.e., not on a bus), the \a 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)
- \returns a QDBusMessage object that can be sent with QDBusConnection::send,
- QDBusConnection::sendWithReply, or QDBusConnection::sendWithReplyAsync
+ This function 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)
{
QDBusMessage message;
- message.d->type = DBUS_MESSAGE_TYPE_METHOD_CALL;
- message.d->service = service;
- message.d->path = path;
- message.d->interface = interface;
- message.d->name = method;
+ message.d_ptr->type = DBUS_MESSAGE_TYPE_METHOD_CALL;
+ message.d_ptr->service = service;
+ message.d_ptr->path = path;
+ message.d_ptr->interface = interface;
+ message.d_ptr->name = method;
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
+ Constructs a new DBus message representing the return values from a called method. The \a other
+ variable represents the method call that the reply will be for.
+
+ This function returns a QDBusMessage object that can be sent with QDBusConnection::send().
*/
QDBusMessage QDBusMessage::methodReply(const QDBusMessage &other)
{
- Q_ASSERT(other.d->msg);
+ Q_ASSERT(other.d_ptr->msg);
QDBusMessage message;
- message.d->connection = other.d->connection;
- message.d->type = DBUS_MESSAGE_TYPE_METHOD_RETURN;
- message.d->reply = dbus_message_ref(other.d->msg);
- other.d->repliedTo = true;
+ message.d_ptr->connection = other.d_ptr->connection;
+ message.d_ptr->type = DBUS_MESSAGE_TYPE_METHOD_RETURN;
+ message.d_ptr->reply = dbus_message_ref(other.d_ptr->msg);
+ other.d_ptr->repliedTo = true;
return message;
}
/*!
- Constructs a DBus message representing an error condition.
+ Constructs a DBus message representing an error condition described by the \a name
+ parameter. The \a msg parameter is optional and may contain a human-readable description of the
+ error. The \a other variable represents the method call that this error relates to.
- \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
+ This function returns 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);
+ Q_ASSERT(other.d_ptr->msg);
QDBusMessage message;
- message.d->connection = other.d->connection;
- message.d->type = DBUS_MESSAGE_TYPE_ERROR;
- message.d->name = name;
- message.d->message = msg;
- message.d->reply = dbus_message_ref(other.d->msg);
- other.d->repliedTo = true;
+ message.d_ptr->connection = other.d_ptr->connection;
+ message.d_ptr->type = DBUS_MESSAGE_TYPE_ERROR;
+ message.d_ptr->name = name;
+ message.d_ptr->message = msg;
+ message.d_ptr->reply = dbus_message_ref(other.d_ptr->msg);
+ other.d_ptr->repliedTo = true;
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
+ Constructs a DBus message representing an error, where \a other is the method call that
+ generated this error and \a error is the error code.
*/
QDBusMessage QDBusMessage::error(const QDBusMessage &other, const QDBusError &error)
{
- Q_ASSERT(other.d->msg);
+ Q_ASSERT(other.d_ptr->msg);
QDBusMessage message;
- message.d->connection = other.d->connection;
- 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);
- other.d->repliedTo = true;
+ message.d_ptr->connection = other.d_ptr->connection;
+ message.d_ptr->type = DBUS_MESSAGE_TYPE_ERROR;
+ message.d_ptr->name = error.name();
+ message.d_ptr->message = error.message();
+ message.d_ptr->reply = dbus_message_ref(other.d_ptr->msg);
+ other.d_ptr->repliedTo = true;
return message;
}
@@ -208,21 +195,21 @@
/*!
Constructs an empty, invalid QDBusMessage object.
- \sa methodCall, methodReply, signal, error
+ \sa methodCall(), methodReply(), signal(), error()
*/
QDBusMessage::QDBusMessage()
{
- d = new QDBusMessagePrivate(this);
+ d_ptr = new QDBusMessagePrivate;
}
/*!
- Constructs a copy of the other object.
+ Constructs a copy of the object given by \a other.
*/
QDBusMessage::QDBusMessage(const QDBusMessage &other)
: QList<QVariant>(other)
{
- d = other.d;
- d->ref.ref();
+ d_ptr = other.d_ptr;
+ d_ptr->ref.ref();
}
/*!
@@ -230,17 +217,17 @@
*/
QDBusMessage::~QDBusMessage()
{
- if (!d->ref.deref())
- delete d;
+ if (!d_ptr->ref.deref())
+ delete d_ptr;
}
/*!
- Copies the contents of the other object.
+ Copies the contents of the object given by \a other.
*/
QDBusMessage &QDBusMessage::operator=(const QDBusMessage &other)
{
QList<QVariant>::operator=(other);
- qAtomicAssign(d, other.d);
+ qAtomicAssign(d_ptr, other.d_ptr);
return *this;
}
@@ -258,26 +245,26 @@
{
DBusMessage *msg = 0;
- switch (d->type) {
+ switch (d_ptr->type) {
case DBUS_MESSAGE_TYPE_METHOD_CALL:
- msg = dbus_message_new_method_call(data(d->service.toUtf8()), data(d->path.toUtf8()),
- data(d->interface.toUtf8()), data(d->name.toUtf8()));
+ msg = dbus_message_new_method_call(data(d_ptr->service.toUtf8()), data(d_ptr->path.toUtf8()),
+ data(d_ptr->interface.toUtf8()), data(d_ptr->name.toUtf8()));
break;
case DBUS_MESSAGE_TYPE_SIGNAL:
- msg = dbus_message_new_signal(data(d->path.toUtf8()), data(d->interface.toUtf8()),
- data(d->name.toUtf8()));
+ msg = dbus_message_new_signal(data(d_ptr->path.toUtf8()), data(d_ptr->interface.toUtf8()),
+ data(d_ptr->name.toUtf8()));
break;
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
- msg = dbus_message_new_method_return(d->reply);
+ msg = dbus_message_new_method_return(d_ptr->reply);
break;
case DBUS_MESSAGE_TYPE_ERROR:
- msg = dbus_message_new_error(d->reply, data(d->name.toUtf8()), data(d->message.toUtf8()));
+ msg = dbus_message_new_error(d_ptr->reply, data(d_ptr->name.toUtf8()), data(d_ptr->message.toUtf8()));
break;
}
if (!msg)
return 0;
- QDBusMarshall::listToMessage(*this, msg, d->signature);
+ QDBusMarshall::listToMessage(*this, msg, d_ptr->signature);
return msg;
}
@@ -291,16 +278,16 @@
if (!dmsg)
return message;
- message.d->connection = connection;
- 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 = message.d->type == DBUS_MESSAGE_TYPE_ERROR ?
+ message.d_ptr->connection = connection;
+ message.d_ptr->type = dbus_message_get_type(dmsg);
+ message.d_ptr->path = QString::fromUtf8(dbus_message_get_path(dmsg));
+ message.d_ptr->interface = QString::fromUtf8(dbus_message_get_interface(dmsg));
+ message.d_ptr->name = message.d_ptr->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);
+ message.d_ptr->service = QString::fromUtf8(dbus_message_get_sender(dmsg));
+ message.d_ptr->signature = QString::fromUtf8(dbus_message_get_signature(dmsg));
+ message.d_ptr->msg = dbus_message_ref(dmsg);
QDBusMarshall::messageToList(message, dmsg);
return message;
@@ -312,8 +299,8 @@
QDBusMessage QDBusMessage::fromError(const QDBusError &error)
{
QDBusMessage message;
- message.d->type = DBUS_MESSAGE_TYPE_ERROR;
- message.d->name = error.name();
+ message.d_ptr->type = DBUS_MESSAGE_TYPE_ERROR;
+ message.d_ptr->name = error.name();
message << error.message();
return message;
}
@@ -324,7 +311,7 @@
*/
QString QDBusMessage::path() const
{
- return d->path;
+ return d_ptr->path;
}
/*!
@@ -333,17 +320,17 @@
*/
QString QDBusMessage::interface() const
{
- return d->interface;
+ return d_ptr->interface;
}
/*!
Returns the name of the signal that was emitted or the name of the error that was
received.
- \sa member
+ \sa member()
*/
QString QDBusMessage::name() const
{
- return d->name;
+ return d_ptr->name;
}
/*!
@@ -362,7 +349,7 @@
*/
QString QDBusMessage::service() const
{
- return d->service;
+ return d_ptr->service;
}
/*!
@@ -375,17 +362,16 @@
*/
int QDBusMessage::timeout() const
{
- return d->timeout;
+ return d_ptr->timeout;
}
/*!
- Sets the timeout for this message to be processed.
-
- \param ms the time, in milliseconds
+ Sets the timeout for this message to be processed, given by \a ms, in milliseconds.
*/
void QDBusMessage::setTimeout(int ms)
{
- d->timeout = ms;
+ qAtomicDetach(d_ptr);
+ d_ptr->timeout = ms;
}
/*!
@@ -395,9 +381,9 @@
*/
bool QDBusMessage::noReply() const
{
- if (!d->msg)
+ if (!d_ptr->msg)
return false;
- return dbus_message_get_no_reply(d->msg);
+ return dbus_message_get_no_reply(d_ptr->msg);
}
/*!
@@ -406,9 +392,9 @@
*/
int QDBusMessage::serialNumber() const
{
- if (!d->msg)
+ if (!d_ptr->msg)
return 0;
- return dbus_message_get_serial(d->msg);
+ return dbus_message_get_serial(d_ptr->msg);
}
/*!
@@ -421,9 +407,9 @@
*/
int QDBusMessage::replySerialNumber() const
{
- if (!d->msg)
+ if (!d_ptr->msg)
return 0;
- return dbus_message_get_reply_serial(d->msg);
+ return dbus_message_get_reply_serial(d_ptr->msg);
}
/*!
@@ -432,7 +418,7 @@
*/
bool QDBusMessage::wasRepliedTo() const
{
- return d->repliedTo;
+ return d_ptr->repliedTo;
}
/*!
@@ -441,16 +427,25 @@
*/
QString QDBusMessage::signature() const
{
- return d->signature;
+ return d_ptr->signature;
}
/*!
- Sets the signature for the output arguments of this method call. This function has no meaning
- in other types of messages or when dealing with received method calls.
+ Sets the signature for the output arguments of this method call to be the value of \a
+ signature. This function has no meaning in other types of messages or when dealing with received
+ method calls.
+
+ A message's signature indicate the type of the parameters to
+ be marshalled over the bus. If there are more arguments than entries 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).
+
*/
void QDBusMessage::setSignature(const QString &signature)
{
- d->signature = signature;
+ qAtomicDetach(d_ptr);
+ d_ptr->signature = signature;
}
/*!
@@ -459,7 +454,7 @@
*/
QDBusConnection QDBusMessage::connection() const
{
- return d->connection;
+ return d_ptr->connection;
}
/*!
@@ -467,7 +462,7 @@
*/
QDBusMessage::MessageType QDBusMessage::type() const
{
- switch (d->type) {
+ switch (d_ptr->type) {
case DBUS_MESSAGE_TYPE_METHOD_CALL:
return MethodCallMessage;
case DBUS_MESSAGE_TYPE_METHOD_RETURN:
@@ -493,7 +488,7 @@
It can be used in the following manner:
\code
- QDBusReply<QString> reply = interface.call("RemoteMethod");
+ QDBusReply<QString> reply = interface->call("RemoteMethod");
if (reply.isSuccess())
// use the returned value
useValue(reply.value());
@@ -504,7 +499,7 @@
If the remote method call cannot fail, you can skip the error checking:
\code
- QString reply = interface.call("RemoteMethod");
+ QString reply = interface->call("RemoteMethod");
\endcode
However, if it does fail under those conditions, the value returned by QDBusReply::value() is
@@ -515,18 +510,18 @@
or not, by calling isError() and isSuccess(), and inspecting the error condition by calling
error(). You cannot call value().
- \sa QDBusMessage, QDBusInterface, \ref StandardInterfaces
+ \sa QDBusMessage, QDBusInterface
*/
/*!
\fn QDBusReply::QDBusReply(const QDBusMessage &reply)
- Automatically construct a QDBusReply object from the reply message \p reply, extracting the
+ Automatically construct a QDBusReply object from the reply message \a reply, extracting the
first return value from it if it is a success reply.
*/
/*!
\fn QDBusReply::QDBusReply(const QDBusError &error)
- Construct an error reply from the D-Bus error.
+ Constructs an error reply from the D-Bus error code given by \a error.
*/
/*!
@@ -554,71 +549,26 @@
the return value of this function is undefined and may be undistinguishable from a valid return
value.
- This function is not available if the remote call returns "void".
+ This function is not available if the remote call returns \c void.
*/
/*!
\fn QDBusReply::operator Type()
Returns the same as value().
- This function is not available if the remote call returns "void".
+ This function is not available if the remote call returns \c void.
*/
/*!
- \fn QDBusReply::fromVariant(const QDBusReply<QDBusVariant> &variantReply)>
- Converts the QDBusReply<QDBusVariant> object to this type by converting the variant contained in
- \p variantReply to the template's type and copying the error condition.
+ \internal
+ \fn QDBusReply::fromVariant(const QDBusReply<QVariant> &variantReply)
+ Converts the QDBusReply<QVariant> object to this type by converting the variant contained in
+ \a variantReply to the template's type and copying the error condition.
- If the QDBusVariant in variantReply is not convertible to this type, it will assume an undefined
+ If the QVariant in variantReply is not convertible to this type, it will assume an undefined
value.
*/
-// document QDBusVariant here too
-/*!
- \class QDBusVariant
- \brief Represents the D-Bus type VARIANT.
-
- This class represents a D-Bus argument of type VARIANT, which is composed of a type description
- and its value.
-*/
-
-/*!
- \var QDBusVariant::type
- Contains the VARIANT's type. It will contain an invalid type if this QDBusVariant argument was
- constructed, as opposed to being received over the D-Bus connection.
-*/
-
-/*!
- \var QDBusVariant::value
- Contain's the VARIANT's value.
-*/
-
-/*!
- \fn QDBusVariant::QDBusVariant()
- Constructs an empty variant. An empty variant cannot be sent over D-Bus without being
- initialized first.
-*/
-
-/*!
- \fn QDBusVariant::QDBusVariant(const QVariant &variant)
- Constructs a D-Bus Variant from the QVariant value \p variant. The D-Bus type, if not set, will
- be guessed from the QVariant value when actually sending the argument over D-Bus by calling
- QDBusType::guessFromVariant. You should explicitly set the type if are unsure the automatic
- guessing will produce the correct type.
-*/
-
-/*!
- \fn QDBusVariant::QDBusVariant(const QVariant &variant, const QDBusType &forcetype)
- Constructs a D-Bus Variant from the QVariant of value \p variant and sets the type to \p
- forcetype. The actual transformation of the QVariant to the proper D-Bus type will happen only
- when sending this argument over D-Bus.
-*/
-
-/*!
- \fn QDBusVariant::operator const QVariant &() const
- Returns the value #value.
-*/
-
#ifndef QT_NO_DEBUG
QDebug operator<<(QDebug dbg, QDBusMessage::MessageType t)
{
@@ -637,6 +587,106 @@
}
}
+static void debugVariantList(QDebug dbg, const QVariantList &list);
+static void debugVariantMap(QDebug dbg, const QVariantMap &map);
+
+static void debugVariant(QDebug dbg, const QVariant &v)
+{
+ dbg.nospace() << v.typeName() << "(";
+ switch (v.userType())
+ {
+ case QVariant::Bool:
+ dbg.nospace() << v.toBool();
+ break;
+ case QMetaType::UChar:
+ dbg.nospace() << qvariant_cast<uchar>(v);
+ break;
+ case QMetaType::Short:
+ dbg.nospace() << qvariant_cast<short>(v);
+ break;
+ case QMetaType::UShort:
+ dbg.nospace() << qvariant_cast<ushort>(v);
+ break;
+ case QVariant::Int:
+ dbg.nospace() << v.toInt();
+ break;
+ case QVariant::UInt:
+ dbg.nospace() << v.toUInt();
+ break;
+ case QVariant::LongLong:
+ dbg.nospace() << v.toLongLong();
+ break;
+ case QVariant::ULongLong:
+ dbg.nospace() << v.toULongLong();
+ break;
+ case QVariant::Double:
+ dbg.nospace() << v.toDouble();
+ break;
+ case QVariant::String:
+ dbg.nospace() << v.toString();
+ break;
+ case QVariant::ByteArray:
+ dbg.nospace() << v.toByteArray();
+ break;
+ case QVariant::StringList:
+ dbg.nospace() << v.toStringList();
+ break;
+ case QVariant::List:
+ debugVariantList(dbg, v.toList());
+ break;
+ case QVariant::Map:
+ debugVariantMap(dbg, v.toMap());
+ break;
+
+ default: {
+ int id = v.userType();
+ if (id == QDBusTypeHelper<QVariant>::id())
+ debugVariant(dbg, QDBusTypeHelper<QVariant>::fromVariant(v));
+ else if (id == QDBusTypeHelper<bool>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<bool> >::fromVariant(v);
+ else if (id == QDBusTypeHelper<short>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<short> >::fromVariant(v);
+ else if (id == QDBusTypeHelper<ushort>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<ushort> >::fromVariant(v);
+ else if (id == QDBusTypeHelper<int>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<int> >::fromVariant(v);
+ else if (id == QDBusTypeHelper<uint>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<uint> >::fromVariant(v);
+ else if (id == QDBusTypeHelper<qlonglong>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<qlonglong> >::fromVariant(v);
+ else if (id == QDBusTypeHelper<qulonglong>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<qulonglong> >::fromVariant(v);
+ else if (id == QDBusTypeHelper<double>::listId())
+ dbg.nospace() << QDBusTypeHelper<QList<double> >::fromVariant(v);
+ else
+ dbg.nospace() << "unknown";
+ }
+ }
+ dbg.nospace() << ")";
+}
+
+static void debugVariantList(QDebug dbg, const QVariantList &list)
+{
+ bool first = true;
+ foreach (const QVariant &v, list) {
+ if (!first)
+ dbg.nospace() << ", ";
+ debugVariant(dbg, v);
+ first = false;
+ }
+}
+
+static void debugVariantMap(QDebug dbg, const QVariantMap &map)
+{
+ QVariantMap::ConstIterator it = map.constBegin();
+ QVariantMap::ConstIterator end = map.constEnd();
+ for ( ; it != end; ++it) {
+ dbg << "(" << it.key() << ", ";
+ debugVariant(dbg, it.value());
+ dbg << ") ";
+ }
+}
+
QDebug operator<<(QDebug dbg, const QDBusMessage &msg)
{
dbg.nospace() << "QDBusMessage(type=" << msg.type()
@@ -645,7 +695,9 @@
<< ", interface=" << msg.interface()
<< ", name=" << msg.name()
<< ", signature=" << msg.signature()
- << ", contents=" << static_cast<QList<QVariant> >(msg) << ")";
+ << ", contents=(";
+ debugVariantList(dbg, msg);
+ dbg.nospace() << " ) )";
return dbg.space();
}
#endif
Index: qdbusmessage.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusmessage.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- qdbusmessage.h 6 Mar 2006 14:29:39 -0000 1.5
+++ qdbusmessage.h 28 Mar 2006 18:56:08 -0000 1.6
@@ -26,19 +26,21 @@
#define QDBUSMESSAGE_H
#include "qdbusmacros.h"
+#include "qdbuserror.h"
#include <QtCore/qlist.h>
#include <QtCore/qvariant.h>
#include <limits.h>
class QDBusMessagePrivate;
-class QDBusError;
class QDBusConnection;
+class QDBusConnectionPrivate;
struct DBusMessage;
class QDBUS_EXPORT QDBusMessage: public QList<QVariant>
{
- friend class QDBusConnection;
+ //friend class QDBusConnection;
+ friend class QDBusConnectionPrivate;
public:
enum { DefaultTimeout = -1, NoTimeout = INT_MAX};
enum MessageType { InvalidMessage, MethodCallMessage, ReplyMessage,
@@ -78,16 +80,15 @@
QDBusConnection connection() const;
-//protected:
- DBusMessage *toDBusMessage() const;
- static QDBusMessage fromDBusMessage(DBusMessage *dmsg, const QDBusConnection &connection);
- static QDBusMessage fromError(const QDBusError& error);
int serialNumber() const;
int replySerialNumber() const;
bool wasRepliedTo() const;
private:
- QDBusMessagePrivate *d;
+ DBusMessage *toDBusMessage() const;
+ static QDBusMessage fromDBusMessage(DBusMessage *dmsg, const QDBusConnection &connection);
+ static QDBusMessage fromError(const QDBusError& error);
+ QDBusMessagePrivate *d_ptr;
};
#ifndef QT_NO_DEBUG
Index: qdbusmessage_p.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusmessage_p.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- qdbusmessage_p.h 6 Mar 2006 14:29:39 -0000 1.4
+++ qdbusmessage_p.h 28 Mar 2006 18:56:08 -0000 1.5
@@ -33,14 +33,13 @@
class QDBusMessagePrivate
{
public:
- QDBusMessagePrivate(QDBusMessage *qq);
+ QDBusMessagePrivate();
~QDBusMessagePrivate();
QString service, path, interface, name, message, signature;
QDBusConnection connection;
DBusMessage *msg;
DBusMessage *reply;
- QDBusMessage *q;
int type;
int timeout;
QAtomic ref;
--- NEW FILE: qdbusmetaobject.cpp ---
/* -*- C++ -*-
*
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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 "qdbusmetaobject_p.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
#include <QtCore/qvarlengtharray.h>
#include "qdbusutil.h"
#include "qdbuserror.h"
#include "qdbusintrospection_p.h"
#include "qdbusabstractinterface_p.h"
class QDBusMetaObjectGenerator
{
public:
QDBusMetaObjectGenerator(const QString &interface,
const QDBusIntrospection::Interface *parsedData);
void write(QDBusMetaObject *obj);
void writeWithoutXml(QDBusMetaObject *obj);
private:
struct Method {
QByteArray parameters;
QByteArray typeName;
QByteArray tag;
QByteArray inputSignature;
QByteArray outputSignature;
QVarLengthArray<int, 6> inputTypes;
QVarLengthArray<int, 2> outputTypes;
int flags;
};
struct Property {
QByteArray typeName;
QByteArray signature;
int type;
int flags;
};
enum PropertyFlags {
Invalid = 0x00000000,
Readable = 0x00000001,
Writable = 0x00000002,
Resettable = 0x00000004,
EnumOrFlag = 0x00000008,
StdCppSet = 0x00000100,
// Override = 0x00000200,
Designable = 0x00001000,
ResolveDesignable = 0x00002000,
Scriptable = 0x00004000,
ResolveScriptable = 0x00008000,
Stored = 0x00010000,
ResolveStored = 0x00020000,
Editable = 0x00040000,
ResolveEditable = 0x00080000,
User = 0x00100000,
ResolveUser = 0x00200000
};
enum MethodFlags {
AccessPrivate = 0x00,
AccessProtected = 0x01,
AccessPublic = 0x02,
AccessMask = 0x03, //mask
MethodMethod = 0x00,
MethodSignal = 0x04,
MethodSlot = 0x08,
MethodTypeMask = 0x0c,
MethodCompatibility = 0x10,
MethodCloned = 0x20,
MethodScriptable = 0x40
};
QMap<QByteArray, Method> methods;
QMap<QByteArray, Property> properties;
const QDBusIntrospection::Interface *data;
QString interface;
void parseMethods();
void parseSignals();
void parseProperties();
};
static const int intsPerProperty = 2;
static const int intsPerMethod = 4;
// ### from kernel/qmetaobject.cpp (Qt 4.1.2):
struct QDBusMetaObjectPrivate
{
int revision;
int className;
int classInfoCount, classInfoData;
int methodCount, methodData;
int propertyCount, propertyData;
int enumeratorCount, enumeratorData;
// this is specific for QDBusMetaObject:
int propertyDBusData;
int methodDBusData;
};
QDBusMetaObjectGenerator::QDBusMetaObjectGenerator(const QString &interfaceName,
const QDBusIntrospection::Interface *parsedData)
: data(parsedData), interface(interfaceName)
{
if (data) {
parseProperties();
parseSignals(); // call parseSignals first so that slots override signals
parseMethods();
}
}
void QDBusMetaObjectGenerator::parseMethods()
{
foreach (const QDBusIntrospection::Method &m, data->methods) {
Method mm;
QByteArray prototype = m.name.toLatin1();
prototype += '(';
bool ok = true;
// build the input argument list
foreach (const QDBusIntrospection::Argument &arg, m.inputArgs) {
int typeId = QDBusUtil::signatureToType(arg.type);
if (typeId == QVariant::Invalid) {
ok = false;
break;
}
mm.inputSignature += arg.type;
mm.inputTypes.append(typeId);
mm.parameters.append(arg.name.toLatin1());
mm.parameters.append(',');
prototype.append( QVariant::typeToName( QVariant::Type(typeId) ) );
prototype.append(',');
}
if (!ok) continue;
// build the output argument list:
for (int i = 0; i < m.outputArgs.count(); ++i) {
const QDBusIntrospection::Argument &arg = m.outputArgs.at(i);
int typeId = QDBusUtil::signatureToType(arg.type);
if (typeId == QVariant::Invalid) {
ok = false;
break;
}
mm.outputSignature += arg.type;
mm.outputTypes.append(typeId);
if (i == 0) {
// return value
mm.typeName = QVariant::typeToName( QVariant::Type(typeId) );
} else {
// non-const ref parameter
mm.parameters.append(arg.name.toLatin1());
mm.parameters.append(',');
prototype.append( QVariant::typeToName( QVariant::Type(typeId) ) );
prototype.append("&,");
}
}
if (!ok) continue;
// convert the last commas:
if (!mm.parameters.isEmpty()) {
mm.parameters.truncate(mm.parameters.length() - 1);
prototype[prototype.length() - 1] = ')';
} else {
prototype.append(')');
}
// check the async tag
if (m.annotations.value(QLatin1String(ANNOTATION_NO_WAIT)) == QLatin1String("true"))
mm.tag = "Q_ASYNC";
// meta method flags
mm.flags = AccessPublic | MethodSlot | MethodScriptable;
// add
methods.insert(QMetaObject::normalizedSignature(prototype), mm);
}
}
void QDBusMetaObjectGenerator::parseSignals()
{
foreach (const QDBusIntrospection::Signal &s, data->signals_) {
Method mm;
QByteArray prototype = s.name.toLatin1();
prototype += '(';
bool ok = true;
// build the output argument list
foreach (const QDBusIntrospection::Argument &arg, s.outputArgs) {
int typeId = QDBusUtil::signatureToType(arg.type);
if (typeId == QVariant::Invalid) {
ok = false;
break;
}
mm.inputSignature += arg.type;
mm.inputTypes.append(typeId);
mm.parameters.append(arg.name.toLatin1());
mm.parameters.append(',');
prototype.append( QVariant::typeToName( QVariant::Type(typeId) ) );
prototype.append(',');
}
if (!ok) continue;
// convert the last commas:
if (!mm.parameters.isEmpty()) {
mm.parameters.truncate(mm.parameters.length() - 1);
prototype[prototype.length() - 1] = ')';
} else {
prototype.append(')');
}
// meta method flags
mm.flags = AccessProtected | MethodSignal | MethodScriptable;
// add
methods.insert(QMetaObject::normalizedSignature(prototype), mm);
}
}
void QDBusMetaObjectGenerator::parseProperties()
{
foreach (const QDBusIntrospection::Property &p, data->properties) {
Property mp;
mp.type = QDBusUtil::signatureToType(p.type);
if (mp.type == QVariant::Invalid)
continue;
QByteArray name = p.name.toLatin1();
mp.signature = p.type.toLatin1();
mp.typeName = QVariant::typeToName( QVariant::Type(mp.type) );
// build the flags:
mp.flags = StdCppSet | Scriptable | Stored;
if (p.access != QDBusIntrospection::Property::Write)
mp.flags |= Readable;
if (p.access != QDBusIntrospection::Property::Read)
mp.flags |= Writable;
if (mp.typeName == "QVariant")
mp.flags |= 0xff << 24;
else if (mp.type < 0xff)
// encode the type in the flags
mp.flags |= mp.type << 24;
// add the property:
properties.insert(name, mp);
}
}
void QDBusMetaObjectGenerator::write(QDBusMetaObject *obj)
{
// this code here is mostly copied from qaxbase.cpp
// with a few modifications to make it cleaner
QString className = interface;
className.replace(QLatin1Char('.'), QLatin1String("::"));
if (className.isEmpty())
className = QLatin1String("QDBusInterface");
QVarLengthArray<uint> data;
data.resize(sizeof(QDBusMetaObjectPrivate) / sizeof(int));
QDBusMetaObjectPrivate *header = reinterpret_cast<QDBusMetaObjectPrivate *>(data.data());
header->revision = 1;
header->className = 0;
header->classInfoCount = 0;
header->classInfoData = 0;
header->methodCount = methods.count();
header->methodData = data.size();
header->propertyCount = properties.count();
header->propertyData = header->methodData + header->methodCount * 5;
header->enumeratorCount = 0;
header->enumeratorData = 0;
header->propertyDBusData = header->propertyData + header->propertyCount * 3;
header->methodDBusData = header->propertyDBusData + header->propertyCount * intsPerProperty;
int data_size = data.size() +
(header->methodCount * (5+intsPerMethod)) +
(header->propertyCount * (3+intsPerProperty));
foreach (const Method &mm, methods)
data_size += 2 + mm.inputTypes.count() + mm.outputTypes.count();
data.resize(data_size + 1);
char null('\0');
QByteArray stringdata = className.toLatin1();
stringdata += null;
stringdata.reserve(8192);
int offset = header->methodData;
int signatureOffset = header->methodDBusData;
int typeidOffset = header->methodDBusData + header->methodCount * intsPerMethod;
data[typeidOffset++] = 0; // eod
// add each method:
for (QMap<QByteArray, Method>::ConstIterator it = methods.constBegin();
it != methods.constEnd(); ++it) {
// form "prototype\0parameters\0typeName\0tag\0inputSignature\0outputSignature"
const Method &mm = it.value();
data[offset++] = stringdata.length();
stringdata += it.key(); // prototype
stringdata += null;
data[offset++] = stringdata.length();
stringdata += mm.parameters;
stringdata += null;
data[offset++] = stringdata.length();
stringdata += mm.typeName;
stringdata += null;
data[offset++] = stringdata.length();
stringdata += mm.tag;
stringdata += null;
data[offset++] = mm.flags;
data[signatureOffset++] = stringdata.length();
stringdata += mm.inputSignature;
stringdata += null;
data[signatureOffset++] = stringdata.length();
stringdata += mm.outputSignature;
stringdata += null;
data[signatureOffset++] = typeidOffset;
data[typeidOffset++] = mm.inputTypes.count();
memcpy(data.data() + typeidOffset, mm.inputTypes.data(), mm.inputTypes.count() * sizeof(int));
typeidOffset += mm.inputTypes.count();
data[signatureOffset++] = typeidOffset;
data[typeidOffset++] = mm.outputTypes.count();
memcpy(data.data() + typeidOffset, mm.outputTypes.data(), mm.outputTypes.count() * sizeof(int));
typeidOffset += mm.outputTypes.count();
}
Q_ASSERT(offset == header->propertyData);
Q_ASSERT(signatureOffset == header->methodDBusData + header->methodCount * intsPerMethod);
Q_ASSERT(typeidOffset == data.size());
// add each property
signatureOffset = header->propertyDBusData;
for (QMap<QByteArray, Property>::ConstIterator it = properties.constBegin();
it != properties.constEnd(); ++it) {
const Property &mp = it.value();
// form is "name\0typeName\0signature\0"
data[offset++] = stringdata.length();
stringdata += it.key(); // name
stringdata += null;
data[offset++] = stringdata.length();
stringdata += mp.typeName;
stringdata += null;
data[offset++] = mp.flags;
data[signatureOffset++] = stringdata.length();
stringdata += mp.signature;
stringdata += null;
data[signatureOffset++] = mp.type;
}
Q_ASSERT(offset == header->propertyDBusData);
Q_ASSERT(signatureOffset == header->methodDBusData);
char *string_data = new char[stringdata.length()];
memcpy(string_data, stringdata, stringdata.length());
uint *uint_data = new uint[data.size()];
memcpy(uint_data, data.data(), data.size() * sizeof(int));
// put the metaobject together
obj->d.data = uint_data;
obj->d.extradata = 0;
obj->d.stringdata = string_data;
obj->d.superdata = &QDBusAbstractInterface::staticMetaObject;
}
#if 0
void QDBusMetaObjectGenerator::writeWithoutXml(const QString &interface)
{
// no XML definition
QString tmp(interface);
tmp.replace(QLatin1Char('.'), QLatin1String("::"));
QByteArray name(tmp.toLatin1());
QDBusMetaObjectPrivate *header = new QDBusMetaObjectPrivate;
memset(header, 0, sizeof *header);
header->revision = 1;
// leave the rest with 0
char *stringdata = new char[name.length() + 1];
stringdata[name.length()] = '\0';
d.data = reinterpret_cast<uint*>(header);
d.extradata = 0;
d.stringdata = stringdata;
d.superdata = &QDBusAbstractInterface::staticMetaObject;
cached = false;
}
#endif
/////////
// class QDBusMetaObject
QDBusMetaObject *QDBusMetaObject::createMetaObject(QString &interface, const QString &xml,
QHash<QString, QDBusMetaObject *> &cache,
QDBusError &error)
{
error = QDBusError();
QDBusIntrospection::Interfaces parsed = QDBusIntrospection::parseInterfaces(xml);
QDBusMetaObject *we = 0;
QDBusIntrospection::Interfaces::ConstIterator it = parsed.constBegin();
QDBusIntrospection::Interfaces::ConstIterator end = parsed.constEnd();
for ( ; it != end; ++it) {
// check if it's in the cache
QDBusMetaObject *obj = cache.value(it.key(), 0);
if (!obj) {
// not in cache; create
obj = new QDBusMetaObject;
QDBusMetaObjectGenerator generator(it.key(), it.value().constData());
generator.write(obj);
if ( (obj->cached = !it.key().startsWith( QLatin1String("local.") )) )
// cache it
cache.insert(it.key(), obj);
}
if (it.key() == interface) {
// it's us
we = obj;
} else if (interface.isEmpty() &&
!it.key().startsWith(QLatin1String("org.freedesktop.DBus."))) {
// also us
we = obj;
interface = it.key();
}
}
if (we)
return we;
// still nothing?
if (parsed.isEmpty()) {
// object didn't return introspection
we = new QDBusMetaObject;
QDBusMetaObjectGenerator generator(interface, 0);
generator.write(we);
we->cached = false;
return we;
}
// mark as an error
error = QDBusError(QDBusError::UnknownInterface,
QString( QLatin1String("Interface '%1' was not found") )
.arg(interface));
return 0;
}
QDBusMetaObject::QDBusMetaObject()
{
}
inline const QDBusMetaObjectPrivate *priv(const uint* data)
{
return reinterpret_cast<const QDBusMetaObjectPrivate *>(data);
}
const char *QDBusMetaObject::dbusNameForMethod(int id) const
{
//id -= methodOffset();
if (id >= 0 && id < priv(d.data)->methodCount) {
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
return d.stringdata + d.data[handle];
}
return 0;
}
const char *QDBusMetaObject::inputSignatureForMethod(int id) const
{
//id -= methodOffset();
if (id >= 0 && id < priv(d.data)->methodCount) {
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
return d.stringdata + d.data[handle + 1];
}
return 0;
}
const char *QDBusMetaObject::outputSignatureForMethod(int id) const
{
//id -= methodOffset();
if (id >= 0 && id < priv(d.data)->methodCount) {
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
return d.stringdata + d.data[handle + 2];
}
return 0;
}
const int *QDBusMetaObject::inputTypesForMethod(int id) const
{
//id -= methodOffset();
if (id >= 0 && id < priv(d.data)->methodCount) {
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
return reinterpret_cast<const int*>(d.data + d.data[handle + 3]);
}
return 0;
}
const int *QDBusMetaObject::outputTypesForMethod(int id) const
{
//id -= methodOffset();
if (id >= 0 && id < priv(d.data)->methodCount) {
int handle = priv(d.data)->methodDBusData + id*intsPerMethod;
return reinterpret_cast<const int*>(d.data + d.data[handle + 4]);
}
return 0;
}
int QDBusMetaObject::propertyMetaType(int id) const
{
//id -= propertyOffset();
if (id >= 0 && id < priv(d.data)->propertyCount) {
int handle = priv(d.data)->propertyDBusData + id*intsPerProperty;
return d.data[handle + 1];
}
return 0;
}
template<typename T>
static inline void assign_helper(void *ptr, const QVariant &value)
{
*reinterpret_cast<T *>(ptr) = qvariant_cast<T>(value);
}
void QDBusMetaObject::assign(void *ptr, const QVariant &value)
{
switch (value.userType())
{
case QVariant::Bool:
assign_helper<bool>(ptr, value);
return;
case QMetaType::UChar:
assign_helper<uchar>(ptr, value);
return;
case QMetaType::Short:
assign_helper<short>(ptr, value);
return;
case QMetaType::UShort:
assign_helper<ushort>(ptr, value);
return;
case QVariant::Int:
assign_helper<int>(ptr, value);
return;
case QVariant::UInt:
assign_helper<uint>(ptr, value);
return;
case QVariant::LongLong:
assign_helper<qlonglong>(ptr, value);
return;
case QVariant::ULongLong:
assign_helper<qulonglong>(ptr, value);
return;
case QVariant::Double:
assign_helper<double>(ptr, value);
return;
case QVariant::String:
assign_helper<QString>(ptr, value);
return;
case QVariant::ByteArray:
assign_helper<QByteArray>(ptr, value);
return;
case QVariant::List:
assign_helper<QVariantList>(ptr, value);
return;
case QVariant::Map:
assign_helper<QVariantMap>(ptr, value);
return;
default:
;
}
}
bool QDBusMetaTypeId::initialized = false;
int QDBusMetaTypeId::variant = 0;
int QDBusMetaTypeId::boollist = 0;
int QDBusMetaTypeId::shortlist = 0;
int QDBusMetaTypeId::ushortlist = 0;
int QDBusMetaTypeId::intlist = 0;
int QDBusMetaTypeId::uintlist = 0;
int QDBusMetaTypeId::longlonglist = 0;
int QDBusMetaTypeId::ulonglonglist = 0;
int QDBusMetaTypeId::doublelist = 0;
bool QDBusMetaTypeId::innerInitialize()
{
variant = qRegisterMetaType<QVariant>("QVariant");
boollist = qRegisterMetaType<QList<bool> >("QList<bool>");
shortlist = qRegisterMetaType<QList<short> >("QList<short>");
ushortlist = qRegisterMetaType<QList<ushort> >("QList<ushort>");
intlist = qRegisterMetaType<QList<int> >("QList<int>");
uintlist = qRegisterMetaType<QList<uint> >("QList<uint>");
longlonglist = qRegisterMetaType<QList<qlonglong> >("QList<qlonglong>");
ulonglonglist = qRegisterMetaType<QList<qulonglong> >("QList<qulonglong>");
doublelist = qRegisterMetaType<QList<double> >("QList<double>");
initialized = true;
return true;
}
int qDBusMetaTypeId(QVariant *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::variant; }
int qDBusMetaTypeId(QList<bool> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::boollist; }
int qDBusMetaTypeId(QList<short> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::shortlist; }
int qDBusMetaTypeId(QList<ushort> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::ushortlist; }
int qDBusMetaTypeId(QList<int> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::intlist; }
int qDBusMetaTypeId(QList<uint> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::uintlist; }
int qDBusMetaTypeId(QList<qlonglong> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::longlonglist; }
int qDBusMetaTypeId(QList<qulonglong> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::ulonglonglist; }
int qDBusMetaTypeId(QList<double> *)
{ QDBusMetaTypeId::initialize(); return QDBusMetaTypeId::doublelist; }
--- NEW FILE: qdbusmetaobject_p.h ---
/*
*
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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 QDBUSMETAOBJECTPRIVATE_H
#define QDBUSMETAOBJECTPRIVATE_H
#include <QtCore/qmetaobject.h>
#include "qdbusmacros.h"
class QDBusError;
class QDBusMetaObjectPrivate;
struct QDBUS_EXPORT QDBusMetaObject: public QMetaObject
{
bool cached;
static QDBusMetaObject *createMetaObject(QString &interface, const QString &xml,
QHash<QString, QDBusMetaObject *> &map,
QDBusError &error);
~QDBusMetaObject()
{
delete [] d.stringdata;
delete [] d.data;
}
// methods (slots & signals):
const char *dbusNameForMethod(int id) const;
const char *inputSignatureForMethod(int id) const;
const char *outputSignatureForMethod(int id) const;
const int *inputTypesForMethod(int id) const;
const int *outputTypesForMethod(int id) const;
// properties:
int propertyMetaType(int id) const;
// helper function:
static void assign(void *, const QVariant &value);
private:
QDBusMetaObject();
};
struct QDBusMetaTypeId
{
static bool innerInitialize();
static bool initialized;
static inline void initialize()
{
if (initialized) return;
innerInitialize();
}
static int variant;
static int boollist;
static int shortlist;
static int ushortlist;
static int intlist;
static int uintlist;
static int longlonglist;
static int ulonglonglist;
static int doublelist;
};
#endif
--- qdbusobject.cpp DELETED ---
--- qdbusobject.h DELETED ---
--- qdbusobject_p.h DELETED ---
Index: qdbusreply.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusreply.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- qdbusreply.h 6 Mar 2006 14:29:39 -0000 1.1
+++ qdbusreply.h 28 Mar 2006 18:56:08 -0000 1.2
@@ -30,22 +30,22 @@
#include "qdbusmacros.h"
#include "qdbusmessage.h"
#include "qdbuserror.h"
-#include "qdbusvariant.h"
+
+#include "qdbustypehelper_p.h"
template<typename T>
class QDBUS_EXPORT QDBusReply
{
typedef T Type;
public:
-
inline QDBusReply(const QDBusMessage &reply)
- : m_error(reply)
+ : m_error(reply), m_data(Type())
{
if (isSuccess())
- m_data = qvariant_cast<Type>(reply.at(0));
+ m_data = QDBusTypeHelper<Type>::fromVariant(reply.at(0));
}
inline QDBusReply(const QDBusError &error)
- : m_error(error)
+ : m_error(error), m_data(Type())
{
}
@@ -64,14 +64,14 @@
return m_data;
}
- static QDBusReply<T> fromVariant(const QDBusReply<QDBusVariant> &variantReply)
+ static QDBusReply<T> fromVariant(const QDBusReply<QVariant> &variantReply)
{
QDBusReply<T> retval;
retval.m_error = variantReply.m_error;
if (retval.isSuccess()) {
- retval.m_data = qvariant_cast<Type>(variantReply.value);
- if (!qVariantCanConvert<Type>(variantReply.value))
- retval.m_error = QDBusError(QLatin1String(DBUS_ERROR_INVALID_SIGNATURE),
+ retval.m_data = qvariant_cast<Type>(variantReply.m_data);
+ if (!qVariantCanConvert<Type>(variantReply.m_data))
+ retval.m_error = QDBusError(QDBusError::InvalidSignature,
QLatin1String("Unexpected reply signature"));
}
return retval;
@@ -82,7 +82,7 @@
Type m_data;
};
-#ifndef DOXYGEN_SHOULD_SKIP_THIS
+# ifndef Q_QDOC
// specialize for void:
template<>
class QDBUS_EXPORT QDBusReply<void>
@@ -105,6 +105,6 @@
private:
QDBusError m_error;
};
-#endif
+# endif
#endif
--- qdbusstandardinterfaces.cpp DELETED ---
--- qdbusstandardinterfaces.h DELETED ---
Index: qdbustype.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbustype.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbustype.cpp 6 Mar 2006 14:29:39 -0000 1.2
+++ qdbustype.cpp 28 Mar 2006 18:56:08 -0000 1.3
@@ -22,264 +22,17 @@
*
*/
-#include "qdbustype.h"
-#include "qdbusvariant.h"
+#include "qdbustype_p.h"
+#include "qdbustypehelper_p.h"
#include <dbus/dbus.h>
#include <QtCore/qstringlist.h>
-/// \internal
-class QDBusPrettyTypeBase
-{
-public:
- struct Entry
- {
- const char* prettyName;
- char signature;
- };
-
- enum Direction
- {
- In,
- Out
- };
-
- enum Access
- {
- Read,
- Write,
- ReadWrite
- };
-
- // so that the compiler doesn't complain
- virtual ~QDBusPrettyTypeBase() { }
-
- virtual QString addElementsToArray(const QString& subType) = 0;
- virtual QString addElementsToMap(const QString& key, const QString& value) = 0;
- virtual QString addElementsToStruct(const QStringList& subTypes) = 0;
- virtual const Entry* entryMap() = 0;
-
- QString toString(const QDBusType& type);
- QString toString(const QDBusTypeList& list);
-};
-
-/// \internal
-class QDBusConventionalNames: public QDBusPrettyTypeBase
-{
-public:
- virtual QString addElementsToArray(const QString& subType);
- virtual QString addElementsToMap(const QString& key, const QString& value);
- virtual QString addElementsToStruct(const QStringList& subTypes) ;
- virtual const Entry* entryMap();
-};
-
-/// \internal
-class QDBusQtNames: public QDBusPrettyTypeBase
-{
-public:
- virtual QString addElementsToArray(const QString& subType);
- virtual QString addElementsToMap(const QString& key, const QString& value);
- virtual QString addElementsToStruct(const QStringList& subTypes) ;
- virtual const Entry* entryMap();
-};
-
-//! \internal
-class QDBusQVariantNames: public QDBusQtNames
-{
-public:
- virtual QString addElementsToArray(const QString& subType);
- virtual QString addElementsToMap(const QString& key, const QString& value);
- virtual QString addElementsToStruct(const QStringList& subTypes) ;
-};
-
-static QString findInMap(char type, const QDBusPrettyTypeBase::Entry* map)
-{
- for ( ; map->signature; ++map)
- if (type == map->signature)
- return QLatin1String(map->prettyName);
- return QString();
-}
-
-//
-// Input MUST be valid
-//
-inline QString QDBusPrettyTypeBase::toString(const QDBusType& type)
-{
- const Entry* map = entryMap();
-
- const QDBusTypeList subTypes = type.subTypes();
- switch (type.dbusType()) {
- case DBUS_TYPE_STRUCT: {
- // handle a struct
- // find its sub-types
-
- QStringList subStrings;
- QDBusTypeList subTypes = type.subTypes();
- foreach (QDBusType t, subTypes)
- subStrings << toString( t );
-
- return addElementsToStruct(subStrings);
- }
-
- case DBUS_TYPE_DICT_ENTRY: {
- Q_ASSERT_X(subTypes.size() == 2, "QDBusType::toString",
- "maps must have exactly two elements");
-
- QString key = findInMap( subTypes.at(0).dbusType(), map );
- QString value = toString( subTypes.at(1) );
-
- Q_ASSERT(!key.isNull());
-
- return addElementsToMap( key, value );
- }
- case DBUS_TYPE_ARRAY: {
- Q_ASSERT_X(subTypes.size() == 1, "QDBusType::toString",
- "more than one element in array");
-
- if (type.qvariantType() == QVariant::Map)
- return toString( subTypes.first() );
- return addElementsToArray( toString( subTypes.at(0) ) );
- }
-
- default: {
- // normal, non-compound type
- QString name = findInMap(type.dbusType(), map);
- Q_ASSERT(!name.isNull());
- return name;
- }
- }
-}
-
-const QDBusPrettyTypeBase::Entry* QDBusConventionalNames::entryMap()
-{
- static QDBusPrettyTypeBase::Entry translation[] = {
- { "BYTE", DBUS_TYPE_BYTE },
- { "BOOLEAN", DBUS_TYPE_BOOLEAN },
- { "INT16", DBUS_TYPE_INT16 },
- { "UINT16", DBUS_TYPE_UINT16 },
- { "INT32", DBUS_TYPE_INT32 },
- { "UINT32", DBUS_TYPE_UINT32 },
- { "INT64", DBUS_TYPE_INT64 },
- { "UINT64", DBUS_TYPE_UINT64 },
- { "DOUBLE", DBUS_TYPE_DOUBLE },
- { "STRING", DBUS_TYPE_STRING },
- { "OBJECT_PATH", DBUS_TYPE_OBJECT_PATH },
- { "SIGNATURE", DBUS_TYPE_SIGNATURE },
- { "VARIANT", DBUS_TYPE_VARIANT }
- };
- return translation;
-}
-
-QString QDBusConventionalNames::addElementsToStruct(const QStringList& subTypes)
-{
- return QString( QLatin1String("STRUCT of (%1)") )
- .arg( subTypes.join( QLatin1String(",") ) );
-}
-
-QString QDBusConventionalNames::addElementsToMap(const QString& key, const QString& value)
-{
- return QString( QLatin1String("ARRAY of DICT_ENTRY of (%1,%2)") )
- .arg(key).arg(value);
-}
-
-QString QDBusConventionalNames::addElementsToArray(const QString& subType)
-{
- return QString( QLatin1String("ARRAY of %1") )
- .arg(subType);
-}
-
-const QDBusPrettyTypeBase::Entry* QDBusQtNames::entryMap()
-{
- static QDBusPrettyTypeBase::Entry translation[] = {
- { "uchar", DBUS_TYPE_BYTE },
- { "bool", DBUS_TYPE_BOOLEAN },
- { "short", DBUS_TYPE_INT16 },
- { "ushort", DBUS_TYPE_UINT16 },
- { "int", DBUS_TYPE_INT32 },
- { "uint", DBUS_TYPE_UINT32 },
- { "qlonglong", DBUS_TYPE_INT64 },
- { "qulonglong", DBUS_TYPE_UINT64 },
- { "double", DBUS_TYPE_DOUBLE },
- { "QString", DBUS_TYPE_STRING },
- { "QString", DBUS_TYPE_OBJECT_PATH },
- { "QString", DBUS_TYPE_SIGNATURE },
- { "QDBusVariant", DBUS_TYPE_VARIANT }
- };
- return translation;
-}
-
-static inline QString templateArg(const QString& input)
-{
- if (input.endsWith(QLatin1Char('>')))
- return input + QLatin1Char(' ');
- return input;
-}
-
-QString QDBusQtNames::addElementsToStruct(const QStringList& subTypes)
-{
- Q_UNUSED(subTypes);
-
- return QLatin1String("QVariantList"); // CHANGEME in the future
-}
-
-QString QDBusQtNames::addElementsToMap(const QString& key, const QString& value)
-{
- if (key == QLatin1String("QString") && value == QLatin1String("QDBusVariant"))
- return QLatin1String("QVariantMap");
-
- return QString( QLatin1String("QMap<%1, %2>") )
- .arg(key)
- .arg( templateArg(value) );
-}
-
-QString QDBusQtNames::addElementsToArray(const QString& subType)
-{
- if (subType == QLatin1String("uchar"))
- // special case
- return QLatin1String("QByteArray");
- else if (subType == QLatin1String("QString"))
- // special case
- return QLatin1String("QStringList");
-
- return QString( QLatin1String("QList<%1>") )
- .arg( templateArg(subType) );
-}
-
-QString QDBusQVariantNames::addElementsToStruct(const QStringList& subTypes)
-{
- Q_UNUSED(subTypes);
-
- return QLatin1String("QVariantList");
-}
-
-QString QDBusQVariantNames::addElementsToMap(const QString& key, const QString& value)
-{
- Q_UNUSED(key);
- Q_UNUSED(value);
-
- return QLatin1String("QVariantMap");
-}
-
-QString QDBusQVariantNames::addElementsToArray(const QString& subType)
-{
- if (subType == QLatin1String("uchar"))
- // special case
- return QLatin1String("QByteArray");
- else if (subType == QLatin1String("QString"))
- // special case
- return QLatin1String("QStringList");
-
- return QLatin1String("QVariantList");
-}
-
-/*!
- \internal
-*/
class QDBusTypePrivate: public QSharedData
{
public:
int code;
- mutable QVariant::Type qvariantType;
+ mutable int qvariantType;
mutable QByteArray signature;
QDBusTypeList subTypes;
@@ -291,6 +44,7 @@
/*!
\class QDBusType
\brief Represents one single D-Bus type.
+ \internal
D-Bus provides a set of primitive types that map to normal, C++ types and to QString, as well as
the possibility to extend the set with the so-called "container" types. The available types are
@@ -322,18 +76,6 @@
*/
/*!
- \enum QDBusType::StringFormat
-
- This enum is used in QDBusType::toString to determine which type of formatting
- to apply to the D-Bus types:
-
- \value ConventionalNames Use the DBus conventional names, such as STRING, BOOLEAN or
- ARRAY of BYTE.
- \value QtNames Use the Qt type names, such as QString, bool and QList<quint32>
- \value QVariantNames Same as QtNames, but for containers, use QVariantList and QVariantMap
-*/
-
-/*!
Constructs an empty (invalid) type.
*/
QDBusType::QDBusType()
@@ -342,7 +84,7 @@
}
/*!
- Constructs the type based on the given DBus type.
+ Constructs the type based on the D-Bus type given by \a type.
*/
QDBusType::QDBusType(int type)
{
@@ -351,7 +93,7 @@
}
/*!
- Constructs the type based on the given QVariant type.
+ Constructs the type based on the QVariant type given by \a type.
\sa QVariant::Type
*/
@@ -360,38 +102,33 @@
const char *sig = dbusSignature(type);
// it never returns NULL
+ // but it may return an empty string:
if (sig[0] == '\0')
return;
- d = new QDBusTypePrivate;
- d->qvariantType = type;
- d->code = sig[0];
- if (sig[1] == '\0')
- // single-letter type
- return;
- else if (sig[2] == '\0') {
- // two-letter type
- // must be an array
+ if (qstrlen(sig) > 2) {
+ *this = QDBusType(sig);
+ } else {
+ d = new QDBusTypePrivate;
+ d->qvariantType = type;
d->code = sig[0];
- QDBusType t;
- t.d = new QDBusTypePrivate;
- t.d->code = sig[1];
- d->subTypes << t;
- }
- else {
- // the only longer type is "a{sv}"
- Q_ASSERT(sig[1] == '{' && sig[5] == '\0');
-
- static QDBusType map("a{sv}");
- d->subTypes = map.d->subTypes;
+ if (sig[1] == '\0')
+ // single-letter type
+ return;
+ else {
+ // two-letter type
+ // must be an array
+ d->code = sig[0];
+ QDBusType t;
+ t.d = new QDBusTypePrivate;
+ t.d->code = sig[1];
+ d->subTypes << t;
+ }
}
}
/*!
- Parses the given DBus signature and constructs the type it represents.
-
- \param signature the signature to parse. It must represent one single type, but can be
- a container type.
+ Parses the D-Bus signature given by \a signature and constructs the type it represents.
*/
QDBusType::QDBusType(const char* signature)
{
@@ -406,10 +143,8 @@
}
/*!
- Parses the given DBus signature and constructs the type it represents.
-
- \param str the signature to parse. It must represent one single type, but can
- a container type.
+ \overload
+ Parses the D-Bus signature given by \a str and constructs the type it represents.
*/
QDBusType::QDBusType(const QString& str)
{
@@ -417,10 +152,8 @@
}
/*!
- Parses the given DBus signature and constructs the type it represents.
-
- \param str the signature to parse. It must represent one single type, but can
- a container type.
+ \overload
+ Parses the D-Bus signature given by \a str and constructs the type it represents.
*/
QDBusType::QDBusType(const QByteArray& str)
{
@@ -430,8 +163,6 @@
/*!
\internal
Creates a QDBusType object based on the current element pointed to by \a iter.
-
- \param iter the iterator. Can be pointing to container types.
*/
QDBusType::QDBusType(DBusSignatureIter* iter)
: d(new QDBusTypePrivate)
@@ -458,7 +189,7 @@
}
/*!
- Copies the type from the other object.
+ Copies the type from the object \a other.
*/
QDBusType::QDBusType(const QDBusType& other)
: d(other.d)
@@ -473,7 +204,7 @@
}
/*!
- Copies the type from the other object.
+ Copies the type from the object given by \a other.
*/
QDBusType& QDBusType::operator=(const QDBusType& other)
{
@@ -550,24 +281,15 @@
/*!
Returns the QVariant::Type for this entry.
*/
-QVariant::Type QDBusType::qvariantType() const
+int QDBusType::qvariantType() const
{
if (d && d->qvariantType != QVariant::Invalid)
return d->qvariantType;
- // check the special array cases:
- if (isArray()) {
- QDBusType t = arrayElement();
-
- if (t.dbusType() == DBUS_TYPE_BYTE)
- return QVariant::ByteArray;
- else if (t.dbusType() == DBUS_TYPE_DICT_ENTRY)
- return QVariant::Map;
- else if (t.isBasic() && t.qvariantType() == QVariant::String)
- return QVariant::StringList;
- }
+ if (!d)
+ return QVariant::Invalid;
- return qvariantType(dbusType());
+ return d->qvariantType = qvariantType(dbusSignature().constData());
}
/*!
@@ -580,8 +302,6 @@
/*!
Returns true if this type is a basic one.
-
- \sa dbus_type_is_basic
*/
bool QDBusType::isBasic() const
{
@@ -590,8 +310,6 @@
/*!
Returns true if this type is a container.
-
- \sa dbus_type_is_container
*/
bool QDBusType::isContainer() const
{
@@ -601,7 +319,7 @@
/*!
Returns the subtypes of this type, if this is a container.
- \sa isContainer
+ \sa isContainer()
*/
QDBusTypeList QDBusType::subTypes() const
{
@@ -613,7 +331,7 @@
/*!
Returns true if this type is an array.
- \sa isContainer, arrayElement
+ \sa isContainer(), arrayElement()
*/
bool QDBusType::isArray() const
{
@@ -624,7 +342,7 @@
This is a convenience function that returns the element type of an array.
If this object is not an array, it returns an invalid QDBusType.
- \sa isArray
+ \sa isArray()
*/
QDBusType QDBusType::arrayElement() const
{
@@ -636,7 +354,7 @@
/*!
Returns true if this type is a map (i.e., an array of dictionary entries).
- \sa isContainer, isArray, arrayElement
+ \sa isContainer(), isArray(), arrayElement()
*/
bool QDBusType::isMap() const
{
@@ -647,7 +365,7 @@
If this object is a map, returns the (basic) type that corresponds to the key type.
If this object is not a map, returns an invalid QDBusType.
- \sa isMap
+ \sa isMap()
*/
QDBusType QDBusType::mapKey() const
{
@@ -660,7 +378,7 @@
If this object is a map, returns the type that corresponds to the value type.
If this object is not a map, returns an invalid QDBusType.
- \sa isMap
+ \sa isMap()
*/
QDBusType QDBusType::mapValue() const
{
@@ -670,7 +388,7 @@
}
/*!
- Returns true if the two types match.
+ Returns true if this type is the same one as \a other.
*/
bool QDBusType::operator==(const QDBusType& other) const
{
@@ -682,37 +400,23 @@
}
/*!
- Returns a string representation of this type.
+ \fn QDBusType::operator!=(const QDBusType &other) const
+ Returns true if the this type and the one given by \a other are different.
*/
-QString QDBusType::toString(StringFormat sf) const
-{
- switch (sf) {
- case ConventionalNames:
- return QDBusConventionalNames().toString(*this);
-
- case QtNames:
- return QDBusQtNames().toString(*this);
-
- case QVariantNames:
- return QDBusQVariantNames().toString(*this);
- }
-
- return QString(); // invalid
-}
/*!
- Converts the DBus type to QVariant::Type
+ Converts the DBus type code \a type to QVariant::Type.
*/
-QVariant::Type QDBusType::qvariantType(int type)
+int QDBusType::qvariantType(int type)
{
char c[2] = { type, 0 };
return qvariantType(c);
}
/*!
- Converts the DBus type signature to QVariant::Type.
+ Converts the DBus type signature \a signature to QVariant::Type.
*/
-QVariant::Type QDBusType::qvariantType(const char* signature)
+int QDBusType::qvariantType(const char* signature)
{
if (!signature)
return QVariant::Invalid;
@@ -736,12 +440,18 @@
case DBUS_TYPE_BOOLEAN:
return QVariant::Bool;
+ case DBUS_TYPE_BYTE:
+ return QMetaType::UChar;
+
case DBUS_TYPE_INT16:
- case DBUS_TYPE_INT32:
- return QVariant::Int;
+ return QMetaType::Short;
- case DBUS_TYPE_BYTE:
case DBUS_TYPE_UINT16:
+ return QMetaType::UShort;
+
+ case DBUS_TYPE_INT32:
+ return QVariant::Int;
+
case DBUS_TYPE_UINT32:
return QVariant::UInt;
@@ -763,23 +473,51 @@
return QVariant::List; // change to QDBusStruct in the future
case DBUS_TYPE_VARIANT:
- return QVariant::UserType; // must set user-type too
+ return QDBusTypeHelper<QVariant>::id();
case DBUS_TYPE_ARRAY: // special case
- // check if it's a string list
- if (qvariantType(signature + 1) == QVariant::String)
- return QVariant::StringList;
+ switch (signature[1]) {
+ case DBUS_TYPE_BOOLEAN:
+ return QDBusTypeHelper<bool>::listId();
- // maybe it's a byte array
- if (DBUS_TYPE_BYTE == signature[1])
+ case DBUS_TYPE_BYTE:
return QVariant::ByteArray;
- // check if it's a dict
- if (DBUS_DICT_ENTRY_BEGIN_CHAR == signature[1])
- return QVariant::Map;
+ case DBUS_TYPE_INT16:
+ return QDBusTypeHelper<short>::listId();
- return QVariant::List;
+ case DBUS_TYPE_UINT16:
+ return QDBusTypeHelper<ushort>::listId();
+ case DBUS_TYPE_INT32:
+ return QDBusTypeHelper<int>::listId();
+
+ case DBUS_TYPE_UINT32:
+ return QDBusTypeHelper<uint>::listId();
+
+ case DBUS_TYPE_INT64:
+ return QDBusTypeHelper<qlonglong>::listId();
+
+ case DBUS_TYPE_UINT64:
+ return QDBusTypeHelper<qulonglong>::listId();
+
+ case DBUS_TYPE_DOUBLE:
+ return QDBusTypeHelper<double>::listId();
+
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_OBJECT_PATH:
+ case DBUS_TYPE_SIGNATURE:
+ return QVariant::StringList;
+
+ case DBUS_TYPE_VARIANT:
+ return QVariant::List;
+
+ case DBUS_DICT_ENTRY_BEGIN_CHAR:
+ return QVariant::Map;
+
+ default:
+ return QVariant::List;
+ }
default:
return QVariant::Invalid;
@@ -787,9 +525,7 @@
}
/*!
- Converts the QVariant::Type to a DBus type code.
-
- \param t the type to convert
+ Converts the QVariant::Type \a t to a DBus type code.
*/
int QDBusType::dbusType(QVariant::Type t)
{
@@ -802,7 +538,6 @@
return DBUS_TYPE_INT32;
case QVariant::UInt:
- case QVariant::Char:
return DBUS_TYPE_UINT32;
case QVariant::LongLong:
@@ -825,9 +560,6 @@
return DBUS_TYPE_BYTE;
case QVariant::String:
- case QVariant::Date:
- case QVariant::Time:
- case QVariant::DateTime:
return DBUS_TYPE_STRING;
case QVariant::Map:
@@ -841,22 +573,20 @@
return DBUS_TYPE_ARRAY;
case QVariant::UserType:
- return DBUS_TYPE_VARIANT;
+ return DBUS_TYPE_INVALID; // invalid
default:
break; // avoid compiler warnings
}
- if (int(t) == QMetaTypeId<QDBusVariant>::qt_metatype_id())
+ if (int(t) == QDBusTypeHelper<QVariant>::id())
return DBUS_TYPE_VARIANT;
return DBUS_TYPE_INVALID;
}
/*!
- Converts the QVariant::Type to a DBus type signature.
-
- \param t the type to convert
+ Converts the QVariant::Type \a t to a DBus type signature.
*/
const char* QDBusType::dbusSignature(QVariant::Type t)
{
@@ -869,7 +599,6 @@
return DBUS_TYPE_INT32_AS_STRING;
case QVariant::UInt:
- case QVariant::Char:
return DBUS_TYPE_UINT32_AS_STRING;
case QMetaType::Short:
@@ -891,9 +620,6 @@
return DBUS_TYPE_DOUBLE_AS_STRING;
case QVariant::String:
- case QVariant::Date:
- case QVariant::Time:
- case QVariant::DateTime:
return DBUS_TYPE_STRING_AS_STRING;
case QVariant::Map:
@@ -920,8 +646,24 @@
DBUS_TYPE_VARIANT_AS_STRING; // av
default:
- if (int(t) == qMetaTypeId<QDBusVariant>())
+ if (int(t) == QDBusTypeHelper<QVariant>::id())
return DBUS_TYPE_VARIANT_AS_STRING;
+ if (int(t) == QDBusTypeHelper<bool>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BOOLEAN_AS_STRING;
+ if (int(t) == QDBusTypeHelper<short>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT16_AS_STRING;
+ if (int(t) == QDBusTypeHelper<ushort>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT16_AS_STRING;
+ if (int(t) == QDBusTypeHelper<int>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT32_AS_STRING;
+ if (int(t) == QDBusTypeHelper<uint>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT32_AS_STRING;
+ if (int(t) == QDBusTypeHelper<qlonglong>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_INT64_AS_STRING;
+ if (int(t) == QDBusTypeHelper<qulonglong>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_UINT64_AS_STRING;
+ if (int(t) == QDBusTypeHelper<double>::listId())
+ return DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_DOUBLE_AS_STRING;
return DBUS_TYPE_INVALID_AS_STRING;
}
@@ -931,12 +673,10 @@
\enum QDBusType::VariantListMode
Defines how the guessFromVariant() function will behave when the QVariant is of type
QVariant::List.
-
- \todo Improve the algorithm
*/
/*!
- Guesses the DBus type from the given variant.
+ Guesses the DBus type from the given \a variant.
*/
QDBusType QDBusType::guessFromVariant(const QVariant& variant, VariantListMode mode)
{
@@ -944,46 +684,36 @@
// investigate deeper
QDBusType t;
t.d = new QDBusTypePrivate;
+ const QVariantList list = variant.toList();
- if (mode == ListIsArray) {
- t.d->code = DBUS_TYPE_ARRAY;
-
- const QVariantList list = variant.toList();
- if (!list.isEmpty()) {
- // check if all elements have the same type
- QVariant::Type type = list.first().type();
- foreach (const QVariant& v, list)
- if (type != v.type()) {
- // at least one is different
- type = QVariant::Invalid;
- break;
- }
-
- if (type != QVariant::Invalid) {
- // all are of the same type
- t.d->subTypes << guessFromVariant(list.first());
- return t;
+ t.d->code = DBUS_TYPE_ARRAY;
+ if (!list.isEmpty()) {
+ // check if all elements have the same type
+ QVariant::Type type = list.first().type();
+ foreach (const QVariant& v, list)
+ if (type != v.type()) {
+ // at least one is different
+ type = QVariant::Invalid;
+ break;
}
+
+ if (type != QVariant::Invalid) {
+ // all are of the same type
+ t.d->subTypes << guessFromVariant(list.first());
+ return t;
}
-
- // internal information has been lost or there are many types
- QDBusType nested;
- nested.d = new QDBusTypePrivate;
- nested.d->code = DBUS_TYPE_VARIANT;
- t.d->subTypes << nested;
- return t;
- }
- else {
- // treat it as a struct
- t.d->code = DBUS_TYPE_STRUCT;
-
- // add the elements:
- const QVariantList list = variant.toList();
- foreach (const QVariant& v, list)
- t.d->subTypes << guessFromVariant(v, mode);
-
+ } else {
+ // an array of "something"
+ t.d->subTypes << QDBusType('v');
return t;
}
+
+ // treat it as a struct
+ t.d->code = DBUS_TYPE_STRUCT;
+ foreach (const QVariant& v, list)
+ t.d->subTypes << guessFromVariant(v, mode);
+
+ return t;
}
else if (variant.type() == QVariant::Map) {
// investigate deeper
@@ -1029,12 +759,13 @@
return t;
}
else
- return QDBusType(variant.type());
+ return QDBusType( QVariant::Type( variant.userType() ) );
}
/*!
\class QDBusTypeList
\brief A list of DBus types.
+ \internal
Represents zero or more DBus types in sequence, such as those used in argument lists
or in subtypes of structs and maps.
@@ -1049,21 +780,18 @@
/*!
\fn QDBusTypeList::QDBusTypeList(const QDBusTypeList& other)
- Copy constructor.
- \param other the list to copy
- */
+ Copy constructor: copies the type list from \a other.
+*/
/*!
\fn QDBusTypeList::QDBusTypeList(const QList<QDBusType>& other)
- Copy constructor.
- \param other the list to copy
- */
+ Copy constructor: copies the type list from \a other.
+*/
/*!
- Constructs a type list by parsing the signature given.
- \param signature the signature to be parsed
- */
+ Constructs a type list by parsing the given \a signature.
+*/
QDBusTypeList::QDBusTypeList(const char* signature)
{
if (!signature || !*signature)
@@ -1085,8 +813,6 @@
/*!
\internal
Constructs a type list by parsing the elements on this iterator level.
-
- \param iter the iterator containing the elements on this level
*/
QDBusTypeList::QDBusTypeList(DBusSignatureIter* iter)
{
--- qdbustype.h DELETED ---
--- NEW FILE: qdbustype_p.h ---
/* -*- C++ -*-
*
* Copyright (C) 2005 Thiago Macieira <thiago at kde.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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:
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);
int 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;
inline bool operator!=(const QDBusType &other) const
{ return !(*this == other); }
static int qvariantType(int type);
static int 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;
QByteArray dbusSignature() const;
};
#endif // QDBUSTYPE_H
--- NEW FILE: qdbustypehelper_p.h ---
/* qdbuslisthelper_p.h Helper class to convert to and from QVariantList
*
* Copyright (C) 2005 Harald Fernengel <harry at kdevelop.org>
* Copyright (C) 2006 Trolltech AS. All rights reserved.
* Author: Thiago Macieira <thiago.macieira at 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 QDBUSTYPEHELPERPRIVATE_H
#define QDBUSTYPEHELPERPRIVATE_H
#include <QtCore/qlist.h>
#include <QtCore/qvariant.h>
#include <QtCore/qmetatype.h>
// we're going to support all D-Bus primitive types here:
// uchar -- not needed: QByteArray
// bool
// short
// ushort
// int
// uint
// qlonglong
// qulonglong
// double
// QString -- not needed: QStringList
// QList -- not possible: will use QVariant
// QVariant
// QDBusStruct -- not yet existant
// QMap -- not possible: will use QVariant
inline QDBUS_EXPORT int qDBusMetaTypeId(bool *) { return QVariant::Bool; }
inline QDBUS_EXPORT int qDBusMetaTypeId(uchar *) { return QMetaType::UChar; }
inline QDBUS_EXPORT int qDBusMetaTypeId(short *) { return QMetaType::Short; }
inline QDBUS_EXPORT int qDBusMetaTypeId(ushort *) { return QMetaType::UShort; }
inline QDBUS_EXPORT int qDBusMetaTypeId(int *) { return QVariant::Int; }
inline QDBUS_EXPORT int qDBusMetaTypeId(uint *) { return QVariant::UInt; }
inline QDBUS_EXPORT int qDBusMetaTypeId(qlonglong *) { return QVariant::LongLong; }
inline QDBUS_EXPORT int qDBusMetaTypeId(qulonglong *) { return QVariant::ULongLong; }
inline QDBUS_EXPORT int qDBusMetaTypeId(double *) { return QVariant::Double; }
inline QDBUS_EXPORT int qDBusMetaTypeId(QString *) { return QVariant::String; }
QDBUS_EXPORT int qDBusMetaTypeId(QVariant *);
QDBUS_EXPORT int qDBusMetaTypeId(QList<bool> *);
inline QDBUS_EXPORT int qDBusMetaTypeId(QByteArray *) { return QVariant::ByteArray; }
QDBUS_EXPORT int qDBusMetaTypeId(QList<short> *);
QDBUS_EXPORT int qDBusMetaTypeId(QList<ushort> *);
QDBUS_EXPORT int qDBusMetaTypeId(QList<int> *);
QDBUS_EXPORT int qDBusMetaTypeId(QList<uint> *);
QDBUS_EXPORT int qDBusMetaTypeId(QList<qlonglong> *);
QDBUS_EXPORT int qDBusMetaTypeId(QList<qulonglong> *);
QDBUS_EXPORT int qDBusMetaTypeId(QList<double> *);
inline QDBUS_EXPORT int qDBusMetaTypeId(QStringList *) { return QVariant::StringList; }
inline QDBUS_EXPORT int qDBusMetaTypeId(QVariantList *) { return QVariant::List; }
inline QDBUS_EXPORT int qDBusMetaTypeId(QVariantMap *) { return QVariant::Map; }
// implement the copy mechanism
template<class T>
struct QDBusTypeHelper
{
typedef T Type;
typedef QList<T> List;
static inline int id()
{
Type* t = 0;
return qDBusMetaTypeId(t);
}
static inline int listId()
{
List *l = 0;
return qDBusMetaTypeId(l);
}
static inline QVariant toVariant(const Type &t)
{
return QVariant(id(), &t);
}
static bool canSpecialConvert(const QVariant &);
static Type specialConvert(const QVariant &);
static inline Type fromVariant(const QVariant &v)
{
if (canSpecialConvert(v))
return specialConvert(v);
QVariant copy(v);
if (copy.convert( QVariant::Type(id()) ))
return *reinterpret_cast<const Type *>(copy.constData());
return Type();
}
static inline QVariantList toVariantList(const List &list)
{
QVariantList tmp;
foreach (const Type &t, list)
tmp.append(toVariant(t));
return tmp;
}
static inline QVariantList toVariantList(const QVariant &v)
{
return toVariantList(QDBusTypeHelper<List>::fromVariant(v));
}
static inline List fromVariantList(const QVariantList &list)
{
List tmp;
foreach (const QVariant &v, list)
tmp.append(fromVariant(v));
return tmp;
}
};
template<>
struct QDBusTypeHelper<QVariant>
{
static inline int id()
{
QVariant *t = 0;
return qDBusMetaTypeId(t);
}
static inline int listId()
{
return QVariant::List;
}
static inline QVariant toVariant(const QVariant &t)
{
return QVariant(id(), &t);
}
static inline QVariant fromVariant(const QVariant &v)
{
if (v.userType() == id())
return *reinterpret_cast<const QVariant *>(v.constData());
return v;
}
static inline QVariantList toVariantList(const QVariantList &list)
{
return list;
}
static inline QVariantList fromVariantList(const QVariantList &list)
{
return list;
}
};
#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_NO_CAST_TO_ASCII)
template<>
struct QDBusTypeHelper<char *>
{
static inline int id()
{ return QVariant::String; }
static inline QVariant toVariant(const char *t)
{ return QVariant(t); }
static inline QByteArray fromVariant(const QVariant &v)
{ return v.toString().toAscii(); }
};
template<>
struct QDBusTypeHelper<const char *>
{
static inline int id()
{ return QVariant::String; }
static inline QVariant toVariant(const char *t)
{ return QVariant(t); }
static inline QByteArray fromVariant(const QVariant &v)
{ return v.toString().toAscii(); }
};
#endif
// support three exceptions: uchar, short and ushort
// we have to do this as long as QVariant can't convert to/from the integer metatypes
template<> inline bool QDBusTypeHelper<short>::canSpecialConvert(const QVariant &v)
{ return v.userType() < int(QVariant::UserType); }
template<> inline short QDBusTypeHelper<short>::specialConvert(const QVariant &v)
{ return v.toInt(); }
template<> inline bool QDBusTypeHelper<ushort>::canSpecialConvert(const QVariant &v)
{ return v.userType() < int(QVariant::UserType); }
template<> inline ushort QDBusTypeHelper<ushort>::specialConvert(const QVariant &v)
{ return v.toUInt(); }
template<> inline bool QDBusTypeHelper<uchar>::canSpecialConvert(const QVariant &v)
{ return v.userType() < int(QVariant::UserType); }
template<> inline uchar QDBusTypeHelper<uchar>::specialConvert(const QVariant &v)
{ return v.toUInt(); }
template<typename T> inline bool QDBusTypeHelper<T>::canSpecialConvert(const QVariant &)
{ return false; }
template<typename T> inline T QDBusTypeHelper<T>::specialConvert(const QVariant &)
{ return T(); }
#endif
Index: qdbusutil.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusutil.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbusutil.cpp 6 Mar 2006 14:29:39 -0000 1.2
+++ qdbusutil.cpp 28 Mar 2006 18:56:08 -0000 1.3
@@ -28,17 +28,27 @@
#include <QtCore/qstringlist.h>
#include <QtCore/qregexp.h>
+#include "qdbustype_p.h"
+
+/*!
+ \namespace QDBusUtil
+ The QDBusUtil namespace contains a few functions that are of general use when dealing with D-Bus
+ strings.
+*/
namespace QDBusUtil
{
/*!
- Returns true if this is \p ifaceName is a valid interface name.
+ \fn QDBusUtil::isValidInterfaceName(const QString &ifaceName)
+ Returns true if this is \a ifaceName is a valid interface name.
Valid interface names must:
- - not be empty
- - not exceed 255 characters in length
- - be composed of dot-separated string components that contain only ASCII letters, digits and the
- underscore ("_") character
- - contain at least two such components
+ \list
+ \o not be empty
+ \o not exceed 255 characters in length
+ \o be composed of dot-separated string components that contain only ASCII letters, digits
+ and the underscore ("_") character
+ \o contain at least two such components
+ \endlist
*/
bool isValidInterfaceName(const QString& ifaceName)
{
@@ -57,7 +67,8 @@
}
/*!
- Returns true if \p connName is a valid unique connection name.
+ \fn QDBusUtil::isValidUniqueConnectionName(const QString &connName)
+ Returns true if \a connName is a valid unique connection name.
Unique connection names start with a colon (":") and are followed by a list of dot-separated
components composed of ASCII letters, digits, the hypen or the underscore ("_") character.
@@ -81,16 +92,19 @@
}
/*!
- Returns true if \p busName is a valid bus name.
+ \fn QDBusUtil::isValidBusName(const QString &busName)
+ Returns true if \a busName is a valid bus name.
A valid bus name is either a valid unique connection name or follows the rules:
- - is not empty
- - does not exceed 255 characters in length
- - be composed of dot-separated string components that contain only ASCII letters, digits,
- hyphens or underscores ("_"), but don't start with a digit
- - contains at least two such elements
+ \list
+ \o is not empty
+ \o does not exceed 255 characters in length
+ \o be composed of dot-separated string components that contain only ASCII letters, digits,
+ hyphens or underscores ("_"), but don't start with a digit
+ \o contains at least two such elements
+ \endlist
- \see isValidUniqueConnectionName
+ \sa isValidUniqueConnectionName()
*/
bool isValidBusName(const QString &busName)
{
@@ -113,7 +127,8 @@
}
/*!
- Returns true if \p memberName is a valid member name. A valid member name does not exceed
+ \fn QDBusUtil::isValidMemberName(const QString &memberName)
+ Returns true if \a memberName is a valid member name. A valid member name does not exceed
255 characters in length, is not empty, is composed only of ASCII letters, digits and
underscores, but does not start with a digit.
*/
@@ -127,7 +142,8 @@
}
/*!
- Returns true if \p errorName is a valid error name. Valid error names are valid interface
+ \fn QDBusUtil::isValidErrorName(const QString &errorName)
+ Returns true if \a errorName is a valid error name. Valid error names are valid interface
names and vice-versa, so this function is actually an alias for isValidInterfaceName.
*/
bool isValidErrorName(const QString &errorName)
@@ -136,14 +152,17 @@
}
/*!
- Returns true if \p path is valid object path.
+ \fn QDBusUtil::isValidObjectPath(const QString &path)
+ Returns true if \a path is valid object path.
Valid object paths follow the rules:
- - start with the slash character ("/")
- - do not end in a slash, unless the path is just the initial slash
- - do not contain any two slashes in sequence
- - contain slash-separated parts, each of which is composed of ASCII letters, digits and
- underscores ("_")
+ \list
+ \o start with the slash character ("/")
+ \o do not end in a slash, unless the path is just the initial slash
+ \o do not contain any two slashes in sequence
+ \o contain slash-separated parts, each of which is composed of ASCII letters, digits and
+ underscores ("_")
+ \endlist
*/
bool isValidObjectPath(const QString &path)
{
@@ -167,11 +186,12 @@
}
/*!
- Returns true if \p signature is a valid D-Bus type signature for one or more types.
- This function returns true if it can all of \p signature into valid, individual types and no
- characters remain in \p signature.
+ \fn QDBusUtil::isValidSignature(const QString &signature)
+ Returns true if \a signature is a valid D-Bus type signature for one or more types.
+ This function returns true if it can all of \a signature into valid, individual types and no
+ characters remain in \a signature.
- \see isValidSingleSignature
+ \sa isValidSingleSignature()
*/
bool isValidSignature(const QString &signature)
{
@@ -179,7 +199,8 @@
}
/*!
- Returns true if \p signature is a valid D-Bus type signature for exactly one full type. This
+ \fn QDBusUtil::isValidSingleSignature(const QString &signature)
+ Returns true if \a signature is a valid D-Bus type signature for exactly one full type. This
function tries to convert the type signature into a D-Bus type and, if it succeeds and no
characters remain in the signature, it returns true.
*/
@@ -188,4 +209,27 @@
return dbus_signature_validate_single(signature.toUtf8(), 0);
}
+ /*!
+ \fn QDBusUtil::signatureToType(const QString &signature)
+ Returns the Qt meta type id for the given D-Bus signature for exactly one full type, given
+ by \a signature.
+
+ \sa isValidSingleSignature(), typeToSignature(), QVariant::type(), QVariant::userType()
+ */
+ QVariant::Type signatureToType(const QString &signature)
+ {
+ return QVariant::Type( QDBusType::qvariantType(signature.toLatin1().constData()) );
+ }
+
+ /*!
+ \fn QDBusUtil::typeToSignature(QVariant::Type type)
+ Returns the D-Bus signature equivalent to the supplied meta type id \a type.
+
+ \sa isValidSingleSignature(), signatureToType(), QVariant::type(), QVariant::userType()
+ */
+ const char *typeToSignature(QVariant::Type type)
+ {
+ return QDBusType::dbusSignature( type );
+ }
+
} // namespace QDBusUtil
Index: qdbusutil.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusutil.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- qdbusutil.h 15 Feb 2006 16:25:12 -0000 1.1
+++ qdbusutil.h 28 Mar 2006 18:56:08 -0000 1.2
@@ -25,26 +25,31 @@
#define QDBUSUTIL_H
#include <QtCore/qstring.h>
+#include <QtCore/qvariant.h>
#include "qdbusmacros.h"
namespace QDBusUtil
{
- bool isValidInterfaceName(const QString &ifaceName) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidInterfaceName(const QString &ifaceName);
- bool isValidUniqueConnectionName(const QString &busName) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidUniqueConnectionName(const QString &busName);
- bool isValidBusName(const QString &busName) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidBusName(const QString &busName);
- bool isValidMemberName(const QString &memberName) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidMemberName(const QString &memberName);
- bool isValidErrorName(const QString &errorName) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidErrorName(const QString &errorName);
- bool isValidObjectPath(const QString &path) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidObjectPath(const QString &path);
- bool isValidSignature(const QString &signature) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidSignature(const QString &signature);
- bool isValidSingleSignature(const QString &signature) QDBUS_EXPORT;
+ QDBUS_EXPORT bool isValidSingleSignature(const QString &signature);
+
+ QDBUS_EXPORT QVariant::Type signatureToType(const QString &signature);
+
+ QDBUS_EXPORT const char *typeToSignature(QVariant::Type type);
}
#endif
--- qdbusvariant.h DELETED ---
Index: qdbusxmlparser.cpp
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusxmlparser.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- qdbusxmlparser.cpp 6 Mar 2006 14:29:39 -0000 1.2
+++ qdbusxmlparser.cpp 28 Mar 2006 18:56:08 -0000 1.3
@@ -26,7 +26,7 @@
#include "qdbusinterface.h"
#include "qdbusinterface_p.h"
#include "qdbusconnection_p.h"
-#include "qdbusobject_p.h"
+#include "qdbusutil.h"
#include <QtXml/qdom.h>
#include <QtCore/qmap.h>
@@ -56,14 +56,6 @@
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)
{
@@ -81,9 +73,8 @@
QDBusIntrospection::Argument argData;
if (arg.hasAttribute(QLatin1String("name")))
argData.name = arg.attribute(QLatin1String("name")); // can be empty
- argData.type = parseType(arg.attribute(QLatin1String("type")));
-
- if (!argData.type.isValid())
+ argData.type = arg.attribute(QLatin1String("type"));
+ if (!QDBusUtil::isValidSingleSignature(argData.type))
continue;
retval << argData;
@@ -93,8 +84,8 @@
}
QDBusXmlParser::QDBusXmlParser(const QString& service, const QString& path,
- const QString& xmlData, QDBusConnectionPrivate* store)
- : m_service(service), m_path(path), m_store(store)
+ const QString& xmlData)
+ : m_service(service), m_path(path)
{
QDomDocument doc;
doc.setContent(xmlData);
@@ -102,16 +93,9 @@
}
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)
+ const QDomElement& node)
+ : m_service(service), m_path(path), m_node(node)
{
- QDBusXmlParser parser(d->data->service, d->data->path, xml, d->parent);
- parser.object();
- parser.interfaces();
}
QDBusIntrospection::Interfaces
@@ -130,27 +114,8 @@
if (iface.isNull() || ifaceName.isEmpty())
continue; // for whatever reason
- QDBusIntrospection::Interface *ifaceData = 0; // make gcc shut up
- 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;
- }
-
+ QDBusIntrospection::Interface *ifaceData = new QDBusIntrospection::Interface;
+ ifaceData->name = ifaceName;
{
// save the data
QTextStream ts(&ifaceData->introspection);
@@ -214,10 +179,10 @@
// parse data
propertyData.name = propertyName;
- propertyData.type = parseType(property.attribute(QLatin1String("type")));
+ propertyData.type = property.attribute(QLatin1String("type"));
propertyData.annotations = parseAnnotations(property);
- if (!propertyData.type.isValid())
+ if (!QDBusUtil::isValidSingleSignature(propertyData.type))
// cannot be!
continue;
@@ -251,16 +216,10 @@
if (m_node.isNull())
return QSharedDataPointer<QDBusIntrospection::Object>();
- // check if the store knows about this one
QDBusIntrospection::Object* objData;
- if (m_store) {
- objData = m_store->findObject(m_service, m_path);
- }
- else {
- objData = new QDBusIntrospection::Object;
- objData->service = m_service;
- objData->path = m_path;
- }
+ 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()) {
@@ -337,7 +296,7 @@
objAbsName.append(QLatin1Char('/'));
objAbsName += objName;
- QDBusXmlParser parser(m_service, objAbsName, obj, m_store);
+ QDBusXmlParser parser(m_service, objAbsName, obj);
retval->childObjectData.insert(objName, parser.objectTree());
}
Index: qdbusxmlparser_p.h
===================================================================
RCS file: /cvs/dbus/dbus/qt/qdbusxmlparser_p.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- qdbusxmlparser_p.h 15 Feb 2006 16:25:12 -0000 1.1
+++ qdbusxmlparser_p.h 28 Mar 2006 18:56:08 -0000 1.2
@@ -28,32 +28,26 @@
#include <QtCore/qmap.h>
#include <QtXml/qdom.h>
#include "qdbusmacros.h"
-#include "qdbusintrospection.h"
-
-class QDBusConnectionPrivate;
-class QDBusObjectPrivate;
+#include "qdbusintrospection_p.h"
-/**
- * @internal
- */
+/*!
+ \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);
+ const QString& xmlData);
QDBusXmlParser(const QString& service, const QString& path,
- const QDomElement& node, QDBusConnectionPrivate* store = 0);
+ const QDomElement& node);
QDBusIntrospection::Interfaces interfaces() const;
QSharedDataPointer<QDBusIntrospection::Object> object() const;
QSharedDataPointer<QDBusIntrospection::ObjectTree> objectTree() const;
-
- static void parse(const QDBusObjectPrivate* d, const QString &xml);
};
#endif
--- NEW FILE: qt-dbus.qdocconf ---
project = QtDBus
description = QtDBus Reference Documentation
url = http://developer.kde.org/~thiago/QtDBus
indexes = $QTDIR/doc/html/qt.index
outputdir = ../doc/api/html
language = Cpp
headerdirs = .
sourcedirs = . doc
imagedirs = doc
extraimages.HTML = qt-logo \
trolltech-logo
sources.fileextensions = "*.cpp *.qdoc"
defines = Q_QDOC \
QT_.*_SUPPORT \
QT_.*_LIB \
QT_COMPAT \
QT3_SUPPORT \
Q_WS_.* \
Q_OS_.* \
Q_BYTE_ORDER \
__cplusplus
macro.key = "\\bold"
macro.menu = "\\bold"
macro.gui = "\\bold"
macro.reg.HTML = "<sup>®</sup>"
macro.raisedaster.HTML = "<sup>*</sup>"
macro.BR.HTML = "<br />"
macro.QD = "\\e{Qt Designer}"
macro.QA = "\\e{Qt Assistant}"
macro.aring.HTML = "å"
macro.Auml.HTML = "Ä"
macro.var = "\\variable"
Cpp.ignoretokens = QAXFACTORY_EXPORT \
QDESIGNER_COMPONENTS_LIBRARY \
QDESIGNER_EXTENSION_LIBRARY \
QDESIGNER_SDK_LIBRARY \
QDESIGNER_SHARED_LIBRARY \
QDESIGNER_UILIB_LIBRARY \
QM_EXPORT_CANVAS \
QM_EXPORT_DNS \
QM_EXPORT_DOM \
QM_EXPORT_FTP \
QM_EXPORT_HTTP \
QM_EXPORT_ICONVIEW \
QM_EXPORT_NETWORK \
QM_EXPORT_OPENGL \
QM_EXPORT_SQL \
QM_EXPORT_TABLE \
QM_EXPORT_WORKSPACE \
QM_EXPORT_XML \
QT_DESIGNER_STATIC \
QT_WIDGET_PLUGIN_EXPORT \
Q_COMPAT_EXPORT \
Q_CORE_EXPORT \
Q_EXPLICIT \
Q_EXPORT \
Q_EXPORT_CODECS_CN \
Q_EXPORT_CODECS_JP \
Q_EXPORT_CODECS_KR \
Q_EXPORT_PLUGIN \
Q_GFX_INLINE \
Q_GUI_EXPORT \
Q_GUI_EXPORT_STYLE_CDE \
Q_GUI_EXPORT_STYLE_COMPACT \
Q_GUI_EXPORT_STYLE_MAC \
Q_GUI_EXPORT_STYLE_MOTIF \
Q_GUI_EXPORT_STYLE_MOTIFPLUS \
Q_GUI_EXPORT_STYLE_PLATINUM \
Q_GUI_EXPORT_STYLE_POCKETPC \
Q_GUI_EXPORT_STYLE_SGI \
Q_GUI_EXPORT_STYLE_WINDOWS \
Q_GUI_EXPORT_STYLE_WINDOWSXP \
Q_INLINE_TEMPLATE \
Q_NETWORK_EXPORT \
Q_OPENGL_EXPORT \
Q_OUTOFLINE_TEMPLATE \
Q_SQL_EXPORT \
Q_SVG_EXPORT \
Q_TESTLIB_EXPORT \
Q_TYPENAME \
Q_XML_EXPORT \
QDBUS_EXPORT \
Q_ASYNC
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
Q_DECLARE_OPERATORS_FOR_FLAGS \
Q_DECLARE_PRIVATE \
Q_DECLARE_PUBLIC \
Q_DECLARE_SHARED \
Q_DECLARE_TR_FUNCTIONS \
Q_DECLARE_TYPEINFO \
Q_DISABLE_COPY \
Q_DUMMY_COMPARISON_OPERATOR \
Q_ENUMS \
Q_FLAGS \
Q_INTERFACES \
__attribute__
HTML.style = "h3.fn,span.fn { margin-left: 1cm; text-indent: -1cm; }\n" \
"a:link { color: #004faf; text-decoration: none }\n" \
"a:visited { color: #672967; text-decoration: none }\n" \
"td.postheader { font-family: sans-serif }\n" \
"tr.address { font-family: sans-serif }\n" \
"body { background: #ffffff; color: black; }\n" \
"pre { background: #dddddd; }"
HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \
"<tr>\n" \
"<td align=\"left\" valign=\"top\" width=\"32\">" \
"<img src=\"images/qt-logo.png\" align=\"left\" width=\"32\" height=\"32\" border=\"0\" />" \
"</td>\n" \
"<td width=\"1\"> </td>" \
"<td class=\"postheader\" valign=\"center\">" \
"<a href=\"index.html\">" \
"<font color=\"#004faf\">Home</font></a> ·" \
" <a href=\"classes.html\">" \
"<font color=\"#004faf\">Classes</font></a> ·" \
" <a href=\"namespaces.html\">" \
"<font color=\"#004faf\">Namespaces</font></a>" \
"</td>\n" \
"<td align=\"right\" valign=\"top\" width=\"230\"><img src=\"images/trolltech-logo.png\" align=\"right\" width=\"203\" height=\"32\" border=\"0\" /></td></tr></table>"
HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
"<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
"<td width=\"30%\">Copyright © 2006 <a href=\"trolltech.html\">Trolltech</a></td>\n" \
"<td width=\"40%\" align=\"center\"> </td>\n" \
"<td width=\"30%\" align=\"right\"><div align=\"right\">QtDBus \\version</div></td>\n" \
"</tr></table></div></address>"
More information about the dbus-commit
mailing list