]> err.no Git - mapper/blob - src/mapper.c
GpsBluez: cleanups
[mapper] / src / mapper.c
1 /*
2  * This file is part of mapper
3  *
4  * Copyright (C) 2007 Kaj-Michael Lang
5  * Copyright (C) 2006-2007 John Costigan.
6  *
7  * POI and GPS-Info code originally written by Cezary Jackiewicz.
8  *
9  * Default map data provided by http://www.openstreetmap.org/
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25
26 #include <config.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <stddef.h>
32 #include <math.h>
33 #include <errno.h>
34 #include <sys/wait.h>
35 #include <glib.h>
36 #include <glib/gstdio.h>
37 #include <glib/gi18n.h>
38 #ifdef WITH_GST
39 #include <gst/gst.h>
40 #include "audio-note.h"
41 #endif
42 #include <gtk/gtk.h>
43 #include <fcntl.h>
44 #include <gdk/gdkkeysyms.h>
45 #include <dbus/dbus.h>
46 #include <dbus/dbus-glib.h>
47 #include <dbus/dbus-glib-lowlevel.h>
48 #include <libgnomevfs/gnome-vfs.h>
49 #include <curl/multi.h>
50 #include <gconf/gconf-client.h>
51 #include <libintl.h>
52 #include <locale.h>
53
54 #ifdef WITH_HAL
55 #include <libhal.h>
56 #endif
57
58 #ifdef WITH_HILDON_DBUS_BT
59 #include <bt-dbus.h>
60 #endif
61
62 #ifdef WITH_GL
63 #include <GL/gl.h>
64 #include <GL/glu.h>
65 #include <gtk/gtkgl.h>
66 #endif
67
68 #include "mapper.h"
69 #include "hildon-mapper.h"
70 #include "utils.h"
71 #include "mapper-types.h"
72 #include "settings.h"
73 #include "gps.h"
74 #include "gps-conn.h"
75 #include "map.h"
76 #include "map-download.h"
77 #include "route.h"
78 #include "track.h"
79 #include "ui-common.h"
80 #include "db.h"
81 #include "osm-db.h"
82 #include "poi.h"
83 #include "cb.h"
84 #include "speak.h"
85 #include "gpx.h"
86 #include "config-gconf.h"
87 #include "dialogs.h"
88
89 gfloat UNITS_CONVERT[] = {1.85200,1.15077945,1.f,};
90
91 GdkColor COLORABLE_DEFAULT[COLORABLE_ENUM_COUNT] = {
92         {0, 0x0000, 0x0000, 0xc000}
93         ,                       /* COLORABLE_MARK */
94         {0, 0x6000, 0x6000, 0xf800}
95         ,                       /* COLORABLE_MARK_VELOCITY */
96         {0, 0x8000, 0x8000, 0x8000}
97         ,                       /* COLORABLE_MARK_OLD */
98         {0, 0xe000, 0x0000, 0x0000}
99         ,                       /* COLORABLE_TRACK */
100         {0, 0xa000, 0x0000, 0x0000}
101         ,                       /* COLORABLE_TRACK_MARK */
102         {0, 0x7000, 0x0000, 0x0000}
103         ,                       /* COLORABLE_TRACK_BREAK */
104         {0, 0x0000, 0xa000, 0x0000}
105         ,                       /* COLORABLE_ROUTE */
106         {0, 0x0000, 0x8000, 0x0000}
107         ,                       /* COLORABLE_ROUTE_WAY */
108         {0, 0x0000, 0x6000, 0x0000}
109         ,                       /* COLORABLE_ROUTE_BREAK */
110         {0, 0xa000, 0x0000, 0xa000}     /* COLORABLE_POI */
111 };
112
113 enum {
114         MAPPER_INIT_START=0,
115         MAPPER_INIT_MISC,
116         MAPPER_INIT_CONFIG,
117         MAPPER_INIT_DB,
118         MAPPER_INIT_POI,
119         MAPPER_INIT_OSM,
120         MAPPER_INIT_VOICE,
121         MAPPER_INIT_UI,
122         MAPPER_INIT_GOTO,
123         MAPPER_INIT_DONE
124 } mapper_init_state;
125
126 guint mis=MAPPER_INIT_START;
127
128 static GtkWidget *init_progress;
129 static GtkWidget *init_dialog;
130
131 #ifdef WITH_HAL
132 LibHalContext *ctx;
133 #endif
134
135 /**
136  * Initialize arrays
137  */
138 static void 
139 variables_init(void)
140 {
141 INFO_FONT_TEXT[INFO_FONT_XXSMALL] = "xx-small";
142 INFO_FONT_TEXT[INFO_FONT_XSMALL] = "x-small";
143 INFO_FONT_TEXT[INFO_FONT_SMALL] = "small";
144 INFO_FONT_TEXT[INFO_FONT_MEDIUM] = "medium";
145 INFO_FONT_TEXT[INFO_FONT_LARGE] = "large";
146 INFO_FONT_TEXT[INFO_FONT_XLARGE] = "x-large";
147 INFO_FONT_TEXT[INFO_FONT_XXLARGE] = "xx-large";
148
149 CUSTOM_KEY_GCONF[CUSTOM_KEY_UP] = GCONF_KEY_PREFIX "/key_up";
150 CUSTOM_KEY_GCONF[CUSTOM_KEY_DOWN] = GCONF_KEY_PREFIX "/key_down";
151 CUSTOM_KEY_GCONF[CUSTOM_KEY_LEFT] = GCONF_KEY_PREFIX "/key_left";
152 CUSTOM_KEY_GCONF[CUSTOM_KEY_RIGHT] = GCONF_KEY_PREFIX "/key_right";
153 CUSTOM_KEY_GCONF[CUSTOM_KEY_SELECT] = GCONF_KEY_PREFIX "/key_select";
154 CUSTOM_KEY_GCONF[CUSTOM_KEY_INCREASE] = GCONF_KEY_PREFIX "/key_increase";
155 CUSTOM_KEY_GCONF[CUSTOM_KEY_DECREASE] = GCONF_KEY_PREFIX "/key_decrease";
156 CUSTOM_KEY_GCONF[CUSTOM_KEY_FULLSCREEN] = GCONF_KEY_PREFIX "/key_fullscreen";
157 CUSTOM_KEY_GCONF[CUSTOM_KEY_ESC] = GCONF_KEY_PREFIX "/key_esc";
158
159 CUSTOM_KEY_ICON[CUSTOM_KEY_UP] = HWK_BUTTON_UP;
160 CUSTOM_KEY_ICON[CUSTOM_KEY_LEFT] = HWK_BUTTON_LEFT;
161 CUSTOM_KEY_ICON[CUSTOM_KEY_DOWN] = HWK_BUTTON_DOWN;
162 CUSTOM_KEY_ICON[CUSTOM_KEY_RIGHT] = HWK_BUTTON_RIGHT;
163 CUSTOM_KEY_ICON[CUSTOM_KEY_SELECT] = HWK_BUTTON_SELECT;
164 CUSTOM_KEY_ICON[CUSTOM_KEY_INCREASE] = HWK_BUTTON_INCREASE;
165 CUSTOM_KEY_ICON[CUSTOM_KEY_DECREASE] = HWK_BUTTON_DECREASE;
166 CUSTOM_KEY_ICON[CUSTOM_KEY_FULLSCREEN] = HWK_BUTTON_VIEW;
167 CUSTOM_KEY_ICON[CUSTOM_KEY_ESC] = HWK_BUTTON_CANCEL;
168
169 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_UP] = CUSTOM_ACTION_PAN_NORTH;
170 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_LEFT] = CUSTOM_ACTION_PAN_WEST;
171 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_DOWN] = CUSTOM_ACTION_PAN_SOUTH;
172 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_RIGHT] = CUSTOM_ACTION_PAN_EAST;
173 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_SELECT] = CUSTOM_ACTION_TOGGLE_AUTOCENTER;
174 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_INCREASE] = CUSTOM_ACTION_ZOOM_IN;
175 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_DECREASE] = CUSTOM_ACTION_ZOOM_OUT;
176 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_FULLSCREEN] = CUSTOM_ACTION_TOGGLE_FULLSCREEN;
177 CUSTOM_KEY_DEFAULT[CUSTOM_KEY_ESC] = CUSTOM_ACTION_TOGGLE_TRACKS;
178
179 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_NORTH] = _("Pan North");
180 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_WEST] = _("Pan West");
181 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_SOUTH] = _("Pan South");
182 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_PAN_EAST] = _("Pan East");
183 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_AUTOCENTER] = _("Toggle Auto-Center");
184 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_FULLSCREEN] = _("Toggle Fullscreen");
185 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ZOOM_IN] = _("Zoom In");
186 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ZOOM_OUT] = _("Zoom Out");
187 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_TRACKS] = _("Toggle Tracks");
188 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_SCALE] = _("Toggle Scale");
189 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_POI] = _("Toggle POIs");
190 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_CHANGE_REPO] = _("Select Next Repository");
191 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ROUTE_DISTNEXT] = _("Show Distance to Next Waypoint");
192 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_ROUTE_DISTLAST] = _("Show Distance to End of Route");
193 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TRACK_BREAK] = _("Insert Track Break");
194 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TRACK_DISTLAST] = _("Show Distance from Last Break");
195 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TRACK_DISTFIRST] = _("Show Distance from Beginning");
196 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_GPS] = _("Toggle GPS");
197 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_GPSINFO] = _("Toggle GPS Info");
198 CUSTOM_ACTION_TEXT[CUSTOM_ACTION_TOGGLE_SPEEDLIMIT] = _("Toggle Speed Limit");
199
200 COLORABLE_GCONF[COLORABLE_MARK] = GCONF_KEY_PREFIX "/color_mark";
201 COLORABLE_GCONF[COLORABLE_MARK_VELOCITY] = GCONF_KEY_PREFIX "/color_mark_velocity";
202 COLORABLE_GCONF[COLORABLE_MARK_OLD] = GCONF_KEY_PREFIX "/color_mark_old";
203 COLORABLE_GCONF[COLORABLE_TRACK] = GCONF_KEY_PREFIX "/color_track";
204 COLORABLE_GCONF[COLORABLE_TRACK_MARK] = GCONF_KEY_PREFIX "/color_track_mark";
205 COLORABLE_GCONF[COLORABLE_TRACK_BREAK] = GCONF_KEY_PREFIX "/color_track_break";
206 COLORABLE_GCONF[COLORABLE_ROUTE] = GCONF_KEY_PREFIX "/color_route";
207 COLORABLE_GCONF[COLORABLE_ROUTE_WAY] = GCONF_KEY_PREFIX "/color_route_way";
208 COLORABLE_GCONF[COLORABLE_ROUTE_BREAK] = GCONF_KEY_PREFIX "/color_route_break";
209 COLORABLE_GCONF[COLORABLE_POI] = GCONF_KEY_PREFIX "/color_poi";
210 }
211
212 /**
213  * Save state and destroy all non-UI elements created by this program in
214  * preparation for exiting.
215  */
216 static void 
217 mapper_destroy(void)
218 {
219 config_save();
220 config_save_repo();
221 map_download_deinit();
222 map_poi_deinit();
223
224 #if defined (WITH_GST) 
225 #if defined (WITH_ESPEAK)
226 speak_deinit();
227 #endif
228 audio_note_deinit();
229 #endif
230
231 gps_disconnect(_gps);
232 gps_free(_gps);
233 osm_db_enable_mainloop(_db, FALSE);
234 osm_deinit();
235 db_close(&_db);
236 path_free(_track);
237 path_free(_route);
238 position_free(_home);
239 position_free(_dest);
240
241 gnome_vfs_shutdown();
242 #ifdef WITH_OSSO
243 osso_deinitialize(_osso);
244 #endif
245 #ifdef WITH_HAL
246 if (ctx)
247         libhal_ctx_shutdown(ctx, NULL);
248 #endif
249 curl_global_cleanup();
250 }
251
252 static gint 
253 mapper_osso_init(void)
254 {
255 #ifdef WITH_OSSO
256 /* Initialize _osso. */
257 _osso = osso_initialize("org.tal.mapper", VERSION, TRUE, NULL);
258 if (!_osso) {
259         g_printerr("osso_initialize failed.\n");
260         return 1;
261 }
262 #endif
263 return 0;
264 }
265
266 #ifdef WITH_HAL
267 static void
268 hal_condition_cb(LibHalContext *ctx, const char *udi, const char *name, const char *detail)
269 {
270 g_debug("HAL: [%s]->[%s:%s]", udi, name, detail);
271 if (strcmp(name, "ButtonPressed")==0 && strcmp(detail, "phone")==0)
272         g_idle_add_full(G_PRIORITY_HIGH_IDLE, headphone_button_cb, NULL,NULL);
273 }
274
275 static gboolean
276 mapper_hal_init(DBusGConnection *gdbc)
277 {
278 DBusError error;
279 DBusConnection *dbc=dbus_g_connection_get_connection(gdbc);
280
281 g_return_val_if_fail(dbc, FALSE);
282
283 dbus_error_init(&error);
284
285 ctx=libhal_ctx_new();
286 g_return_val_if_fail(ctx, FALSE);
287
288 if (!libhal_ctx_set_dbus_connection(ctx, dbc)) {
289         g_warning("HAL dbus connection failed");
290         return FALSE;
291 }
292
293 if (!libhal_ctx_init(ctx, &error)) {
294         g_warning("HAL Init failed");
295         ctx=NULL;
296         return FALSE;
297 }
298
299 libhal_ctx_set_device_condition(ctx, hal_condition_cb);
300 libhal_device_add_property_watch(ctx, "/org/freedesktop/Hal/devices/platform_retu_headset_logicaldev_input",NULL);
301
302 return TRUE;
303 }
304 #endif
305
306 static gint 
307 mapper_osso_cb_init(void)
308 {
309 gchar *filter_string;
310
311 #ifdef WITH_OSSO
312 if (OSSO_OK != osso_rpc_set_default_cb_f(_osso, dbus_cb_default, NULL)) {
313         g_printerr("osso_rpc_set_default_cb_f failed.\n");
314         return 1;
315 }
316 #endif
317
318 #ifdef WITH_OSSO_IC
319 filter_string = g_strdup_printf("interface=%s", ICD_DBUS_INTERFACE);
320 /* add match */
321 dbus_bus_add_match(dbus_conn, filter_string, NULL);
322 g_free(filter_string);
323
324 /* add the callback */
325 dbus_connection_add_filter(dbus_conn, get_connection_status_signal_cb, NULL, NULL);
326 osso_iap_cb(iap_callback);
327 #endif
328
329 return 0;
330 }
331
332 static void 
333 timezone_init(void)
334 {
335 time_t time1;
336 struct tm time2;
337
338 time1 = time(NULL);
339 localtime_r(&time1, &time2);
340 _gmtoffset = time2.tm_gmtoff;
341 }
342
343 static gboolean
344 mapper_init(gpointer data)
345 {
346 GError *error = NULL;
347 gboolean ret=TRUE;
348 gfloat p=0;
349 gchar *w="Starting";
350
351 switch (mis) {
352         case MAPPER_INIT_START:
353                 curl_global_init(CURL_GLOBAL_NOTHING);
354                 gnome_vfs_init();
355                 /* XXX: Load GPS configuration, then create gps */
356                 _gps=gps_new(GPS_IO_SIMULATION);
357                 _gps->connection_retry=gps_retry_connection;
358                 _gps->connection_error=NULL;
359                 _gps->connection_progress=gps_conn_set_progress;
360                 _gps->update_location=gps_location_update;
361                 _gps->update_info=gps_info_update;
362
363                 timezone_init();
364                 gpx_init();
365                 variables_init();
366                 latlon_init();
367                 _track=path_new(PATH_TYPE_TRACK, 0);
368                 _route=path_new(PATH_TYPE_ROUTE, 1);
369                 _home=position_new(POSITION_TYPE_HOME, 0);
370                 _dest=position_new(POSITION_TYPE_DESTINATION, 1);
371                 mis=MAPPER_INIT_CONFIG;
372                 p=0.1;
373                 w="Init";
374         break;
375         case MAPPER_INIT_CONFIG:
376                 config_init();
377                 map_download_init();
378                 mis=MAPPER_INIT_DB;
379                 p=0.2;
380                 w="Config";
381         break;
382         case MAPPER_INIT_DB:
383                 if (db_connect(&_db, _mapper_db)) {
384                         mis=MAPPER_INIT_POI;
385                 } else {
386                         mis=MAPPER_INIT_VOICE;
387                 }
388                 p=0.5;
389                 w="Database";
390         break;
391         case MAPPER_INIT_POI:
392                 poi_init(&_db);
393                 mis=MAPPER_INIT_OSM;
394                 p=0.6;
395                 w="POIs";
396         break;
397         case MAPPER_INIT_OSM:
398                 if (osm_init(&_db))
399                         osm_db_enable_mainloop(_db, TRUE);
400                 mis=MAPPER_INIT_VOICE;
401                 p=0.8;
402                 w="OSM";
403         break;
404         case MAPPER_INIT_VOICE:
405 #if defined (WITH_GST)
406                 if (audio_note_init()==FALSE)
407                         g_printerr("Audio note init failed\n");                 
408 #if defined (WITH_ESPEAK)
409                 if (speak_init("en",_voice_speed,_voice_pitch)==FALSE) {
410                         g_printerr("Espeak init failed\n");
411                         popup_error(_window, "Speech init failed. Disabled.");
412                 }
413 #endif
414 #endif
415                 mis=MAPPER_INIT_MISC;
416                 p=0.85;
417                 w="Speech";
418         break;
419         case MAPPER_INIT_MISC:
420                 /* Initialize D-Bus system connection. */
421                 if (NULL == (dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error))) {
422                         g_warning("Failed to open connection to D-Bus: %s.\n", error->message);
423                         popup_error(NULL, "Failed to connect to D-Bus.");
424                         error=NULL;
425                 }
426
427                 /* XXX: Move this */
428 #ifdef WITH_OSSO
429                 osso_hw_set_event_cb(_osso, NULL, osso_cb_hw_state, NULL);
430 #endif
431 #ifdef WITH_HAL
432                 mapper_hal_init(dbus_conn);
433 #endif
434                 mis=MAPPER_INIT_UI;
435                 p=0.9;
436                 w="Misc";
437         break;
438         case MAPPER_INIT_UI:
439                 mapper_ui_init();
440                 mis=MAPPER_INIT_GOTO;
441                 p=0.99;
442                 w="UI";
443         break;
444         case MAPPER_INIT_GOTO:
445                 if (map_goto_position(&_home)==FALSE)
446                         g_printerr("Home is not set.\n");
447                 else
448                         map_center_unit(_center.unitx, _center.unity);
449                 mis=MAPPER_INIT_DONE;
450                 p=1.0;
451                 w="Done";
452         break;
453         case MAPPER_INIT_DONE:
454                 progress_dialog_remove(init_dialog);
455                 if (_enable_gps)   
456                         gps_connect_now(_gps);
457                 return FALSE;
458         break;
459 }
460
461 gtk_progress_bar_set_fraction(GTK_PROGRESS(init_progress), p);
462 gtk_progress_bar_set_text(GTK_PROGRESS(init_progress), w);
463 return ret;
464 }
465
466 gint 
467 main(gint argc, gchar * argv[])
468 {
469 dbus_conn=NULL;
470
471 setlocale(LC_ALL, "");
472 bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
473 bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
474 textdomain(GETTEXT_PACKAGE);
475
476 g_thread_init(NULL);
477 g_type_init();
478 g_set_application_name("Mapper");
479 #if defined (WITH_GST)
480 gst_init(&argc, &argv);
481 #endif
482 gtk_init(&argc, &argv);
483 #if defined (WITH_GL)
484 if (!gtk_gl_init_check(&argc, &argv)) {
485         g_warning("OpenGL init failed");
486 }
487 #endif
488
489 if (mapper_osso_init()!=0)
490         return 1;
491 if (mapper_osso_cb_init()!=0)
492         return 1;
493
494 init_progress=gtk_progress_bar_new();
495 init_dialog=progress_dialog(NULL, "Mapper is loading...",init_progress);
496 gtk_widget_show_all(init_dialog);
497 g_idle_add((GSourceFunc)mapper_init, NULL);
498 gtk_main();
499 mapper_destroy();
500
501 return 0;
502 }