From 3de2bf3918ee3c4f160016101f614afd5fa20733 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Tue, 8 Jul 2008 10:54:57 +0200 Subject: [PATCH] dbus: add client support Signed-off-by: Julien Danjou --- client.c | 2 +- client.h | 2 + common/tokenize.gperf | 2 + dbus.c | 145 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 149 insertions(+), 2 deletions(-) diff --git a/client.c b/client.c index 3f00e39a5..f37a1f6b2 100644 --- a/client.c +++ b/client.c @@ -1122,7 +1122,7 @@ luaA_client_unmanage(lua_State *L) * \param L The Lua VM state. * \return The number of elements pushed on stack. */ -static int +int luaA_client_newindex(lua_State *L) { size_t len; diff --git a/client.h b/client.h index 50e235aa7..147c4e945 100644 --- a/client.h +++ b/client.h @@ -46,6 +46,8 @@ void client_setfloating(client_t *, bool); char * client_markup_parse(client_t *, const char *, ssize_t); void client_setborder(client_t *, int); +int luaA_client_newindex(lua_State *); + int luaA_client_userdata_new(lua_State *, client_t *); DO_SLIST(client_t, client, p_delete) diff --git a/common/tokenize.gperf b/common/tokenize.gperf index 710c93e65..079197d63 100644 --- a/common/tokenize.gperf +++ b/common/tokenize.gperf @@ -11,8 +11,10 @@ border_width bottom bottomleft bottomright +byname center class +client color coords fg diff --git a/dbus.c b/dbus.c index 6b3aac878..3f30eb23c 100644 --- a/dbus.c +++ b/dbus.c @@ -27,6 +27,7 @@ #include "dbus.h" #include "widget.h" +#include "client.h" extern awesome_t globalconf; @@ -34,11 +35,129 @@ static DBusError err; static DBusConnection *dbus_connection = NULL; ev_io dbusio = { .fd = -1 }; +/** Check a dbus object path format and its number of element. + * \param path The path. + * \param nelem The number of element it should have. + * \return true if the path is ok, false otherwise. + */ +static bool +a_dbus_path_check(char **path, int nelem) +{ + int i; + + for(i = 0; path[i]; i++); + if(i != nelem) + return false; + return (!a_strcmp(path[0], "org") && !a_strcmp(path[1], "awesome")); +} + +static void +a_dbus_process_request_client(DBusMessage *msg) +{ + int i = 2; + DBusMessageIter iter; + const char *m; + char **path, *arg; + client_t *c; + bool b; + uint64_t i64; + double d; + + if(!dbus_message_get_path_decomposed(msg, &path)) + return; + + /* path is: + * /org/awesome/clients/bywhat/id */ + if(!a_dbus_path_check(path, 5) + || a_strcmp(path[2], "clients")) + goto bailout; + + /* handle by- */ + switch(a_tokenize(path[3], -1)) + { + case A_TK_BYNAME: + for(c = globalconf.clients; c; c = c->next) + if(!a_strcmp(c->name, path[4])) + break; + /* not found, return */ + if(!c) + goto bailout; + printf("found\n"); + break; + default: + return; + } + + if(!dbus_message_iter_init(msg, &iter)) + { + printf("bad init\n"); + dbus_error_free(&err); + return; + } + + /* clear stack */ + lua_settop(globalconf.L, 0); + + /* push index function */ + lua_pushcfunction(globalconf.L, luaA_client_newindex); + + /* push the client */ + luaA_client_userdata_new(globalconf.L, c); + + /* get the method name */ + m = dbus_message_get_member(msg); + + /* push the method name */ + lua_pushstring(globalconf.L, m); + + do + { + switch(dbus_message_iter_get_arg_type(&iter)) + { + case DBUS_TYPE_STRING: + dbus_message_iter_get_basic(&iter, &arg); + lua_pushstring(globalconf.L, arg); + break; + case DBUS_TYPE_BOOLEAN: + dbus_message_iter_get_basic(&iter, &b); + lua_pushboolean(globalconf.L, b); + break; + case DBUS_TYPE_INT16: + case DBUS_TYPE_UINT16: + case DBUS_TYPE_INT32: + case DBUS_TYPE_UINT32: + case DBUS_TYPE_INT64: + case DBUS_TYPE_UINT64: + dbus_message_iter_get_basic(&iter, &i64); + lua_pushnumber(globalconf.L, i64); + break; + case DBUS_TYPE_DOUBLE: + dbus_message_iter_get_basic(&iter, &d); + lua_pushnumber(globalconf.L, d); + break; + default: + break; + } + i++; + } + while(dbus_message_iter_next(&iter)); + + lua_pcall(globalconf.L, i, 0, 0); + printf("pcall\n"); + +bailout: + for(i = 0; path[i]; i++) + p_delete(&path[i]); + p_delete(&path); +} + static void a_dbus_process_requests(EV_P_ ev_io *w, int revents) { DBusMessage *msg; int nmsg = 0; + const char *n; + ssize_t len; if(!dbus_connection && !a_dbus_init()) return; @@ -50,13 +169,37 @@ a_dbus_process_requests(EV_P_ ev_io *w, int revents) if(!(msg = dbus_connection_pop_message(dbus_connection))) break; - if(dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected")) { a_dbus_cleanup(); dbus_message_unref(msg); return; } + else + { + /* get the interface */ + n = dbus_message_get_interface(msg); + len = a_strlen(n); + + /* check destination: at least has sizeof(org.awesome.) + * and match org.awesome */ + if(len > 12 && !a_strncmp(n, "org.awesome", 11)) + { + /* n is now after at the end of 'org.awesome.' */ + n += 12; + + /* we assume that after the dot there's a class name, like + * widget, client, etc… */ + switch(a_tokenize(n, -1)) + { + case A_TK_CLIENT: + a_dbus_process_request_client(msg); + break; + default: + break; + } + } + } dbus_message_unref(msg);