awful.menu: add a menu for listing clients
[awesome.git] / dbus.c
blob7a406f7d32ccbae706a646fd96dc346c8f77039d
1 /*
2 * dbus.c - awesome dbus support
4 * Copyright © 2008 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "config.h"
23 #ifdef WITH_DBUS
25 #include <ev.h>
26 #include <dbus/dbus.h>
27 #include <unistd.h>
28 #include <fcntl.h>
30 #include "dbus.h"
31 #include "widget.h"
32 #include "client.h"
34 extern awesome_t globalconf;
36 static DBusError err;
37 static DBusConnection *dbus_connection = NULL;
38 ev_io dbusio = { .fd = -1 };
40 /** Check a dbus object path format and its number of element.
41 * \param path The path.
42 * \param nelem The number of element it should have.
43 * \return true if the path is ok, false otherwise.
45 static bool
46 a_dbus_path_check(char **path, int nelem)
48 int i;
50 for(i = 0; path[i]; i++);
51 if(i != nelem)
52 return false;
53 return (!a_strcmp(path[0], "org") && !a_strcmp(path[1], "awesome"));
56 static void
57 a_dbus_process_request_do(DBusMessage *msg)
59 int i;
60 DBusMessageIter iter;
61 char **path, *cmd;
63 if(!dbus_message_get_path_decomposed(msg, &path))
64 return;
66 /* path is:
67 * /org/awesome */
68 if(!a_dbus_path_check(path, 2))
69 goto bailout;
71 if(!dbus_message_iter_init(msg, &iter))
73 dbus_error_free(&err);
74 goto bailout;
76 else if(DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&iter))
78 dbus_error_free(&err);
79 goto bailout;
81 else
82 dbus_message_iter_get_basic(&iter, &cmd);
84 luaA_dostring(globalconf.L, cmd);
86 bailout:
87 for(i = 0; path[i]; i++)
88 p_delete(&path[i]);
89 p_delete(&path);
92 static void
93 a_dbus_process_requests(EV_P_ ev_io *w, int revents)
95 DBusMessage *msg;
96 int nmsg = 0;
98 if(!dbus_connection && !a_dbus_init())
99 return;
101 while(true)
103 dbus_connection_read_write(dbus_connection, 0);
105 if(!(msg = dbus_connection_pop_message(dbus_connection)))
106 break;
108 if(dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected"))
110 a_dbus_cleanup();
111 dbus_message_unref(msg);
112 return;
114 else if(dbus_message_is_method_call(msg, "org.awesome", "do"))
115 a_dbus_process_request_do(msg);
117 dbus_message_unref(msg);
119 nmsg++;
122 if(nmsg)
123 dbus_connection_flush(dbus_connection);
126 bool
127 a_dbus_init(void)
129 bool ret;
130 int fd;
132 dbus_error_init(&err);
134 dbus_connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
135 if(dbus_error_is_set(&err))
137 warn("DBus system bus connection failed: %s", err.message);
138 dbus_connection = NULL;
139 dbus_error_free(&err);
140 return false;
143 dbus_connection_set_exit_on_disconnect(dbus_connection, FALSE);
145 ret = dbus_bus_request_name(dbus_connection, "org.awesome", 0, &err);
147 if(dbus_error_is_set(&err))
149 warn("failed to request DBus name: %s", err.message);
150 a_dbus_cleanup();
151 return false;
154 if(ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
156 warn("not primary DBus name owner");
157 a_dbus_cleanup();
158 return false;
161 if(!dbus_connection_get_unix_fd(dbus_connection, &fd))
163 warn("cannot get DBus connection file descriptor");
164 a_dbus_cleanup();
165 return false;
168 fcntl(fd, F_SETFD, FD_CLOEXEC);
170 ev_io_init(&dbusio, a_dbus_process_requests, fd, EV_READ);
171 ev_io_start(EV_DEFAULT_UC_ &dbusio);
172 ev_unref(EV_DEFAULT_UC);
173 return true;
176 void
177 a_dbus_cleanup(void)
179 if(!dbus_connection)
180 return;
182 dbus_error_free(&err);
184 if (dbusio.fd >= 0) {
185 ev_ref(EV_DEFAULT_UC);
186 ev_io_stop(EV_DEFAULT_UC_ &dbusio);
187 dbusio.fd = -1;
190 /* This is a shared connection owned by libdbus
191 * Do not close it, only unref
193 dbus_connection_unref(dbus_connection);
194 dbus_connection = NULL;
197 #else /* HAVE_DBUS */
199 #include "dbus.h"
201 bool
202 a_dbus_init(void)
204 return false;
207 void
208 a_dbus_cleanup(void)
210 /* empty */
213 #endif
214 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80