Fix:Core:Minor bugs fixed
[navit-package] / navit / main.c
1 /**
2  * Navit, a modular navigation system.
3  * Copyright (C) 2005-2008 Navit Team
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * version 2 as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19
20 #include <locale.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <getopt.h>
24 #include <string.h>
25 #include <signal.h>
26 #include <glib.h>
27 #include <sys/types.h>
28
29 #ifndef _WIN32
30 #include <sys/wait.h>
31 #include <signal.h>
32 #endif
33
34 #include <unistd.h>
35 #include "config.h"
36 #include "file.h"
37 #include "debug.h"
38 #include "main.h"
39 #include "navit.h"
40 #include "gui.h"
41 #include "xmlconfig.h"
42 #include "item.h"
43 #include "coord.h"
44 #include "route.h"
45 #include "navigation.h"
46 #include "event.h"
47 #include "callback.h"
48 #include "navit_nls.h"
49 #if HAVE_API_WIN32_BASE
50 #include <windows.h>
51 #include <winbase.h>
52 #endif
53
54
55 struct map_data *map_data_default;
56
57 struct callback_list *cbl;
58
59
60 static void sigchld(int sig)
61 {
62 #if !defined(_WIN32) && !defined(__CEGCC__)
63         int status;
64         while (waitpid(-1, &status, WNOHANG) > 0);
65 #endif
66 }
67
68 #if 0
69 static gchar *get_home_directory(void)
70 {
71         static gchar *homedir = NULL;
72
73         if (homedir) return homedir;
74         homedir = getenv("HOME");
75         if (!homedir)
76         {
77                 dbg(0,"Could not find home directory. Using current directory as home directory.\n");
78                 homedir =g_strdup(".");
79         } else {
80                 homedir=g_strdup(homedir);
81         }
82         return homedir;
83 }
84 #endif
85
86 static GList *navit;
87
88 struct iter {
89         GList *list;
90 };
91
92 struct iter *
93 main_iter_new(void)
94 {
95         struct iter *ret=g_new0(struct iter, 1);
96         ret->list=navit;
97         return ret;
98 }
99
100 void
101 main_iter_destroy(struct iter *iter)
102 {
103         g_free(iter);
104 }
105
106 struct navit *
107 main_get_navit(struct iter *iter)
108 {
109         GList *list;
110         struct navit *ret=NULL;
111         if (iter)
112                 list=iter->list;
113         else
114                 list=navit;
115         if (list) {
116                 ret=(struct navit *)(list->data);
117                 if (iter)
118                         iter->list=g_list_next(iter->list);
119         }
120         return ret;
121         
122 }
123 void
124 main_add_navit(struct navit *nav)
125 {
126         navit=g_list_prepend(navit, nav);
127         callback_list_call_2(cbl, nav, 1);
128 }
129
130 void
131 main_remove_navit(struct navit *nav)
132 {
133         navit=g_list_remove(navit, nav);
134         callback_list_call_2(cbl, nav, 0);
135         if (! navit) 
136                 event_main_loop_quit();
137 }
138
139 int
140 main_add_attr(struct attr *attr)
141 {
142         switch (attr->type)
143         {
144         case attr_callback:
145                 callback_list_add(cbl, attr->u.callback);
146                 return 1;
147         default:
148                 return 0;
149         }
150 }
151
152 int
153 main_remove_attr(struct attr *attr)
154 {
155         switch (attr->type)
156         {
157         case attr_callback:
158                 callback_list_remove(cbl, attr->u.callback);
159                 return 1;
160         default:
161                 return 0;
162         }
163 }
164
165
166 #ifdef HAVE_API_WIN32
167 void
168 setenv(char *var, char *val, int overwrite)
169 {
170         char *str=g_strdup_printf("%s=%s",var,val);
171         if (overwrite || !getenv(var)) 
172                 putenv(str);
173         g_free(str);
174 }
175 #endif
176
177 static char *environment_vars[][4]={
178         {"NAVIT_LIBDIR",        ":",            "::/navit",             ":/lib"},
179         {"NAVIT_SHAREDIR",      ":",            ":/share/navit",        ":"},
180         {"NAVIT_LOCALEDIR",     ":/../locale",  ":/share/locale",       ":/locale"},
181         {"NAVIT_USER_DATADIR",  ":",            "~/.navit",             ":/data"},
182         {"NAVIT_LOGFILE",       NULL,           NULL,                   ":/navit.log"},
183         {"NAVIT_LIBPREFIX",     "*/.libs/",     NULL,                   NULL},
184         {NULL,                  NULL,           NULL,                   NULL},
185 };
186
187 static void
188 main_setup_environment(int mode)
189 {
190         int i=0;
191         char *var,*val;
192         while ((var=environment_vars[i][0])) {
193                 val=environment_vars[i][mode+1];
194                 if (val) {
195                         switch (val[0]) {
196                         case ':':
197                                 if (val[1] == ':')
198                                         val=g_strdup_printf("%s/%s%s", getenv("NAVIT_PREFIX"), LIBDIR+sizeof(PREFIX), val+2);
199                                 else
200                                         val=g_strdup_printf("%s%s", getenv("NAVIT_PREFIX"), val+1);
201                                 break;
202                         case '~':
203                                 val=g_strdup_printf("%s%s", getenv("HOME"), val+1);
204                                 break;
205                         default:
206                                 val=g_strdup(val);
207                                 break;
208                         }
209                         setenv(var, val, 0);
210                         g_free(val);
211                 }
212                 i++;
213         }
214 }
215
216 void
217 main_init(char *program)
218 {
219         char *s;
220         int l;
221
222 #ifndef _WIN32
223         signal(SIGCHLD, sigchld);
224 #endif
225         cbl=callback_list_new();
226         setenv("LC_NUMERIC","C",1);
227         setlocale(LC_ALL,"");
228         setlocale(LC_NUMERIC,"C");
229         if (file_exists("navit.c") || file_exists("navit.o") || file_exists("navit.lo")) {
230                 char buffer[PATH_MAX];
231                 printf(_("Running from source directory\n"));
232                 getcwd(buffer, PATH_MAX);
233                 setenv("NAVIT_PREFIX", buffer, 0);
234                 main_setup_environment(0);
235         } else {
236                 if (!getenv("NAVIT_PREFIX")) {
237                         int progpath_len;
238 #ifdef HAVE_API_WIN32_BASE
239                         wchar_t filename[MAX_PATH + 1];
240                         char program[MAX_PATH + 1];
241                         char *cp;
242                         int sz;
243 #ifdef HAVE_API_WIN32
244                         char *progpath="\\bin\\navit.exe";
245                         sz = GetModuleFileNameW(NULL, filename, MAX_PATH);
246 #else
247                         char *progpath="\\navit.exe";
248                         sz = GetModuleFileName(NULL, filename, MAX_PATH);
249 #endif
250                         if (sz > 0) 
251                                 wcstombs(program, filename, sz + 1);
252                         else 
253                                 strcpy(program, PREFIX);
254 #else
255                         char *progpath="/bin/navit";
256 #endif
257                         l=strlen(program);
258                         progpath_len=strlen(progpath);
259                         if (l > progpath_len && !strcmp(program+l-progpath_len,progpath)) {
260                                 s=g_strdup(program);
261                                 s[l-progpath_len]='\0';
262                                 if (strcmp(s, PREFIX))
263                                         printf(_("setting '%s' to '%s'\n"), "NAVIT_PREFIX", s);
264                                 setenv("NAVIT_PREFIX", s, 0);
265                                 g_free(s);
266                         } else
267                                 setenv("NAVIT_PREFIX", PREFIX, 0);
268                 } 
269 #ifdef HAVE_API_WIN32_BASE
270                 setenv("HOME", getenv("NAVIT_PREFIX"), 0);
271 #endif
272
273 #ifdef HAVE_API_WIN32_CE
274                 main_setup_environment(2);
275 #else
276                 main_setup_environment(1);
277 #endif
278         }
279         if (getenv("LC_ALL")) 
280                 dbg(0,"Warning: LC_ALL is set, this might lead to problems\n");
281         s = getenv("NAVIT_WID");
282         if (s) {
283                 setenv("SDL_WINDOWID", s, 0);
284         }
285 }
286
287 void
288 main_init_nls(void)
289 {
290 #ifdef ENABLE_NLS
291 #ifdef FORCE_LOCALE
292 #define STRINGIFY(x) #x
293         setlocale(LC_MESSAGES,STRINGIFY(FORCE_LOCALE));
294 #endif
295         bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
296         bind_textdomain_codeset (PACKAGE, "UTF-8");
297         textdomain(PACKAGE);
298 #endif
299 }