Merge branch 'upstream-svn' into upstream
[navit-package] / navit / main.c
index 1a6b265..0bc92a0 100644 (file)
@@ -1,3 +1,22 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
 #include <locale.h>
 #include <stdlib.h>
 #include <stdio.h>
 #endif
 
 #include <unistd.h>
-#include <libintl.h>
 #include "config.h"
 #include "file.h"
 #include "debug.h"
 #include "main.h"
 #include "navit.h"
 #include "gui.h"
-#include "xmlconfig.h"
 #include "item.h"
+#include "xmlconfig.h"
 #include "coord.h"
 #include "route.h"
 #include "navigation.h"
 #include "event.h"
+#include "callback.h"
+#include "navit_nls.h"
+#if HAVE_API_WIN32_BASE
+#include <windows.h>
+#include <winbase.h>
+#endif
 
-#define _(STRING)    gettext(STRING)
 
 struct map_data *map_data_default;
 
+struct callback_list *cbl;
+
+
 static void sigchld(int sig)
 {
-#ifndef _WIN32
+#if !defined(_WIN32) && !defined(__CEGCC__)
        int status;
        while (waitpid(-1, &status, WNOHANG) > 0);
 #endif
 }
 
-
-static gchar *get_home_directory(void)
+#ifdef HAVE_API_WIN32
+void
+setenv(char *var, char *val, int overwrite)
 {
-       static gchar *homedir = NULL;
-
-       if (homedir) return homedir;
-       homedir = getenv("HOME");
-       }
-       if (!homedir)
-       {
-               g_warning("Could not find home directory. Using current directory as home directory.");
-               homedir = ".";
-       }
-       return homedir;
+       char *str=g_strdup_printf("%s=%s",var,val);
+       if (overwrite || !getenv(var))
+               putenv(str);
+       g_free(str);
 }
+#endif
 
-static GList *navit;
-
-struct iter {
-       GList *list;
+/*
+ * environment_vars[][0:name,1-3:mode]
+ * ':'  replaced with NAVIT_PREFIX
+ * '::' replaced with NAVIT_PREFIX and LIBDIR
+ * '~'  replaced with HOME
+*/
+static char *environment_vars[][5]={
+       {"NAVIT_LIBDIR",      ":",          "::/navit",      ":\\lib",      ":/lib"},
+       {"NAVIT_SHAREDIR",    ":",          ":/share/navit", ":",           ":/share"},
+       {"NAVIT_LOCALEDIR",   ":/../locale",":/share/locale",":\\locale",   ":/locale"},
+       {"NAVIT_USER_DATADIR",":",          "~/.navit",      ":\\data",     ":/home"},
+#if 1
+       {"NAVIT_LOGFILE",     NULL,         NULL,            ":\\navit.log",NULL},
+#endif
+       {"NAVIT_LIBPREFIX",   "*/.libs/",   NULL,            NULL,          NULL},
+       {NULL,                NULL,         NULL,            NULL,          NULL},
 };
 
-struct iter *
-main_iter_new(void)
+static void
+main_setup_environment(int mode)
 {
-       struct iter *ret=g_new0(struct iter, 1);
-       ret->list=navit;
-       return ret;
+       int i=0;
+       char *var,*val,*homedir;
+       while ((var=environment_vars[i][0])) {
+               val=environment_vars[i][mode+1];
+               if (val) {
+                       switch (val[0]) {
+                       case ':':
+                               if (val[1] == ':')
+                                       val=g_strdup_printf("%s/%s%s", getenv("NAVIT_PREFIX"), LIBDIR+sizeof(PREFIX), val+2);
+                               else
+                                       val=g_strdup_printf("%s%s", getenv("NAVIT_PREFIX"), val+1);
+                               break;
+                       case '~':
+                               homedir=getenv("HOME");
+                               if (!homedir)
+                                       homedir="./";
+                               val=g_strdup_printf("%s%s", homedir, val+1);
+                               break;
+                       default:
+                               val=g_strdup(val);
+                               break;
+                       }
+                       setenv(var, val, 0);
+                       g_free(val);
+               }
+               i++;
+       }
 }
 
-void
-main_iter_destroy(struct iter *iter)
-{
-       g_free(iter);
-}
+#ifdef HAVE_API_WIN32_BASE
+char *nls_table[][3]={
+       {"DAN","DNK","da_DK"},
+       {"DEU","DEU","de_DE"},
+       {"DEA","AUT","de_AT"},
+       {"ENU","USA","en_US"},
+       {"FRA","FRA","fr_FR"},
+       {"RUS","RUS","ru_RU"},
+       {NULL,NULL,NULL},
+};
 
-struct navit *
-main_get_navit(struct iter *iter)
-{
-       GList *list;
-       struct navit *ret=NULL;
-       if (iter)
-               list=iter->list;
-       else
-               list=navit;
-       if (list) {
-               ret=(struct navit *)(list->data);
-               if (iter)
-                       iter->list=g_list_next(iter->list);
-       }
-       return ret;
-       
-}
-void
-main_add_navit(struct navit *nav)
+static void
+win_set_nls(void)
 {
-       navit=g_list_prepend(navit, nav);
-}
+       wchar_t wcountry[32],wlang[32]; 
+       char country[32],lang[32];
+       int i=0;
 
-void
-main_remove_navit(struct navit *nav)
-{
-       navit=g_list_remove(navit, nav);
-       if (! navit) 
-               event_main_loop_quit();
+       GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVLANGNAME, wlang, sizeof(wlang));
+       WideCharToMultiByte(CP_ACP,0,wlang,-1,lang,sizeof(lang),NULL,NULL);
+       GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SABBREVCTRYNAME, wcountry, sizeof(wcountry));
+       WideCharToMultiByte(CP_ACP,0,wcountry,-1,country,sizeof(country),NULL,NULL);
+       while (nls_table[i][0]) {
+               if (!strcmp(nls_table[i][0], lang) && !(strcmp(nls_table[i][1], country))) {
+                       dbg(1,"Setting LANG=%s for Lang %s Country %s\n",nls_table[i][2], lang, country);
+                       setenv("LANG",nls_table[i][2],0);
+                       return;
+               }
+               i++;
+       }
+       dbg(1,"Lang %s Country %s not found\n",lang,country);
 }
+#endif
 
 void
-print_usage(void)
+main_init(char *program)
 {
-       printf(_("navit usage:\nnavit [options]\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"));
-}
-
-int main(int argc, char **argv)
-{
-       GError *error = NULL;
-       char *config_file = NULL;
        char *s;
        int l;
 
-
 #ifndef _WIN32
        signal(SIGCHLD, sigchld);
 #endif
-
+       cbl=callback_list_new();
+#ifdef HAVE_API_WIN32_BASE
+       win_set_nls();
+#endif
        setenv("LC_NUMERIC","C",1);
        setlocale(LC_ALL,"");
        setlocale(LC_NUMERIC,"C");
-       if (file_exists("navit.c") || file_exists("navit.o")) {
+#if !defined _WIN32 && !defined _WIN32_WCE
+       if (file_exists("navit.c") || file_exists("navit.o") || file_exists("navit.lo")) {
                char buffer[PATH_MAX];
                printf(_("Running from source directory\n"));
-               getcwd(buffer, PATH_MAX);
+               getcwd(buffer, PATH_MAX);               /* libc of navit returns "dummy" */
                setenv("NAVIT_PREFIX", buffer, 0);
-               setenv("NAVIT_LIBDIR", buffer, 0);
-               setenv("NAVIT_SHAREDIR", buffer, 0);
-               setenv("NAVIT_LIBPREFIX", "*/.libs/", 0);
-               s=g_strdup_printf("%s/../locale", buffer);
-               setenv("NAVIT_LOCALEDIR", s, 0);
-               g_free(s);
+               main_setup_environment(0);
        } else {
                if (!getenv("NAVIT_PREFIX")) {
-                       l=strlen(argv[0]);
-                       if (l > 10 && !strcmp(argv[0]+l-10,"/bin/navit")) {
-                               s=g_strdup(argv[0]);
-                               s[l-10]='\0';
+               int progpath_len;
+                       char *progpath="/bin/navit";
+                       l=strlen(program);
+                       progpath_len=strlen(progpath);
+                       if (l > progpath_len && !strcmp(program+l-progpath_len,progpath)) {
+                               s=g_strdup(program);
+                               s[l-progpath_len]='\0';
                                if (strcmp(s, PREFIX))
                                        printf(_("setting '%s' to '%s'\n"), "NAVIT_PREFIX", s);
                                setenv("NAVIT_PREFIX", s, 0);
@@ -151,133 +199,59 @@ int main(int argc, char **argv)
                        } else
                                setenv("NAVIT_PREFIX", PREFIX, 0);
                }
-#ifdef _WIN32
-               s=g_strdup_printf("locale");
+#ifdef HAVE_API_ANDROID
+               main_setup_environment(3);
 #else
-               s=g_strdup_printf("%s/share/locale", getenv("NAVIT_PREFIX"));
+               main_setup_environment(1);
 #endif
-               setenv("NAVIT_LOCALEDIR", s, 0);
-               g_free(s);
-#ifdef _WIN32
-               s=g_strdup_printf(".");
+       }
+
+#else          /* _WIN32 || _WIN32_WCE */
+       if (!getenv("NAVIT_PREFIX"))
+       {
+               char  filename[MAX_PATH + 1],
+                    *end;
+
+               *filename = '\0';
+#ifdef _UNICODE                /* currently for wince */
+               wchar_t wfilename[MAX_PATH + 1];
+               if (GetModuleFileNameW(NULL, wfilename, MAX_PATH))
+               {
+                       wcstombs(filename, wfilename, MAX_PATH);
 #else
-               s=g_strdup_printf("%s/share/navit", getenv("NAVIT_PREFIX"));
+               if (GetModuleFileName(NULL, filename, MAX_PATH))
+               {
 #endif
-               setenv("NAVIT_SHAREDIR", s, 0);
-               g_free(s);
-               s=g_strdup_printf("%s/lib/navit", getenv("NAVIT_PREFIX"));
-               setenv("NAVIT_LIBDIR", s, 0);
-               g_free(s);
+                       end = strrchr(filename, L'\\'); /* eliminate the file name which is on the right side */
+                       if(end)
+                               *end = '\0';
+               }
+               setenv("NAVIT_PREFIX", filename, 0);
        }
-        bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
-       bind_textdomain_codeset (PACKAGE, "UTF-8");
-       textdomain(PACKAGE);
+       if (!getenv("HOME"))
+               setenv("HOME", getenv("NAVIT_PREFIX"), 0);
+       main_setup_environment(2);
+#endif /* _WIN32 || _WIN32_WCE */
 
-       debug_init(argv[0]);
-       if (getenv("LC_ALL")) 
-               dbg(0,"Warning: LC_ALL is set, this might lead to problems\n");
-#ifndef USE_PLUGINS
-       extern void builtin_init(void);
-       builtin_init();
-#endif
-#if 0
-       /* handled in gui/gtk */
-       gtk_set_locale();
-       gtk_init(&argc, &argv);
-       gdk_rgb_init();
-#endif
+       if (getenv("LC_ALL"))
+               dbg(0,"Warning: LC_ALL is set, this might lead to problems (e.g. strange positions from GPS)\n");
        s = getenv("NAVIT_WID");
        if (s) {
                setenv("SDL_WINDOWID", s, 0);
        }
-       route_init();
-       navigation_init();
-       config_file=NULL;
-       int opt;
-       opterr=0;  //don't bomb out on errors.
-       if (argc > 1) {
-               while((opt = getopt(argc, argv, ":hvc:d:")) != -1) {
-                       switch(opt) {
-                       case 'h':
-                               print_usage();
-                               exit(0);
-                               break;
-                       case '  v':
-                               printf("        %s %s\n", "navit", "0.0.4+svn"); 
-                               exit(0);
-                               break;
-                       case 'c':
-                               printf("c       onfig file n is set to `%s'\n", optarg);
-                   config_file = optarg;
-                               break;
-                       case 'd':
-                               printf("T       ODO Verbose option is set to `%s'\n", optarg);
-                               break;
-                       case ':':
-                               fprintf(stderr, "navit: Error - Option `%c' needs a value\n", optopt);
-                               print_usage();
-                               exit(1);
-                               break;
-                       case '?':
-                               fprintf(stderr, "navit: Error - No such option: `%c'\n", optopt);
-                               print_usage();
-                               exit(1);
-                       }
-           }
-       }
-       if (optind < argc) {
-               // there are still unknown non config options left on the command line.
-               print_usage();
-               exit(1);
-       }
-
-       if (! config_file) {
-               config_file=g_strjoin(NULL,get_home_directory(), "/.navit/navit.xml" , NULL);
-               if (!file_exists(config_file)) {
-                       g_free(config_file);
-                       config_file=NULL;
-                       }
-       }
-       if (! config_file) {
-               if (file_exists("navit.xml.local"))
-                       config_file="navit.xml.local";
-       }
-       if (! config_file) {
-               if (file_exists("navit.xml"))
-                       config_file="navit.xml";
-       }
-       if (! config_file) {
-               config_file=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml.local" , NULL);
-               if (!file_exists(config_file)) {
-                       g_free(config_file);
-                       config_file=NULL;
-               }
-       }
-       if (! config_file) {
-               config_file=g_strjoin(NULL,getenv("NAVIT_SHAREDIR"), "/navit.xml" , NULL);
-               if (!file_exists(config_file)) {
-                       g_free(config_file);
-                       config_file=NULL;
-               }
-       }
-       if (!config_file) {
-               printf(_("No config file navit.xml, navit.xml.local found\n"));
-               exit(1);
-       }
-       if (!config_load(config_file, &error)) {
-               printf(_("Error parsing '%s': %s\n"), config_file, error->message);
-               exit(1);
-       } else {
-               printf(_("Using '%s'\n"), config_file);
-       }
-       if (! navit) {
-               printf(_("No instance has been created, exiting\n"));
-               exit(1);
-       }
-       if (main_loop_gui) {
-               gui_run_main_loop(main_loop_gui);
-       } else 
-               event_main_loop_run();
+}
 
-       return 0;
+void
+main_init_nls(void)
+{
+#ifdef ENABLE_NLS
+#ifdef FORCE_LOCALE
+#define STRINGIFY2(x) #x
+#define STRINGIFY(x) STRINGIFY2(x)
+       setlocale(LC_MESSAGES,STRINGIFY(FORCE_LOCALE));
+#endif
+       bindtextdomain(PACKAGE, getenv("NAVIT_LOCALEDIR"));
+       bind_textdomain_codeset (PACKAGE, "UTF-8");
+       textdomain(PACKAGE);
+#endif
 }