commit 732d6b3d422839853a0d8f90d07f07886eca3480
parent 2fca804c5ebd83c043d890aedfa0f93e5002f3b9
Author: Sweets <Sweets@users.noreply.github.com>
Date: Sun, 13 Sep 2020 23:10:05 -0700
Major refactor
Diffstat:
M | Makefile | | | 2 | +- |
D | callbacks.c | | | 257 | ------------------------------------------------------------------------------- |
D | callbacks.h | | | 24 | ------------------------ |
A | output.c | | | 172 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | output.h | | | 25 | +++++++++++++++++++++++++ |
M | tiramisu.c | | | 97 | ++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------- |
M | tiramisu.h | | | 33 | +++++++++++++++++++++++++++++++++ |
7 files changed, 292 insertions(+), 318 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,6 +1,6 @@
TARGET = tiramisu
-SRC := tiramisu.c callbacks.c
+SRC := tiramisu.c output.c
PREFIX ?= /usr/local
diff --git a/callbacks.c b/callbacks.c
@@ -1,257 +0,0 @@
-#include <stdio.h>
-#include <glib.h>
-
-#include "tiramisu.h"
-#include "callbacks.h"
-
-unsigned int notification_id = 0;
-
-char *sanitize(const char *string) {
- /* allocating double the size of the original string should always be enough */
- char *out = calloc(strlen(string) * 2 + 1, 1);
-
- while (*string) {
- if (*string == '"')
- strcat(out, "\\\"");
- else if (*string == '\n')
- strcat(out, "\\n");
- else
- out[strlen(out)] = *string;
- string++;
- }
-
- return out;
-}
-
-void method_handler(GDBusConnection *connection, const gchar *sender,
- const gchar *object, const gchar *interface, const gchar *method,
- GVariant *parameters, GDBusMethodInvocation *invocation,
- gpointer user_data) {
-
- GVariantIter iterator;
- gchar *app_name;
- guint32 replaces_id;
- gchar *app_icon;
- gchar *summary;
- gchar *body;
- gchar **actions;
- GVariant *hints;
- gint32 timeout;
- GVariant *return_value = NULL;
-
- if (!strcmp(method, "Notify"))
- goto output;
-
- if (!strcmp(method, "GetServerInformation")) {
- return_value = g_variant_new("(ssss)",
- "tiramisu", "Sweets", "1.0", "1.2");
- goto flush;
- }
-
- print("Unhandled: %s %s\n", method, sender);
-
-output:
- notification_id++;
-
- g_variant_iter_init(&iterator, parameters);
- g_variant_iter_next(&iterator, "s", &app_name);
- g_variant_iter_next(&iterator, "u", &replaces_id);
- g_variant_iter_next(&iterator, "s", &app_icon);
- g_variant_iter_next(&iterator, "s", &summary);
- g_variant_iter_next(&iterator, "s", &body);
- g_variant_iter_next(&iterator, "^a&s", &actions);
- g_variant_iter_next(&iterator, "@a{sv}", &hints);
- g_variant_iter_next(&iterator, "i", &timeout);
-
- char *app_name_sanitized = sanitize(app_name);
- char *app_icon_sanitized = sanitize(app_icon);
- printf(
-#ifdef PRINT_JSON
- "{ \"app_name\": \"%s\", \"app_icon\": \"%s\", ",
-#else
- "app_name: %s\napp_icon: %s\n",
-#endif
- app_name_sanitized,
- app_icon_sanitized);
-
- free(app_name_sanitized);
- free(app_icon_sanitized);
- free(app_name);
- free(app_icon);
-
- printf(
-#ifdef PRINT_JSON
- "\"replaces_id\": \"%u\", \"timeout\": \"%d\", ",
-#else
- "replaces_id: %u\ntimeout: %d\n",
-#endif
- replaces_id, timeout);
-
-#ifdef PRINT_JSON
- printf("\"hints\": { ");
-#else
- printf("hints: ");
-#endif
-
- gchar *key;
- GVariant *value;
-
-#ifdef PRINT_JSON
- const char *int_format = "\"%s\": %d";
- const char *uint_format = "\"%s\": %u";
-#else
- const char *int_format = "\t%s: %d\n";
- const char *uint_format = "\t%s: %u\n";
-#endif
-
- unsigned int index = 0;
- g_variant_iter_init(&iterator, hints);
- while (g_variant_iter_loop(&iterator, "{sv}", &key, NULL)) {
-
-#ifdef PRINT_JSON
- if (index > 0)
- printf(", ");
-#endif
-
- /* There has to be a better way. glib, why? */
-
- if ((value = g_variant_lookup_value(hints, key, GT_STRING))) {
- char *value_sanitized = sanitize(g_variant_get_string(value, NULL));
- printf(
-#ifdef PRINT_JSON
- "\"%s\": \"%s\"",
-#else
- "\t%s: %s\n",
-#endif
- key, value_sanitized);
- free(value_sanitized);
- } else if ((value = g_variant_lookup_value(hints, key, GT_INT16)))
- printf(int_format, key, g_variant_get_int16(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_INT32)))
- printf(int_format, key, g_variant_get_int32(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_INT64)))
- printf(int_format, key, g_variant_get_int64(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_UINT16)))
- printf(uint_format, key, g_variant_get_uint16(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_UINT32)))
- printf(uint_format, key, g_variant_get_uint32(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_UINT64)))
- printf(uint_format, key, g_variant_get_uint64(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_DOUBLE)))
- printf(
-#ifdef PRINT_JSON
- "\"%s\": %f",
-#else
- "\t%s: %f\n",
-#endif
- key, g_variant_get_double(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_BYTE)))
- printf(
-#ifdef PRINT_JSON
- "\"%s\": %x",
-#else
- "\t%s: %x\n",
-#endif
- key, g_variant_get_byte(value));
- else if ((value = g_variant_lookup_value(hints, key, GT_BOOL)))
- printf(
-#ifdef PRINT_JSON
- "\"%s\": %d",
-#else
- "\t%s: %d\n",
-#endif
- key, g_variant_get_boolean(value));
-
- index++;
- g_variant_unref(value);
- }
-
- g_variant_unref(hints);
-
- index = 0;
-#ifdef PRINT_JSON
- printf("}, \"actions\": {");
-#else
- printf("actions: ");
-#endif
-
- while (actions[index] && actions[index + 1]) {
-#ifdef PRINT_JSON
- if (index > 0)
- printf(", ");
- printf("\"%s\": \"%s\"",
-#else
- printf("\t%s: %s\n",
-#endif
- actions[index + 1], actions[index]);
- index += 2;
- }
- free(actions);
-
- char *summary_sanitized = sanitize(summary);
- char *body_sanitized = sanitize(body);
- printf(
-#ifdef PRINT_JSON
- "}, \"summary\": \"%s\", \"body\": \"%s\" }\n",
-#else
- "summary: %s\nbody: %s\n",
-#endif
- summary_sanitized,
- body_sanitized);
- free(summary_sanitized);
- free(body_sanitized);
- free(summary);
- free(body);
-
- return_value = g_variant_new("(u)", notification_id);
-
- fflush(stdout);
-
- goto flush;
-
-flush:
- g_dbus_method_invocation_return_value(invocation, return_value);
- g_dbus_connection_flush(connection, NULL, NULL, NULL);
- return;
-
-}
-
-void bus_acquired(GDBusConnection *connection, const gchar *name,
- gpointer user_data) {
- print("%s\n", "Bus has been acquired.");
-
- guint registered_object;
- registered_object = g_dbus_connection_register_object(connection,
- "/org/freedesktop/Notifications",
- introspection->interfaces[0],
- &(const GDBusInterfaceVTable){ method_handler },
- NULL,
- NULL,
- NULL);
-
- if (!registered_object) {
- print("%s\n", "Unable to register.");
- stop_main_loop(NULL);
- }
-}
-
-void name_acquired(GDBusConnection *connection, const gchar *name,
- gpointer user_data) {
- dbus_connection = connection;
- print("%s\n", "Name has been acquired.");
-}
-
-void name_lost(GDBusConnection *connection, const gchar *name,
- gpointer user_data) {
- // we lost the Notifications daemon name or couldn't acquire it, shutdown
-
- if (!connection) {
- printf("%s; %s\n",
- "Unable to connect to acquire org.freedesktop.Notifications",
- "could not connect to dbus.");
- stop_main_loop(NULL);
- }
- else
- print("%s\n", "Successfully acquired org.freedesktop.Notifications");
-
-}
diff --git a/callbacks.h b/callbacks.h
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <gio/gio.h>
-#include <glib.h>
-
-#define GT_STRING G_VARIANT_TYPE_STRING
-#define GT_INT16 G_VARIANT_TYPE_INT16
-#define GT_INT32 G_VARIANT_TYPE_INT32
-#define GT_INT64 G_VARIANT_TYPE_INT64
-#define GT_UINT16 G_VARIANT_TYPE_UINT16
-#define GT_UINT32 G_VARIANT_TYPE_UINT32
-#define GT_UINT64 G_VARIANT_TYPE_UINT64
-#define GT_DOUBLE G_VARIANT_TYPE_DOUBLE
-#define GT_BOOL G_VARIANT_TYPE_BOOLEAN
-#define GT_BYTE G_VARIANT_TYPE_BYTE
-
-extern unsigned int notification_id;
-
-void method_handler(GDBusConnection*, const gchar*, const gchar*, const gchar*,
- const gchar*, GVariant*, GDBusMethodInvocation*, gpointer);
-
-void bus_acquired(GDBusConnection*, const gchar*, gpointer);
-void name_acquired(GDBusConnection*, const gchar*, gpointer);
-void name_lost(GDBusConnection*, const gchar*, gpointer);
diff --git a/output.c b/output.c
@@ -0,0 +1,172 @@
+#include <stdio.h>
+#include <glib.h>
+
+#include "tiramisu.h"
+#include "output.h"
+
+char *sanitize(const char *string) {
+ /* allocating double the size of the original string should be enough */
+ char *out = calloc(strlen(string) * 2 + 1, 1);
+
+ while (*string) {
+ if (*string == '"')
+ strcat(out, "\\\"");
+ else if (*string == '\n')
+ strcat(out, "\\n");
+ else
+ out[strlen(out)] = *string;
+ string++;
+ }
+
+ return out;
+}
+
+void output_notification(GVariant *parameters) {
+ GVariantIter iterator;
+ gchar *app_name;
+ guint32 replaces_id;
+ gchar *app_icon;
+ gchar *summary;
+ gchar *body;
+ gchar **actions;
+ GVariant *hints;
+ gint32 timeout;
+
+ g_variant_iter_init(&iterator, parameters);
+ g_variant_iter_next(&iterator, "s", &app_name);
+ g_variant_iter_next(&iterator, "u", &replaces_id);
+ g_variant_iter_next(&iterator, "s", &app_icon);
+ g_variant_iter_next(&iterator, "s", &summary);
+ g_variant_iter_next(&iterator, "s", &body);
+ g_variant_iter_next(&iterator, "^a&s", &actions);
+ g_variant_iter_next(&iterator, "@a{sv}", &hints);
+ g_variant_iter_next(&iterator, "i", &timeout);
+
+ char *app_name_sanitized = sanitize(app_name);
+ char *app_icon_sanitized = sanitize(app_icon);
+ char *summary_sanitized = sanitize(summary);
+ char *body_sanitized = sanitize(body);
+
+ json_output(app_name_sanitized, app_icon_sanitized, replaces_id, timeout,
+ hints, actions, summary_sanitized, body_sanitized);
+
+ free(app_name_sanitized);
+ free(app_icon_sanitized);
+ free(app_name);
+ free(app_icon);
+
+ free(actions);
+
+ free(summary);
+ free(body);
+ free(summary_sanitized);
+ free(body_sanitized);
+
+ fflush(stdout);
+}
+
+void hints_output_iterator(GVariant *hints, const char *str_format,
+ const char *int_format, const char *uint_format,
+ const char *double_format, const char *boolean_format,
+ const char *byte_format) {
+
+ GVariantIter iterator;
+ gchar *key;
+ GVariant *value;
+
+ unsigned int index = 0;
+ char *value_sanitized;
+
+ g_variant_iter_init(&iterator, hints);
+ while (g_variant_iter_loop(&iterator, "{sv}", &key, NULL)) {
+ if (index)
+ printf(", ");
+
+ /* Strings */
+ if ((value = g_variant_lookup_value(hints, key, GT_STRING))) {
+ value_sanitized = sanitize(g_variant_get_string(value, NULL));
+ printf(str_format, key, value_sanitized);
+ free(value_sanitized);
+ }
+ /* Integers */
+ else if ((value = g_variant_lookup_value(hints, key, GT_INT16)))
+ printf(int_format, key, g_variant_get_int16(value));
+ else if ((value = g_variant_lookup_value(hints, key, GT_INT32)))
+ printf(int_format, key, g_variant_get_int32(value));
+ else if ((value = g_variant_lookup_value(hints, key, GT_INT64)))
+ printf(int_format, key, g_variant_get_int64(value));
+ /* Unsigned integers */
+ else if ((value = g_variant_lookup_value(hints, key, GT_UINT16)))
+ printf(uint_format, key, g_variant_get_uint16(value));
+ else if ((value = g_variant_lookup_value(hints, key, GT_UINT32)))
+ printf(uint_format, key, g_variant_get_uint32(value));
+ else if ((value = g_variant_lookup_value(hints, key, GT_UINT64)))
+ printf(uint_format, key, g_variant_get_uint64(value));
+ /* Doubles */
+ else if ((value = g_variant_lookup_value(hints, key, GT_DOUBLE)))
+ printf(double_format, key, g_variant_get_double(value));
+ /* Bytes */
+ else if ((value = g_variant_lookup_value(hints, key, GT_BYTE)))
+ printf(byte_format, key, g_variant_get_byte(value));
+ /* Booleans */
+ else if ((value = g_variant_lookup_value(hints, key, GT_BOOL)))
+ printf(boolean_format, key, g_variant_get_boolean(value));
+
+ g_variant_unref(value);
+ index++;
+ }
+
+ g_variant_unref(hints);
+}
+
+void default_output(gchar *app_name, gchar *app_icon, guint32 replaces_id,
+ gint32 timeout, GVariant *hints, gchar **actions, gchar *summary,
+ gchar *body) {
+
+ printf("app_name: %s\napp_icon: %s\nreplaces_id: %u\ntimeout: %d\n",
+ app_name, app_icon, replaces_id, timeout);
+
+ printf("hints:\n");
+ hints_output_iterator(hints, "\t%s: %s\n", "\t%s: %d\n", "\t%s: %u",
+ "\t%s: %f\n", "\t%s: %x\n", "\t%s: %d\n");
+ printf("actions:\n");
+
+ unsigned int index = 0;
+ while (actions[index] && actions[index + 1]) {
+ printf("\t%s: %s\n", actions[index + 1], actions[index]);
+ index += 2;
+ }
+
+ printf("summary: %s\nbody: %s", summary, body);
+
+}
+
+void json_output(gchar *app_name, gchar *app_icon, guint32 replaces_id,
+ gint32 timeout, GVariant *hints, gchar **actions, gchar *summary,
+ gchar *body) {
+
+ printf("{"
+ "\"app_name\": \"%s\", "
+ "\"app_icon\": \"%s\", "
+ "\"replaces_id\": %u, "
+ "\"timeout\": %d, ",
+ app_name, app_icon, replaces_id, timeout);
+
+ printf("\"hints\": {");
+ hints_output_iterator(hints, "\"%s\": \"%s\"", "\"%s\": %d", "\"%s\": %u",
+ "\"%s\": %f", "\"%s\": %x", "\"%s\": %d");
+ printf("}, \"actions\": {");
+
+ unsigned int index = 0;
+ while (actions[index] && actions[index + 1]) {
+ if (index)
+ printf(", ");
+ printf("\"%s\": \"%s\"", actions[index + 1], actions[index]);
+ index += 2;
+ }
+
+ printf("}, ");
+ printf("\"summary\": \"%s\", "
+ "\"body\": \"%s\"}\n", summary, body);
+
+}
diff --git a/output.h b/output.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <gio/gio.h>
+#include <glib.h>
+
+#define GT_STRING G_VARIANT_TYPE_STRING
+#define GT_INT16 G_VARIANT_TYPE_INT16
+#define GT_INT32 G_VARIANT_TYPE_INT32
+#define GT_INT64 G_VARIANT_TYPE_INT64
+#define GT_UINT16 G_VARIANT_TYPE_UINT16
+#define GT_UINT32 G_VARIANT_TYPE_UINT32
+#define GT_UINT64 G_VARIANT_TYPE_UINT64
+#define GT_DOUBLE G_VARIANT_TYPE_DOUBLE
+#define GT_BOOL G_VARIANT_TYPE_BOOLEAN
+#define GT_BYTE G_VARIANT_TYPE_BYTE
+
+char *sanitize(const char*);
+
+void output_notification(GVariant*);
+void hints_output_iterator(GVariant*, const char*, const char*, const char*,
+ const char*, const char*, const char*);
+void default_output(gchar*, gchar*, guint32, gint32, GVariant*, gchar**, gchar*,
+ gchar*);
+void json_output(gchar*, gchar*, guint32, gint32, GVariant*, gchar**, gchar*,
+ gchar*);
diff --git a/tiramisu.c b/tiramisu.c
@@ -7,43 +7,13 @@
#include <glib-unix.h>
#include "tiramisu.h"
-#include "callbacks.h"
+#include "output.h"
#include "config.h"
GDBusConnection *dbus_connection = NULL;
GDBusNodeInfo *introspection = NULL;
GMainLoop *main_loop = NULL;
-
-/* Build introspection XML based on configuration */
-
-const char *xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- "<node name=\"/org/freedesktop/Notifications\">\n"
- " <interface name=\"org.freedesktop.Notifications\">\n"
-
- " <method name=\"Notify\">\n"
- " <arg direction=\"in\" type=\"s\" name=\"app_name\"/>\n"
- " <arg direction=\"in\" type=\"u\" name=\"replaces_id\"/>\n"
- " <arg direction=\"in\" type=\"s\" name=\"app_icon\"/>\n"
- " <arg direction=\"in\" type=\"s\" name=\"summary\"/>\n"
- " <arg direction=\"in\" type=\"s\" name=\"body\"/>\n"
- " <arg direction=\"in\" type=\"as\" name=\"actions\"/>\n"
- " <arg direction=\"in\" type=\"a{sv}\" name=\"hints\"/>\n"
- " <arg direction=\"in\" type=\"i\""
- " name=\"expire_timeout\"/>\n"
- " <arg direction=\"out\" type=\"u\""
- " name=\"id\"/>\n"
- " </method>\n"
-
-
- " <method name=\"GetServerInformation\">\n"
- " <arg direction=\"out\" type=\"s\" name=\"name\"/>\n"
- " <arg direction=\"out\" type=\"s\" name=\"vendor\"/>\n"
- " <arg direction=\"out\" type=\"s\" name=\"version\"/>\n"
- " <arg direction=\"out\" type=\"s\" name=\"spec_version\"/>\n"
- " </method>\n"
-
- " </interface>\n"
- "</node>";
+unsigned int notification_id = 0;
gboolean stop_main_loop(gpointer user_data) {
g_main_loop_quit(main_loop);
@@ -56,13 +26,13 @@ int main(int argc, char **argv) {
/* Connect to DBUS */
- introspection = g_dbus_node_info_new_for_xml(xml, NULL);
+ introspection = g_dbus_node_info_new_for_xml(INTROSPECTION_XML, NULL);
owned_name = g_bus_own_name(G_BUS_TYPE_SESSION,
"org.freedesktop.Notifications",
G_BUS_NAME_OWNER_FLAGS_NONE,
- (GBusAcquiredCallback)bus_acquired, /* bus_acquired_handler */
- (GBusNameAcquiredCallback)name_acquired, /* name_acquired_handler */
- (GBusNameLostCallback)name_lost, /* name_lost_handler */
+ (GBusAcquiredCallback)bus_acquired,
+ (GBusNameAcquiredCallback)name_acquired,
+ (GBusNameLostCallback)name_lost,
NULL, /* user_data */
NULL); /* user_data_free_func */
@@ -83,3 +53,58 @@ int main(int argc, char **argv) {
g_bus_unown_name(owned_name);
}
+
+void bus_acquired(GDBusConnection *connection, const gchar *name,
+ gpointer user_data) {
+ print("%s\n", "Bus has been acquired.");
+
+ guint registered_object = g_dbus_connection_register_object(connection,
+ "/org/freedesktop/Notifications", introspection->interfaces[0],
+ &(const GDBusInterfaceVTable){ method_handler }, NULL, NULL, NULL);
+
+ if (!registered_object) {
+ print("%s\n", "Unable to register.");
+ stop_main_loop(NULL);
+ }
+}
+
+void name_acquired(GDBusConnection *connection, const gchar *name,
+ gpointer user_data) {
+ dbus_connection = connection;
+ print("%s\n", "Name has been acquired.");
+}
+
+void name_lost(GDBusConnection *connection, const gchar *name,
+ gpointer user_data) {
+ // we lost the Notifications daemon name or couldn't acquire it, shutdown
+
+ if (!connection) {
+ printf("%s; %s\n",
+ "Unable to connect to acquire org.freedesktop.Notifications",
+ "could not connect to dbus.");
+ stop_main_loop(NULL);
+ }
+ else
+ print("%s\n", "Successfully acquired org.freedesktop.Notifications");
+}
+
+void method_handler(GDBusConnection *connection, const gchar *sender,
+ const gchar *object, const gchar *interface, const gchar *label,
+ GVariant *parameters, GDBusMethodInvocation *invocation,
+ gpointer user_data) {
+
+ GVariant *return_value = NULL;
+
+ if (!strcmp(label, "GetServerInformation"))
+ return_value = g_variant_new("(ssss)",
+ "tiramisu", "Sweets", "1.0", "1.2");
+ else if (!strcmp(label, "Notify")) {
+ output_notification(parameters);
+ return_value = g_variant_new("(u)", ++notification_id);
+ } else
+ print("Unhandled: %s %s\n", label, sender);
+
+ g_dbus_method_invocation_return_value(invocation, return_value);
+ g_dbus_connection_flush(connection, NULL, NULL, NULL);
+
+}
diff --git a/tiramisu.h b/tiramisu.h
@@ -12,10 +12,43 @@ extern GDBusConnection *dbus_connection;
extern GDBusNodeInfo *introspection;
extern GMainLoop *main_loop;
+extern unsigned int notification_id;
+
#ifdef DEBUG
#define print(...) fprintf(stderr, __VA_ARGS__);
#else
#define print(...) (void)(__VA_ARGS__);
#endif
+#define INTROSPECTION_XML "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"\
+ "<node name=\"/org/freedesktop/Notifications\">\n"\
+ " <interface name=\"org.freedesktop.Notifications\">\n"\
+ " <method name=\"Notify\">\n"\
+ " <arg direction=\"in\" type=\"s\" name=\"app_name\"/>\n"\
+ " <arg direction=\"in\" type=\"u\""\
+ " name=\"replaces_id\"/>\n"\
+ " <arg direction=\"in\" type=\"s\" name=\"app_icon\"/>\n"\
+ " <arg direction=\"in\" type=\"s\" name=\"summary\"/>\n"\
+ " <arg direction=\"in\" type=\"s\" name=\"body\"/>\n"\
+ " <arg direction=\"in\" type=\"as\" name=\"actions\"/>\n"\
+ " <arg direction=\"in\" type=\"a{sv}\" name=\"hints\"/>\n"\
+ " <arg direction=\"in\" type=\"i\""\
+ " name=\"expire_timeout\"/>\n"\
+ " <arg direction=\"out\" type=\"u\""\
+ " name=\"id\"/>\n"\
+ " </method>\n"\
+ " <method name=\"GetServerInformation\">\n"\
+ " <arg direction=\"out\" type=\"s\" name=\"name\"/>\n"\
+ " <arg direction=\"out\" type=\"s\" name=\"vendor\"/>\n"\
+ " <arg direction=\"out\" type=\"s\" name=\"version\"/>\n"\
+ " <arg direction=\"out\" type=\"s\" name=\"spec_version\"/>\n"\
+ " </method>\n"\
+ " </interface>\n"\
+ "</node>"
+
gboolean stop_main_loop(gpointer);
+void bus_acquired(GDBusConnection*, const gchar*, gpointer);
+void name_acquired(GDBusConnection*, const gchar*, gpointer);
+void name_lost(GDBusConnection*, const gchar*, gpointer);
+void method_handler(GDBusConnection*, const gchar*, const gchar*, const gchar*,
+ const gchar*, GVariant*, GDBusMethodInvocation*, gpointer);