implement more app list IPC code
[ladish.git] / gui / app_supervisor_proxy.c
blob3531ca176526e0d947d8ffc71a9ea0e0ec8552fe
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*
3 * LADI Session Handler (ladish)
5 * Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
7 **************************************************************************
8 * This file contains implementation of code that interfaces
9 * app supervisor object through D-Bus
10 **************************************************************************
12 * LADI Session Handler is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * LADI Session Handler is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with LADI Session Handler. If not, see <http://www.gnu.org/licenses/>
24 * or write to the Free Software Foundation, Inc.,
25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "app_supervisor_proxy.h"
29 #include "../dbus/helpers.h"
30 #include "../dbus_constants.h"
32 struct ladish_app_supervisor_proxy
34 char * service;
35 char * object;
36 uint64_t version;
38 void * context;
39 void (* app_added)(void * context, uint64_t id, const char * name, bool running, bool terminal, uint8_t level);
40 void (* app_removed)(void * context, uint64_t id);
43 static const char * g_signals[] =
45 "AppAdded",
46 "AppRemoved",
47 "AppStateChanged",
48 NULL
51 #define proxy_ptr ((struct ladish_app_supervisor_proxy *)proxy)
53 static
54 DBusHandlerResult
55 message_hook(
56 DBusConnection * connection,
57 DBusMessage * message,
58 void * proxy)
60 const char * object_path;
61 uint64_t new_list_version;
62 uint64_t id;
63 const char * name;
64 dbus_bool_t running;
65 dbus_bool_t terminal;
66 uint8_t level;
68 object_path = dbus_message_get_path(message);
69 if (object_path == NULL || strcmp(object_path, proxy_ptr->object) != 0)
71 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
74 if (dbus_message_is_signal(message, IFACE_APP_SUPERVISOR, "AppAdded"))
76 if (!dbus_message_get_args(
77 message,
78 &g_dbus_error,
79 DBUS_TYPE_UINT64, &new_list_version,
80 DBUS_TYPE_UINT64, &id,
81 DBUS_TYPE_STRING, &name,
82 DBUS_TYPE_BOOLEAN, &running,
83 DBUS_TYPE_BOOLEAN, &terminal,
84 DBUS_TYPE_BYTE, &level,
85 DBUS_TYPE_INVALID))
87 log_error("dbus_message_get_args() failed to extract AppAdded signal arguments (%s)", g_dbus_error.message);
88 dbus_error_free(&g_dbus_error);
89 return DBUS_HANDLER_RESULT_HANDLED;
92 //log_info("AppAdded signal received. id=%"PRIu64", name='%s', %srunning, %s, level %u", id, name, running ? "" : "not ", terminal ? "terminal" : "shell", (unsigned int)level);
93 proxy_ptr->app_added(proxy_ptr->context, id, name, running, terminal, level);
94 return DBUS_HANDLER_RESULT_HANDLED;
97 if (dbus_message_is_signal(message, IFACE_APP_SUPERVISOR, "AppRemoved"))
99 if (!dbus_message_get_args(
100 message,
101 &g_dbus_error,
102 DBUS_TYPE_UINT64, &new_list_version,
103 DBUS_TYPE_UINT64, &id,
104 DBUS_TYPE_INVALID))
106 log_error("dbus_message_get_args() failed to extract AppRemoved signal arguments (%s)", g_dbus_error.message);
107 dbus_error_free(&g_dbus_error);
108 return DBUS_HANDLER_RESULT_HANDLED;
111 //log_info("AppRemoved signal received, id=%"PRIu64, id);
112 proxy_ptr->app_removed(proxy_ptr->context, id);
113 return DBUS_HANDLER_RESULT_HANDLED;
116 if (dbus_message_is_signal(message, IFACE_APP_SUPERVISOR, "AppStateChanged"))
118 if (!dbus_message_get_args(
119 message,
120 &g_dbus_error,
121 DBUS_TYPE_UINT64, &new_list_version,
122 DBUS_TYPE_UINT64, &id,
123 DBUS_TYPE_STRING, &name,
124 DBUS_TYPE_BOOLEAN, &running,
125 DBUS_TYPE_BOOLEAN, &terminal,
126 DBUS_TYPE_BYTE, &level,
127 DBUS_TYPE_INVALID))
129 log_error("dbus_message_get_args() failed to extract AppStateChanged signal arguments (%s)", g_dbus_error.message);
130 dbus_error_free(&g_dbus_error);
131 return DBUS_HANDLER_RESULT_HANDLED;
134 log_info("AppStateChanged signal received");
135 return DBUS_HANDLER_RESULT_HANDLED;
138 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
141 #undef proxy_ptr
143 static void refresh_internal(struct ladish_app_supervisor_proxy * proxy_ptr, bool force)
145 DBusMessage* reply_ptr;
146 DBusMessageIter iter;
147 dbus_uint64_t version;
148 const char * reply_signature;
149 DBusMessageIter array_iter;
150 DBusMessageIter struct_iter;
151 uint64_t id;
152 const char * name;
153 dbus_bool_t running;
154 dbus_bool_t terminal;
155 uint8_t level;
157 log_info("refresh_internal() called");
159 version = proxy_ptr->version;
161 if (!dbus_call(proxy_ptr->service, proxy_ptr->object, IFACE_APP_SUPERVISOR, "GetAll", "t", &version, NULL, &reply_ptr))
163 log_error("GetAll() failed.");
164 return;
167 reply_signature = dbus_message_get_signature(reply_ptr);
169 if (strcmp(reply_signature, "ta(tsbby)") != 0)
171 log_error("GetAll() reply signature mismatch. '%s'", reply_signature);
172 goto unref;
175 dbus_message_iter_init(reply_ptr, &iter);
177 //log_info_msg("version " + (char)dbus_message_iter_get_arg_type(&iter));
178 dbus_message_iter_get_basic(&iter, &version);
179 dbus_message_iter_next(&iter);
181 if (!force && version <= proxy_ptr->version)
183 goto unref;
186 //log_info("got new list version %llu", (unsigned long long)version);
187 proxy_ptr->version = version;
189 for (dbus_message_iter_recurse(&iter, &array_iter);
190 dbus_message_iter_get_arg_type(&array_iter) != DBUS_TYPE_INVALID;
191 dbus_message_iter_next(&array_iter))
193 dbus_message_iter_recurse(&array_iter, &struct_iter);
195 dbus_message_iter_get_basic(&struct_iter, &id);
196 dbus_message_iter_next(&struct_iter);
198 dbus_message_iter_get_basic(&struct_iter, &name);
199 dbus_message_iter_next(&struct_iter);
201 dbus_message_iter_get_basic(&struct_iter, &running);
202 dbus_message_iter_next(&struct_iter);
204 dbus_message_iter_get_basic(&struct_iter, &terminal);
205 dbus_message_iter_next(&struct_iter);
207 dbus_message_iter_get_basic(&struct_iter, &level);
208 dbus_message_iter_next(&struct_iter);
210 //log_info("App id=%"PRIu64", name='%s', %srunning, %s, level %u", id, name, running ? "" : "not ", terminal ? "terminal" : "shell", (unsigned int)level);
211 proxy_ptr->app_added(proxy_ptr->context, id, name, running, terminal, level);
213 dbus_message_iter_next(&struct_iter);
216 unref:
217 dbus_message_unref(reply_ptr);
220 bool
221 ladish_app_supervisor_proxy_create(
222 const char * service,
223 const char * object,
224 void * context,
225 void (* app_added)(void * context, uint64_t id, const char * name, bool running, bool terminal, uint8_t level),
226 void (* app_removed)(void * context, uint64_t id),
227 ladish_app_supervisor_proxy_handle * handle_ptr)
229 struct ladish_app_supervisor_proxy * proxy_ptr;
231 proxy_ptr = malloc(sizeof(struct ladish_app_supervisor_proxy));
232 if (proxy_ptr == NULL)
234 log_error("malloc() failed to allocate struct proxy");
235 goto fail;
238 proxy_ptr->service = strdup(service);
239 if (proxy_ptr->service == NULL)
241 log_error("strdup() failed too duplicate service name '%s'", service);
242 goto free_proxy;
245 proxy_ptr->object = strdup(object);
246 if (proxy_ptr->object == NULL)
248 log_error("strdup() failed too duplicate object name '%s'", object);
249 goto free_service;
252 proxy_ptr->version = 0;
254 proxy_ptr->context = context;
255 proxy_ptr->app_added = app_added;
256 proxy_ptr->app_removed = app_removed;
258 if (!dbus_register_object_signal_handler(
259 g_dbus_connection,
260 proxy_ptr->service,
261 proxy_ptr->object,
262 IFACE_APP_SUPERVISOR,
263 g_signals,
264 message_hook,
265 proxy_ptr))
267 return false;
270 refresh_internal(proxy_ptr, true);
272 *handle_ptr = (ladish_app_supervisor_proxy_handle)proxy_ptr;
274 return true;
276 free_service:
277 free(proxy_ptr->service);
279 free_proxy:
280 free(proxy_ptr);
282 fail:
283 return false;
286 #define proxy_ptr ((struct ladish_app_supervisor_proxy *)proxy)
288 void ladish_app_supervisor_proxy_destroy(ladish_app_supervisor_proxy_handle proxy)
290 dbus_unregister_object_signal_handler(
291 g_dbus_connection,
292 proxy_ptr->service,
293 proxy_ptr->object,
294 IFACE_APP_SUPERVISOR,
295 g_signals,
296 message_hook,
297 proxy_ptr);
299 free(proxy_ptr->object);
300 free(proxy_ptr->service);
301 free(proxy_ptr);
304 bool ladish_app_supervisor_proxy_run_custom(ladish_app_supervisor_proxy_handle proxy, const char * command, const char * name, bool run_in_terminal)
306 dbus_bool_t terminal;
307 if (!dbus_call(proxy_ptr->service, proxy_ptr->object, IFACE_APP_SUPERVISOR, "RunCustom", "bss", &terminal, &command, &name, ""))
309 log_error("RunCustom() failed.");
310 return false;
313 return true;
316 #undef proxy_ptr