xembed: make xembed_info_get() asynchronous
[awesome.git] / dbus.c
bloba89e4d3e9088f307d3beb75ed0349e5682f3491b
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>
28 #include "dbus.h"
29 #include "widget.h"
30 #include "client.h"
32 extern awesome_t globalconf;
34 static DBusError err;
35 static DBusConnection *dbus_connection = NULL;
36 ev_io dbusio = { .fd = -1 };
38 /** Check a dbus object path format and its number of element.
39 * \param path The path.
40 * \param nelem The number of element it should have.
41 * \return true if the path is ok, false otherwise.
43 static bool
44 a_dbus_path_check(char **path, int nelem)
46 int i;
48 for(i = 0; path[i]; i++);
49 if(i != nelem)
50 return false;
51 return (!a_strcmp(path[0], "org") && !a_strcmp(path[1], "awesome"));
54 static void
55 a_dbus_process_request_do(DBusMessage *msg)
57 int i;
58 DBusMessageIter iter;
59 char **path, *cmd;
61 if(!dbus_message_get_path_decomposed(msg, &path))
62 return;
64 /* path is:
65 * /org/awesome */
66 if(!a_dbus_path_check(path, 2))
67 goto bailout;
69 if(!dbus_message_iter_init(msg, &iter))
71 dbus_error_free(&err);
72 goto bailout;
74 else if(DBUS_TYPE_STRING != dbus_message_iter_get_arg_type(&iter))
76 dbus_error_free(&err);
77 goto bailout;
79 else
80 dbus_message_iter_get_basic(&iter, &cmd);
82 luaA_dostring(globalconf.L, cmd);
84 bailout:
85 for(i = 0; path[i]; i++)
86 p_delete(&path[i]);
87 p_delete(&path);
90 static void
91 a_dbus_process_requests(EV_P_ ev_io *w, int revents)
93 DBusMessage *msg;
94 int nmsg = 0;
96 if(!dbus_connection && !a_dbus_init())
97 return;
99 while(true)
101 dbus_connection_read_write(dbus_connection, 0);
103 if(!(msg = dbus_connection_pop_message(dbus_connection)))
104 break;
106 if(dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected"))
108 a_dbus_cleanup();
109 dbus_message_unref(msg);
110 return;
112 else if(dbus_message_is_method_call(msg, "org.awesome", "do"))
113 a_dbus_process_request_do(msg);
115 dbus_message_unref(msg);
117 nmsg++;
120 if(nmsg)
121 dbus_connection_flush(dbus_connection);
124 bool
125 a_dbus_init(void)
127 bool ret;
128 int fd;
130 dbus_error_init(&err);
132 dbus_connection = dbus_bus_get(DBUS_BUS_SESSION, &err);
133 if(dbus_error_is_set(&err))
135 warn("DBus system bus connection failed: %s", err.message);
136 dbus_connection = NULL;
137 dbus_error_free(&err);
138 return false;
141 dbus_connection_set_exit_on_disconnect(dbus_connection, FALSE);
143 ret = dbus_bus_request_name(dbus_connection, "org.awesome", 0, &err);
145 if(dbus_error_is_set(&err))
147 warn("failed to request DBus name: %s", err.message);
148 a_dbus_cleanup();
149 return false;
152 if(ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
154 warn("not primary DBus name owner");
155 a_dbus_cleanup();
156 return false;
159 if(!dbus_connection_get_unix_fd(dbus_connection, &fd))
161 warn("cannot get DBus connection file descriptor");
162 a_dbus_cleanup();
163 return false;
166 ev_io_init(&dbusio, a_dbus_process_requests, fd, EV_READ);
167 ev_io_start(EV_DEFAULT_UC_ &dbusio);
168 ev_unref(EV_DEFAULT_UC);
169 return true;
172 void
173 a_dbus_cleanup(void)
175 if(!dbus_connection)
176 return;
178 dbus_error_free(&err);
180 if (dbusio.fd >= 0) {
181 ev_ref(EV_DEFAULT_UC);
182 ev_io_stop(EV_DEFAULT_UC_ &dbusio);
183 dbusio.fd = -1;
186 /* This is a shared connection owned by libdbus
187 * Do not close it, only unref
189 dbus_connection_unref(dbus_connection);
190 dbus_connection = NULL;
193 #else /* HAVE_DBUS */
195 #include "dbus.h"
197 bool
198 a_dbus_init(void)
200 return false;
203 void
204 a_dbus_cleanup(void)
206 /* empty */
209 #endif
210 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80