* Nested objects introspection patch (David Belser)
* More indentation in generated code (David Belser) * Avoid redundant calls to dbus_bus_add_match (David Belser) * Typo in HAVE_PTHREAD_H macro (Olivier Hochreutiner) * Allow other listeners to receive the same signal, if any (Olivier Hochreutiner)
This commit is contained in:
parent
ecd2428049
commit
68a722e6d1
10 changed files with 89 additions and 64 deletions
50
INSTALL
50
INSTALL
|
@ -1,8 +1,8 @@
|
||||||
Installation Instructions
|
Installation Instructions
|
||||||
*************************
|
*************************
|
||||||
|
|
||||||
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 Free
|
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
|
||||||
Software Foundation, Inc.
|
2006 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This file is free documentation; the Free Software Foundation gives
|
This file is free documentation; the Free Software Foundation gives
|
||||||
unlimited permission to copy, distribute and modify it.
|
unlimited permission to copy, distribute and modify it.
|
||||||
|
@ -10,7 +10,10 @@ unlimited permission to copy, distribute and modify it.
|
||||||
Basic Installation
|
Basic Installation
|
||||||
==================
|
==================
|
||||||
|
|
||||||
These are generic installation instructions.
|
Briefly, the shell commands `./configure; make; make install' should
|
||||||
|
configure, build, and install this package. The following
|
||||||
|
more-detailed instructions are generic; see the `README' file for
|
||||||
|
instructions specific to this package.
|
||||||
|
|
||||||
The `configure' shell script attempts to guess correct values for
|
The `configure' shell script attempts to guess correct values for
|
||||||
various system-dependent variables used during compilation. It uses
|
various system-dependent variables used during compilation. It uses
|
||||||
|
@ -23,9 +26,9 @@ debugging `configure').
|
||||||
|
|
||||||
It can also use an optional file (typically called `config.cache'
|
It can also use an optional file (typically called `config.cache'
|
||||||
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||||
the results of its tests to speed up reconfiguring. (Caching is
|
the results of its tests to speed up reconfiguring. Caching is
|
||||||
disabled by default to prevent problems with accidental use of stale
|
disabled by default to prevent problems with accidental use of stale
|
||||||
cache files.)
|
cache files.
|
||||||
|
|
||||||
If you need to do unusual things to compile the package, please try
|
If you need to do unusual things to compile the package, please try
|
||||||
to figure out how `configure' could check whether to do them, and mail
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
@ -35,20 +38,17 @@ some point `config.cache' contains results you don't want to keep, you
|
||||||
may remove or edit it.
|
may remove or edit it.
|
||||||
|
|
||||||
The file `configure.ac' (or `configure.in') is used to create
|
The file `configure.ac' (or `configure.in') is used to create
|
||||||
`configure' by a program called `autoconf'. You only need
|
`configure' by a program called `autoconf'. You need `configure.ac' if
|
||||||
`configure.ac' if you want to change it or regenerate `configure' using
|
you want to change it or regenerate `configure' using a newer version
|
||||||
a newer version of `autoconf'.
|
of `autoconf'.
|
||||||
|
|
||||||
The simplest way to compile this package is:
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
1. `cd' to the directory containing the package's source code and type
|
1. `cd' to the directory containing the package's source code and type
|
||||||
`./configure' to configure the package for your system. If you're
|
`./configure' to configure the package for your system.
|
||||||
using `csh' on an old version of System V, you might need to type
|
|
||||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
|
||||||
`configure' itself.
|
|
||||||
|
|
||||||
Running `configure' takes awhile. While running, it prints some
|
Running `configure' might take a while. While running, it prints
|
||||||
messages telling which features it is checking for.
|
some messages telling which features it is checking for.
|
||||||
|
|
||||||
2. Type `make' to compile the package.
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ details on some of the pertinent environment variables.
|
||||||
by setting variables in the command line or in the environment. Here
|
by setting variables in the command line or in the environment. Here
|
||||||
is an example:
|
is an example:
|
||||||
|
|
||||||
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
./configure CC=c99 CFLAGS=-g LIBS=-lposix
|
||||||
|
|
||||||
*Note Defining Variables::, for more details.
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
|
@ -87,17 +87,15 @@ Compiling For Multiple Architectures
|
||||||
|
|
||||||
You can compile the package for more than one kind of computer at the
|
You can compile the package for more than one kind of computer at the
|
||||||
same time, by placing the object files for each architecture in their
|
same time, by placing the object files for each architecture in their
|
||||||
own directory. To do this, you must use a version of `make' that
|
own directory. To do this, you can use GNU `make'. `cd' to the
|
||||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
|
||||||
directory where you want the object files and executables to go and run
|
directory where you want the object files and executables to go and run
|
||||||
the `configure' script. `configure' automatically checks for the
|
the `configure' script. `configure' automatically checks for the
|
||||||
source code in the directory that `configure' is in and in `..'.
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
If you have to use a `make' that does not support the `VPATH'
|
With a non-GNU `make', it is safer to compile the package for one
|
||||||
variable, you have to compile the package for one architecture at a
|
architecture at a time in the source code directory. After you have
|
||||||
time in the source code directory. After you have installed the
|
installed the package for one architecture, use `make distclean' before
|
||||||
package for one architecture, use `make distclean' before reconfiguring
|
reconfiguring for another architecture.
|
||||||
for another architecture.
|
|
||||||
|
|
||||||
Installation Names
|
Installation Names
|
||||||
==================
|
==================
|
||||||
|
@ -190,12 +188,12 @@ them in the `configure' command line, using `VAR=value'. For example:
|
||||||
./configure CC=/usr/local2/bin/gcc
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
causes the specified `gcc' to be used as the C compiler (unless it is
|
causes the specified `gcc' to be used as the C compiler (unless it is
|
||||||
overridden in the site shell script). Here is a another example:
|
overridden in the site shell script).
|
||||||
|
|
||||||
/bin/bash ./configure CONFIG_SHELL=/bin/bash
|
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
|
||||||
|
an Autoconf bug. Until the bug is fixed you can use this workaround:
|
||||||
|
|
||||||
Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
|
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
|
||||||
configuration-related scripts to be executed by `/bin/bash'.
|
|
||||||
|
|
||||||
`configure' Invocation
|
`configure' Invocation
|
||||||
======================
|
======================
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
EXTRA_DIST = README echo-introspect.xml
|
EXTRA_DIST = README echo-introspect.xml
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
AM_CPPFLAGS = -I$(top_srcdir)/include -I$(top_builddir)/include
|
||||||
|
|
||||||
noinst_PROGRAMS = echo-server
|
noinst_PROGRAMS = echo-server
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PTHREAD
|
#ifdef HAVE_PTHREAD_H
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -143,9 +143,9 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
#if defined HAVE_PTHREAD
|
#if defined HAVE_PTHREAD_H
|
||||||
|
|
||||||
pthread_mutex _mutex;
|
pthread_mutex_t _mutex;
|
||||||
|
|
||||||
#elif defined HAVE_WIN32
|
#elif defined HAVE_WIN32
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "api.h"
|
#include "api.h"
|
||||||
#include "eventloop.h"
|
#include "dispatcher.h"
|
||||||
|
|
||||||
namespace DBus {
|
namespace DBus {
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,7 @@ public:
|
||||||
class ObjectAdaptor;
|
class ObjectAdaptor;
|
||||||
|
|
||||||
typedef std::list<ObjectAdaptor*> ObjectAdaptorPList;
|
typedef std::list<ObjectAdaptor*> ObjectAdaptorPList;
|
||||||
|
typedef std::list<std::string> ObjectPathList;
|
||||||
|
|
||||||
class DXXAPI ObjectAdaptor : public Object, public virtual AdaptorBase
|
class DXXAPI ObjectAdaptor : public Object, public virtual AdaptorBase
|
||||||
{
|
{
|
||||||
|
@ -113,6 +114,8 @@ public:
|
||||||
|
|
||||||
static ObjectAdaptorPList from_path_prefix( const std::string& prefix );
|
static ObjectAdaptorPList from_path_prefix( const std::string& prefix );
|
||||||
|
|
||||||
|
static ObjectPathList child_nodes_from_prefix( const std::string& prefix );
|
||||||
|
|
||||||
struct Private;
|
struct Private;
|
||||||
|
|
||||||
ObjectAdaptor( Connection& conn, const Path& path );
|
ObjectAdaptor( Connection& conn, const Path& path );
|
||||||
|
|
|
@ -8,9 +8,11 @@ GLIB_H = $(HEADER_DIR)/glib-integration.h
|
||||||
GLIB_CPP = glib-integration.cpp
|
GLIB_CPP = glib-integration.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
CONFIG_H = $(top_builddir)/include/dbus-c++/config.h
|
||||||
|
|
||||||
HEADER_DIR = $(top_srcdir)/include/dbus-c++
|
HEADER_DIR = $(top_srcdir)/include/dbus-c++
|
||||||
HEADER_FILES = \
|
HEADER_FILES = \
|
||||||
$(HEADER_DIR)/config.h \
|
$(CONFIG_H) \
|
||||||
$(HEADER_DIR)/dbus.h \
|
$(HEADER_DIR)/dbus.h \
|
||||||
$(HEADER_DIR)/types.h \
|
$(HEADER_DIR)/types.h \
|
||||||
$(HEADER_DIR)/connection.h \
|
$(HEADER_DIR)/connection.h \
|
||||||
|
|
|
@ -74,7 +74,7 @@ DefaultWatch::~DefaultWatch()
|
||||||
|
|
||||||
DefaultMutex::DefaultMutex()
|
DefaultMutex::DefaultMutex()
|
||||||
{
|
{
|
||||||
#if defined HAVE_PTHREAD
|
#if defined HAVE_PTHREAD_H
|
||||||
|
|
||||||
pthread_mutex_init(&_mutex, NULL);
|
pthread_mutex_init(&_mutex, NULL);
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ DefaultMutex::DefaultMutex()
|
||||||
|
|
||||||
DefaultMutex::~DefaultMutex()
|
DefaultMutex::~DefaultMutex()
|
||||||
{
|
{
|
||||||
#if defined HAVE_PTHREAD
|
#if defined HAVE_PTHREAD_H
|
||||||
|
|
||||||
pthread_mutex_destroy(&_mutex);
|
pthread_mutex_destroy(&_mutex);
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ DefaultMutex::~DefaultMutex()
|
||||||
|
|
||||||
void DefaultMutex::lock()
|
void DefaultMutex::lock()
|
||||||
{
|
{
|
||||||
#if defined HAVE_PTHREAD
|
#if defined HAVE_PTHREAD_H
|
||||||
|
|
||||||
pthread_mutex_lock(&_mutex);
|
pthread_mutex_lock(&_mutex);
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ void DefaultMutex::lock()
|
||||||
|
|
||||||
void DefaultMutex::unlock()
|
void DefaultMutex::unlock()
|
||||||
{
|
{
|
||||||
#if defined HAVE_PTHREAD
|
#if defined HAVE_PTHREAD_H
|
||||||
|
|
||||||
pthread_mutex_unlock(&_mutex);
|
pthread_mutex_unlock(&_mutex);
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,11 @@ bool InterfaceProxy::dispatch_signal( const SignalMessage& msg )
|
||||||
if( si != _signals.end() )
|
if( si != _signals.end() )
|
||||||
{
|
{
|
||||||
si->second.call( msg );
|
si->second.call( msg );
|
||||||
return true;
|
// Here we always return false because there might be
|
||||||
|
// another InterfaceProxy listening for the same signal.
|
||||||
|
// This way we instruct libdbus-1 to go on dispatching
|
||||||
|
// the signal.
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,7 +61,7 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
|
||||||
IntrospectedInterface* const intro = iti->second->introspect();
|
IntrospectedInterface* const intro = iti->second->introspect();
|
||||||
if(intro)
|
if(intro)
|
||||||
{
|
{
|
||||||
xml << "<interface name=\"" << intro->name << "\">";
|
xml << "\n\t<interface name=\"" << intro->name << "\">";
|
||||||
|
|
||||||
for(const IntrospectedProperty* p = intro->properties; p->name; ++p)
|
for(const IntrospectedProperty* p = intro->properties; p->name; ++p)
|
||||||
{
|
{
|
||||||
|
@ -70,18 +70,18 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
|
||||||
if(p->read) access += "read";
|
if(p->read) access += "read";
|
||||||
if(p->write) access += "write";
|
if(p->write) access += "write";
|
||||||
|
|
||||||
xml << "<property name=\"" << p->name << "\""
|
xml << "\n\t\t<property name=\"" << p->name << "\""
|
||||||
<< " type=\"" << p->type << "\""
|
<< " type=\"" << p->type << "\""
|
||||||
<< " access=\"" << access << "\"/>";
|
<< " access=\"" << access << "\"/>";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const IntrospectedMethod* m = intro->methods; m->args; ++m)
|
for(const IntrospectedMethod* m = intro->methods; m->args; ++m)
|
||||||
{
|
{
|
||||||
xml << "<method name=\"" << m->name << "\">";
|
xml << "\n\t\t<method name=\"" << m->name << "\">";
|
||||||
|
|
||||||
for(const IntrospectedArgument* a = m->args; a->type; ++a)
|
for(const IntrospectedArgument* a = m->args; a->type; ++a)
|
||||||
{
|
{
|
||||||
xml << "<arg direction=\"" << (a->in ? "in" : "out") << "\""
|
xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
|
||||||
<< " type=\"" << a->type << "\"";
|
<< " type=\"" << a->type << "\"";
|
||||||
|
|
||||||
if(a->name) xml << " name=\"" << a->name << "\"";
|
if(a->name) xml << " name=\"" << a->name << "\"";
|
||||||
|
@ -89,12 +89,12 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
|
||||||
xml << "/>";
|
xml << "/>";
|
||||||
}
|
}
|
||||||
|
|
||||||
xml << "</method>";
|
xml << "\n\t\t</method>";
|
||||||
}
|
}
|
||||||
|
|
||||||
for(const IntrospectedMethod* m = intro->signals; m->args; ++m)
|
for(const IntrospectedMethod* m = intro->signals; m->args; ++m)
|
||||||
{
|
{
|
||||||
xml << "<signal name=\"" << m->name << "\">";
|
xml << "\n\t\t<signal name=\"" << m->name << "\">";
|
||||||
|
|
||||||
for(const IntrospectedArgument* a = m->args; a->type; ++a)
|
for(const IntrospectedArgument* a = m->args; a->type; ++a)
|
||||||
{
|
{
|
||||||
|
@ -104,12 +104,22 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
|
||||||
|
|
||||||
xml << "/>";
|
xml << "/>";
|
||||||
}
|
}
|
||||||
xml << "</signal>";
|
xml << "\n\t\t</signal>";
|
||||||
}
|
}
|
||||||
|
|
||||||
xml << "</interface>";
|
xml << "\n\t</interface>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/');
|
||||||
|
ObjectPathList::const_iterator oni;
|
||||||
|
|
||||||
|
for(oni = nodes.begin(); oni != nodes.end(); ++oni)
|
||||||
|
{
|
||||||
|
xml << "\n\t<node name=\"" << (*oni) << "\"/>";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* broken
|
||||||
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
|
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
|
||||||
|
|
||||||
ObjectAdaptorPList::const_iterator oci;
|
ObjectAdaptorPList::const_iterator oci;
|
||||||
|
@ -121,8 +131,9 @@ Message IntrospectableAdaptor::Introspect( const CallMessage& call )
|
||||||
|
|
||||||
xml << "<node name=\"" << name << "\"/>";
|
xml << "<node name=\"" << name << "\"/>";
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
xml << "</node>";
|
xml << "\n</node>";
|
||||||
|
|
||||||
ReturnMessage reply(call);
|
ReturnMessage reply(call);
|
||||||
MessageIter wi = reply.writer();
|
MessageIter wi = reply.writer();
|
||||||
|
|
|
@ -119,6 +119,31 @@ ObjectAdaptorPList ObjectAdaptor::from_path_prefix( const std::string& prefix )
|
||||||
return ali;
|
return ali;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObjectPathList ObjectAdaptor::child_nodes_from_prefix( const std::string& prefix )
|
||||||
|
{
|
||||||
|
ObjectPathList ali;
|
||||||
|
|
||||||
|
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
|
||||||
|
|
||||||
|
size_t plen = prefix.length();
|
||||||
|
|
||||||
|
while(ati != _adaptor_table.end())
|
||||||
|
{
|
||||||
|
if(!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
|
||||||
|
{
|
||||||
|
std::string p = ati->second->path().substr(plen);
|
||||||
|
p = p.substr(0,p.find('/'));
|
||||||
|
ali.push_back(p);
|
||||||
|
}
|
||||||
|
++ati;
|
||||||
|
}
|
||||||
|
|
||||||
|
ali.sort();
|
||||||
|
ali.unique();
|
||||||
|
|
||||||
|
return ali;
|
||||||
|
}
|
||||||
|
|
||||||
ObjectAdaptor::ObjectAdaptor( Connection& conn, const Path& path )
|
ObjectAdaptor::ObjectAdaptor( Connection& conn, const Path& path )
|
||||||
: Object(conn, path, conn.unique_name())
|
: Object(conn, path, conn.unique_name())
|
||||||
{
|
{
|
||||||
|
@ -138,16 +163,6 @@ void ObjectAdaptor::register_obj()
|
||||||
{
|
{
|
||||||
throw ErrorNoMemory("unable to register object path");
|
throw ErrorNoMemory("unable to register object path");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
InterfaceAdaptorTable::const_iterator ii = _interfaces.begin();
|
|
||||||
while( ii != _interfaces.end() )
|
|
||||||
{
|
|
||||||
std::string im = "type='method_call',interface='"+ii->first+"',path='"+path()+"'";
|
|
||||||
conn().add_match(im.c_str());
|
|
||||||
++ii;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_adaptor_table[path()] = this;
|
_adaptor_table[path()] = this;
|
||||||
}
|
}
|
||||||
|
@ -159,14 +174,6 @@ void ObjectAdaptor::unregister_obj()
|
||||||
debug_log("unregistering local object %s", path().c_str());
|
debug_log("unregistering local object %s", path().c_str());
|
||||||
|
|
||||||
dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
|
dbus_connection_unregister_object_path(conn()._pvt->conn, path().c_str());
|
||||||
|
|
||||||
InterfaceAdaptorTable::const_iterator ii = _interfaces.begin();
|
|
||||||
while( ii != _interfaces.end() )
|
|
||||||
{
|
|
||||||
std::string im = "type='method_call',interface='"+ii->first+"',path='"+path()+"'";
|
|
||||||
conn().remove_match(im.c_str());
|
|
||||||
++ii;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectAdaptor::_emit_signal( SignalMessage& sig )
|
void ObjectAdaptor::_emit_signal( SignalMessage& sig )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue