From 7ac120f629403ac38ed209986dd4c256a52ef890 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sun, 28 Mar 2010 22:17:31 +0200 Subject: Allow Inkscape to run from Unicode directories on Windows Fixed bugs: - https://launchpad.net/bugs/505107 (bzr r9248) --- src/main.cpp | 180 +++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 102 insertions(+), 78 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index d11222203..a4ed5d77b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,6 +47,8 @@ #endif /* Not def: POPT_TABLEEND */ #include +#include +#include #include #include #include @@ -471,61 +473,71 @@ gchar * blankParam = g_strdup(""); #ifdef WIN32 -/** - * Return the directory of the .exe that is currently running - */ -static Glib::ustring _win32_getExePath() -{ - char exeName[MAX_PATH+1]; - // TODO these should use xxxW() calls explicitly and convert UTF-16 <--> UTF-8 - GetModuleFileName(NULL, exeName, MAX_PATH); - char *slashPos = strrchr(exeName, '\\'); - if (slashPos) { - *slashPos = '\0'; - } - Glib::ustring s = exeName; - return s; -} - /** * Set up the PATH and PYTHONPATH environment variables on * win32 + * @param exe Inkscape executable directory in UTF-8 */ -static int _win32_set_inkscape_env(const Glib::ustring &exePath) +static void _win32_set_inkscape_env(gchar const *exe) { - // TODO use g_getenv() and g_setenv() that use filename encoding, which is UTF-8 on Windows - - char *oldenv = getenv("PATH"); - Glib::ustring tmp = "PATH="; - tmp += exePath; - tmp += ";"; - tmp += exePath; - tmp += "\\python;"; - tmp += exePath; - tmp += "\\python\\Scripts;"; // for uniconv.cmd - tmp += exePath; - tmp += "\\perl"; - if(oldenv != NULL) { - tmp += ";"; - tmp += oldenv; + gchar const *path = g_getenv("PATH"); + gchar const *pythonpath = g_getenv("PYTHONPATH"); + + gchar *python = g_build_filename(exe, "python", NULL); + gchar *scripts = g_build_filename(exe, "python", "Scripts", NULL); + gchar *perl = g_build_filename(exe, "python", NULL); + gchar *pythonlib = g_build_filename(exe, "python", "Lib", NULL); + gchar *pythondll = g_build_filename(exe, "python", "DLLs", NULL); + + // Python 2.x needs short paths in PYTHONPATH. + // Otherwise it doesn't work when Inkscape is installed in Unicode directories. + // g_win32_locale_filename_from_utf8 is the Glib equivalent + // of GetShortPathName. + // Remove this once we move to Python 3.0. + gchar *python_s = g_win32_locale_filename_from_utf8(python); + gchar *pythonlib_s = g_win32_locale_filename_from_utf8(pythonlib); + gchar *pythondll_s = g_win32_locale_filename_from_utf8(pythondll); + + gchar *new_path; + gchar *new_pythonpath; + if (path) { + new_path = g_strdup_printf("%s;%s;%s;%s;%s", exe, python, scripts, perl, path); + } else { + new_path = g_strdup_printf("%s;%s;%s;%s", exe, python, scripts, perl); } - _putenv(tmp.c_str()); - - oldenv = getenv("PYTHONPATH"); - tmp = "PYTHONPATH="; - tmp += exePath; - tmp += "\\python;"; - tmp += exePath; - tmp += "\\python\\Lib;"; - tmp += exePath; - tmp += "\\python\\DLLs"; - if(oldenv != NULL) { - tmp += ";"; - tmp += oldenv; + if (pythonpath) { + new_pythonpath = g_strdup_printf("%s;%s;%s;%s", python_s, pythonlib_s, pythondll_s, pythonpath); + } else { + new_pythonpath = g_strdup_printf("%s;%s;%s", python_s, pythonlib_s, pythondll_s); } - _putenv(tmp.c_str()); - return 0; + g_setenv("PATH", new_path, TRUE); + g_setenv("PYTHONPATH", new_pythonpath, TRUE); + + /* + printf("PATH = %s\n\n", g_getenv("PATH")); + printf("PYTHONPATH = %s\n\n", g_getenv("PYTHONPATH")); + + gchar *p = g_find_program_in_path("python"); + if (p) { + printf("python in %s\n\n", p); + g_free(p); + } else { + printf("python not found\n\n"); + }*/ + + g_free(python); + g_free(scripts); + g_free(perl); + g_free(pythonlib); + g_free(pythondll); + + g_free(python_s); + g_free(pythonlib_s); + g_free(pythondll_s); + + g_free(new_path); + g_free(new_pythonpath); } #endif @@ -568,55 +580,68 @@ main(int argc, char **argv) when inkscape.exe is executed from another directory. We use relative paths on win32. HKCR\svgfile\shell\open\command is a good example + + TODO: this breaks the CLI on Windows, see LP #167455 + However, the CLI is broken anyway, because we are a GUI app */ - Glib::ustring homedir = _win32_getExePath(); - // TODO these should use xxxW() calls explicitly and convert UTF-16 <--> UTF-8 - SetCurrentDirectory(homedir.c_str()); - _win32_set_inkscape_env(homedir); + const int pathbuf = 2048; + gunichar2 *path = g_new(gunichar2, pathbuf); + GetModuleFileNameW(NULL, (WCHAR*) path, pathbuf); + gchar *inkscape = g_utf16_to_utf8(path, -1, NULL, NULL, NULL); + gchar *exedir = g_path_get_dirname(inkscape); + gunichar2 *dirw = g_utf8_to_utf16(exedir, -1, NULL, NULL, NULL); + SetCurrentDirectoryW((WCHAR*) dirw); + _win32_set_inkscape_env(exedir); + +# ifdef ENABLE_NLS + // obtain short path to executable dir and pass it + // to bindtextdomain (it doesn't understand UTF-8) + gchar *shortexedir = g_win32_locale_filename_from_utf8(exedir); + gchar *localepath = g_build_filename(shortexedir, PACKAGE_LOCALE_DIR, NULL); + bindtextdomain(GETTEXT_PACKAGE, localepath); + g_free(shortexedir); + g_free(localepath); +# endif + + g_free(path); + g_free(inkscape); + g_free(exedir); + g_free(dirw); + // Don't touch the registry (works fine without it) for Inkscape Portable gchar const *val = g_getenv("INKSCAPE_PORTABLE_PROFILE_DIR"); if (!val) { RegistryTool rt; rt.setPathInfo(); } -#endif - - // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) - Gtk::Main::init_gtkmm_internals(); - - // Bug #197475 - set_extensions_env(); - - /** - * Call bindtextdomain() for various machines's paths - */ -#ifdef ENABLE_NLS -#ifdef WIN32 - Glib::ustring localePath = homedir; - localePath += "\\"; - localePath += PACKAGE_LOCALE_DIR; - bindtextdomain(GETTEXT_PACKAGE, localePath.c_str()); -#else -#ifdef ENABLE_BINRELOC +#elif defined(ENABLE_NLS) +# ifdef ENABLE_BINRELOC bindtextdomain(GETTEXT_PACKAGE, BR_LOCALEDIR("")); -#else +# else bindtextdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); +# endif #endif -#endif + + // the bit below compiles regardless of platform +#ifdef ENABLE_NLS // Allow the user to override the locale directory by setting // the environment variable INKSCAPE_LOCALEDIR. - char *inkscape_localedir = getenv("INKSCAPE_LOCALEDIR"); + char const *inkscape_localedir = g_getenv("INKSCAPE_LOCALEDIR"); if (inkscape_localedir != NULL) { bindtextdomain(GETTEXT_PACKAGE, inkscape_localedir); } -#endif + // common setup bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); - -#ifdef ENABLE_NLS textdomain(GETTEXT_PACKAGE); #endif + // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) + Gtk::Main::init_gtkmm_internals(); + + // Bug #197475 + set_extensions_env(); + LIBXML_TEST_VERSION Inkscape::GC::init(); @@ -626,8 +651,7 @@ main(int argc, char **argv) gboolean use_gui; #ifndef WIN32 - // TODO use g_getenv() and g_setenv() that use filename encoding, which is UTF-8 on Windows - use_gui = (getenv("DISPLAY") != NULL); + use_gui = (g_getenv("DISPLAY") != NULL); #else use_gui = TRUE; #endif -- cgit v1.2.3 From 9219826d44dbe32de525ab43e8215f8abaf04fbd Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Mon, 29 Mar 2010 01:13:04 +0200 Subject: Fix regression (inkex.py not found for extensions in user's directory) (bzr r9250) --- src/main.cpp | 35 ++++++++--------------------------- 1 file changed, 8 insertions(+), 27 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index a4ed5d77b..c50ba7311 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -474,8 +474,7 @@ gchar * blankParam = g_strdup(""); #ifdef WIN32 /** - * Set up the PATH and PYTHONPATH environment variables on - * win32 + * Set up the PATH and PYTHONPATH environment variables on Windows * @param exe Inkscape executable directory in UTF-8 */ static void _win32_set_inkscape_env(gchar const *exe) @@ -488,15 +487,16 @@ static void _win32_set_inkscape_env(gchar const *exe) gchar *perl = g_build_filename(exe, "python", NULL); gchar *pythonlib = g_build_filename(exe, "python", "Lib", NULL); gchar *pythondll = g_build_filename(exe, "python", "DLLs", NULL); + gchar *extdir = g_build_filename(exe, "share", "extensions", NULL); // Python 2.x needs short paths in PYTHONPATH. // Otherwise it doesn't work when Inkscape is installed in Unicode directories. - // g_win32_locale_filename_from_utf8 is the Glib equivalent - // of GetShortPathName. + // g_win32_locale_filename_from_utf8 is the GLib wrapper for GetShortPathName. // Remove this once we move to Python 3.0. gchar *python_s = g_win32_locale_filename_from_utf8(python); gchar *pythonlib_s = g_win32_locale_filename_from_utf8(pythonlib); gchar *pythondll_s = g_win32_locale_filename_from_utf8(pythondll); + gchar *extdir_s = g_win32_locale_filename_from_utf8(extdir); gchar *new_path; gchar *new_pythonpath; @@ -506,9 +506,11 @@ static void _win32_set_inkscape_env(gchar const *exe) new_path = g_strdup_printf("%s;%s;%s;%s", exe, python, scripts, perl); } if (pythonpath) { - new_pythonpath = g_strdup_printf("%s;%s;%s;%s", python_s, pythonlib_s, pythondll_s, pythonpath); + new_pythonpath = g_strdup_printf("%s;%s;%s;%s;%s", + extdir_s, python_s, pythonlib_s, pythondll_s, pythonpath); } else { - new_pythonpath = g_strdup_printf("%s;%s;%s", python_s, pythonlib_s, pythondll_s); + new_pythonpath = g_strdup_printf("%s;%s;%s;%s", + extdir_s, python_s, pythonlib_s, pythondll_s); } g_setenv("PATH", new_path, TRUE); @@ -541,24 +543,6 @@ static void _win32_set_inkscape_env(gchar const *exe) } #endif -/** - * Add INKSCAPE_EXTENSIONDIR to PYTHONPATH so that extensions in users home - * can find inkex.py et al. (Bug #197475) - */ -static int set_extensions_env() -{ - char *oldenv = getenv("PYTHONPATH"); - Glib::ustring tmp = INKSCAPE_EXTENSIONDIR; - if (oldenv != NULL) { - tmp += G_SEARCHPATH_SEPARATOR; - tmp += oldenv; - } - g_setenv("PYTHONPATH", tmp.c_str(), TRUE); - - return 0; -} - - /** * This is the classic main() entry point of the program, though on some * architectures it might be called by something else. @@ -639,9 +623,6 @@ main(int argc, char **argv) // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) Gtk::Main::init_gtkmm_internals(); - // Bug #197475 - set_extensions_env(); - LIBXML_TEST_VERSION Inkscape::GC::init(); -- cgit v1.2.3 From 4f8ab4cea8237d843a25d033d077851ba2fd6a5d Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Mon, 29 Mar 2010 01:23:56 +0200 Subject: Oops - obviously the previous fix didn't work outside Windows (bzr r9251) --- src/main.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index c50ba7311..a6dfb37f0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -487,7 +487,6 @@ static void _win32_set_inkscape_env(gchar const *exe) gchar *perl = g_build_filename(exe, "python", NULL); gchar *pythonlib = g_build_filename(exe, "python", "Lib", NULL); gchar *pythondll = g_build_filename(exe, "python", "DLLs", NULL); - gchar *extdir = g_build_filename(exe, "share", "extensions", NULL); // Python 2.x needs short paths in PYTHONPATH. // Otherwise it doesn't work when Inkscape is installed in Unicode directories. @@ -496,7 +495,6 @@ static void _win32_set_inkscape_env(gchar const *exe) gchar *python_s = g_win32_locale_filename_from_utf8(python); gchar *pythonlib_s = g_win32_locale_filename_from_utf8(pythonlib); gchar *pythondll_s = g_win32_locale_filename_from_utf8(pythondll); - gchar *extdir_s = g_win32_locale_filename_from_utf8(extdir); gchar *new_path; gchar *new_pythonpath; @@ -506,11 +504,11 @@ static void _win32_set_inkscape_env(gchar const *exe) new_path = g_strdup_printf("%s;%s;%s;%s", exe, python, scripts, perl); } if (pythonpath) { - new_pythonpath = g_strdup_printf("%s;%s;%s;%s;%s", - extdir_s, python_s, pythonlib_s, pythondll_s, pythonpath); - } else { new_pythonpath = g_strdup_printf("%s;%s;%s;%s", - extdir_s, python_s, pythonlib_s, pythondll_s); + python_s, pythonlib_s, pythondll_s, pythonpath); + } else { + new_pythonpath = g_strdup_printf("%s;%s;%s", + python_s, pythonlib_s, pythondll_s); } g_setenv("PATH", new_path, TRUE); @@ -543,6 +541,24 @@ static void _win32_set_inkscape_env(gchar const *exe) } #endif +static void set_extensions_env() +{ + gchar const *pythonpath = g_getenv("PYTHONPATH"); + gchar *extdir; + +#ifdef WIN32 + extdir = g_win32_locale_filename_from_utf8(INKSCAPE_EXTENSIONDIR); +#else + extdir = g_strdup(INKSCAPE_EXTENSIONDIR); +#endif + + gchar *new_pythonpath = g_strdup_printf("%s" G_SEARCHPATH_SEPARATOR_S "%s", + extdir, pythonpath); + g_setenv("PYTHONPATH", new_pythonpath, TRUE); + g_free(extdir); + g_free(new_pythonpath); +} + /** * This is the classic main() entry point of the program, though on some * architectures it might be called by something else. @@ -620,6 +636,8 @@ main(int argc, char **argv) textdomain(GETTEXT_PACKAGE); #endif + set_extensions_env(); + // Prevents errors like "Unable to wrap GdkPixbuf..." (in nr-filter-image.cpp for example) Gtk::Main::init_gtkmm_internals(); -- cgit v1.2.3 From 58a6b2ed5541bad9c7369aa357d7fbe43d1e5c66 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 30 Mar 2010 00:22:39 +0200 Subject: More correct setting of PYTHONPATH at startup (bzr r9257) --- src/main.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index a6dfb37f0..cd60d9fa1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -545,18 +545,24 @@ static void set_extensions_env() { gchar const *pythonpath = g_getenv("PYTHONPATH"); gchar *extdir; + gchar *new_pythonpath; #ifdef WIN32 extdir = g_win32_locale_filename_from_utf8(INKSCAPE_EXTENSIONDIR); #else extdir = g_strdup(INKSCAPE_EXTENSIONDIR); #endif + if (pythonpath) { + new_pythonpath = g_strdup_printf("%s" G_SEARCHPATH_SEPARATOR_S "%s", + extdir, pythonpath); + g_free(extdir); + } else { + new_pythonpath = extdir; + } - gchar *new_pythonpath = g_strdup_printf("%s" G_SEARCHPATH_SEPARATOR_S "%s", - extdir, pythonpath); g_setenv("PYTHONPATH", new_pythonpath, TRUE); - g_free(extdir); g_free(new_pythonpath); + printf("PYTHONPATH = %s", g_getenv("PYTHONPATH")); } /** -- cgit v1.2.3 From 7dd671c8bf7f9aa02afb4128f75fcd3684e9641d Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Tue, 30 Mar 2010 18:05:21 +0200 Subject: Make all paths in PYTHONPATH absolute. Fixed bugs: - https://launchpad.net/bugs/551433 (bzr r9261) --- src/main.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index cd60d9fa1..32102f3b3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -552,6 +552,19 @@ static void set_extensions_env() #else extdir = g_strdup(INKSCAPE_EXTENSIONDIR); #endif + + // On some platforms, INKSCAPE_EXTENSIONDIR is not absolute, + // but relative to the directory that contains the Inkscape executable. + // Since we spawn Python chdir'ed into the script's directory, + // we need to obtain the absolute path here. + if (!g_path_is_absolute(extdir)) { + gchar *curdir = g_get_current_dir(); + gchar *extdir_new = g_build_filename(curdir, extdir, NULL); + g_free(extdir); + g_free(curdir); + extdir = extdir_new; + } + if (pythonpath) { new_pythonpath = g_strdup_printf("%s" G_SEARCHPATH_SEPARATOR_S "%s", extdir, pythonpath); @@ -562,7 +575,7 @@ static void set_extensions_env() g_setenv("PYTHONPATH", new_pythonpath, TRUE); g_free(new_pythonpath); - printf("PYTHONPATH = %s", g_getenv("PYTHONPATH")); + printf("PYTHONPATH = %s\n", g_getenv("PYTHONPATH")); } /** @@ -588,7 +601,6 @@ main(int argc, char **argv) HKCR\svgfile\shell\open\command is a good example TODO: this breaks the CLI on Windows, see LP #167455 - However, the CLI is broken anyway, because we are a GUI app */ const int pathbuf = 2048; gunichar2 *path = g_new(gunichar2, pathbuf); -- cgit v1.2.3 From 6851867b2f6e0d58d32a564a123e3b3c12458342 Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Fri, 2 Apr 2010 20:13:21 +0200 Subject: Do not print PYTHONPATH on every invocation (stale debug output) Fixed bugs: - https://launchpad.net/bugs/554109 (bzr r9278) --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 32102f3b3..5aa164df8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -575,7 +575,7 @@ static void set_extensions_env() g_setenv("PYTHONPATH", new_pythonpath, TRUE); g_free(new_pythonpath); - printf("PYTHONPATH = %s\n", g_getenv("PYTHONPATH")); + //printf("PYTHONPATH = %s\n", g_getenv("PYTHONPATH")); } /** -- cgit v1.2.3 From a870a3f925fe2dd16a60f48a956af772988b805b Mon Sep 17 00:00:00 2001 From: Krzysztof Kosi??ski Date: Sat, 3 Apr 2010 01:47:43 +0200 Subject: Fix command line invocation on Windows (LP #167455). Fixed bugs: - https://launchpad.net/bugs/167455 (bzr r9281) --- src/main.cpp | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 5aa164df8..9f7bc9ad3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -593,22 +593,7 @@ main(int argc, char **argv) #endif #ifdef WIN32 - /* - Set the current directory to the directory of the - executable. This seems redundant, but is needed for - when inkscape.exe is executed from another directory. - We use relative paths on win32. - HKCR\svgfile\shell\open\command is a good example - - TODO: this breaks the CLI on Windows, see LP #167455 - */ - const int pathbuf = 2048; - gunichar2 *path = g_new(gunichar2, pathbuf); - GetModuleFileNameW(NULL, (WCHAR*) path, pathbuf); - gchar *inkscape = g_utf16_to_utf8(path, -1, NULL, NULL, NULL); - gchar *exedir = g_path_get_dirname(inkscape); - gunichar2 *dirw = g_utf8_to_utf16(exedir, -1, NULL, NULL, NULL); - SetCurrentDirectoryW((WCHAR*) dirw); + gchar *exedir = g_strdup(win32_getExePath().data()); _win32_set_inkscape_env(exedir); # ifdef ENABLE_NLS @@ -620,11 +605,7 @@ main(int argc, char **argv) g_free(shortexedir); g_free(localepath); # endif - - g_free(path); - g_free(inkscape); g_free(exedir); - g_free(dirw); // Don't touch the registry (works fine without it) for Inkscape Portable gchar const *val = g_getenv("INKSCAPE_PORTABLE_PROFILE_DIR"); -- cgit v1.2.3