- NO FUNCTIONAL CODE CHANGES!!!!
- changed code formating from tabs to spaces and others - used astyle with this option: --style=ansi --indent=spaces=2 -M --pad-oper --unpad-paren --pad-header --align-pointer=name --lineend=linux
This commit is contained in:
parent
b100e9d32a
commit
1c8e43e6d6
76 changed files with 5691 additions and 5492 deletions
|
@ -42,432 +42,433 @@
|
|||
using namespace DBus;
|
||||
|
||||
Connection::Private::Private(DBusConnection *c, Server::Private *s)
|
||||
: conn(c) , dispatcher(NULL), server(s)
|
||||
: conn(c) , dispatcher(NULL), server(s)
|
||||
{
|
||||
init();
|
||||
init();
|
||||
}
|
||||
|
||||
Connection::Private::Private(DBusBusType type)
|
||||
: dispatcher(NULL), server(NULL)
|
||||
{
|
||||
InternalError e;
|
||||
InternalError e;
|
||||
|
||||
conn = dbus_bus_get_private(type, e);
|
||||
conn = dbus_bus_get_private(type, e);
|
||||
|
||||
if (e) throw Error(e);
|
||||
if (e) throw Error(e);
|
||||
|
||||
init();
|
||||
init();
|
||||
}
|
||||
|
||||
Connection::Private::~Private()
|
||||
{
|
||||
debug_log("terminating connection 0x%08x", conn);
|
||||
debug_log("terminating connection 0x%08x", conn);
|
||||
|
||||
detach_server();
|
||||
detach_server();
|
||||
|
||||
if (dbus_connection_get_is_connected(conn))
|
||||
{
|
||||
std::vector<std::string>::iterator i = names.begin();
|
||||
if (dbus_connection_get_is_connected(conn))
|
||||
{
|
||||
std::vector<std::string>::iterator i = names.begin();
|
||||
|
||||
while (i != names.end())
|
||||
{
|
||||
debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str());
|
||||
dbus_bus_release_name(conn, i->c_str(), NULL);
|
||||
++i;
|
||||
}
|
||||
dbus_connection_close(conn);
|
||||
}
|
||||
dbus_connection_unref(conn);
|
||||
while (i != names.end())
|
||||
{
|
||||
debug_log("%s: releasing bus name %s", dbus_bus_get_unique_name(conn), i->c_str());
|
||||
dbus_bus_release_name(conn, i->c_str(), NULL);
|
||||
++i;
|
||||
}
|
||||
dbus_connection_close(conn);
|
||||
}
|
||||
dbus_connection_unref(conn);
|
||||
}
|
||||
|
||||
void Connection::Private::init()
|
||||
{
|
||||
dbus_connection_ref(conn);
|
||||
dbus_connection_ref(conn); //todo: the library has to own another reference
|
||||
dbus_connection_ref(conn);
|
||||
dbus_connection_ref(conn); //todo: the library has to own another reference
|
||||
|
||||
disconn_filter = new Callback<Connection::Private, bool, const Message &>(
|
||||
this, &Connection::Private::disconn_filter_function
|
||||
);
|
||||
disconn_filter = new Callback<Connection::Private, bool, const Message &>(
|
||||
this, &Connection::Private::disconn_filter_function
|
||||
);
|
||||
|
||||
dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least
|
||||
dbus_connection_add_filter(conn, message_filter_stub, &disconn_filter, NULL); // TODO: some assert at least
|
||||
|
||||
dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0);
|
||||
dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true??
|
||||
dbus_connection_set_dispatch_status_function(conn, dispatch_status_stub, this, 0);
|
||||
dbus_connection_set_exit_on_disconnect(conn, false); //why was this set to true??
|
||||
}
|
||||
|
||||
void Connection::Private::detach_server()
|
||||
{
|
||||
/* Server::Private *tmp = server;
|
||||
/* Server::Private *tmp = server;
|
||||
|
||||
server = NULL;
|
||||
server = NULL;
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
ConnectionList::iterator i;
|
||||
if (tmp)
|
||||
{
|
||||
ConnectionList::iterator i;
|
||||
|
||||
for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
|
||||
{
|
||||
if (i->_pvt.get() == this)
|
||||
{
|
||||
tmp->connections.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
for (i = tmp->connections.begin(); i != tmp->connections.end(); ++i)
|
||||
{
|
||||
if (i->_pvt.get() == this)
|
||||
{
|
||||
tmp->connections.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
bool Connection::Private::do_dispatch()
|
||||
{
|
||||
debug_log("dispatching on %p", conn);
|
||||
debug_log("dispatching on %p", conn);
|
||||
|
||||
if (!dbus_connection_get_is_connected(conn))
|
||||
{
|
||||
debug_log("connection terminated");
|
||||
if (!dbus_connection_get_is_connected(conn))
|
||||
{
|
||||
debug_log("connection terminated");
|
||||
|
||||
detach_server();
|
||||
detach_server();
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS;
|
||||
return dbus_connection_dispatch(conn) != DBUS_DISPATCH_DATA_REMAINS;
|
||||
}
|
||||
|
||||
void Connection::Private::dispatch_status_stub(DBusConnection *dc, DBusDispatchStatus status, void *data)
|
||||
{
|
||||
Private *p = static_cast<Private *>(data);
|
||||
Private *p = static_cast<Private *>(data);
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case DBUS_DISPATCH_DATA_REMAINS:
|
||||
debug_log("some dispatching to do on %p", dc);
|
||||
p->dispatcher->queue_connection(p);
|
||||
break;
|
||||
switch (status)
|
||||
{
|
||||
case DBUS_DISPATCH_DATA_REMAINS:
|
||||
debug_log("some dispatching to do on %p", dc);
|
||||
p->dispatcher->queue_connection(p);
|
||||
break;
|
||||
|
||||
case DBUS_DISPATCH_COMPLETE:
|
||||
debug_log("all dispatching done on %p", dc);
|
||||
break;
|
||||
case DBUS_DISPATCH_COMPLETE:
|
||||
debug_log("all dispatching done on %p", dc);
|
||||
break;
|
||||
|
||||
case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
|
||||
debug_log("connection %p needs memory", dc);
|
||||
break;
|
||||
}
|
||||
case DBUS_DISPATCH_NEED_MEMORY: //uh oh...
|
||||
debug_log("connection %p needs memory", dc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DBusHandlerResult Connection::Private::message_filter_stub(DBusConnection *conn, DBusMessage *dmsg, void *data)
|
||||
{
|
||||
MessageSlot *slot = static_cast<MessageSlot *>(data);
|
||||
MessageSlot *slot = static_cast<MessageSlot *>(data);
|
||||
|
||||
Message msg = Message(new Message::Private(dmsg));
|
||||
Message msg = Message(new Message::Private(dmsg));
|
||||
|
||||
return slot && !slot->empty() && slot->call(msg)
|
||||
? DBUS_HANDLER_RESULT_HANDLED
|
||||
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
return slot && !slot->empty() && slot->call(msg)
|
||||
? DBUS_HANDLER_RESULT_HANDLED
|
||||
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
|
||||
bool Connection::Private::disconn_filter_function(const Message &msg)
|
||||
{
|
||||
if (msg.is_signal(DBUS_INTERFACE_LOCAL,"Disconnected"))
|
||||
{
|
||||
debug_log("%p disconnected by local bus", conn);
|
||||
dbus_connection_close(conn);
|
||||
if (msg.is_signal(DBUS_INTERFACE_LOCAL, "Disconnected"))
|
||||
{
|
||||
debug_log("%p disconnected by local bus", conn);
|
||||
dbus_connection_close(conn);
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DBusDispatchStatus Connection::Private::dispatch_status()
|
||||
{
|
||||
return dbus_connection_get_dispatch_status(conn);
|
||||
return dbus_connection_get_dispatch_status(conn);
|
||||
}
|
||||
|
||||
bool Connection::Private::has_something_to_dispatch()
|
||||
{
|
||||
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
|
||||
return dispatch_status() == DBUS_DISPATCH_DATA_REMAINS;
|
||||
}
|
||||
|
||||
|
||||
Connection Connection::SystemBus()
|
||||
{
|
||||
return Connection(new Private(DBUS_BUS_SYSTEM));
|
||||
return Connection(new Private(DBUS_BUS_SYSTEM));
|
||||
}
|
||||
|
||||
Connection Connection::SessionBus()
|
||||
{
|
||||
return Connection(new Private(DBUS_BUS_SESSION));
|
||||
return Connection(new Private(DBUS_BUS_SESSION));
|
||||
}
|
||||
|
||||
Connection Connection::ActivationBus()
|
||||
{
|
||||
return Connection(new Private(DBUS_BUS_STARTER));
|
||||
return Connection(new Private(DBUS_BUS_STARTER));
|
||||
}
|
||||
|
||||
Connection::Connection(const char *address, bool priv)
|
||||
: _timeout(-1)
|
||||
: _timeout(-1)
|
||||
{
|
||||
InternalError e;
|
||||
DBusConnection *conn = priv
|
||||
? dbus_connection_open_private(address, e)
|
||||
: dbus_connection_open(address, e);
|
||||
InternalError e;
|
||||
DBusConnection *conn = priv
|
||||
? dbus_connection_open_private(address, e)
|
||||
: dbus_connection_open(address, e);
|
||||
|
||||
if (e) throw Error(e);
|
||||
if (e) throw Error(e);
|
||||
|
||||
_pvt = new Private(conn);
|
||||
_pvt = new Private(conn);
|
||||
|
||||
setup(default_dispatcher);
|
||||
setup(default_dispatcher);
|
||||
|
||||
debug_log("connected to %s", address);
|
||||
debug_log("connected to %s", address);
|
||||
}
|
||||
|
||||
Connection::Connection(Connection::Private *p)
|
||||
: _pvt(p), _timeout(-1)
|
||||
: _pvt(p), _timeout(-1)
|
||||
{
|
||||
setup(default_dispatcher);
|
||||
setup(default_dispatcher);
|
||||
}
|
||||
|
||||
Connection::Connection(const Connection &c)
|
||||
: _pvt(c._pvt),_timeout(c._timeout)
|
||||
: _pvt(c._pvt), _timeout(c._timeout)
|
||||
{
|
||||
dbus_connection_ref(_pvt->conn);
|
||||
dbus_connection_ref(_pvt->conn);
|
||||
}
|
||||
|
||||
Connection::~Connection()
|
||||
{
|
||||
dbus_connection_unref(_pvt->conn);
|
||||
dbus_connection_unref(_pvt->conn);
|
||||
}
|
||||
|
||||
Dispatcher *Connection::setup(Dispatcher *dispatcher)
|
||||
{
|
||||
debug_log("registering stubs for connection %p", _pvt->conn);
|
||||
debug_log("registering stubs for connection %p", _pvt->conn);
|
||||
|
||||
if (!dispatcher) dispatcher = default_dispatcher;
|
||||
if (!dispatcher) dispatcher = default_dispatcher;
|
||||
|
||||
if (!dispatcher) throw ErrorFailed("no default dispatcher set for new connection");
|
||||
if (!dispatcher) throw ErrorFailed("no default dispatcher set for new connection");
|
||||
|
||||
Dispatcher *prev = _pvt->dispatcher;
|
||||
Dispatcher *prev = _pvt->dispatcher;
|
||||
|
||||
_pvt->dispatcher = dispatcher;
|
||||
_pvt->dispatcher = dispatcher;
|
||||
|
||||
dispatcher->queue_connection(_pvt.get());
|
||||
dispatcher->queue_connection(_pvt.get());
|
||||
|
||||
dbus_connection_set_watch_functions(
|
||||
_pvt->conn,
|
||||
Dispatcher::Private::on_add_watch,
|
||||
Dispatcher::Private::on_rem_watch,
|
||||
Dispatcher::Private::on_toggle_watch,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
dbus_connection_set_watch_functions(
|
||||
_pvt->conn,
|
||||
Dispatcher::Private::on_add_watch,
|
||||
Dispatcher::Private::on_rem_watch,
|
||||
Dispatcher::Private::on_toggle_watch,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
|
||||
dbus_connection_set_timeout_functions(
|
||||
_pvt->conn,
|
||||
Dispatcher::Private::on_add_timeout,
|
||||
Dispatcher::Private::on_rem_timeout,
|
||||
Dispatcher::Private::on_toggle_timeout,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
dbus_connection_set_timeout_functions(
|
||||
_pvt->conn,
|
||||
Dispatcher::Private::on_add_timeout,
|
||||
Dispatcher::Private::on_rem_timeout,
|
||||
Dispatcher::Private::on_toggle_timeout,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
|
||||
return prev;
|
||||
return prev;
|
||||
}
|
||||
|
||||
bool Connection::operator == (const Connection &c) const
|
||||
{
|
||||
return _pvt->conn == c._pvt->conn;
|
||||
return _pvt->conn == c._pvt->conn;
|
||||
}
|
||||
|
||||
bool Connection::register_bus()
|
||||
{
|
||||
InternalError e;
|
||||
InternalError e;
|
||||
|
||||
bool r = dbus_bus_register(_pvt->conn, e);
|
||||
|
||||
if (e) throw (e);
|
||||
bool r = dbus_bus_register(_pvt->conn, e);
|
||||
|
||||
return r;
|
||||
if (e) throw(e);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
bool Connection::connected() const
|
||||
{
|
||||
return dbus_connection_get_is_connected(_pvt->conn);
|
||||
return dbus_connection_get_is_connected(_pvt->conn);
|
||||
}
|
||||
|
||||
void Connection::disconnect()
|
||||
{
|
||||
// dbus_connection_disconnect(_pvt->conn); // disappeared in 0.9x
|
||||
dbus_connection_close(_pvt->conn);
|
||||
dbus_connection_close(_pvt->conn);
|
||||
}
|
||||
|
||||
void Connection::exit_on_disconnect(bool exit)
|
||||
{
|
||||
dbus_connection_set_exit_on_disconnect(_pvt->conn, exit);
|
||||
dbus_connection_set_exit_on_disconnect(_pvt->conn, exit);
|
||||
}
|
||||
|
||||
bool Connection::unique_name(const char *n)
|
||||
{
|
||||
return dbus_bus_set_unique_name(_pvt->conn, n);
|
||||
return dbus_bus_set_unique_name(_pvt->conn, n);
|
||||
}
|
||||
|
||||
const char *Connection::unique_name() const
|
||||
{
|
||||
return dbus_bus_get_unique_name(_pvt->conn);
|
||||
return dbus_bus_get_unique_name(_pvt->conn);
|
||||
}
|
||||
|
||||
void Connection::flush()
|
||||
{
|
||||
dbus_connection_flush(_pvt->conn);
|
||||
dbus_connection_flush(_pvt->conn);
|
||||
}
|
||||
|
||||
void Connection::add_match(const char *rule)
|
||||
{
|
||||
InternalError e;
|
||||
InternalError e;
|
||||
|
||||
dbus_bus_add_match(_pvt->conn, rule, e);
|
||||
dbus_bus_add_match(_pvt->conn, rule, e);
|
||||
|
||||
debug_log("%s: added match rule %s", unique_name(), rule);
|
||||
debug_log("%s: added match rule %s", unique_name(), rule);
|
||||
|
||||
if (e) throw Error(e);
|
||||
if (e) throw Error(e);
|
||||
}
|
||||
|
||||
void Connection::remove_match(const char *rule,
|
||||
bool throw_on_error)
|
||||
bool throw_on_error)
|
||||
{
|
||||
InternalError e;
|
||||
|
||||
dbus_bus_remove_match(_pvt->conn, rule, e);
|
||||
InternalError e;
|
||||
|
||||
debug_log("%s: removed match rule %s", unique_name(), rule);
|
||||
dbus_bus_remove_match(_pvt->conn, rule, e);
|
||||
|
||||
if (e) {
|
||||
if (throw_on_error)
|
||||
throw Error(e);
|
||||
else
|
||||
debug_log("DBus::Connection::remove_match: %s (%s).",
|
||||
static_cast<DBusError*>(e)->message,
|
||||
static_cast<DBusError*>(e)->name);
|
||||
}
|
||||
debug_log("%s: removed match rule %s", unique_name(), rule);
|
||||
|
||||
if (e)
|
||||
{
|
||||
if (throw_on_error)
|
||||
throw Error(e);
|
||||
else
|
||||
debug_log("DBus::Connection::remove_match: %s (%s).",
|
||||
static_cast<DBusError *>(e)->message,
|
||||
static_cast<DBusError *>(e)->name);
|
||||
}
|
||||
}
|
||||
|
||||
bool Connection::add_filter(MessageSlot &s)
|
||||
{
|
||||
debug_log("%s: adding filter", unique_name());
|
||||
return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
|
||||
debug_log("%s: adding filter", unique_name());
|
||||
return dbus_connection_add_filter(_pvt->conn, Private::message_filter_stub, &s, NULL);
|
||||
}
|
||||
|
||||
void Connection::remove_filter(MessageSlot &s)
|
||||
{
|
||||
debug_log("%s: removing filter", unique_name());
|
||||
dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
|
||||
debug_log("%s: removing filter", unique_name());
|
||||
dbus_connection_remove_filter(_pvt->conn, Private::message_filter_stub, &s);
|
||||
}
|
||||
|
||||
bool Connection::send(const Message &msg, unsigned int *serial)
|
||||
{
|
||||
return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial);
|
||||
return dbus_connection_send(_pvt->conn, msg._pvt->msg, serial);
|
||||
}
|
||||
|
||||
Message Connection::send_blocking(Message &msg, int timeout)
|
||||
{
|
||||
DBusMessage *reply;
|
||||
InternalError e;
|
||||
|
||||
if (this->_timeout != -1)
|
||||
{
|
||||
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, this->_timeout, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e);
|
||||
}
|
||||
DBusMessage *reply;
|
||||
InternalError e;
|
||||
|
||||
if (e) throw Error(e);
|
||||
if (this->_timeout != -1)
|
||||
{
|
||||
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, this->_timeout, e);
|
||||
}
|
||||
else
|
||||
{
|
||||
reply = dbus_connection_send_with_reply_and_block(_pvt->conn, msg._pvt->msg, timeout, e);
|
||||
}
|
||||
|
||||
return Message(new Message::Private(reply), false);
|
||||
if (e) throw Error(e);
|
||||
|
||||
return Message(new Message::Private(reply), false);
|
||||
}
|
||||
|
||||
PendingCall Connection::send_async(Message &msg, int timeout)
|
||||
{
|
||||
DBusPendingCall *pending;
|
||||
DBusPendingCall *pending;
|
||||
|
||||
if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to start asynchronous call");
|
||||
}
|
||||
return PendingCall(new PendingCall::Private(pending));
|
||||
if (!dbus_connection_send_with_reply(_pvt->conn, msg._pvt->msg, &pending, timeout))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to start asynchronous call");
|
||||
}
|
||||
return PendingCall(new PendingCall::Private(pending));
|
||||
}
|
||||
|
||||
void Connection::request_name(const char *name, int flags)
|
||||
{
|
||||
InternalError e;
|
||||
InternalError e;
|
||||
|
||||
debug_log("%s: registering bus name %s", unique_name(), name);
|
||||
debug_log("%s: registering bus name %s", unique_name(), name);
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* Think about giving back the 'ret' value. Some people on the list
|
||||
* requested about this...
|
||||
*/
|
||||
int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);
|
||||
/*
|
||||
* TODO:
|
||||
* Think about giving back the 'ret' value. Some people on the list
|
||||
* requested about this...
|
||||
*/
|
||||
int ret = dbus_bus_request_name(_pvt->conn, name, flags, e);
|
||||
|
||||
if (ret == -1)
|
||||
{
|
||||
if (e) throw Error(e);
|
||||
}
|
||||
if (ret == -1)
|
||||
{
|
||||
if (e) throw Error(e);
|
||||
}
|
||||
|
||||
// this->remove_match("destination");
|
||||
|
||||
if (name)
|
||||
{
|
||||
_pvt->names.push_back(name);
|
||||
std::string match = "destination='" + _pvt->names.back() + "'";
|
||||
add_match(match.c_str());
|
||||
}
|
||||
if (name)
|
||||
{
|
||||
_pvt->names.push_back(name);
|
||||
std::string match = "destination='" + _pvt->names.back() + "'";
|
||||
add_match(match.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long Connection::sender_unix_uid(const char *sender)
|
||||
{
|
||||
InternalError e;
|
||||
|
||||
unsigned long ul = dbus_bus_get_unix_user(_pvt->conn, sender, e);
|
||||
|
||||
if (e) throw Error(e);
|
||||
|
||||
return ul;
|
||||
InternalError e;
|
||||
|
||||
unsigned long ul = dbus_bus_get_unix_user(_pvt->conn, sender, e);
|
||||
|
||||
if (e) throw Error(e);
|
||||
|
||||
return ul;
|
||||
}
|
||||
|
||||
bool Connection::has_name(const char *name)
|
||||
{
|
||||
InternalError e;
|
||||
{
|
||||
InternalError e;
|
||||
|
||||
bool b = dbus_bus_name_has_owner(_pvt->conn, name, e);
|
||||
bool b = dbus_bus_name_has_owner(_pvt->conn, name, e);
|
||||
|
||||
if (e) throw Error(e);
|
||||
if (e) throw Error(e);
|
||||
|
||||
return b;
|
||||
return b;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& Connection::names()
|
||||
{
|
||||
return _pvt->names;
|
||||
return _pvt->names;
|
||||
}
|
||||
|
||||
bool Connection::start_service(const char *name, unsigned long flags)
|
||||
{
|
||||
InternalError e;
|
||||
InternalError e;
|
||||
|
||||
bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e);
|
||||
bool b = dbus_bus_start_service_by_name(_pvt->conn, name, flags, NULL, e);
|
||||
|
||||
if (e) throw Error(e);
|
||||
|
||||
return b;
|
||||
if (e) throw Error(e);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void Connection::set_timeout(int timeout)
|
||||
{
|
||||
_timeout=timeout;
|
||||
}
|
||||
|
||||
int Connection::get_timeout()
|
||||
{
|
||||
return _timeout;
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
int Connection::get_timeout()
|
||||
{
|
||||
return _timeout;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,37 +38,38 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
namespace DBus {
|
||||
namespace DBus
|
||||
{
|
||||
|
||||
struct DXXAPILOCAL Connection::Private
|
||||
{
|
||||
DBusConnection * conn;
|
||||
DBusConnection *conn;
|
||||
|
||||
std::vector<std::string> names;
|
||||
std::vector<std::string> names;
|
||||
|
||||
Dispatcher *dispatcher;
|
||||
bool do_dispatch();
|
||||
Dispatcher *dispatcher;
|
||||
bool do_dispatch();
|
||||
|
||||
MessageSlot disconn_filter;
|
||||
bool disconn_filter_function(const Message &);
|
||||
MessageSlot disconn_filter;
|
||||
bool disconn_filter_function(const Message &);
|
||||
|
||||
Server::Private *server;
|
||||
void detach_server();
|
||||
Server::Private *server;
|
||||
void detach_server();
|
||||
|
||||
Private(DBusConnection *, Server::Private * = NULL);
|
||||
Private(DBusConnection *, Server::Private * = NULL);
|
||||
|
||||
Private(DBusBusType);
|
||||
Private(DBusBusType);
|
||||
|
||||
~Private();
|
||||
~Private();
|
||||
|
||||
void init();
|
||||
void init();
|
||||
|
||||
DBusDispatchStatus dispatch_status();
|
||||
bool has_something_to_dispatch();
|
||||
DBusDispatchStatus dispatch_status();
|
||||
bool has_something_to_dispatch();
|
||||
|
||||
static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *);
|
||||
static void dispatch_status_stub(DBusConnection *, DBusDispatchStatus, void *);
|
||||
|
||||
static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *);
|
||||
static DBusHandlerResult message_filter_stub(DBusConnection *, DBusMessage *, void *);
|
||||
};
|
||||
|
||||
} /* namespace DBus */
|
||||
|
|
|
@ -35,19 +35,19 @@ static void _debug_log_default(const char *format, ...)
|
|||
{
|
||||
//#ifdef DEBUG
|
||||
|
||||
static int debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0;
|
||||
static int debug_env = getenv("DBUSXX_VERBOSE") ? 1 : 0;
|
||||
|
||||
if (debug_env)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
if (debug_env)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
fprintf(stderr, "dbus-c++: ");
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "dbus-c++: ");
|
||||
vfprintf(stderr, format, args);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
//#endif//DEBUG
|
||||
}
|
||||
|
|
|
@ -38,64 +38,64 @@ DBus::Dispatcher *DBus::default_dispatcher = NULL;
|
|||
using namespace DBus;
|
||||
|
||||
Timeout::Timeout(Timeout::Internal *i)
|
||||
: _int(i)
|
||||
: _int(i)
|
||||
{
|
||||
dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
|
||||
dbus_timeout_set_data((DBusTimeout *)i, this, NULL);
|
||||
}
|
||||
|
||||
int Timeout::interval() const
|
||||
{
|
||||
return dbus_timeout_get_interval((DBusTimeout *)_int);
|
||||
return dbus_timeout_get_interval((DBusTimeout *)_int);
|
||||
}
|
||||
|
||||
bool Timeout::enabled() const
|
||||
{
|
||||
return dbus_timeout_get_enabled((DBusTimeout *)_int);
|
||||
return dbus_timeout_get_enabled((DBusTimeout *)_int);
|
||||
}
|
||||
|
||||
bool Timeout::handle()
|
||||
{
|
||||
return dbus_timeout_handle((DBusTimeout *)_int);
|
||||
return dbus_timeout_handle((DBusTimeout *)_int);
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
Watch::Watch(Watch::Internal *i)
|
||||
: _int(i)
|
||||
: _int(i)
|
||||
{
|
||||
dbus_watch_set_data((DBusWatch *)i, this, NULL);
|
||||
dbus_watch_set_data((DBusWatch *)i, this, NULL);
|
||||
}
|
||||
|
||||
int Watch::descriptor() const
|
||||
{
|
||||
#if HAVE_WIN32
|
||||
return dbus_watch_get_socket((DBusWatch*)_int);
|
||||
return dbus_watch_get_socket((DBusWatch *)_int);
|
||||
#else
|
||||
// check dbus version and use dbus_watch_get_unix_fd() only in dbus >= 1.1.1
|
||||
#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || \
|
||||
// check dbus version and use dbus_watch_get_unix_fd() only in dbus >= 1.1.1
|
||||
#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || \
|
||||
(DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MAJOR > 1) || \
|
||||
(DBUS_VERSION_MAJOR > 1)
|
||||
return dbus_watch_get_unix_fd((DBusWatch*)_int);
|
||||
#else
|
||||
return dbus_watch_get_fd((DBusWatch*)_int);
|
||||
#endif
|
||||
return dbus_watch_get_unix_fd((DBusWatch *)_int);
|
||||
#else
|
||||
return dbus_watch_get_fd((DBusWatch *)_int);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
int Watch::flags() const
|
||||
{
|
||||
return dbus_watch_get_flags((DBusWatch *)_int);
|
||||
return dbus_watch_get_flags((DBusWatch *)_int);
|
||||
}
|
||||
|
||||
bool Watch::enabled() const
|
||||
{
|
||||
return dbus_watch_get_enabled((DBusWatch *)_int);
|
||||
return dbus_watch_get_enabled((DBusWatch *)_int);
|
||||
}
|
||||
|
||||
bool Watch::handle(int flags)
|
||||
{
|
||||
return dbus_watch_handle((DBusWatch *)_int, flags);
|
||||
return dbus_watch_handle((DBusWatch *)_int, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -103,216 +103,218 @@ bool Watch::handle(int flags)
|
|||
|
||||
dbus_bool_t Dispatcher::Private::on_add_watch(DBusWatch *watch, void *data)
|
||||
{
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
|
||||
Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);
|
||||
Watch::Internal *w = reinterpret_cast<Watch::Internal *>(watch);
|
||||
|
||||
d->add_watch(w);
|
||||
d->add_watch(w);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dispatcher::Private::on_rem_watch(DBusWatch *watch, void *data)
|
||||
{
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
|
||||
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
|
||||
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
|
||||
|
||||
d->rem_watch(w);
|
||||
d->rem_watch(w);
|
||||
}
|
||||
|
||||
void Dispatcher::Private::on_toggle_watch(DBusWatch *watch, void *data)
|
||||
{
|
||||
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
|
||||
Watch *w = static_cast<Watch *>(dbus_watch_get_data(watch));
|
||||
|
||||
w->toggle();
|
||||
w->toggle();
|
||||
}
|
||||
|
||||
dbus_bool_t Dispatcher::Private::on_add_timeout(DBusTimeout *timeout, void *data)
|
||||
{
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
|
||||
Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);
|
||||
Timeout::Internal *t = reinterpret_cast<Timeout::Internal *>(timeout);
|
||||
|
||||
d->add_timeout(t);
|
||||
d->add_timeout(t);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Dispatcher::Private::on_rem_timeout(DBusTimeout *timeout, void *data)
|
||||
{
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
Dispatcher *d = static_cast<Dispatcher *>(data);
|
||||
|
||||
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
|
||||
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
|
||||
|
||||
d->rem_timeout(t);
|
||||
d->rem_timeout(t);
|
||||
}
|
||||
|
||||
void Dispatcher::Private::on_toggle_timeout(DBusTimeout *timeout, void *data)
|
||||
{
|
||||
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
|
||||
Timeout *t = static_cast<Timeout *>(dbus_timeout_get_data(timeout));
|
||||
|
||||
t->toggle();
|
||||
t->toggle();
|
||||
}
|
||||
|
||||
void Dispatcher::queue_connection(Connection::Private *cp)
|
||||
{
|
||||
_mutex_p.lock();
|
||||
_pending_queue.push_back(cp);
|
||||
_mutex_p.unlock();
|
||||
_mutex_p.lock();
|
||||
_pending_queue.push_back(cp);
|
||||
_mutex_p.unlock();
|
||||
}
|
||||
|
||||
|
||||
bool Dispatcher::has_something_to_dispatch()
|
||||
{
|
||||
_mutex_p.lock();
|
||||
bool has_something = false;
|
||||
for(Connection::PrivatePList::iterator it = _pending_queue.begin();
|
||||
it != _pending_queue.end() && !has_something;
|
||||
++it)
|
||||
{
|
||||
has_something = (*it)->has_something_to_dispatch();
|
||||
}
|
||||
_mutex_p.lock();
|
||||
bool has_something = false;
|
||||
for (Connection::PrivatePList::iterator it = _pending_queue.begin();
|
||||
it != _pending_queue.end() && !has_something;
|
||||
++it)
|
||||
{
|
||||
has_something = (*it)->has_something_to_dispatch();
|
||||
}
|
||||
|
||||
_mutex_p.unlock();
|
||||
return has_something;
|
||||
_mutex_p.unlock();
|
||||
return has_something;
|
||||
}
|
||||
|
||||
|
||||
void Dispatcher::dispatch_pending()
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
_mutex_p.lock();
|
||||
if (_pending_queue.empty())
|
||||
{
|
||||
_mutex_p.unlock();
|
||||
break;
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
_mutex_p.lock();
|
||||
if (_pending_queue.empty())
|
||||
{
|
||||
_mutex_p.unlock();
|
||||
break;
|
||||
}
|
||||
|
||||
Connection::PrivatePList pending_queue_copy(_pending_queue);
|
||||
_mutex_p.unlock();
|
||||
Connection::PrivatePList pending_queue_copy(_pending_queue);
|
||||
_mutex_p.unlock();
|
||||
|
||||
size_t copy_elem_num(pending_queue_copy.size());
|
||||
size_t copy_elem_num(pending_queue_copy.size());
|
||||
|
||||
dispatch_pending(pending_queue_copy);
|
||||
dispatch_pending(pending_queue_copy);
|
||||
|
||||
//only push_back on list is mandatory!
|
||||
_mutex_p.lock();
|
||||
//only push_back on list is mandatory!
|
||||
_mutex_p.lock();
|
||||
|
||||
Connection::PrivatePList::iterator i, j;
|
||||
i = _pending_queue.begin();
|
||||
size_t counter = 0;
|
||||
while (counter < copy_elem_num && i != _pending_queue.end())
|
||||
{
|
||||
j = i;
|
||||
++j;
|
||||
_pending_queue.erase(i);
|
||||
i = j;
|
||||
++counter;
|
||||
}
|
||||
Connection::PrivatePList::iterator i, j;
|
||||
i = _pending_queue.begin();
|
||||
size_t counter = 0;
|
||||
while (counter < copy_elem_num && i != _pending_queue.end())
|
||||
{
|
||||
j = i;
|
||||
++j;
|
||||
_pending_queue.erase(i);
|
||||
i = j;
|
||||
++counter;
|
||||
}
|
||||
|
||||
_mutex_p.unlock();
|
||||
}
|
||||
_mutex_p.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void Dispatcher::dispatch_pending(Connection::PrivatePList& pending_queue)
|
||||
void Dispatcher::dispatch_pending(Connection::PrivatePList &pending_queue)
|
||||
{
|
||||
// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
|
||||
// SEEME: dbus-glib is dispatching only one message at a time to not starve the loop/other things...
|
||||
|
||||
_mutex_p_copy.lock();
|
||||
while (pending_queue.size() > 0)
|
||||
{
|
||||
Connection::PrivatePList::iterator i, j;
|
||||
_mutex_p_copy.lock();
|
||||
while (pending_queue.size() > 0)
|
||||
{
|
||||
Connection::PrivatePList::iterator i, j;
|
||||
|
||||
i = pending_queue.begin();
|
||||
i = pending_queue.begin();
|
||||
|
||||
while (i != pending_queue.end())
|
||||
{
|
||||
j = i;
|
||||
while (i != pending_queue.end())
|
||||
{
|
||||
j = i;
|
||||
|
||||
++j;
|
||||
++j;
|
||||
|
||||
if ((*i)->do_dispatch())
|
||||
pending_queue.erase(i);
|
||||
else
|
||||
debug_log("dispatch_pending_private: do_dispatch error");
|
||||
if ((*i)->do_dispatch())
|
||||
pending_queue.erase(i);
|
||||
else
|
||||
debug_log("dispatch_pending_private: do_dispatch error");
|
||||
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
_mutex_p_copy.unlock();
|
||||
i = j;
|
||||
}
|
||||
}
|
||||
_mutex_p_copy.unlock();
|
||||
}
|
||||
|
||||
void DBus::_init_threading()
|
||||
{
|
||||
#ifdef DBUS_HAS_THREADS_INIT_DEFAULT
|
||||
dbus_threads_init_default();
|
||||
dbus_threads_init_default();
|
||||
#else
|
||||
debug_log("Thread support is not enabled! Your D-Bus version is too old!");
|
||||
debug_log("Thread support is not enabled! Your D-Bus version is too old!");
|
||||
#endif//DBUS_HAS_THREADS_INIT_DEFAULT
|
||||
}
|
||||
|
||||
void DBus::_init_threading(
|
||||
MutexNewFn m1,
|
||||
MutexFreeFn m2,
|
||||
MutexLockFn m3,
|
||||
MutexUnlockFn m4,
|
||||
CondVarNewFn c1,
|
||||
CondVarFreeFn c2,
|
||||
CondVarWaitFn c3,
|
||||
CondVarWaitTimeoutFn c4,
|
||||
CondVarWakeOneFn c5,
|
||||
CondVarWakeAllFn c6
|
||||
MutexNewFn m1,
|
||||
MutexFreeFn m2,
|
||||
MutexLockFn m3,
|
||||
MutexUnlockFn m4,
|
||||
CondVarNewFn c1,
|
||||
CondVarFreeFn c2,
|
||||
CondVarWaitFn c3,
|
||||
CondVarWaitTimeoutFn c4,
|
||||
CondVarWakeOneFn c5,
|
||||
CondVarWakeAllFn c6
|
||||
)
|
||||
{
|
||||
#ifndef DBUS_HAS_RECURSIVE_MUTEX
|
||||
DBusThreadFunctions functions = {
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
|
||||
(DBusMutexNewFunction) m1,
|
||||
(DBusMutexFreeFunction) m2,
|
||||
(DBusMutexLockFunction) m3,
|
||||
(DBusMutexUnlockFunction) m4,
|
||||
(DBusCondVarNewFunction) c1,
|
||||
(DBusCondVarFreeFunction) c2,
|
||||
(DBusCondVarWaitFunction) c3,
|
||||
(DBusCondVarWaitTimeoutFunction) c4,
|
||||
(DBusCondVarWakeOneFunction) c5,
|
||||
(DBusCondVarWakeAllFunction) c6
|
||||
};
|
||||
DBusThreadFunctions functions =
|
||||
{
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_LOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_MUTEX_UNLOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
|
||||
(DBusMutexNewFunction) m1,
|
||||
(DBusMutexFreeFunction) m2,
|
||||
(DBusMutexLockFunction) m3,
|
||||
(DBusMutexUnlockFunction) m4,
|
||||
(DBusCondVarNewFunction) c1,
|
||||
(DBusCondVarFreeFunction) c2,
|
||||
(DBusCondVarWaitFunction) c3,
|
||||
(DBusCondVarWaitTimeoutFunction) c4,
|
||||
(DBusCondVarWakeOneFunction) c5,
|
||||
(DBusCondVarWakeAllFunction) c6
|
||||
};
|
||||
#else
|
||||
DBusThreadFunctions functions = {
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK|
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
|
||||
0, 0, 0, 0,
|
||||
(DBusCondVarNewFunction) c1,
|
||||
(DBusCondVarFreeFunction) c2,
|
||||
(DBusCondVarWaitFunction) c3,
|
||||
(DBusCondVarWaitTimeoutFunction) c4,
|
||||
(DBusCondVarWakeOneFunction) c5,
|
||||
(DBusCondVarWakeAllFunction) c6,
|
||||
(DBusRecursiveMutexNewFunction) m1,
|
||||
(DBusRecursiveMutexFreeFunction) m2,
|
||||
(DBusRecursiveMutexLockFunction) m3,
|
||||
(DBusRecursiveMutexUnlockFunction) m4
|
||||
};
|
||||
DBusThreadFunctions functions =
|
||||
{
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_LOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_RECURSIVE_MUTEX_UNLOCK_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_NEW_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_FREE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAIT_TIMEOUT_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ONE_MASK |
|
||||
DBUS_THREAD_FUNCTIONS_CONDVAR_WAKE_ALL_MASK,
|
||||
0, 0, 0, 0,
|
||||
(DBusCondVarNewFunction) c1,
|
||||
(DBusCondVarFreeFunction) c2,
|
||||
(DBusCondVarWaitFunction) c3,
|
||||
(DBusCondVarWaitTimeoutFunction) c4,
|
||||
(DBusCondVarWakeOneFunction) c5,
|
||||
(DBusCondVarWakeAllFunction) c6,
|
||||
(DBusRecursiveMutexNewFunction) m1,
|
||||
(DBusRecursiveMutexFreeFunction) m2,
|
||||
(DBusRecursiveMutexLockFunction) m3,
|
||||
(DBusRecursiveMutexUnlockFunction) m4
|
||||
};
|
||||
#endif//DBUS_HAS_RECURSIVE_MUTEX
|
||||
dbus_threads_init(&functions);
|
||||
dbus_threads_init(&functions);
|
||||
}
|
||||
|
|
|
@ -35,21 +35,22 @@
|
|||
|
||||
#include "internalerror.h"
|
||||
|
||||
namespace DBus {
|
||||
namespace DBus
|
||||
{
|
||||
|
||||
struct DXXAPILOCAL Dispatcher::Private
|
||||
{
|
||||
static dbus_bool_t on_add_watch(DBusWatch *watch, void *data);
|
||||
static dbus_bool_t on_add_watch(DBusWatch *watch, void *data);
|
||||
|
||||
static void on_rem_watch(DBusWatch *watch, void *data);
|
||||
static void on_rem_watch(DBusWatch *watch, void *data);
|
||||
|
||||
static void on_toggle_watch(DBusWatch *watch, void *data);
|
||||
static void on_toggle_watch(DBusWatch *watch, void *data);
|
||||
|
||||
static dbus_bool_t on_add_timeout(DBusTimeout *timeout, void *data);
|
||||
static dbus_bool_t on_add_timeout(DBusTimeout *timeout, void *data);
|
||||
|
||||
static void on_rem_timeout(DBusTimeout *timeout, void *data);
|
||||
static void on_rem_timeout(DBusTimeout *timeout, void *data);
|
||||
|
||||
static void on_toggle_timeout(DBusTimeout *timeout, void *data);
|
||||
static void on_toggle_timeout(DBusTimeout *timeout, void *data);
|
||||
};
|
||||
|
||||
} /* namespace DBus */
|
||||
|
|
|
@ -33,120 +33,120 @@ using namespace DBus;
|
|||
|
||||
Dispatcher *gdispatcher = NULL;
|
||||
|
||||
Ecore::BusTimeout::BusTimeout( Timeout::Internal* ti)
|
||||
: Timeout(ti)
|
||||
Ecore::BusTimeout::BusTimeout(Timeout::Internal *ti)
|
||||
: Timeout(ti)
|
||||
{
|
||||
if (Timeout::enabled())
|
||||
{
|
||||
_enable();
|
||||
_enable();
|
||||
}
|
||||
}
|
||||
|
||||
Ecore::BusTimeout::~BusTimeout()
|
||||
{
|
||||
_disable();
|
||||
_disable();
|
||||
}
|
||||
|
||||
void Ecore::BusTimeout::toggle()
|
||||
{
|
||||
debug_log("ecore: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off");
|
||||
debug_log("ecore: timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
|
||||
|
||||
if(Timeout::enabled())
|
||||
if (Timeout::enabled())
|
||||
{
|
||||
_enable();
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
_disable();
|
||||
}
|
||||
}
|
||||
|
||||
Eina_Bool Ecore::BusTimeout::timeout_handler( void *data )
|
||||
Eina_Bool Ecore::BusTimeout::timeout_handler(void *data)
|
||||
{
|
||||
Ecore::BusTimeout* t = reinterpret_cast<Ecore::BusTimeout*>(data);
|
||||
Ecore::BusTimeout *t = reinterpret_cast<Ecore::BusTimeout *>(data);
|
||||
|
||||
debug_log("Ecore::BusTimeout::timeout_handler( void *data )");
|
||||
debug_log("Ecore::BusTimeout::timeout_handler( void *data )");
|
||||
|
||||
t->handle();
|
||||
t->handle();
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
void Ecore::BusTimeout::_enable()
|
||||
{
|
||||
debug_log("Ecore::BusTimeout::_enable()");
|
||||
|
||||
_etimer = ecore_timer_add (((double)Timeout::interval())/1000, timeout_handler, this);
|
||||
|
||||
_etimer = ecore_timer_add(((double)Timeout::interval()) / 1000, timeout_handler, this);
|
||||
}
|
||||
|
||||
void Ecore::BusTimeout::_disable()
|
||||
{
|
||||
debug_log("Ecore::BusTimeout::_disable()");
|
||||
|
||||
ecore_timer_del (_etimer);
|
||||
ecore_timer_del(_etimer);
|
||||
}
|
||||
|
||||
Ecore::BusWatch::BusWatch( Watch::Internal* wi)
|
||||
: Watch(wi), fd_handler (NULL), _bd (NULL)
|
||||
{
|
||||
Ecore::BusWatch::BusWatch(Watch::Internal *wi)
|
||||
: Watch(wi), fd_handler(NULL), _bd(NULL)
|
||||
{
|
||||
if (Watch::enabled())
|
||||
{
|
||||
_enable();
|
||||
_enable();
|
||||
}
|
||||
}
|
||||
|
||||
Ecore::BusWatch::~BusWatch()
|
||||
{
|
||||
_disable();
|
||||
_disable();
|
||||
}
|
||||
|
||||
void Ecore::BusWatch::toggle()
|
||||
{
|
||||
debug_log("ecore: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off");
|
||||
debug_log("ecore: watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
|
||||
|
||||
if(Watch::enabled()) _enable();
|
||||
else _disable();
|
||||
if (Watch::enabled()) _enable();
|
||||
else _disable();
|
||||
}
|
||||
|
||||
Eina_Bool Ecore::BusWatch::watch_dispatch( void *data, Ecore_Fd_Handler *fdh )
|
||||
Eina_Bool Ecore::BusWatch::watch_dispatch(void *data, Ecore_Fd_Handler *fdh)
|
||||
{
|
||||
Ecore::BusWatch* w = reinterpret_cast<Ecore::BusWatch*>(data);
|
||||
Ecore::BusWatch *w = reinterpret_cast<Ecore::BusWatch *>(data);
|
||||
|
||||
debug_log("Ecore::BusWatch watch_handler");
|
||||
debug_log("Ecore::BusWatch watch_handler");
|
||||
|
||||
int flags = w->flags();
|
||||
int flags = w->flags();
|
||||
|
||||
if (w->flags() & DBUS_WATCH_READABLE)
|
||||
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ);
|
||||
if (w->flags() & DBUS_WATCH_WRITABLE)
|
||||
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE);
|
||||
if (w->flags() & DBUS_WATCH_READABLE)
|
||||
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_READ);
|
||||
if (w->flags() & DBUS_WATCH_WRITABLE)
|
||||
ecore_main_fd_handler_active_set(w->fd_handler, ECORE_FD_WRITE);
|
||||
|
||||
w->handle(flags);
|
||||
w->_bd->dispatch_pending();
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void Ecore::BusWatch::_enable()
|
||||
{
|
||||
debug_log("Ecore::BusWatch::_enable()");
|
||||
|
||||
fd_handler = ecore_main_fd_handler_add (descriptor(),
|
||||
(Ecore_Fd_Handler_Flags) (ECORE_FD_READ | ECORE_FD_WRITE),
|
||||
watch_dispatch, this,
|
||||
NULL, NULL);
|
||||
fd_handler = ecore_main_fd_handler_add(descriptor(),
|
||||
(Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_WRITE),
|
||||
watch_dispatch, this,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
void Ecore::BusWatch::_disable()
|
||||
{
|
||||
if (fd_handler)
|
||||
{
|
||||
ecore_main_fd_handler_del (fd_handler);
|
||||
ecore_main_fd_handler_del(fd_handler);
|
||||
fd_handler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void Ecore::BusWatch::data (Ecore::BusDispatcher *bd)
|
||||
void Ecore::BusWatch::data(Ecore::BusDispatcher *bd)
|
||||
{
|
||||
_bd = bd;
|
||||
}
|
||||
|
@ -155,41 +155,41 @@ Ecore::BusDispatcher::BusDispatcher()
|
|||
{
|
||||
}
|
||||
|
||||
Eina_Bool Ecore::BusDispatcher::check ( void *data, Ecore_Fd_Handler *fdh)
|
||||
Eina_Bool Ecore::BusDispatcher::check(void *data, Ecore_Fd_Handler *fdh)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Timeout* Ecore::BusDispatcher::add_timeout( Timeout::Internal* wi )
|
||||
Timeout *Ecore::BusDispatcher::add_timeout(Timeout::Internal *wi)
|
||||
{
|
||||
Timeout* t = new Ecore::BusTimeout( wi );
|
||||
Timeout *t = new Ecore::BusTimeout(wi);
|
||||
|
||||
debug_log("ecore: added timeout %p (%s)", t, t->enabled() ? "on":"off");
|
||||
debug_log("ecore: added timeout %p (%s)", t, t->enabled() ? "on" : "off");
|
||||
|
||||
return t;
|
||||
return t;
|
||||
}
|
||||
|
||||
void Ecore::BusDispatcher::rem_timeout( Timeout* t )
|
||||
void Ecore::BusDispatcher::rem_timeout(Timeout *t)
|
||||
{
|
||||
debug_log("ecore: removed timeout %p", t);
|
||||
debug_log("ecore: removed timeout %p", t);
|
||||
|
||||
delete t;
|
||||
delete t;
|
||||
}
|
||||
|
||||
Watch* Ecore::BusDispatcher::add_watch( Watch::Internal* wi )
|
||||
Watch *Ecore::BusDispatcher::add_watch(Watch::Internal *wi)
|
||||
{
|
||||
Ecore::BusWatch* w = new Ecore::BusWatch(wi);
|
||||
w->data (this);
|
||||
Ecore::BusWatch *w = new Ecore::BusWatch(wi);
|
||||
w->data(this);
|
||||
|
||||
debug_log("ecore: added watch %p (%s) fd=%d flags=%d",
|
||||
w, w->enabled() ? "on":"off", w->descriptor(), w->flags()
|
||||
);
|
||||
return w;
|
||||
debug_log("ecore: added watch %p (%s) fd=%d flags=%d",
|
||||
w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
|
||||
);
|
||||
return w;
|
||||
}
|
||||
|
||||
void Ecore::BusDispatcher::rem_watch( Watch* w )
|
||||
void Ecore::BusDispatcher::rem_watch(Watch *w)
|
||||
{
|
||||
debug_log("ecore: removed watch %p", w);
|
||||
debug_log("ecore: removed watch %p", w);
|
||||
|
||||
delete w;
|
||||
delete w;
|
||||
}
|
||||
|
|
|
@ -39,23 +39,23 @@ using namespace DBus;
|
|||
*/
|
||||
|
||||
Error::Error()
|
||||
: _int(new InternalError)
|
||||
: _int(new InternalError)
|
||||
{}
|
||||
|
||||
Error::Error(InternalError &i)
|
||||
: _int(new InternalError(i))
|
||||
: _int(new InternalError(i))
|
||||
{}
|
||||
|
||||
Error::Error(const char *name, const char *message)
|
||||
: _int(new InternalError)
|
||||
: _int(new InternalError)
|
||||
{
|
||||
set(name, message);
|
||||
set(name, message);
|
||||
}
|
||||
|
||||
Error::Error(Message &m)
|
||||
: _int(new InternalError)
|
||||
: _int(new InternalError)
|
||||
{
|
||||
dbus_set_error_from_message(&(_int->error), m._pvt->msg);
|
||||
dbus_set_error_from_message(&(_int->error), m._pvt->msg);
|
||||
}
|
||||
|
||||
Error::~Error() throw()
|
||||
|
@ -64,26 +64,26 @@ Error::~Error() throw()
|
|||
|
||||
const char *Error::name() const
|
||||
{
|
||||
return _int->error.name;
|
||||
return _int->error.name;
|
||||
}
|
||||
|
||||
const char *Error::message() const
|
||||
{
|
||||
return _int->error.message;
|
||||
return _int->error.message;
|
||||
}
|
||||
|
||||
bool Error::is_set() const
|
||||
{
|
||||
return *(_int);
|
||||
return *(_int);
|
||||
}
|
||||
|
||||
void Error::set(const char *name, const char *message)
|
||||
{
|
||||
dbus_set_error_const(&(_int->error), name, message);
|
||||
dbus_set_error_const(&(_int->error), name, message);
|
||||
}
|
||||
|
||||
const char *Error::what() const throw()
|
||||
{
|
||||
return _int->error.message;
|
||||
return _int->error.message;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,182 +43,182 @@ using namespace DBus;
|
|||
using namespace std;
|
||||
|
||||
BusTimeout::BusTimeout(Timeout::Internal *ti, BusDispatcher *bd)
|
||||
: Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
|
||||
: Timeout(ti), DefaultTimeout(Timeout::interval(), true, bd)
|
||||
{
|
||||
DefaultTimeout::enabled(Timeout::enabled());
|
||||
DefaultTimeout::enabled(Timeout::enabled());
|
||||
}
|
||||
|
||||
void BusTimeout::toggle()
|
||||
{
|
||||
debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off");
|
||||
debug_log("timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
|
||||
|
||||
DefaultTimeout::enabled(Timeout::enabled());
|
||||
DefaultTimeout::enabled(Timeout::enabled());
|
||||
}
|
||||
|
||||
BusWatch::BusWatch(Watch::Internal *wi, BusDispatcher *bd)
|
||||
: Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
|
||||
: Watch(wi), DefaultWatch(Watch::descriptor(), 0, bd)
|
||||
{
|
||||
int flags = POLLHUP | POLLERR;
|
||||
int flags = POLLHUP | POLLERR;
|
||||
|
||||
if (Watch::flags() & DBUS_WATCH_READABLE)
|
||||
flags |= POLLIN;
|
||||
if (Watch::flags() & DBUS_WATCH_WRITABLE)
|
||||
flags |= POLLOUT;
|
||||
if (Watch::flags() & DBUS_WATCH_READABLE)
|
||||
flags |= POLLIN;
|
||||
if (Watch::flags() & DBUS_WATCH_WRITABLE)
|
||||
flags |= POLLOUT;
|
||||
|
||||
DefaultWatch::flags(flags);
|
||||
DefaultWatch::enabled(Watch::enabled());
|
||||
DefaultWatch::flags(flags);
|
||||
DefaultWatch::enabled(Watch::enabled());
|
||||
}
|
||||
|
||||
void BusWatch::toggle()
|
||||
{
|
||||
debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on":"off");
|
||||
debug_log("watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
|
||||
|
||||
DefaultWatch::enabled(Watch::enabled());
|
||||
DefaultWatch::enabled(Watch::enabled());
|
||||
}
|
||||
|
||||
BusDispatcher::BusDispatcher() :
|
||||
_running(false)
|
||||
_running(false)
|
||||
{
|
||||
// pipe to create a new fd used to unlock a dispatcher at any
|
||||
// pipe to create a new fd used to unlock a dispatcher at any
|
||||
// moment (used by leave function)
|
||||
int ret = pipe(_pipe);
|
||||
if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
|
||||
|
||||
_fdunlock[0] = _pipe[0];
|
||||
_fdunlock[1] = _pipe[1];
|
||||
int ret = pipe(_pipe);
|
||||
if (ret == -1) throw Error("PipeError:errno", toString(errno).c_str());
|
||||
|
||||
_fdunlock[0] = _pipe[0];
|
||||
_fdunlock[1] = _pipe[1];
|
||||
}
|
||||
|
||||
void BusDispatcher::enter()
|
||||
{
|
||||
debug_log("entering dispatcher %p", this);
|
||||
debug_log("entering dispatcher %p", this);
|
||||
|
||||
_running = true;
|
||||
_running = true;
|
||||
|
||||
while (_running)
|
||||
{
|
||||
do_iteration();
|
||||
while (_running)
|
||||
{
|
||||
do_iteration();
|
||||
|
||||
for (std::list <Pipe*>::iterator p_it = pipe_list.begin ();
|
||||
p_it != pipe_list.end ();
|
||||
++p_it)
|
||||
{
|
||||
Pipe* read_pipe = *p_it;
|
||||
for (std::list <Pipe *>::iterator p_it = pipe_list.begin();
|
||||
p_it != pipe_list.end();
|
||||
++p_it)
|
||||
{
|
||||
Pipe *read_pipe = *p_it;
|
||||
char buffer[1024]; // TODO: should be max pipe size
|
||||
unsigned int nbytes = 0;
|
||||
|
||||
|
||||
while (read_pipe->read(buffer, nbytes) > 0)
|
||||
{
|
||||
read_pipe->_handler (read_pipe->_data, buffer, nbytes);
|
||||
{
|
||||
read_pipe->_handler(read_pipe->_data, buffer, nbytes);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug_log("leaving dispatcher %p", this);
|
||||
debug_log("leaving dispatcher %p", this);
|
||||
}
|
||||
|
||||
void BusDispatcher::leave()
|
||||
{
|
||||
_running = false;
|
||||
|
||||
int ret = write(_fdunlock[1],"exit",strlen("exit"));
|
||||
if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
|
||||
|
||||
close(_fdunlock[1]);
|
||||
close(_fdunlock[0]);
|
||||
_running = false;
|
||||
|
||||
int ret = write(_fdunlock[1], "exit", strlen("exit"));
|
||||
if (ret == -1) throw Error("WriteError:errno", toString(errno).c_str());
|
||||
|
||||
close(_fdunlock[1]);
|
||||
close(_fdunlock[0]);
|
||||
}
|
||||
|
||||
Pipe *BusDispatcher::add_pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data)
|
||||
{
|
||||
Pipe *new_pipe = new Pipe (handler, data);
|
||||
pipe_list.push_back (new_pipe);
|
||||
Pipe *new_pipe = new Pipe(handler, data);
|
||||
pipe_list.push_back(new_pipe);
|
||||
|
||||
return new_pipe;
|
||||
return new_pipe;
|
||||
}
|
||||
|
||||
void BusDispatcher::del_pipe (Pipe *pipe)
|
||||
void BusDispatcher::del_pipe(Pipe *pipe)
|
||||
{
|
||||
pipe_list.remove (pipe);
|
||||
delete pipe;
|
||||
pipe_list.remove(pipe);
|
||||
delete pipe;
|
||||
}
|
||||
|
||||
void BusDispatcher::do_iteration()
|
||||
{
|
||||
dispatch_pending();
|
||||
dispatch();
|
||||
dispatch_pending();
|
||||
dispatch();
|
||||
}
|
||||
|
||||
Timeout *BusDispatcher::add_timeout(Timeout::Internal *ti)
|
||||
{
|
||||
BusTimeout *bt = new BusTimeout(ti, this);
|
||||
BusTimeout *bt = new BusTimeout(ti, this);
|
||||
|
||||
bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
|
||||
bt->data(bt);
|
||||
bt->expired = new Callback<BusDispatcher, void, DefaultTimeout &>(this, &BusDispatcher::timeout_expired);
|
||||
bt->data(bt);
|
||||
|
||||
debug_log("added timeout %p (%s) (%d millies)",
|
||||
bt,
|
||||
((Timeout*)bt)->enabled() ? "on":"off",
|
||||
((Timeout*)bt)->interval()
|
||||
);
|
||||
debug_log("added timeout %p (%s) (%d millies)",
|
||||
bt,
|
||||
((Timeout *)bt)->enabled() ? "on" : "off",
|
||||
((Timeout *)bt)->interval()
|
||||
);
|
||||
|
||||
return bt;
|
||||
return bt;
|
||||
}
|
||||
|
||||
void BusDispatcher::rem_timeout(Timeout *t)
|
||||
{
|
||||
debug_log("removed timeout %p", t);
|
||||
debug_log("removed timeout %p", t);
|
||||
|
||||
delete t;
|
||||
delete t;
|
||||
}
|
||||
|
||||
Watch *BusDispatcher::add_watch(Watch::Internal *wi)
|
||||
{
|
||||
BusWatch *bw = new BusWatch(wi, this);
|
||||
BusWatch *bw = new BusWatch(wi, this);
|
||||
|
||||
bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
|
||||
bw->data(bw);
|
||||
bw->ready = new Callback<BusDispatcher, void, DefaultWatch &>(this, &BusDispatcher::watch_ready);
|
||||
bw->data(bw);
|
||||
|
||||
debug_log("added watch %p (%s) fd=%d flags=%d",
|
||||
bw, ((Watch *)bw)->enabled() ? "on":"off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
|
||||
debug_log("added watch %p (%s) fd=%d flags=%d",
|
||||
bw, ((Watch *)bw)->enabled() ? "on" : "off", ((Watch *)bw)->descriptor(), ((Watch *)bw)->flags());
|
||||
|
||||
return bw;
|
||||
return bw;
|
||||
}
|
||||
|
||||
void BusDispatcher::rem_watch(Watch *w)
|
||||
{
|
||||
debug_log("removed watch %p", w);
|
||||
debug_log("removed watch %p", w);
|
||||
|
||||
delete w;
|
||||
delete w;
|
||||
}
|
||||
|
||||
void BusDispatcher::timeout_expired(DefaultTimeout &et)
|
||||
{
|
||||
debug_log("timeout %p expired", &et);
|
||||
debug_log("timeout %p expired", &et);
|
||||
|
||||
BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
|
||||
BusTimeout *timeout = reinterpret_cast<BusTimeout *>(et.data());
|
||||
|
||||
timeout->handle();
|
||||
timeout->handle();
|
||||
}
|
||||
|
||||
void BusDispatcher::watch_ready(DefaultWatch &ew)
|
||||
{
|
||||
BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
|
||||
BusWatch *watch = reinterpret_cast<BusWatch *>(ew.data());
|
||||
|
||||
debug_log("watch %p ready, flags=%d state=%d",
|
||||
watch, ((Watch *)watch)->flags(), watch->state()
|
||||
);
|
||||
debug_log("watch %p ready, flags=%d state=%d",
|
||||
watch, ((Watch *)watch)->flags(), watch->state()
|
||||
);
|
||||
|
||||
int flags = 0;
|
||||
int flags = 0;
|
||||
|
||||
if (watch->state() & POLLIN)
|
||||
flags |= DBUS_WATCH_READABLE;
|
||||
if (watch->state() & POLLOUT)
|
||||
flags |= DBUS_WATCH_WRITABLE;
|
||||
if (watch->state() & POLLHUP)
|
||||
flags |= DBUS_WATCH_HANGUP;
|
||||
if (watch->state() & POLLERR)
|
||||
flags |= DBUS_WATCH_ERROR;
|
||||
if (watch->state() & POLLIN)
|
||||
flags |= DBUS_WATCH_READABLE;
|
||||
if (watch->state() & POLLOUT)
|
||||
flags |= DBUS_WATCH_WRITABLE;
|
||||
if (watch->state() & POLLHUP)
|
||||
flags |= DBUS_WATCH_HANGUP;
|
||||
if (watch->state() & POLLERR)
|
||||
flags |= DBUS_WATCH_ERROR;
|
||||
|
||||
watch->handle(flags);
|
||||
watch->handle(flags);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,225 +38,226 @@ using namespace std;
|
|||
|
||||
static double millis(timeval tv)
|
||||
{
|
||||
return (tv.tv_sec *1000.0 + tv.tv_usec/1000.0);
|
||||
return (tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0);
|
||||
}
|
||||
|
||||
|
||||
DefaultTimeout::DefaultTimeout(int interval, bool repeat, DefaultMainLoop *ed)
|
||||
: _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
|
||||
: _enabled(true), _interval(interval), _repeat(repeat), _expiration(0), _data(0), _disp(ed)
|
||||
{
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
_expiration = millis(now) + interval;
|
||||
_expiration = millis(now) + interval;
|
||||
|
||||
_disp->_mutex_t.lock();
|
||||
_disp->_timeouts.push_back(this);
|
||||
_disp->_mutex_t.unlock();
|
||||
_disp->_mutex_t.lock();
|
||||
_disp->_timeouts.push_back(this);
|
||||
_disp->_mutex_t.unlock();
|
||||
}
|
||||
|
||||
DefaultTimeout::~DefaultTimeout()
|
||||
{
|
||||
_disp->_mutex_t.lock();
|
||||
_disp->_timeouts.remove(this);
|
||||
_disp->_mutex_t.unlock();
|
||||
_disp->_mutex_t.lock();
|
||||
_disp->_timeouts.remove(this);
|
||||
_disp->_mutex_t.unlock();
|
||||
}
|
||||
|
||||
DefaultWatch::DefaultWatch(int fd, int flags, DefaultMainLoop *ed)
|
||||
: _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
|
||||
: _enabled(true), _fd(fd), _flags(flags), _state(0), _data(0), _disp(ed)
|
||||
{
|
||||
_disp->_mutex_w.lock();
|
||||
_disp->_watches.push_back(this);
|
||||
_disp->_mutex_w.unlock();
|
||||
_disp->_mutex_w.lock();
|
||||
_disp->_watches.push_back(this);
|
||||
_disp->_mutex_w.unlock();
|
||||
}
|
||||
|
||||
DefaultWatch::~DefaultWatch()
|
||||
{
|
||||
_disp->_mutex_w.lock();
|
||||
_disp->_watches.remove(this);
|
||||
_disp->_mutex_w.unlock();
|
||||
_disp->_mutex_w.lock();
|
||||
_disp->_watches.remove(this);
|
||||
_disp->_mutex_w.unlock();
|
||||
}
|
||||
|
||||
DefaultMutex::DefaultMutex()
|
||||
{
|
||||
pthread_mutex_init(&_mutex, NULL);
|
||||
pthread_mutex_init(&_mutex, NULL);
|
||||
}
|
||||
|
||||
DefaultMutex::DefaultMutex(bool recursive)
|
||||
{
|
||||
if (recursive)
|
||||
{
|
||||
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
_mutex = recmutex;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_init(&_mutex, NULL);
|
||||
}
|
||||
if (recursive)
|
||||
{
|
||||
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
|
||||
_mutex = recmutex;
|
||||
}
|
||||
else
|
||||
{
|
||||
pthread_mutex_init(&_mutex, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
DefaultMutex::~DefaultMutex()
|
||||
{
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
pthread_mutex_destroy(&_mutex);
|
||||
}
|
||||
|
||||
void DefaultMutex::lock()
|
||||
{
|
||||
pthread_mutex_lock(&_mutex);
|
||||
pthread_mutex_lock(&_mutex);
|
||||
}
|
||||
|
||||
void DefaultMutex::unlock()
|
||||
{
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
pthread_mutex_unlock(&_mutex);
|
||||
}
|
||||
|
||||
DefaultMainLoop::DefaultMainLoop() :
|
||||
_mutex_w(true)
|
||||
_mutex_w(true)
|
||||
{
|
||||
}
|
||||
|
||||
DefaultMainLoop::~DefaultMainLoop()
|
||||
{
|
||||
_mutex_w.lock();
|
||||
_mutex_w.lock();
|
||||
|
||||
DefaultWatches::iterator wi = _watches.begin();
|
||||
while (wi != _watches.end())
|
||||
{
|
||||
DefaultWatches::iterator wmp = wi;
|
||||
++wmp;
|
||||
_mutex_w.unlock();
|
||||
delete (*wi);
|
||||
_mutex_w.lock();
|
||||
wi = wmp;
|
||||
}
|
||||
_mutex_w.unlock();
|
||||
DefaultWatches::iterator wi = _watches.begin();
|
||||
while (wi != _watches.end())
|
||||
{
|
||||
DefaultWatches::iterator wmp = wi;
|
||||
++wmp;
|
||||
_mutex_w.unlock();
|
||||
delete(*wi);
|
||||
_mutex_w.lock();
|
||||
wi = wmp;
|
||||
}
|
||||
_mutex_w.unlock();
|
||||
|
||||
_mutex_t.lock();
|
||||
_mutex_t.lock();
|
||||
|
||||
DefaultTimeouts::iterator ti = _timeouts.begin();
|
||||
while (ti != _timeouts.end())
|
||||
{
|
||||
DefaultTimeouts::iterator tmp = ti;
|
||||
++tmp;
|
||||
_mutex_t.unlock();
|
||||
delete (*ti);
|
||||
_mutex_t.lock();
|
||||
ti = tmp;
|
||||
}
|
||||
_mutex_t.unlock();
|
||||
DefaultTimeouts::iterator ti = _timeouts.begin();
|
||||
while (ti != _timeouts.end())
|
||||
{
|
||||
DefaultTimeouts::iterator tmp = ti;
|
||||
++tmp;
|
||||
_mutex_t.unlock();
|
||||
delete(*ti);
|
||||
_mutex_t.lock();
|
||||
ti = tmp;
|
||||
}
|
||||
_mutex_t.unlock();
|
||||
}
|
||||
|
||||
void DefaultMainLoop::dispatch()
|
||||
{
|
||||
_mutex_w.lock();
|
||||
_mutex_w.lock();
|
||||
|
||||
int nfd = _watches.size();
|
||||
int nfd = _watches.size();
|
||||
|
||||
if(_fdunlock)
|
||||
{
|
||||
nfd=nfd+2;
|
||||
}
|
||||
if (_fdunlock)
|
||||
{
|
||||
nfd = nfd + 2;
|
||||
}
|
||||
|
||||
pollfd fds[nfd];
|
||||
pollfd fds[nfd];
|
||||
|
||||
DefaultWatches::iterator wi = _watches.begin();
|
||||
DefaultWatches::iterator wi = _watches.begin();
|
||||
|
||||
for (nfd = 0; wi != _watches.end(); ++wi)
|
||||
{
|
||||
if ((*wi)->enabled())
|
||||
{
|
||||
fds[nfd].fd = (*wi)->descriptor();
|
||||
fds[nfd].events = (*wi)->flags();
|
||||
fds[nfd].revents = 0;
|
||||
for (nfd = 0; wi != _watches.end(); ++wi)
|
||||
{
|
||||
if ((*wi)->enabled())
|
||||
{
|
||||
fds[nfd].fd = (*wi)->descriptor();
|
||||
fds[nfd].events = (*wi)->flags();
|
||||
fds[nfd].revents = 0;
|
||||
|
||||
++nfd;
|
||||
}
|
||||
}
|
||||
++nfd;
|
||||
}
|
||||
}
|
||||
|
||||
if(_fdunlock){
|
||||
fds[nfd].fd = _fdunlock[0];
|
||||
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
|
||||
fds[nfd].revents = 0;
|
||||
|
||||
nfd++;
|
||||
fds[nfd].fd = _fdunlock[1];
|
||||
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
|
||||
fds[nfd].revents = 0;
|
||||
}
|
||||
if (_fdunlock)
|
||||
{
|
||||
fds[nfd].fd = _fdunlock[0];
|
||||
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
|
||||
fds[nfd].revents = 0;
|
||||
|
||||
_mutex_w.unlock();
|
||||
nfd++;
|
||||
fds[nfd].fd = _fdunlock[1];
|
||||
fds[nfd].events = POLLIN | POLLOUT | POLLPRI ;
|
||||
fds[nfd].revents = 0;
|
||||
}
|
||||
|
||||
int wait_min = 10000;
|
||||
_mutex_w.unlock();
|
||||
|
||||
DefaultTimeouts::iterator ti;
|
||||
int wait_min = 10000;
|
||||
|
||||
_mutex_t.lock();
|
||||
DefaultTimeouts::iterator ti;
|
||||
|
||||
for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
|
||||
{
|
||||
if ((*ti)->enabled() && (*ti)->interval() < wait_min)
|
||||
wait_min = (*ti)->interval();
|
||||
}
|
||||
_mutex_t.lock();
|
||||
|
||||
_mutex_t.unlock();
|
||||
for (ti = _timeouts.begin(); ti != _timeouts.end(); ++ti)
|
||||
{
|
||||
if ((*ti)->enabled() && (*ti)->interval() < wait_min)
|
||||
wait_min = (*ti)->interval();
|
||||
}
|
||||
|
||||
poll(fds, nfd, wait_min);
|
||||
_mutex_t.unlock();
|
||||
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
poll(fds, nfd, wait_min);
|
||||
|
||||
double now_millis = millis(now);
|
||||
timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
_mutex_t.lock();
|
||||
double now_millis = millis(now);
|
||||
|
||||
ti = _timeouts.begin();
|
||||
_mutex_t.lock();
|
||||
|
||||
while (ti != _timeouts.end())
|
||||
{
|
||||
DefaultTimeouts::iterator tmp = ti;
|
||||
++tmp;
|
||||
ti = _timeouts.begin();
|
||||
|
||||
if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
|
||||
{
|
||||
(*ti)->expired(*(*ti));
|
||||
while (ti != _timeouts.end())
|
||||
{
|
||||
DefaultTimeouts::iterator tmp = ti;
|
||||
++tmp;
|
||||
|
||||
if ((*ti)->_repeat)
|
||||
{
|
||||
(*ti)->_expiration = now_millis + (*ti)->_interval;
|
||||
}
|
||||
if ((*ti)->enabled() && now_millis >= (*ti)->_expiration)
|
||||
{
|
||||
(*ti)->expired(*(*ti));
|
||||
|
||||
}
|
||||
if ((*ti)->_repeat)
|
||||
{
|
||||
(*ti)->_expiration = now_millis + (*ti)->_interval;
|
||||
}
|
||||
|
||||
ti = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
_mutex_t.unlock();
|
||||
ti = tmp;
|
||||
}
|
||||
|
||||
_mutex_w.lock();
|
||||
_mutex_t.unlock();
|
||||
|
||||
for (int j = 0; j < nfd; ++j)
|
||||
{
|
||||
DefaultWatches::iterator wi;
|
||||
_mutex_w.lock();
|
||||
|
||||
for (wi = _watches.begin(); wi != _watches.end();)
|
||||
{
|
||||
DefaultWatches::iterator tmp = wi;
|
||||
++tmp;
|
||||
for (int j = 0; j < nfd; ++j)
|
||||
{
|
||||
DefaultWatches::iterator wi;
|
||||
|
||||
if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
|
||||
{
|
||||
if (fds[j].revents)
|
||||
{
|
||||
(*wi)->_state = fds[j].revents;
|
||||
for (wi = _watches.begin(); wi != _watches.end();)
|
||||
{
|
||||
DefaultWatches::iterator tmp = wi;
|
||||
++tmp;
|
||||
|
||||
(*wi)->ready(*(*wi));
|
||||
if ((*wi)->enabled() && (*wi)->_fd == fds[j].fd)
|
||||
{
|
||||
if (fds[j].revents)
|
||||
{
|
||||
(*wi)->_state = fds[j].revents;
|
||||
|
||||
fds[j].revents = 0;
|
||||
}
|
||||
}
|
||||
(*wi)->ready(*(*wi));
|
||||
|
||||
wi = tmp;
|
||||
}
|
||||
}
|
||||
_mutex_w.unlock();
|
||||
fds[j].revents = 0;
|
||||
}
|
||||
}
|
||||
|
||||
wi = tmp;
|
||||
}
|
||||
}
|
||||
_mutex_w.unlock();
|
||||
}
|
||||
|
||||
|
|
|
@ -31,169 +31,170 @@
|
|||
using namespace DBus;
|
||||
|
||||
Glib::BusTimeout::BusTimeout(Timeout::Internal *ti, GMainContext *ctx, int priority)
|
||||
: Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL)
|
||||
: Timeout(ti), _ctx(ctx), _priority(priority), _source(NULL)
|
||||
{
|
||||
if (Timeout::enabled())
|
||||
_enable();
|
||||
if (Timeout::enabled())
|
||||
_enable();
|
||||
}
|
||||
|
||||
Glib::BusTimeout::~BusTimeout()
|
||||
{
|
||||
_disable();
|
||||
_disable();
|
||||
}
|
||||
|
||||
void Glib::BusTimeout::toggle()
|
||||
{
|
||||
debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on":"off");
|
||||
debug_log("glib: timeout %p toggled (%s)", this, Timeout::enabled() ? "on" : "off");
|
||||
|
||||
if (Timeout::enabled()) _enable();
|
||||
else _disable();
|
||||
if (Timeout::enabled()) _enable();
|
||||
else _disable();
|
||||
}
|
||||
|
||||
gboolean Glib::BusTimeout::timeout_handler(gpointer data)
|
||||
{
|
||||
Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *>(data);
|
||||
Glib::BusTimeout *t = reinterpret_cast<Glib::BusTimeout *>(data);
|
||||
|
||||
t->handle();
|
||||
t->handle();
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void Glib::BusTimeout::_enable()
|
||||
{
|
||||
if (_source)
|
||||
_disable(); // be sane
|
||||
if (_source)
|
||||
_disable(); // be sane
|
||||
|
||||
_source = g_timeout_source_new(Timeout::interval());
|
||||
g_source_set_priority(_source, _priority);
|
||||
g_source_set_callback(_source, timeout_handler, this, NULL);
|
||||
g_source_attach(_source, _ctx);
|
||||
_source = g_timeout_source_new(Timeout::interval());
|
||||
g_source_set_priority(_source, _priority);
|
||||
g_source_set_callback(_source, timeout_handler, this, NULL);
|
||||
g_source_attach(_source, _ctx);
|
||||
}
|
||||
|
||||
void Glib::BusTimeout::_disable()
|
||||
{
|
||||
if (_source)
|
||||
{
|
||||
g_source_destroy(_source);
|
||||
_source = NULL;
|
||||
}
|
||||
if (_source)
|
||||
{
|
||||
g_source_destroy(_source);
|
||||
_source = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct BusSource
|
||||
{
|
||||
GSource source;
|
||||
GPollFD poll;
|
||||
GSource source;
|
||||
GPollFD poll;
|
||||
};
|
||||
|
||||
static gboolean watch_prepare(GSource *source, gint *timeout)
|
||||
{
|
||||
debug_log("glib: watch_prepare");
|
||||
debug_log("glib: watch_prepare");
|
||||
|
||||
*timeout = -1;
|
||||
return FALSE;
|
||||
*timeout = -1;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean watch_check(GSource *source)
|
||||
{
|
||||
debug_log("glib: watch_check");
|
||||
debug_log("glib: watch_check");
|
||||
|
||||
BusSource *io = (BusSource *)source;
|
||||
return io->poll.revents ? TRUE : FALSE;
|
||||
BusSource *io = (BusSource *)source;
|
||||
return io->poll.revents ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static gboolean watch_dispatch(GSource *source, GSourceFunc callback, gpointer data)
|
||||
{
|
||||
debug_log("glib: watch_dispatch");
|
||||
debug_log("glib: watch_dispatch");
|
||||
|
||||
gboolean cb = callback(data);
|
||||
return cb;
|
||||
gboolean cb = callback(data);
|
||||
return cb;
|
||||
}
|
||||
|
||||
static GSourceFuncs watch_funcs = {
|
||||
watch_prepare,
|
||||
watch_check,
|
||||
watch_dispatch,
|
||||
NULL
|
||||
static GSourceFuncs watch_funcs =
|
||||
{
|
||||
watch_prepare,
|
||||
watch_check,
|
||||
watch_dispatch,
|
||||
NULL
|
||||
};
|
||||
|
||||
Glib::BusWatch::BusWatch(Watch::Internal *wi, GMainContext *ctx, int priority)
|
||||
: Watch(wi), _ctx(ctx), _priority(priority), _source(NULL)
|
||||
: Watch(wi), _ctx(ctx), _priority(priority), _source(NULL)
|
||||
{
|
||||
if (Watch::enabled())
|
||||
_enable();
|
||||
if (Watch::enabled())
|
||||
_enable();
|
||||
}
|
||||
|
||||
Glib::BusWatch::~BusWatch()
|
||||
{
|
||||
_disable();
|
||||
_disable();
|
||||
}
|
||||
|
||||
void Glib::BusWatch::toggle()
|
||||
{
|
||||
debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on":"off");
|
||||
debug_log("glib: watch %p toggled (%s)", this, Watch::enabled() ? "on" : "off");
|
||||
|
||||
if (Watch::enabled()) _enable();
|
||||
else _disable();
|
||||
if (Watch::enabled()) _enable();
|
||||
else _disable();
|
||||
}
|
||||
|
||||
gboolean Glib::BusWatch::watch_handler(gpointer data)
|
||||
{
|
||||
Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *>(data);
|
||||
Glib::BusWatch *w = reinterpret_cast<Glib::BusWatch *>(data);
|
||||
|
||||
BusSource *io = (BusSource *)(w->_source);
|
||||
BusSource *io = (BusSource *)(w->_source);
|
||||
|
||||
int flags = 0;
|
||||
if (io->poll.revents &G_IO_IN)
|
||||
flags |= DBUS_WATCH_READABLE;
|
||||
if (io->poll.revents &G_IO_OUT)
|
||||
flags |= DBUS_WATCH_WRITABLE;
|
||||
if (io->poll.revents &G_IO_ERR)
|
||||
flags |= DBUS_WATCH_ERROR;
|
||||
if (io->poll.revents &G_IO_HUP)
|
||||
flags |= DBUS_WATCH_HANGUP;
|
||||
int flags = 0;
|
||||
if (io->poll.revents & G_IO_IN)
|
||||
flags |= DBUS_WATCH_READABLE;
|
||||
if (io->poll.revents & G_IO_OUT)
|
||||
flags |= DBUS_WATCH_WRITABLE;
|
||||
if (io->poll.revents & G_IO_ERR)
|
||||
flags |= DBUS_WATCH_ERROR;
|
||||
if (io->poll.revents & G_IO_HUP)
|
||||
flags |= DBUS_WATCH_HANGUP;
|
||||
|
||||
w->handle(flags);
|
||||
w->handle(flags);
|
||||
|
||||
return TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void Glib::BusWatch::_enable()
|
||||
{
|
||||
if (_source)
|
||||
_disable(); // be sane
|
||||
_source = g_source_new(&watch_funcs, sizeof(BusSource));
|
||||
g_source_set_priority(_source, _priority);
|
||||
g_source_set_callback(_source, watch_handler, this, NULL);
|
||||
if (_source)
|
||||
_disable(); // be sane
|
||||
_source = g_source_new(&watch_funcs, sizeof(BusSource));
|
||||
g_source_set_priority(_source, _priority);
|
||||
g_source_set_callback(_source, watch_handler, this, NULL);
|
||||
|
||||
int flags = Watch::flags();
|
||||
int condition = 0;
|
||||
int flags = Watch::flags();
|
||||
int condition = 0;
|
||||
|
||||
if (flags &DBUS_WATCH_READABLE)
|
||||
condition |= G_IO_IN;
|
||||
if (flags &DBUS_WATCH_WRITABLE)
|
||||
condition |= G_IO_OUT;
|
||||
if (flags &DBUS_WATCH_ERROR)
|
||||
condition |= G_IO_ERR;
|
||||
if (flags &DBUS_WATCH_HANGUP)
|
||||
condition |= G_IO_HUP;
|
||||
if (flags & DBUS_WATCH_READABLE)
|
||||
condition |= G_IO_IN;
|
||||
if (flags & DBUS_WATCH_WRITABLE)
|
||||
condition |= G_IO_OUT;
|
||||
if (flags & DBUS_WATCH_ERROR)
|
||||
condition |= G_IO_ERR;
|
||||
if (flags & DBUS_WATCH_HANGUP)
|
||||
condition |= G_IO_HUP;
|
||||
|
||||
GPollFD *poll = &(((BusSource *)_source)->poll);
|
||||
poll->fd = Watch::descriptor();
|
||||
poll->events = condition;
|
||||
poll->revents = 0;
|
||||
GPollFD *poll = &(((BusSource *)_source)->poll);
|
||||
poll->fd = Watch::descriptor();
|
||||
poll->events = condition;
|
||||
poll->revents = 0;
|
||||
|
||||
g_source_add_poll(_source, poll);
|
||||
g_source_attach(_source, _ctx);
|
||||
g_source_add_poll(_source, poll);
|
||||
g_source_attach(_source, _ctx);
|
||||
}
|
||||
|
||||
void Glib::BusWatch::_disable()
|
||||
{
|
||||
if (!_source)
|
||||
return;
|
||||
GPollFD *poll = &(((BusSource *)_source)->poll);
|
||||
g_source_remove_poll(_source, poll);
|
||||
g_source_destroy(_source);
|
||||
_source = NULL;
|
||||
if (!_source)
|
||||
return;
|
||||
GPollFD *poll = &(((BusSource *)_source)->poll);
|
||||
g_source_remove_poll(_source, poll);
|
||||
g_source_destroy(_source);
|
||||
_source = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -203,23 +204,23 @@ void Glib::BusWatch::_disable()
|
|||
*/
|
||||
struct DispatcherSource
|
||||
{
|
||||
GSource source;
|
||||
Dispatcher *dispatcher;
|
||||
GSource source;
|
||||
Dispatcher *dispatcher;
|
||||
};
|
||||
|
||||
|
||||
static gboolean dispatcher_prepare(GSource *source, gint *timeout)
|
||||
{
|
||||
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher;
|
||||
|
||||
*timeout = -1;
|
||||
Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
|
||||
|
||||
return dispatcher->has_something_to_dispatch()? TRUE:FALSE;
|
||||
*timeout = -1;
|
||||
|
||||
return dispatcher->has_something_to_dispatch() ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static gboolean dispatcher_check(GSource *source)
|
||||
{
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -227,88 +228,89 @@ dispatcher_dispatch(GSource *source,
|
|||
GSourceFunc callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
Dispatcher *dispatcher = ((DispatcherSource*)source)->dispatcher;
|
||||
Dispatcher *dispatcher = ((DispatcherSource *)source)->dispatcher;
|
||||
|
||||
dispatcher->dispatch_pending();
|
||||
return TRUE;
|
||||
dispatcher->dispatch_pending();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const GSourceFuncs dispatcher_funcs = {
|
||||
dispatcher_prepare,
|
||||
dispatcher_check,
|
||||
dispatcher_dispatch,
|
||||
NULL
|
||||
static const GSourceFuncs dispatcher_funcs =
|
||||
{
|
||||
dispatcher_prepare,
|
||||
dispatcher_check,
|
||||
dispatcher_dispatch,
|
||||
NULL
|
||||
};
|
||||
|
||||
Glib::BusDispatcher::BusDispatcher()
|
||||
: _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL)
|
||||
: _ctx(NULL), _priority(G_PRIORITY_DEFAULT), _source(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Glib::BusDispatcher::~BusDispatcher()
|
||||
{
|
||||
if (_source)
|
||||
{
|
||||
GSource *temp = _source;
|
||||
_source = NULL;
|
||||
if (_source)
|
||||
{
|
||||
GSource *temp = _source;
|
||||
_source = NULL;
|
||||
|
||||
g_source_destroy (temp);
|
||||
g_source_unref (temp);
|
||||
}
|
||||
g_source_destroy(temp);
|
||||
g_source_unref(temp);
|
||||
}
|
||||
|
||||
if (_ctx)
|
||||
g_main_context_unref(_ctx);
|
||||
if (_ctx)
|
||||
g_main_context_unref(_ctx);
|
||||
}
|
||||
|
||||
void Glib::BusDispatcher::attach(GMainContext *ctx)
|
||||
{
|
||||
g_assert(_ctx == NULL); // just to be sane
|
||||
g_assert(_ctx == NULL); // just to be sane
|
||||
|
||||
_ctx = ctx ? ctx : g_main_context_default();
|
||||
g_main_context_ref(_ctx);
|
||||
|
||||
// create the source for dispatching messages
|
||||
_source = g_source_new((GSourceFuncs *) &dispatcher_funcs,
|
||||
sizeof(DispatcherSource));
|
||||
_ctx = ctx ? ctx : g_main_context_default();
|
||||
g_main_context_ref(_ctx);
|
||||
|
||||
((DispatcherSource*)_source)->dispatcher = this;
|
||||
g_source_attach (_source, _ctx);
|
||||
// create the source for dispatching messages
|
||||
_source = g_source_new((GSourceFuncs *) &dispatcher_funcs,
|
||||
sizeof(DispatcherSource));
|
||||
|
||||
((DispatcherSource *)_source)->dispatcher = this;
|
||||
g_source_attach(_source, _ctx);
|
||||
}
|
||||
|
||||
Timeout *Glib::BusDispatcher::add_timeout(Timeout::Internal *wi)
|
||||
{
|
||||
Timeout *t = new Glib::BusTimeout(wi, _ctx, _priority);
|
||||
Timeout *t = new Glib::BusTimeout(wi, _ctx, _priority);
|
||||
|
||||
debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on":"off");
|
||||
debug_log("glib: added timeout %p (%s)", t, t->enabled() ? "on" : "off");
|
||||
|
||||
return t;
|
||||
return t;
|
||||
}
|
||||
|
||||
void Glib::BusDispatcher::rem_timeout(Timeout *t)
|
||||
{
|
||||
debug_log("glib: removed timeout %p", t);
|
||||
debug_log("glib: removed timeout %p", t);
|
||||
|
||||
delete t;
|
||||
delete t;
|
||||
}
|
||||
|
||||
Watch *Glib::BusDispatcher::add_watch(Watch::Internal *wi)
|
||||
{
|
||||
Watch *w = new Glib::BusWatch(wi, _ctx, _priority);
|
||||
Watch *w = new Glib::BusWatch(wi, _ctx, _priority);
|
||||
|
||||
debug_log("glib: added watch %p (%s) fd=%d flags=%d",
|
||||
w, w->enabled() ? "on":"off", w->descriptor(), w->flags()
|
||||
);
|
||||
return w;
|
||||
debug_log("glib: added watch %p (%s) fd=%d flags=%d",
|
||||
w, w->enabled() ? "on" : "off", w->descriptor(), w->flags()
|
||||
);
|
||||
return w;
|
||||
}
|
||||
|
||||
void Glib::BusDispatcher::rem_watch(Watch *w)
|
||||
{
|
||||
debug_log("glib: removed watch %p", w);
|
||||
debug_log("glib: removed watch %p", w);
|
||||
|
||||
delete w;
|
||||
delete w;
|
||||
}
|
||||
|
||||
void Glib::BusDispatcher::set_priority(int priority)
|
||||
{
|
||||
_priority = priority;
|
||||
_priority = priority;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
using namespace DBus;
|
||||
|
||||
Interface::Interface(const std::string &name)
|
||||
: _name(name)
|
||||
: _name(name)
|
||||
{}
|
||||
|
||||
Interface::~Interface()
|
||||
|
@ -41,129 +41,129 @@ Interface::~Interface()
|
|||
|
||||
InterfaceAdaptor *AdaptorBase::find_interface(const std::string &name)
|
||||
{
|
||||
InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
|
||||
InterfaceAdaptorTable::const_iterator ii = _interfaces.find(name);
|
||||
|
||||
return ii != _interfaces.end() ? ii->second : NULL;
|
||||
return ii != _interfaces.end() ? ii->second : NULL;
|
||||
}
|
||||
|
||||
InterfaceAdaptor::InterfaceAdaptor(const std::string &name)
|
||||
: Interface(name)
|
||||
: Interface(name)
|
||||
{
|
||||
debug_log("adding interface %s", name.c_str());
|
||||
debug_log("adding interface %s", name.c_str());
|
||||
|
||||
_interfaces[name] = this;
|
||||
_interfaces[name] = this;
|
||||
}
|
||||
|
||||
Message InterfaceAdaptor::dispatch_method(const CallMessage &msg)
|
||||
{
|
||||
const char *name = msg.member();
|
||||
const char *name = msg.member();
|
||||
|
||||
MethodTable::iterator mi = _methods.find(name);
|
||||
if (mi != _methods.end())
|
||||
{
|
||||
return mi->second.call(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
|
||||
}
|
||||
MethodTable::iterator mi = _methods.find(name);
|
||||
if (mi != _methods.end())
|
||||
{
|
||||
return mi->second.call(msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ErrorMessage(msg, DBUS_ERROR_UNKNOWN_METHOD, name);
|
||||
}
|
||||
}
|
||||
|
||||
void InterfaceAdaptor::emit_signal(const SignalMessage &sig)
|
||||
{
|
||||
SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
|
||||
SignalMessage &sig2 = const_cast<SignalMessage &>(sig);
|
||||
|
||||
if (sig2.interface() == NULL)
|
||||
sig2.interface(name().c_str());
|
||||
if (sig2.interface() == NULL)
|
||||
sig2.interface(name().c_str());
|
||||
|
||||
_emit_signal(sig2);
|
||||
_emit_signal(sig2);
|
||||
}
|
||||
|
||||
Variant *InterfaceAdaptor::get_property(const std::string &name)
|
||||
{
|
||||
PropertyTable::iterator pti = _properties.find(name);
|
||||
PropertyTable::iterator pti = _properties.find(name);
|
||||
|
||||
if (pti != _properties.end())
|
||||
{
|
||||
if (!pti->second.read)
|
||||
throw ErrorAccessDenied("property is not readable");
|
||||
if (pti != _properties.end())
|
||||
{
|
||||
if (!pti->second.read)
|
||||
throw ErrorAccessDenied("property is not readable");
|
||||
|
||||
return &(pti->second.value);
|
||||
}
|
||||
return NULL;
|
||||
return &(pti->second.value);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void InterfaceAdaptor::set_property(const std::string &name, Variant &value)
|
||||
{
|
||||
PropertyTable::iterator pti = _properties.find(name);
|
||||
PropertyTable::iterator pti = _properties.find(name);
|
||||
|
||||
if (pti != _properties.end())
|
||||
{
|
||||
if (!pti->second.write)
|
||||
throw ErrorAccessDenied("property is not writeable");
|
||||
if (pti != _properties.end())
|
||||
{
|
||||
if (!pti->second.write)
|
||||
throw ErrorAccessDenied("property is not writeable");
|
||||
|
||||
Signature sig = value.signature();
|
||||
Signature sig = value.signature();
|
||||
|
||||
if (pti->second.sig != sig)
|
||||
throw ErrorInvalidSignature("property expects a different type");
|
||||
if (pti->second.sig != sig)
|
||||
throw ErrorInvalidSignature("property expects a different type");
|
||||
|
||||
pti->second.value = value;
|
||||
return;
|
||||
}
|
||||
throw ErrorFailed("requested property not found");
|
||||
pti->second.value = value;
|
||||
return;
|
||||
}
|
||||
throw ErrorFailed("requested property not found");
|
||||
}
|
||||
|
||||
InterfaceProxy *ProxyBase::find_interface(const std::string &name)
|
||||
{
|
||||
InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
|
||||
InterfaceProxyTable::const_iterator ii = _interfaces.find(name);
|
||||
|
||||
return ii != _interfaces.end() ? ii->second : NULL;
|
||||
return ii != _interfaces.end() ? ii->second : NULL;
|
||||
}
|
||||
|
||||
InterfaceProxy::InterfaceProxy(const std::string &name)
|
||||
: Interface(name)
|
||||
: Interface(name)
|
||||
{
|
||||
debug_log("adding interface %s", name.c_str());
|
||||
debug_log("adding interface %s", name.c_str());
|
||||
|
||||
_interfaces[name] = this;
|
||||
_interfaces[name] = this;
|
||||
}
|
||||
|
||||
bool InterfaceProxy::dispatch_signal(const SignalMessage &msg)
|
||||
{
|
||||
const char *name = msg.member();
|
||||
const char *name = msg.member();
|
||||
|
||||
SignalTable::iterator si = _signals.find(name);
|
||||
if (si != _signals.end())
|
||||
{
|
||||
si->second.call(msg);
|
||||
// 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
|
||||
{
|
||||
return false;
|
||||
}
|
||||
SignalTable::iterator si = _signals.find(name);
|
||||
if (si != _signals.end())
|
||||
{
|
||||
si->second.call(msg);
|
||||
// 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
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Message InterfaceProxy::invoke_method(const CallMessage &call)
|
||||
{
|
||||
CallMessage &call2 = const_cast<CallMessage &>(call);
|
||||
CallMessage &call2 = const_cast<CallMessage &>(call);
|
||||
|
||||
if (call.interface() == NULL)
|
||||
call2.interface(name().c_str());
|
||||
if (call.interface() == NULL)
|
||||
call2.interface(name().c_str());
|
||||
|
||||
return _invoke_method(call2);
|
||||
return _invoke_method(call2);
|
||||
}
|
||||
|
||||
bool InterfaceProxy::invoke_method_noreply(const CallMessage &call)
|
||||
{
|
||||
CallMessage &call2 = const_cast<CallMessage &>(call);
|
||||
CallMessage &call2 = const_cast<CallMessage &>(call);
|
||||
|
||||
if (call.interface() == NULL)
|
||||
call2.interface(name().c_str());
|
||||
if (call.interface() == NULL)
|
||||
call2.interface(name().c_str());
|
||||
|
||||
return _invoke_method_noreply(call2);
|
||||
return _invoke_method_noreply(call2);
|
||||
}
|
||||
|
|
|
@ -33,43 +33,44 @@
|
|||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
namespace DBus {
|
||||
namespace DBus
|
||||
{
|
||||
|
||||
struct DXXAPI InternalError
|
||||
{
|
||||
DBusError error;
|
||||
DBusError error;
|
||||
|
||||
InternalError()
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
}
|
||||
InternalError()
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
}
|
||||
|
||||
explicit InternalError(DBusError *e)
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
dbus_move_error(e, &error);
|
||||
}
|
||||
explicit InternalError(DBusError *e)
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
dbus_move_error(e, &error);
|
||||
}
|
||||
|
||||
InternalError(const InternalError &ie)
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error);
|
||||
}
|
||||
|
||||
~InternalError()
|
||||
{
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
InternalError(const InternalError &ie)
|
||||
{
|
||||
dbus_error_init(&error);
|
||||
dbus_move_error(const_cast<DBusError *>(&(ie.error)), &error);
|
||||
}
|
||||
|
||||
operator DBusError *()
|
||||
{
|
||||
return &error;
|
||||
}
|
||||
~InternalError()
|
||||
{
|
||||
dbus_error_free(&error);
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return dbus_error_is_set(&error);
|
||||
}
|
||||
operator DBusError *()
|
||||
{
|
||||
return &error;
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return dbus_error_is_set(&error);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace DBus */
|
||||
|
|
|
@ -38,156 +38,156 @@ using namespace DBus;
|
|||
static const char *introspectable_name = "org.freedesktop.DBus.Introspectable";
|
||||
|
||||
IntrospectableAdaptor::IntrospectableAdaptor()
|
||||
: InterfaceAdaptor(introspectable_name)
|
||||
: InterfaceAdaptor(introspectable_name)
|
||||
{
|
||||
register_method(IntrospectableAdaptor, Introspect, Introspect);
|
||||
register_method(IntrospectableAdaptor, Introspect, Introspect);
|
||||
}
|
||||
|
||||
Message IntrospectableAdaptor::Introspect(const CallMessage &call)
|
||||
{
|
||||
debug_log("requested introspection data");
|
||||
debug_log("requested introspection data");
|
||||
|
||||
std::ostringstream xml;
|
||||
std::ostringstream xml;
|
||||
|
||||
xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
|
||||
xml << DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE;
|
||||
|
||||
const std::string path = object()->path();
|
||||
const std::string path = object()->path();
|
||||
|
||||
xml << "<node name=\"" << path << "\">";
|
||||
xml << "<node name=\"" << path << "\">";
|
||||
|
||||
InterfaceAdaptorTable::const_iterator iti;
|
||||
InterfaceAdaptorTable::const_iterator iti;
|
||||
|
||||
for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti)
|
||||
{
|
||||
debug_log("introspecting interface %s", iti->first.c_str());
|
||||
for (iti = _interfaces.begin(); iti != _interfaces.end(); ++iti)
|
||||
{
|
||||
debug_log("introspecting interface %s", iti->first.c_str());
|
||||
|
||||
IntrospectedInterface *const intro = iti->second->introspect();
|
||||
if (intro)
|
||||
{
|
||||
xml << "\n\t<interface name=\"" << intro->name << "\">";
|
||||
IntrospectedInterface *const intro = iti->second->introspect();
|
||||
if (intro)
|
||||
{
|
||||
xml << "\n\t<interface name=\"" << intro->name << "\">";
|
||||
|
||||
for (const IntrospectedProperty *p = intro->properties; p->name; ++p)
|
||||
{
|
||||
std::string access;
|
||||
for (const IntrospectedProperty *p = intro->properties; p->name; ++p)
|
||||
{
|
||||
std::string access;
|
||||
|
||||
if (p->read) access += "read";
|
||||
if (p->write) access += "write";
|
||||
if (p->read) access += "read";
|
||||
if (p->write) access += "write";
|
||||
|
||||
xml << "\n\t\t<property name=\"" << p->name << "\""
|
||||
<< " type=\"" << p->type << "\""
|
||||
<< " access=\"" << access << "\"/>";
|
||||
}
|
||||
xml << "\n\t\t<property name=\"" << p->name << "\""
|
||||
<< " type=\"" << p->type << "\""
|
||||
<< " access=\"" << access << "\"/>";
|
||||
}
|
||||
|
||||
for (const IntrospectedMethod *m = intro->methods; m->args; ++m)
|
||||
{
|
||||
xml << "\n\t\t<method name=\"" << m->name << "\">";
|
||||
for (const IntrospectedMethod *m = intro->methods; m->args; ++m)
|
||||
{
|
||||
xml << "\n\t\t<method name=\"" << m->name << "\">";
|
||||
|
||||
for (const IntrospectedArgument *a = m->args; a->type; ++a)
|
||||
{
|
||||
xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
|
||||
<< " type=\"" << a->type << "\"";
|
||||
for (const IntrospectedArgument *a = m->args; a->type; ++a)
|
||||
{
|
||||
xml << "\n\t\t\t<arg direction=\"" << (a->in ? "in" : "out") << "\""
|
||||
<< " type=\"" << a->type << "\"";
|
||||
|
||||
if (a->name) xml << " name=\"" << a->name << "\"";
|
||||
if (a->name) xml << " name=\"" << a->name << "\"";
|
||||
|
||||
xml << "/>";
|
||||
}
|
||||
xml << "/>";
|
||||
}
|
||||
|
||||
xml << "\n\t\t</method>";
|
||||
}
|
||||
xml << "\n\t\t</method>";
|
||||
}
|
||||
|
||||
for (const IntrospectedMethod *m = intro->signals; m->args; ++m)
|
||||
{
|
||||
xml << "\n\t\t<signal name=\"" << m->name << "\">";
|
||||
for (const IntrospectedMethod *m = intro->signals; m->args; ++m)
|
||||
{
|
||||
xml << "\n\t\t<signal name=\"" << m->name << "\">";
|
||||
|
||||
for (const IntrospectedArgument *a = m->args; a->type; ++a)
|
||||
{
|
||||
xml << "<arg type=\"" << a->type << "\"";
|
||||
for (const IntrospectedArgument *a = m->args; a->type; ++a)
|
||||
{
|
||||
xml << "<arg type=\"" << a->type << "\"";
|
||||
|
||||
if (a->name) xml << " name=\"" << a->name << "\"";
|
||||
if (a->name) xml << " name=\"" << a->name << "\"";
|
||||
|
||||
xml << "/>";
|
||||
}
|
||||
xml << "\n\t\t</signal>";
|
||||
}
|
||||
xml << "/>";
|
||||
}
|
||||
xml << "\n\t\t</signal>";
|
||||
}
|
||||
|
||||
xml << "\n\t</interface>";
|
||||
}
|
||||
}
|
||||
xml << "\n\t</interface>";
|
||||
}
|
||||
}
|
||||
|
||||
const ObjectPathList nodes = ObjectAdaptor::child_nodes_from_prefix(path + '/');
|
||||
ObjectPathList::const_iterator oni;
|
||||
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) << "\"/>";
|
||||
}
|
||||
for (oni = nodes.begin(); oni != nodes.end(); ++oni)
|
||||
{
|
||||
xml << "\n\t<node name=\"" << (*oni) << "\"/>";
|
||||
}
|
||||
|
||||
/* broken
|
||||
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
|
||||
/* broken
|
||||
const ObjectAdaptorPList children = ObjectAdaptor::from_path_prefix(path + '/');
|
||||
|
||||
ObjectAdaptorPList::const_iterator oci;
|
||||
ObjectAdaptorPList::const_iterator oci;
|
||||
|
||||
for (oci = children.begin(); oci != children.end(); ++oci)
|
||||
{
|
||||
std::string name = (*oci)->path().substr(path.length()+1);
|
||||
name.substr(name.find('/'));
|
||||
for (oci = children.begin(); oci != children.end(); ++oci)
|
||||
{
|
||||
std::string name = (*oci)->path().substr(path.length()+1);
|
||||
name.substr(name.find('/'));
|
||||
|
||||
xml << "<node name=\"" << name << "\"/>";
|
||||
}
|
||||
*/
|
||||
xml << "<node name=\"" << name << "\"/>";
|
||||
}
|
||||
*/
|
||||
|
||||
xml << "\n</node>";
|
||||
xml << "\n</node>";
|
||||
|
||||
ReturnMessage reply(call);
|
||||
MessageIter wi = reply.writer();
|
||||
wi.append_string(xml.str().c_str());
|
||||
return reply;
|
||||
ReturnMessage reply(call);
|
||||
MessageIter wi = reply.writer();
|
||||
wi.append_string(xml.str().c_str());
|
||||
return reply;
|
||||
}
|
||||
|
||||
IntrospectedInterface * IntrospectableAdaptor::introspect() const
|
||||
IntrospectedInterface *IntrospectableAdaptor::introspect() const
|
||||
{
|
||||
static IntrospectedArgument Introspect_args[] =
|
||||
{
|
||||
{ "data", "s", false },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Introspectable_methods[] =
|
||||
{
|
||||
{ "Introspect", Introspect_args },
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Introspectable_signals[] =
|
||||
{
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedProperty Introspectable_properties[] =
|
||||
{
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedInterface Introspectable_interface =
|
||||
{
|
||||
introspectable_name,
|
||||
Introspectable_methods,
|
||||
Introspectable_signals,
|
||||
Introspectable_properties
|
||||
};
|
||||
return &Introspectable_interface;
|
||||
static IntrospectedArgument Introspect_args[] =
|
||||
{
|
||||
{ "data", "s", false },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Introspectable_methods[] =
|
||||
{
|
||||
{ "Introspect", Introspect_args },
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Introspectable_signals[] =
|
||||
{
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedProperty Introspectable_properties[] =
|
||||
{
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedInterface Introspectable_interface =
|
||||
{
|
||||
introspectable_name,
|
||||
Introspectable_methods,
|
||||
Introspectable_signals,
|
||||
Introspectable_properties
|
||||
};
|
||||
return &Introspectable_interface;
|
||||
}
|
||||
|
||||
IntrospectableProxy::IntrospectableProxy()
|
||||
: InterfaceProxy(introspectable_name)
|
||||
: InterfaceProxy(introspectable_name)
|
||||
{}
|
||||
|
||||
std::string IntrospectableProxy::Introspect()
|
||||
{
|
||||
DBus::CallMessage call;
|
||||
DBus::CallMessage call;
|
||||
|
||||
call.member("Introspect");
|
||||
call.member("Introspect");
|
||||
|
||||
DBus::Message ret = invoke_method(call);
|
||||
DBus::Message ret = invoke_method(call);
|
||||
|
||||
DBus::MessageIter ri = ret.reader();
|
||||
const char *str = ri.get_string();
|
||||
DBus::MessageIter ri = ret.reader();
|
||||
const char *str = ri.get_string();
|
||||
|
||||
return str;
|
||||
return str;
|
||||
}
|
||||
|
|
436
src/message.cpp
436
src/message.cpp
|
@ -40,475 +40,475 @@ using namespace DBus;
|
|||
|
||||
int MessageIter::type()
|
||||
{
|
||||
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter);
|
||||
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter);
|
||||
}
|
||||
|
||||
bool MessageIter::at_end()
|
||||
{
|
||||
return type() == DBUS_TYPE_INVALID;
|
||||
return type() == DBUS_TYPE_INVALID;
|
||||
}
|
||||
|
||||
bool MessageIter::has_next()
|
||||
{
|
||||
return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
|
||||
return dbus_message_iter_has_next((DBusMessageIter *)&_iter);
|
||||
}
|
||||
|
||||
MessageIter &MessageIter::operator ++()
|
||||
{
|
||||
dbus_message_iter_next((DBusMessageIter *)&_iter);
|
||||
return (*this);
|
||||
dbus_message_iter_next((DBusMessageIter *)&_iter);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
MessageIter MessageIter::operator ++(int)
|
||||
{
|
||||
MessageIter copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
MessageIter copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool MessageIter::append_basic(int type_id, void *value)
|
||||
{
|
||||
return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value);
|
||||
return dbus_message_iter_append_basic((DBusMessageIter *)&_iter, type_id, value);
|
||||
}
|
||||
|
||||
void MessageIter::get_basic(int type_id, void *ptr)
|
||||
{
|
||||
if (type() != type_id)
|
||||
throw ErrorInvalidArgs("type mismatch");
|
||||
if (type() != type_id)
|
||||
throw ErrorInvalidArgs("type mismatch");
|
||||
|
||||
dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr);
|
||||
dbus_message_iter_get_basic((DBusMessageIter *)_iter, ptr);
|
||||
}
|
||||
|
||||
bool MessageIter::append_byte(unsigned char b)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_BYTE, &b);
|
||||
return append_basic(DBUS_TYPE_BYTE, &b);
|
||||
}
|
||||
|
||||
unsigned char MessageIter::get_byte()
|
||||
{
|
||||
unsigned char b;
|
||||
get_basic(DBUS_TYPE_BYTE, &b);
|
||||
return b;
|
||||
{
|
||||
unsigned char b;
|
||||
get_basic(DBUS_TYPE_BYTE, &b);
|
||||
return b;
|
||||
}
|
||||
|
||||
bool MessageIter::append_bool(bool b)
|
||||
{
|
||||
dbus_bool_t db = b;
|
||||
return append_basic(DBUS_TYPE_BOOLEAN, &db);
|
||||
dbus_bool_t db = b;
|
||||
return append_basic(DBUS_TYPE_BOOLEAN, &db);
|
||||
}
|
||||
|
||||
bool MessageIter::get_bool()
|
||||
bool MessageIter::get_bool()
|
||||
{
|
||||
dbus_bool_t db;
|
||||
get_basic(DBUS_TYPE_BOOLEAN, &db);
|
||||
return (bool)db;
|
||||
dbus_bool_t db;
|
||||
get_basic(DBUS_TYPE_BOOLEAN, &db);
|
||||
return (bool)db;
|
||||
}
|
||||
|
||||
bool MessageIter::append_int16(signed short i)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_INT16, &i);
|
||||
return append_basic(DBUS_TYPE_INT16, &i);
|
||||
}
|
||||
|
||||
signed short MessageIter::get_int16()
|
||||
{
|
||||
signed short i;
|
||||
get_basic(DBUS_TYPE_INT16, &i);
|
||||
return i;
|
||||
{
|
||||
signed short i;
|
||||
get_basic(DBUS_TYPE_INT16, &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
bool MessageIter::append_uint16(unsigned short u)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_UINT16, &u);
|
||||
return append_basic(DBUS_TYPE_UINT16, &u);
|
||||
}
|
||||
|
||||
unsigned short MessageIter::get_uint16()
|
||||
{
|
||||
unsigned short u;
|
||||
get_basic(DBUS_TYPE_UINT16, &u);
|
||||
return u;
|
||||
{
|
||||
unsigned short u;
|
||||
get_basic(DBUS_TYPE_UINT16, &u);
|
||||
return u;
|
||||
}
|
||||
|
||||
bool MessageIter::append_int32(signed int i)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_INT32, &i);
|
||||
return append_basic(DBUS_TYPE_INT32, &i);
|
||||
}
|
||||
|
||||
signed int MessageIter::get_int32()
|
||||
{
|
||||
signed int i;
|
||||
get_basic(DBUS_TYPE_INT32, &i);
|
||||
return i;
|
||||
{
|
||||
signed int i;
|
||||
get_basic(DBUS_TYPE_INT32, &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
bool MessageIter::append_uint32(unsigned int u)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_UINT32, &u);
|
||||
return append_basic(DBUS_TYPE_UINT32, &u);
|
||||
}
|
||||
|
||||
unsigned int MessageIter::get_uint32()
|
||||
{
|
||||
unsigned int u;
|
||||
get_basic(DBUS_TYPE_UINT32, &u);
|
||||
return u;
|
||||
{
|
||||
unsigned int u;
|
||||
get_basic(DBUS_TYPE_UINT32, &u);
|
||||
return u;
|
||||
}
|
||||
|
||||
signed long long MessageIter::get_int64()
|
||||
{
|
||||
signed long long i;
|
||||
get_basic(DBUS_TYPE_INT64, &i);
|
||||
return i;
|
||||
signed long long i;
|
||||
get_basic(DBUS_TYPE_INT64, &i);
|
||||
return i;
|
||||
}
|
||||
|
||||
bool MessageIter::append_int64(signed long long i)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_INT64, &i);
|
||||
return append_basic(DBUS_TYPE_INT64, &i);
|
||||
}
|
||||
|
||||
unsigned long long MessageIter::get_uint64()
|
||||
{
|
||||
unsigned long long u;
|
||||
get_basic(DBUS_TYPE_UINT64, &u);
|
||||
return u;
|
||||
unsigned long long u;
|
||||
get_basic(DBUS_TYPE_UINT64, &u);
|
||||
return u;
|
||||
}
|
||||
|
||||
bool MessageIter::append_uint64(unsigned long long u)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_UINT64, &u);
|
||||
return append_basic(DBUS_TYPE_UINT64, &u);
|
||||
}
|
||||
|
||||
double MessageIter::get_double()
|
||||
{
|
||||
double d;
|
||||
get_basic(DBUS_TYPE_DOUBLE, &d);
|
||||
return d;
|
||||
double d;
|
||||
get_basic(DBUS_TYPE_DOUBLE, &d);
|
||||
return d;
|
||||
}
|
||||
|
||||
bool MessageIter::append_double(double d)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_DOUBLE, &d);
|
||||
return append_basic(DBUS_TYPE_DOUBLE, &d);
|
||||
}
|
||||
|
||||
bool MessageIter::append_string(const char *chars)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_STRING, &chars);
|
||||
return append_basic(DBUS_TYPE_STRING, &chars);
|
||||
}
|
||||
|
||||
const char *MessageIter::get_string()
|
||||
{
|
||||
char *chars;
|
||||
get_basic(DBUS_TYPE_STRING, &chars);
|
||||
return chars;
|
||||
char *chars;
|
||||
get_basic(DBUS_TYPE_STRING, &chars);
|
||||
return chars;
|
||||
}
|
||||
|
||||
bool MessageIter::append_path(const char *chars)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
|
||||
return append_basic(DBUS_TYPE_OBJECT_PATH, &chars);
|
||||
}
|
||||
|
||||
const char *MessageIter::get_path()
|
||||
{
|
||||
char *chars;
|
||||
get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
|
||||
return chars;
|
||||
char *chars;
|
||||
get_basic(DBUS_TYPE_OBJECT_PATH, &chars);
|
||||
return chars;
|
||||
}
|
||||
|
||||
bool MessageIter::append_signature(const char *chars)
|
||||
{
|
||||
return append_basic(DBUS_TYPE_SIGNATURE, &chars);
|
||||
return append_basic(DBUS_TYPE_SIGNATURE, &chars);
|
||||
}
|
||||
|
||||
const char *MessageIter::get_signature()
|
||||
{
|
||||
char *chars;
|
||||
get_basic(DBUS_TYPE_SIGNATURE, &chars);
|
||||
return chars;
|
||||
char *chars;
|
||||
get_basic(DBUS_TYPE_SIGNATURE, &chars);
|
||||
return chars;
|
||||
}
|
||||
|
||||
MessageIter MessageIter::recurse()
|
||||
MessageIter MessageIter::recurse()
|
||||
{
|
||||
MessageIter iter(msg());
|
||||
dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *)&(iter._iter));
|
||||
return iter;
|
||||
MessageIter iter(msg());
|
||||
dbus_message_iter_recurse((DBusMessageIter *)&_iter, (DBusMessageIter *) & (iter._iter));
|
||||
return iter;
|
||||
}
|
||||
|
||||
char *MessageIter::signature() const
|
||||
{
|
||||
return dbus_message_iter_get_signature((DBusMessageIter *)&_iter);
|
||||
return dbus_message_iter_get_signature((DBusMessageIter *)&_iter);
|
||||
}
|
||||
|
||||
bool MessageIter::append_array(char type, const void *ptr, size_t length)
|
||||
{
|
||||
return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length);
|
||||
return dbus_message_iter_append_fixed_array((DBusMessageIter *)&_iter, type, &ptr, length);
|
||||
}
|
||||
|
||||
int MessageIter::array_type()
|
||||
{
|
||||
return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter);
|
||||
return dbus_message_iter_get_element_type((DBusMessageIter *)&_iter);
|
||||
}
|
||||
|
||||
int MessageIter::get_array(void *ptr)
|
||||
{
|
||||
int length;
|
||||
dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
|
||||
return length;
|
||||
int length;
|
||||
dbus_message_iter_get_fixed_array((DBusMessageIter *)&_iter, ptr, &length);
|
||||
return length;
|
||||
}
|
||||
|
||||
bool MessageIter::is_array()
|
||||
{
|
||||
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY;
|
||||
return dbus_message_iter_get_arg_type((DBusMessageIter *)&_iter) == DBUS_TYPE_ARRAY;
|
||||
}
|
||||
|
||||
bool MessageIter::is_dict()
|
||||
{
|
||||
return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY;
|
||||
return is_array() && dbus_message_iter_get_element_type((DBusMessageIter *)_iter) == DBUS_TYPE_DICT_ENTRY;
|
||||
}
|
||||
|
||||
MessageIter MessageIter::new_array(const char *sig)
|
||||
{
|
||||
MessageIter arr(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *)&(arr._iter)
|
||||
);
|
||||
return arr;
|
||||
MessageIter arr(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)&_iter, DBUS_TYPE_ARRAY, sig, (DBusMessageIter *) & (arr._iter)
|
||||
);
|
||||
return arr;
|
||||
}
|
||||
|
||||
MessageIter MessageIter::new_variant(const char *sig)
|
||||
{
|
||||
MessageIter var(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *)&(var._iter)
|
||||
);
|
||||
return var;
|
||||
MessageIter var(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)_iter, DBUS_TYPE_VARIANT, sig, (DBusMessageIter *) & (var._iter)
|
||||
);
|
||||
return var;
|
||||
}
|
||||
|
||||
MessageIter MessageIter::new_struct()
|
||||
{
|
||||
MessageIter stu(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *)&(stu._iter)
|
||||
);
|
||||
return stu;
|
||||
MessageIter stu(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)_iter, DBUS_TYPE_STRUCT, NULL, (DBusMessageIter *) & (stu._iter)
|
||||
);
|
||||
return stu;
|
||||
}
|
||||
|
||||
MessageIter MessageIter::new_dict_entry()
|
||||
{
|
||||
MessageIter ent(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *)&(ent._iter)
|
||||
);
|
||||
return ent;
|
||||
MessageIter ent(msg());
|
||||
dbus_message_iter_open_container(
|
||||
(DBusMessageIter *)_iter, DBUS_TYPE_DICT_ENTRY, NULL, (DBusMessageIter *) & (ent._iter)
|
||||
);
|
||||
return ent;
|
||||
}
|
||||
|
||||
void MessageIter::close_container(MessageIter &container)
|
||||
{
|
||||
dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *)&(container._iter));
|
||||
dbus_message_iter_close_container((DBusMessageIter *)&_iter, (DBusMessageIter *) & (container._iter));
|
||||
}
|
||||
|
||||
static bool is_basic_type(int typecode)
|
||||
{
|
||||
switch (typecode)
|
||||
{
|
||||
case 'y':
|
||||
case 'b':
|
||||
case 'n':
|
||||
case 'q':
|
||||
case 'i':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 't':
|
||||
case 'd':
|
||||
case 's':
|
||||
case 'o':
|
||||
case 'g':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
switch (typecode)
|
||||
{
|
||||
case 'y':
|
||||
case 'b':
|
||||
case 'n':
|
||||
case 'q':
|
||||
case 'i':
|
||||
case 'u':
|
||||
case 'x':
|
||||
case 't':
|
||||
case 'd':
|
||||
case 's':
|
||||
case 'o':
|
||||
case 'g':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void MessageIter::copy_data(MessageIter &to)
|
||||
{
|
||||
for (MessageIter &from = *this; !from.at_end(); ++from)
|
||||
{
|
||||
if (is_basic_type(from.type()))
|
||||
{
|
||||
debug_log("copying basic type: %c", from.type());
|
||||
for (MessageIter &from = *this; !from.at_end(); ++from)
|
||||
{
|
||||
if (is_basic_type(from.type()))
|
||||
{
|
||||
debug_log("copying basic type: %c", from.type());
|
||||
|
||||
unsigned char value[8];
|
||||
from.get_basic(from.type(), &value);
|
||||
to.append_basic(from.type(), &value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageIter from_container = from.recurse();
|
||||
char *sig = from_container.signature();
|
||||
unsigned char value[8];
|
||||
from.get_basic(from.type(), &value);
|
||||
to.append_basic(from.type(), &value);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageIter from_container = from.recurse();
|
||||
char *sig = from_container.signature();
|
||||
|
||||
debug_log("copying compound type: %c[%s]", from.type(), sig);
|
||||
debug_log("copying compound type: %c[%s]", from.type(), sig);
|
||||
|
||||
MessageIter to_container (to.msg());
|
||||
dbus_message_iter_open_container
|
||||
(
|
||||
(DBusMessageIter *)&(to._iter),
|
||||
from.type(),
|
||||
from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
|
||||
(DBusMessageIter *)&(to_container._iter)
|
||||
);
|
||||
MessageIter to_container(to.msg());
|
||||
dbus_message_iter_open_container
|
||||
(
|
||||
(DBusMessageIter *) & (to._iter),
|
||||
from.type(),
|
||||
from.type() == DBUS_TYPE_VARIANT ? NULL : sig,
|
||||
(DBusMessageIter *) & (to_container._iter)
|
||||
);
|
||||
|
||||
from_container.copy_data(to_container);
|
||||
to.close_container(to_container);
|
||||
free(sig);
|
||||
}
|
||||
}
|
||||
from_container.copy_data(to_container);
|
||||
to.close_container(to_container);
|
||||
free(sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
Message::Message()
|
||||
: _pvt(new Private)
|
||||
: _pvt(new Private)
|
||||
{
|
||||
}
|
||||
|
||||
Message::Message(Message::Private *p, bool incref)
|
||||
: _pvt(p)
|
||||
: _pvt(p)
|
||||
{
|
||||
if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
|
||||
if (_pvt->msg && incref) dbus_message_ref(_pvt->msg);
|
||||
}
|
||||
|
||||
Message::Message(const Message &m)
|
||||
: _pvt(m._pvt)
|
||||
: _pvt(m._pvt)
|
||||
{
|
||||
dbus_message_ref(_pvt->msg);
|
||||
dbus_message_ref(_pvt->msg);
|
||||
}
|
||||
|
||||
Message::~Message()
|
||||
{
|
||||
dbus_message_unref(_pvt->msg);
|
||||
dbus_message_unref(_pvt->msg);
|
||||
}
|
||||
|
||||
Message &Message::operator = (const Message &m)
|
||||
{
|
||||
if (&m != this)
|
||||
{
|
||||
dbus_message_unref(_pvt->msg);
|
||||
_pvt = m._pvt;
|
||||
dbus_message_ref(_pvt->msg);
|
||||
}
|
||||
return *this;
|
||||
if (&m != this)
|
||||
{
|
||||
dbus_message_unref(_pvt->msg);
|
||||
_pvt = m._pvt;
|
||||
dbus_message_ref(_pvt->msg);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Message Message::copy()
|
||||
{
|
||||
Private *pvt = new Private(dbus_message_copy(_pvt->msg));
|
||||
return Message(pvt);
|
||||
Private *pvt = new Private(dbus_message_copy(_pvt->msg));
|
||||
return Message(pvt);
|
||||
}
|
||||
|
||||
bool Message::append(int first_type, ...)
|
||||
{
|
||||
va_list vl;
|
||||
va_start(vl, first_type);
|
||||
va_list vl;
|
||||
va_start(vl, first_type);
|
||||
|
||||
bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
|
||||
bool b = dbus_message_append_args_valist(_pvt->msg, first_type, vl);
|
||||
|
||||
va_end(vl);
|
||||
return b;
|
||||
va_end(vl);
|
||||
return b;
|
||||
}
|
||||
|
||||
void Message::terminate()
|
||||
{
|
||||
dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
|
||||
dbus_message_append_args(_pvt->msg, DBUS_TYPE_INVALID);
|
||||
}
|
||||
|
||||
int Message::type() const
|
||||
{
|
||||
return dbus_message_get_type(_pvt->msg);
|
||||
return dbus_message_get_type(_pvt->msg);
|
||||
}
|
||||
|
||||
int Message::serial() const
|
||||
{
|
||||
return dbus_message_get_serial(_pvt->msg);
|
||||
return dbus_message_get_serial(_pvt->msg);
|
||||
}
|
||||
|
||||
int Message::reply_serial() const
|
||||
{
|
||||
return dbus_message_get_reply_serial(_pvt->msg);
|
||||
return dbus_message_get_reply_serial(_pvt->msg);
|
||||
}
|
||||
|
||||
bool Message::reply_serial(int s)
|
||||
{
|
||||
return dbus_message_set_reply_serial(_pvt->msg, s);
|
||||
return dbus_message_set_reply_serial(_pvt->msg, s);
|
||||
}
|
||||
|
||||
const char *Message::sender() const
|
||||
{
|
||||
return dbus_message_get_sender(_pvt->msg);
|
||||
return dbus_message_get_sender(_pvt->msg);
|
||||
}
|
||||
|
||||
bool Message::sender(const char *s)
|
||||
{
|
||||
return dbus_message_set_sender(_pvt->msg, s);
|
||||
return dbus_message_set_sender(_pvt->msg, s);
|
||||
}
|
||||
|
||||
const char *Message::destination() const
|
||||
{
|
||||
return dbus_message_get_destination(_pvt->msg);
|
||||
return dbus_message_get_destination(_pvt->msg);
|
||||
}
|
||||
|
||||
bool Message::destination(const char *s)
|
||||
{
|
||||
return dbus_message_set_destination(_pvt->msg, s);
|
||||
return dbus_message_set_destination(_pvt->msg, s);
|
||||
}
|
||||
|
||||
bool Message::is_error() const
|
||||
{
|
||||
return type() == DBUS_MESSAGE_TYPE_ERROR;
|
||||
return type() == DBUS_MESSAGE_TYPE_ERROR;
|
||||
}
|
||||
|
||||
bool Message::is_signal(const char *interface, const char *member) const
|
||||
{
|
||||
return dbus_message_is_signal(_pvt->msg, interface, member);
|
||||
return dbus_message_is_signal(_pvt->msg, interface, member);
|
||||
}
|
||||
|
||||
MessageIter Message::writer()
|
||||
{
|
||||
MessageIter iter(*this);
|
||||
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *)&(iter._iter));
|
||||
return iter;
|
||||
MessageIter iter(*this);
|
||||
dbus_message_iter_init_append(_pvt->msg, (DBusMessageIter *) & (iter._iter));
|
||||
return iter;
|
||||
}
|
||||
|
||||
MessageIter Message::reader() const
|
||||
{
|
||||
MessageIter iter(const_cast<Message &>(*this));
|
||||
dbus_message_iter_init(_pvt->msg, (DBusMessageIter *)&(iter._iter));
|
||||
return iter;
|
||||
MessageIter iter(const_cast<Message &>(*this));
|
||||
dbus_message_iter_init(_pvt->msg, (DBusMessageIter *) & (iter._iter));
|
||||
return iter;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
*/
|
||||
|
||||
ErrorMessage::ErrorMessage()
|
||||
{
|
||||
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
|
||||
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_ERROR);
|
||||
}
|
||||
|
||||
ErrorMessage::ErrorMessage(const Message &to_reply, const char *name, const char *message)
|
||||
{
|
||||
_pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
|
||||
_pvt->msg = dbus_message_new_error(to_reply._pvt->msg, name, message);
|
||||
}
|
||||
|
||||
bool ErrorMessage::operator == (const ErrorMessage &m) const
|
||||
{
|
||||
return dbus_message_is_error(_pvt->msg, m.name());
|
||||
return dbus_message_is_error(_pvt->msg, m.name());
|
||||
}
|
||||
|
||||
const char *ErrorMessage::name() const
|
||||
{
|
||||
return dbus_message_get_error_name(_pvt->msg);
|
||||
return dbus_message_get_error_name(_pvt->msg);
|
||||
}
|
||||
|
||||
bool ErrorMessage::name(const char *n)
|
||||
{
|
||||
return dbus_message_set_error_name(_pvt->msg, n);
|
||||
return dbus_message_set_error_name(_pvt->msg, n);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -516,55 +516,55 @@ bool ErrorMessage::name(const char *n)
|
|||
|
||||
SignalMessage::SignalMessage(const char *name)
|
||||
{
|
||||
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
|
||||
member(name);
|
||||
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_SIGNAL);
|
||||
member(name);
|
||||
}
|
||||
|
||||
SignalMessage::SignalMessage(const char *path, const char *interface, const char *name)
|
||||
{
|
||||
_pvt->msg = dbus_message_new_signal(path, interface, name);
|
||||
_pvt->msg = dbus_message_new_signal(path, interface, name);
|
||||
}
|
||||
|
||||
bool SignalMessage::operator == (const SignalMessage &m) const
|
||||
{
|
||||
return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
|
||||
return dbus_message_is_signal(_pvt->msg, m.interface(), m.member());
|
||||
}
|
||||
|
||||
const char *SignalMessage::interface() const
|
||||
{
|
||||
return dbus_message_get_interface(_pvt->msg);
|
||||
return dbus_message_get_interface(_pvt->msg);
|
||||
}
|
||||
|
||||
bool SignalMessage::interface(const char *i)
|
||||
{
|
||||
return dbus_message_set_interface(_pvt->msg, i);
|
||||
return dbus_message_set_interface(_pvt->msg, i);
|
||||
}
|
||||
|
||||
const char *SignalMessage::member() const
|
||||
{
|
||||
return dbus_message_get_member(_pvt->msg);
|
||||
return dbus_message_get_member(_pvt->msg);
|
||||
}
|
||||
|
||||
bool SignalMessage::member(const char *m)
|
||||
{
|
||||
return dbus_message_set_member(_pvt->msg, m);
|
||||
return dbus_message_set_member(_pvt->msg, m);
|
||||
}
|
||||
|
||||
const char *SignalMessage::path() const
|
||||
{
|
||||
return dbus_message_get_path(_pvt->msg);
|
||||
return dbus_message_get_path(_pvt->msg);
|
||||
}
|
||||
|
||||
char ** SignalMessage::path_split() const
|
||||
char **SignalMessage::path_split() const
|
||||
{
|
||||
char ** p;
|
||||
dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
|
||||
return p;
|
||||
char **p;
|
||||
dbus_message_get_path_decomposed(_pvt->msg, &p); //todo: return as a std::vector ?
|
||||
return p;
|
||||
}
|
||||
|
||||
bool SignalMessage::path(const char *p)
|
||||
{
|
||||
return dbus_message_set_path(_pvt->msg, p);
|
||||
return dbus_message_set_path(_pvt->msg, p);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -572,59 +572,59 @@ bool SignalMessage::path(const char *p)
|
|||
|
||||
CallMessage::CallMessage()
|
||||
{
|
||||
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
|
||||
_pvt->msg = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_CALL);
|
||||
}
|
||||
|
||||
CallMessage::CallMessage(const char *dest, const char *path, const char *iface, const char *method)
|
||||
{
|
||||
_pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
|
||||
_pvt->msg = dbus_message_new_method_call(dest, path, iface, method);
|
||||
}
|
||||
|
||||
bool CallMessage::operator == (const CallMessage &m) const
|
||||
{
|
||||
return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
|
||||
return dbus_message_is_method_call(_pvt->msg, m.interface(), m.member());
|
||||
}
|
||||
|
||||
const char *CallMessage::interface() const
|
||||
{
|
||||
return dbus_message_get_interface(_pvt->msg);
|
||||
return dbus_message_get_interface(_pvt->msg);
|
||||
}
|
||||
|
||||
bool CallMessage::interface(const char *i)
|
||||
{
|
||||
return dbus_message_set_interface(_pvt->msg, i);
|
||||
return dbus_message_set_interface(_pvt->msg, i);
|
||||
}
|
||||
|
||||
const char *CallMessage::member() const
|
||||
{
|
||||
return dbus_message_get_member(_pvt->msg);
|
||||
return dbus_message_get_member(_pvt->msg);
|
||||
}
|
||||
|
||||
bool CallMessage::member(const char *m)
|
||||
{
|
||||
return dbus_message_set_member(_pvt->msg, m);
|
||||
return dbus_message_set_member(_pvt->msg, m);
|
||||
}
|
||||
|
||||
const char *CallMessage::path() const
|
||||
{
|
||||
return dbus_message_get_path(_pvt->msg);
|
||||
return dbus_message_get_path(_pvt->msg);
|
||||
}
|
||||
|
||||
char ** CallMessage::path_split() const
|
||||
char **CallMessage::path_split() const
|
||||
{
|
||||
char ** p;
|
||||
dbus_message_get_path_decomposed(_pvt->msg, &p);
|
||||
return p;
|
||||
char **p;
|
||||
dbus_message_get_path_decomposed(_pvt->msg, &p);
|
||||
return p;
|
||||
}
|
||||
|
||||
bool CallMessage::path(const char *p)
|
||||
{
|
||||
return dbus_message_set_path(_pvt->msg, p);
|
||||
return dbus_message_set_path(_pvt->msg, p);
|
||||
}
|
||||
|
||||
const char *CallMessage::signature() const
|
||||
{
|
||||
return dbus_message_get_signature(_pvt->msg);
|
||||
return dbus_message_get_signature(_pvt->msg);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -632,11 +632,11 @@ const char *CallMessage::signature() const
|
|||
|
||||
ReturnMessage::ReturnMessage(const CallMessage &callee)
|
||||
{
|
||||
_pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
|
||||
_pvt = new Private(dbus_message_new_method_return(callee._pvt->msg));
|
||||
}
|
||||
|
||||
const char *ReturnMessage::signature() const
|
||||
{
|
||||
return dbus_message_get_signature(_pvt->msg);
|
||||
return dbus_message_get_signature(_pvt->msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,17 +34,18 @@
|
|||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
namespace DBus {
|
||||
namespace DBus
|
||||
{
|
||||
|
||||
struct DXXAPILOCAL Message::Private
|
||||
{
|
||||
DBusMessage *msg;
|
||||
DBusMessage *msg;
|
||||
|
||||
Private() : msg(0)
|
||||
{}
|
||||
Private() : msg(0)
|
||||
{}
|
||||
|
||||
Private(DBusMessage *m) : msg(m)
|
||||
{}
|
||||
Private(DBusMessage *m) : msg(m)
|
||||
{}
|
||||
};
|
||||
|
||||
} /* namespace DBus */
|
||||
|
|
372
src/object.cpp
372
src/object.cpp
|
@ -40,7 +40,7 @@
|
|||
using namespace DBus;
|
||||
|
||||
Object::Object(Connection &conn, const Path &path, const char *service)
|
||||
: _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1)
|
||||
: _conn(conn), _path(path), _service(service ? service : ""), _default_timeout(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -50,53 +50,53 @@ Object::~Object()
|
|||
|
||||
void Object::set_timeout(int new_timeout)
|
||||
{
|
||||
debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
|
||||
if(new_timeout < 0 && new_timeout != -1)
|
||||
throw ErrorInvalidArgs("Bad timeout, cannot set it");
|
||||
_default_timeout = new_timeout;
|
||||
debug_log("%s: %d millies", __PRETTY_FUNCTION__, new_timeout);
|
||||
if (new_timeout < 0 && new_timeout != -1)
|
||||
throw ErrorInvalidArgs("Bad timeout, cannot set it");
|
||||
_default_timeout = new_timeout;
|
||||
}
|
||||
|
||||
struct ObjectAdaptor::Private
|
||||
{
|
||||
static void unregister_function_stub(DBusConnection *, void *);
|
||||
static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
|
||||
static void unregister_function_stub(DBusConnection *, void *);
|
||||
static DBusHandlerResult message_function_stub(DBusConnection *, DBusMessage *, void *);
|
||||
};
|
||||
|
||||
static DBusObjectPathVTable _vtable =
|
||||
{
|
||||
ObjectAdaptor::Private::unregister_function_stub,
|
||||
ObjectAdaptor::Private::message_function_stub,
|
||||
NULL, NULL, NULL, NULL
|
||||
{
|
||||
ObjectAdaptor::Private::unregister_function_stub,
|
||||
ObjectAdaptor::Private::message_function_stub,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
void ObjectAdaptor::Private::unregister_function_stub(DBusConnection *conn, void *data)
|
||||
{
|
||||
//TODO: what do we have to do here ?
|
||||
//TODO: what do we have to do here ?
|
||||
}
|
||||
|
||||
DBusHandlerResult ObjectAdaptor::Private::message_function_stub(DBusConnection *, DBusMessage *dmsg, void *data)
|
||||
{
|
||||
ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
|
||||
ObjectAdaptor *o = static_cast<ObjectAdaptor *>(data);
|
||||
|
||||
if (o)
|
||||
{
|
||||
Message msg(new Message::Private(dmsg));
|
||||
if (o)
|
||||
{
|
||||
Message msg(new Message::Private(dmsg));
|
||||
|
||||
debug_log("in object %s", o->path().c_str());
|
||||
debug_log(" got message #%d from %s to %s",
|
||||
msg.serial(),
|
||||
msg.sender(),
|
||||
msg.destination()
|
||||
);
|
||||
debug_log("in object %s", o->path().c_str());
|
||||
debug_log(" got message #%d from %s to %s",
|
||||
msg.serial(),
|
||||
msg.sender(),
|
||||
msg.destination()
|
||||
);
|
||||
|
||||
return o->handle_message(msg)
|
||||
? DBUS_HANDLER_RESULT_HANDLED
|
||||
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
return o->handle_message(msg)
|
||||
? DBUS_HANDLER_RESULT_HANDLED
|
||||
: DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map<Path, ObjectAdaptor *> ObjectAdaptorTable;
|
||||
|
@ -104,282 +104,282 @@ static ObjectAdaptorTable _adaptor_table;
|
|||
|
||||
ObjectAdaptor *ObjectAdaptor::from_path(const Path &path)
|
||||
{
|
||||
ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);
|
||||
ObjectAdaptorTable::iterator ati = _adaptor_table.find(path);
|
||||
|
||||
if (ati != _adaptor_table.end())
|
||||
return ati->second;
|
||||
if (ati != _adaptor_table.end())
|
||||
return ati->second;
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ObjectAdaptorPList ObjectAdaptor::from_path_prefix(const std::string &prefix)
|
||||
{
|
||||
ObjectAdaptorPList ali;
|
||||
ObjectAdaptorPList ali;
|
||||
|
||||
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
|
||||
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
|
||||
|
||||
size_t plen = prefix.length();
|
||||
size_t plen = prefix.length();
|
||||
|
||||
while (ati != _adaptor_table.end())
|
||||
{
|
||||
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
|
||||
ali.push_back(ati->second);
|
||||
while (ati != _adaptor_table.end())
|
||||
{
|
||||
if (!strncmp(ati->second->path().c_str(), prefix.c_str(), plen))
|
||||
ali.push_back(ati->second);
|
||||
|
||||
++ati;
|
||||
}
|
||||
++ati;
|
||||
}
|
||||
|
||||
return ali;
|
||||
return ali;
|
||||
}
|
||||
|
||||
ObjectPathList ObjectAdaptor::child_nodes_from_prefix(const std::string &prefix)
|
||||
{
|
||||
ObjectPathList ali;
|
||||
ObjectPathList ali;
|
||||
|
||||
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
|
||||
ObjectAdaptorTable::iterator ati = _adaptor_table.begin();
|
||||
|
||||
size_t plen = prefix.length();
|
||||
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;
|
||||
}
|
||||
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();
|
||||
ali.sort();
|
||||
ali.unique();
|
||||
|
||||
return ali;
|
||||
return ali;
|
||||
}
|
||||
|
||||
ObjectAdaptor::ObjectAdaptor(Connection &conn, const Path &path)
|
||||
: Object(conn, path, conn.unique_name())
|
||||
: Object(conn, path, conn.unique_name())
|
||||
{
|
||||
register_obj();
|
||||
register_obj();
|
||||
}
|
||||
|
||||
ObjectAdaptor::~ObjectAdaptor()
|
||||
{
|
||||
unregister_obj(false);
|
||||
unregister_obj(false);
|
||||
}
|
||||
|
||||
void ObjectAdaptor::register_obj()
|
||||
{
|
||||
debug_log("registering local object %s", path().c_str());
|
||||
debug_log("registering local object %s", path().c_str());
|
||||
|
||||
if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
|
||||
{
|
||||
throw ErrorNoMemory("unable to register object path");
|
||||
}
|
||||
if (!dbus_connection_register_object_path(conn()._pvt->conn, path().c_str(), &_vtable, this))
|
||||
{
|
||||
throw ErrorNoMemory("unable to register object path");
|
||||
}
|
||||
|
||||
_adaptor_table[path()] = this;
|
||||
_adaptor_table[path()] = this;
|
||||
}
|
||||
|
||||
void ObjectAdaptor::unregister_obj(bool)
|
||||
{
|
||||
_adaptor_table.erase(path());
|
||||
_adaptor_table.erase(path());
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void ObjectAdaptor::_emit_signal(SignalMessage &sig)
|
||||
{
|
||||
sig.path(path().c_str());
|
||||
sig.path(path().c_str());
|
||||
|
||||
conn().send(sig);
|
||||
conn().send(sig);
|
||||
}
|
||||
|
||||
struct ReturnLaterError
|
||||
{
|
||||
const Tag *tag;
|
||||
const Tag *tag;
|
||||
};
|
||||
|
||||
bool ObjectAdaptor::handle_message(const Message &msg)
|
||||
{
|
||||
switch (msg.type())
|
||||
{
|
||||
case DBUS_MESSAGE_TYPE_METHOD_CALL:
|
||||
{
|
||||
const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
|
||||
const char *member = cmsg.member();
|
||||
const char *interface = cmsg.interface();
|
||||
switch (msg.type())
|
||||
{
|
||||
case DBUS_MESSAGE_TYPE_METHOD_CALL:
|
||||
{
|
||||
const CallMessage &cmsg = reinterpret_cast<const CallMessage &>(msg);
|
||||
const char *member = cmsg.member();
|
||||
const char *interface = cmsg.interface();
|
||||
|
||||
debug_log(" invoking method %s.%s", interface, member);
|
||||
|
||||
InterfaceAdaptor *ii = find_interface(interface);
|
||||
if (ii)
|
||||
{
|
||||
try
|
||||
{
|
||||
Message ret = ii->dispatch_method(cmsg);
|
||||
conn().send(ret);
|
||||
}
|
||||
catch(Error &e)
|
||||
{
|
||||
ErrorMessage em(cmsg, e.name(), e.message());
|
||||
conn().send(em);
|
||||
}
|
||||
catch(ReturnLaterError &rle)
|
||||
{
|
||||
_continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
debug_log(" invoking method %s.%s", interface, member);
|
||||
|
||||
InterfaceAdaptor *ii = find_interface(interface);
|
||||
if (ii)
|
||||
{
|
||||
try
|
||||
{
|
||||
Message ret = ii->dispatch_method(cmsg);
|
||||
conn().send(ret);
|
||||
}
|
||||
catch (Error &e)
|
||||
{
|
||||
ErrorMessage em(cmsg, e.name(), e.message());
|
||||
conn().send(em);
|
||||
}
|
||||
catch (ReturnLaterError &rle)
|
||||
{
|
||||
_continuations[rle.tag] = new Continuation(conn(), cmsg, rle.tag);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectAdaptor::return_later(const Tag *tag)
|
||||
{
|
||||
ReturnLaterError rle = { tag };
|
||||
throw rle;
|
||||
ReturnLaterError rle = { tag };
|
||||
throw rle;
|
||||
}
|
||||
|
||||
void ObjectAdaptor::return_now(Continuation *ret)
|
||||
{
|
||||
ret->_conn.send(ret->_return);
|
||||
ret->_conn.send(ret->_return);
|
||||
|
||||
ContinuationMap::iterator di = _continuations.find(ret->_tag);
|
||||
ContinuationMap::iterator di = _continuations.find(ret->_tag);
|
||||
|
||||
delete di->second;
|
||||
delete di->second;
|
||||
|
||||
_continuations.erase(di);
|
||||
_continuations.erase(di);
|
||||
}
|
||||
|
||||
void ObjectAdaptor::return_error(Continuation *ret, const Error error)
|
||||
{
|
||||
ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));
|
||||
ret->_conn.send(ErrorMessage(ret->_call, error.name(), error.message()));
|
||||
|
||||
ContinuationMap::iterator di = _continuations.find(ret->_tag);
|
||||
ContinuationMap::iterator di = _continuations.find(ret->_tag);
|
||||
|
||||
delete di->second;
|
||||
delete di->second;
|
||||
|
||||
_continuations.erase(di);
|
||||
_continuations.erase(di);
|
||||
}
|
||||
|
||||
ObjectAdaptor::Continuation *ObjectAdaptor::find_continuation(const Tag *tag)
|
||||
{
|
||||
ContinuationMap::iterator di = _continuations.find(tag);
|
||||
ContinuationMap::iterator di = _continuations.find(tag);
|
||||
|
||||
return di != _continuations.end() ? di->second : NULL;
|
||||
return di != _continuations.end() ? di->second : NULL;
|
||||
}
|
||||
|
||||
ObjectAdaptor::Continuation::Continuation(Connection &conn, const CallMessage &call, const Tag *tag)
|
||||
: _conn(conn), _call(call), _return(_call), _tag(tag)
|
||||
: _conn(conn), _call(call), _return(_call), _tag(tag)
|
||||
{
|
||||
_writer = _return.writer(); //todo: verify
|
||||
_writer = _return.writer(); //todo: verify
|
||||
}
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
ObjectProxy::ObjectProxy(Connection &conn, const Path &path, const char *service)
|
||||
: Object(conn, path, service)
|
||||
: Object(conn, path, service)
|
||||
{
|
||||
register_obj();
|
||||
register_obj();
|
||||
}
|
||||
|
||||
ObjectProxy::~ObjectProxy()
|
||||
{
|
||||
unregister_obj(false);
|
||||
unregister_obj(false);
|
||||
}
|
||||
|
||||
void ObjectProxy::register_obj()
|
||||
{
|
||||
debug_log("registering remote object %s", path().c_str());
|
||||
debug_log("registering remote object %s", path().c_str());
|
||||
|
||||
_filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message);
|
||||
|
||||
conn().add_filter(_filtered);
|
||||
_filtered = new Callback<ObjectProxy, bool, const Message &>(this, &ObjectProxy::handle_message);
|
||||
|
||||
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
|
||||
while (ii != _interfaces.end())
|
||||
{
|
||||
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'";
|
||||
conn().add_match(im.c_str());
|
||||
++ii;
|
||||
}
|
||||
conn().add_filter(_filtered);
|
||||
|
||||
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
|
||||
while (ii != _interfaces.end())
|
||||
{
|
||||
std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
|
||||
conn().add_match(im.c_str());
|
||||
++ii;
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectProxy::unregister_obj(bool throw_on_error)
|
||||
{
|
||||
debug_log("unregistering remote object %s", path().c_str());
|
||||
debug_log("unregistering remote object %s", path().c_str());
|
||||
|
||||
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
|
||||
while (ii != _interfaces.end())
|
||||
{
|
||||
std::string im = "type='signal',interface='"+ii->first+"',path='"+path()+"'";
|
||||
conn().remove_match(im.c_str(), throw_on_error);
|
||||
++ii;
|
||||
}
|
||||
conn().remove_filter(_filtered);
|
||||
InterfaceProxyTable::const_iterator ii = _interfaces.begin();
|
||||
while (ii != _interfaces.end())
|
||||
{
|
||||
std::string im = "type='signal',interface='" + ii->first + "',path='" + path() + "'";
|
||||
conn().remove_match(im.c_str(), throw_on_error);
|
||||
++ii;
|
||||
}
|
||||
conn().remove_filter(_filtered);
|
||||
}
|
||||
|
||||
Message ObjectProxy::_invoke_method(CallMessage &call)
|
||||
{
|
||||
if (call.path() == NULL)
|
||||
call.path(path().c_str());
|
||||
if (call.path() == NULL)
|
||||
call.path(path().c_str());
|
||||
|
||||
if (call.destination() == NULL)
|
||||
call.destination(service().c_str());
|
||||
if (call.destination() == NULL)
|
||||
call.destination(service().c_str());
|
||||
|
||||
return conn().send_blocking(call, get_timeout());
|
||||
return conn().send_blocking(call, get_timeout());
|
||||
}
|
||||
|
||||
bool ObjectProxy::_invoke_method_noreply(CallMessage &call)
|
||||
{
|
||||
if (call.path() == NULL)
|
||||
call.path(path().c_str());
|
||||
if (call.path() == NULL)
|
||||
call.path(path().c_str());
|
||||
|
||||
if (call.destination() == NULL)
|
||||
call.destination(service().c_str());
|
||||
if (call.destination() == NULL)
|
||||
call.destination(service().c_str());
|
||||
|
||||
return conn().send(call);
|
||||
return conn().send(call);
|
||||
}
|
||||
|
||||
bool ObjectProxy::handle_message(const Message &msg)
|
||||
{
|
||||
switch (msg.type())
|
||||
{
|
||||
case DBUS_MESSAGE_TYPE_SIGNAL:
|
||||
{
|
||||
const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
|
||||
const char *interface = smsg.interface();
|
||||
const char *member = smsg.member();
|
||||
const char *objpath = smsg.path();
|
||||
switch (msg.type())
|
||||
{
|
||||
case DBUS_MESSAGE_TYPE_SIGNAL:
|
||||
{
|
||||
const SignalMessage &smsg = reinterpret_cast<const SignalMessage &>(msg);
|
||||
const char *interface = smsg.interface();
|
||||
const char *member = smsg.member();
|
||||
const char *objpath = smsg.path();
|
||||
|
||||
if (objpath != path()) return false;
|
||||
if (objpath != path()) return false;
|
||||
|
||||
debug_log("filtered signal %s(in %s) from %s to object %s",
|
||||
member, interface, msg.sender(), objpath);
|
||||
debug_log("filtered signal %s(in %s) from %s to object %s",
|
||||
member, interface, msg.sender(), objpath);
|
||||
|
||||
InterfaceProxy *ii = find_interface(interface);
|
||||
if (ii)
|
||||
{
|
||||
return ii->dispatch_signal(smsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
InterfaceProxy *ii = find_interface(interface);
|
||||
if (ii)
|
||||
{
|
||||
return ii->dispatch_signal(smsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
default:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,107 +36,107 @@
|
|||
using namespace DBus;
|
||||
|
||||
PendingCall::Private::Private(DBusPendingCall *dpc)
|
||||
: call(dpc), dataslot(-1)
|
||||
: call(dpc), dataslot(-1)
|
||||
{
|
||||
if (!dbus_pending_call_allocate_data_slot(&dataslot))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to allocate data slot");
|
||||
}
|
||||
if (!dbus_pending_call_allocate_data_slot(&dataslot))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to allocate data slot");
|
||||
}
|
||||
}
|
||||
|
||||
PendingCall::Private::~Private()
|
||||
{
|
||||
if (dataslot != -1)
|
||||
{
|
||||
dbus_pending_call_allocate_data_slot(&dataslot);
|
||||
}
|
||||
if (dataslot != -1)
|
||||
{
|
||||
dbus_pending_call_allocate_data_slot(&dataslot);
|
||||
}
|
||||
}
|
||||
|
||||
void PendingCall::Private::notify_stub(DBusPendingCall *dpc, void *data)
|
||||
{
|
||||
PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
|
||||
PendingCall::Private *pvt = static_cast<PendingCall::Private *>(data);
|
||||
|
||||
PendingCall pc(pvt);
|
||||
pvt->slot(pc);
|
||||
PendingCall pc(pvt);
|
||||
pvt->slot(pc);
|
||||
}
|
||||
|
||||
PendingCall::PendingCall(PendingCall::Private *p)
|
||||
: _pvt(p)
|
||||
: _pvt(p)
|
||||
{
|
||||
if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to initialize pending call");
|
||||
}
|
||||
if (!dbus_pending_call_set_notify(_pvt->call, Private::notify_stub, p, NULL))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to initialize pending call");
|
||||
}
|
||||
}
|
||||
|
||||
PendingCall::PendingCall(const PendingCall &c)
|
||||
: _pvt(c._pvt)
|
||||
: _pvt(c._pvt)
|
||||
{
|
||||
dbus_pending_call_ref(_pvt->call);
|
||||
dbus_pending_call_ref(_pvt->call);
|
||||
}
|
||||
|
||||
PendingCall::~PendingCall()
|
||||
{
|
||||
dbus_pending_call_unref(_pvt->call);
|
||||
dbus_pending_call_unref(_pvt->call);
|
||||
}
|
||||
|
||||
PendingCall &PendingCall::operator = (const PendingCall &c)
|
||||
{
|
||||
if (&c != this)
|
||||
{
|
||||
dbus_pending_call_unref(_pvt->call);
|
||||
_pvt = c._pvt;
|
||||
dbus_pending_call_ref(_pvt->call);
|
||||
}
|
||||
return *this;
|
||||
if (&c != this)
|
||||
{
|
||||
dbus_pending_call_unref(_pvt->call);
|
||||
_pvt = c._pvt;
|
||||
dbus_pending_call_ref(_pvt->call);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool PendingCall::completed()
|
||||
{
|
||||
return dbus_pending_call_get_completed(_pvt->call);
|
||||
return dbus_pending_call_get_completed(_pvt->call);
|
||||
}
|
||||
|
||||
void PendingCall::cancel()
|
||||
{
|
||||
dbus_pending_call_cancel(_pvt->call);
|
||||
dbus_pending_call_cancel(_pvt->call);
|
||||
}
|
||||
|
||||
void PendingCall::block()
|
||||
{
|
||||
dbus_pending_call_block(_pvt->call);
|
||||
dbus_pending_call_block(_pvt->call);
|
||||
}
|
||||
|
||||
void PendingCall::data(void *p)
|
||||
{
|
||||
if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to initialize data slot");
|
||||
}
|
||||
if (!dbus_pending_call_set_data(_pvt->call, _pvt->dataslot, p, NULL))
|
||||
{
|
||||
throw ErrorNoMemory("Unable to initialize data slot");
|
||||
}
|
||||
}
|
||||
|
||||
void *PendingCall::data()
|
||||
{
|
||||
return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
|
||||
return dbus_pending_call_get_data(_pvt->call, _pvt->dataslot);
|
||||
}
|
||||
|
||||
Slot<void, PendingCall &>& PendingCall::slot()
|
||||
{
|
||||
return _pvt->slot;
|
||||
return _pvt->slot;
|
||||
}
|
||||
|
||||
Message PendingCall::steal_reply()
|
||||
{
|
||||
DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
|
||||
if (!dmsg)
|
||||
{
|
||||
dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
|
||||
DBusMessage *dmsg = dbus_pending_call_steal_reply(_pvt->call);
|
||||
if (!dmsg)
|
||||
{
|
||||
dbus_bool_t callComplete = dbus_pending_call_get_completed(_pvt->call);
|
||||
|
||||
if (callComplete)
|
||||
throw ErrorNoReply("No reply available");
|
||||
else
|
||||
throw ErrorNoReply("Call not complete");
|
||||
}
|
||||
if (callComplete)
|
||||
throw ErrorNoReply("No reply available");
|
||||
else
|
||||
throw ErrorNoReply("Call not complete");
|
||||
}
|
||||
|
||||
return Message(new Message::Private(dmsg));
|
||||
return Message(new Message::Private(dmsg));
|
||||
}
|
||||
|
||||
|
|
|
@ -34,19 +34,20 @@
|
|||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
namespace DBus {
|
||||
namespace DBus
|
||||
{
|
||||
|
||||
struct DXXAPILOCAL PendingCall::Private
|
||||
{
|
||||
DBusPendingCall *call;
|
||||
int dataslot;
|
||||
Slot<void, PendingCall &> slot;
|
||||
|
||||
Private(DBusPendingCall *);
|
||||
DBusPendingCall *call;
|
||||
int dataslot;
|
||||
Slot<void, PendingCall &> slot;
|
||||
|
||||
~Private();
|
||||
Private(DBusPendingCall *);
|
||||
|
||||
static void notify_stub(DBusPendingCall *dpc, void *data);
|
||||
~Private();
|
||||
|
||||
static void notify_stub(DBusPendingCall *dpc, void *data);
|
||||
};
|
||||
|
||||
} /* namespace DBus */
|
||||
|
|
18
src/pipe.cpp
18
src/pipe.cpp
|
@ -42,13 +42,13 @@ using namespace std;
|
|||
|
||||
Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), const void *data) :
|
||||
_handler(handler),
|
||||
_fd_write (0),
|
||||
_fd_read (0),
|
||||
_fd_write(0),
|
||||
_fd_read(0),
|
||||
_data(data)
|
||||
{
|
||||
int fd[2];
|
||||
|
||||
if(pipe(fd) == 0)
|
||||
if (pipe(fd) == 0)
|
||||
{
|
||||
_fd_read = fd[0];
|
||||
_fd_write = fd[1];
|
||||
|
@ -56,23 +56,23 @@ Pipe::Pipe(void(*handler)(const void *data, void *buffer, unsigned int nbyte), c
|
|||
}
|
||||
else
|
||||
{
|
||||
throw Error("PipeError:errno", toString(errno).c_str());
|
||||
throw Error("PipeError:errno", toString(errno).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Pipe::write(const void *buffer, unsigned int nbytes)
|
||||
{
|
||||
// first write the size into the pipe...
|
||||
::write(_fd_write, static_cast <const void*> (&nbytes), sizeof(nbytes));
|
||||
::write(_fd_write, static_cast <const void *>(&nbytes), sizeof(nbytes));
|
||||
|
||||
// ...then write the real data
|
||||
::write(_fd_write, buffer, nbytes);
|
||||
::write(_fd_write, buffer, nbytes);
|
||||
}
|
||||
|
||||
ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
|
||||
{
|
||||
{
|
||||
// first read the size from the pipe...
|
||||
::read(_fd_read, &nbytes, sizeof (nbytes));
|
||||
::read(_fd_read, &nbytes, sizeof(nbytes));
|
||||
|
||||
//ssize_t size = 0;
|
||||
return ::read(_fd_read, buffer, nbytes);
|
||||
|
@ -80,5 +80,5 @@ ssize_t Pipe::read(void *buffer, unsigned int &nbytes)
|
|||
|
||||
void Pipe::signal()
|
||||
{
|
||||
::write(_fd_write, '\0', 1);
|
||||
::write(_fd_write, '\0', 1);
|
||||
}
|
||||
|
|
142
src/property.cpp
142
src/property.cpp
|
@ -35,117 +35,117 @@ using namespace DBus;
|
|||
static const char *properties_name = "org.freedesktop.DBus.Properties";
|
||||
|
||||
PropertiesAdaptor::PropertiesAdaptor()
|
||||
: InterfaceAdaptor(properties_name)
|
||||
: InterfaceAdaptor(properties_name)
|
||||
{
|
||||
register_method(PropertiesAdaptor, Get, Get);
|
||||
register_method(PropertiesAdaptor, Set, Set);
|
||||
register_method(PropertiesAdaptor, Get, Get);
|
||||
register_method(PropertiesAdaptor, Set, Set);
|
||||
}
|
||||
|
||||
Message PropertiesAdaptor::Get(const CallMessage &call)
|
||||
{
|
||||
MessageIter ri = call.reader();
|
||||
MessageIter ri = call.reader();
|
||||
|
||||
std::string iface_name;
|
||||
std::string property_name;
|
||||
std::string iface_name;
|
||||
std::string property_name;
|
||||
|
||||
ri >> iface_name >> property_name;
|
||||
ri >> iface_name >> property_name;
|
||||
|
||||
debug_log("requesting property %s on interface %s", property_name.c_str(), iface_name.c_str());
|
||||
debug_log("requesting property %s on interface %s", property_name.c_str(), iface_name.c_str());
|
||||
|
||||
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
|
||||
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
|
||||
|
||||
if (!interface)
|
||||
throw ErrorFailed("requested interface not found");
|
||||
if (!interface)
|
||||
throw ErrorFailed("requested interface not found");
|
||||
|
||||
Variant *value = interface->get_property(property_name);
|
||||
Variant *value = interface->get_property(property_name);
|
||||
|
||||
if (!value)
|
||||
throw ErrorFailed("requested property not found");
|
||||
if (!value)
|
||||
throw ErrorFailed("requested property not found");
|
||||
|
||||
on_get_property(*interface, property_name, *value);
|
||||
on_get_property(*interface, property_name, *value);
|
||||
|
||||
ReturnMessage reply(call);
|
||||
ReturnMessage reply(call);
|
||||
|
||||
MessageIter wi = reply.writer();
|
||||
MessageIter wi = reply.writer();
|
||||
|
||||
wi << *value;
|
||||
return reply;
|
||||
wi << *value;
|
||||
return reply;
|
||||
}
|
||||
|
||||
Message PropertiesAdaptor::Set(const CallMessage &call)
|
||||
{
|
||||
MessageIter ri = call.reader();
|
||||
MessageIter ri = call.reader();
|
||||
|
||||
std::string iface_name;
|
||||
std::string property_name;
|
||||
Variant value;
|
||||
std::string iface_name;
|
||||
std::string property_name;
|
||||
Variant value;
|
||||
|
||||
ri >> iface_name >> property_name >> value;
|
||||
ri >> iface_name >> property_name >> value;
|
||||
|
||||
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
|
||||
InterfaceAdaptor *interface = (InterfaceAdaptor *) find_interface(iface_name);
|
||||
|
||||
if (!interface)
|
||||
throw ErrorFailed("requested interface not found");
|
||||
if (!interface)
|
||||
throw ErrorFailed("requested interface not found");
|
||||
|
||||
on_set_property(*interface, property_name, value);
|
||||
on_set_property(*interface, property_name, value);
|
||||
|
||||
interface->set_property(property_name, value);
|
||||
interface->set_property(property_name, value);
|
||||
|
||||
ReturnMessage reply(call);
|
||||
ReturnMessage reply(call);
|
||||
|
||||
return reply;
|
||||
return reply;
|
||||
}
|
||||
|
||||
IntrospectedInterface * PropertiesAdaptor::introspect() const
|
||||
IntrospectedInterface *PropertiesAdaptor::introspect() const
|
||||
{
|
||||
static IntrospectedArgument Get_args[] =
|
||||
{
|
||||
{ "interface_name", "s", true },
|
||||
{ "property_name", "s", true },
|
||||
{ "value", "v", false },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedArgument Set_args[] =
|
||||
{
|
||||
{ "interface_name", "s", true },
|
||||
{ "property_name", "s", true },
|
||||
{ "value", "v", true },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Properties_methods[] =
|
||||
{
|
||||
{ "Get", Get_args },
|
||||
{ "Set", Set_args },
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Properties_signals[] =
|
||||
{
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedProperty Properties_properties[] =
|
||||
{
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedInterface Properties_interface =
|
||||
{
|
||||
properties_name,
|
||||
Properties_methods,
|
||||
Properties_signals,
|
||||
Properties_properties
|
||||
};
|
||||
return &Properties_interface;
|
||||
static IntrospectedArgument Get_args[] =
|
||||
{
|
||||
{ "interface_name", "s", true },
|
||||
{ "property_name", "s", true },
|
||||
{ "value", "v", false },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedArgument Set_args[] =
|
||||
{
|
||||
{ "interface_name", "s", true },
|
||||
{ "property_name", "s", true },
|
||||
{ "value", "v", true },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Properties_methods[] =
|
||||
{
|
||||
{ "Get", Get_args },
|
||||
{ "Set", Set_args },
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedMethod Properties_signals[] =
|
||||
{
|
||||
{ 0, 0 }
|
||||
};
|
||||
static IntrospectedProperty Properties_properties[] =
|
||||
{
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
static IntrospectedInterface Properties_interface =
|
||||
{
|
||||
properties_name,
|
||||
Properties_methods,
|
||||
Properties_signals,
|
||||
Properties_properties
|
||||
};
|
||||
return &Properties_interface;
|
||||
}
|
||||
|
||||
PropertiesProxy::PropertiesProxy()
|
||||
: InterfaceProxy(properties_name)
|
||||
: InterfaceProxy(properties_name)
|
||||
{
|
||||
}
|
||||
|
||||
Variant PropertiesProxy::Get(const std::string &iface, const std::string &property)
|
||||
{
|
||||
//todo
|
||||
Variant v;
|
||||
return v;
|
||||
Variant v;
|
||||
return v;
|
||||
}
|
||||
|
||||
void PropertiesProxy::Set(const std::string &iface, const std::string &property, const Variant &value)
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
using namespace DBus;
|
||||
|
||||
Server::Private::Private(DBusServer *s)
|
||||
: server(s)
|
||||
: server(s)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -46,31 +46,31 @@ Server::Private::~Private()
|
|||
|
||||
void Server::Private::on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data)
|
||||
{
|
||||
Server *s = static_cast<Server *>(data);
|
||||
Server *s = static_cast<Server *>(data);
|
||||
|
||||
Connection nc (new Connection::Private(conn, s->_pvt.get()));
|
||||
Connection nc(new Connection::Private(conn, s->_pvt.get()));
|
||||
|
||||
s->_pvt->connections.push_back(nc);
|
||||
s->_pvt->connections.push_back(nc);
|
||||
|
||||
s->on_new_connection(nc);
|
||||
s->on_new_connection(nc);
|
||||
|
||||
debug_log("incoming connection 0x%08x", conn);
|
||||
debug_log("incoming connection 0x%08x", conn);
|
||||
}
|
||||
|
||||
Server::Server(const char *address)
|
||||
{
|
||||
InternalError e;
|
||||
DBusServer *server = dbus_server_listen(address, e);
|
||||
InternalError e;
|
||||
DBusServer *server = dbus_server_listen(address, e);
|
||||
|
||||
if (e) throw Error(e);
|
||||
if (e) throw Error(e);
|
||||
|
||||
debug_log("server 0x%08x listening on %s", server, address);
|
||||
debug_log("server 0x%08x listening on %s", server, address);
|
||||
|
||||
_pvt = new Private(server);
|
||||
_pvt = new Private(server);
|
||||
|
||||
dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL);
|
||||
dbus_server_set_new_connection_function(_pvt->server, Private::on_new_conn_cb, this, NULL);
|
||||
|
||||
setup(default_dispatcher);
|
||||
setup(default_dispatcher);
|
||||
}
|
||||
/*
|
||||
Server::Server(const Server &s)
|
||||
|
@ -81,49 +81,49 @@ Server::Server(const Server &s)
|
|||
*/
|
||||
Server::~Server()
|
||||
{
|
||||
dbus_server_unref(_pvt->server);
|
||||
dbus_server_unref(_pvt->server);
|
||||
}
|
||||
|
||||
Dispatcher *Server::setup(Dispatcher *dispatcher)
|
||||
{
|
||||
debug_log("registering stubs for server %p", _pvt->server);
|
||||
debug_log("registering stubs for server %p", _pvt->server);
|
||||
|
||||
Dispatcher *prev = _pvt->dispatcher;
|
||||
Dispatcher *prev = _pvt->dispatcher;
|
||||
|
||||
dbus_server_set_watch_functions(
|
||||
_pvt->server,
|
||||
Dispatcher::Private::on_add_watch,
|
||||
Dispatcher::Private::on_rem_watch,
|
||||
Dispatcher::Private::on_toggle_watch,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
dbus_server_set_watch_functions(
|
||||
_pvt->server,
|
||||
Dispatcher::Private::on_add_watch,
|
||||
Dispatcher::Private::on_rem_watch,
|
||||
Dispatcher::Private::on_toggle_watch,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
|
||||
dbus_server_set_timeout_functions(
|
||||
_pvt->server,
|
||||
Dispatcher::Private::on_add_timeout,
|
||||
Dispatcher::Private::on_rem_timeout,
|
||||
Dispatcher::Private::on_toggle_timeout,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
dbus_server_set_timeout_functions(
|
||||
_pvt->server,
|
||||
Dispatcher::Private::on_add_timeout,
|
||||
Dispatcher::Private::on_rem_timeout,
|
||||
Dispatcher::Private::on_toggle_timeout,
|
||||
dispatcher,
|
||||
0
|
||||
);
|
||||
|
||||
_pvt->dispatcher = dispatcher;
|
||||
_pvt->dispatcher = dispatcher;
|
||||
|
||||
return prev;
|
||||
return prev;
|
||||
}
|
||||
|
||||
bool Server::operator == (const Server &s) const
|
||||
{
|
||||
return _pvt->server == s._pvt->server;
|
||||
return _pvt->server == s._pvt->server;
|
||||
}
|
||||
|
||||
bool Server::listening() const
|
||||
{
|
||||
return dbus_server_get_is_connected(_pvt->server);
|
||||
return dbus_server_get_is_connected(_pvt->server);
|
||||
}
|
||||
void Server::disconnect()
|
||||
{
|
||||
dbus_server_disconnect(_pvt->server);
|
||||
dbus_server_disconnect(_pvt->server);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,21 +35,22 @@
|
|||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
namespace DBus {
|
||||
|
||||
struct DXXAPILOCAL Server::Private
|
||||
namespace DBus
|
||||
{
|
||||
DBusServer *server;
|
||||
|
||||
Dispatcher *dispatcher;
|
||||
struct DXXAPILOCAL Server::Private
|
||||
{
|
||||
DBusServer *server;
|
||||
|
||||
ConnectionList connections;
|
||||
Dispatcher *dispatcher;
|
||||
|
||||
Private(DBusServer *);
|
||||
ConnectionList connections;
|
||||
|
||||
~Private();
|
||||
Private(DBusServer *);
|
||||
|
||||
static void on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data);
|
||||
~Private();
|
||||
|
||||
static void on_new_conn_cb(DBusServer *server, DBusConnection *conn, void *data);
|
||||
};
|
||||
|
||||
} /* namespace DBus */
|
||||
|
|
|
@ -37,70 +37,70 @@
|
|||
using namespace DBus;
|
||||
|
||||
Variant::Variant()
|
||||
: _msg(CallMessage()) // dummy message used as temporary storage for variant data
|
||||
: _msg(CallMessage()) // dummy message used as temporary storage for variant data
|
||||
{
|
||||
}
|
||||
|
||||
Variant::Variant(MessageIter &it)
|
||||
: _msg(CallMessage())
|
||||
: _msg(CallMessage())
|
||||
{
|
||||
MessageIter vi = it.recurse();
|
||||
MessageIter mi = _msg.writer();
|
||||
vi.copy_data(mi);
|
||||
MessageIter vi = it.recurse();
|
||||
MessageIter mi = _msg.writer();
|
||||
vi.copy_data(mi);
|
||||
}
|
||||
|
||||
Variant &Variant::operator = (const Variant &v)
|
||||
{
|
||||
if (&v != this)
|
||||
{
|
||||
_msg = v._msg;
|
||||
}
|
||||
return *this;
|
||||
if (&v != this)
|
||||
{
|
||||
_msg = v._msg;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Variant::clear()
|
||||
{
|
||||
CallMessage empty;
|
||||
_msg = empty;
|
||||
CallMessage empty;
|
||||
_msg = empty;
|
||||
}
|
||||
|
||||
const Signature Variant::signature() const
|
||||
{
|
||||
char *sigbuf = reader().signature();
|
||||
char *sigbuf = reader().signature();
|
||||
|
||||
Signature signature = sigbuf;
|
||||
Signature signature = sigbuf;
|
||||
|
||||
free(sigbuf);
|
||||
free(sigbuf);
|
||||
|
||||
return signature;
|
||||
return signature;
|
||||
}
|
||||
|
||||
MessageIter &operator << (MessageIter &iter, const Variant &val)
|
||||
{
|
||||
const Signature sig = val.signature();
|
||||
const Signature sig = val.signature();
|
||||
|
||||
MessageIter rit = val.reader();
|
||||
MessageIter wit = iter.new_variant(sig.c_str());
|
||||
MessageIter rit = val.reader();
|
||||
MessageIter wit = iter.new_variant(sig.c_str());
|
||||
|
||||
rit.copy_data(wit);
|
||||
rit.copy_data(wit);
|
||||
|
||||
iter.close_container(wit);
|
||||
iter.close_container(wit);
|
||||
|
||||
return iter;
|
||||
return iter;
|
||||
}
|
||||
|
||||
MessageIter &operator >> (MessageIter &iter, Variant &val)
|
||||
{
|
||||
if (iter.type() != DBUS_TYPE_VARIANT)
|
||||
throw ErrorInvalidArgs("variant type expected");
|
||||
if (iter.type() != DBUS_TYPE_VARIANT)
|
||||
throw ErrorInvalidArgs("variant type expected");
|
||||
|
||||
val.clear();
|
||||
val.clear();
|
||||
|
||||
MessageIter vit = iter.recurse();
|
||||
MessageIter mit = val.writer();
|
||||
MessageIter vit = iter.recurse();
|
||||
MessageIter mit = val.writer();
|
||||
|
||||
vit.copy_data(mit);
|
||||
vit.copy_data(mit);
|
||||
|
||||
return ++iter;
|
||||
return ++iter;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue