summaryrefslogtreecommitdiffstats
path: root/src/tools/dbusxml2qt3
diff options
context:
space:
mode:
authorMichele Calgaro <[email protected]>2019-04-27 00:21:43 +0900
committerMichele Calgaro <[email protected]>2019-04-27 00:21:43 +0900
commitf9c9e15267bd0319a8190ba146d7be95c37dac2e (patch)
tree1180022eddef0ffc8f44b030e721b6efef4f8b2a /src/tools/dbusxml2qt3
parent7d3c2ed4e8cdf9292059a4fc8f3678ca9d1d7c5c (diff)
downloaddbus-1-tqt-f9c9e15267bd0319a8190ba146d7be95c37dac2e.tar.gz
dbus-1-tqt-f9c9e15267bd0319a8190ba146d7be95c37dac2e.zip
Moved source files to "src" folder.
Signed-off-by: Michele Calgaro <[email protected]>
Diffstat (limited to 'src/tools/dbusxml2qt3')
-rw-r--r--src/tools/dbusxml2qt3/LICENSE18
-rw-r--r--src/tools/dbusxml2qt3/classgen.cpp1091
-rw-r--r--src/tools/dbusxml2qt3/classgen.h54
-rw-r--r--src/tools/dbusxml2qt3/main.cpp637
-rw-r--r--src/tools/dbusxml2qt3/methodgen.cpp1793
-rw-r--r--src/tools/dbusxml2qt3/methodgen.h153
6 files changed, 3746 insertions, 0 deletions
diff --git a/src/tools/dbusxml2qt3/LICENSE b/src/tools/dbusxml2qt3/LICENSE
new file mode 100644
index 0000000..1edf08c
--- /dev/null
+++ b/src/tools/dbusxml2qt3/LICENSE
@@ -0,0 +1,18 @@
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
diff --git a/src/tools/dbusxml2qt3/classgen.cpp b/src/tools/dbusxml2qt3/classgen.cpp
new file mode 100644
index 0000000..12051c0
--- /dev/null
+++ b/src/tools/dbusxml2qt3/classgen.cpp
@@ -0,0 +1,1091 @@
+/*
+* Copyright (C) 2007 Kevin Krammer <[email protected]>
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+// TQt includes
+#include <tqdom.h>
+#include <tqfile.h>
+#include <tqstringlist.h>
+#include <tqtextstream.h>
+
+// local includes
+#include "classgen.h"
+#include "methodgen.h"
+
+class Set : public TQMap<TQString, bool>
+{
+public:
+ void insertString(const TQString& key)
+ {
+ insert(key, true);
+ }
+
+ void removeString(const TQString& key)
+ {
+ erase(key);
+ }
+
+ void insertStringList(const TQStringList& list)
+ {
+ TQStringList::const_iterator it = list.begin();
+ TQStringList::const_iterator endIt = list.end();
+ for (; it != endIt; ++it)
+ {
+ insert(*it, true);
+ }
+ }
+};
+
+static void writeFileHeader(TQTextStream& stream)
+{
+ stream << "// File autogenerated" << endl;
+ stream << endl;
+}
+
+static void writeFileFooter(TQTextStream& stream)
+{
+ stream << "// End of File" << endl;
+ stream << endl;
+}
+
+static void openIncludeGuard(const TQString& className, TQTextStream& stream)
+{
+ stream << "#if !defined(" << className.upper() << "_H_INCLUDED)" << endl;
+ stream << "#define " << className.upper() << "_H_INCLUDED" << endl;
+ stream << endl;
+}
+
+static void closeIncludeGuard(const TQString& className, TQTextStream& stream)
+{
+ stream << "#endif //" << className.upper() << "_H_INCLUDED" << endl;
+ stream << endl;
+}
+
+static void openNamespaces(const TQStringList& namespaces, TQTextStream& stream)
+{
+ TQStringList::const_iterator it = namespaces.begin();
+ TQStringList::const_iterator endIt = namespaces.end();
+ for (; it != endIt; ++it)
+ {
+ stream << "namespace " << *it << endl;
+ stream << "{" << endl;
+ }
+ stream << endl;
+}
+
+static void closeNamespaces(const TQStringList& namespaces, TQTextStream& stream)
+{
+ TQStringList::const_iterator it = namespaces.end();
+ TQStringList::const_iterator endIt = namespaces.end();
+ for (--it; it != endIt; --it)
+ {
+ stream << "}; // namespace " << *it << endl;
+ stream << endl;
+ }
+}
+
+static void writeIncludes(const TQString& description, const TQStringList& includes,
+ TQTextStream& stream)
+{
+ if (includes.isEmpty()) return;
+
+ stream << "// " << description << " includes" << endl;
+
+ TQStringList::const_iterator it = includes.begin();
+ TQStringList::const_iterator endIt = includes.end();
+ for (;it != endIt; ++it)
+ {
+ stream << "#include " << *it << endl;
+ }
+
+ stream << endl;
+}
+
+static void extractHeaderIncludes(const Method& method,
+ TQMap<TQString, Set>& includes)
+{
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).headerIncludes.isEmpty()) continue;
+
+ TQMap<TQString, TQStringList>::const_iterator mapIt =
+ (*it).headerIncludes.begin();
+ TQMap<TQString, TQStringList>::const_iterator mapEndIt =
+ (*it).headerIncludes.end();
+
+ for (; mapIt != mapEndIt; ++mapIt)
+ {
+ includes[mapIt.key()].insertStringList(mapIt.data());
+ }
+ }
+}
+
+static void extractForwardDeclarations(const Method& method, Set& forwards)
+{
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).forwardDeclarations.isEmpty()) continue;
+
+ forwards.insertStringList((*it).forwardDeclarations);
+ }
+}
+
+static void writeHeaderIncludes(const Class& classData, Class::Role role,
+ TQTextStream& stream)
+{
+ TQMap<TQString, Set> includes;
+ Set forwards;
+
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<Method>::const_iterator endIt = classData.methods.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).arguments.isEmpty()) continue;
+
+ extractHeaderIncludes(*it, includes);
+ extractForwardDeclarations(*it, forwards);
+ }
+
+ it = classData.msignals.begin();
+ endIt = classData.msignals.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).arguments.isEmpty()) continue;
+
+ extractHeaderIncludes(*it, includes);
+ extractForwardDeclarations(*it, forwards);
+ }
+
+
+ TQValueList<Property>::const_iterator propertyIt = classData.properties.begin();
+ TQValueList<Property>::const_iterator propertyEndIt = classData.properties.end();
+ for (; propertyIt != propertyEndIt; ++propertyIt)
+ {
+ if (!(*propertyIt).headerIncludes.isEmpty())
+ {
+ TQMap<TQString, TQStringList>::const_iterator mapIt =
+ (*propertyIt).headerIncludes.begin();
+ TQMap<TQString, TQStringList>::const_iterator mapEndIt =
+ (*propertyIt).headerIncludes.end();
+
+ for (; mapIt != mapEndIt; ++mapIt)
+ {
+ includes[mapIt.key()].insertStringList(mapIt.data());
+ }
+ }
+
+ if (!(*propertyIt).forwardDeclarations.isEmpty())
+ {
+ forwards.insertStringList((*propertyIt).forwardDeclarations);
+ }
+ }
+
+ switch (role)
+ {
+ case Class::Interface:
+ includes["tqdbus"].insertString("<tqdbusobject.h>");
+ forwards.insertString("class TQT_DBusError");
+ forwards.insertString("class TQDomElement");
+ if (!classData.msignals.isEmpty())
+ forwards.insertString("class TQString");
+ if (!classData.asyncMethods.isEmpty())
+ {
+ includes["TQt"].insertString("<tqmap.h>");
+ forwards.erase("template <typename K, typename V> class TQMap");
+
+ includes["tqdbus"].insertString("<tqdbusmessage.h>");
+ forwards.erase("class TQT_DBusMessage");
+ }
+ break;
+
+ case Class::Proxy:
+ includes["TQt"].insertString("<tqobject.h>");
+ forwards.insertString("class TQT_DBusConnection");
+ forwards.insertString("class TQT_DBusError");
+ forwards.insertString("class TQT_DBusMessage");
+ forwards.insertString("class TQT_DBusProxy");
+ forwards.insertString("class TQString");
+ if (!classData.properties.isEmpty())
+ forwards.insertString("class TQT_DBusVariant");
+ if (!classData.asyncMethods.isEmpty())
+ {
+ includes["TQt"].insertString("<tqmap.h>");
+ forwards.erase("template <typename K, typename V> class TQMap");
+ }
+ break;
+
+ case Class::Node:
+ includes["tqdbus"].insertString("<tqdbusobject.h>");
+ forwards.insertString("class TQT_DBusConnection");
+ forwards.insertString("class TQString");
+ break;
+ }
+
+ includes["tqdbus"].insertString("<tqdbuserror.h>");
+
+ if (!includes["TQt"].isEmpty())
+ writeIncludes("TQt", includes["TQt"].keys(), stream);
+
+ if (!includes["tqdbus"].isEmpty())
+ writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream);
+
+ if (!includes["local"].isEmpty())
+ writeIncludes("local", includes["local"].keys(), stream);
+
+ stream << "// forward declarations" << endl;
+ Set::const_iterator setIt = forwards.begin();
+ Set::const_iterator setEndIt = forwards.end();
+ for (; setIt != setEndIt; ++setIt)
+ {
+ stream << setIt.key() << ";" << endl;
+ }
+ stream << endl;
+}
+
+static void extractSourceIncludes(const Method& method,
+ TQMap<TQString, Set>& includes)
+{
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).sourceIncludes.isEmpty()) continue;
+
+ TQMap<TQString, TQStringList>::const_iterator mapIt =
+ (*it).sourceIncludes.begin();
+ TQMap<TQString, TQStringList>::const_iterator mapEndIt =
+ (*it).sourceIncludes.end();
+
+ for (; mapIt != mapEndIt; ++mapIt)
+ {
+ includes[mapIt.key()].insertStringList(mapIt.data());
+ }
+ }
+}
+
+static void writeSourceIncludes(const Class& classData, Class::Role role,
+ TQTextStream& stream)
+{
+ TQMap<TQString, Set> includes;
+
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<Method>::const_iterator endIt = classData.methods.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).arguments.isEmpty()) continue;
+
+ extractSourceIncludes(*it, includes);
+ }
+
+ it = classData.msignals.begin();
+ endIt = classData.msignals.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).arguments.isEmpty()) continue;
+
+ extractSourceIncludes(*it, includes);
+ }
+
+ TQValueList<Property>::const_iterator propertyIt = classData.properties.begin();
+ TQValueList<Property>::const_iterator propertyEndIt = classData.properties.end();
+ for (; propertyIt != propertyEndIt; ++propertyIt)
+ {
+ if ((*propertyIt).sourceIncludes.isEmpty()) continue;
+
+ TQMap<TQString, TQStringList>::const_iterator mapIt =
+ (*propertyIt).sourceIncludes.begin();
+ TQMap<TQString, TQStringList>::const_iterator mapEndIt =
+ (*propertyIt).sourceIncludes.end();
+
+ for (; mapIt != mapEndIt; ++mapIt)
+ {
+ includes[mapIt.key()].insertStringList(mapIt.data());
+ }
+ }
+
+ switch (role)
+ {
+ case Class::Interface:
+ includes["TQt"].insertString("<tqdom.h>");
+ includes["tqdbus"].insertString("<tqdbuserror.h>");
+ includes["tqdbus"].insertString("<tqdbusmessage.h>");
+ break;
+
+ case Class::Proxy:
+ includes["tqdbus"].insertString("<tqdbuserror.h>");
+ includes["tqdbus"].insertString("<tqdbusmessage.h>");
+ includes["tqdbus"].insertString("<tqdbusproxy.h>");
+ if (!classData.properties.isEmpty())
+ {
+ includes["tqdbus"].insertString("<tqdbusconnection.h>");
+ includes["tqdbus"].insertString("<tqdbusvariant.h>");
+ }
+ break;
+
+ case Class::Node:
+ includes["TQt"].insertString("<tqdom.h>");
+ includes["TQt"].insertString("<tqmap.h>");
+ includes["tqdbus"].insertString("<tqdbusconnection.h>");
+ includes["tqdbus"].insertString("<tqdbusmessage.h>");
+ break;
+ }
+
+ if (!includes["TQt"].isEmpty())
+ writeIncludes("TQt", includes["TQt"].keys(), stream);
+
+ if (!includes["tqdbus"].isEmpty())
+ writeIncludes("TQt D-Bus", includes["tqdbus"].keys(), stream);
+
+ if (!includes["local"].isEmpty())
+ writeIncludes("local", includes["local"].keys(), stream);
+
+ stream << endl;
+}
+
+static void writeInterfaceIncludes(const TQValueList<Class> interfaces,
+ TQTextStream& stream)
+{
+ stream << "// interface classes includes" << endl;
+
+ TQValueList<Class>::const_iterator it = interfaces.begin();
+ TQValueList<Class>::const_iterator endIt = interfaces.end();
+ for (; it != endIt; ++it)
+ {
+ stream << "#include \"" << (*it).name.lower() << ".h\"" << endl;
+ }
+
+ stream << "#include \"introspectableinterface.h\"" << endl;
+
+ stream << endl;
+}
+
+static void openClassDeclaration(const Class& classData,
+ Class::Role role, TQTextStream& stream)
+{
+ switch (role)
+ {
+ case Class::Interface:
+ stream << "class " << classData.name << " : public TQT_DBusObjectBase"
+ << endl;
+ stream << "{" << endl;
+ stream << "public:" << endl;
+ stream << " virtual ~" << classData.name << "() {}" << endl;
+ stream << endl;
+ stream << " static void buildIntrospectionData(TQDomElement& interfaceElement);" << endl;
+ break;
+
+ case Class::Proxy:
+ stream << "class " << classData.name << " : public TQObject" << endl;
+ stream << "{" << endl;
+ stream << " Q_OBJECT" << endl;
+ stream << " " << endl;
+ stream << "public:" << endl;
+ stream << " " << classData.name
+ << "(const TQString& service, const TQString& path, TQObject* parent = 0, const char* name = 0);" << endl;
+ stream << endl;
+
+ stream << " virtual ~" << classData.name << "();" << endl;
+ stream << endl;
+
+ stream << " void setConnection(const TQT_DBusConnection& connection);"
+ << endl;
+ break;
+
+ case Class::Node:
+ stream << "class " << classData.name << " : public TQT_DBusObjectBase"
+ << endl;
+ stream << "{" << endl;
+ stream << "public:" << endl;
+ stream << " " << classData.name << "();" << endl;
+ stream << endl;
+ stream << " virtual ~" << classData.name << "();" << endl;
+ stream << endl;
+ stream << " bool registerObject(const TQT_DBusConnection& connection, "
+ << "const TQString& path);" << endl;
+ stream << endl;
+ stream << " void unregisterObject();" << endl;
+ stream << endl;
+ stream << "protected:" << endl;
+ stream << " virtual TQT_DBusObjectBase* createInterface("
+ << "const TQString& interfaceName) = 0;" << endl;
+ stream << endl;
+ stream << "protected: // usually no need to reimplement" << endl;
+ stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl;
+ stream << endl;
+ stream << "private:" << endl;
+ stream << " class Private;" << endl;
+ stream << " Private* m_private;" << endl;
+ break;
+ }
+
+ stream << endl;
+}
+
+static void closeClassDeclaration(const Class& classData, Class::Role role,
+ TQTextStream& stream)
+{
+ switch (role)
+ {
+ case Class::Interface:
+ break;
+
+ case Class::Proxy:
+ stream << "private: // Hiding copy constructor and assignment operator" << endl;
+ stream << " " << classData.name << "(const "
+ << classData.name << "&);" << endl;
+ stream << " " << classData.name << "& operator=(const "
+ << classData.name << "&);" << endl;
+ break;
+
+ case Class::Node:
+ stream << "private: // Hiding copy constructor and assignment operator" << endl;
+ stream << " " << classData.name << "(const "
+ << classData.name << "&);" << endl;
+ stream << " " << classData.name << "& operator=(const "
+ << classData.name << "&);" << endl;
+ break;
+ }
+ stream << "}; // class " << classData.name << endl;
+ stream << endl;
+}
+
+static void writeMethodDeclarations(const Class& classData, Class::Role role,
+ TQTextStream& stream)
+{
+ if (role == Class::Interface && !classData.asyncReplyMethods.isEmpty())
+ {
+ stream << "public:" << endl;
+
+ TQValueList<Method>::const_iterator it =
+ classData.asyncReplyMethods.begin();
+ TQValueList<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 TQT_DBusError& error);"
+ << endl;
+ stream << endl;
+ }
+ }
+
+ if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty())
+ {
+ bool pureVirtual = true;
+ switch (role)
+ {
+ case Class::Interface:
+ pureVirtual = true;
+ stream << "protected:" << endl;
+ break;
+
+ case Class::Proxy:
+ pureVirtual = false;
+ stream << "public:" << endl;
+ break;
+
+ case Class::Node: // no variable methods
+ break;
+ }
+
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<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())
+ {
+ bool pureVirtual = true;
+ bool skip = false;
+ switch (role)
+ {
+ case Class::Interface:
+ tqWarning("Properties not yet supported for interfaces");
+ skip = true;
+ pureVirtual = true;
+ break;
+
+ case Class::Proxy:
+ pureVirtual = false;
+ stream << "public:" << endl;
+ stream << " virtual void setDBusProperty(const TQString& name,"
+ << " const TQT_DBusVariant& variant, TQT_DBusError& error);"
+ << endl;
+ stream << " virtual TQT_DBusVariant getDBusProperty(const TQString& name, TQT_DBusError& error) const;" << endl;
+ stream << endl;
+ break;
+
+ case Class::Node: // no node properties
+ skip = true;
+ break;
+ }
+
+ if (!skip)
+ {
+ TQValueList<Property>::const_iterator it = classData.properties.begin();
+ TQValueList<Property>::const_iterator endIt = classData.properties.end();
+ for (; it != endIt; ++it)
+ {
+ MethodGenerator::writePropertyDeclaration(*it, pureVirtual, stream);
+ }
+ }
+ }
+
+ switch (role)
+ {
+ case Class::Interface:
+ if (!classData.methods.isEmpty() || !classData.asyncMethods.isEmpty())
+ {
+ stream << "protected: // implement sending replies" << endl;
+ stream << " virtual void handleMethodReply(const TQT_DBusMessage& reply) = 0;" << endl;
+ stream << endl;
+ stream << "protected: // usually no need to reimplement" << endl;
+ stream << " virtual bool handleMethodCall(const TQT_DBusMessage& message);" << endl;
+ }
+ else
+ {
+ stream << "protected: // no methods to handle" << endl;
+ stream << " virtual bool handleMethodCall(const TQT_DBusMessage&) { return false; }" << endl;
+ }
+ break;
+
+ case Class::Proxy:
+ {
+ if (!classData.msignals.isEmpty())
+ {
+ stream << "protected slots: // usually no need to reimplement" << endl;
+ stream << " virtual void slotHandleDBusSignal(const TQT_DBusMessage& message);" << endl;
+ stream << endl;
+ }
+
+ if (!classData.asyncReplySignals.isEmpty())
+ {
+ if (classData.msignals.isEmpty())
+ {
+ stream << "protected slots: // usually no need to reimplement" << endl;
+ }
+ stream << " virtual void slotHandleAsyncReply(int id, const TQT_DBusMessage& message);" << endl;
+ stream << endl;
+ }
+
+ stream << "protected:" << endl;
+ stream << " TQT_DBusProxy* m_baseProxy;" << endl;
+
+ if (!classData.asyncMethods.isEmpty())
+ {
+ stream << endl;
+ stream << " TQMap<int, TQString> m_asyncCalls;" << endl;
+ }
+
+ break;
+ }
+
+ case Class::Node: // not variable methods
+ break;
+ }
+
+ stream << endl;
+}
+
+static void writeSignalDeclarations(const Class& classData, Class::Role role,
+ TQTextStream& stream)
+{
+ if (classData.msignals.isEmpty() && classData.asyncReplySignals.isEmpty())
+ return;
+
+ TQString prefix;
+ switch (role)
+ {
+ case Class::Interface:
+ stream << "protected: // implement sending signals" << endl;
+ stream << " virtual bool handleSignalSend(const TQT_DBusMessage& reply) = 0;" << endl;
+ stream << " virtual TQString objectPath() const = 0;" << endl;
+ stream << endl;
+ stream << "protected: // for sending D-Bus signals" << endl;
+ prefix = " virtual bool emit";
+ break;
+
+ case Class::Proxy:
+ stream << "signals:" << endl;
+ stream << " void AsyncErrorResponseDetected(int asyncCallId, const TQT_DBusError error);" << endl << endl;
+ prefix = " void ";
+ break;
+
+ case Class::Node: // no signals
+ break;
+ }
+
+ TQValueList<Method>::const_iterator it = classData.msignals.begin();
+ TQValueList<Method>::const_iterator endIt = classData.msignals.end();
+ for (; it != endIt; ++it)
+ {
+ stream << prefix;
+ 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;
+}
+
+static void writeSignalEmitters(const Class& classData, TQTextStream& stream)
+{
+ if (classData.msignals.isEmpty()) return;
+
+ TQValueList<Method>::const_iterator it = classData.msignals.begin();
+ TQValueList<Method>::const_iterator endIt = classData.msignals.end();
+ for (; it != endIt; ++it)
+ {
+ MethodGenerator::writeSignalEmitter(classData, *it, stream);
+ }
+
+ stream << endl;
+}
+
+static void writeMethodCallDeclarations(const Class& classData,
+ TQTextStream& stream)
+{
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<Method>::const_iterator endIt = classData.methods.end();
+ for (; it != endIt; ++it)
+ {
+ stream << " ";
+ MethodGenerator::writeMethodCallDeclaration(*it, stream);
+ }
+
+ if (!classData.asyncReplyMethods.isEmpty())
+ {
+ stream << "protected:" << endl;
+ stream << " TQMap<int, TQT_DBusMessage> m_asyncCalls;" << endl;
+ stream << endl;
+ }
+}
+
+static void writeInterfaceAsyncReplyHandlers(const Class& classData,
+ TQTextStream& stream)
+{
+ if (classData.asyncReplyMethods.isEmpty()) return;
+
+ TQValueList<Method>::const_iterator it = classData.asyncReplyMethods.begin();
+ TQValueList<Method>::const_iterator endIt = classData.asyncReplyMethods.end();
+ for (; it != endIt; ++it)
+ {
+ MethodGenerator::writeInterfaceAsyncReplyHandler(classData, *it, stream);
+ }
+}
+
+static void writeMethodCalls(const Class& classData, TQTextStream& stream)
+{
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<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);
+ }
+}
+
+static void writeProxyMethods(const Class& classData, TQTextStream& stream)
+{
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<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);
+ }
+}
+
+static void writeProxyProperties(const Class& classData, TQTextStream& stream)
+{
+ if (classData.properties.isEmpty()) return;
+
+ MethodGenerator::writeProxyGenericProperty(classData, stream);
+
+ TQValueList<Property>::const_iterator it = classData.properties.begin();
+ TQValueList<Property>::const_iterator endIt = classData.properties.end();
+ for (; it != endIt; ++it)
+ {
+ MethodGenerator::writeProxyProperty(classData, *it, stream);
+ }
+}
+
+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;
+
+ TQValueList<Method>::iterator it = classData.methods.begin();
+ TQValueList<Method>::iterator endIt = classData.methods.end();
+ for (; it != endIt; ++it)
+ {
+ if (!(*it).async) continue;
+
+ Method method = *it;
+
+ TQValueList<Argument> methodArgs;
+ TQValueList<Argument> signalArgs;
+
+ // add id argument
+ methodArgs << idArgMethod;
+ signalArgs << idArgSignal;
+
+ // split in/out arguments: "in" belong to the method, "out" to the new signal
+ TQValueList<Argument>::const_iterator argIt = method.arguments.begin();
+ TQValueList<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;
+
+ TQValueList<Method>::iterator it = classData.methods.begin();
+ TQValueList<Method>::iterator endIt = classData.methods.end();
+ for (; it != endIt; ++it)
+ {
+ if (!(*it).async) continue;
+
+ Method method = *it;
+
+ TQValueList<Argument> methodArgs;
+ TQValueList<Argument> replyArgs;
+
+ // add id argument
+ methodArgs << idArgMethod;
+ replyArgs << idArgReply;
+
+ // split in/out arguments: "in" belong to the call, "out" to the reply
+ TQValueList<Argument>::const_iterator argIt = method.arguments.begin();
+ TQValueList<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 TQString& baseName,
+ TQTextStream& headerStream,
+ TQTextStream& sourceStream)
+{
+ TQFile* headerFile = new TQFile(baseName + ".h");
+ TQFile* sourceFile = new TQFile(baseName + ".cpp");
+
+ if (!headerFile->open(IO_WriteOnly) || !sourceFile->open(IO_WriteOnly))
+ {
+ delete headerFile;
+ delete sourceFile;
+
+ return false;
+ }
+
+ headerStream.setDevice(TQT_TQIODEVICE(headerFile));
+ sourceStream.setDevice(TQT_TQIODEVICE(sourceFile));
+
+ // create header
+ writeFileHeader(headerStream);
+ openIncludeGuard(baseName, headerStream);
+
+ // create source
+ writeFileHeader(sourceStream);
+ sourceStream << "// declaration include" << endl;
+ sourceStream << "#include \"" << baseName << ".h\"" << endl;
+ sourceStream << endl;
+
+ return true;
+}
+
+bool ClassGenerator::finishStreams(const TQString& baseName,
+ TQTextStream& headerStream,
+ TQTextStream& sourceStream)
+{
+ closeIncludeGuard(baseName, headerStream);
+ writeFileFooter(headerStream);
+ writeFileFooter(sourceStream);
+
+ TQIODevice* device = headerStream.device();
+ headerStream.unsetDevice();
+ delete device;
+
+ device = sourceStream.device();
+ sourceStream.unsetDevice();
+ delete device;
+
+ return true;
+}
+
+bool ClassGenerator::extractClass(const TQDomElement& interfaceElement,
+ Class& classData)
+{
+ tqDebug("ClassGenerator: processing interface '%s'",
+ interfaceElement.attribute("name").latin1());
+
+ classData.dbusName = interfaceElement.attribute("name");
+
+ TQStringList nameParts = TQStringList::split('.', classData.dbusName);
+
+ if (nameParts.count() < 2) return false;
+
+ classData.name = nameParts.back();
+ nameParts.pop_back();
+ classData.namespaces = nameParts;
+
+ return MethodGenerator::extractMethods(interfaceElement, classData);
+}
+
+bool ClassGenerator::generateInterface(const Class& classData,
+ TQTextStream& headerStream,
+ TQTextStream& sourceStream)
+{
+ Class classDataCopy = classData;
+ splitAsyncInterfaceMethods(classDataCopy);
+
+ // create header
+ writeHeaderIncludes(classDataCopy, Class::Interface, headerStream);
+
+ openNamespaces(classDataCopy.namespaces, headerStream);
+ openClassDeclaration(classDataCopy, Class::Interface, headerStream);
+
+ writeSignalDeclarations(classDataCopy, Class::Interface, headerStream);
+ writeMethodDeclarations(classDataCopy, Class::Interface, headerStream);
+ writeMethodCallDeclarations(classDataCopy, headerStream);
+
+ closeClassDeclaration(classDataCopy, Class::Interface, headerStream);
+ closeNamespaces(classDataCopy.namespaces, headerStream);
+
+ // create source
+ writeSourceIncludes(classDataCopy, Class::Interface, sourceStream);
+
+ openNamespaces(classDataCopy.namespaces, sourceStream);
+
+ MethodGenerator::writeIntrospectionDataMethod(classDataCopy, sourceStream);
+
+ writeSignalEmitters(classDataCopy, sourceStream);
+ writeInterfaceAsyncReplyHandlers(classDataCopy, sourceStream);
+ writeMethodCalls(classDataCopy, sourceStream);
+
+ MethodGenerator::writeInterfaceMainMethod(classDataCopy, sourceStream);
+
+ closeNamespaces(classDataCopy.namespaces, sourceStream);
+
+ return true;
+}
+
+bool ClassGenerator::generateProxy(const Class& classData,
+ TQTextStream& headerStream,
+ TQTextStream& sourceStream)
+{
+ Class classDataCopy = classData;
+ splitAsyncProxyMethods(classDataCopy);
+
+ // create header
+ writeHeaderIncludes(classDataCopy, Class::Proxy, headerStream);
+
+ openNamespaces(classDataCopy.namespaces, headerStream);
+ openClassDeclaration(classDataCopy, Class::Proxy, headerStream);
+
+ writeSignalDeclarations(classDataCopy, Class::Proxy, headerStream);
+ writeMethodDeclarations(classDataCopy, Class::Proxy, headerStream);
+
+ closeClassDeclaration(classDataCopy, Class::Proxy, headerStream);
+ closeNamespaces(classDataCopy.namespaces, headerStream);
+
+ // create source
+ writeSourceIncludes(classDataCopy, Class::Proxy, sourceStream);
+
+ openNamespaces(classDataCopy.namespaces, sourceStream);
+
+ MethodGenerator::writeProxyBegin(classDataCopy, sourceStream);
+
+ writeProxyMethods(classDataCopy, sourceStream);
+
+ writeProxyProperties(classDataCopy, sourceStream);
+
+ if (!classDataCopy.msignals.isEmpty())
+ MethodGenerator::writeSignalHandler(classDataCopy, sourceStream);
+
+ if (!classDataCopy.asyncReplySignals.isEmpty())
+ MethodGenerator::writeProxyAsyncReplyHandler(classDataCopy, sourceStream);
+
+ closeNamespaces(classDataCopy.namespaces, sourceStream);
+
+ return true;
+}
+
+bool ClassGenerator::generateNode(const Class& classData,
+ const TQValueList<Class>& interfaces,
+ TQTextStream& headerStream,
+ TQTextStream& sourceStream)
+{
+ // create header
+ writeHeaderIncludes(classData, Class::Node, headerStream);
+
+ openNamespaces(classData.namespaces, headerStream);
+ openClassDeclaration(classData, Class::Node, headerStream);
+
+ closeClassDeclaration(classData, Class::Node, headerStream);
+ closeNamespaces(classData.namespaces, headerStream);
+
+ // create source
+ writeSourceIncludes(classData, Class::Node, sourceStream);
+ writeInterfaceIncludes(interfaces, sourceStream);
+
+ openNamespaces(classData.namespaces, sourceStream);
+
+ MethodGenerator::writeNodePrivate(classData, sourceStream);
+
+ MethodGenerator::writeNodeBegin(classData, sourceStream);
+
+ MethodGenerator::writeNodeMethods(classData, interfaces, sourceStream);
+
+ closeNamespaces(classData.namespaces, sourceStream);
+
+ return true;
+}
+
+// End of File
diff --git a/src/tools/dbusxml2qt3/classgen.h b/src/tools/dbusxml2qt3/classgen.h
new file mode 100644
index 0000000..3597890
--- /dev/null
+++ b/src/tools/dbusxml2qt3/classgen.h
@@ -0,0 +1,54 @@
+/*
+* Copyright (C) 2007 Kevin Krammer <[email protected]>
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#if !defined(CLASSGEN_H_INCLUDED)
+#define CLASSGEN_H_INCLUDED
+
+// forward declarations
+class Class;
+class TQDomElement;
+class TQTextStream;
+template<typename T> class TQValueList;
+
+class ClassGenerator
+{
+public:
+ static bool initStreams(const TQString& baseName,
+ TQTextStream& headerStream, TQTextStream& sourceStream);
+
+ static bool finishStreams(const TQString& baseName,
+ TQTextStream& headerStream, TQTextStream& sourceStream);
+
+ static bool extractClass(const TQDomElement& interfaceElement, Class& classData);
+ static bool generateInterface(const Class& classData,
+ TQTextStream& headerStream,
+ TQTextStream& sourceStream);
+ static bool generateProxy(const Class& classData,
+ TQTextStream& headerStream, TQTextStream& sourceStream);
+ static bool generateNode(const Class& classData,
+ const TQValueList<Class>& interfaces,
+ TQTextStream& headerStream, TQTextStream& sourceStream);
+};
+
+#endif
+
+// End of File
diff --git a/src/tools/dbusxml2qt3/main.cpp b/src/tools/dbusxml2qt3/main.cpp
new file mode 100644
index 0000000..0208072
--- /dev/null
+++ b/src/tools/dbusxml2qt3/main.cpp
@@ -0,0 +1,637 @@
+/*
+* Copyright (C) 2007 Kevin Krammer <[email protected]>
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+// standard includes
+#include <iostream>
+#include <cstdlib>
+
+// TQt includes
+#include <tqdom.h>
+#include <tqfile.h>
+#include <tqmap.h>
+#include <tqtextstream.h>
+
+// local includes
+#include "classgen.h"
+#include "methodgen.h"
+
+typedef TQMap<TQString, TQString> OptionMap;
+
+void usage();
+
+OptionMap parseOptions(int argc, char** argv);
+
+bool checkForOption(const OptionMap& options, const TQString& option)
+{
+ return options.find(option) != options.end();
+}
+
+int main(int argc, char** argv)
+{
+ const OptionMap options = parseOptions(argc, argv);
+
+ if (!checkForOption(options, "filename"))
+ {
+ std::cerr << "dbusxml2qt3: introspection data file missing" << std::endl;
+ usage();
+ exit(1);
+ }
+
+ TQString fileName = options["filename"];
+ TQFile file(fileName);
+ if (!file.exists())
+ {
+ std::cerr << "dbusxml2qt3: introspection data file '"
+ << fileName.local8Bit().data()
+ << "' does not exist" << std::endl;
+ exit(2);
+ }
+
+ if (!file.open(IO_ReadOnly))
+ {
+ std::cerr << "dbusxml2qt3: introspection data file '"
+ << fileName.local8Bit().data()
+ << "' cannot be read" << std::endl;
+ exit(2);
+ }
+
+ TQDomDocument document;
+
+ if (!document.setContent(&file))
+ {
+ file.close();
+
+ std::cerr << "dbusxml2qt3: introspection data file '"
+ << fileName.local8Bit().data()
+ << "' cannot be parsed" << std::endl;
+ exit(2);
+ }
+
+ file.close();
+
+ TQDomElement rootElement = document.documentElement();
+ if (rootElement.isNull() || rootElement.tagName() != "node")
+ {
+ std::cerr << "dbusxml2qt3: introspection data file '"
+ << fileName.local8Bit().data()
+ << "' does not have a 'node' element as its root node"
+ << std::endl;
+ exit(2);
+ }
+
+ TQValueList<Class> interfaces;
+ bool hasIntrospectable = false;
+
+ TQDomNode child = rootElement.firstChild();
+ for (; !child.isNull(); child = child.nextSibling())
+ {
+ if (!child.isElement()) continue;
+
+ TQDomElement element = child.toElement();
+
+ if (element.tagName() == "interface")
+ {
+ if (!element.attribute("name").isEmpty())
+ {
+ Class classData;
+ if (ClassGenerator::extractClass(element, classData))
+ {
+ if (classData.dbusName == "org.freedesktop.DBus.Introspectable")
+ hasIntrospectable = true;
+ else
+ interfaces << classData;
+ }
+ }
+ }
+ }
+
+ if (interfaces.isEmpty())
+ {
+ std::cerr << "dbusxml2qt3: introspection data file '"
+ << fileName.local8Bit().data()
+ << "' does not contain any valid interface descriptions"
+ << std::endl;
+ exit(3);
+ }
+
+ bool generateProxies = checkForOption(options, "proxy");
+ bool generateInterfaces = checkForOption(options, "interface");
+ bool generateNode = checkForOption(options, "node");
+
+ // if no specific option is selected, we generate everything
+ bool generateAll = !(generateProxies || generateInterfaces || generateNode);
+
+ if (checkForOption(options, "classname"))
+ {
+ // class name only useful for single interfaces or just node
+ if (interfaces.count() > 1 && (generateAll || generateInterfaces || generateProxies))
+ {
+ std::cerr << "dbusxml2qt3: class name option specified but "
+ << "introspection data file '"
+ << fileName.local8Bit().data()
+ << "' contains more than one interface description"
+ << std::endl;
+ exit(3);
+ }
+
+ // class name for node is handled differently later on
+ if (!generateNode)
+ {
+ TQStringList nameParts = TQStringList::split("::", options["classname"]);
+
+ interfaces[0].name = nameParts.back();
+
+ nameParts.pop_back();
+ interfaces[0].namespaces = nameParts;
+ }
+ }
+
+ if (checkForOption(options, "namespace"))
+ {
+ TQStringList nameParts = TQStringList::split("::", options["namespace"]);
+
+ TQValueList<Class>::iterator it = interfaces.begin();
+ TQValueList<Class>::iterator endIt = interfaces.end();
+ for (; it != endIt; ++it)
+ {
+ (*it).namespaces = nameParts;
+ }
+ }
+
+ if (generateInterfaces || generateAll)
+ {
+ TQTextStream headerStream;
+ TQTextStream sourceStream;
+
+ TQString baseName = options["interface"];
+ if (!baseName.isEmpty())
+ {
+ if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream))
+ {
+ std::cerr << "dbusxml2qt3: proxy files, using base name '"
+ << baseName.local8Bit().data()
+ << "', could not be opened for writing"
+ << std::endl;
+ exit(4);
+ }
+ }
+
+ TQValueList<Class>::const_iterator it = interfaces.begin();
+ TQValueList<Class>::const_iterator endIt = interfaces.end();
+ for (; it != endIt; ++it)
+ {
+ if (baseName.isEmpty())
+ {
+ if (!ClassGenerator::initStreams((*it).name.lower() + "interface",
+ headerStream, sourceStream))
+ {
+ std::cerr << "dbusxml2qt3: interface files, using base name '"
+ << baseName.local8Bit().data()
+ << "', could not be opened for writing"
+ << std::endl;
+ exit(4);
+ }
+ }
+
+ ClassGenerator::generateInterface(*it, headerStream, sourceStream);
+
+ if (baseName.isEmpty())
+ {
+ ClassGenerator::finishStreams((*it).name.lower() + "interface",
+ headerStream, sourceStream);
+ }
+ }
+
+ if (!baseName.isEmpty())
+ ClassGenerator::finishStreams(baseName, headerStream, sourceStream);
+ }
+
+ if (generateProxies || generateAll)
+ {
+ TQTextStream headerStream;
+ TQTextStream sourceStream;
+
+ TQString baseName = options["proxy"];
+ if (!baseName.isEmpty())
+ {
+ if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream))
+ {
+ std::cerr << "dbusxml2qt3: proxy files, using base name '"
+ << baseName.local8Bit().data()
+ << "', could not be opened for writing"
+ << std::endl;
+ exit(4);
+ }
+ }
+
+ TQValueList<Class>::const_iterator it = interfaces.begin();
+ TQValueList<Class>::const_iterator endIt = interfaces.end();
+ for (; it != endIt; ++it)
+ {
+ if (baseName.isEmpty())
+ {
+ if (!ClassGenerator::initStreams((*it).name.lower() + "proxy",
+ headerStream, sourceStream))
+ {
+ std::cerr << "dbusxml2qt3: proxy files, using base name '"
+ << baseName.local8Bit().data()
+ << "', could not be opened for writing"
+ << std::endl;
+ exit(4);
+ }
+ }
+
+ ClassGenerator::generateProxy(*it, headerStream, sourceStream);
+
+ if (baseName.isEmpty())
+ {
+ ClassGenerator::finishStreams((*it).name.lower() + "proxy",
+ headerStream, sourceStream);
+ }
+ }
+
+ if (!baseName.isEmpty())
+ ClassGenerator::finishStreams(baseName, headerStream, sourceStream);
+ }
+
+ if (generateNode || generateAll)
+ {
+ if (!hasIntrospectable)
+ {
+ tqDebug("Generating org.freedesktop.DBus.Introspectable on demand");
+
+ Class classData;
+ classData.name = "Introspectable";
+ classData.dbusName = "org.freedesktop.DBus.Introspectable";
+
+ classData.namespaces << "org" << "freedesktop" << "DBus";
+
+ Method method;
+ method.name = "Introspect";
+ method.noReply = false;
+ method.async = false;
+
+ Argument argument;
+ argument.name = "data";
+ argument.direction = Argument::Out;
+ argument.signature = "TQString";
+ argument.accessor = "String";
+ argument.isPrimitive = false;
+ argument.dbusSignature = "s";
+
+ argument.forwardDeclarations << "class TQString";
+ argument.sourceIncludes["TQt"].append("<tqstring.h>");
+
+ method.arguments << argument;
+ classData.methods << method;
+
+ TQTextStream headerStream;
+ TQTextStream sourceStream;
+
+ if (!ClassGenerator::initStreams(classData.name.lower() + "interface",
+ headerStream, sourceStream))
+ {
+ std::cerr << "dbusxml2qt3: interface files, using base name '"
+ << classData.name.lower().local8Bit().data() << "interface"
+ << "', could not be opened for writing"
+ << std::endl;
+ exit(4);
+ }
+
+ ClassGenerator::generateInterface(classData,
+ headerStream, sourceStream);
+
+ ClassGenerator::finishStreams(classData.name.lower() + "interface",
+ headerStream, sourceStream);
+ }
+
+ TQString nodeClassName = options["classname"];
+ if (nodeClassName.isEmpty())
+ {
+ nodeClassName = rootElement.attribute("name");
+ if (nodeClassName.startsWith("/")) nodeClassName = nodeClassName.mid(1);
+ if (nodeClassName.isEmpty())
+ {
+ std::cerr << "dbusxml2qt3: cannot generate node without class name."
+ << std::endl;
+ exit(3);
+ }
+
+ nodeClassName.replace('/', "_");
+ }
+
+ TQStringList nameParts = TQStringList::split("::", nodeClassName);
+
+ Class classData;
+ classData.name = nameParts.back();
+
+ nameParts.pop_back();
+ classData.namespaces = nameParts;
+
+ if (checkForOption(options, "namespace"))
+ {
+ nameParts = TQStringList::split("::", options["namespace"]);
+
+ classData.namespaces = nameParts;
+ }
+
+ TQTextStream headerStream;
+ TQTextStream sourceStream;
+
+ TQString baseName = options["node"];
+ if (baseName.isEmpty()) baseName = classData.name.lower() + "node";
+
+ if (!ClassGenerator::initStreams(baseName, headerStream, sourceStream))
+ {
+ std::cerr << "dbusxml2qt3: interface files, using base name '"
+ << baseName.local8Bit().data()
+ << "', could not be opened for writing"
+ << std::endl;
+ exit(4);
+ }
+
+ ClassGenerator::generateNode(classData, interfaces,
+ headerStream, sourceStream);
+
+ ClassGenerator::finishStreams(baseName, headerStream, sourceStream);
+ }
+
+ return 0;
+}
+
+void usage()
+{
+ std::cout << "usage: dbusxml2qt3 [options] <introspectionfile>" << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "Options:" << std::endl;
+ std::cout << "-h, --help" << std::endl;
+ std::cout << "\tDisplay this help" << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "-c <classname>, --class <classname>" << std::endl;
+ std::cout << "\tUse 'classname' instead of last string in interface name"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "-N [namespace], --namespace [namespace]" << std::endl;
+ std::cout << "\tOverride namespaces. If provided, use 'namespace' instead, otherwise ignore namespaces"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "-i [basename], --interface [basename]" << std::endl;
+ std::cout << "\tGenerate interface files. If provided, use 'basename' for filenames"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "-p [basename], --proxy [basename]" << std::endl;
+ std::cout << "\tGenerate proxy files. If provided, use 'basename' for filenames"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "-n [basename], --node [basename]" << std::endl;
+ std::cout << "\tGenerate node files. If provided, use 'basename' for filenames"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "Examples:" << std::endl;
+ std::cout << "dbusxml2qt3 myinterface.xml" << std::endl;
+ std::cout << "\tGenerates as much as possible, i.e. interfaces, proxies and, "
+ << "if a node name is specified in 'myinterface.xml', the node files"
+ << std::endl;
+ std::cout << "\tUses lowercased interface names as plus type specific suffix "
+ << "for the file names" << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "dbusxml2qt3 myinterface.xml -N" << std::endl;
+ std::cout << "\tSame as first example but does not use namespaces"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "dbusxml2qt3 myinterface.xml -N org::myorg" << std::endl;
+ std::cout << "\tSame as first example but overrides namespaces with 'org::myorg'"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "dbusxml2qt3 myinterface.xml -n mynode -c MyNode" << std::endl;
+ std::cout << "\tGenerate only node files, use 'mynode' as the file basename "
+ << "and classname 'MyClass'"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "dbusxml2qt3 myinterface.xml -p" << std::endl;
+ std::cout << "\tGenerate only proxy files, use default file basename"
+ << std::endl;
+ std::cout << std::endl;
+
+ std::cout << "dbusxml2qt3 myinterface.xml -p myproxy" << std::endl;
+ std::cout << "\tGenerate only proxy files, use 'myproxy' as the file basename"
+ << std::endl;
+ std::cout << std::endl;
+}
+
+bool testAndSetOption(OptionMap& options, const TQString& option, const TQString& value)
+{
+ OptionMap::iterator it = options.find(option);
+ if (it == options.end())
+ {
+ options.insert(option, value);
+ return true;
+ }
+
+ return false;
+}
+
+OptionMap parseOptions(int argc, char** argv)
+{
+ TQStringList args;
+ for (int i = 1; i < argc; ++i)
+ {
+ args << TQString::fromLocal8Bit(argv[i]);
+ }
+
+ OptionMap options;
+
+ while (!args.isEmpty())
+ {
+ TQString arg = args.front();
+ args.pop_front();
+
+ if (arg.startsWith("-"))
+ {
+ if (arg.endsWith("help"))
+ {
+ usage();
+ exit(0);
+ }
+ else if (arg == "-p" || arg == "--proxy")
+ {
+ // test for optional argument
+ TQString value;
+ if (!args.isEmpty() > 0 && !args[0].startsWith("-"))
+ {
+ value = args.front();
+ args.pop_front();
+ }
+
+ if (!testAndSetOption(options, "proxy", value))
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data() << "'";
+
+ if (!value.isEmpty())
+ std::cerr << ", value '" << value.local8Bit().data() << "':";
+ else
+ std::cerr << ":";
+
+ std::cerr << " already set to '"
+ << options["proxy"].local8Bit().data() << std::endl;
+ }
+ }
+ else if (arg == "-i" || arg == "--interface")
+ {
+ // test for optional argument
+ TQString value;
+ if (!args.isEmpty() > 0 && !args[0].startsWith("-"))
+ {
+ value = args.front();
+ args.pop_front();
+ }
+
+ if (!testAndSetOption(options, "interface", value))
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data() << "'";
+
+ if (!value.isEmpty())
+ std::cerr << ", value '" << value.local8Bit().data() << "':";
+ else
+ std::cerr << ":";
+
+ std::cerr << " already set to '"
+ << options["interface"].local8Bit().data() << std::endl;
+ }
+ }
+ else if (arg == "-n" || arg == "--node")
+ {
+ // test for optional argument
+ TQString value;
+ if (!args.isEmpty() > 0 && !args[0].startsWith("-"))
+ {
+ value = args.front();
+ args.pop_front();
+ }
+
+ if (!testAndSetOption(options, "node", value))
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data() << "'";
+
+ if (!value.isEmpty())
+ std::cerr << ", value '" << value.local8Bit().data() << "':";
+ else
+ std::cerr << ":";
+
+ std::cerr << " already set to '"
+ << options["node"].local8Bit().data() << std::endl;
+ }
+ }
+ else if (arg == "-N" || arg == "--namespace")
+ {
+ // test for optional argument
+ TQString value;
+ if (!args.isEmpty() > 0 && !args[0].startsWith("-"))
+ {
+ value = args.front();
+ args.pop_front();
+ }
+
+ if (!testAndSetOption(options, "namespace", value))
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data() << "'";
+
+ if (!value.isEmpty())
+ std::cerr << ", value '" << value.local8Bit().data() << "':";
+ else
+ std::cerr << ":";
+
+ std::cerr << " already set to '"
+ << options["namespace"].local8Bit().data() << std::endl;
+ }
+ }
+ else if (arg == "-c" || arg == "--class")
+ {
+ // test for mandatory argument
+ if (args.isEmpty() || args[0].startsWith("-"))
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data()
+ << "': mandatory parameter missing" << std::endl;
+ usage();
+ exit(1);
+ }
+
+ TQString value = args.front();
+ args.pop_front();
+
+ if (!testAndSetOption(options, "classname", value))
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data() << "'";
+
+ if (!value.isEmpty())
+ std::cerr << ", value '" << value.local8Bit().data() << "':";
+ else
+ std::cerr << ":";
+
+ std::cerr << " already set to '"
+ << options["classname"].local8Bit().data() << std::endl;
+ }
+ }
+ else
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data()
+ << "': unknown option" << std::endl;
+ usage();
+ exit(1);
+ }
+ }
+ else
+ {
+ if (!testAndSetOption(options, "filename", arg))
+ {
+ std::cerr << "Error while parsing command line argument '"
+ << arg.local8Bit().data()
+ << "': introspection file already given as '"
+ << options["filename"].local8Bit().data() << std::endl;
+ usage();
+ exit(1);
+ }
+ }
+ }
+
+ return options;
+}
+
+// End of File
diff --git a/src/tools/dbusxml2qt3/methodgen.cpp b/src/tools/dbusxml2qt3/methodgen.cpp
new file mode 100644
index 0000000..4e407d5
--- /dev/null
+++ b/src/tools/dbusxml2qt3/methodgen.cpp
@@ -0,0 +1,1793 @@
+/*
+* Copyright (C) 2007 Kevin Krammer <[email protected]>
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+// TQt includes
+#include <tqdom.h>
+#include <tqtextstream.h>
+
+// local includes
+#include "methodgen.h"
+
+static bool parseDBusSignature(const TQString& signature, Argument& argument)
+{
+ argument.dbusSignature = signature;
+
+ if (signature.length() == 1)
+ {
+ if (signature == "b")
+ {
+ argument.signature = "bool";
+ argument.accessor = "Bool";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "y")
+ {
+ argument.signature = "TQ_UINT8";
+ argument.accessor = "Byte";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "n")
+ {
+ argument.signature = "TQ_INT16";
+ argument.accessor = "Int16";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "q")
+ {
+ argument.signature = "TQ_UINT16";
+ argument.accessor = "UInt16";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "i")
+ {
+ argument.signature = "TQ_INT32";
+ argument.accessor = "Int32";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "u")
+ {
+ argument.signature = "TQ_UINT32";
+ argument.accessor = "UInt32";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "x")
+ {
+ argument.signature = "TQ_INT64";
+ argument.accessor = "Int64";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "t")
+ {
+ argument.signature = "TQ_UINT64";
+ argument.accessor = "UInt64";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "d")
+ {
+ argument.signature = "double";
+ argument.accessor = "Double";
+ argument.isPrimitive = true;
+ }
+ else if (signature == "s")
+ {
+ argument.signature = "TQString";
+ argument.accessor = "String";
+ argument.isPrimitive = false;
+
+ argument.forwardDeclarations.append("class TQString");
+ argument.sourceIncludes["TQt"].append("<tqstring.h>");
+ }
+ else if (signature == "o")
+ {
+ argument.signature = "TQT_DBusObjectPath";
+ argument.accessor = "ObjectPath";
+ argument.isPrimitive = false;
+
+ argument.forwardDeclarations.append("class TQT_DBusObjectPath");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusobjectpath.h>");
+ }
+ else if (signature == "h")
+ {
+ argument.signature = "TQT_DBusUnixFd";
+ argument.accessor = "UnixFd";
+ argument.isPrimitive = false;
+
+ argument.forwardDeclarations.append("class TQT_DBusUnixFd");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusunixfd.h>");
+ }
+ else if (signature == "v")
+ {
+ argument.signature = "TQT_DBusVariant";
+ argument.accessor = "Variant";
+ argument.isPrimitive = false;
+
+ argument.forwardDeclarations.append("class TQT_DBusVariant");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusvariant.h>");
+ }
+ else
+ return false;
+ }
+ else if (signature.startsWith("a"))
+ {
+ if (signature == "as")
+ {
+ argument.signature = "TQStringList";
+ argument.accessor = "List";
+ argument.subAccessor = "TQStringList";
+ argument.isPrimitive = false;
+
+ argument.forwardDeclarations.append("class TQStringList");
+
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdatalist.h>");
+ argument.sourceIncludes["TQt"].append("<tqstringlist.h>");
+ }
+ else if (signature.startsWith("a{"))
+ {
+ int from = signature.find("{");
+ int to = signature.findRev("}");
+ if (from == -1 || to == -1 || (to - from - 1) < 2) return false;
+
+ TQString dictSignature = signature.mid(from + 1, (to - from - 1));
+
+ Argument key;
+ if (!parseDBusSignature(dictSignature.left(1), key)) return false;
+
+ Argument value;
+ if (parseDBusSignature(dictSignature.mid(1), value))
+ {
+ if (!value.subAccessor.isEmpty())
+ {
+ argument.isPrimitive = false;
+ argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >";
+ argument.signature = "TQT_DBusDataMap< " + key.signature + " >";
+ argument.accessor = key.accessor + "KeyMap";
+
+ argument.forwardDeclarations.append("template <typename K> class TQT_DBusDataMap");
+ argument.forwardDeclarations += key.forwardDeclarations;
+
+ argument.sourceIncludes = key.sourceIncludes;
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdata.h>");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdatamap.h>");
+ }
+ else
+ {
+ argument.isPrimitive = false;
+ argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >";
+ argument.signature = "TQMap< " + key.signature +
+ ", " + value.signature + " >";
+ argument.accessor = key.accessor + "KeyMap";
+ argument.subAccessor = value.accessor + "Map";
+
+ argument.forwardDeclarations.append("template <typename K, typename V> class TQMap");
+ argument.forwardDeclarations += key.forwardDeclarations;
+ argument.forwardDeclarations += value.forwardDeclarations;
+
+ argument.sourceIncludes = key.sourceIncludes;
+ argument.sourceIncludes["TQt"].append("<tqmap.h>");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdata.h>");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdatamap.h>");
+
+ TQMap<TQString, TQStringList>::const_iterator it =
+ value.sourceIncludes.begin();
+ TQMap<TQString, TQStringList>::const_iterator endIt =
+ value.sourceIncludes.end();
+ for (; it != endIt; ++it)
+ {
+ argument.sourceIncludes[it.key()] += it.data();
+ }
+ }
+ }
+ else
+ {
+ argument.isPrimitive = false;
+ argument.containerClass = "TQT_DBusDataMap< " + key.signature + " >";
+ argument.signature = "TQT_DBusDataMap< " + key.signature + " >";
+ argument.accessor = key.accessor + "KeyMap";
+
+ argument.forwardDeclarations.append("template <typename K> class TQT_DBusDataMap");
+ argument.forwardDeclarations += key.forwardDeclarations;
+
+ argument.sourceIncludes = key.sourceIncludes;
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdata.h>");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdatamap.h>");
+ }
+ }
+ else
+ {
+ TQString itemSignature = signature.mid(1);
+
+ Argument item;
+ if (parseDBusSignature(itemSignature, item) && !itemSignature.startsWith("a"))
+ {
+ argument.isPrimitive = false;
+ argument.signature = "TQValueList< " + item.signature + " >";
+ argument.accessor = "List";
+ argument.subAccessor = item.accessor + "List";
+ argument.containerClass = "TQT_DBusDataList";
+
+ argument.forwardDeclarations.append("class TQT_DBusDataList");
+ argument.forwardDeclarations.append("template <typename T> class TQValueList");
+ argument.forwardDeclarations += item.forwardDeclarations;
+
+ argument.sourceIncludes["TQt"].append("<tqvaluelist.h>");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdatalist.h>");
+
+ TQMap<TQString, TQStringList>::const_iterator it =
+ item.sourceIncludes.begin();
+ TQMap<TQString, TQStringList>::const_iterator endIt =
+ item.sourceIncludes.end();
+ for (; it != endIt; ++it)
+ {
+ argument.sourceIncludes[it.key()] += it.data();
+ }
+ }
+ else
+ {
+ argument.signature = "TQT_DBusDataList";
+ argument.accessor = "List";
+ argument.isPrimitive = false;
+
+ argument.forwardDeclarations.append("class TQT_DBusDataList");
+
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdatalist.h>");
+ }
+ }
+ }
+ else
+ return false;
+
+ return true;
+}
+
+static TQMap<TQString, TQString> extractTypeAnnotations(const TQDomElement& element)
+{
+ const TQString annotationPrefix = "org.freedesktop.DBus.TQt3.Type.";
+
+ TQMap<TQString, TQString> annotations;
+
+ TQDomNode node = element.firstChild();
+ for (uint count = 1; !node.isNull(); node = node.nextSibling(), ++count)
+ {
+ if (!node.isElement()) continue;
+
+ TQDomElement element = node.toElement();
+ if (element.tagName() != "annotation") continue;
+
+ TQString name = element.attribute("name");
+ if (name.isEmpty()) continue;
+
+ TQString value = element.attribute("value").stripWhiteSpace();
+ if (value.isEmpty()) continue;
+
+ if (!name.startsWith(annotationPrefix)) continue;
+
+ TQString arg = name.mid(annotationPrefix.length());
+
+ annotations.insert(arg, value);
+ }
+
+ return annotations;
+}
+
+static bool hasAnnotation(const TQDomElement& element, const TQString& annotation, TQString* value = 0)
+{
+ for (TQDomNode node = element.firstChild(); !node.isNull();
+ node = node.nextSibling())
+ {
+ if (!node.isElement()) continue;
+
+ TQDomElement 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 TQValueList<Argument> extractArguments(const TQDomElement& methodElement,
+ Class& classData)
+{
+ TQMap<TQString, TQString> argAnnotations = extractTypeAnnotations(methodElement);
+
+ TQValueList<Argument> arguments;
+
+ bool isSignal = methodElement.tagName() == "signal";
+
+ uint inCount = 0;
+ uint outCount = 0;
+ for (TQDomNode node = methodElement.firstChild(); !node.isNull();
+ node = node.nextSibling())
+ {
+ if (!node.isElement()) continue;
+
+ TQDomElement element = node.toElement();
+ if (element.tagName() != "arg") continue;
+ if (element.attribute("type").isEmpty()) continue;
+
+ Argument argument;
+ argument.name = element.attribute("name");
+ if (argument.name.isEmpty())
+ argument.name = TQString("arg%1").arg(inCount + outCount);
+
+ argument.direction = Argument::In;
+ if (!isSignal && element.attribute("direction", "in") == "out")
+ argument.direction = Argument::Out;
+
+ TQString annotation;
+ if (!isSignal && argument.direction == Argument::In)
+ {
+ annotation = argAnnotations[TQString("In%1").arg(inCount)];
+ ++inCount;
+ }
+ else
+ {
+ annotation = argAnnotations[TQString("Out%1").arg(outCount)];
+ ++outCount;
+ }
+
+ if (!annotation.isEmpty())
+ {
+ // just assume nobody uses annotations for primitives
+ argument.annotatedType = annotation;
+ argument.signature = annotation;
+ argument.isPrimitive = false;
+ argument.dbusSignature = element.attribute("type");
+
+ TQString includeBase =
+ TQString("\"%1type%2.h\"").arg(classData.name.lower());
+
+ argument.headerIncludes["local"].append(includeBase.arg("declarations"));
+ argument.sourceIncludes["local"].append(includeBase.arg("includes"));
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdataconverter.h>");
+ }
+ else if (!parseDBusSignature(element.attribute("type"), argument))
+ {
+ argument.signature = "TQT_DBusData";
+ argument.isPrimitive = false;
+
+ argument.forwardDeclarations.append("class TQT_DBusData");
+ argument.sourceIncludes["tqdbus"].append("<tqdbusdata.h>");
+ }
+
+ arguments.append(argument);
+ }
+
+ return arguments;
+}
+
+static void writeVariable(const Argument& argument, uint index,
+ const TQString& prefix, TQTextStream& stream)
+{
+ stream << prefix << argument.signature << " _" << argument.name;
+ if (argument.direction == Argument::In)
+ {
+ if (!argument.annotatedType.isEmpty())
+ {
+ stream << ";" << endl;
+
+ // TODO: error handling?
+ stream << prefix << "TQT_DBusDataConverter::convertFromTQT_DBusData<"
+ << argument.annotatedType
+ << TQString(">(message[%1], _").arg(index)
+ << argument.name << ")";
+ }
+ else if (!argument.accessor.isEmpty())
+ {
+ stream << TQString::fromUtf8(" = message[%1].to").arg(index);
+ stream << argument.accessor;
+
+ if (!argument.subAccessor.isEmpty())
+ {
+ stream << TQString("().to%1").arg(argument.subAccessor);
+ }
+
+ stream << "()";
+ }
+ else
+ stream << TQString::fromUtf8(" = message[%1]").arg(index);
+ }
+
+ stream << ";" << endl;
+}
+
+static void writeVariables(const TQString& prefix, const Method& method,
+ TQTextStream& stream)
+{
+ uint count = 0;
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; it != endIt; ++it)
+ {
+ writeVariable(*it, count, prefix, stream);
+
+ if ((*it).direction == Argument::In) ++count;
+ }
+}
+
+static void writeSignalEmit(const Method& signal, TQTextStream& stream)
+{
+ stream << " emit " << signal.name << "(";
+
+ TQValueList<Argument>::const_iterator it = signal.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = signal.arguments.end();
+ for (; it != endIt;)
+ {
+ stream << "_" << (*it).name;
+
+ ++it;
+ if (it != endIt) stream << ", ";
+ }
+
+ stream << ");" << endl;
+}
+
+static void writeMethodIntrospection(const Method& method, bool& firstArgument,
+ TQTextStream& stream)
+{
+ stream << " methodElement.setAttribute(\"name\", \""
+ << method.name << "\");" << endl;
+
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; it != endIt; ++it)
+ {
+ stream << endl;
+ if (firstArgument)
+ {
+ firstArgument = false;
+
+ stream << " TQDomElement argumentElement = document.createElement("
+ << "\"arg\");" << endl;
+ }
+ else
+ {
+ stream << " argumentElement = document.createElement("
+ << "\"arg\");" << endl;
+ }
+
+ stream << " argumentElement.setAttribute(\"name\", \""
+ << (*it).name << "\");" << endl;
+
+ stream << " argumentElement.setAttribute(\"type\", \""
+ << (*it).dbusSignature << "\");" << endl;
+
+ stream << " argumentElement.setAttribute(\"direction\", \""
+ << ((*it).direction == Argument::In ? "in" : "out") << "\");"
+ << endl;
+
+ stream << " methodElement.appendChild(argumentElement);" << endl;
+ }
+ stream << endl;
+}
+
+static void writeNodeInitialization(const Class& classData,
+ const TQValueList<Class>& interfaces, TQTextStream& stream)
+{
+ stream << "bool " << classData.name
+ << "::registerObject(const TQT_DBusConnection& connection, "
+ << "const TQString& path)" << endl;
+ stream << "{" << endl;
+ stream << " if (path.isEmpty()) return false;" << endl;
+ stream << endl;
+
+ stream << " if (!m_private->objectPath.isEmpty()) unregisterObject();"
+ << endl;
+ stream << endl;
+
+ stream << " m_private->connection = connection;" << endl;
+ stream << " m_private->objectPath = path;" << endl;
+ stream << endl;
+ stream << " if (!m_private->connection.registerObject(path, this))" << endl;
+ stream << " {" << endl;
+ stream << " m_private->connection = TQT_DBusConnection();" << endl;
+ stream << " m_private->objectPath = TQString();" << endl;
+ stream << endl;
+ stream << " return false;" << endl;
+ stream << " }" << endl;
+ stream << endl;
+
+ stream << " if (m_private->interfaces.isEmpty())" << endl;
+ stream << " {" << endl;
+ stream << " TQString name = \"org.freedesktop.DBus.Introspectable\";"
+ << endl;
+ stream << " TQT_DBusObjectBase* interface = m_private;" << endl;
+ stream << " m_private->interfaces.insert(name, interface);" << endl;
+
+ TQValueList<Class>::const_iterator it = interfaces.begin();
+ TQValueList<Class>::const_iterator endIt = interfaces.end();
+ for (; it != endIt; ++it)
+ {
+ stream << endl;
+ stream << " name = \"" << (*it).dbusName << "\";" << endl;
+ stream << " interface = createInterface(name);" << endl;
+ stream << " Q_ASSERT(interface != 0);" << endl;
+ stream << " m_private->interfaces.insert(name, interface);" << endl;
+ }
+
+ stream << " }" << endl;
+ stream << endl;
+ stream << " return true;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+}
+static void writeNodeIntrospection(const Class& classData,
+ const TQValueList<Class>& interfaces, TQTextStream& stream)
+{
+ stream << "void " << classData.name << "::Private"
+ << "::cacheIntrospectionData()" << endl;
+ stream << "{" << endl;
+
+ stream << " TQDomDocument doc;" << endl;
+ stream << " TQDomElement nodeElement = doc.createElement(\"node\");" << endl;
+ stream << " TQDomElement interfaceElement = doc.createElement(\"interface\");"
+ << endl;
+ stream << " org::freedesktop::DBus::Introspectable"
+ << "::buildIntrospectionData(interfaceElement);" << endl;
+ stream << " nodeElement.appendChild(interfaceElement);" << endl;
+
+ TQValueList<Class>::const_iterator it = interfaces.begin();
+ TQValueList<Class>::const_iterator endIt = interfaces.end();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).dbusName == "org.freedesktop.DBus.Introspectable") continue;
+
+ stream << endl;
+ stream << " interfaceElement = doc.createElement(\"interface\");"
+ << endl;
+ stream << " " << (*it).namespaces.join("::") + "::" + (*it).name
+ << "::buildIntrospectionData(interfaceElement);" << endl;
+ stream << " nodeElement.appendChild(interfaceElement);" << endl;
+ }
+
+ stream << endl;
+ stream << " doc.appendChild(nodeElement);" << endl;
+ stream << endl;
+
+ stream << " introspectionData = \"<!DOCTYPE node PUBLIC \\\""
+ << "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\\\"\\n"
+ << "\\\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
+ << "\\\">\\n\";" << endl;
+ stream << " introspectionData += doc.toString();" << endl;
+ stream << "}" << endl;
+ stream << endl;
+}
+
+bool MethodGenerator::extractMethods(const TQDomElement& interfaceElement,
+ Class& classData)
+{
+ TQMap<TQString, TQString> propertyAnnotations =
+ extractTypeAnnotations(interfaceElement);
+
+ uint propertyCount = 0;
+ for (TQDomNode node = interfaceElement.firstChild(); !node.isNull();
+ node = node.nextSibling())
+ {
+ if (!node.isElement()) continue;
+
+ TQDomElement element = node.toElement();
+ if (element.attribute("name").isEmpty()) continue;
+
+ if (element.tagName() == "method" || element.tagName() == "signal")
+ {
+ Method method;
+ 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);
+ if (method.async) {
+ method.async = false;
+ classData.methods.append(method);
+ }
+ }
+ else
+ classData.msignals.append(method);
+ }
+ else if (element.tagName() == "property")
+ {
+ Property property;
+ property.name = element.attribute("name");
+ property.read = element.attribute("access").find("read") != -1;
+ property.write = element.attribute("access").find("write") != -1;
+
+ TQString annotation =
+ propertyAnnotations[TQString("Property%1").arg(propertyCount)];
+
+ if (!annotation.isEmpty())
+ {
+ property.annotatedType = annotation;
+ property.signature = annotation;
+ property.dbusSignature = element.attribute("type");
+ property.isPrimitive = false;
+
+ TQString includeBase =
+ TQString("\"%1type%2.h\"").arg(classData.name.lower());
+
+ property.headerIncludes["local"].append(includeBase.arg("declarations"));
+ property.sourceIncludes["local"].append(includeBase.arg("includes"));
+ property.sourceIncludes["tqdbus"].append("<tqdbusdataconverter.h>");
+ }
+ else if (!parseDBusSignature(element.attribute("type"), property))
+ {
+ property.signature = "TQT_DBusData";
+ property.isPrimitive = false;
+
+ property.forwardDeclarations.append("class TQT_DBusData");
+ property.sourceIncludes["tqdbus"].append("<tqdbusdata.h>");
+ }
+
+ classData.properties.append(property);
+ ++propertyCount;
+ }
+ }
+
+ return !classData.methods.isEmpty() || !classData.msignals.isEmpty() ||
+ !classData.properties.isEmpty();
+}
+
+void MethodGenerator::writeMethodDeclaration(const Method& method, bool pureVirtual,
+ bool withError, TQTextStream& stream)
+{
+ stream << method.name << "(";
+
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; 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 || withError) stream << ", ";
+ }
+
+ if (withError)
+ stream << "TQT_DBusError& error)";
+ else
+ stream << ")";
+
+ if (pureVirtual)
+ stream << " = 0;" << endl;
+ else
+ stream << ";" << endl;
+
+ stream << endl;
+}
+
+void MethodGenerator::writePropertyDeclaration(const Property& property,
+ bool pureVirtual, TQTextStream& stream)
+{
+ if (property.write)
+ {
+ stream << " virtual void set" << property.name << "(";
+
+ if (!property.isPrimitive) stream << "const ";
+
+ stream << property.signature;
+
+ if (!property.isPrimitive) stream << "&";
+
+ stream << " value, TQT_DBusError& error)";
+
+ if (pureVirtual)
+ stream << " = 0;" << endl;
+ else
+ stream << ";" << endl;
+ }
+
+ if (property.read)
+ {
+ stream << " virtual " << property.signature << " get"
+ << property.name << "(TQT_DBusError& error) const";
+
+ if (pureVirtual)
+ stream << " = 0;" << endl;
+ else
+ stream << ";" << endl;
+ }
+
+ if (property.read || property.write) stream << endl;
+}
+
+void MethodGenerator::writeMethodCallDeclaration(const Method& method,
+ TQTextStream& stream)
+{
+ if (method.async)
+ stream << "void call" << method.name << "Async";
+ else
+ stream << "TQT_DBusMessage call" << method.name;
+
+ stream << "(const TQT_DBusMessage& message);" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeMethodCall(const Class& classData,
+ const Method& method, TQTextStream& stream)
+{
+ if (method.async)
+ stream << "void " << classData.name << "::call" << method.name << "Async";
+ else
+ stream << "TQT_DBusMessage " << classData.name << "::call" << method.name;
+
+ stream << "(const TQT_DBusMessage& message)" << endl;
+
+ stream << "{" << endl;
+
+ if (method.async)
+ {
+ // FIXME: using writeVariables by removing asyncCallId argument
+ Method reducedMethod = method;
+ reducedMethod.arguments.pop_front();
+
+ writeVariables(" ", reducedMethod, stream);
+ }
+ else
+ {
+ stream << " TQT_DBusError error;" << endl;
+ stream << " TQT_DBusMessage reply;" << endl;
+ stream << endl;
+
+ writeVariables(" ", method, stream);
+ }
+
+ stream << endl;
+
+ 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 << "(";
+
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ while (it != endIt)
+ {
+ stream << "_" << (*it).name;
+
+ ++it;
+ if (it != endIt) stream << ", ";
+ }
+
+ 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 = TQT_DBusMessage::methodReply(message);" << endl;
+
+ it = method.arguments.begin();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).direction == Argument::Out)
+ {
+ if (!(*it).annotatedType.isEmpty())
+ {
+ stream << " TQT_DBusData " << (*it).name << "Data;" << endl;
+ stream << " TQT_DBusDataConverter::convertToTQT_DBusData<"
+ << (*it).annotatedType << ">(_"
+ << (*it).name << ", " << (*it).name << "Data);"
+ << endl;
+ stream << " reply << " << (*it).name << "Data";
+ }
+ else if (!(*it).accessor.isEmpty())
+ {
+ stream << " reply << TQT_DBusData::from" << (*it).accessor;
+ if (!(*it).subAccessor.isEmpty())
+ {
+ stream << "(" << (*it).containerClass;
+ }
+
+ stream << "(_" << (*it).name << ")";
+
+ if (!(*it).subAccessor.isEmpty())
+ {
+ stream << ")";
+ }
+ }
+ else
+ stream << " reply << _" << (*it).name;
+
+ stream << ";" << endl;
+ }
+ }
+ stream << " }" << endl;
+ stream << " else" << endl;
+ stream << " {" << endl;
+
+ stream << " if (!error.isValid())" << endl;
+ stream << " {" << endl;
+ stream << " tqWarning(\"Call to implementation of ";
+
+ TQStringList::const_iterator nsIt = classData.namespaces.begin();
+ TQStringList::const_iterator nsEndIt = classData.namespaces.end();
+ for (; nsIt != nsEndIt; ++nsIt)
+ {
+ stream << *nsIt << "::";
+ }
+
+ stream << classData.name << "::" << method.name;
+ stream << " returned 'false' but error object is not valid!\");" << endl;
+ stream << endl;
+ stream << " error = TQT_DBusError::stdFailed(\"";
+
+ nsIt = classData.namespaces.begin();
+ for (; nsIt != nsEndIt; ++nsIt)
+ {
+ stream << *nsIt << ".";
+ }
+
+ stream << classData.name << "." << method.name << " execution failed\");"
+ << endl;
+ stream << " }" << endl;
+ stream << endl;
+
+ stream << " reply = TQT_DBusMessage::methodError(message, error);" << endl;
+
+ stream << " }" << endl;
+ stream << endl;
+ stream << " return reply;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeSignalEmitter(const Class& classData,
+ const Method& method, TQTextStream& stream)
+{
+ stream << "bool " << classData.name << "::emit" << method.name << "(";
+
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; 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;
+
+ // TODO: create error or use enum for return
+ stream << " TQString path = objectPath();" << endl;
+ stream << " Q_ASSERT(!path.isEmpty());" << endl;
+ stream << endl;
+
+ stream << " TQT_DBusMessage message = TQT_DBusMessage::signal(path, \"";
+ stream << classData.dbusName << "\", \"" << method.name << "\");" << endl;
+ stream << endl;
+
+ it = method.arguments.begin();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).direction == Argument::In)
+ {
+ if (!(*it).annotatedType.isEmpty())
+ {
+ // TODO: error handling
+ stream << " TQT_DBusData " << (*it).name << "Data;" << endl;
+ stream << " if (TQT_DBusDataConverter:convertToTQT_DBusData<"
+ << (*it).annotatedType << ">("
+ << (*it).name << ", " << (*it).name << "Data"
+ << ") != TQT_DBusDataConverter::Success) return false;"
+ << endl;
+ stream << " message << " << (*it).name << "Data";
+ }
+ else if (!(*it).accessor.isEmpty())
+ {
+ stream << " message << TQT_DBusData::from" << (*it).accessor;
+ if (!(*it).subAccessor.isEmpty())
+ {
+ stream << "(" << (*it).containerClass;
+ }
+
+ stream << "(" << (*it).name << ")";
+
+ if (!(*it).subAccessor.isEmpty())
+ {
+ stream << ")";
+ }
+ }
+ else
+ stream << " message << " << (*it).name;
+
+ stream << ";" << endl;
+ }
+ }
+ stream << endl;
+
+ stream << " return handleSignalSend(message);" << endl;
+
+ stream << "}" << endl;
+ stream << endl;
+}
+
+
+void MethodGenerator::writeInterfaceAsyncReplyHandler(const Class& classData,
+ const Method& method, TQTextStream& stream)
+{
+ stream << "void " << classData.name << "::" << method.name
+ << "AsyncReply(";
+
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<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 << " TQMap<int, TQT_DBusMessage>::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl;
+ stream << " if (findIt == m_asyncCalls.end()) return;" << endl;
+ stream << endl;
+
+ stream << " TQT_DBusMessage call = findIt.data();" << endl;
+ stream << " m_asyncCalls.erase(findIt);" << endl;
+ stream << endl;
+
+ stream << " TQT_DBusMessage reply = TQT_DBusMessage::methodReply(call);"
+ << endl;
+
+ it = method.arguments.begin();
+ for (++it; it != endIt; ++it) // skip asyncCallId at beginning
+ {
+ if (!(*it).annotatedType.isEmpty())
+ {
+ stream << " TQT_DBusData " << (*it).name << "Data;" << endl;
+
+ // TODO error handling
+ stream << " if (TQT_DBusDataConverter::convertToTQT_DBusData<"
+ << (*it).annotatedType << ">(" << (*it).name << ", "
+ << (*it).name << "Data"
+ << ") != TQT_DBusDataConverter::Success) return false;"
+ << endl;
+ stream << " reply << " << (*it).name << "Data;" << endl;
+ }
+ else if (!(*it).accessor.isEmpty())
+ {
+ stream << " reply << TQT_DBusData::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 TQT_DBusError& error)";
+ stream << endl;
+
+ stream << "{" << endl;
+
+ stream << " TQMap<int, TQT_DBusMessage>::iterator findIt = m_asyncCalls.find(asyncCallId);" << endl;
+ stream << " if (findIt == m_asyncCalls.end()) return;" << endl;
+ stream << endl;
+
+ stream << " TQT_DBusMessage call = findIt.data();" << endl;
+ stream << " m_asyncCalls.erase(findIt);" << endl;
+ stream << endl;
+
+ stream << " TQT_DBusMessage reply = TQT_DBusMessage::methodError(call, error);"
+ << endl;
+ stream << " handleMethodReply(reply);" << endl;
+
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeInterfaceMainMethod(const Class& classData,
+ TQTextStream& stream)
+{
+ if (classData.methods.isEmpty()) return;
+
+ stream << "bool " << classData.name
+ << "::handleMethodCall(const TQT_DBusMessage& message)" << endl;
+ stream << "{" << endl;
+
+ stream << " if (message.interface() != \"" << classData.dbusName
+ << "\") return false;" << endl;
+ stream << endl;
+
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<Method>::const_iterator endIt = classData.methods.end();
+ for (; it != endIt; ++it)
+ {
+ stream << " if (message.member() == \"" << (*it).name << "\")" << endl;
+ stream << " {" << endl;
+
+ if ((*it).async)
+ {
+ stream << " call" << (*it).name << "Async(message);" << endl;
+ stream << endl;
+ }
+ else
+ {
+ stream << " TQT_DBusMessage reply = call" << (*it).name
+ << "(message);" << endl;
+ stream << " handleMethodReply(reply);" << endl;
+ stream << endl;
+ }
+ stream << " return true;" << endl;
+ stream << " }" << endl;
+ stream << endl;
+ }
+
+ stream << " return false; " << endl;
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeSignalHandler(const Class& classData,
+ TQTextStream& stream)
+{
+ stream << "void " << classData.name
+ << "::slotHandleDBusSignal(const TQT_DBusMessage& message)" << endl;
+ stream << "{" << endl;
+
+ TQValueList<Method>::const_iterator it = classData.msignals.begin();
+ TQValueList<Method>::const_iterator endIt = classData.msignals.end();
+ bool first = true;
+ for (; it != endIt; ++it)
+ {
+ stream << " ";
+
+ if (!first)
+ stream << "else ";
+ else
+ first = false;
+
+ stream << "if (message.member() == \"" << (*it).name << "\")" << endl;
+ stream << " {" << endl;
+
+ writeVariables(" ", *it, stream);
+ stream << endl;
+
+ writeSignalEmit(*it, stream);
+
+ stream << " }" << endl;
+ }
+
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeProxyBegin(const Class& classData, TQTextStream& stream)
+{
+ stream << classData.name << "::" << classData.name
+ << "(const TQString& service, const TQString& path, TQObject* parent, const char* name)" << endl;
+ stream << " : TQObject(parent, name)," << endl;
+ stream << " m_baseProxy(new TQT_DBusProxy())" << endl;
+ stream << "{" << endl;
+ stream << " m_baseProxy->setInterface(\""
+ << classData.dbusName << "\");" << endl;
+ stream << " m_baseProxy->setPath(path);" << endl;
+ stream << " m_baseProxy->setService(service);" << endl;
+ stream << endl;
+
+ if (!classData.msignals.isEmpty())
+ {
+ stream << " TQObject::connect(m_baseProxy, "
+ << "TQT_SIGNAL(dbusSignal(const TQT_DBusMessage&))," << endl;
+ stream << " this, "
+ << " TQT_SLOT(slotHandleDBusSignal(const TQT_DBusMessage&)));"
+ << endl;
+ }
+
+ if (!classData.asyncReplySignals.isEmpty())
+ {
+ stream << " TQObject::connect(m_baseProxy, "
+ << "TQT_SIGNAL(asyncReply(int, const TQT_DBusMessage&))," << endl;
+ stream << " this, "
+ << " TQT_SLOT(slotHandleAsyncReply(int, const TQT_DBusMessage&)));"
+ << endl;
+ }
+
+ stream << "}" << endl;
+
+ stream << endl;
+
+ stream << classData.name << "::~" << classData.name << "()" << endl;
+ stream << "{" << endl;
+ stream << " delete m_baseProxy;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+
+ stream << "void " << classData.name
+ << "::setConnection(const TQT_DBusConnection& connection)" << endl;
+ stream << "{" << endl;
+ stream << " m_baseProxy->setConnection(connection);" << endl;
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeProxyMethod(const TQString& className,
+ const Method& method, TQTextStream& stream)
+{
+ stream << "bool " << className << "::" << method.name
+ << (method.async ? "Async(" : "(");
+
+ TQValueList<Argument>::const_iterator it = method.arguments.begin();
+ TQValueList<Argument>::const_iterator endIt = method.arguments.end();
+ for (; it != endIt; ++it)
+ {
+ if (!(*it).isPrimitive && (*it).direction == Argument::In)
+ stream << "const ";
+
+ stream << (*it).signature;
+
+ if (!(*it).isPrimitive || (*it).direction == Argument::Out) stream << "&";
+
+ stream << " " << (*it).name << ", ";
+ }
+
+ stream << "TQT_DBusError& error)" << endl;
+
+ stream << "{" << endl;
+ stream << " TQValueList<TQT_DBusData> parameters;" << endl;
+ stream << endl;
+
+ uint outCount = 0;
+
+ it = method.arguments.begin();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).direction == Argument::Out)
+ {
+ ++outCount;
+ continue;
+ }
+
+ if (!(*it).annotatedType.isEmpty())
+ {
+ stream << " TQT_DBusData " << (*it).name << "Data;" << endl;
+
+ // TODO error handling
+ stream << " if (TQT_DBusDataConverter::convertToTQT_DBusData<"
+ << (*it).annotatedType << ">(" << (*it).name << ", "
+ << (*it).name << "Data"
+ << ") != TQT_DBusDataConverter::Success) return false;"
+ << endl;
+ stream << " parameters << " << (*it).name << "Data;" << endl;
+ }
+ else if (!(*it).accessor.isEmpty())
+ {
+ stream << " parameters << TQT_DBusData::from" << (*it).accessor << "(";
+
+ if ((*it).subAccessor.isEmpty())
+ stream << (*it).name;
+ else
+ stream << (*it).containerClass << "(" << (*it).name << ")";
+
+ stream << ");" << endl;
+ }
+ else
+ stream << " parameters << " << (*it).name << ";" << endl;
+ }
+
+ stream << endl;
+
+ if (outCount == 0 && method.noReply)
+ {
+ stream << " if (!m_baseProxy->send(\"" << method.name
+ << "\", parameters))" << endl;
+ stream << " {" << endl;
+ stream << " error = m_baseProxy->lastError();" << endl;
+ stream << " return false;" << endl;
+ stream << " }" << endl;
+ stream << " return true;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+ 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 << " error = TQT_DBusError();";
+ stream << endl;
+
+ stream << " return (asyncCallId != 0);" << endl;
+ stream << "}" << endl;
+ stream << endl;
+ return;
+ }
+
+ stream << " TQT_DBusMessage reply = m_baseProxy->sendWithReply(\"";
+ stream << method.name << "\", parameters, &error);" << endl;
+ stream << endl;
+
+ stream << " if (reply.type() != TQT_DBusMessage::ReplyMessage) return false;"
+ << endl;
+
+ if (outCount == 0)
+ {
+ stream << " return true;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+ return;
+ }
+
+ stream << endl;
+
+ // TODO: create error or use enum for return
+ stream << " if (reply.count() != " << outCount << ") return false;" << endl;
+ stream << endl;
+
+ bool firstAccessor = true;
+ bool firstSubAccessor = true;
+
+ it = method.arguments.begin();
+ for (; it != endIt; ++it)
+ {
+ if ((*it).direction == Argument::In) continue;
+
+ --outCount;
+
+ if (!(*it).annotatedType.isEmpty())
+ {
+ // TODO error handling
+ stream << " if (TQT_DBusDataConverter::convertFromTQT_DBusData<"
+ << (*it).annotatedType << ">(reply.front(), "
+ << (*it).name
+ << ") != TQT_DBusDataConverter::Success) return false;"
+ << endl;
+ }
+ else if (!(*it).accessor.isEmpty())
+ {
+ if (firstAccessor)
+ {
+ stream << " bool ok = false;" << endl;
+ stream << endl;
+ firstAccessor = false;
+ }
+
+ if ((*it).subAccessor.isEmpty())
+ {
+ stream << " " << (*it).name << " = reply.front().to"
+ << (*it).accessor << "(&ok);" << endl;
+ }
+ else
+ {
+ if (firstSubAccessor)
+ {
+ stream << " bool subOK = false;" << endl;
+ stream << endl;
+ firstSubAccessor = false;
+ }
+
+ stream << " " << (*it).name << " = reply.front().to"
+ << (*it).accessor << "(&ok).to" << (*it).subAccessor
+ << "(&subOK);" << endl;
+
+ // TODO: create error or use enum for return
+ stream << " if (!subOK) return false;" << endl;
+ }
+
+ // TODO: create error or use enum for return
+ stream << " if (!ok) return false;" << endl;
+ }
+ else
+ stream << " " << (*it).name << " = reply.front();" << endl;
+ stream << endl;
+
+ if (outCount > 0)
+ {
+ stream << " reply.pop_front();" << endl;
+ stream << endl;
+ }
+ }
+
+ stream << " return true;" << endl;
+
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeProxyGenericProperty(const Class& classData,
+ TQTextStream& stream)
+{
+ stream << "void " << classData.name
+ << "::setDBusProperty(const TQString& name, "
+ << "const TQT_DBusVariant& value, TQT_DBusError& error)"
+ << endl;
+ stream << "{" << endl;
+
+ stream << " TQT_DBusConnection connection = m_baseProxy->connection();" << endl;
+ stream << endl;
+ stream << " TQT_DBusMessage message = TQT_DBusMessage::methodCall("
+ << "m_baseProxy->service(), m_baseProxy->path(), "
+ << "\"org.freedesktop.DBus.Properties\", \"Set\");" << endl;
+ stream << endl;
+
+ stream << " message << TQT_DBusData::fromString(m_baseProxy->interface());"
+ << endl;
+ stream << " message << TQT_DBusData::fromString(name);" << endl;
+ stream << " message << TQT_DBusData::fromVariant(value);" << endl;
+ stream << endl;
+
+ stream << " connection.sendWithReply(message, &error);" << endl;
+
+ stream << "}" << endl;
+
+ stream << endl;
+
+ stream << "TQT_DBusVariant " << classData.name
+ << "::getDBusProperty(const TQString& name, TQT_DBusError& error) const"
+ << endl;
+ stream << "{" << endl;
+
+ stream << " TQT_DBusConnection connection = m_baseProxy->connection();" << endl;
+ stream << endl;
+
+ stream << " TQT_DBusMessage message = TQT_DBusMessage::methodCall("
+ << "m_baseProxy->service(), m_baseProxy->path(), "
+ << "\"org.freedesktop.DBus.Properties\", \"Get\");" << endl;
+ stream << endl;
+
+ stream << " message << TQT_DBusData::fromString(m_baseProxy->interface());"
+ << endl;
+ stream << " message << TQT_DBusData::fromString(name);" << endl;
+ stream << endl;
+
+ stream << " TQT_DBusMessage reply = connection.sendWithReply(message, &error);"
+ << endl;
+ stream << endl;
+
+ stream << " if (reply.type() != TQT_DBusMessage::ReplyMessage)"
+ << " return TQT_DBusVariant();" << endl;
+ stream << " if (reply.count() != 1) return TQT_DBusVariant();" << endl;
+
+ stream << endl;
+
+ stream << " bool ok = false;" << endl;
+ stream << " TQT_DBusVariant value = reply.front().toVariant(&ok);" << endl;
+
+ // TODO generate error
+ stream << " if (!ok) return TQT_DBusVariant();" << endl;
+ stream << endl;
+
+ stream << " return value;" << endl;
+
+ stream << "}" << endl;
+
+ stream << endl;
+}
+
+void MethodGenerator::writeProxyProperty(const Class& classData,
+ const Property& property, TQTextStream& stream)
+{
+ if (property.write)
+ {
+ stream << "void " << classData.name << "::set" << property.name << "(";
+
+ if (!property.isPrimitive) stream << "const ";
+
+ stream << property.signature;
+
+ if (!property.isPrimitive) stream << "&";
+
+ stream << " value, TQT_DBusError& error)" << endl;
+ stream << "{" << endl;
+ stream << " TQT_DBusVariant variant;" << endl;
+
+ if (!property.annotatedType.isEmpty())
+ {
+ // TODO: error handling
+ stream << " TQT_DBusDataConverter::convertToTQT_DBusData<"
+ << property.annotatedType << ">(value, variant.value);"
+ << endl;
+ }
+ else if (!property.accessor.isEmpty())
+ {
+ stream << " variant.value = TQT_DBusData::from"
+ << property.accessor << "(";
+
+ if (property.subAccessor.isEmpty())
+ stream << "value";
+ else
+ stream << property.containerClass << "(value)";
+
+ stream << ");" << endl;
+ }
+ else
+ stream << " variant.value = TQT_DBusData(value);" << endl;
+
+ stream << " variant.signature = \"" << property.dbusSignature << "\";"
+ << endl;
+
+ stream << endl;
+ stream << " setDBusProperty(\"" << property.name
+ << "\", variant, error);" << endl;
+
+ stream << "}" << endl;
+ stream << endl;
+ }
+
+ if (property.read)
+ {
+ stream << property.signature << " " << classData.name
+ << "::get" << property.name << "(TQT_DBusError& error) const" << endl;
+ stream << "{" << endl;
+
+ stream << " TQT_DBusVariant variant = getDBusProperty(\""
+ << property.name << "\", error);" << endl;
+ stream << endl;
+ stream << " if (error.isValid()) return "
+ << property.signature << "();" << endl;
+ stream << endl;
+
+ if (!property.annotatedType.isEmpty())
+ {
+ stream << " " << property.signature << " result;" << endl;
+
+ // TODO error handling
+ stream << " TQT_DBusDataConverter::convertFromTQT_DBusData<"
+ << property.annotatedType << ">(variant.value, result);"
+ << endl;
+ }
+ else if (!property.accessor.isEmpty())
+ {
+ stream << " bool ok = false;" << endl;
+ stream << endl;
+
+ if (property.subAccessor.isEmpty())
+ {
+ stream << " " << property.signature << " result = ";
+ stream << " variant.value.to" << property.accessor
+ << "(&ok);" << endl;
+ }
+ else
+ {
+ stream << " bool subOK = false;" << endl;
+ stream << endl;
+
+ stream << " " << property.signature << " result = ";
+ stream << " variant.value.to"
+ << property.accessor << "(&ok).to" << property.subAccessor
+ << "(&subOK);" << endl;
+
+ // TODO: create error
+ stream << " if (!subOK) {}" << endl;
+ }
+
+ // TODO: create error
+ stream << " if (!ok) {}" << endl;
+ }
+ else
+ stream << " " << property.signature << " result = variant.value;";
+ stream << endl;
+
+ stream << " return result;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+ }
+}
+
+void MethodGenerator::writeProxyAsyncReplyHandler(const Class& classData,
+ TQTextStream& stream)
+{
+ stream << "void " << classData.name
+ << "::slotHandleAsyncReply(int asyncCallId, const TQT_DBusMessage& message)" << endl;
+ stream << "{" << endl;
+
+ stream << " TQMap<int, TQString>::iterator findIt = "
+ << "m_asyncCalls.find(asyncCallId);" << endl;
+ stream << " if (findIt == m_asyncCalls.end()) return;" << endl;
+ stream << endl;
+ stream << " const TQString signalName = findIt.data();" << endl;
+ stream << " m_asyncCalls.erase(findIt);" << endl;
+ stream << endl;
+
+ TQValueList<Method>::const_iterator it = classData.asyncReplySignals.begin();
+ TQValueList<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 << endl;
+
+ stream << " if (message.type() == TQT_DBusMessage::ErrorMessage) {" << endl;
+ stream << " emit AsyncErrorResponseDetected(_asyncCallId, message.error());" << endl;
+ stream << " }" << endl << 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,
+ TQTextStream& stream)
+{
+ stream << "void " << classData.name
+ << "::buildIntrospectionData(TQDomElement& interfaceElement)" << endl;
+ stream << "{" << endl;
+
+ stream << " interfaceElement.setAttribute(\"name\", \""
+ << classData.dbusName << "\");" << endl;
+ stream << endl;
+
+ bool firstMethod = true;
+ bool firstArgument = true;
+
+ TQValueList<Method>::const_iterator it = classData.methods.begin();
+ TQValueList<Method>::const_iterator endIt = classData.methods.end();
+ for (; it != endIt; ++it)
+ {
+ if (firstMethod)
+ {
+ firstMethod = false;
+ stream << " TQDomDocument document = interfaceElement.ownerDocument();" << endl;
+ stream << " TQDomElement methodElement = document.createElement("
+ << "\"method\");" << endl;
+ }
+ else
+ {
+ stream << endl;
+ stream << " methodElement = document.createElement("
+ << "\"method\");" << endl;
+ }
+
+ writeMethodIntrospection(*it, firstArgument, stream);
+
+ stream << " interfaceElement.appendChild(methodElement);" << endl;
+ }
+
+ it = classData.msignals.begin();
+ endIt = classData.msignals.end();
+ for (; it != endIt; ++it)
+ {
+ if (firstMethod)
+ {
+ firstMethod = false;
+ stream << " TQDomDocument document = interfaceElement.ownerDocument();" << endl;
+ stream << endl;
+ stream << " TQDomElement methodElement = document.createElement("
+ << "\"signal\");" << endl;
+ }
+ else
+ {
+ stream << endl;
+ stream << " methodElement = document.createElement("
+ << "\"signal\");" << endl;
+ }
+
+ writeMethodIntrospection(*it, firstArgument, stream);
+
+ stream << " interfaceElement.appendChild(methodElement);" << endl;
+ }
+
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeNodePrivate(const Class& classData, TQTextStream& stream)
+{
+ stream << "class " << classData.name
+ << "::Private : public org::freedesktop::DBus::Introspectable" << endl;
+ stream << "{" << endl;
+ stream << "public:" << endl;
+ stream << " virtual ~Private();" << endl;
+ stream << endl;
+
+ stream << "public:" << endl;
+ stream << " TQMap<TQString, TQT_DBusObjectBase*> interfaces;" << endl;
+ stream << " TQString introspectionData;" << endl;
+ stream << endl;
+ stream << " TQT_DBusConnection connection;" << endl;
+ stream << " TQString objectPath;" << endl;
+ stream << endl;
+
+ stream << "protected:" << endl;
+ stream << " virtual bool Introspect(TQString& data, TQT_DBusError& error);"
+ << endl;
+ stream << endl;
+ stream << " virtual void handleMethodReply(const TQT_DBusMessage& reply);"
+ << endl;
+
+ stream << "private:" << endl;
+ stream << " void cacheIntrospectionData();" << endl;
+
+ stream << "};" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeNodeBegin(const Class& classData, TQTextStream& stream)
+{
+ stream << classData.name << "::" << classData.name
+ << "() : TQT_DBusObjectBase()," << endl;
+ stream << " m_private(new Private())" << endl;
+ stream << "{" << endl;
+ stream << "}" << endl;
+ stream << endl;
+
+ stream << classData.name << "::~" << classData.name << "()" << endl;
+ stream << "{" << endl;
+ stream << " unregisterObject();" << endl;
+ stream << endl;
+ stream << " delete m_private;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+}
+
+void MethodGenerator::writeNodeMethods(const Class& classData,
+ const TQValueList<Class>& interfaces, TQTextStream& stream)
+{
+ writeNodeInitialization(classData, interfaces, stream);
+
+ stream << "void " << classData.name << "::unregisterObject()" << endl;
+ stream << "{" << endl;
+ stream << " if (m_private->objectPath.isEmpty()) return;" << endl;
+ stream << endl;
+ stream << " m_private->connection.unregisterObject(m_private->objectPath);" << endl;
+ stream << endl;
+ stream << " m_private->connection = TQT_DBusConnection();" << endl;
+ stream << " m_private->objectPath = TQString();" << endl;
+ stream << "}" << endl;
+ stream << endl;
+
+ stream << "bool " << classData.name
+ << "::handleMethodCall(const TQT_DBusMessage& message)" << endl;
+ stream << "{" << endl;
+ stream << " TQMap<TQString, TQT_DBusObjectBase*>::iterator findIt = "
+ << "m_private->interfaces.find(message.interface());" << endl;
+ stream << " if (findIt == m_private->interfaces.end()) return false;"
+ << endl;
+ stream << endl;
+ stream << " return delegateMethodCall(message, findIt.data());" << endl;
+ stream << "}" << endl;
+ stream << endl;
+
+ stream << classData.name << "::Private::~Private()" << endl;
+ stream << "{" << endl;
+ stream << " TQMap<TQString, TQT_DBusObjectBase*>::const_iterator it = "
+ << "interfaces.begin();" << endl;
+ stream << " TQMap<TQString, TQT_DBusObjectBase*>::const_iterator endIt = "
+ << "interfaces.end();" << endl;
+ stream << " for (; it != endIt; ++it)" << endl;
+ stream << " {" << endl;
+ stream << " TQT_DBusObjectBase* interface = it.data();" << endl;
+ stream << " if (interface != this)" << endl;
+ stream << " delete interface;" << endl;
+ stream << " }" << endl;
+ stream << " interfaces.clear();" << endl;
+ stream << "}" << endl;
+ stream << endl;
+
+ stream << "bool " << classData.name << "::Private"
+ << "::Introspect(TQString& data, TQT_DBusError& error)" << endl;
+ stream << "{" << endl;
+ stream << " Q_UNUSED(error);" << endl;
+ stream << " if (introspectionData.isEmpty()) cacheIntrospectionData();"
+ << endl;
+ stream << endl;
+ stream << " data = introspectionData;" << endl;
+ stream << endl;
+ stream << " return true;" << endl;
+ stream << "}" << endl;
+ stream << endl;
+
+ stream << "void " << classData.name << "::Private"
+ << "::handleMethodReply(const TQT_DBusMessage& reply)" << endl;
+ stream << "{" << endl;
+ stream << " connection.send(reply);" << endl;
+ stream << "}" << endl;
+ stream << endl;
+
+ writeNodeIntrospection(classData, interfaces, stream);
+}
+
+// End of File
diff --git a/src/tools/dbusxml2qt3/methodgen.h b/src/tools/dbusxml2qt3/methodgen.h
new file mode 100644
index 0000000..9954fb2
--- /dev/null
+++ b/src/tools/dbusxml2qt3/methodgen.h
@@ -0,0 +1,153 @@
+/*
+* Copyright (C) 2007 Kevin Krammer <[email protected]>
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#if !defined(METHODGEN_H_INCLUDED)
+#define METHODGEN_H_INCLUDED
+
+// TQt includes
+#include <tqmap.h>
+#include <tqstringlist.h>
+
+// forward declarations
+class TQTextStream;
+
+class Argument
+{
+public:
+ enum Direction
+ {
+ In,
+ Out
+ };
+
+ TQString name;
+ TQString annotatedType;
+ TQString signature;
+ TQString accessor;
+ TQString subAccessor;
+ TQString containerClass;
+ Direction direction;
+ bool isPrimitive;
+
+ TQStringList forwardDeclarations;
+ TQMap<TQString, TQStringList> headerIncludes;
+ TQMap<TQString, TQStringList> sourceIncludes;
+
+ TQString dbusSignature;
+};
+
+class Method
+{
+public:
+ TQString name;
+ TQValueList<Argument> arguments;
+ bool noReply;
+ bool async;
+};
+
+class Property : public Argument
+{
+public:
+ bool read;
+ bool write;
+};
+
+class Class
+{
+public:
+ enum Role
+ {
+ Interface,
+ Proxy,
+ Node
+ };
+
+ TQString name;
+ TQString dbusName;
+ TQStringList namespaces;
+ TQValueList<Method> methods;
+ TQValueList<Method> msignals;
+ TQValueList<Property> properties;
+
+ TQValueList<Method> asyncMethods;
+ TQValueList<Method> asyncReplySignals;
+ TQValueList<Method> asyncReplyMethods;
+};
+
+class MethodGenerator
+{
+public:
+ static bool extractMethods(const TQDomElement& interfaceElement,
+ Class& classData);
+
+ static void writeMethodDeclaration(const Method& method, bool pureVirtual,
+ bool withError, TQTextStream& stream);
+
+ static void writePropertyDeclaration(const Property& property, bool pureVirtual,
+ TQTextStream& stream);
+
+ static void writeMethodCallDeclaration(const Method& method,
+ TQTextStream& stream);
+
+ static void writeMethodCall(const Class& classData, const Method& method,
+ TQTextStream& stream);
+
+ static void writeSignalEmitter(const Class& classData, const Method& method,
+ TQTextStream& stream);
+
+ static void writeInterfaceAsyncReplyHandler(const Class& classData,
+ const Method& method,
+ TQTextStream& stream);
+
+ static void writeInterfaceMainMethod(const Class& classData,
+ TQTextStream& stream);
+
+ static void writeSignalHandler(const Class& classData, TQTextStream& stream);
+
+ static void writeProxyBegin(const Class& classData, TQTextStream& stream);
+
+ static void writeProxyMethod(const TQString& className, const Method& method,
+ TQTextStream& stream);
+
+ static void writeProxyGenericProperty(const Class& classData,
+ TQTextStream& stream);
+
+ static void writeProxyProperty(const Class& classData, const Property& property,
+ TQTextStream& stream);
+
+ static void writeProxyAsyncReplyHandler(const Class& classData,
+ TQTextStream& stream);
+
+ static void writeIntrospectionDataMethod(const Class& classData,
+ TQTextStream& stream);
+
+ static void writeNodePrivate(const Class& classData, TQTextStream& stream);
+
+ static void writeNodeBegin(const Class& classData, TQTextStream& stream);
+
+ static void writeNodeMethods(const Class& classData,
+ const TQValueList<Class>& interfaces, TQTextStream& stream);
+};
+
+#endif
+
+// End of File