diff --git a/configure.ac b/configure.ac index 7d87ee9..965eb33 100644 --- a/configure.ac +++ b/configure.ac @@ -202,6 +202,7 @@ AC_OUTPUT( doc/Doxyfile examples/Makefile examples/properties/Makefile + examples/properties_get_set/Makefile examples/echo/Makefile examples/ecore/Makefile examples/hal/Makefile diff --git a/examples/Makefile.am b/examples/Makefile.am index a940bc8..d3cbb7c 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = properties echo hal glib ecore +SUBDIRS = properties properties_get_set echo hal glib MAINTAINERCLEANFILES = \ Makefile.in diff --git a/examples/echo/Makefile.am b/examples/echo/Makefile.am index 713c749..63fe2eb 100644 --- a/examples/echo/Makefile.am +++ b/examples/echo/Makefile.am @@ -10,9 +10,7 @@ echo_server_LDADD = $(top_builddir)/src/libdbus-c++-1.la echo-server-glue.h: echo-introspect.xml $(top_builddir)/tools/dbusxx-xml2cpp $^ --adaptor=$@ -if HAVE_PTHREAD noinst_PROGRAMS += echo-client-mt -endif echo_client_mt_SOURCES = echo-client-glue.h echo-client.h echo-client.cpp echo_client_mt_LDADD = $(top_builddir)/src/libdbus-c++-1.la @PTHREAD_LIBS@ diff --git a/examples/echo/echo-client.h b/examples/echo/echo-client.h index abfb620..54401ec 100644 --- a/examples/echo/echo-client.h +++ b/examples/echo/echo-client.h @@ -5,7 +5,7 @@ #include "echo-client-glue.h" class EchoClient -: public org::freedesktop::DBus::EchoDemo, +: public org::freedesktop::DBus::EchoDemo_proxy, public DBus::IntrospectableProxy, public DBus::ObjectProxy { diff --git a/examples/echo/echo-server.h b/examples/echo/echo-server.h index 94d597e..3f0be58 100644 --- a/examples/echo/echo-server.h +++ b/examples/echo/echo-server.h @@ -5,7 +5,7 @@ #include "echo-server-glue.h" class EchoServer -: public org::freedesktop::DBus::EchoDemo, +: public org::freedesktop::DBus::EchoDemo_adaptor, public DBus::IntrospectableAdaptor, public DBus::ObjectAdaptor { diff --git a/examples/properties/props-server.h b/examples/properties/props-server.h index cf9ba83..574ec40 100644 --- a/examples/properties/props-server.h +++ b/examples/properties/props-server.h @@ -5,7 +5,7 @@ #include "props-glue.h" class PropsServer -: public org::freedesktop::DBus::PropsDemo, +: public org::freedesktop::DBus::PropsDemo_adaptor, public DBus::IntrospectableAdaptor, public DBus::PropertiesAdaptor, public DBus::ObjectAdaptor diff --git a/examples/properties_get_set/Makefile.am b/examples/properties_get_set/Makefile.am new file mode 100644 index 0000000..6e5419d --- /dev/null +++ b/examples/properties_get_set/Makefile.am @@ -0,0 +1,26 @@ +EXTRA_DIST = propsget-introspect.xml + +AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include + +noinst_PROGRAMS = propsgs-server propsgs-client + +propsgs_server_SOURCES = propsgs-glue.h propsgs-server.h propsgs-server.cpp +propsgs_server_LDADD = $(top_builddir)/src/libdbus-c++-1.la + +propsgs_client_SOURCES = propsgs-glue.h propsgs-client.h propsgs-client.cpp +propsgs_client_LDADD = $(top_builddir)/src/libdbus-c++-1.la -lpthread + +propsgs-glue-adaptor.h: propsgs-introspect.xml + $(top_builddir)/tools/dbusxx-xml2cpp $^ --adaptor=$@ -- + +propsgs-glue-proxy.h: propsgs-introspect.xml + $(top_builddir)/tools/dbusxx-xml2cpp $^ --proxy=$@ -- + +BUILT_SOURCES = propsgs-glue-adaptor.h propsgs-glue-proxy.h +CLEANFILES = $(BUILT_SOURCES) + +dist-hook: + cd $(distdir); rm -f $(BUILT_SOURCES) + +MAINTAINERCLEANFILES = \ + Makefile.in diff --git a/examples/properties_get_set/propsgs-client.cpp b/examples/properties_get_set/propsgs-client.cpp new file mode 100644 index 0000000..b47ad39 --- /dev/null +++ b/examples/properties_get_set/propsgs-client.cpp @@ -0,0 +1,75 @@ +#include "propsgs-client.h" +#include +#include + +using namespace org::freedesktop::DBus; + +#define P(x) std::cout << #x << " = " << x << std::endl; + +static const char *PROPS_SERVER_NAME = "org.freedesktop.DBus.Examples.Properties"; +static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties"; + +PropsClient::PropsClient(DBus::Connection &connection, const char *path, const char *name) +: DBus::ObjectProxy(connection, path, name) +{ +} + +void PropsClient::MessageChanged(const std::string& message){ + std::cout << "message received: " << message << std::endl; +}; + +DBus::BusDispatcher dispatcher; + +PropsClient * client; + +void niam(int sig) +{ + dispatcher.leave(); + pthread_exit(NULL); + delete client; +} + +#include + +void * test_property_proxy(void * input){ + P("1"); + sleep(2); + P(client->Version()); + + P("2"); + sleep(1); + P(client->Message()); + + P("3"); + sleep(1); + client->Message( "message set by property access" ); + + P("4"); + sleep(1); + P(client->Message()); + + P("5"); + sleep(1); + client->Data( 1.1 ); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SessionBus(); + + client = new PropsClient(conn, PROPS_SERVER_PATH, PROPS_SERVER_NAME ); + + pthread_t thread; + pthread_create(&thread, NULL, test_property_proxy, 0); + + P("dispatcher.enter();"); + + dispatcher.enter(); + + return 0; +} diff --git a/examples/properties_get_set/propsgs-client.h b/examples/properties_get_set/propsgs-client.h new file mode 100644 index 0000000..85595d5 --- /dev/null +++ b/examples/properties_get_set/propsgs-client.h @@ -0,0 +1,20 @@ +#ifndef __DEMO_PROPS_SERVER_H +#define __DEMO_PROPS_SERVER_H + +#include +#include "propsgs-glue-proxy.h" + +class PropsClient +: public org::freedesktop::DBus::PropsGSDemo_proxy, + public DBus::IntrospectableProxy, +// public DBus::PropertiesProxy, + public DBus::ObjectProxy +{ +public: + + PropsClient(DBus::Connection &connection, const char *path, const char *name); + + void MessageChanged(const std::string& message); +}; + +#endif//__DEMO_PROPS_SERVER_H diff --git a/examples/properties_get_set/propsgs-introspect.xml b/examples/properties_get_set/propsgs-introspect.xml new file mode 100644 index 0000000..5c0e74f --- /dev/null +++ b/examples/properties_get_set/propsgs-introspect.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/examples/properties_get_set/propsgs-server.cpp b/examples/properties_get_set/propsgs-server.cpp new file mode 100644 index 0000000..8339d20 --- /dev/null +++ b/examples/properties_get_set/propsgs-server.cpp @@ -0,0 +1,46 @@ +#include "propsgs-server.h" +#include + +static const char *PROPS_SERVER_NAME = "org.freedesktop.DBus.Examples.Properties"; +static const char *PROPS_SERVER_PATH = "/org/freedesktop/DBus/Examples/Properties"; + +PropsServer::PropsServer(DBus::Connection &connection) +: DBus::ObjectAdaptor(connection, PROPS_SERVER_PATH) +{ + Version = 1; + Message = "default message"; +} + +void PropsServer::on_set_property + (DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value) +{ + if (property == "Message") + { + std::string msg = value; + this->MessageChanged(msg); + } +} + +DBus::BusDispatcher dispatcher; + +void niam(int sig) +{ + dispatcher.leave(); +} + +int main() +{ + signal(SIGTERM, niam); + signal(SIGINT, niam); + + DBus::default_dispatcher = &dispatcher; + + DBus::Connection conn = DBus::Connection::SessionBus(); + conn.request_name(PROPS_SERVER_NAME); + + PropsServer server(conn); + + dispatcher.enter(); + + return 0; +} diff --git a/examples/properties_get_set/propsgs-server.h b/examples/properties_get_set/propsgs-server.h new file mode 100644 index 0000000..a3169d6 --- /dev/null +++ b/examples/properties_get_set/propsgs-server.h @@ -0,0 +1,21 @@ +#ifndef __DEMO_PROPS_SERVER_H +#define __DEMO_PROPS_SERVER_H + +#include +#include "propsgs-glue-adaptor.h" + +class PropsServer +: public org::freedesktop::DBus::PropsGSDemo_adaptor, + public DBus::IntrospectableAdaptor, + public DBus::PropertiesAdaptor, + public DBus::ObjectAdaptor +{ +public: + + PropsServer(DBus::Connection &connection); + + void on_set_property + (DBus::InterfaceAdaptor &interface, const std::string &property, const DBus::Variant &value); +}; + +#endif//__DEMO_PROPS_SERVER_H diff --git a/include/dbus-c++/eventloop.h b/include/dbus-c++/eventloop.h index ac44a0f..edaed42 100644 --- a/include/dbus-c++/eventloop.h +++ b/include/dbus-c++/eventloop.h @@ -27,10 +27,7 @@ #include "dbus-c++-config.h" -#ifdef HAVE_PTHREAD_H #include -#endif - #include #include "api.h" @@ -141,15 +138,7 @@ public: private: -#if defined HAVE_PTHREAD_H - pthread_mutex_t _mutex; - -#elif defined HAVE_WIN32 - -//TODO: use a critical section - -#endif }; class DXXAPI DefaultMainLoop diff --git a/src/eventloop.cpp b/src/eventloop.cpp index 5112231..7d96777 100644 --- a/src/eventloop.cpp +++ b/src/eventloop.cpp @@ -78,42 +78,22 @@ DefaultWatch::~DefaultWatch() DefaultMutex::DefaultMutex() { -#if defined HAVE_PTHREAD_H - pthread_mutex_init(&_mutex, NULL); - -#elif defined HAVE_WIN32 -#endif } DefaultMutex::~DefaultMutex() { -#if defined HAVE_PTHREAD_H - pthread_mutex_destroy(&_mutex); - -#elif defined HAVE_WIN32 -#endif } void DefaultMutex::lock() { -#if defined HAVE_PTHREAD_H - pthread_mutex_lock(&_mutex); - -#elif defined HAVE_WIN32 -#endif } void DefaultMutex::unlock() { -#if defined HAVE_PTHREAD_H - pthread_mutex_unlock(&_mutex); - -#elif defined HAVE_WIN32 -#endif } DefaultMainLoop::DefaultMainLoop() diff --git a/src/interface.cpp b/src/interface.cpp index 63bc443..f1cd68f 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -74,7 +74,9 @@ void InterfaceAdaptor::emit_signal(const SignalMessage &sig) { SignalMessage &sig2 = const_cast(sig); - sig2.interface(name().c_str()); + if (sig2.interface() == NULL) + sig2.interface(name().c_str()); + _emit_signal(sig2); } @@ -151,6 +153,8 @@ Message InterfaceProxy::invoke_method(const CallMessage &call) { CallMessage &call2 = const_cast(call); - call2.interface(name().c_str()); + if (call.interface() == NULL) + call2.interface(name().c_str()); + return _invoke_method(call2); } diff --git a/src/object.cpp b/src/object.cpp index 13b7052..9148cb2 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -324,8 +324,11 @@ void ObjectProxy::unregister_obj() Message ObjectProxy::_invoke_method(CallMessage &call) { - call.path(path().c_str()); - call.destination(service().c_str()); + if (call.path() == NULL) + call.path(path().c_str()); + + if (call.destination() == NULL) + call.destination(service().c_str()); return conn().send_blocking(call); } diff --git a/tools/xml2cpp.cpp b/tools/xml2cpp.cpp index 25a32d2..45c8dde 100644 --- a/tools/xml2cpp.cpp +++ b/tools/xml2cpp.cpp @@ -257,6 +257,8 @@ void generate_proxy(Xml::Document &doc, const char *filename) getline(ss, ifaceclass); + ifaceclass += "_proxy"; + cerr << "generating code for interface " << ifacename << "..." << endl; file << "class " << ifaceclass << endl @@ -281,6 +283,62 @@ void generate_proxy(Xml::Document &doc, const char *filename) file << tab << "}" << endl << endl; +/// write properties + file << "public:" << endl << endl + << tab << "/* properties exported by this interface */" << endl; + + for (Xml::Nodes::iterator pi = properties.begin (); + pi != properties.end (); ++pi) + { + Xml::Node & property = **pi; + string prop_name = property.get ("name"); + string property_access = property.get ("access"); + if (property_access == "read" || property_access == "readwrite") + { + file << tab << tab << "const " << signature_to_type (property.get("type")) + << " " << prop_name << "() {" << endl; + file << tab << tab << tab << "::DBus::CallMessage call ;\n "; + file << tab << tab << tab + << "call.member(\"Get\"); call.interface(\"org.freedesktop.DBus.Properties\");" + << endl; + file << tab << tab << tab + << "::DBus::MessageIter wi = call.writer(); " << endl; + file << tab << tab << tab + << "const std::string interface_name = \"" << ifacename << "\";" + << endl; + file << tab << tab << tab + << "const std::string property_name = \"" << prop_name << "\";" + << endl; + file << tab << tab << tab << "wi << interface_name;" << endl; + file << tab << tab << tab << "wi << property_name;" << endl; + file << tab << tab << tab + << "::DBus::Message ret = this->invoke_method (call);" << endl; + file << tab << tab << tab + << "::DBus::MessageIter ri = ret.reader ();" << endl; + file << tab << tab << tab << "::DBus::Variant argout; " << endl; + file << tab << tab << tab << "ri >> argout;" << endl; + file << tab << tab << tab << "return argout;" << endl; + file << tab << tab << "};" << endl; + } + + if (property_access == "write" || property_access == "readwrite") + { + file << tab << tab << "void " << prop_name << "( const "<< signature_to_type (property.get("type")) << " & input" << ") {" << endl; + file << tab << tab << tab << "::DBus::CallMessage call ;\n "; + file << tab << tab << tab <<"call.member(\"Set\"); call.interface( \"org.freedesktop.DBus.Properties\");"<< endl; + file << tab << tab << tab <<"::DBus::MessageIter wi = call.writer(); " << endl; + file << tab << tab << tab <<"::DBus::Variant value;" << endl; + file << tab << tab << tab <<"::DBus::MessageIter vi = value.writer ();" << endl; + file << tab << tab << tab <<"vi << input;" << endl; + file << tab << tab << tab <<"const std::string interface_name = \"" << ifacename << "\";" << endl; + file << tab << tab << tab <<"const std::string property_name = \"" << prop_name << "\";"<< endl; + file << tab << tab << tab <<"wi << interface_name;" << endl; + file << tab << tab << tab <<"wi << property_name;" << endl; + file << tab << tab << tab <<"wi << value;" << endl; + file << tab << tab << tab <<"::DBus::Message ret = this->invoke_method (call);" << endl; + file << tab << tab << "};" << endl; + } + } file << "public:" << endl << endl @@ -560,6 +618,8 @@ void generate_adaptor(Xml::Document &doc, const char *filename) getline(ss, ifaceclass); + ifaceclass += "_adaptor"; + cerr << "generating code for interface " << ifacename << "..." << endl; file << "class " << ifaceclass << endl