prepare 0.3 release
[azimuth] / src / azimuth.c
1 /*
2  * azimuth.c - Source for Azimith
3  * Copyright (C) 2010 Guillaume Desmottes
4  * @author Guillaume Desmottes <gdesmott@gnome.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  */
20
21
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include <gconf/gconf-client.h>
26 #include <telepathy-glib/util.h>
27
28 #include <location/location-gpsd-control.h>
29
30 #include "azimuth.h"
31 #include "azimuth-gconf.h"
32 #include "position-publisher.h"
33
34 G_DEFINE_TYPE(Azimuth, azimuth, G_TYPE_OBJECT)
35
36 /* private structure */
37 typedef struct _AzimuthPrivate AzimuthPrivate;
38
39 struct _AzimuthPrivate
40 {
41   GMainLoop *loop;
42   PositionPublisher *publisher;
43   GConfClient *gconf;
44   LocationGPSDControl *gps_control;
45 };
46
47 #define AZIMUTH_GET_PRIVATE(o)     (G_TYPE_INSTANCE_GET_PRIVATE ((o), AZIMUTH_TYPE, AzimuthPrivate))
48
49 static void
50 update_gps (Azimuth *self)
51 {
52   AzimuthPrivate *priv = AZIMUTH_GET_PRIVATE (self);
53   gboolean start_gps;
54
55   start_gps = gconf_client_get_bool (priv->gconf,
56       AZIMUTH_GCONF_KEY_START_GPS, NULL);
57
58   if (priv->publisher != NULL &&
59       start_gps &&
60       position_publisher_has_connections (priv->publisher))
61     {
62       g_print ("starting GPS\n");
63       location_gpsd_control_start (priv->gps_control);
64     }
65   else
66     {
67       g_print ("stopping GPS\n");
68       location_gpsd_control_stop (priv->gps_control);
69     }
70 }
71
72 static void
73 update_blur (Azimuth *self)
74 {
75   AzimuthPrivate *priv = AZIMUTH_GET_PRIVATE (self);
76   gboolean blur;
77
78   if (priv->publisher == NULL)
79     return;
80
81   blur = gconf_client_get_bool (priv->gconf,
82       AZIMUTH_GCONF_KEY_BLUR, NULL);
83
84   position_publisher_set_blur (priv->publisher, blur);
85 }
86
87 static void
88 has_connections_changed_cb (PositionPublisher *publisher,
89     gboolean has_connections,
90     Azimuth *self)
91 {
92   update_gps (self);
93 }
94
95 static void
96 create_publisher (Azimuth *self)
97 {
98   AzimuthPrivate *priv = AZIMUTH_GET_PRIVATE (self);
99
100   priv->publisher = position_publisher_new ();
101
102   g_signal_connect (priv->publisher, "has-connections-changed",
103       G_CALLBACK (has_connections_changed_cb), self);
104 }
105
106 static void
107 enabled_changed (Azimuth *self,
108     gboolean enabled)
109 {
110   AzimuthPrivate *priv = AZIMUTH_GET_PRIVATE (self);
111
112   if (enabled)
113     {
114       if (priv->publisher != NULL)
115         return;
116
117       g_print ("enable publishing\n");
118       create_publisher (self);
119
120       update_blur (self);
121     }
122   else
123     {
124       g_print ("disable publishing\n");
125       if (priv->publisher == NULL)
126         return;
127
128       g_object_unref (priv->publisher);
129       priv->publisher = NULL;
130     }
131
132   update_gps (self);
133 }
134
135 static void
136 gconf_notification_cb (GConfClient *client,
137     guint cnxn_id,
138     GConfEntry *entry,
139     gpointer user_data)
140 {
141   Azimuth *self = user_data;
142   const gchar *key = gconf_entry_get_key (entry);
143   GConfValue *value = gconf_entry_get_value (entry);
144
145   if (!tp_strdiff (key, AZIMUTH_GCONF_KEY_ENABLED) &&
146       value->type == GCONF_VALUE_BOOL)
147     {
148       gboolean enabled = gconf_value_get_bool (value);
149
150       enabled_changed (self, enabled);
151     }
152
153   else if (!tp_strdiff (key, AZIMUTH_GCONF_KEY_START_GPS) &&
154       value->type == GCONF_VALUE_BOOL)
155     {
156       update_gps (self);
157     }
158
159   else if (!tp_strdiff (key, AZIMUTH_GCONF_KEY_BLUR) &&
160       value->type == GCONF_VALUE_BOOL)
161     {
162       update_blur (self);
163     }
164 }
165
166 static void
167 azimuth_init (Azimuth *self)
168 {
169   AzimuthPrivate *priv = AZIMUTH_GET_PRIVATE (self);
170
171   priv->loop = g_main_loop_new (NULL, FALSE);
172   priv->publisher = NULL;
173
174   priv->gconf = gconf_client_get_default ();
175
176   gconf_client_add_dir (priv->gconf, AZIMUTH_GCONF_SECTION,
177       GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
178
179   gconf_client_notify_add (priv->gconf, AZIMUTH_GCONF_SECTION,
180       gconf_notification_cb, self, NULL, NULL);
181
182   /* GPS controller */
183   priv->gps_control = location_gpsd_control_get_default();
184
185   g_object_set (G_OBJECT(priv->gps_control),
186     "preferred-method", LOCATION_METHOD_USER_SELECTED,
187     "preferred-interval", LOCATION_INTERVAL_120S,
188     NULL);
189 }
190
191 static void
192 azimuth_dispose (GObject *object)
193 {
194   Azimuth *self = AZIMUTH (object);
195   AzimuthPrivate *priv = AZIMUTH_GET_PRIVATE (self);
196
197   if (priv->publisher != NULL)
198     {
199       g_object_unref (priv->publisher);
200       priv->publisher = NULL;
201     }
202
203   if (priv->loop != NULL)
204     {
205       g_main_loop_unref (priv->loop);
206       priv->loop = NULL;
207     }
208
209   if (priv->gconf != NULL)
210     {
211       g_object_unref (priv->gconf);
212       priv->gconf = NULL;
213     }
214
215   if (priv->gps_control != NULL)
216     {
217       location_gpsd_control_stop (priv->gps_control);
218       g_object_unref (priv->gps_control);
219       priv->gps_control = NULL;
220     }
221
222   if (G_OBJECT_CLASS (azimuth_parent_class)->dispose)
223     G_OBJECT_CLASS (azimuth_parent_class)->dispose (object);
224 }
225
226 static void
227 azimuth_class_init (AzimuthClass *azimuth_class)
228 {
229   GObjectClass *object_class = G_OBJECT_CLASS (azimuth_class);
230
231   g_type_class_add_private (azimuth_class, sizeof (AzimuthPrivate));
232
233   object_class->dispose = azimuth_dispose;
234 }
235
236 Azimuth *
237 azimuth_new (void)
238 {
239   return g_object_new (AZIMUTH_TYPE,
240       NULL);
241 }
242
243 void
244 azimuth_run (Azimuth *self)
245 {
246   AzimuthPrivate *priv = AZIMUTH_GET_PRIVATE (self);
247   gboolean enabled;
248
249   enabled = gconf_client_get_bool (priv->gconf, AZIMUTH_GCONF_KEY_ENABLED,
250       NULL);
251   if (enabled)
252     {
253       g_print ("publishing is enabled\n");
254       g_assert (priv->publisher == NULL);
255       create_publisher (self);
256
257       update_gps (self);
258       update_blur (self);
259     }
260   else
261     {
262       g_print ("publishing is disabled\n");
263     }
264
265   g_print ("azimuth running\n");
266   g_main_loop_run (priv->loop);
267 }