]> git.street.me.uk Git - andy/viking.git/blob - src/modules.c
Fix usage of default maps cache directory when it does not end in a separator.
[andy/viking.git] / src / modules.c
1 /*
2  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3  *
4  * Copyright (C) 2006-2012, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program 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
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <glib.h>
27 #include <glib/gstdio.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31
32 #include "modules.h"
33
34 #include "bing.h"
35 #include "spotmaps.h"
36 #include "google.h"
37 #include "terraserver.h"
38 #include "expedia.h"
39 #include "osm.h"
40 #include "osm-traces.h"
41 #include "bluemarble.h"
42 #include "geonames.h"
43 #include "dir.h"
44 #include "vikmapslayer.h"
45 #include "vikexttools.h"
46 #include "vikexttool_datasources.h"
47 #include "vikgoto.h"
48 #include "vikrouting.h"
49
50 /* Loadable types */
51 #include "vikslippymapsource.h"
52 #include "viktmsmapsource.h"
53 #include "vikwmscmapsource.h"
54 #include "vikwebtoolcenter.h"
55 #include "vikwebtoolbounds.h"
56 #include "vikgotoxmltool.h"
57 #include "vikwebtool_datasource.h"
58 #include "vikroutingwebengine.h"
59
60 #include "vikgobjectbuilder.h"
61
62 #define VIKING_MAPS_FILE "maps.xml"
63 #define VIKING_EXTTOOLS_FILE "external_tools.xml"
64 #define VIKING_DATASOURCES_FILE "datasources.xml"
65 #define VIKING_GOTOTOOLS_FILE "goto_tools.xml"
66 #define VIKING_ROUTING_FILE "routing.xml"
67
68 static void
69 modules_register_map_source(VikGobjectBuilder *self, GObject *object)
70 {
71   g_debug (__FUNCTION__);
72   VikMapSource *mapsource = VIK_MAP_SOURCE (object);
73   /* FIXME label should be hosted by object */
74   maps_layer_register_map_source (mapsource);
75 }
76
77 static void
78 modules_register_exttools(VikGobjectBuilder *self, GObject *object)
79 {
80   g_debug (__FUNCTION__);
81   VikExtTool *tool = VIK_EXT_TOOL (object);
82   vik_ext_tools_register (tool);
83 }
84
85 static void
86 modules_register_datasources(VikGobjectBuilder *self, GObject *object)
87 {
88   g_debug (__FUNCTION__);
89   VikExtTool *tool = VIK_EXT_TOOL (object);
90   vik_ext_tool_datasources_register (tool);
91 }
92
93 static void
94 modules_register_gototools(VikGobjectBuilder *self, GObject *object)
95 {
96   g_debug (__FUNCTION__);
97   VikGotoTool *tool = VIK_GOTO_TOOL (object);
98   vik_goto_register (tool);
99 }
100
101 static void
102 modules_register_routing_engine(VikGobjectBuilder *self, GObject *object)
103 {
104   g_debug (__FUNCTION__);
105   VikRoutingEngine *engine = VIK_ROUTING_ENGINE (object);
106   vik_routing_register (engine);
107 }
108
109 static void
110 modules_load_config_dir(const gchar *dir)
111 {
112   g_debug("Loading configurations from directory %s", dir);
113
114   /* Maps sources */
115   gchar *maps = g_build_filename(dir, VIKING_MAPS_FILE, NULL);
116   if (g_access (maps, R_OK) == 0)
117   {
118         VikGobjectBuilder *builder = vik_gobject_builder_new ();
119         g_signal_connect (builder, "new-object", G_CALLBACK (modules_register_map_source), NULL);
120         vik_gobject_builder_parse (builder, maps);
121         g_object_unref (builder);
122   }
123
124   /* External tools */
125   gchar *tools = g_build_filename(dir, VIKING_EXTTOOLS_FILE, NULL);
126   if (g_access (tools, R_OK) == 0)
127   {
128         VikGobjectBuilder *builder = vik_gobject_builder_new ();
129         g_signal_connect (builder, "new-object", G_CALLBACK (modules_register_exttools), NULL);
130         vik_gobject_builder_parse (builder, tools);
131         g_object_unref (builder);
132   }
133
134   gchar *datasources = g_build_filename(dir, VIKING_DATASOURCES_FILE, NULL);
135   if (g_access (datasources, R_OK) == 0)
136   {
137         VikGobjectBuilder *builder = vik_gobject_builder_new ();
138         g_signal_connect (builder, "new-object", G_CALLBACK (modules_register_datasources), NULL);
139         vik_gobject_builder_parse (builder, datasources);
140         g_object_unref (builder);
141   }
142
143   /* Go-to search engines */
144   gchar *go_to = g_build_filename(dir, VIKING_GOTOTOOLS_FILE, NULL);
145   if (g_access (go_to, R_OK) == 0)
146   {
147         VikGobjectBuilder *builder = vik_gobject_builder_new ();
148         g_signal_connect (builder, "new-object", G_CALLBACK (modules_register_gototools), NULL);
149         vik_gobject_builder_parse (builder, go_to);
150         g_object_unref (builder);
151   }
152
153   /* Routing engines */
154   gchar *routing = g_build_filename(dir, VIKING_ROUTING_FILE, NULL);
155   if (g_access (routing, R_OK) == 0)
156   {
157         VikGobjectBuilder *builder = vik_gobject_builder_new ();
158         g_signal_connect (builder, "new-object", G_CALLBACK (modules_register_routing_engine), NULL);
159         vik_gobject_builder_parse (builder, routing);
160         g_object_unref (builder);
161   }
162 }
163
164 static void
165 modules_load_config(void)
166 {
167   /* Look in the directories of data path */
168   gchar * * data_dirs = a_get_viking_data_path();
169   /* Priority is standard one:
170      left element is more important than right one.
171      But our logic is to load all existing files and overwrite
172      overlapping config with last recent one.
173      So, we have to process directories in reverse order. */
174   /* First: find the last element */
175   gchar * * ptr = data_dirs;
176   while (*ptr != NULL) ptr++;
177   /* Second: deduce the number of directories */
178   int nb_data_dirs = 0;
179   nb_data_dirs = ptr - data_dirs;
180   /* Last: parse them in reverse order */
181   for (; nb_data_dirs > 0 ; nb_data_dirs--)
182   {
183     modules_load_config_dir(data_dirs[nb_data_dirs-1]);
184   }
185   g_strfreev(data_dirs);
186         
187   /* Check if system config is set */
188   modules_load_config_dir(VIKING_SYSCONFDIR);
189
190   const gchar *data_home = a_get_viking_data_home ();
191   if (data_home)
192   {
193     modules_load_config_dir(data_home);
194   }
195         
196   /* Check user's home config */
197   modules_load_config_dir(a_get_viking_dir());
198 }
199
200 static void
201 register_loadable_types(void)
202 {
203   /* Force registering of loadable types */
204   volatile GType types[] = {
205     /* Maps */
206     VIK_TYPE_SLIPPY_MAP_SOURCE,
207     VIK_TYPE_TMS_MAP_SOURCE,
208     VIK_TYPE_WMSC_MAP_SOURCE,
209
210     /* Goto */
211     VIK_GOTO_XML_TOOL_TYPE,
212
213     /* Tools */
214     VIK_WEBTOOL_CENTER_TYPE,
215     VIK_WEBTOOL_BOUNDS_TYPE,
216
217     /* Datasource */
218     VIK_WEBTOOL_DATASOURCE_TYPE,
219
220     /* Routing */
221     VIK_ROUTING_WEB_ENGINE_TYPE
222   };
223
224   /* kill 'unused variable'  warning */
225   g_debug("%ld types loaded", sizeof(types)/sizeof(GType));
226 }
227
228 void modules_init()
229 {
230 #ifdef VIK_CONFIG_BING
231   bing_init();
232 #endif
233 #ifdef VIK_CONFIG_GOOGLE 
234   google_init();
235 #endif
236 #ifdef VIK_CONFIG_EXPEDIA
237   expedia_init();
238 #endif
239 #ifdef VIK_CONFIG_TERRASERVER
240   terraserver_init();
241 #endif
242 #ifdef VIK_CONFIG_OPENSTREETMAP
243   osm_init();
244   osm_traces_init();
245 #endif
246 #ifdef VIK_CONFIG_BLUEMARBLE
247   bluemarble_init();
248 #endif
249 #ifdef VIK_CONFIG_GEONAMES
250   geonames_init();
251 #endif
252 #ifdef VIK_CONFIG_SPOTMAPS
253   spotmaps_init();
254 #endif
255
256   register_loadable_types ();
257
258   /* As modules are loaded, we can load configuration files */
259   modules_load_config ();
260 }
261