dbus: move to signal

Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
Julien Danjou 2009-07-29 16:10:29 +02:00
parent 047d04d438
commit 299bc00286
7 changed files with 115 additions and 97 deletions

162
dbus.c
View File

@ -30,12 +30,15 @@
#include <fcntl.h>
#include "event.h"
#include "luaa.h"
static DBusConnection *dbus_connection_session = NULL;
static DBusConnection *dbus_connection_system = NULL;
ev_io dbusio_ses = { .fd = -1 };
ev_io dbusio_sys = { .fd = -1 };
static signal_array_t dbus_signals;
static void
a_dbus_cleanup_bus(DBusConnection *dbus_connection, ev_io *dbusio)
{
@ -248,7 +251,11 @@ a_dbus_message_iter(DBusMessageIter *iter)
static void
a_dbus_process_request(DBusConnection *dbus_connection, DBusMessage *msg)
{
if(globalconf.hooks.dbus == LUA_REFNIL)
const char *interface = dbus_message_get_interface(msg);
signal_t *sig = signal_array_getbyid(&dbus_signals,
a_strhash((const unsigned char *) interface));
if(!sig)
return;
lua_createtable(globalconf.L, 0, 5);
@ -274,11 +281,10 @@ a_dbus_process_request(DBusConnection *dbus_connection, DBusMessage *msg)
lua_setfield(globalconf.L, -2, "type");
const char *s = dbus_message_get_interface(msg);
lua_pushstring(globalconf.L, NONULL(s));
lua_pushstring(globalconf.L, NONULL(interface));
lua_setfield(globalconf.L, -2, "interface");
s = dbus_message_get_path(msg);
const char *s = dbus_message_get_path(msg);
lua_pushstring(globalconf.L, NONULL(s));
lua_setfield(globalconf.L, -2, "path");
@ -300,67 +306,85 @@ a_dbus_process_request(DBusConnection *dbus_connection, DBusMessage *msg)
nargs += a_dbus_message_iter(&iter);
if(dbus_message_get_no_reply(msg))
luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.dbus, nargs, 0);
else
{
int n = lua_gettop(globalconf.L) - nargs;
luaA_dofunction_from_registry(globalconf.L, globalconf.hooks.dbus, nargs, LUA_MULTRET);
n -= lua_gettop(globalconf.L);
DBusMessage *reply = dbus_message_new_method_return(msg);
dbus_message_iter_init_append(reply, &iter);
/* i is negative */
for(int i = n; i < 0; i += 2)
/* emit signals */
foreach(func, sig->sigfuncs)
{
/* i is the type name, i+1 the value */
size_t len;
const char *type = lua_tolstring(globalconf.L, i, &len);
for(int i = 0; i < nargs; i++)
lua_pushvalue(globalconf.L, - nargs);
luaA_object_push(globalconf.L, (void *) *func);
luaA_dofunction(globalconf.L, nargs, 0);
}
else
foreach(func, sig->sigfuncs)
{
int n = lua_gettop(globalconf.L);
if(!type || len != 1)
break;
for(int i = 0; i < nargs; i++)
lua_pushvalue(globalconf.L, - nargs);
luaA_object_push(globalconf.L, (void *) *func);
luaA_dofunction(globalconf.L, nargs, LUA_MULTRET);
switch(*type)
n -= lua_gettop(globalconf.L);
DBusMessage *reply = dbus_message_new_method_return(msg);
dbus_message_iter_init_append(reply, &iter);
/* i is negative */
for(int i = n; i < 0; i += 2)
{
case DBUS_TYPE_BOOLEAN:
/* i is the type name, i+1 the value */
size_t len;
const char *type = lua_tolstring(globalconf.L, i, &len);
if(!type || len != 1)
{
dbus_bool_t b = lua_toboolean(globalconf.L, i + 1);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b);
luaA_warn(globalconf.L,
"your D-Bus signal handling method returned bad data");
return;
}
break;
switch(*type)
{
case DBUS_TYPE_BOOLEAN:
{
dbus_bool_t b = lua_toboolean(globalconf.L, i + 1);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &b);
}
break;
#define DBUS_MSG_RETURN_HANDLE_TYPE_STRING(dbustype) \
case dbustype: \
if((s = lua_tostring(globalconf.L, i + 1))) \
case dbustype: \
if((s = lua_tostring(globalconf.L, i + 1))) \
dbus_message_iter_append_basic(&iter, dbustype, &s); \
break;
DBUS_MSG_RETURN_HANDLE_TYPE_STRING(DBUS_TYPE_STRING)
DBUS_MSG_RETURN_HANDLE_TYPE_STRING(DBUS_TYPE_BYTE)
break;
DBUS_MSG_RETURN_HANDLE_TYPE_STRING(DBUS_TYPE_STRING)
DBUS_MSG_RETURN_HANDLE_TYPE_STRING(DBUS_TYPE_BYTE)
#undef DBUS_MSG_RETURN_HANDLE_TYPE_STRING
#define DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(type, dbustype) \
case dbustype: \
{ \
type num = lua_tonumber(globalconf.L, i + 1); \
dbus_message_iter_append_basic(&iter, dbustype, &num); \
} \
break;
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(int16_t, DBUS_TYPE_INT16)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(uint16_t, DBUS_TYPE_UINT16)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(int32_t, DBUS_TYPE_INT32)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(uint32_t, DBUS_TYPE_UINT32)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(int64_t, DBUS_TYPE_INT64)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(uint64_t, DBUS_TYPE_UINT64)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(double, DBUS_TYPE_DOUBLE)
case dbustype: \
{ \
type num = lua_tonumber(globalconf.L, i + 1); \
dbus_message_iter_append_basic(&iter, dbustype, &num); \
} \
break;
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(int16_t, DBUS_TYPE_INT16)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(uint16_t, DBUS_TYPE_UINT16)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(int32_t, DBUS_TYPE_INT32)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(uint32_t, DBUS_TYPE_UINT32)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(int64_t, DBUS_TYPE_INT64)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(uint64_t, DBUS_TYPE_UINT64)
DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER(double, DBUS_TYPE_DOUBLE)
#undef DBUS_MSG_RETURN_HANDLE_TYPE_NUMBER
}
lua_remove(globalconf.L, i);
lua_remove(globalconf.L, i + 1);
}
lua_remove(globalconf.L, i);
lua_remove(globalconf.L, i + 1);
dbus_connection_send(dbus_connection, reply, NULL);
dbus_message_unref(reply);
}
dbus_connection_send(dbus_connection, reply, NULL);
dbus_message_unref(reply);
}
lua_pop(globalconf.L, nargs);
}
static void
@ -622,12 +646,48 @@ luaA_dbus_remove_match(lua_State *L)
return 0;
}
/** Add a signal receiver on the D-Bus.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam A string with the interface name.
* \lparam The function to call.
*/
static int
luaA_dbus_add_signal(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
luaA_checkfunction(L, 2);
signal_add(&dbus_signals, name, luaA_object_ref(L, 2));
return 0;
}
/** Add a signal receiver on the D-Bus.
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam A string with the interface name.
* \lparam The function to call.
*/
static int
luaA_dbus_remove_signal(lua_State *L)
{
const char *name = luaL_checkstring(L, 1);
luaA_checkfunction(L, 2);
const void *func = lua_topointer(L, 2);
signal_remove(&dbus_signals, name, func);
luaA_object_unref(L, (void *) func);
return 0;
}
const struct luaL_reg awesome_dbus_lib[] =
{
{ "request_name", luaA_dbus_request_name },
{ "release_name", luaA_dbus_release_name },
{ "add_match", luaA_dbus_add_match },
{ "remove_match", luaA_dbus_remove_match },
{ "add_signal", luaA_dbus_add_signal },
{ "remove_signal", luaA_dbus_remove_signal },
{ NULL, NULL }
};

23
hooks.c
View File

@ -214,26 +214,6 @@ luaA_hooks_exit(lua_State *L)
HANDLE_HOOK(L, globalconf.hooks.exit);
}
#ifdef WITH_DBUS
/** Set the function to be called when a D-Bus event is received.
* The first argument passed to this function is the type of the message we
* receive: signal, method_call, method_return or error.
* The second argument is the path.
* The other arguments are a variable list of arguments.
* The function can return values using pair of type, value.
* For example: return "s", "hello", "i", 32
* \param L The Lua VM state.
* \return The number of elements pushed on stack.
* \luastack
* \lparam A function to call on D-Bus events.
*/
static int
luaA_hooks_dbus(lua_State *L)
{
HANDLE_HOOK(L, globalconf.hooks.dbus);
}
#endif
const struct luaL_reg awesome_hooks_lib[] =
{
{ "focus", luaA_hooks_focus },
@ -249,8 +229,5 @@ const struct luaL_reg awesome_hooks_lib[] =
{ "startup_notification", luaA_hooks_startup_notification },
{ "timer", luaA_hooks_timer },
{ "exit", luaA_hooks_exit },
#ifdef WITH_DBUS
{ "dbus", luaA_hooks_dbus },
#endif
{ NULL, NULL }
};

View File

@ -123,18 +123,6 @@ for name, hook in pairs(capi.hooks) do
end)
end
end
elseif name == "dbus" then
_M[name].register = function (interface, f)
if not _M[name].callbacks then
_M[name].callbacks = {}
hook(function (msg, ...)
if _M[name].callbacks[msg.interface] then
return _M[name].callbacks[msg.interface](msg, ...)
end
end)
end
_M[name].callbacks[interface] = f
end
else
_M[name].register = function (f)
if not _M[name].callbacks then

View File

@ -19,7 +19,7 @@ local type = type
module("awful.remote")
if dbus then
hooks.dbus.register("org.naquadah.awesome.awful.Remote", function(data, code)
dbus.add_signal("org.naquadah.awesome.awful.Remote", function(data, code)
if data.member == "Eval" then
local f, e = loadstring(code)
if f then

View File

@ -401,8 +401,8 @@ end
-- DBUS/Notification support
-- Notify
if hooks.dbus then
hooks.dbus.register("org.freedesktop.Notifications", function (data, appname, replaces_id, icon, title, text, actions, hints, expire)
if capi.dbus then
capi.dbus.add_signal("org.freedesktop.Notifications", function (data, appname, replaces_id, icon, title, text, actions, hints, expire)
args = { preset = { } }
if data.member == "Notify" then
if text ~= "" then
@ -476,7 +476,7 @@ if hooks.dbus then
end
end)
hooks.dbus.register("org.freedesktop.DBus.Introspectable",
capi.dbus.add_signal("org.freedesktop.DBus.Introspectable",
function (data, text)
if data.member == "Introspect" then
local xml = [=[<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object

3
luaa.c
View File

@ -718,9 +718,6 @@ luaA_init(xdgHandle* xdg)
globalconf.hooks.startup_notification = LUA_REFNIL;
globalconf.hooks.timer = LUA_REFNIL;
globalconf.hooks.exit = LUA_REFNIL;
#ifdef WITH_DBUS
globalconf.hooks.dbus = LUA_REFNIL;
#endif
/* add Lua lib path (/usr/share/awesome/lib by default) */
lua_getglobal(L, "package");

View File

@ -122,10 +122,6 @@ struct awesome_t
int exit;
/** Startup notification hooks */
int startup_notification;
#ifdef WITH_DBUS
/** Command to run on dbus events */
int dbus;
#endif
} hooks;
/** The event loop */
struct ev_loop *loop;