You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
997 lines
34 KiB
997 lines
34 KiB
diff -ur libdbus-1-qt3-0.8.1/qdbusintegrator.cpp ../dbus-qt4-qt3backport/qdbusintegrator.cpp
|
|
--- libdbus-1-qt3-0.8.1/qdbusintegrator.cpp 2007-12-17 12:34:08.000000000 +0100
|
|
+++ ../dbus-qt4-qt3backport/qdbusintegrator.cpp 2008-03-13 10:28:54.000000000 +0100
|
|
@@ -121,7 +121,7 @@
|
|
QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
|
|
|
|
int flags = dbus_watch_get_flags(watch);
|
|
- int fd = dbus_watch_get_fd(watch);
|
|
+ int fd = dbus_watch_get_unix_fd(watch);
|
|
|
|
QDBusConnectionPrivate::Watcher watcher;
|
|
if (flags & DBUS_WATCH_READABLE) {
|
|
@@ -163,7 +163,7 @@
|
|
//qDebug("remove watch");
|
|
|
|
QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
|
|
- int fd = dbus_watch_get_fd(watch);
|
|
+ int fd = dbus_watch_get_unix_fd(watch);
|
|
|
|
QDBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd);
|
|
if (it != d->watchers.end())
|
|
@@ -205,7 +205,7 @@
|
|
//qDebug("toggle watch");
|
|
|
|
QDBusConnectionPrivate *d = static_cast<QDBusConnectionPrivate *>(data);
|
|
- int fd = dbus_watch_get_fd(watch);
|
|
+ int fd = dbus_watch_get_unix_fd(watch);
|
|
|
|
QDBusConnectionPrivate::WatcherHash::iterator it = d->watchers.find(fd);
|
|
if (it != d->watchers.end()) {
|
|
@@ -218,7 +218,7 @@
|
|
int flags = dbus_watch_get_flags(watch);
|
|
|
|
// qDebug("toggle watch %d to %d (write: %d, read: %d)",
|
|
-// dbus_watch_get_fd(watch), enabled,
|
|
+// dbus_watch_get_unix_fd(watch), enabled,
|
|
// flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE);
|
|
|
|
if (flags & DBUS_WATCH_READABLE && (*wit).read)
|
|
diff -ur libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/classgen.cpp ../dbus-qt4-qt3backport/tools/dbusxml2qt3/classgen.cpp
|
|
--- libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/classgen.cpp 2007-12-17 12:34:08.000000000 +0100
|
|
+++ ../dbus-qt4-qt3backport/tools/dbusxml2qt3/classgen.cpp 2008-03-13 10:28:54.000000000 +0100
|
|
@@ -38,6 +38,11 @@
|
|
insert(key, true);
|
|
}
|
|
|
|
+ void removeString(const QString& key)
|
|
+ {
|
|
+ erase(key);
|
|
+ }
|
|
+
|
|
void insertStringList(const QStringList& list)
|
|
{
|
|
QStringList::const_iterator it = list.begin();
|
|
@@ -194,6 +199,14 @@
|
|
forwards.insertString("class QDomElement");
|
|
if (!classData.signals.isEmpty())
|
|
forwards.insertString("class QString");
|
|
+ if (!classData.asyncMethods.isEmpty())
|
|
+ {
|
|
+ includes["Qt"].insertString("<qmap.h>");
|
|
+ forwards.erase("template <typename K, typename V> class QMap");
|
|
+
|
|
+ includes["qdbus"].insertString("<dbus/qdbusmessage.h>");
|
|
+ forwards.erase("class QDBusMessage");
|
|
+ }
|
|
break;
|
|
|
|
case Class::Proxy:
|
|
@@ -205,6 +218,11 @@
|
|
forwards.insertString("class QString");
|
|
if (!classData.properties.isEmpty())
|
|
forwards.insertString("class QDBusVariant");
|
|
+ if (!classData.asyncMethods.isEmpty())
|
|
+ {
|
|
+ includes["Qt"].insertString("<qmap.h>");
|
|
+ forwards.erase("template <typename K, typename V> class QMap");
|
|
+ }
|
|
break;
|
|
|
|
case Class::Node:
|
|
@@ -345,7 +363,7 @@
|
|
stream << "#include \"" << (*it).name.lower() << ".h\"" << endl;
|
|
}
|
|
|
|
- stream << "#include \"introspectable.h\"" << endl;
|
|
+ stream << "#include \"introspectableinterface.h\"" << endl;
|
|
|
|
stream << endl;
|
|
}
|
|
@@ -442,7 +460,30 @@
|
|
static void writeMethodDeclarations(const Class& classData, Class::Role role,
|
|
QTextStream& stream)
|
|
{
|
|
- if (!classData.methods.isEmpty())
|
|
+ if (role == Class::Interface && !classData.asyncReplyMethods.isEmpty())
|
|
+ {
|
|
+ stream << "public:" << endl;
|
|
+
|
|
+ QValueList<Method>::const_iterator it =
|
|
+ classData.asyncReplyMethods.begin();
|
|
+ QValueList<Method>::const_iterator endIt =
|
|
+ classData.asyncReplyMethods.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
+ Method method = *it;
|
|
+ method.name += "AsyncReply";
|
|
+
|
|
+ stream << " virtual void ";
|
|
+ MethodGenerator::writeMethodDeclaration(method, false, false, stream);
|
|
+
|
|
+ stream << " virtual void " << (*it).name
|
|
+ << "AsyncError(int asyncCallId, const QDBusError& error);"
|
|
+ << endl;
|
|
+ stream << endl;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty())
|
|
{
|
|
bool pureVirtual = true;
|
|
switch (role)
|
|
@@ -465,9 +506,35 @@
|
|
QValueList<Method>::const_iterator endIt = classData.methods.end();
|
|
for (; it != endIt; ++it)
|
|
{
|
|
+ if ((*it).async) continue;
|
|
+
|
|
stream << " virtual bool ";
|
|
MethodGenerator::writeMethodDeclaration(*it, pureVirtual, true, stream);
|
|
}
|
|
+
|
|
+ it = classData.asyncMethods.begin();
|
|
+ endIt = classData.asyncMethods.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
+ Method method = *it;
|
|
+ method.name += "Async";
|
|
+
|
|
+ switch (role)
|
|
+ {
|
|
+ case Class::Interface:
|
|
+ stream << " virtual void ";
|
|
+ MethodGenerator::writeMethodDeclaration(method, pureVirtual, false, stream);
|
|
+ break;
|
|
+
|
|
+ case Class::Proxy:
|
|
+ stream << " virtual bool ";
|
|
+ MethodGenerator::writeMethodDeclaration(method, pureVirtual, true, stream);
|
|
+ break;
|
|
+
|
|
+ case Class::Node: // no async methods
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
if (!classData.properties.isEmpty())
|
|
@@ -511,7 +578,7 @@
|
|
switch (role)
|
|
{
|
|
case Class::Interface:
|
|
- if (!classData.methods.isEmpty())
|
|
+ if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty())
|
|
{
|
|
stream << "protected: // implement sending replies" << endl;
|
|
stream << " virtual void handleMethodReply(const QDBusMessage& reply) = 0;" << endl;
|
|
@@ -527,15 +594,35 @@
|
|
break;
|
|
|
|
case Class::Proxy:
|
|
+ {
|
|
if (!classData.signals.isEmpty())
|
|
{
|
|
stream << "protected slots: // usually no need to reimplement" << endl;
|
|
stream << " virtual void slotHandleDBusSignal(const QDBusMessage& message);" << endl;
|
|
stream << endl;
|
|
}
|
|
+
|
|
+ if (!classData.asyncReplySignals.isEmpty())
|
|
+ {
|
|
+ if (classData.signals.isEmpty())
|
|
+ {
|
|
+ stream << "protected slots: // usually no need to reimplement" << endl;
|
|
+ }
|
|
+ stream << " virtual void slotHandleAsyncReply(int id, const QDBusMessage& message);" << endl;
|
|
+ stream << endl;
|
|
+ }
|
|
+
|
|
stream << "protected:" << endl;
|
|
stream << " QDBusProxy* m_baseProxy;" << endl;
|
|
+
|
|
+ if (!classData.asyncMethods.isEmpty())
|
|
+ {
|
|
+ stream << endl;
|
|
+ stream << " QMap<int, QString> m_asyncCalls;" << endl;
|
|
+ }
|
|
+
|
|
break;
|
|
+ }
|
|
|
|
case Class::Node: // not variable methods
|
|
break;
|
|
@@ -547,7 +634,8 @@
|
|
static void writeSignalDeclarations(const Class& classData, Class::Role role,
|
|
QTextStream& stream)
|
|
{
|
|
- if (classData.signals.isEmpty()) return;
|
|
+ if (classData.signals.isEmpty() && classData.asyncReplySignals.isEmpty())
|
|
+ return;
|
|
|
|
QString prefix;
|
|
switch (role)
|
|
@@ -578,6 +666,18 @@
|
|
MethodGenerator::writeMethodDeclaration(*it, false, false, stream);
|
|
}
|
|
|
|
+ it = classData.asyncReplySignals.begin();
|
|
+ endIt = classData.asyncReplySignals.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
+ stream << prefix;
|
|
+
|
|
+ Method signal = *it;
|
|
+ signal.name += "AsyncReply";
|
|
+
|
|
+ MethodGenerator::writeMethodDeclaration(signal, false, false, stream);
|
|
+ }
|
|
+
|
|
stream << endl;
|
|
}
|
|
|
|
@@ -598,8 +698,6 @@
|
|
static void writeMethodCallDeclarations(const Class& classData,
|
|
QTextStream& stream)
|
|
{
|
|
- if (classData.methods.isEmpty()) return;
|
|
-
|
|
QValueList<Method>::const_iterator it = classData.methods.begin();
|
|
QValueList<Method>::const_iterator endIt = classData.methods.end();
|
|
for (; it != endIt; ++it)
|
|
@@ -607,6 +705,26 @@
|
|
stream << " ";
|
|
MethodGenerator::writeMethodCallDeclaration(*it, stream);
|
|
}
|
|
+
|
|
+ if (!classData.asyncReplyMethods.isEmpty())
|
|
+ {
|
|
+ stream << "protected:" << endl;
|
|
+ stream << " QMap<int, QDBusMessage> m_asyncCalls;" << endl;
|
|
+ stream << endl;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void writeInterfaceAsyncReplyHandlers(const Class& classData,
|
|
+ QTextStream& stream)
|
|
+{
|
|
+ if (classData.asyncReplyMethods.isEmpty()) return;
|
|
+
|
|
+ QValueList<Method>::const_iterator it = classData.asyncReplyMethods.begin();
|
|
+ QValueList<Method>::const_iterator endIt = classData.asyncReplyMethods.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
+ MethodGenerator::writeInterfaceAsyncReplyHandler(classData, *it, stream);
|
|
+ }
|
|
}
|
|
|
|
static void writeMethodCalls(const Class& classData, QTextStream& stream)
|
|
@@ -615,6 +733,15 @@
|
|
QValueList<Method>::const_iterator endIt = classData.methods.end();
|
|
for (; it != endIt; ++it)
|
|
{
|
|
+ if ((*it).async) continue;
|
|
+
|
|
+ MethodGenerator::writeMethodCall(classData, *it, stream);
|
|
+ }
|
|
+
|
|
+ it = classData.asyncMethods.begin();
|
|
+ endIt = classData.asyncMethods.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
MethodGenerator::writeMethodCall(classData, *it, stream);
|
|
}
|
|
}
|
|
@@ -625,6 +752,15 @@
|
|
QValueList<Method>::const_iterator endIt = classData.methods.end();
|
|
for (; it != endIt; ++it)
|
|
{
|
|
+ if ((*it).async) continue;
|
|
+
|
|
+ MethodGenerator::writeProxyMethod(classData.name, *it, stream);
|
|
+ }
|
|
+
|
|
+ it = classData.asyncMethods.begin();
|
|
+ endIt = classData.asyncMethods.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
MethodGenerator::writeProxyMethod(classData.name, *it, stream);
|
|
}
|
|
}
|
|
@@ -643,6 +779,121 @@
|
|
}
|
|
}
|
|
|
|
+static void splitAsyncProxyMethods(Class& classData)
|
|
+{
|
|
+ // create the async identifier
|
|
+ Argument idArgMethod;
|
|
+ idArgMethod.name = "asyncCallId";
|
|
+ idArgMethod.signature = "int";
|
|
+ idArgMethod.isPrimitive = true;
|
|
+ idArgMethod.direction = Argument::Out;
|
|
+
|
|
+ Argument idArgSignal = idArgMethod;
|
|
+ idArgSignal.direction = Argument::In;
|
|
+
|
|
+ QValueList<Method>::iterator it = classData.methods.begin();
|
|
+ QValueList<Method>::iterator endIt = classData.methods.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
+ if (!(*it).async) continue;
|
|
+
|
|
+ Method method = *it;
|
|
+
|
|
+ QValueList<Argument> methodArgs;
|
|
+ QValueList<Argument> signalArgs;
|
|
+
|
|
+ // add id argument
|
|
+ methodArgs << idArgMethod;
|
|
+ signalArgs << idArgSignal;
|
|
+
|
|
+ // split in/out arguments: "in" belong to the method, "out" to the new signal
|
|
+ QValueList<Argument>::const_iterator argIt = method.arguments.begin();
|
|
+ QValueList<Argument>::const_iterator argEndIt = method.arguments.end();
|
|
+ for (; argIt != argEndIt; ++argIt)
|
|
+ {
|
|
+ if ((*argIt).direction == Argument::Out)
|
|
+ {
|
|
+ // signal parameters are "out" but have "in" signature,
|
|
+ // e.g. "const T&"
|
|
+ Argument arg = *argIt;
|
|
+ arg.direction = Argument::In;
|
|
+
|
|
+ signalArgs << arg;
|
|
+ }
|
|
+ else
|
|
+ methodArgs << *argIt;
|
|
+ }
|
|
+
|
|
+ // change method
|
|
+ method.arguments = methodArgs;
|
|
+
|
|
+ classData.asyncMethods << method;
|
|
+
|
|
+ // create "callback" signal
|
|
+ Method signal = method;
|
|
+ signal.arguments = signalArgs;
|
|
+
|
|
+ classData.asyncReplySignals << signal;
|
|
+ }
|
|
+}
|
|
+
|
|
+static void splitAsyncInterfaceMethods(Class& classData)
|
|
+{
|
|
+ // create the async identifier
|
|
+ Argument idArgMethod;
|
|
+ idArgMethod.name = "asyncCallId";
|
|
+ idArgMethod.signature = "int";
|
|
+ idArgMethod.isPrimitive = true;
|
|
+ idArgMethod.direction = Argument::In;
|
|
+
|
|
+ Argument idArgReply = idArgMethod;
|
|
+
|
|
+ QValueList<Method>::iterator it = classData.methods.begin();
|
|
+ QValueList<Method>::iterator endIt = classData.methods.end();
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
+ if (!(*it).async) continue;
|
|
+
|
|
+ Method method = *it;
|
|
+
|
|
+ QValueList<Argument> methodArgs;
|
|
+ QValueList<Argument> replyArgs;
|
|
+
|
|
+ // add id argument
|
|
+ methodArgs << idArgMethod;
|
|
+ replyArgs << idArgReply;
|
|
+
|
|
+ // split in/out arguments: "in" belong to the call, "out" to the reply
|
|
+ QValueList<Argument>::const_iterator argIt = method.arguments.begin();
|
|
+ QValueList<Argument>::const_iterator argEndIt = method.arguments.end();
|
|
+ for (; argIt != argEndIt; ++argIt)
|
|
+ {
|
|
+ if ((*argIt).direction == Argument::Out)
|
|
+ {
|
|
+ // reply parameters are "out" for the service but "in" for
|
|
+ // the reply handler
|
|
+ Argument arg = *argIt;
|
|
+ arg.direction = Argument::In;
|
|
+
|
|
+ replyArgs << arg;
|
|
+ }
|
|
+ else
|
|
+ methodArgs << *argIt;
|
|
+ }
|
|
+
|
|
+ // change method
|
|
+ method.arguments = methodArgs;
|
|
+
|
|
+ classData.asyncMethods << method;
|
|
+
|
|
+ // create reply handler
|
|
+ Method reply = method;
|
|
+ reply.arguments = replyArgs;
|
|
+
|
|
+ classData.asyncReplyMethods << reply;
|
|
+ }
|
|
+}
|
|
+
|
|
bool ClassGenerator::initStreams(const QString& baseName,
|
|
QTextStream& headerStream,
|
|
QTextStream& sourceStream)
|
|
@@ -680,7 +931,6 @@
|
|
{
|
|
closeIncludeGuard(baseName, headerStream);
|
|
writeFileFooter(headerStream);
|
|
-
|
|
writeFileFooter(sourceStream);
|
|
|
|
QIODevice* device = headerStream.device();
|
|
@@ -717,33 +967,36 @@
|
|
QTextStream& headerStream,
|
|
QTextStream& sourceStream)
|
|
{
|
|
+ Class classDataCopy = classData;
|
|
+ splitAsyncInterfaceMethods(classDataCopy);
|
|
+
|
|
// create header
|
|
- writeHeaderIncludes(classData, Class::Interface, headerStream);
|
|
+ writeHeaderIncludes(classDataCopy, Class::Interface, headerStream);
|
|
|
|
- openNamespaces(classData.namespaces, headerStream);
|
|
- openClassDeclaration(classData, Class::Interface, headerStream);
|
|
+ openNamespaces(classDataCopy.namespaces, headerStream);
|
|
+ openClassDeclaration(classDataCopy, Class::Interface, headerStream);
|
|
|
|
- writeSignalDeclarations(classData, Class::Interface, headerStream);
|
|
- writeMethodDeclarations(classData, Class::Interface, headerStream);
|
|
- writeMethodCallDeclarations(classData, headerStream);
|
|
+ writeSignalDeclarations(classDataCopy, Class::Interface, headerStream);
|
|
+ writeMethodDeclarations(classDataCopy, Class::Interface, headerStream);
|
|
+ writeMethodCallDeclarations(classDataCopy, headerStream);
|
|
|
|
- closeClassDeclaration(classData, Class::Interface, headerStream);
|
|
- closeNamespaces(classData.namespaces, headerStream);
|
|
+ closeClassDeclaration(classDataCopy, Class::Interface, headerStream);
|
|
+ closeNamespaces(classDataCopy.namespaces, headerStream);
|
|
|
|
// create source
|
|
- writeSourceIncludes(classData, Class::Interface, sourceStream);
|
|
-
|
|
- openNamespaces(classData.namespaces, sourceStream);
|
|
+ writeSourceIncludes(classDataCopy, Class::Interface, sourceStream);
|
|
|
|
- MethodGenerator::writeIntrospectionDataMethod(classData, sourceStream);
|
|
+ openNamespaces(classDataCopy.namespaces, sourceStream);
|
|
|
|
- writeSignalEmitters(classData, sourceStream);
|
|
+ MethodGenerator::writeIntrospectionDataMethod(classDataCopy, sourceStream);
|
|
|
|
- writeMethodCalls(classData, sourceStream);
|
|
+ writeSignalEmitters(classDataCopy, sourceStream);
|
|
+ writeInterfaceAsyncReplyHandlers(classDataCopy, sourceStream);
|
|
+ writeMethodCalls(classDataCopy, sourceStream);
|
|
|
|
- MethodGenerator::writeInterfaceMainMethod(classData, sourceStream);
|
|
+ MethodGenerator::writeInterfaceMainMethod(classDataCopy, sourceStream);
|
|
|
|
- closeNamespaces(classData.namespaces, sourceStream);
|
|
+ closeNamespaces(classDataCopy.namespaces, sourceStream);
|
|
|
|
return true;
|
|
}
|
|
@@ -752,33 +1005,39 @@
|
|
QTextStream& headerStream,
|
|
QTextStream& sourceStream)
|
|
{
|
|
+ Class classDataCopy = classData;
|
|
+ splitAsyncProxyMethods(classDataCopy);
|
|
+
|
|
// create header
|
|
- writeHeaderIncludes(classData, Class::Proxy, headerStream);
|
|
+ writeHeaderIncludes(classDataCopy, Class::Proxy, headerStream);
|
|
|
|
- openNamespaces(classData.namespaces, headerStream);
|
|
- openClassDeclaration(classData, Class::Proxy, headerStream);
|
|
+ openNamespaces(classDataCopy.namespaces, headerStream);
|
|
+ openClassDeclaration(classDataCopy, Class::Proxy, headerStream);
|
|
|
|
- writeSignalDeclarations(classData, Class::Proxy, headerStream);
|
|
- writeMethodDeclarations(classData, Class::Proxy, headerStream);
|
|
+ writeSignalDeclarations(classDataCopy, Class::Proxy, headerStream);
|
|
+ writeMethodDeclarations(classDataCopy, Class::Proxy, headerStream);
|
|
|
|
- closeClassDeclaration(classData, Class::Proxy, headerStream);
|
|
- closeNamespaces(classData.namespaces, headerStream);
|
|
+ closeClassDeclaration(classDataCopy, Class::Proxy, headerStream);
|
|
+ closeNamespaces(classDataCopy.namespaces, headerStream);
|
|
|
|
// create source
|
|
- writeSourceIncludes(classData, Class::Proxy, sourceStream);
|
|
+ writeSourceIncludes(classDataCopy, Class::Proxy, sourceStream);
|
|
|
|
- openNamespaces(classData.namespaces, sourceStream);
|
|
+ openNamespaces(classDataCopy.namespaces, sourceStream);
|
|
|
|
- MethodGenerator::writeProxyBegin(classData, sourceStream);
|
|
+ MethodGenerator::writeProxyBegin(classDataCopy, sourceStream);
|
|
|
|
- writeProxyMethods(classData, sourceStream);
|
|
+ writeProxyMethods(classDataCopy, sourceStream);
|
|
|
|
- writeProxyProperties(classData, sourceStream);
|
|
+ writeProxyProperties(classDataCopy, sourceStream);
|
|
|
|
- if (!classData.signals.isEmpty())
|
|
- MethodGenerator::writeSignalHandler(classData, sourceStream);
|
|
+ if (!classDataCopy.signals.isEmpty())
|
|
+ MethodGenerator::writeSignalHandler(classDataCopy, sourceStream);
|
|
|
|
- closeNamespaces(classData.namespaces, sourceStream);
|
|
+ if (!classDataCopy.asyncReplySignals.isEmpty())
|
|
+ MethodGenerator::writeProxyAsyncReplyHandler(classDataCopy, sourceStream);
|
|
+
|
|
+ closeNamespaces(classDataCopy.namespaces, sourceStream);
|
|
|
|
return true;
|
|
}
|
|
@@ -796,7 +1055,6 @@
|
|
|
|
closeClassDeclaration(classData, Class::Node, headerStream);
|
|
closeNamespaces(classData.namespaces, headerStream);
|
|
- closeIncludeGuard(classData.name, headerStream);
|
|
|
|
// create source
|
|
writeSourceIncludes(classData, Class::Node, sourceStream);
|
|
diff -ur libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/main.cpp ../dbus-qt4-qt3backport/tools/dbusxml2qt3/main.cpp
|
|
--- libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/main.cpp 2007-12-17 12:34:08.000000000 +0100
|
|
+++ ../dbus-qt4-qt3backport/tools/dbusxml2qt3/main.cpp 2008-03-13 10:28:54.000000000 +0100
|
|
@@ -153,12 +153,16 @@
|
|
exit(3);
|
|
}
|
|
|
|
- QStringList nameParts = QStringList::split("::", options["classname"]);
|
|
+ // class name for node is handled differently later on
|
|
+ if (!generateNode)
|
|
+ {
|
|
+ QStringList nameParts = QStringList::split("::", options["classname"]);
|
|
|
|
- interfaces[0].name = nameParts.back();
|
|
+ interfaces[0].name = nameParts.back();
|
|
|
|
- nameParts.pop_back();
|
|
- interfaces[0].namespaces = nameParts;
|
|
+ nameParts.pop_back();
|
|
+ interfaces[0].namespaces = nameParts;
|
|
+ }
|
|
}
|
|
|
|
if (checkForOption(options, "namespace"))
|
|
@@ -284,6 +288,7 @@
|
|
Method method;
|
|
method.name = "Introspect";
|
|
method.noReply = false;
|
|
+ method.async = false;
|
|
|
|
Argument argument;
|
|
argument.name = "data";
|
|
diff -ur libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/methodgen.cpp ../dbus-qt4-qt3backport/tools/dbusxml2qt3/methodgen.cpp
|
|
--- libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/methodgen.cpp 2007-12-17 12:34:08.000000000 +0100
|
|
+++ ../dbus-qt4-qt3backport/tools/dbusxml2qt3/methodgen.cpp 2008-03-13 10:28:54.000000000 +0100
|
|
@@ -279,6 +279,24 @@
|
|
return annotations;
|
|
}
|
|
|
|
+static bool hasAnnotation(const QDomElement& element, const QString& annotation, QString* value = 0)
|
|
+{
|
|
+ for (QDomNode node = element.firstChild(); !node.isNull();
|
|
+ node = node.nextSibling())
|
|
+ {
|
|
+ if (!node.isElement()) continue;
|
|
+
|
|
+ QDomElement childElement = node.toElement();
|
|
+ if (childElement.tagName() != "annotation") continue;
|
|
+ if (childElement.attribute("name") != annotation) continue;
|
|
+
|
|
+ if (value != 0) *value = childElement.attribute("value");
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
static QValueList<Argument> extractArguments(const QDomElement& methodElement,
|
|
Class& classData)
|
|
{
|
|
@@ -568,9 +586,13 @@
|
|
method.name = element.attribute("name");
|
|
method.arguments = extractArguments(element, classData);
|
|
method.noReply = false;
|
|
+ method.async = false;
|
|
|
|
if (element.tagName() == "method")
|
|
+ {
|
|
+ method.async = hasAnnotation(element, "org.freedesktop.DBus.GLib.Async");
|
|
classData.methods.append(method);
|
|
+ }
|
|
else
|
|
classData.signals.append(method);
|
|
}
|
|
@@ -689,36 +711,85 @@
|
|
void MethodGenerator::writeMethodCallDeclaration(const Method& method,
|
|
QTextStream& stream)
|
|
{
|
|
- stream << "QDBusMessage call" << method.name
|
|
- << "(const QDBusMessage& mesage);" << endl;
|
|
+ if (method.async)
|
|
+ stream << "void call" << method.name << "Async";
|
|
+ else
|
|
+ stream << "QDBusMessage call" << method.name;
|
|
+
|
|
+ stream << "(const QDBusMessage& message);" << endl;
|
|
stream << endl;
|
|
}
|
|
|
|
void MethodGenerator::writeMethodCall(const Class& classData,
|
|
const Method& method, QTextStream& stream)
|
|
{
|
|
- stream << "QDBusMessage " << classData.name << "::call" << method.name
|
|
- << "(const QDBusMessage& message)" << endl;;
|
|
+ if (method.async)
|
|
+ stream << "void " << classData.name << "::call" << method.name << "Async";
|
|
+ else
|
|
+ stream << "QDBusMessage " << classData.name << "::call" << method.name;
|
|
+
|
|
+ stream << "(const QDBusMessage& message)" << endl;
|
|
|
|
stream << "{" << endl;
|
|
- stream << " QDBusError error;" << endl;
|
|
- stream << " QDBusMessage reply;" << endl;
|
|
- stream << endl;
|
|
|
|
- writeVariables(" ", method, stream);
|
|
+ if (method.async)
|
|
+ {
|
|
+ // FIXME: using writeVariables by removing asyncCallId argument
|
|
+ Method reducedMethod = method;
|
|
+ reducedMethod.arguments.pop_front();
|
|
+
|
|
+ writeVariables(" ", reducedMethod, stream);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ stream << " QDBusError error;" << endl;
|
|
+ stream << " QDBusMessage reply;" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ writeVariables(" ", method, stream);
|
|
+ }
|
|
|
|
stream << endl;
|
|
- stream << " if (" << method.name << "(";
|
|
+
|
|
+ if (method.async)
|
|
+ {
|
|
+ stream << " int _asyncCallId = 0;" << endl;
|
|
+ stream << " while (m_asyncCalls.find(_asyncCallId) != m_asyncCalls.end())"
|
|
+ << endl;
|
|
+ stream << " {" << endl;
|
|
+ stream << " ++_asyncCallId;" << endl;
|
|
+ stream << " }" << endl;
|
|
+ stream << " m_asyncCalls.insert(_asyncCallId, message);" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " " << method.name << "Async(";
|
|
+ }
|
|
+ else
|
|
+ stream << " if (" << method.name << "(";
|
|
|
|
QValueList<Argument>::const_iterator it = method.arguments.begin();
|
|
QValueList<Argument>::const_iterator endIt = method.arguments.end();
|
|
- for (; it != endIt; ++it)
|
|
+ while (it != endIt)
|
|
{
|
|
- stream << "_" << (*it).name << ", ";
|
|
+ stream << "_" << (*it).name;
|
|
+
|
|
+ ++it;
|
|
+ if (it != endIt) stream << ", ";
|
|
}
|
|
|
|
- stream << "error))" << endl;
|
|
+ if (method.async)
|
|
+ {
|
|
+ stream << ");" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " return;" << endl;
|
|
+ stream << "}" << endl;
|
|
+ stream << endl;
|
|
+ return;
|
|
+ }
|
|
|
|
+ if (method.arguments.count() > 0) stream << ", ";
|
|
+ stream << "error))" << endl;
|
|
|
|
stream << " {" << endl;
|
|
stream << " reply = QDBusMessage::methodReply(message);" << endl;
|
|
@@ -878,6 +949,102 @@
|
|
stream << endl;
|
|
}
|
|
|
|
+
|
|
+void MethodGenerator::writeInterfaceAsyncReplyHandler(const Class& classData,
|
|
+ const Method& method, QTextStream& stream)
|
|
+{
|
|
+ stream << "void " << classData.name << "::" << method.name
|
|
+ << "AsyncReply(";
|
|
+
|
|
+ QValueList<Argument>::const_iterator it = method.arguments.begin();
|
|
+ QValueList<Argument>::const_iterator endIt = method.arguments.end();
|
|
+ while (it != endIt)
|
|
+ {
|
|
+ if (!(*it).isPrimitive && (*it).direction == Argument::In)
|
|
+ stream << "const ";
|
|
+
|
|
+ stream << (*it).signature;
|
|
+
|
|
+ if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&";
|
|
+
|
|
+ stream << " " << (*it).name;
|
|
+
|
|
+ ++it;
|
|
+ if (it != endIt) stream << ", ";
|
|
+ }
|
|
+ stream << ")" << endl;
|
|
+ stream << endl;
|
|
+ stream << "{" << endl;
|
|
+
|
|
+ stream << " QMap<int, QDBusMessage>::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl;
|
|
+ stream << " if (findIt == m_asyncCalls.end()) return;" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " QDBusMessage call = findIt.data();" << endl;
|
|
+ stream << " m_asyncCalls.erase(findIt);" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " QDBusMessage reply = QDBusMessage::methodReply(call);"
|
|
+ << endl;
|
|
+
|
|
+ it = method.arguments.begin();
|
|
+ for (++it; it != endIt; ++it) // skip asyncCallId at beginning
|
|
+ {
|
|
+ if (!(*it).annotatedType.isEmpty())
|
|
+ {
|
|
+ stream << " QDBusData " << (*it).name << "Data;" << endl;
|
|
+
|
|
+ // TODO error handling
|
|
+ stream << " if (QDBusDataConverter::convertToQDBusData<"
|
|
+ << (*it).annotatedType << ">(" << (*it).name << ", "
|
|
+ << (*it).name << "Data"
|
|
+ << ") != QDBusDataConverter::Success) return false;"
|
|
+ << endl;
|
|
+ stream << " reply << " << (*it).name << "Data;" << endl;
|
|
+ }
|
|
+ else if (!(*it).accessor.isEmpty())
|
|
+ {
|
|
+ stream << " reply << QDBusData::from" << (*it).accessor << "(";
|
|
+
|
|
+ if ((*it).subAccessor.isEmpty())
|
|
+ stream << (*it).name;
|
|
+ else
|
|
+ stream << (*it).containerClass << "(" << (*it).name << ")";
|
|
+
|
|
+ stream << ");" << endl;
|
|
+ }
|
|
+ else
|
|
+ stream << " reply << " << (*it).name << ";" << endl;
|
|
+ }
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " handleMethodReply(reply);" << endl;
|
|
+
|
|
+ stream << "}" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << "void " << classData.name << "::" << method.name
|
|
+ << "AsyncError(int asyncCallId, const QDBusError& error)";
|
|
+ stream << endl;
|
|
+
|
|
+ stream << "{" << endl;
|
|
+
|
|
+ stream << " QMap<int, QDBusMessage>::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl;
|
|
+ stream << " if (findIt == m_asyncCalls.end()) return;" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " QDBusMessage call = findIt.data();" << endl;
|
|
+ stream << " m_asyncCalls.erase(findIt);" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " QDBusMessage reply = QDBusMessage::methodError(call, error);"
|
|
+ << endl;
|
|
+ stream << " handleMethodReply(reply);" << endl;
|
|
+
|
|
+ stream << "}" << endl;
|
|
+ stream << endl;
|
|
+}
|
|
+
|
|
void MethodGenerator::writeInterfaceMainMethod(const Class& classData,
|
|
QTextStream& stream)
|
|
{
|
|
@@ -897,10 +1064,19 @@
|
|
{
|
|
stream << " if (message.member() == \"" << (*it).name << "\")" << endl;
|
|
stream << " {" << endl;
|
|
- stream << " QDBusMessage reply = call" << (*it).name << "(message);"
|
|
- << endl;
|
|
- stream << " handleMethodReply(reply);" << endl;
|
|
- stream << endl;
|
|
+
|
|
+ if ((*it).async)
|
|
+ {
|
|
+ stream << " call" << (*it).name << "Async(message);" << endl;
|
|
+ stream << endl;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ stream << " QDBusMessage reply = call" << (*it).name
|
|
+ << "(message);" << endl;
|
|
+ stream << " handleMethodReply(reply);" << endl;
|
|
+ stream << endl;
|
|
+ }
|
|
stream << " return true;" << endl;
|
|
stream << " }" << endl;
|
|
stream << endl;
|
|
@@ -967,6 +1143,15 @@
|
|
<< endl;
|
|
}
|
|
|
|
+ if (!classData.asyncReplySignals.isEmpty())
|
|
+ {
|
|
+ stream << " QObject::connect(m_baseProxy, "
|
|
+ << "SIGNAL(asyncReply(int, const QDBusMessage&))," << endl;
|
|
+ stream << " this, "
|
|
+ << " SLOT(slotHandleAsyncReply(int, const QDBusMessage&)));"
|
|
+ << endl;
|
|
+ }
|
|
+
|
|
stream << "}" << endl;
|
|
|
|
stream << endl;
|
|
@@ -988,7 +1173,8 @@
|
|
void MethodGenerator::writeProxyMethod(const QString& className,
|
|
const Method& method, QTextStream& stream)
|
|
{
|
|
- stream << "bool " << className << "::" << method.name << "(";
|
|
+ stream << "bool " << className << "::" << method.name
|
|
+ << (method.async ? "Async(" : "(");
|
|
|
|
QValueList<Argument>::const_iterator it = method.arguments.begin();
|
|
QValueList<Argument>::const_iterator endIt = method.arguments.end();
|
|
@@ -1064,6 +1250,22 @@
|
|
return;
|
|
}
|
|
|
|
+ if (method.async)
|
|
+ {
|
|
+ stream << " asyncCallId = m_baseProxy->sendWithAsyncReply(\"";
|
|
+ stream << method.name << "\", parameters);" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " if (asyncCallId != 0) m_asyncCalls[asyncCallId] = \""
|
|
+ << method.name << "\";" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ stream << " return (asyncCallId != 0);" << endl;
|
|
+ stream << "}" << endl;
|
|
+ stream << endl;
|
|
+ return;
|
|
+ }
|
|
+
|
|
stream << " QDBusMessage reply = m_baseProxy->sendWithReply(\"";
|
|
stream << method.name << "\", parameters, &error);" << endl;
|
|
stream << endl;
|
|
@@ -1335,6 +1537,58 @@
|
|
}
|
|
}
|
|
|
|
+void MethodGenerator::writeProxyAsyncReplyHandler(const Class& classData,
|
|
+ QTextStream& stream)
|
|
+{
|
|
+ stream << "void " << classData.name
|
|
+ << "::slotHandleAsyncReply(int asyncCallId, const QDBusMessage& message)" << endl;
|
|
+ stream << "{" << endl;
|
|
+
|
|
+ stream << " QMap<int, QString>::iterator findIt = "
|
|
+ << "m_asyncCalls.find(asyncCallId);" << endl;
|
|
+ stream << " if (findIt == m_asyncCalls.end()) return;" << endl;
|
|
+ stream << endl;
|
|
+ stream << " const QString signalName = findIt.data();" << endl;
|
|
+ stream << " m_asyncCalls.erase(findIt);" << endl;
|
|
+ stream << endl;
|
|
+
|
|
+ QValueList<Method>::const_iterator it = classData.asyncReplySignals.begin();
|
|
+ QValueList<Method>::const_iterator endIt = classData.asyncReplySignals.end();
|
|
+ bool first = true;
|
|
+ for (; it != endIt; ++it)
|
|
+ {
|
|
+ stream << " ";
|
|
+
|
|
+ if (!first)
|
|
+ stream << "else ";
|
|
+ else
|
|
+ first = false;
|
|
+
|
|
+ stream << "if (signalName == \"" << (*it).name << "\")" << endl;
|
|
+ stream << " {" << endl;
|
|
+
|
|
+ // FIXME tricking writeVariables and writeSignalEmit into writing
|
|
+ // the reply emit code by manipulating arguments and name
|
|
+ stream << " int _asyncCallId = asyncCallId;" << endl;
|
|
+
|
|
+ Method signal = *it;
|
|
+ signal.arguments.pop_front();
|
|
+
|
|
+ writeVariables(" ", signal, stream);
|
|
+ stream << endl;
|
|
+
|
|
+ signal = *it;
|
|
+ signal.name += "AsyncReply";
|
|
+
|
|
+ writeSignalEmit(signal, stream);
|
|
+
|
|
+ stream << " }" << endl;
|
|
+ }
|
|
+
|
|
+ stream << "}" << endl;
|
|
+ stream << endl;
|
|
+}
|
|
+
|
|
void MethodGenerator::writeIntrospectionDataMethod(const Class& classData,
|
|
QTextStream& stream)
|
|
{
|
|
diff -ur libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/methodgen.h ../dbus-qt4-qt3backport/tools/dbusxml2qt3/methodgen.h
|
|
--- libdbus-1-qt3-0.8.1/tools/dbusxml2qt3/methodgen.h 2007-12-17 12:34:08.000000000 +0100
|
|
+++ ../dbus-qt4-qt3backport/tools/dbusxml2qt3/methodgen.h 2008-03-13 10:28:55.000000000 +0100
|
|
@@ -61,6 +61,7 @@
|
|
QString name;
|
|
QValueList<Argument> arguments;
|
|
bool noReply;
|
|
+ bool async;
|
|
};
|
|
|
|
class Property : public Argument
|
|
@@ -86,6 +87,10 @@
|
|
QValueList<Method> methods;
|
|
QValueList<Method> signals;
|
|
QValueList<Property> properties;
|
|
+
|
|
+ QValueList<Method> asyncMethods;
|
|
+ QValueList<Method> asyncReplySignals;
|
|
+ QValueList<Method> asyncReplyMethods;
|
|
};
|
|
|
|
class MethodGenerator
|
|
@@ -109,6 +114,10 @@
|
|
static void writeSignalEmitter(const Class& classData, const Method& method,
|
|
QTextStream& stream);
|
|
|
|
+ static void writeInterfaceAsyncReplyHandler(const Class& classData,
|
|
+ const Method& method,
|
|
+ QTextStream& stream);
|
|
+
|
|
static void writeInterfaceMainMethod(const Class& classData,
|
|
QTextStream& stream);
|
|
|
|
@@ -125,6 +134,9 @@
|
|
static void writeProxyProperty(const Class& classData, const Property& property,
|
|
QTextStream& stream);
|
|
|
|
+ static void writeProxyAsyncReplyHandler(const Class& classData,
|
|
+ QTextStream& stream);
|
|
+
|
|
static void writeIntrospectionDataMethod(const Class& classData,
|
|
QTextStream& stream);
|
|
|