Fix:Core:Re-Enabled log file for windows
[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 "item.h"
42 #include "xmlconfig.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 static GList *navit;
69
70 struct iter {
71         GList *list;
72 };
73
74 struct iter *
75 main_iter_new(void)
76 {
77         struct iter *ret=g_new0(struct iter, 1);
78         ret->list=navit;
79         return ret;
80 }
81
82 void
83 main_iter_destroy(struct iter *iter)
84 {
85         g_free(iter);
86 }
87
88 struct navit *
89 main_get_navit(struct iter *iter)
90 {
91         GList *list;
92         struct navit *ret=NULL;
93         if (iter)
94                 list=iter->list;
95         else
96                 list=navit;
97         if (list) {
98                 ret=(struct navit *)(list->data);
99                 if (iter)
100                         iter->list=g_list_next(iter->list);
101         }
102         return ret;
103
104 }
105 void
106 main_add_navit(struct navit *nav)
107 {
108         navit=g_list_prepend(navit, nav);
109         callback_list_call_2(cbl, nav, 1);
110 }
111
112 void
113 main_remove_navit(struct navit *nav)
114 {
115         navit=g_list_remove(navit, nav);
116         callback_list_call_2(cbl, nav, 0);
117         if (! navit)
118                 event_main_loop_quit();
119 }
120
121 int
122 main_add_attr(struct attr *attr)
123 {
124         switch (attr->type)
125         {
126         case attr_callback:
127                 callback_list_add(cbl, attr->u.callback);
128                 return 1;
129         default:
130                 return 0;
131         }
132 }
133
134 int
135 main_remove_attr(struct attr *attr)
136 {
137         switch (attr->type)
138         {
139         case attr_callback:
140                 callback_list_remove(cbl, attr->u.callback);
141                 return 1;
142         default:
143                 return 0;
144         }
145 }
146
147
148 #ifdef HAVE_API_WIN32
149 void
150 setenv(char *var, char *val, int overwrite)
151 {
152         char *str=g_strdup_printf("%s=%s",var,val);
153         if (overwrite || !getenv(var))
154                 putenv(str);
155         g_free(str);
156 }
157 #endif
158
159 /*
160  * environment_vars[][0:name,1-3:mode]
161  * ':'  replaced with NAVIT_PREFIX
162  * '::' replaced with NAVIT_PREFIX and LIBDIR
163  * '~'  replaced with HOME
164 */
165 static char *environment_vars[][5]={
166         {"NAVIT_LIBDIR",      ":",          "::/navit",      ":\\lib",      ":/lib"},
167         {"NAVIT_SHAREDIR",    ":",          ":/share/navit", ":",           ":/share"},
168         {"NAVIT_LOCALEDIR",   ":/../locale",":/share/locale",":\\locale",   ":/locale"},
169         {"NAVIT_USER_DATADIR",":",          "~/.navit",      ":\\data",     ":/home"},
170 #if 1
171         {"NAVIT_LOGFILE",     NULL,         NULL,            ":\\navit.log",NULL},
172 #endif
173         {"NAVIT_LIBPREFIX",   "*/.libs/",   NULL,            NULL,          NULL},
174         {NULL,                NULL,         NULL,            NULL,          NULL},
175 };
176
177 static void
178 main_setup_environment(int mode)
179 {
180         int i=0;
181         char *var,*val,*homedir;
182         while ((var=environment_vars[i][0])) {
183                 val=environment_vars[i][mode+1];
184                 if (val) {
185                         switch (val[0]) {
186                         case ':':
187                                 if (val[1] == ':')
188                                         val=g_strdup_printf("%s/%s%s", getenv("NAVIT_PREFIX"), LIBDIR+sizeof(PREFIX), val+2);
189                                 else
190                                         val=g_strdup_printf("%s%s", getenv("NAVIT_PREFIX"), val+1);
191                                 break;
192                         case '~':
193                                 homedir=getenv("HOME");
194                                 if (!homedir)
195                                         homedir="./";
196                                 val=g_strdup_printf("%s%s", homedir, val+1);
197                                 break;
198                         default:
199                                 val=g_strdup(val);
200                                 break;
201                         }
202                         setenv(var, val, 0);
203                         g_free(val);
204                 }
205                 i++;
206         }
207 }
208
209 void
210 main_init(char *program)
211 {
212         char *s;
213         int l;
214
215 #ifndef _WIN32
216         signal(SIGCHLD, sigchld);
217 #endif
218         cbl=callback_list_new();
219         setenv("LC_NUMERIC","C",1);
220         setlocale(LC_ALL,"");
221         setlocale(LC_NUMERIC,"C");
222 #if !defined _WIN32 && !defined _WIN32_WCE
223         if (file_exists("navit.c") || file_exists("navit.o") || file_exists("navit.lo")) {
224                 char buffer[PATH_MAX];
225                 printf(_("Running from source directory\n"));
226                 getcwd(buffer, PATH_MAX);               /* libc of navit returns "dummy" */
227                 setenv("NAVIT_PREFIX", buffer, 0);
228                 main_setup_environment(0);
229         } else {
230                 if (!getenv("NAVIT_PREFIX")) {
231                 int progpath_len;
232                         char *progpath="/bin/navit";
233                         l=strlen(program);
234                         progpath_len=strlen(progpath);
235                         if (l > progpath_len && !strcmp(program+l-progpath_len,progpath)) {
236                                 s=g_strdup(program);
237                                 s[l-progpath_len]='\0';
238                                 if (strcmp(s, PREFIX))
239                                         printf(_("setting '%s' to '%s'\n"), "NAVIT_PREFIX", s);
240                                 setenv("NAVIT_PREFIX", s, 0);
241                                 g_free(s);
242                         } else
243                                 setenv("NAVIT_PREFIX", PREFIX, 0);
244                 }
245 #ifdef HAVE_API_ANDROID
246                 main_setup_environment(3);
247 #else
248                 main_setup_environment(1);
249 #endif
250         }
251
252 #else           /* _WIN32 || _WIN32_WCE */
253         if (!getenv("NAVIT_PREFIX"))
254         {
255                 char  filename[MAX_PATH + 1],
256                      *end;
257
258                 *filename = '\0';
259 #ifdef _UNICODE         /* currently for wince */
260                 wchar_t wfilename[MAX_PATH + 1];
261                 if (GetModuleFileNameW(NULL, wfilename, MAX_PATH))
262                 {
263                         wcstombs(filename, wfilename, MAX_PATH);
264 #else
265                 if (GetModuleFileName(NULL, filename, MAX_PATH))
266                 {
267 #endif
268                         end = strrchr(filename, L'\\'); /* eliminate the file name which is on the right side */
269                         if(end)
270                                 *end = '\0';
271                 }
272                 setenv("NAVIT_PREFIX", filename, 0);
273         }
274         if (!getenv("HOME"))
275                 setenv("HOME", getenv("NAVIT_PREFIX"), 0);
276         main_setup_environment(2);
277 #endif  /* _WIN32 || _WIN32_WCE */
278
279         if (getenv("LC_ALL"))
280                 dbg(0,"Warning: LC_ALL is set, this might lead to problems (e.g. strange positions from GPS)\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 STRINGIFY2(x) #x
293 #define STRINGIFY(x) STRINGIFY2(x)
294         setlocale(LC_MESSAGES,STRINGIFY(FORCE_LOCALE));
295 #endif
296         bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
297         bind_textdomain_codeset (PACKAGE, "UTF-8");
298         textdomain(PACKAGE);
299 #endif
300 }