summaryrefslogtreecommitdiff
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..ba9ebed
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,157 @@
+#include "global.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+
+DBusConnection *dbuscon;
+
+#define BUS_NAME "net.blicky.dbustest"
+
+
+
+/* dbus <-> libev IO watchers */
+
+struct dbusev_io { ev_io io; DBusWatch *w; };
+
+static void dbusev_io(ev_io *io, int revents) {
+ printf("io f=%d\n", revents);
+ dbus_watch_handle(((struct dbusev_io *)io)->w, (revents & EV_READ ? DBUS_WATCH_READABLE : 0) | (revents & EV_WRITE ? DBUS_WATCH_WRITABLE : 0));
+}
+
+
+static void dbusev_watchtoggle(DBusWatch *w, void *data) {
+ printf("watchtoggle en=%d, fd=%d, f=%d\n", dbus_watch_get_enabled(w), dbus_watch_get_unix_fd(w), dbus_watch_get_flags(w));
+ ev_io *io = dbus_watch_get_data(w);
+ if(dbus_watch_get_enabled(w)) {
+ int f = dbus_watch_get_flags(w);
+ ev_io_set(io, dbus_watch_get_unix_fd(w), (f & DBUS_WATCH_READABLE ? EV_READ : 0) | (f & DBUS_WATCH_WRITABLE ? EV_WRITE : 0));
+ ev_io_start(io);
+ } else
+ ev_io_stop(io);
+}
+
+
+static dbus_bool_t dbusev_addwatch(DBusWatch *w, void *data) {
+ printf("addwatch\n");
+ ev_io *io = malloc(sizeof(struct dbusev_io));
+ if(!io)
+ return FALSE;
+ ((struct dbusev_io *)io)->w = w;
+ dbus_watch_set_data(w, io, NULL);
+ ev_init(io, dbusev_io);
+ dbusev_watchtoggle(w, data);
+ return TRUE;
+}
+
+
+static void dbusev_removewatch(DBusWatch *w, void *data) {
+ printf("removewatch\n");
+ ev_io *io = dbus_watch_get_data(w);
+ ev_io_stop(io);
+ free(io);
+}
+
+
+
+/* dbus <-> libev timeout functions */
+
+struct dbusev_timer { ev_timer timer; DBusTimeout *t; };
+
+static void dbusev_timer(ev_timer *timer, int revents) {
+ dbus_timeout_handle(((struct dbusev_timer *)timer)->t);
+}
+
+
+static void dbusev_timeouttoggle(DBusTimeout *t, void *data) {
+ printf("timeouttoggle\n");
+ ev_timer *timer = dbus_timeout_get_data(t);
+ if(dbus_timeout_get_enabled(t)) {
+ timer->repeat = ((ev_tstamp)dbus_timeout_get_interval(t))/1000.0;
+ ev_timer_again(timer);
+ } else
+ ev_timer_stop(timer);
+}
+
+
+static dbus_bool_t dbusev_addtimeout(DBusTimeout *t, void *data) {
+ printf("addtimeout\n");
+ ev_timer *timer = malloc(sizeof(struct dbusev_timer));
+ if(!timer)
+ return FALSE;
+ ((struct dbusev_timer *)timer)->t = t;
+ dbus_timeout_set_data(t, timer, NULL);
+ ev_init(timer, dbusev_timer);
+ dbusev_timeouttoggle(t, data);
+ return TRUE;
+}
+
+
+static void dbusev_removetimeout(DBusTimeout *t, void *data) {
+ printf("removetimeout\n");
+ ev_timer *timer = dbus_timeout_get_data(t);
+ ev_timer_stop(timer);
+ free(timer);
+}
+
+
+
+/* dbus <-> libev dispatch handling */
+
+static void dbusev_dispatch(ev_idle *idl, int revents) {
+ if(dbus_connection_dispatch(dbuscon) == DBUS_DISPATCH_COMPLETE)
+ ev_idle_stop(idl);
+}
+
+
+static void dbusev_dispatchstatus(DBusConnection *con, DBusDispatchStatus s, void *data) {
+ printf("dispatchstatus = %d\n", s);
+ static ev_idle *idl = NULL;
+ if(!idl) {
+ idl = malloc(sizeof(ev_idle));
+ ev_idle_init(idl, dbusev_dispatch);
+ }
+ ev_idle_start(idl);
+}
+
+
+
+/* Creates a dbus connection, requests (or rather, requires) our BUS_NAME and
+ * sets the connection up for use with libev. Exits on error. */
+static void init_dbus() {
+ DBusError err;
+ dbus_error_init(&err);
+
+ dbuscon = dbus_bus_get(DBUS_BUS_STARTER, &err);
+ if(dbus_error_is_set(&err)) {
+ printf("Failed to connect to the bus: %s\n", err.message);
+ exit(1);
+ }
+
+ int ret = dbus_bus_request_name(dbuscon, BUS_NAME, DBUS_NAME_FLAG_DO_NOT_QUEUE, &err);
+ if(dbus_error_is_set(&err) || ret == DBUS_REQUEST_NAME_REPLY_EXISTS) {
+ printf("Failed to acquire dbus name: %s\n", dbus_error_is_set(&err) ? err.message : "Name already taken");
+ exit(1);
+ }
+
+ dbus_connection_set_watch_functions(dbuscon, dbusev_addwatch, dbusev_removewatch, dbusev_watchtoggle, NULL, NULL);
+ dbus_connection_set_timeout_functions(dbuscon, dbusev_addtimeout, dbusev_removetimeout, dbusev_timeouttoggle, NULL, NULL);
+ dbus_connection_set_dispatch_status_function(dbuscon, dbusev_dispatchstatus, NULL, NULL);
+}
+
+
+
+int main(int argc, char **argv) {
+ ev_default_loop(0);
+ init_dbus();
+
+ /* Make sure to dispatch() before entering the main loop, we may have missed
+ * a dispatchstatus update while initializing. */
+ while(dbus_connection_dispatch(dbuscon) != DBUS_DISPATCH_COMPLETE)
+ ;
+
+ ev_run(0);
+
+ return 0;
+}
+