diff --git a/geoclue/geoclue-master-client.c b/geoclue/geoclue-master-client.c index 2f74c761ddec0d4cd89b42f9e436571340d02b85..7beffd7bc971df11286889b39eb95f157b6d31de 100644 --- a/geoclue/geoclue-master-client.c +++ b/geoclue/geoclue-master-client.c @@ -26,11 +26,7 @@ * ... * * master = geoclue_master_get_default (); - * * client = geoclue_master_create_client (master, NULL, NULL); - * if (!client) { - * / * handle error * / - * } * * if (!geoclue_master_client_set_requirements (client, * GEOCLUE_ACCURACY_LEVEL_NONE, @@ -80,12 +76,21 @@ enum { LAST_SIGNAL }; + static guint32 signals[LAST_SIGNAL] = {0, }; #define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GEOCLUE_TYPE_MASTER_CLIENT, GeoclueMasterClientPrivate)) G_DEFINE_TYPE_WITH_CODE (GeoclueMasterClient, geoclue_master_client, G_TYPE_OBJECT, geoclue_types_init ();); + +typedef struct _GeoclueMasterClientAsyncData { + GeoclueMasterClient *client; + GCallback callback; + gpointer userdata; +} GeoclueMasterClientAsyncData; + + static void finalize (GObject *object) { @@ -301,6 +306,65 @@ geoclue_master_client_set_requirements (GeoclueMasterClient *client, return TRUE; } +static void +set_requirements_callback (DBusGProxy *proxy, + GError *error, + GeoclueMasterClientAsyncData *data) +{ + (*(GeoclueSetRequirementsCallback)data->callback) (data->client, + error, + data->userdata); + g_free (data); +} + +/** + * GeoclueSetRequirementsCallback: + * @client: A #GeoclueMasterClient object + * @error: Error as #Gerror (may be %NULL) + * @userdata: User data pointer set in geoclue_master_client_set_requirements_async() + * + * Callback function for geoclue_master_client_set_requirements_async(). + */ + +/** + * geoclue_master_client_set_requirements_async: + * @client: A #GeoclueMasterClient + * @min_accuracy: The required minimum accuracy as a #GeoclueAccuracyLevel. + * @min_time: The minimum time between update signals (currently not implemented) + * @require_updates: Whether the updates (signals) are required. Only applies to interfaces with signals + * @allowed_resources: The resources that are allowed to be used as a #GeoclueResourceFlags + * @callback: #GeoclueSetRequirementsCallback function to call when requirements have been set + * @userdata: User data pointer + * + * Asynchronous version of geoclue_master_client_set_requirements(). + */ +void +geoclue_master_client_set_requirements_async (GeoclueMasterClient *client, + GeoclueAccuracyLevel min_accuracy, + int min_time, + gboolean require_updates, + GeoclueResourceFlags allowed_resources, + GeoclueSetRequirementsCallback callback, + gpointer userdata) +{ + GeoclueMasterClientPrivate *priv = GET_PRIVATE (client); + GeoclueMasterClientAsyncData *data; + + data = g_new (GeoclueMasterClientAsyncData, 1); + data->client = client; + data->callback = G_CALLBACK (callback); + data->userdata = userdata; + + org_freedesktop_Geoclue_MasterClient_set_requirements_async + (priv->proxy, + min_accuracy, + min_time, + require_updates, + allowed_resources, + (org_freedesktop_Geoclue_MasterClient_set_requirements_reply)set_requirements_callback, + data); +} + /** * geoclue_master_client_create_address: * @client: A #GeoclueMasterClient @@ -326,12 +390,6 @@ geoclue_master_client_create_address (GeoclueMasterClient *client, return geoclue_address_new (GEOCLUE_MASTER_DBUS_SERVICE, priv->object_path); } -typedef struct _GeoclueMasterClientAsyncData { - GeoclueMasterClient *client; - GCallback callback; - gpointer userdata; -} GeoclueMasterClientAsyncData; - static void address_start_async_callback (DBusGProxy *proxy, GError *error, @@ -352,7 +410,7 @@ address_start_async_callback (DBusGProxy *proxy, } /** - * GreateAddressCallback: + * CreateAddressCallback: * @client: A #GeoclueMasterClient object * @address: returned #GeoclueAddress * @error: Error as #Gerror (may be %NULL) @@ -435,7 +493,7 @@ position_start_async_callback (DBusGProxy *proxy, } /** - * GreatePositionCallback: + * CreatePositionCallback: * @client: A #GeoclueMasterClient object * @position: returned #GeocluePosition * @error: Error as #Gerror (may be %NULL) @@ -504,6 +562,54 @@ gboolean geoclue_master_client_get_address_provider (GeoclueMasterClient *clien return TRUE; } +static void +get_provider_callback (DBusGProxy *proxy, + char * name, + char * description, + char * service, + char * path, + GError *error, + GeoclueMasterClientAsyncData *data) +{ + + (*(GeoclueGetProviderCallback)data->callback) (data->client, + name, + description, + service, + path, + error, + data->userdata); + g_free (data); +} + +/** + * geoclue_master_client_get_address_provider_async: + * @client: A #GeoclueMasterClient + * @callback: A #GeoclueGetProviderCallback function that will be called when return values are available + * @userdata: pointer for user specified data + * + * Gets name and other information for the currently used address provider asynchronously. + */ +void +geoclue_master_client_get_address_provider_async (GeoclueMasterClient *client, + GeoclueGetProviderCallback callback, + gpointer userdata) +{ + GeoclueMasterClientPrivate *priv = GET_PRIVATE (client); + GeoclueMasterClientAsyncData *data; + + data = g_new (GeoclueMasterClientAsyncData, 1); + data->client = client; + data->callback = G_CALLBACK (callback); + data->userdata = userdata; + + org_freedesktop_Geoclue_MasterClient_get_address_provider_async + (priv->proxy, + (org_freedesktop_Geoclue_MasterClient_get_address_provider_reply)get_provider_callback, + data); +} + + /** * geoclue_master_client_get_position_provider: * @client: A #GeoclueMasterClient @@ -535,3 +641,29 @@ gboolean geoclue_master_client_get_position_provider (GeoclueMasterClient *clie return TRUE; } +/** + * geoclue_master_client_get_position_provider_async: + * @client: A #GeoclueMasterClient + * @callback: A #GeoclueGetProviderCallback function that will be called when return values are available + * @userdata: pointer for user specified data + * + * Gets name and other information for the currently used position provider asynchronously. + */ +void +geoclue_master_client_get_position_provider_async (GeoclueMasterClient *client, + GeoclueGetProviderCallback callback, + gpointer userdata) +{ + GeoclueMasterClientPrivate *priv = GET_PRIVATE (client); + GeoclueMasterClientAsyncData *data; + + data = g_new (GeoclueMasterClientAsyncData, 1); + data->client = client; + data->callback = G_CALLBACK (callback); + data->userdata = userdata; + + org_freedesktop_Geoclue_MasterClient_get_position_provider_async + (priv->proxy, + (org_freedesktop_Geoclue_MasterClient_get_position_provider_reply)get_provider_callback, + data); +} diff --git a/geoclue/geoclue-master-client.h b/geoclue/geoclue-master-client.h index 287051a54cfc7774d2e025287c84aa24346b18fd..48d68370cf3f8e251b95b5e69e03ca85f2588a99 100644 --- a/geoclue/geoclue-master-client.h +++ b/geoclue/geoclue-master-client.h @@ -49,6 +49,16 @@ gboolean geoclue_master_client_set_requirements (GeoclueMasterClient *client, gboolean require_updates, GeoclueResourceFlags allowed_resources, GError **error); +typedef void (*GeoclueSetRequirementsCallback) (GeoclueMasterClient *client, + GError *error, + gpointer userdata); +void geoclue_master_client_set_requirements_async (GeoclueMasterClient *client, + GeoclueAccuracyLevel min_accuracy, + int min_time, + gboolean require_updates, + GeoclueResourceFlags allowed_resources, + GeoclueSetRequirementsCallback callback, + gpointer userdata); GeoclueAddress *geoclue_master_client_create_address (GeoclueMasterClient *client, GError **error); typedef void (*CreateAddressCallback) (GeoclueMasterClient *client, @@ -75,12 +85,26 @@ gboolean geoclue_master_client_get_address_provider (GeoclueMasterClient *clien char **service, char **path, GError **error); +typedef void (*GeoclueGetProviderCallback) (GeoclueMasterClient *client, + char *name, + char *description, + char *service, + char *path, + GError *error, + gpointer userdata); +void geoclue_master_client_get_address_provider_async (GeoclueMasterClient *client, + GeoclueGetProviderCallback callback, + gpointer userdata); + gboolean geoclue_master_client_get_position_provider (GeoclueMasterClient *client, char **name, char **description, char **service, char **path, GError **error); +void geoclue_master_client_get_position_provider_async (GeoclueMasterClient *client, + GeoclueGetProviderCallback callback, + gpointer userdata); G_END_DECLS diff --git a/geoclue/geoclue-master.c b/geoclue/geoclue-master.c index 3323729ddb2fec9a851541ba566e6e4b06d3483f..d313ae6b89ba9d83595cb582c6e797412602429b 100644 --- a/geoclue/geoclue-master.c +++ b/geoclue/geoclue-master.c @@ -36,6 +36,14 @@ typedef struct _GeoclueMasterPrivate { G_DEFINE_TYPE (GeoclueMaster, geoclue_master, G_TYPE_OBJECT); + +typedef struct _GeoclueMasterAsyncData { + GeoclueMaster *master; + GCallback callback; + gpointer userdata; +} GeoclueMasterAsyncData; + + static void finalize (GObject *object) { @@ -147,3 +155,50 @@ geoclue_master_create_client (GeoclueMaster *master, return client; } + +static void +create_client_callback (DBusGProxy *proxy, + char *path, + GError *error, + GeoclueMasterAsyncData *data) +{ + GeoclueMasterClient *client; + + client = NULL; + + if (!error) { + client = g_object_new (GEOCLUE_TYPE_MASTER_CLIENT, + "object-path", path, + NULL); + } + + (*(GeoclueCreateClientCallback)data->callback) (data->master, + client, + path, + error, + data->userdata); + + g_free (data); +} + +void +geoclue_master_create_client_async (GeoclueMaster *master, + GeoclueCreateClientCallback callback, + gpointer userdata) +{ + GeoclueMasterPrivate *priv; + GeoclueMasterAsyncData *data; + + g_return_if_fail (GEOCLUE_IS_MASTER (master)); + + priv = GET_PRIVATE (master); + data = g_new (GeoclueMasterAsyncData, 1); + data->master = master; + data->callback = G_CALLBACK (callback); + data->userdata = userdata; + + org_freedesktop_Geoclue_Master_create_async + (priv->proxy, + (org_freedesktop_Geoclue_Master_create_reply)create_client_callback, + data); +} diff --git a/geoclue/geoclue-master.h b/geoclue/geoclue-master.h index dbe3c178173bbd33eb8b5ff101e4f198e1566234..1b310a77013bd4e406ba3e6fb72b82bfe1e9dbc3 100644 --- a/geoclue/geoclue-master.h +++ b/geoclue/geoclue-master.h @@ -33,9 +33,18 @@ typedef struct _GeoclueMasterClass { GType geoclue_master_get_type (void); GeoclueMaster *geoclue_master_get_default (void); + GeoclueMasterClient *geoclue_master_create_client (GeoclueMaster *master, char **object_path, GError **error); +typedef void (*GeoclueCreateClientCallback) (GeoclueMaster *master, + GeoclueMasterClient *client, + char *object_path, + GError *error, + gpointer userdata); +void geoclue_master_create_client_async (GeoclueMaster *master, + GeoclueCreateClientCallback callback, + gpointer userdata); G_END_DECLS diff --git a/geoclue/geoclue-provider.c b/geoclue/geoclue-provider.c index ed94bbc0dd98b0056b0f26accfe105965cf09123..12b8e1d1ce97629fded59354516e8cc483121be1 100644 --- a/geoclue/geoclue-provider.c +++ b/geoclue/geoclue-provider.c @@ -27,9 +27,7 @@ * * pos = geoclue_position_new ("org.freedesktop.Geoclue.Providers.Example", * "/org/freedesktop/Geoclue/Providers/Example"); - * if (pos == NULL) { - * / * error * / - * } + * * if (geoclue_provider_get_provider_info (GEOCLUE_PROVIDER (pos), * &name, NULL, &error)) { * g_print ("name = %s", name); @@ -45,6 +43,12 @@ #include #include "gc-iface-geoclue-bindings.h" +typedef struct _GeoclueProviderAsyncData { + GeoclueProvider *provider; + GCallback callback; + gpointer userdata; +} GeoclueProviderAsyncData; + typedef struct _GeoclueProviderPrivate { DBusGProxy *geoclue_proxy; @@ -80,6 +84,24 @@ status_changed (DBusGProxy *proxy, g_signal_emit (provider, signals[STATUS_CHANGED], 0, status); } +static void +add_reference_callback (DBusGProxy *proxy, GError *error, gpointer userdata) +{ + if (error) { + g_printerr ("Could not reference provider: %s", error->message); + g_error_free (error); + } +} + +static void +remove_reference_callback (DBusGProxy *proxy, GError *error, gpointer userdata) +{ + if (error) { + g_printerr ("Could not unreference provider: %s", error->message); + g_error_free (error); + } +} + static void finalize (GObject *object) { @@ -97,12 +119,10 @@ dispose (GObject *object) { GeoclueProvider *provider = GEOCLUE_PROVIDER (object); GeoclueProviderPrivate *priv = GET_PRIVATE (object); - GError *error = NULL; - if (!org_freedesktop_Geoclue_remove_reference (priv->geoclue_proxy, &error)){ - g_printerr ("Could not unreference provider: %s", error->message); - g_error_free (error); - } + org_freedesktop_Geoclue_remove_reference_async (priv->geoclue_proxy, + remove_reference_callback, + NULL); if (priv->geoclue_proxy) { g_object_unref (priv->geoclue_proxy); priv->geoclue_proxy = NULL; @@ -152,10 +172,9 @@ constructor (GType type, priv->geoclue_proxy = dbus_g_proxy_new_for_name (connection, priv->service, priv->path, GEOCLUE_INTERFACE_NAME); - if (!org_freedesktop_Geoclue_add_reference (priv->geoclue_proxy, &error)){ - g_printerr ("Could not reference provider: %s", error->message); - g_error_free (error); - } + org_freedesktop_Geoclue_add_reference_async (priv->geoclue_proxy, + add_reference_callback, + NULL); dbus_g_proxy_add_signal (priv->geoclue_proxy, "StatusChanged", G_TYPE_INT, G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->geoclue_proxy, "StatusChanged", @@ -303,6 +322,60 @@ geoclue_provider_get_status (GeoclueProvider *provider, return TRUE; } +static void +get_status_async_callback (DBusGProxy *proxy, + GeoclueStatus status, + GError *error, + GeoclueProviderAsyncData *data) +{ + (*(GeoclueProviderStatusCallback)data->callback) (data->provider, + status, + error, + data->userdata); + g_free (data); + +} + +/** + * GeoclueProviderStatusCallback: + * @provider: A #GeoclueProvider object + * @status: A #GeoclueStatus + * @error: Error as #GError or %NULL + * @userdata: User data pointer set in geoclue_provider_get_status_async() + * + * Callback function for geoclue_provider_get_status_async(). + */ + +/** + * geoclue_provider_get_status_async: + * @provider: A #GeoclueProvider object + * @callback: A #GeoclueProviderStatusCallback function that will be called when return values are available + * @userdata: pointer for user specified data + * + * Asynchronous version of geoclue_provider_get_status(). Function returns + * (essentially) immediately and calls @callback when status is available or + * when there is an error. + */ +void +geoclue_provider_get_status_async (GeoclueProvider *provider, + GeoclueProviderStatusCallback callback, + gpointer userdata) +{ + GeoclueProviderPrivate *priv = GET_PRIVATE (provider); + GeoclueProviderAsyncData *data; + + data = g_new (GeoclueProviderAsyncData, 1); + data->provider = provider; + data->callback = G_CALLBACK (callback); + data->userdata = userdata; + + org_freedesktop_Geoclue_get_status_async + (priv->geoclue_proxy, + (org_freedesktop_Geoclue_get_status_reply)get_status_async_callback, + data); +} + + /** * geoclue_provider_set_options: * @provider: A #GeoclueProvider object @@ -328,6 +401,58 @@ geoclue_provider_set_options (GeoclueProvider *provider, options, error); } +static void +set_options_async_callback (DBusGProxy *proxy, + GError *error, + GeoclueProviderAsyncData *data) +{ + (*(GeoclueProviderOptionsCallback)data->callback) (data->provider, + error, + data->userdata); + g_free (data); +} + +/** + * GeoclueProviderOptionsCallback: + * @provider: A #GeoclueProvider object + * @error: Error as #GError or %NULL + * @userdata: User data pointer set in geoclue_provider_set_options_async() + * + * Callback function for geoclue_provider_set_options_async(). + */ + +/** + * geoclue_provider_set_options_async: + * @provider: A #GeoclueProvider object + * @options: A #GHashTable of options + * @callback: A #GeoclueProviderOptionsCallback function that will be called when options are set + * @userdata: pointer for user specified data + * + * Asynchronous version of geoclue_provider_set_options(). Function returns + * (essentially) immediately and calls @callback when options have been set or + * when there is an error. + */ +void +geoclue_provider_set_options_async (GeoclueProvider *provider, + GHashTable *options, + GeoclueProviderOptionsCallback callback, + gpointer userdata) +{ + GeoclueProviderPrivate *priv = GET_PRIVATE (provider); + GeoclueProviderAsyncData *data; + + data = g_new (GeoclueProviderAsyncData, 1); + data->provider = provider; + data->callback = G_CALLBACK (callback); + data->userdata = userdata; + + org_freedesktop_Geoclue_set_options_async + (priv->geoclue_proxy, + options, + (org_freedesktop_Geoclue_set_options_reply)set_options_async_callback, + data); +} + /** * geoclue_provider_get_provider_info: * @provider: A #GeoclueProvider object @@ -351,3 +476,58 @@ geoclue_provider_get_provider_info (GeoclueProvider *provider, name, description, error); } + +static void +get_provider_info_async_callback (DBusGProxy *proxy, + char *name, + char *description, + GError *error, + GeoclueProviderAsyncData *data) +{ + (*(GeoclueProviderInfoCallback)data->callback) (data->provider, + name, + description, + error, + data->userdata); + g_free (data); +} + +/** + * GeoclueProviderInfoCallback: + * @provider: A #GeoclueProvider object + * @name: Name of the provider + * @description: one-line description of the provider + * @error: Error as #GError or %NULL + * @userdata: User data pointer set in geoclue_provider_get_provider_info_async() + * + * Callback function for geoclue_provider_get_provider_info_async(). + */ + +/** + * geoclue_provider_get_provider_info_async: + * @provider: A #GeoclueProvider object + * @callback: A #GeoclueProviderInfoCallback function that will be called when info is available + * @userdata: pointer for user specified data + * + * Asynchronous version of geoclue_provider_get_provider_info(). Function returns + * (essentially) immediately and calls @callback when info is available or + * when there is an error. + */ +void +geoclue_provider_get_provider_info_async (GeoclueProvider *provider, + GeoclueProviderInfoCallback callback, + gpointer userdata) +{ + GeoclueProviderPrivate *priv = GET_PRIVATE (provider); + GeoclueProviderAsyncData *data; + + data = g_new (GeoclueProviderAsyncData, 1); + data->provider = provider; + data->callback = G_CALLBACK (callback); + data->userdata = userdata; + + org_freedesktop_Geoclue_get_provider_info_async + (priv->geoclue_proxy, + (org_freedesktop_Geoclue_get_provider_info_reply)get_provider_info_async_callback, + data); +} diff --git a/geoclue/geoclue-provider.h b/geoclue/geoclue-provider.h index 740d4bdbcd46a3538d0aad75ae4730d321f91779..08a4331f7c5c6c1a56326a4834e76f889132320d 100644 --- a/geoclue/geoclue-provider.h +++ b/geoclue/geoclue-provider.h @@ -40,13 +40,37 @@ GType geoclue_provider_get_type (void); gboolean geoclue_provider_get_status (GeoclueProvider *provider, GeoclueStatus *status, GError **error); +typedef void (*GeoclueProviderStatusCallback) (GeoclueProvider *provider, + GeoclueStatus status, + GError *error, + gpointer userdata); +void geoclue_provider_get_status_async (GeoclueProvider *provider, + GeoclueProviderStatusCallback callback, + gpointer userdata); + gboolean geoclue_provider_get_provider_info (GeoclueProvider *provider, char **name, char **description, GError **error); +typedef void (*GeoclueProviderInfoCallback) (GeoclueProvider *provider, + char *name, + char *description, + GError *error, + gpointer userdata); +void geoclue_provider_get_provider_info_async (GeoclueProvider *provider, + GeoclueProviderInfoCallback callback, + gpointer userdata); + gboolean geoclue_provider_set_options (GeoclueProvider *provider, GHashTable *options, GError **error); +typedef void (*GeoclueProviderOptionsCallback) (GeoclueProvider *provider, + GError *error, + gpointer userdata); +void geoclue_provider_set_options_async (GeoclueProvider *provider, + GHashTable *options, + GeoclueProviderOptionsCallback callback, + gpointer userdata); G_END_DECLS diff --git a/src/client.c b/src/client.c index beb1a626a5f5d1d6f02962e9dccbfd13e654936c..ce178261da850a5944e64bf7b64af6ea7987c834 100644 --- a/src/client.c +++ b/src/client.c @@ -52,10 +52,12 @@ typedef struct _GcMasterClientPrivate { gboolean require_updates; GeoclueResourceFlags allowed_resources; + gboolean position_started; GcMasterProvider *position_provider; GList *position_providers; gboolean position_provider_choice_in_progress; + gboolean address_started; GcMasterProvider *address_provider; GList *address_providers; gboolean address_provider_choice_in_progress; @@ -530,24 +532,6 @@ gc_master_client_choose_address_provider (GcMasterClient *client, return TRUE; } -static gboolean -gc_iface_master_client_set_requirements (GcMasterClient *client, - GeoclueAccuracyLevel min_accuracy, - int min_time, - gboolean require_updates, - GeoclueResourceFlags allowed_resources, - GError **error) -{ - GcMasterClientPrivate *priv = GET_PRIVATE (client); - - priv->min_accuracy = min_accuracy; - priv->min_time = min_time; - priv->require_updates = require_updates; - priv->allowed_resources = allowed_resources; - - return TRUE; -} - static void gc_master_provider_set_position_providers (GcMasterClient *client, GList *providers) @@ -588,12 +572,79 @@ gc_master_provider_set_address_providers (GcMasterClient *client, g_free (accuracy_data); } +static void +gc_master_client_init_position_providers (GcMasterClient *client) +{ + GcMasterClientPrivate *priv = GET_PRIVATE (client); + GList *providers; + + if (!priv->position_started) { + return; + } + + /* TODO: free priv->position_providers */ + + providers = gc_master_get_providers (GC_IFACE_POSITION, + priv->min_accuracy, + priv->require_updates, + priv->allowed_resources, + NULL); + g_debug ("client: %d position providers matching requirements found, now choosing current provider", + g_list_length (providers)); + + gc_master_provider_set_position_providers (client, providers); + gc_master_client_choose_position_provider (client, priv->position_providers); +} +static void +gc_master_client_init_address_providers (GcMasterClient *client) +{ + GList *providers; + GcMasterClientPrivate *priv = GET_PRIVATE (client); + + if (!priv->address_started) { + return; + } + + /* TODO: free priv->address_providers */ + + providers = gc_master_get_providers (GC_IFACE_ADDRESS, + priv->min_accuracy, + priv->require_updates, + priv->allowed_resources, + NULL); + g_debug ("client: %d address providers matching requirements found, now choosing current provider", + g_list_length (providers)); + + gc_master_provider_set_address_providers (client, providers); + gc_master_client_choose_address_provider (client, priv->address_providers); +} + +static gboolean +gc_iface_master_client_set_requirements (GcMasterClient *client, + GeoclueAccuracyLevel min_accuracy, + int min_time, + gboolean require_updates, + GeoclueResourceFlags allowed_resources, + GError **error) +{ + GcMasterClientPrivate *priv = GET_PRIVATE (client); + + priv->min_accuracy = min_accuracy; + priv->min_time = min_time; + priv->require_updates = require_updates; + priv->allowed_resources = allowed_resources; + + gc_master_client_init_position_providers (client); + gc_master_client_init_address_providers (client); + + return TRUE; +} + static gboolean gc_iface_master_client_position_start (GcMasterClient *client, GError **error) { - GList *providers; GcMasterClientPrivate *priv = GET_PRIVATE (client); if (priv->position_providers) { @@ -605,16 +656,9 @@ gc_iface_master_client_position_start (GcMasterClient *client, return FALSE; } - providers = gc_master_get_providers (GC_IFACE_POSITION, - priv->min_accuracy, - priv->require_updates, - priv->allowed_resources, - NULL); - g_debug ("client: %d position providers matching requirements found, now choosing current provider", - g_list_length (providers)); + priv->position_started = TRUE; - gc_master_provider_set_position_providers (client, providers); - gc_master_client_choose_position_provider (client, priv->position_providers); + gc_master_client_init_position_providers (client); return TRUE; } @@ -623,7 +667,6 @@ static gboolean gc_iface_master_client_address_start (GcMasterClient *client, GError **error) { - GList *providers; GcMasterClientPrivate *priv = GET_PRIVATE (client); if (priv->address_providers) { @@ -635,16 +678,8 @@ gc_iface_master_client_address_start (GcMasterClient *client, return FALSE; } - providers = gc_master_get_providers (GC_IFACE_ADDRESS, - priv->min_accuracy, - priv->require_updates, - priv->allowed_resources, - NULL); - g_debug ("client: %d address providers matching requirements found, now choosing current provider", - g_list_length (providers)); - - gc_master_provider_set_address_providers (client, providers); - gc_master_client_choose_address_provider (client, priv->address_providers); + priv->address_started = TRUE; + gc_master_client_init_address_providers (client); return TRUE; } @@ -777,9 +812,11 @@ gc_master_client_init (GcMasterClient *client) priv->position_provider_choice_in_progress = FALSE; priv->address_provider_choice_in_progress = FALSE; + priv->position_started = FALSE; priv->position_provider = NULL; priv->position_providers = NULL; + priv->address_started = FALSE; priv->address_provider = NULL; priv->address_providers = NULL; } diff --git a/test/Makefile.am b/test/Makefile.am index 057aa33dcdef6855fbc02f0e17926bc2818b808b..4ca96e557431740dbe7d4d72c8e14270f5f69d52 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -8,6 +8,7 @@ geoclue_test_gui_LDADD = \ $(top_builddir)/geoclue/libgeoclue.la geoclue_test_gui_CFLAGS= \ + -DGEOCLUE_PROVIDERS_DIR=\""$(datadir)/geoclue-providers"\" \ $(GTK_CFLAGS) \ $(GEOCLUE_CFLAGS) diff --git a/test/geoclue-test-gui.c b/test/geoclue-test-gui.c index 0c074c7abf5a68b64acb84728e2f38752112f6a0..8e08af6d865e0e50ed1e398727e99527ae1a2598 100644 --- a/test/geoclue-test-gui.c +++ b/test/geoclue-test-gui.c @@ -1,3 +1,12 @@ +/* + * Geoclue + * client-test-gui.c - Geoclue Test GUI + * + * Authors: Jussi Kukkonen + * + * Copyright 2008 OpenedHand Ltd + * 2008 Intel Corporation + */ #include #include @@ -13,6 +22,7 @@ enum { COL_ADDRESS_PROVIDER = 0, COL_ADDRESS_PROVIDER_NAME, + COL_ADDRESS_IS_MASTER, COL_ADDRESS_COUNTRY, COL_ADDRESS_COUNTRYCODE, COL_ADDRESS_REGION, @@ -25,32 +35,13 @@ enum { enum { COL_POSITION_PROVIDER = 0, COL_POSITION_PROVIDER_NAME, + COL_POSITION_IS_MASTER, COL_POSITION_LAT, COL_POSITION_LON, COL_POSITION_ALT, NUM_POSITION_COLS }; -static char *address_providers[] = -{ - "Hostip", - "Plazes", - "Manual", - "Localnet", - - NULL -}; -static char *position_providers[] = -{ - "Hostip", - "Plazes", - /*"Gsmloc",*/ /* gsmloc takes a looong time to if there's no gsm */ - "Gypsy", - "Gpsd", - - NULL -}; - #define GEOCLUE_TYPE_TEST_GUI geoclue_test_gui_get_type() #define GEOCLUE_TEST_GUI(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GEOCLUE_TYPE_TEST_GUI, GeoclueTestGui)) @@ -65,9 +56,14 @@ typedef struct { GeoclueMasterClient *client; char *master_client_path; + GeoclueAccuracyLevel master_accuracy; + GeoclueResourceFlags master_resources; GtkListStore *position_store; - GtkListStore *address_store; + GList *position_providers; /* PositionProviders, first one is master */ + + GtkListStore *address_store; + GList *address_providers; /* AddressProviders, first one is master */ } GeoclueTestGui; typedef struct { @@ -109,42 +105,56 @@ geoclue_test_gui_master_log_message (GeoclueTestGui *gui, char *message) strftime (time_buffer, 19, "%X", timeinfo); line = g_strdup_printf ("%s: %s\n", time_buffer, message); - g_debug (line); gtk_text_buffer_get_end_iter (gui->buffer, &iter); gtk_text_buffer_insert (gui->buffer, &iter, line, -1); g_free (line); } -static void -update_address (GeoclueTestGui *gui, GeoclueAddress *address, GHashTable *details) +static gboolean +get_matching_tree_iter (GtkTreeModel *model, GeoclueProvider *provider, GtkTreeIter *iter) { - GtkTreeIter iter; + GeoclueProvider *p = NULL; gboolean valid; - GeoclueAddress *a = NULL; - g_assert (details); + g_assert (model); + g_assert (provider); - valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->address_store), &iter); + valid = gtk_tree_model_get_iter_first (model, iter); while (valid) { - gtk_tree_model_get (GTK_TREE_MODEL (gui->address_store), &iter, - COL_ADDRESS_PROVIDER, &a, + gtk_tree_model_get (model, iter, + COL_ADDRESS_PROVIDER, &p, -1); - if (address == a) { - gtk_list_store_set (gui->address_store, &iter, - COL_ADDRESS_COUNTRY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRY), - COL_ADDRESS_COUNTRYCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRYCODE), - COL_ADDRESS_REGION, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_REGION), - COL_ADDRESS_LOCALITY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_LOCALITY), - COL_ADDRESS_AREA, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_AREA), - COL_ADDRESS_POSTALCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_POSTALCODE), - COL_ADDRESS_STREET, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_STREET), - -1); - break; + if (p == provider) { + return TRUE; } - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (gui->address_store), &iter); + + valid = gtk_tree_model_iter_next (model, iter); } + return FALSE; +} + +static void +update_address (GeoclueTestGui *gui, GeoclueAddress *address, GHashTable *details) +{ + GtkTreeIter iter; + + g_assert (details); + + if (get_matching_tree_iter (GTK_TREE_MODEL (gui->address_store), + GEOCLUE_PROVIDER (address), + &iter)) { + gtk_list_store_set (gui->address_store, &iter, + COL_ADDRESS_COUNTRY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRY), + COL_ADDRESS_COUNTRYCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_COUNTRYCODE), + COL_ADDRESS_REGION, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_REGION), + COL_ADDRESS_LOCALITY, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_LOCALITY), + COL_ADDRESS_AREA, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_AREA), + COL_ADDRESS_POSTALCODE, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_POSTALCODE), + COL_ADDRESS_STREET, g_hash_table_lookup (details, GEOCLUE_ADDRESS_KEY_STREET), + -1); + } } @@ -153,26 +163,16 @@ update_position (GeoclueTestGui *gui, GeocluePosition *position, double lat, double lon, double alt) { GtkTreeIter iter; - gboolean valid; - GeocluePosition *p = NULL; - - valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->position_store), &iter); - while (valid) { - gtk_tree_model_get (GTK_TREE_MODEL (gui->position_store), &iter, - COL_POSITION_PROVIDER, &p, + if (get_matching_tree_iter (GTK_TREE_MODEL (gui->position_store), + GEOCLUE_PROVIDER (position), + &iter)) { + gtk_list_store_set (gui->position_store, &iter, + COL_POSITION_LAT, lat, + COL_POSITION_LON, lon, + COL_POSITION_ALT, alt, -1); - if (position == p) { - gtk_list_store_set (gui->position_store, &iter, - COL_POSITION_LAT, lat, - COL_POSITION_LON, lon, - COL_POSITION_ALT, alt, - -1); - break; - } - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (gui->position_store), &iter); } - } @@ -183,18 +183,7 @@ address_changed (GeoclueAddress *address, GeoclueAccuracy *accuracy, GeoclueTestGui *gui) { - GtkTreeIter iter; - GeoclueAddress *a = NULL; - update_address (gui, address, details); - - gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->address_store), &iter); - gtk_tree_model_get (GTK_TREE_MODEL (gui->address_store), &iter, - COL_ADDRESS_PROVIDER, &a, - -1); - if (a == address) { - geoclue_test_gui_master_log_message (gui, "Master address changed"); - } } @@ -208,163 +197,185 @@ position_changed (GeocluePosition *position, GeoclueAccuracy *accuracy, GeoclueTestGui *gui) { - GtkTreeIter iter; - GeocluePosition *p = NULL; - update_position (gui, position, latitude, longitude, altitude); - - gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->position_store), &iter); - gtk_tree_model_get (GTK_TREE_MODEL (gui->position_store), &iter, - COL_POSITION_PROVIDER, &p, - -1); - if (p == position) { - geoclue_test_gui_master_log_message (gui, "Master position changed"); +} + +static void +address_callback (GeoclueAddress *address, + int timestamp, + GHashTable *details, + GeoclueAccuracy *accuracy, + GError *error, + gpointer userdata) +{ + if (error) { + g_warning ("Error getting address: %s\n", error->message); + g_error_free (error); + details = geoclue_address_details_new (); } + + update_address (GEOCLUE_TEST_GUI (userdata), address, details); } static void -append_to_address_store (GeoclueTestGui *gui, GeoclueAddress *address, char *name) +info_callback (GeoclueProvider *provider, + char *name, + char *description, + GError *error, + gpointer userdata) { - GHashTable *details = NULL; GtkTreeIter iter; + GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata); - gtk_list_store_append (gui->address_store, &iter); - gtk_list_store_set (gui->address_store, &iter, - COL_ADDRESS_PROVIDER, address, - COL_ADDRESS_PROVIDER_NAME, name, - -1); + if (error) { + g_warning ("Error getting provider info: %s\n", error->message); + g_error_free (error); + return; + } + if (get_matching_tree_iter (GTK_TREE_MODEL (gui->address_store), + provider, + &iter)) { + /* skip master, that's handled in master_*_provider_changed */ + if (strcmp (name, "Geoclue Master") != 0) { + gtk_list_store_set (gui->address_store, &iter, + COL_ADDRESS_PROVIDER_NAME, name, + -1); + } + } - if (address == NULL) { - g_printerr ("Error while creating GeoclueAddress %s", name); - } else { - g_signal_connect (G_OBJECT (address), "address-changed", - G_CALLBACK (address_changed), gui); - - if (!geoclue_address_get_address (address, NULL, - &details, NULL, - NULL)) { - g_warning ("Error getting address\n"); - details = geoclue_address_details_new (); + if (get_matching_tree_iter (GTK_TREE_MODEL (gui->position_store), + provider, + &iter)) { + /* skip master, that's handled in master_*_provider_changed */ + if (strcmp (name, "Geoclue Master") != 0) { + gtk_list_store_set (gui->position_store, &iter, + COL_POSITION_PROVIDER_NAME, name, + -1); } - update_address (gui, address, details); - g_hash_table_destroy (details); } } -static void -add_address_provider_to_store (GeoclueTestGui *gui, char *service, char *path) +static void +add_to_address_store (GeoclueTestGui *gui, GeoclueAddress *address, gboolean is_master) { - GeoclueAddress *address = NULL; - char *name = NULL; - - char *msg = g_strdup_printf ("Adding address provider %s", path); - geoclue_test_gui_master_log_message (gui, msg); - g_free (msg); + GtkTreeIter iter; - /*TODO: should unref these at some point? */ - address = geoclue_address_new (service, path); + g_assert (gui->address_store); + g_assert (address); - if (address == NULL) { - g_printerr ("Error while creating GeoclueAddress %s.\n", path); - name = "(error)"; + if (is_master) { + /* master is already on the first line */ + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->address_store), &iter); } else { - geoclue_provider_get_provider_info (GEOCLUE_PROVIDER (address), &name, NULL, NULL); + gtk_list_store_append (gui->address_store, &iter); } + gtk_list_store_set (gui->address_store, &iter, + COL_ADDRESS_PROVIDER, address, + COL_ADDRESS_IS_MASTER, is_master, + -1); + g_signal_connect (G_OBJECT (address), "address-changed", + G_CALLBACK (address_changed), gui); + geoclue_provider_get_provider_info_async (GEOCLUE_PROVIDER (address), + info_callback, + gui); + geoclue_address_get_address_async (address, address_callback, gui); - append_to_address_store (gui, address, name); } -static void -add_master_address_provider_to_store (GeoclueTestGui *gui) +static gboolean +get_next_provider (GDir *dir, char **name, char **service, char **path, char **ifaces) { - GeoclueAddress *address = NULL; + const char *filename; + char *fullname; + GKeyFile *keyfile; + gboolean ret; + GError *error; + + filename = g_dir_read_name (dir); + if (!filename) { + return FALSE; + } - geoclue_test_gui_master_log_message (gui, "Adding master address provider"); + fullname = g_build_filename (GEOCLUE_PROVIDERS_DIR, + filename, NULL); + keyfile = g_key_file_new (); + ret = g_key_file_load_from_file (keyfile, fullname, + G_KEY_FILE_NONE, &error); + g_free (fullname); - /*TODO: should unref these at some point? */ - address = geoclue_master_client_create_address (gui->client, NULL); + if (!ret) { + g_warning ("Error loading %s: %s", filename, error->message); + g_error_free (error); + } else { + *name = g_key_file_get_value (keyfile, "Geoclue Provider", + "Name", NULL); + + *service = g_key_file_get_value (keyfile, "Geoclue Provider", + "Service", NULL); + *path = g_key_file_get_value (keyfile, "Geoclue Provider", + "Path", NULL); + *ifaces = g_key_file_get_value (keyfile, "Geoclue Provider", + "Interfaces", NULL); + } - append_to_address_store (gui, address, "master"); + g_key_file_free (keyfile); + return TRUE; } static void -append_to_position_store (GeoclueTestGui *gui, GeocluePosition *position, char *name) +position_callback (GeocluePosition *position, + GeocluePositionFields fields, + int timestamp, + double lat, double lon, double alt, + GeoclueAccuracy *accuracy, + GError *error, + gpointer userdata) { - double lat, lon, alt; - GtkTreeIter iter; - - lat = lon = alt = 0.0/0.0; - - gtk_list_store_append (gui->position_store, &iter); - gtk_list_store_set (gui->position_store, &iter, - COL_POSITION_PROVIDER, position, - COL_POSITION_PROVIDER_NAME, name, - -1); - - if (!position) { - g_printerr ("Error while creating GeocluePosition %s.\n", name); - - } else { - g_signal_connect (G_OBJECT (position), "position-changed", - G_CALLBACK (position_changed), gui); - - if (!geoclue_position_get_position (position, NULL, - &lat, &lon, &alt, - NULL, NULL)) { - g_warning ("Error getting position\n"); - } - - update_position (gui, position, lat, lon, alt); + if (error) { + g_warning ("Error getting position: %s\n", error->message); + g_error_free (error); + lat = lon = alt = 0.0/0.0; } + update_position (GEOCLUE_TEST_GUI (userdata), position, lat, lon, alt); } -static void -add_position_provider_to_store (GeoclueTestGui *gui, char *service, char *path) +static void +add_to_position_store (GeoclueTestGui *gui, GeocluePosition *position, gboolean is_master) { - GeocluePosition *position = NULL; - char *name = NULL; - - char *msg = g_strdup_printf ("Adding position provider %s", path); - geoclue_test_gui_master_log_message (gui, msg); - g_free (msg); + GtkTreeIter iter; - /*TODO: should unref these at some point? */ - position = geoclue_position_new (service, path); + g_assert (gui->position_store); + g_assert (position); - if (position == NULL) { - g_printerr ("Error while creating GeoclueAddress %s.\n", path); - name = "(error)"; + if (is_master) { + /* master is already on the first line */ + gtk_tree_model_get_iter_first (GTK_TREE_MODEL (gui->position_store), &iter); } else { - geoclue_provider_get_provider_info (GEOCLUE_PROVIDER (position), &name, NULL, NULL); + gtk_list_store_append (gui->position_store, &iter); } + gtk_list_store_set (gui->position_store, &iter, + COL_POSITION_PROVIDER, position, + COL_POSITION_IS_MASTER, is_master, + -1); - append_to_position_store (gui, position, name); -} - -static void -add_master_position_provider_to_store (GeoclueTestGui *gui) -{ - GeocluePosition *position = NULL; - - geoclue_test_gui_master_log_message (gui, "Adding master position provider"); - - /*TODO: should unref these at some point? */ - position = geoclue_master_client_create_position (gui->client, NULL); + g_signal_connect (G_OBJECT (position), "position-changed", + G_CALLBACK (position_changed), gui); - append_to_position_store (gui, position, "master"); + geoclue_provider_get_provider_info_async (GEOCLUE_PROVIDER (position), + info_callback, + gui); + geoclue_position_get_position_async (position, position_callback, gui); } static GtkWidget * get_address_tree_view (GeoclueTestGui *gui) { - char *service, *path; GtkTreeView *view; GtkCellRenderer *renderer; - int i; view = GTK_TREE_VIEW (gtk_tree_view_new ()); @@ -375,6 +386,7 @@ get_address_tree_view (GeoclueTestGui *gui) "text", COL_ADDRESS_PROVIDER_NAME, NULL); + renderer = gtk_cell_renderer_text_new (); gtk_tree_view_insert_column_with_attributes (view, -1, GEOCLUE_ADDRESS_KEY_COUNTRY, @@ -428,6 +440,7 @@ get_address_tree_view (GeoclueTestGui *gui) gui->address_store = gtk_list_store_new (NUM_ADDRESS_COLS, G_TYPE_POINTER, G_TYPE_STRING, + G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, @@ -436,16 +449,6 @@ get_address_tree_view (GeoclueTestGui *gui) G_TYPE_STRING, G_TYPE_STRING); - add_master_address_provider_to_store (gui); - i = 0; - while (address_providers[i]) { - service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", address_providers[i]); - path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", address_providers[i]); - add_address_provider_to_store (gui, service, path); - g_free (service); - g_free (path); - i++; - } gtk_tree_view_set_model (view, GTK_TREE_MODEL(gui->address_store)); return GTK_WIDGET (view); @@ -455,10 +458,8 @@ get_address_tree_view (GeoclueTestGui *gui) static GtkWidget * get_position_tree_view (GeoclueTestGui *gui) { - char *service, *path; GtkTreeView *view; GtkCellRenderer *renderer; - int i; view = GTK_TREE_VIEW (gtk_tree_view_new ()); @@ -494,20 +495,11 @@ get_position_tree_view (GeoclueTestGui *gui) gui->position_store = gtk_list_store_new (NUM_POSITION_COLS, G_TYPE_POINTER, G_TYPE_STRING, + G_TYPE_BOOLEAN, G_TYPE_DOUBLE, G_TYPE_DOUBLE, G_TYPE_DOUBLE); - add_master_position_provider_to_store (gui); - i = 0; - while (position_providers[i]) { - service = g_strdup_printf ("org.freedesktop.Geoclue.Providers.%s", position_providers[i]); - path = g_strdup_printf ("/org/freedesktop/Geoclue/Providers/%s", position_providers[i]); - add_position_provider_to_store (gui, service, path); - g_free (service); - g_free (path); - i++; - } gtk_tree_view_set_model (view, GTK_TREE_MODEL(gui->position_store)); return GTK_WIDGET (view); @@ -552,11 +544,243 @@ master_address_provider_changed (GeoclueMasterClient *client, COL_ADDRESS_PROVIDER_NAME, g_strdup_printf ("Master (%s)", name), -1); } - msg = g_strdup_printf ("Master: position provider changed: %s", name); + msg = g_strdup_printf ("Master: address provider changed: %s", name); geoclue_test_gui_master_log_message (gui, msg); g_free (msg); } +static void +set_requirements_callback (GeoclueMasterClient *client, + GError *error, + gpointer userdata) +{ + if (error) { + g_printerr ("Setting requirements failed : %s", error->message); + g_error_free (error); + } +} + +static void +update_master_requirements (GeoclueTestGui *gui) +{ + geoclue_master_client_set_requirements_async (gui->client, + gui->master_accuracy, + 0, + FALSE, + gui->master_resources, + set_requirements_callback, + NULL); +} + +static void +create_address_callback (GeoclueMasterClient *client, + GeoclueAddress *address, + GError *error, + gpointer userdata) +{ + GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata); + + if (error) { + g_printerr ("Master Client: Failed to create address: %s", error->message); + g_error_free (error); + return; + } + add_to_address_store (gui, address, TRUE); +} + +static void +create_position_callback (GeoclueMasterClient *client, + GeocluePosition *position, + GError *error, + gpointer userdata) +{ + GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata); + + if (error) { + g_printerr ("Master Client: Failed to create position: %s", error->message); + g_error_free (error); + return; + } + add_to_position_store (gui, position, TRUE); +} + + +static void +create_client_callback (GeoclueMaster *master, + GeoclueMasterClient *client, + char *object_path, + GError *error, + gpointer userdata) +{ + GDir *dir; + char *name, *path, *service, *ifaces; + GtkTreeIter iter; + GeoclueTestGui *gui = GEOCLUE_TEST_GUI (userdata); + + if (error) { + g_printerr ("Failed to create master client: %s", error->message); + g_error_free (error); + return; + } + + gui->client = client; + + g_signal_connect (G_OBJECT (gui->client), "position-provider-changed", + G_CALLBACK (master_position_provider_changed), gui); + g_signal_connect (G_OBJECT (gui->client), "address-provider-changed", + G_CALLBACK (master_address_provider_changed), gui); + update_master_requirements (gui); + + /* add master providers to the lists */ + gtk_list_store_append (gui->position_store, &iter); + geoclue_master_client_create_position_async (gui->client, + create_position_callback, + gui); + gtk_list_store_append (gui->address_store, &iter); + geoclue_master_client_create_address_async (gui->client, + create_address_callback, + gui); + + /* add individual providers based on files in GEOCLUE_PROVIDERS_DIR */ + dir = g_dir_open (GEOCLUE_PROVIDERS_DIR, 0, &error); + if (!dir) { + g_warning ("Error opening %s: %s\n", + GEOCLUE_PROVIDERS_DIR, error->message); + g_error_free (error); + return; + } + + name = service = path = ifaces = NULL; + while (get_next_provider (dir, &name, &service, &path, &ifaces)) { + if (ifaces && strstr (ifaces, "org.freedesktop.Geoclue.Position")) { + add_to_position_store (gui, geoclue_position_new (service, path), FALSE); + } + if (ifaces && strstr (ifaces, "org.freedesktop.Geoclue.Address")) { + add_to_address_store (gui, geoclue_address_new (service, path), FALSE); + } + g_free (name); + g_free (path); + g_free (service); + g_free (ifaces); + } + + g_dir_close (dir); + g_object_unref (master); +} + +static void +geoclue_test_gui_load_providers (GeoclueTestGui *gui) +{ + GeoclueMaster *master; + + master = geoclue_master_get_default (); + geoclue_master_create_client_async (master, + create_client_callback, + gui); +} + +static void +accuracy_combo_changed (GtkComboBox *combo, GeoclueTestGui *gui) +{ + GtkTreeIter iter; + + if (gtk_combo_box_get_active_iter (combo, &iter)) { + GtkTreeModel *model; + + model = gtk_combo_box_get_model (combo); + gtk_tree_model_get (model, &iter, 0, &gui->master_accuracy, -1); + + update_master_requirements (gui); + } +} + +static void +gps_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui) +{ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) { + gui->master_resources |= GEOCLUE_RESOURCE_GPS; + } else { + gui->master_resources &= ~GEOCLUE_RESOURCE_GPS; + } + update_master_requirements (gui); +} + +static void +network_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui) +{ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) { + gui->master_resources |= GEOCLUE_RESOURCE_NETWORK; + } else { + gui->master_resources &= ~GEOCLUE_RESOURCE_NETWORK; + } + update_master_requirements (gui); +} + +static void +cell_check_toggled (GtkCheckButton *btn, GeoclueTestGui *gui) +{ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (btn))) { + gui->master_resources |= GEOCLUE_RESOURCE_CELL; + } else { + gui->master_resources &= ~GEOCLUE_RESOURCE_CELL; + } + update_master_requirements (gui); +} + +static GtkWidget* +get_accuracy_combo (GeoclueTestGui *gui) +{ + GtkListStore *store; + GtkWidget *combo; + GtkTreeIter iter; + GtkCellRenderer *renderer; + + store = gtk_list_store_new (2, G_TYPE_UINT, G_TYPE_STRING); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, GEOCLUE_ACCURACY_LEVEL_COUNTRY, + 1, "Country", + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, GEOCLUE_ACCURACY_LEVEL_REGION, + 1, "Region", + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, GEOCLUE_ACCURACY_LEVEL_LOCALITY, + 1, "Locality", + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, GEOCLUE_ACCURACY_LEVEL_POSTALCODE, + 1, "Postalcode", + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, GEOCLUE_ACCURACY_LEVEL_STREET, + 1, "Street", + -1); + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, GEOCLUE_ACCURACY_LEVEL_DETAILED, + 1, "Detailed", + -1); + + combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store)); + renderer = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer, + "text", 1, NULL); + + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); + gui->master_accuracy = GEOCLUE_ACCURACY_LEVEL_COUNTRY; + + return combo; +} + + static void geoclue_test_gui_init (GeoclueTestGui *gui) { @@ -564,11 +788,12 @@ geoclue_test_gui_init (GeoclueTestGui *gui) GtkWidget *position_view; GtkWidget *notebook; GtkWidget *box; - GtkWidget *hbox; + GtkWidget *frame; + GtkWidget *hbox, *vbox; GtkWidget *label; + GtkWidget *combo, *check; GtkWidget *scrolled_win; GtkWidget *view; - GeoclueMaster *master; gui->window = gtk_window_new (GTK_WINDOW_TOPLEVEL); g_signal_connect (G_OBJECT (gui->window), "destroy", @@ -579,31 +804,48 @@ geoclue_test_gui_init (GeoclueTestGui *gui) g_object_set (G_OBJECT (view), "editable", FALSE, NULL); gui->buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); - master = geoclue_master_get_default (); - gui->client = geoclue_master_create_client (master, &gui->master_client_path, NULL); - if (!gui->client) { - g_printerr ("No Geoclue master client!"); - g_object_unref (gui); - return; - } - g_signal_connect (G_OBJECT (gui->client), "position-provider-changed", - G_CALLBACK (master_position_provider_changed), gui); - g_signal_connect (G_OBJECT (gui->client), "address-provider-changed", - G_CALLBACK (master_address_provider_changed), gui); - if (!geoclue_master_client_set_requirements (gui->client, - GEOCLUE_ACCURACY_LEVEL_COUNTRY, - 0, - FALSE, - GEOCLUE_RESOURCE_GPS | GEOCLUE_RESOURCE_NETWORK, - NULL)){ - g_printerr ("set_requirements failed"); - } - g_object_unref (master); + box = gtk_vbox_new (FALSE, 8); + gtk_container_add (GTK_CONTAINER (gui->window), box); + frame = gtk_frame_new ("Master settings"); + gtk_box_pack_start (GTK_BOX (box), frame, FALSE, FALSE, 4); - box = gtk_vbox_new (FALSE, 5); - gtk_container_add (GTK_CONTAINER (gui->window), box); + + hbox = gtk_hbox_new (FALSE, 24); + gtk_container_add (GTK_CONTAINER (frame), hbox); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 8); + label = gtk_label_new ("Required accuracy level:"); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + combo = get_accuracy_combo (gui); + g_signal_connect (combo, "changed", + G_CALLBACK (accuracy_combo_changed), gui); + gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + label = gtk_label_new ("Allow resources:"); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + check = gtk_check_button_new_with_label ("Network"); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE); + gui->master_resources |= GEOCLUE_RESOURCE_NETWORK; + g_signal_connect (check, "toggled", + G_CALLBACK (network_check_toggled), gui); + gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0); + + check = gtk_check_button_new_with_label ("GPS"); + g_signal_connect (check, "toggled", + G_CALLBACK (gps_check_toggled), gui); + gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0); + + check = gtk_check_button_new_with_label ("Cell"); + g_signal_connect (check, "toggled", + G_CALLBACK (cell_check_toggled), gui); + gtk_box_pack_start (GTK_BOX (vbox), check, FALSE, FALSE, 0); notebook = gtk_notebook_new (); gtk_box_pack_start (GTK_BOX (box), notebook, FALSE, FALSE, 0); @@ -630,6 +872,8 @@ geoclue_test_gui_init (GeoclueTestGui *gui) gtk_container_add (GTK_CONTAINER (box), scrolled_win); gtk_container_add (GTK_CONTAINER (scrolled_win), view); + geoclue_test_gui_load_providers (gui); + geoclue_test_gui_master_log_message (gui, "Started Geoclue test UI"); gtk_widget_show_all (gui->window); @@ -641,8 +885,10 @@ int main (int argc, char **argv) GeoclueTestGui *gui; gtk_init (&argc, &argv); + gui = g_object_new (GEOCLUE_TYPE_TEST_GUI, NULL); gtk_main (); + g_object_unref (gui); return 0;