94ae4b384999917d7d828411377374f4792b251d
[profile/ivi/navit.git] / navit / 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 <string.h>
24 #include <signal.h>
25 #include <glib.h>
26 #include <sys/types.h>
27
28 #include "config.h"
29
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33
34 #ifndef _WIN32
35 #include <sys/wait.h>
36 #include <signal.h>
37 #endif
38
39 #include "file.h"
40 #include "debug.h"
41 #include "main.h"
42 #include "navit.h"
43 #include "gui.h"
44 #include "item.h"
45 #include "xmlconfig.h"
46 #include "coord.h"
47 #include "route.h"
48 #include "navigation.h"
49 #include "event.h"
50 #include "callback.h"
51 #include "navit_nls.h"
52 #include "util.h"
53 #if HAVE_API_WIN32_BASE
54 #include <windows.h>
55 #include <winbase.h>
56 #endif
57
58 #ifdef HAVE_API_WIN32_CE
59 #include "libc.h"
60 #endif
61
62 struct map_data *map_data_default;
63
64 struct callback_list *cbl;
65
66 #ifdef HAVE_API_WIN32
67 void
68 setenv(char *var, char *val, int overwrite)
69 {
70         char *str=g_strdup_printf("%s=%s",var,val);
71         if (overwrite || !getenv(var))
72                 putenv(str);
73         g_free(str);
74 }
75 #endif
76
77 /*
78  * environment_vars[][0:name,1-3:mode]
79  * ':'  replaced with NAVIT_PREFIX
80  * '::' replaced with NAVIT_PREFIX and LIBDIR
81  * '~'  replaced with HOME
82 */
83 static char *environment_vars[][5]={
84         {"NAVIT_LIBDIR",      ":",          "::/navit",      ":\\lib",      ":/lib"},
85         {"NAVIT_SHAREDIR",    ":",          ":/share/navit", ":",           ":/share"},
86         {"NAVIT_LOCALEDIR",   ":/../locale",":/share/locale",":\\locale",   ":/locale"},
87         {"NAVIT_USER_DATADIR",":",          "~/.navit",      ":\\data",     ":/home"},
88 #if 1
89         {"NAVIT_LOGFILE",     NULL,         NULL,            ":\\navit.log",NULL},
90 #endif
91         {"NAVIT_LIBPREFIX",   "*/.libs/",   NULL,            NULL,          NULL},
92         {NULL,                NULL,         NULL,            NULL,          NULL},
93 };
94
95 static void
96 main_setup_environment(int mode)
97 {
98         int i=0;
99         char *var,*val,*homedir;
100         while ((var=environment_vars[i][0])) {
101                 val=environment_vars[i][mode+1];
102                 if (val) {
103                         switch (val[0]) {
104                         case ':':
105                                 if (val[1] == ':')
106                                         val=g_strdup_printf("%s/%s%s", getenv("NAVIT_PREFIX"), LIBDIR+sizeof(PREFIX), val+2);
107                                 else
108                                         val=g_strdup_printf("%s%s", getenv("NAVIT_PREFIX"), val+1);
109                                 break;
110                         case '~':
111                                 homedir=getenv("HOME");
112                                 if (!homedir)
113                                         homedir="./";
114                                 val=g_strdup_printf("%s%s", homedir, val+1);
115                                 break;
116                         default:
117                                 val=g_strdup(val);
118                                 break;
119                         }
120                         setenv(var, val, 0);
121                         g_free(val);
122                 }
123                 i++;
124         }
125 }
126
127 #ifdef HAVE_API_WIN32_BASE
128 char *nls_table[][3]={
129         // NLS Table compiled by Nick "Number6" Geoghegan
130         // Not an exhaustive list, but supports 99% of all languages in Windows
131         //{"LANGNAME", "CTRYNAME", "Language Code"},
132         {"AFK", "ZAF", "af_ZA"},        // Afrikaans (South Africa)
133         {"SQI", "ALB", "sq_AL"},        // Albanian (Albania)
134         {"AMH", "ETH", "am_ET"},        // Amharic (Ethiopia)
135         {"ARG", "DZA", "ar_DZ"},        // Arabic (Algeria)
136         {"ARH", "BHR", "ar_BH"},        // Arabic (Bahrain)
137         {"ARE", "EGY", "ar_EG"},        // Arabic (Egypt)
138         {"ARI", "IRQ", "ar_IQ"},        // Arabic (Iraq)
139         {"ARJ", "JOR", "ar_JO"},        // Arabic (Jordan)
140         {"ARK", "KWT", "ar_KW"},        // Arabic (Kuwait)
141         {"ARB", "LBN", "ar_LB"},        // Arabic (Lebanon)
142         {"ARL", "LBY", "ar_LY"},        // Arabic (Libya)
143         {"ARM", "MAR", "ar_MA"},        // Arabic (Morocco)
144         {"ARO", "OMN", "ar_OM"},        // Arabic (Oman)
145         {"ARQ", "QAT", "ar_QA"},        // Arabic (Qatar)
146         {"ARA", "SAU", "ar_SA"},        // Arabic (Saudi Arabia)
147         {"ARS", "SYR", "ar_SY"},        // Arabic (Syria)
148         {"ART", "TUN", "ar_TN"},        // Arabic (Tunisia)
149         {"ARU", "ARE", "ar_AE"},        // Arabic (U.A.E.)
150         {"ARY", "YEM", "ar_YE"},        // Arabic (Yemen)
151         {"HYE", "ARM", "hy_AM"},        // Armenian (Armenia)
152         {"ASM", "IND", "as_IN"},        // Assamese (India)
153         {"BAS", "RUS", "ba_RU"},        // Bashkir (Russia)
154         {"EUQ", "ESP", "eu_ES"},        // Basque (Basque)
155         {"BEL", "BLR", "be_BY"},        // Belarusian (Belarus)
156         {"BNG", "BDG", "bn_BD"},        // Bengali (Bangladesh)
157         {"BNG", "IND", "bn_IN"},        // Bengali (India)
158         {"BRE", "FRA", "br_FR"},        // Breton (France)
159         {"BGR", "BGR", "bg_BG"},        // Bulgarian (Bulgaria)
160         {"CAT", "ESP", "ca_ES"},        // Catalan (Catalan)
161         {"ZHH", "HKG", "zh_HK"},        // Chinese (Hong Kong S.A.R.)
162         {"ZHM", "MCO", "zh_MO"},        // Chinese (Macao S.A.R.)
163         {"CHS", "CHN", "zh_CN"},        // Chinese (People's Republic of China)
164         {"ZHI", "SGP", "zh_SG"},        // Chinese (Singapore)
165         {"CHT", "TWN", "zh_TW"},        // Chinese (Taiwan)
166         {"COS", "FRA", "co_FR"},        // Corsican (France)
167         {"HRV", "HRV", "hr_HR"},        // Croatian (Croatia)
168         {"HRB", "BIH", "hr_BA"},        // Croatian (Latin, Bosnia and Herzegovina)
169         {"CSY", "CZE", "cs_CZ"},        // Czech (Czech Republic)
170         {"DAN", "DNK", "da_DK"},        // Danish (Denmark)
171         {"NLB", "BEL", "nl_BE"},        // Dutch (Belgium)
172         {"NLD", "NLD", "nl_NL"},        // Dutch (Netherlands)
173         {"ENA", "AUS", "en_AU"},        // English (Australia)
174         {"ENL", "BLZ", "en_BZ"},        // English (Belize)
175         {"ENC", "CAN", "en_CA"},        // English (Canada)
176         {"ENB", "CAR", "en_CB"},        // English (Caribbean)
177         {"ENN", "IND", "en_IN"},        // English (India)
178         {"ENI", "IRL", "en_IE"},        // English (Ireland)
179         {"ENJ", "JAM", "en_JM"},        // English (Jamaica)
180         {"ENM", "MYS", "en_MY"},        // English (Malaysia)
181         {"ENZ", "NZL", "en_NZ"},        // English (New Zealand)
182         {"ENP", "PHL", "en_PH"},        // English (Republic of the Philippines)
183         {"ENE", "SGP", "en_SG"},        // English (Singapore)
184         {"ENS", "ZAF", "en_ZA"},        // English (South Africa)
185         {"ENT", "TTO", "en_TT"},        // English (Trinidad and Tobago)
186         {"ENG", "GBR", "en_GB"},        // English (United Kingdom)
187         {"ENU", "USA", "en_US"},        // English (United States)
188         {"ENW", "ZWE", "en_ZW"},        // English (Zimbabwe)
189         {"ETI", "EST", "et_EE"},        // Estonian (Estonia)
190         {"FOS", "FRO", "fo_FO"},        // Faroese (Faroe Islands)
191         {"FIN", "FIN", "fi_FI"},        // Finnish (Finland)
192         {"FRB", "BEL", "fr_BE"},        // French (Belgium)
193         {"FRC", "CAN", "fr_CA"},        // French (Canada)
194         {"FRA", "FRA", "fr_FR"},        // French (France)
195         {"FRL", "LUX", "fr_LU"},        // French (Luxembourg)
196         {"FRM", "MCO", "fr_MC"},        // French (Principality of Monaco)
197         {"FRS", "CHE", "fr_CH"},        // French (Switzerland)
198         {"FYN", "NLD", "fy_NL"},        // Frisian (Netherlands)
199         {"GLC", "ESP", "gl_ES"},        // Galician (Galician)
200         {"KAT", "GEO", "ka_GE"},        // Georgian (Georgia)
201         {"DEA", "AUT", "de_AT"},        // German (Austria)
202         {"DEU", "DEU", "de_DE"},        // German (Germany)
203         {"DEC", "LIE", "de_LI"},        // German (Liechtenstein)
204         {"DEL", "LUX", "de_LU"},        // German (Luxembourg)
205         {"DES", "CHE", "de_CH"},        // German (Switzerland)
206         {"ELL", "GRC", "el_GR"},        // Greek (Greece)
207         {"KAL", "GRL", "kl_GL"},        // Greenlandic (Greenland)
208         {"GUJ", "IND", "gu_IN"},        // Gujarati (India)
209         {"HEB", "ISR", "he_IL"},        // Hebrew (Israel)
210         {"HIN", "IND", "hi_IN"},        // Hindi (India)
211         {"HUN", "HUN", "hu_HU"},        // Hungarian (Hungary)
212         {"ISL", "ISL", "is_IS"},        // Icelandic (Iceland)
213         {"IBO", "NGA", "ig_NG"},        // Igbo (Nigeria)
214         {"IND", "IDN", "id_ID"},        // Indonesian (Indonesia)
215         {"IRE", "IRL", "ga_IE"},        // Irish (Ireland)
216         {"XHO", "ZAF", "xh_ZA"},        // isiXhosa (South Africa)
217         {"ZUL", "ZAF", "zu_ZA"},        // isiZulu (South Africa)
218         {"ITA", "ITA", "it_IT"},        // Italian (Italy)
219         {"ITS", "CHE", "it_CH"},        // Italian (Switzerland)
220         {"JPN", "JPN", "ja_JP"},        // Japanese (Japan)
221         {"KDI", "IND", "kn_IN"},        // Kannada (India)
222         {"KKZ", "KAZ", "kk_KZ"},        // Kazakh (Kazakhstan)
223         {"KHM", "KHM", "km_KH"},        // Khmer (Cambodia)
224         {"KIN", "RWA", "rw_RW"},        // Kinyarwanda (Rwanda)
225         {"SWK", "KEN", "sw_KE"},        // Kiswahili (Kenya)
226         {"KOR", "KOR", "ko_KR"},        // Korean (Korea)
227         {"KYR", "KGZ", "ky_KG"},        // Kyrgyz (Kyrgyzstan)
228         {"LAO", "LAO", "lo_LA"},        // Lao (Lao P.D.R.)
229         {"LVI", "LVA", "lv_LV"},        // Latvian (Latvia)
230         {"LTH", "LTU", "lt_LT"},        // Lithuanian (Lithuania)
231         {"LBX", "LUX", "lb_LU"},        // Luxembourgish (Luxembourg)
232         {"MKI", "MKD", "mk_MK"},        // Macedonian (Former Yugoslav Republic of Macedonia)
233         {"MSB", "BRN", "ms_BN"},        // Malay (Brunei Darussalam)
234         {"MSL", "MYS", "ms_MY"},        // Malay (Malaysia)
235         {"MYM", "IND", "ml_IN"},        // Malayalam (India)
236         {"MLT", "MLT", "mt_MT"},        // Maltese (Malta)
237         {"MRI", "NZL", "mi_NZ"},        // Maori (New Zealand)
238         {"MAR", "IND", "mr_IN"},        // Marathi (India)
239         {"MON", "MNG", "mn_MN"},        // Mongolian (Cyrillic, Mongolia)
240         {"NEP", "NEP", "ne_NP"},        // Nepali (Nepal)
241         {"NOR", "NOR", "nb_NO"},        // Norwegian, BokmÃ¥(Norway)
242         {"NON", "NOR", "nn_NO"},        // Norwegian, Nynorsk (Norway)
243         {"OCI", "FRA", "oc_FR"},        // Occitan (France)
244         {"ORI", "IND", "or_IN"},        // Oriya (India)
245         {"PAS", "AFG", "ps_AF"},        // Pashto (Afghanistan)
246         {"FAR", "IRN", "fa_IR"},        // Persian
247         {"PLK", "POL", "pl_PL"},        // Polish (Poland)
248         {"PTB", "BRA", "pt_BR"},        // Portuguese (Brazil)
249         {"PTG", "PRT", "pt_PT"},        // Portuguese (Portugal)
250         {"PAN", "IND", "pa_IN"},        // Punjabi (India)
251         {"ROM", "ROM", "ro_RO"},        // Romanian (Romania)
252         {"RMC", "CHE", "rm_CH"},        // Romansh (Switzerland)
253         {"RUS", "RUS", "ru_RU"},        // Russian (Russia)
254         {"SMG", "FIN", "se_FI"},        // Sami, Northern (Finland)
255         {"SME", "NOR", "se_NO"},        // Sami, Northern (Norway)
256         {"SMF", "SWE", "se_SE"},        // Sami, Northern (Sweden)
257         {"SAN", "IND", "sa_IN"},        // Sanskrit (India)
258         {"TSN", "ZAF", "tn_ZA"},        // Setswana (South Africa)
259         {"SIN", "LKA", "si_LK"},        // Sinhala (Sri Lanka)
260         {"SKY", "SVK", "sk_SK"},        // Slovak (Slovakia)
261         {"SLV", "SVN", "sl_SI"},        // Slovenian (Slovenia)
262         {"ESS", "ARG", "es_AR"},        // Spanish (Argentina)
263         {"ESB", "BOL", "es_BO"},        // Spanish (Bolivia)
264         {"ESL", "CHL", "es_CL"},        // Spanish (Chile)
265         {"ESO", "COL", "es_CO"},        // Spanish (Colombia)
266         {"ESC", "CRI", "es_CR"},        // Spanish (Costa Rica)
267         {"ESD", "DOM", "es_DO"},        // Spanish (Dominican Republic)
268         {"ESF", "ECU", "es_EC"},        // Spanish (Ecuador)
269         {"ESE", "SLV", "es_SV"},        // Spanish (El Salvador)
270         {"ESG", "GTM", "es_GT"},        // Spanish (Guatemala)
271         {"ESH", "HND", "es_HN"},        // Spanish (Honduras)
272         {"ESM", "MEX", "es_MX"},        // Spanish (Mexico)
273         {"ESI", "NIC", "es_NI"},        // Spanish (Nicaragua)
274         {"ESA", "PAN", "es_PA"},        // Spanish (Panama)
275         {"ESZ", "PRY", "es_PY"},        // Spanish (Paraguay)
276         {"ESR", "PER", "es_PE"},        // Spanish (Peru)
277         {"ESU", "PRI", "es_PR"},        // Spanish (Puerto Rico)
278         {"ESN", "ESP", "es_ES"},        // Spanish (Spain)
279         {"EST", "USA", "es_US"},        // Spanish (United States)
280         {"ESY", "URY", "es_UY"},        // Spanish (Uruguay)
281         {"ESV", "VEN", "es_VE"},        // Spanish (Venezuela)
282         {"SVF", "FIN", "sv_FI"},        // Swedish (Finland)
283         {"SVE", "SWE", "sv_SE"},        // Swedish (Sweden)
284         {"TAM", "IND", "ta_IN"},        // Tamil (India)
285         {"TTT", "RUS", "tt_RU"},        // Tatar (Russia)
286         {"TEL", "IND", "te_IN"},        // Telugu (India)
287         {"THA", "THA", "th_TH"},        // Thai (Thailand)
288         {"BOB", "CHN", "bo_CN"},        // Tibetan (PRC)
289         {"TRK", "TUR", "tr_TR"},        // Turkish (Turkey)
290         {"TUK", "TKM", "tk_TM"},        // Turkmen (Turkmenistan)
291         {"UIG", "CHN", "ug_CN"},        // Uighur (PRC)
292         {"UKR", "UKR", "uk_UA"},        // Ukrainian (Ukraine)
293         {"URD", "PAK", "ur_PK"},        // Urdu (Islamic Republic of Pakistan)
294         {"VIT", "VNM", "vi_VN"},        // Vietnamese (Vietnam)
295         {"CYM", "GBR", "cy_GB"},        // Welsh (United Kingdom)
296         {"WOL", "SEN", "wo_SN"},        // Wolof (Senegal)
297         {"III", "CHN", "ii_CN"},        // Yi (PRC)
298         {"YOR", "NGA", "yo_NG"},        // Yoruba (Nigeria)
299         {NULL,NULL,NULL},               // Default - Can't find the language / Language not listed above                
300 };
301
302 static void
303 win_set_nls(void)
304 {
305         char country[32],lang[32];
306         int i=0;
307
308 #ifdef HAVE_API_WIN32_CE 
309         wchar_t wcountry[32],wlang[32]; 
310         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, wlang, sizeof(wlang));
311         WideCharToMultiByte(CP_ACP,0,wlang,-1,lang,sizeof(lang),NULL,NULL);
312         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVCTRYNAME, wcountry, sizeof(wcountry));
313         WideCharToMultiByte(CP_ACP,0,wcountry,-1,country,sizeof(country),NULL,NULL);
314 #else
315         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, lang, sizeof(lang));
316         GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVCTRYNAME, country, sizeof(country));
317 #endif
318         while (nls_table[i][0]) {
319                 if (!strcmp(nls_table[i][0], lang) && !(strcmp(nls_table[i][1], country))) {
320                         dbg(1,"Setting LANG=%s for Lang %s Country %s\n",nls_table[i][2], lang, country);
321                         setenv("LANG",nls_table[i][2],0);
322                         return;
323                 }
324                 i++;
325         }
326         dbg(1,"Lang %s Country %s not found\n",lang,country);
327 }
328 #endif
329
330 void
331 main_init(const char *program)
332 {
333         char *s;
334 #ifdef _UNICODE         /* currently for wince */
335                 wchar_t wfilename[MAX_PATH + 1];
336 #endif
337
338         spawn_process_init();
339
340         cbl=callback_list_new();
341 #ifdef HAVE_API_WIN32_BASE
342         win_set_nls();
343 #endif
344         setenv("LC_NUMERIC","C",1);
345         setlocale(LC_ALL,"");
346         setlocale(LC_NUMERIC,"C");
347 #if !defined _WIN32 && !defined _WIN32_WCE
348         if (file_exists("navit.c") || file_exists("navit.o") || file_exists("navit.lo") || file_exists("version.h")) {
349                 char buffer[PATH_MAX];
350                 printf(_("Running from source directory\n"));
351                 getcwd(buffer, PATH_MAX);               /* libc of navit returns "dummy" */
352                 setenv("NAVIT_PREFIX", buffer, 0);
353                 main_setup_environment(0);
354         } else {
355                 if (!getenv("NAVIT_PREFIX")) {
356                         int l;
357                         int progpath_len;
358                         char *progpath="/bin/navit";
359                         l=strlen(program);
360                         progpath_len=strlen(progpath);
361                         if (l > progpath_len && !strcmp(program+l-progpath_len,progpath)) {
362                                 s=g_strdup(program);
363                                 s[l-progpath_len]='\0';
364                                 if (strcmp(s, PREFIX))
365                                         printf(_("setting '%s' to '%s'\n"), "NAVIT_PREFIX", s);
366                                 setenv("NAVIT_PREFIX", s, 0);
367                                 g_free(s);
368                         } else
369                                 setenv("NAVIT_PREFIX", PREFIX, 0);
370                 }
371 #ifdef HAVE_API_ANDROID
372                 main_setup_environment(3);
373 #else
374                 main_setup_environment(1);
375 #endif
376         }
377
378 #else           /* _WIN32 || _WIN32_WCE */
379         if (!getenv("NAVIT_PREFIX"))
380         {
381                 char  filename[MAX_PATH + 1],
382                      *end;
383                 int len;
384
385                 *filename = '\0';
386 #ifdef _UNICODE         /* currently for wince */
387                 if (GetModuleFileNameW(NULL, wfilename, MAX_PATH))
388                 {
389                         wcstombs(filename, wfilename, MAX_PATH);
390 #else
391                 if (GetModuleFileName(NULL, filename, MAX_PATH))
392                 {
393 #endif
394                         end = strrchr(filename, L'\\'); /* eliminate the file name which is on the right side */
395                         if(end)
396                                 *end = '\0';
397                 }
398                 len=strlen(filename);
399                 if (len > 4 && !strcmp(filename+len-4,"\\bin")) {
400                         filename[len-4]='\0';
401                 }
402                 setenv("NAVIT_PREFIX", filename, 0);
403         }
404         if (!getenv("HOME"))
405                 setenv("HOME", getenv("NAVIT_PREFIX"), 0);
406         main_setup_environment(2);
407 #endif  /* _WIN32 || _WIN32_WCE */
408
409         if (getenv("LC_ALL"))
410                 dbg(0,"Warning: LC_ALL is set, this might lead to problems (e.g. strange positions from GPS)\n");
411         s = getenv("NAVIT_WID");
412         if (s) {
413                 setenv("SDL_WINDOWID", s, 0);
414         }
415 }
416
417 void
418 main_init_nls(void)
419 {
420 #ifdef ENABLE_NLS
421 #ifdef FORCE_LOCALE
422 #define STRINGIFY2(x) #x
423 #define STRINGIFY(x) STRINGIFY2(x)
424         setlocale(LC_MESSAGES,STRINGIFY(FORCE_LOCALE));
425 #endif
426         bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
427         bind_textdomain_codeset (PACKAGE, "UTF-8");
428         textdomain(PACKAGE);
429 #endif
430 }