diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 157 |
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; +} + |