Fix:Core:Fixes ticket #14 : Start navit with the view centered on last position ...
[navit-package] / navit / main.c
1 #include <locale.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <getopt.h>
5 #include <string.h>
6 #include <signal.h>
7 #include <glib.h>
8 #include <sys/types.h>
9
10 #ifndef _WIN32
11 #include <sys/wait.h>
12 #include <signal.h>
13 #endif
14
15 #include <unistd.h>
16 #include <libintl.h>
17 #include "config.h"
18 #include "file.h"
19 #include "debug.h"
20 #include "main.h"
21 #include "navit.h"
22 #include "gui.h"
23 #include "xmlconfig.h"
24 #include "item.h"
25 #include "coord.h"
26 #include "route.h"
27 #include "navigation.h"
28 #include "event.h"
29
30 #define _(STRING)    gettext(STRING)
31
32 struct map_data *map_data_default;
33
34 static void sigchld(int sig)
35 {
36 #ifndef _WIN32
37         int status;
38         while (waitpid(-1, &status, WNOHANG) > 0);
39 #endif
40 }
41
42
43 gchar *get_home_directory(void)
44 {
45         static gchar *homedir = NULL;
46
47         if (homedir) return homedir;
48         homedir = getenv("HOME");
49         if (!homedir)
50         {
51                 g_warning("Could not find home directory. Using current directory as home directory.");
52                 homedir = ".";
53         }
54         return homedir;
55 }
56
57 static GList *navit;
58
59 struct iter {
60         GList *list;
61 };
62
63 struct iter *
64 main_iter_new(void)
65 {
66         struct iter *ret=g_new0(struct iter, 1);
67         ret->list=navit;
68         return ret;
69 }
70
71 void
72 main_iter_destroy(struct iter *iter)
73 {
74         g_free(iter);
75 }
76
77 struct navit *
78 main_get_navit(struct iter *iter)
79 {
80         GList *list;
81         struct navit *ret=NULL;
82         if (iter)
83                 list=iter->list;
84         else
85                 list=navit;
86         if (list) {
87                 ret=(struct navit *)(list->data);
88                 if (iter)
89                         iter->list=g_list_next(iter->list);
90         }
91         return ret;
92         
93 }
94 void
95 main_add_navit(struct navit *nav)
96 {
97         navit=g_list_prepend(navit, nav);
98 }
99
100 void
101 main_remove_navit(struct navit *nav)
102 {
103         navit=g_list_remove(navit, nav);
104         if (! navit) 
105                 event_main_loop_quit();
106 }
107
108 void
109 print_usage(void)
110 {
111         printf(_("navit usage:\nnavit [options] [configfile]\n\t-c <file>: use <file> as config file\n\t-d <n>: set the debug output level to <n>. (TODO)\n\t-h: print this usage info and exit.\n\t-v: Print the version and exit.\n"));
112 }
113
114 int main(int argc, char **argv)
115 {
116         GError *error = NULL;
117         char *config_file = NULL;
118         char *s;
119         int l;
120
121
122 #ifndef _WIN32
123         signal(SIGCHLD, sigchld);
124 #endif
125
126         setenv("LC_NUMERIC","C",1);
127         setlocale(LC_ALL,"");
128         setlocale(LC_NUMERIC,"C");
129         if (file_exists("navit.c") || file_exists("navit.o")) {
130                 char buffer[PATH_MAX];
131                 printf(_("Running from source directory\n"));
132                 getcwd(buffer, PATH_MAX);
133                 setenv("NAVIT_PREFIX", buffer, 0);
134                 setenv("NAVIT_LIBDIR", buffer, 0);
135                 setenv("NAVIT_SHAREDIR", buffer, 0);
136                 setenv("NAVIT_LIBPREFIX", "*/.libs/", 0);
137                 s=g_strdup_printf("%s/../locale", buffer);
138                 setenv("NAVIT_LOCALEDIR", s, 0);
139                 g_free(s);
140         } else {
141                 if (!getenv("NAVIT_PREFIX")) {
142                         l=strlen(argv[0]);
143                         if (l > 10 && !strcmp(argv[0]+l-10,"/bin/navit")) {
144                                 s=g_strdup(argv[0]);
145                                 s[l-10]='\0';
146                                 if (strcmp(s, PREFIX))
147                                         printf(_("setting '%s' to '%s'\n"), "NAVIT_PREFIX", s);
148                                 setenv("NAVIT_PREFIX", s, 0);
149                                 g_free(s);
150                         } else
151                                 setenv("NAVIT_PREFIX", PREFIX, 0);
152                 }
153 #ifdef _WIN32
154                 s=g_strdup_printf("locale");
155 #else
156                 s=g_strdup_printf("%s/share/locale", getenv("NAVIT_PREFIX"));
157 #endif
158                 setenv("NAVIT_LOCALEDIR", s, 0);
159                 g_free(s);
160 #ifdef _WIN32
161                 s=g_strdup_printf(".");
162 #else
163                 s=g_strdup_printf("%s/share/navit", getenv("NAVIT_PREFIX"));
164 #endif
165                 setenv("NAVIT_SHAREDIR", s, 0);
166                 g_free(s);
167                 s=g_strdup_printf("%s/lib/navit", getenv("NAVIT_PREFIX"));
168                 setenv("NAVIT_LIBDIR", s, 0);
169                 g_free(s);
170         }
171         bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
172         bind_textdomain_codeset (PACKAGE, "UTF-8");
173         textdomain(PACKAGE);
174
175         debug_init(argv[0]);
176         if (getenv("LC_ALL")) 
177                 dbg(0,"Warning: LC_ALL is set, this might lead to problems\n");
178 #ifndef USE_PLUGINS
179         extern void builtin_init(void);
180         builtin_init();
181 #endif
182 #if 0
183         /* handled in gui/gtk */
184         gtk_set_locale();
185         gtk_init(&argc, &argv);
186         gdk_rgb_init();
187 #endif
188         s = getenv("NAVIT_WID");
189         if (s) {
190                 setenv("SDL_WINDOWID", s, 0);
191         }
192         route_init();
193         navigation_init();
194         config_file=NULL;
195         int opt;
196         opterr=0;  //don't bomb out on errors.
197         if (argc > 1) {
198                 while((opt = getopt(argc, argv, ":hvc:d:")) != -1) {
199                         switch(opt) {
200                         case 'h':
201                                 print_usage();
202                                 exit(0);
203                                 break;
204                         case 'v':
205                                 printf("%s %s\n", "navit", "0.0.4+svn"); 
206                                 exit(0);
207                                 break;
208                         case 'c':
209                                 printf("config file n is set to `%s'\n", optarg);
210                     config_file = optarg;
211                                 break;
212                         case 'd':
213                                 printf("TODO Verbose option is set to `%s'\n", optarg);
214                                 break;
215                         case ':':
216                                 fprintf(stderr, "navit: Error - Option `%c' needs a value\n", optopt);
217                                 print_usage();
218                                 exit(1);
219                                 break;
220                         case '?':
221                                 fprintf(stderr, "navit: Error - No such option: `%c'\n", optopt);
222                                 print_usage();
223                                 exit(1);
224                         }
225             }
226         }
227         // use 1st cmd line option that is left for the config file
228         if (optind < argc) config_file = argv[optind];
229
230     GList *list = NULL, *li;
231     // if config file is explicitely given only look for it, otherwise try std paths
232         if (config_file) list = g_list_append(list,g_strdup(config_file));
233     else {
234                 list = g_list_append(list,g_strjoin(NULL,get_home_directory(), "/.navit/navit.xml" , NULL));
235                 list = g_list_append(list,g_strdup("navit.xml.local"));
236                 list = g_list_append(list,g_strdup("navit.xml"));
237                 list = g_list_append(list,g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml.local" , NULL));
238                 list = g_list_append(list,g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml" , NULL));
239         }
240         li = list;
241         do {
242                 if (li == NULL) {
243                         // We have not found an existing config file from all possibilities
244                         printf(_("No config file navit.xml, navit.xml.local found\n"));
245                         exit(1);
246                 }
247         // Try the next config file possibility from the list
248                 config_file = li->data;
249                 if (!file_exists(config_file)) g_free(config_file);
250                 li = g_list_next(li);
251         } while (!file_exists(config_file));
252         g_list_free(list);
253
254         if (!config_load(config_file, &error)) {
255                 printf(_("Error parsing '%s': %s\n"), config_file, error->message);
256                 exit(1);
257         } else {
258                 printf(_("Using '%s'\n"), config_file);
259         }
260         if (! navit) {
261                 printf(_("No instance has been created, exiting\n"));
262                 exit(1);
263         }
264         if (main_loop_gui) {
265                 gui_run_main_loop(main_loop_gui);
266         } else 
267                 event_main_loop_run();
268
269         return 0;
270 }