diff options
-rw-r--r-- | clockwatcher.c | 10 | ||||
-rw-r--r-- | gps.h | 7 | ||||
-rw-r--r-- | gpxlogger.c | 8 | ||||
-rw-r--r-- | libgps_dbus.c | 70 |
4 files changed, 63 insertions, 32 deletions
diff --git a/clockwatcher.c b/clockwatcher.c index a7ff2f72..56e07fd3 100644 --- a/clockwatcher.c +++ b/clockwatcher.c @@ -66,7 +66,12 @@ static void quit_handler(int signum) static int dbus_mainloop(void) { - return gps_dbus_open(conditionally_log_fix, &gpsdata);; + int s; + if ((s = gps_dbus_open(&gpsdata)) == 0) { + gps_dbus_stream(&gpsdata, 0, conditionally_log_fix); + gps_dbus_mainloop(); + } + return s; } #endif /* defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S) */ @@ -148,8 +153,7 @@ static int shm_mainloop(void) * **************************************************************************/ -struct method_t -{ +struct method_t{ const char *name; int (*method)(void); const char *description; @@ -1742,10 +1742,14 @@ extern int gps_sock_stream(struct gps_data_t *, unsigned int, /*@null@*/void *); extern const char /*@observer@*/ *gps_sock_data(const struct gps_data_t *); extern void gps_shm_close(struct gps_data_t *); -extern void libgps_trace(int errlevel, const char *, ...); +extern int gps_dbus_open(struct gps_data_t *); +extern int gps_dbus_stream(struct gps_data_t *, unsigned int, /*@null@*/void *); +extern void gps_dbus_mainloop(void); /* dependencies on struct gpsdata_t end hrere */ +extern void libgps_trace(int errlevel, const char *, ...); + extern void gps_clear_fix(/*@ out @*/struct gps_fix_t *); extern void gps_clear_dop( /*@out@*/ struct dop_t *); extern void gps_merge_fix(/*@ out @*/struct gps_fix_t *, @@ -1754,7 +1758,6 @@ extern void gps_merge_fix(/*@ out @*/struct gps_fix_t *, extern void gps_enable_debug(int, FILE *); extern /*@observer@*/const char *gps_maskdump(gps_mask_t); -extern int gps_dbus_open(void (*)(struct gps_data_t *), struct gps_data_t *); extern double safe_atof(const char *); extern time_t mkgmtime(register struct tm *); diff --git a/gpxlogger.c b/gpxlogger.c index d0032150..60ce409c 100644 --- a/gpxlogger.c +++ b/gpxlogger.c @@ -191,8 +191,14 @@ static void quit_handler(int signum) static int dbus_mainloop(void) { + int s; + print_gpx_header(); - return gps_dbus_open(conditionally_log_fix, &gpsdata); + if ((s = gps_dbus_open(&gpsdata)) == 0) { + gps_dbus_stream(&gpsdata, 0, conditionally_log_fix); + gps_dbus_mainloop(); + } + return 0; } #endif /* defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S) */ diff --git a/libgps_dbus.c b/libgps_dbus.c index 3c05705d..5e124f32 100644 --- a/libgps_dbus.c +++ b/libgps_dbus.c @@ -30,8 +30,14 @@ struct privdata_t #include <glib/gprintf.h> -DBusConnection *connection; - +/* + * Unpleasant that we have to declare a static context pointer here - means + * you can't have multiple DBUS sessions open (not that this matters + * much in practice). The problem is the DBUS API lacks some hook + * arguments that it ought to have. + */ +static struct gps_data_t *share_gpsdata; +static DBusConnection *connection; static char gpsd_devname[BUFSIZ]; static DBusHandlerResult handle_gps_fix(DBusMessage * message) @@ -39,35 +45,33 @@ static DBusHandlerResult handle_gps_fix(DBusMessage * message) DBusError error; /* this packet format was designed before we split eph */ double eph; - struct gps_data_t gpsdata; dbus_error_init(&error); - (void)memset(&gpsdata, '\0', sizeof(gpsdata)); dbus_message_get_args(message, &error, - DBUS_TYPE_DOUBLE, &gpsdata.fix.time, - DBUS_TYPE_INT32, &gpsdata.fix.mode, - DBUS_TYPE_DOUBLE, &gpsdata.fix.ept, - DBUS_TYPE_DOUBLE, &gpsdata.fix.latitude, - DBUS_TYPE_DOUBLE, &gpsdata.fix.longitude, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.time, + DBUS_TYPE_INT32, &share_gpsdata->fix.mode, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.ept, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.latitude, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.longitude, DBUS_TYPE_DOUBLE, &eph, - DBUS_TYPE_DOUBLE, &gpsdata.fix.altitude, - DBUS_TYPE_DOUBLE, &gpsdata.fix.epv, - DBUS_TYPE_DOUBLE, &gpsdata.fix.track, - DBUS_TYPE_DOUBLE, &gpsdata.fix.epd, - DBUS_TYPE_DOUBLE, &gpsdata.fix.speed, - DBUS_TYPE_DOUBLE, &gpsdata.fix.eps, - DBUS_TYPE_DOUBLE, &gpsdata.fix.climb, - DBUS_TYPE_DOUBLE, &gpsdata.fix.epc, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.altitude, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.epv, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.track, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.epd, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.speed, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.eps, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.climb, + DBUS_TYPE_DOUBLE, &share_gpsdata->fix.epc, DBUS_TYPE_STRING, &gpsd_devname, DBUS_TYPE_INVALID); - if (gpsdata.fix.mode > MODE_NO_FIX ) - gpsdata.status = STATUS_FIX; + if (share_gpsdata->fix.mode > MODE_NO_FIX ) + share_gpsdata->status = STATUS_FIX; else - gpsdata.status = STATUS_NO_FIX; + share_gpsdata->status = STATUS_NO_FIX; - PRIVATE(&gpsdata)->handler(&gpsdata); + PRIVATE(share_gpsdata)->handler(share_gpsdata); return DBUS_HANDLER_RESULT_HANDLED; } @@ -90,15 +94,13 @@ static DBusHandlerResult signal_handler(DBusConnection * connection, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -int gps_dbus_open(void (*handler)(struct gps_data_t *), struct gps_data_t *gpsdata) +int gps_dbus_open(struct gps_data_t *gpsdata) { - GMainLoop *mainloop; DBusError error; gpsdata->privdata = (void *)malloc(sizeof(struct privdata_t)); if (gpsdata->privdata == NULL) return -1; - PRIVATE(gpsdata)->handler = handler; dbus_error_init(&error); connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); @@ -121,11 +123,27 @@ int gps_dbus_open(void (*handler)(struct gps_data_t *), struct gps_data_t *gpsda return 5; } - /* This probably needs to be factored out */ + share_gpsdata = gpsdata; + return 0; +} + +int gps_dbus_stream(struct gps_data_t *unused UNUSED, + unsigned int flags UNUSED, + /*@null@*/ void *handler) +{ + /* must refer to the static context here */ + PRIVATE(share_gpsdata)->handler = (void (*)(struct gps_data_t *))handler; + return 0; +} + +void gps_dbus_mainloop(void) +/* run a DBUS main loop with a specified handler */ +{ + GMainLoop *mainloop; + mainloop = g_main_loop_new(NULL, FALSE); dbus_connection_setup_with_g_main(connection, NULL); g_main_loop_run(mainloop); - return 0; } #endif /* defined(DBUS_EXPORT_ENABLE) && !defined(S_SPLINT_S) */ |