diff --git a/providers/gpsd/geoclue-gpsd.c b/providers/gpsd/geoclue-gpsd.c index fed8077..6dcdc1e 100644 --- a/providers/gpsd/geoclue-gpsd.c +++ b/providers/gpsd/geoclue-gpsd.c @@ -137,14 +137,10 @@ set_options (GcIfaceGeoclue *gc, } /* new values? */ - if (host != NULL && gpsd->host != NULL) { - changed = (strcmp (host, gpsd->host) != 0); - } else if (!(host == NULL && gpsd->host == NULL)) { + if (g_strcmp0 (host, gpsd->host) != 0 || + g_strcmp0 (port, gpsd->port) != 0) { changed = TRUE; } - if (!changed) { - changed = (strcmp (port, gpsd->port) != 0); - } if (!changed) { return TRUE; @@ -152,10 +148,16 @@ set_options (GcIfaceGeoclue *gc, /* update private values with new ones, restart gpsd */ g_free (gpsd->port); - if (gpsd->host) { - g_free (gpsd->host); - } + gpsd->port = NULL; + g_free (gpsd->host); + gpsd->host = NULL; + geoclue_gpsd_stop_gpsd (gpsd); + + if (host == NULL) { + return TRUE; + } + gpsd->port = g_strdup (port); gpsd->host = g_strdup (host); if (!geoclue_gpsd_start_gpsd (gpsd)) { diff --git a/providers/gypsy/geoclue-gypsy.c b/providers/gypsy/geoclue-gypsy.c index 57d2a20..96aac34 100644 --- a/providers/gypsy/geoclue-gypsy.c +++ b/providers/gypsy/geoclue-gypsy.c @@ -362,17 +362,25 @@ set_options (GcIfaceGeoclue *gc, GError **error) { GeoclueGypsy *gypsy = GEOCLUE_GYPSY (gc); - gpointer device_name; + const char *device_name; char *path; device_name = g_hash_table_lookup (options, "org.freedesktop.Geoclue.GPSDevice"); - if (device_name == NULL) { - return TRUE; - } + + if (g_strcmp0 (gypsy->device_name, device_name) == 0) { + return TRUE; + } + + g_free (gypsy->device_name); + gypsy->device_name = NULL; + + if (device_name == NULL || *device_name == '\0') { + return TRUE; + } gypsy->device_name = g_strdup (device_name); - g_print ("Gypsy provider using %s\n", gypsy->device_name); + g_print ("Gypsy provider using '%s'\n", gypsy->device_name); path = gypsy_control_create (gypsy->control, gypsy->device_name, error); if (*error != NULL) { diff --git a/src/main.c b/src/main.c index 240d2d8..81d6a45 100644 --- a/src/main.c +++ b/src/main.c @@ -22,9 +22,39 @@ static GMainLoop *mainloop; static GHashTable *options; +static GcMaster *master; + +#define GEOCLUE_GCONF_TOP "/apps/geoclue/master" #define GEOCLUE_MASTER_NAME "org.freedesktop.Geoclue.Master" +static void +gconf_key_changed (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + const char *key, *value; + GConfValue *v; + + key = gconf_entry_get_key (entry); + v = gconf_entry_get_value (entry); + if (v->type != GCONF_VALUE_STRING) + return; + value = gconf_value_get_string (v); + + g_message ("gconf key changed %s", key); + + /* Don't add empty strings in the hashtable */ + if (value != NULL && value[0] == '\0') + value = NULL; + + g_hash_table_insert (options, g_path_get_basename (key), + g_strdup (value)); + + g_signal_emit_by_name (G_OBJECT (master), "options-changed", options); +} + static GHashTable * load_options (void) { @@ -32,18 +62,21 @@ load_options (void) GConfClient *client = gconf_client_get_default (); GSList *entries, *e; GError *error = NULL; - - entries = gconf_client_all_entries (client, "/apps/geoclue/master", &error); + + gconf_client_add_dir (client, GEOCLUE_GCONF_TOP, + GCONF_CLIENT_PRELOAD_RECURSIVE, NULL); + + entries = gconf_client_all_entries (client, GEOCLUE_GCONF_TOP, &error); if (error != NULL) { g_warning ("Error loading master options: %s", error->message); g_error_free (error); return NULL; } - /* Not an error, the directory is just empty */ - if (entries == NULL) { - return NULL; - } + /* Setup keys monitoring */ + gconf_client_notify_add (client, GEOCLUE_GCONF_TOP, + (GConfClientNotifyFunc) gconf_key_changed, + NULL, NULL, NULL); ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); g_print ("Master options:\n"); @@ -54,8 +87,13 @@ load_options (void) key = gconf_entry_get_key (entry); v = gconf_entry_get_value (entry); + if (v->type != GCONF_VALUE_STRING) + continue; value = gconf_value_get_string (v); + if (value != NULL && value[0] == '\0') + value = NULL; + g_print (" %s = %s\n", key, value); g_hash_table_insert (ht, g_path_get_basename (key), g_strdup (value)); @@ -76,7 +114,6 @@ int main (int argc, char **argv) { - GcMaster *master; DBusGConnection *conn; DBusGProxy *proxy; GError *error = NULL; diff --git a/src/master-provider.c b/src/master-provider.c index b13e401..ffcc079 100644 --- a/src/master-provider.c +++ b/src/master-provider.c @@ -1151,6 +1151,22 @@ gc_master_provider_is_good (GcMasterProvider *provider, ((priv->required_resources & (~allowed_resources)) == 0)); } +void +gc_master_provider_update_options (GcMasterProvider *provider) +{ + GeoclueProvider *geoclue; + GError *error = NULL; + + geoclue = gc_master_provider_get_provider (provider); + + if (!geoclue_provider_set_options (geoclue, + geoclue_get_main_options (), + &error)) { + g_warning ("Error setting provider options: %s\n", error->message); + g_error_free (error); + } +} + GeoclueStatus gc_master_provider_get_status (GcMasterProvider *provider) { diff --git a/src/master-provider.h b/src/master-provider.h index 8876210..6d35c08 100644 --- a/src/master-provider.h +++ b/src/master-provider.h @@ -81,6 +81,8 @@ gboolean gc_master_provider_is_good (GcMasterProvider *provider, void gc_master_provider_network_status_changed (GcMasterProvider *provider, GeoclueNetworkStatus status); +void gc_master_provider_update_options (GcMasterProvider *provider); + char* gc_master_provider_get_name (GcMasterProvider *provider); char* gc_master_provider_get_description (GcMasterProvider *provider); char* gc_master_provider_get_service (GcMasterProvider *provider); diff --git a/src/master.c b/src/master.c index 8b53eea..fa9037e 100644 --- a/src/master.c +++ b/src/master.c @@ -24,6 +24,13 @@ #endif #endif +enum { + OPTIONS_CHANGED, + LAST_SIGNAL +}; + +static guint32 signals[LAST_SIGNAL] = {0, }; + G_DEFINE_TYPE (GcMaster, gc_master, G_TYPE_OBJECT); static GList *providers = NULL; @@ -60,6 +67,16 @@ gc_master_class_init (GcMasterClass *klass) { dbus_g_object_type_install_info (gc_master_get_type (), &dbus_glib_gc_iface_master_object_info); + + signals[OPTIONS_CHANGED] = g_signal_new ("options-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_FIRST | + G_SIGNAL_NO_RECURSE, + G_STRUCT_OFFSET (GcMasterClass, options_changed), + NULL, NULL, + g_cclosure_marshal_VOID__BOXED, + G_TYPE_NONE, 1, + G_TYPE_HASH_TABLE); } /* Load the provider details out of a keyfile */ diff --git a/src/master.h b/src/master.h index f5ea2ee..0676be1 100644 --- a/src/master.h +++ b/src/master.h @@ -30,6 +30,8 @@ typedef struct { typedef struct { GObjectClass parent_class; + + void (*options_changed) (GcMaster *master, GHashTable *options); } GcMasterClass; GType gc_master_get_type (void);