Code

Allow Inkscape to run from Unicode directories on Windows
authorKrzysztof Kosiński <tweenk.pl@gmail.com>
Sun, 28 Mar 2010 20:17:31 +0000 (22:17 +0200)
committerKrzysztof Kosiński <tweenk.pl@gmail.com>
Sun, 28 Mar 2010 20:17:31 +0000 (22:17 +0200)
src/extension/implementation/script.cpp
src/extension/implementation/script.h
src/io/sys.cpp
src/main.cpp
src/prefix.cpp
src/registrytool.cpp

index 60623191f290c3fc2e6ce53bf32f434797723504..256996663c056ce1262d474daffcd324ba321a1d 100644 (file)
@@ -21,6 +21,8 @@
 #include <unistd.h>
 
 #include <errno.h>
+#include <glib.h>
+#include <glib/gstdio.h>
 #include <gtkmm.h>
 
 #include "ui/view/view.h"
@@ -101,14 +103,12 @@ Script::interpreter_t const Script::interpreterTab[] = {
     \param interpNameArg  The name of the interpreter that we're looking
     for, should be an entry in interpreterTab
 */
-Glib::ustring Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg)
+std::string Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg)
 {
-    Glib::ustring interpName = interpNameArg;
-
     interpreter_t const *interp = 0;
     bool foundInterp = false;
     for (interp =  interpreterTab ; interp->identity ; interp++ ){
-        if (interpName == interp->identity) {
+        if (interpNameArg == interp->identity) {
             foundInterp = true;
             break;
         }
@@ -118,55 +118,26 @@ Glib::ustring Script::resolveInterpreterExecutable(const Glib::ustring &interpNa
     if (!foundInterp) {
         return "";
     }
-    interpName = interp->defaultval;
+    std::string interpreter_path = Glib::filename_from_utf8(interp->defaultval);
 
-    // 1.  Check preferences
+    // 1.  Check preferences for an override.
+    // Note: this must be an absolute path.
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     Glib::ustring prefInterp = prefs->getString("/extensions/" + Glib::ustring(interp->prefstring));
 
     if (!prefInterp.empty()) {
-        interpName = prefInterp;
-        return interpName;
-    }
-
-#ifdef WIN32
-
-    // 2.  Windows.  Try looking relative to inkscape.exe
-    RegistryTool rt;
-    Glib::ustring fullPath;
-    Glib::ustring path;
-    Glib::ustring exeName;
-    if (rt.getExeInfo(fullPath, path, exeName)) {
-// TODO replace with proper glib/glibmm path building routines:
-        Glib::ustring interpPath = path;
-        interpPath.append("\\");
-        interpPath.append(interpNameArg);
-        interpPath.append("\\");
-        interpPath.append(interpName);
-        interpPath.append(".exe");
-        struct stat finfo;
-        if (stat(interpPath .c_str(), &finfo) == 0) {
-            g_message("Found local interpreter, '%s',  Size: %d",
-                      interpPath .c_str(),
-                      (int)finfo.st_size);
-            return interpPath;
-        }
+        interpreter_path = Glib::filename_from_utf8(prefInterp);
     }
 
-    // 3. Try searching the path
-    char szExePath[MAX_PATH] = {0};
-    char szCurrentDir[MAX_PATH] = {0};
-    GetCurrentDirectory(sizeof(szCurrentDir), szCurrentDir);
-    HINSTANCE ret = FindExecutable(interpName.c_str(), szCurrentDir, szExePath);
-    if (ret > reinterpret_cast<HINSTANCE>(32)) {
-        interpName = szExePath;
-        return interpName;
+    // 2. Search the path.
+    // Do this on all systems, for consistency.
+    // PATH is set up to contain the Python and Perl binary directories
+    // on Windows, so no extra code is necessary.
+    if (!Glib::path_is_absolute(interpreter_path)) {
+        interpreter_path = Glib::find_program_in_path(interpreter_path);
     }
-
-#endif // win32
-
-
-    return interpName;
+    printf("Interpreter name: %s\n", interpreter_path.data());
+    return interpreter_path;
 }
 
 /** \brief     This function creates a script object and sets up the
@@ -206,38 +177,33 @@ Script::~Script()
     string.  This means that the caller of this function can always
     free what they are given (and should do it too!).
 */
-Glib::ustring
+std::string
 Script::solve_reldir(Inkscape::XML::Node *reprin) {
 
     gchar const *s = reprin->attribute("reldir");
 
-    if (!s) {
+    // right now the only recognized relative directory is "extensions"
+    if (!s || Glib::ustring(s) != "extensions") {
         Glib::ustring str = sp_repr_children(reprin)->content();
         return str;
     }
 
     Glib::ustring reldir = s;
 
-    if (reldir == "extensions") {
-
-        for (unsigned int i=0;
-            i < Inkscape::Extension::Extension::search_path.size();
-            i++) {
+    for (unsigned int i=0;
+        i < Inkscape::Extension::Extension::search_path.size();
+        i++) {
 
-            gchar * fname = g_build_filename(
-               Inkscape::Extension::Extension::search_path[i],
-               sp_repr_children(reprin)->content(),
-               NULL);
-            Glib::ustring filename = fname;
-            g_free(fname);
+        gchar * fname = g_build_filename(
+           Inkscape::Extension::Extension::search_path[i],
+           sp_repr_children(reprin)->content(),
+           NULL);
+        Glib::ustring filename = fname;
+        g_free(fname);
 
-            if ( Inkscape::IO::file_test(filename.c_str(), G_FILE_TEST_EXISTS) ) {
-                return filename;
-            }
+        if ( Inkscape::IO::file_test(filename.c_str(), G_FILE_TEST_EXISTS) ) {
+            return Glib::filename_from_utf8(filename);
         }
-    } else {
-        Glib::ustring str = sp_repr_children(reprin)->content();
-        return str;
     }
 
     return "";
@@ -261,29 +227,25 @@ Script::solve_reldir(Inkscape::XML::Node *reprin) {
     then a TRUE is returned.  If we get all the way through the path
     then a FALSE is returned, the command could not be found.
 */
-bool Script::check_existance(const Glib::ustring &command)
+bool Script::check_existence(const std::string &command)
 {
 
     // Check the simple case first
-    if (command.size() == 0) {
+    if (command.empty()) {
         return false;
     }
 
-    //Don't search when it contains a slash. */
-    if (command.find(G_DIR_SEPARATOR) != command.npos) {
-        if (Inkscape::IO::file_test(command.c_str(), G_FILE_TEST_EXISTS)) {
+    //Don't search when it is an absolute path. */
+    if (!Glib::path_is_absolute(command)) {
+        if (Glib::file_test(command, Glib::FILE_TEST_EXISTS)) {
             return true;
         } else {
             return false;
         }
     }
 
-
-    Glib::ustring path;
-    gchar *s = (gchar *) g_getenv("PATH");
-    if (s) {
-        path = s;
-    } else {
+    std::string path = Glib::getenv("PATH");
+    if (path.empty()) {
        /* There is no `PATH' in the environment.
            The default search path is the current directory */
         path = G_SEARCHPATH_SEPARATOR_S;
@@ -293,7 +255,7 @@ bool Script::check_existance(const Glib::ustring &command)
     std::string::size_type pos2 = 0;
     while ( pos < path.size() ) {
 
-        Glib::ustring localPath;
+        std::string localPath;
 
         pos2 = path.find(G_SEARCHPATH_SEPARATOR, pos);
         if (pos2 == path.npos) {
@@ -305,11 +267,11 @@ bool Script::check_existance(const Glib::ustring &command)
         }
 
         //printf("### %s\n", localPath.c_str());
-        Glib::ustring candidatePath =
+        std::string candidatePath =
                       Glib::build_filename(localPath, command);
 
-        if (Inkscape::IO::file_test(candidatePath .c_str(),
-                      G_FILE_TEST_EXISTS)) {
+        if (Glib::file_test(candidatePath,
+                      Glib::FILE_TEST_EXISTS)) {
             return true;
         }
 
@@ -357,16 +319,10 @@ bool Script::load(Inkscape::Extension::Extension *module)
                 if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "command")) {
                     const gchar *interpretstr = child_repr->attribute("interpreter");
                     if (interpretstr != NULL) {
-                        Glib::ustring interpString =
-                            resolveInterpreterExecutable(interpretstr);
-                        //g_message("Found: %s and %s",interpString.c_str(),interpretstr);
-                        command.insert(command.end(), interpretstr);
+                        std::string interpString = resolveInterpreterExecutable(interpretstr);
+                        command.insert(command.end(), interpString);
                     }
-                    Glib::ustring tmp = "\"";
-                    tmp += solve_reldir(child_repr);
-                    tmp += "\"";
-
-                    command.insert(command.end(), tmp);
+                    command.insert(command.end(), solve_reldir(child_repr));
                 }
                 if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "helper_extension")) {
                     helper_extension = sp_repr_children(child_repr)->content();
@@ -419,10 +375,10 @@ Script::check(Inkscape::Extension::Extension *module)
             child_repr = sp_repr_children(child_repr);
             while (child_repr != NULL) {
                 if (!strcmp(child_repr->name(), INKSCAPE_EXTENSION_NS "check")) {
-                    Glib::ustring command_text = solve_reldir(child_repr);
-                    if (command_text.size() > 0) {
+                    std::string command_text = solve_reldir(child_repr);
+                    if (!command_text.empty()) {
                         /* I've got the command */
-                        bool existance = check_existance(command_text);
+                        bool existance = check_existence(command_text);
                         if (!existance)
                             return false;
                     }
@@ -763,8 +719,7 @@ void Script::effect(Inkscape::Extension::Effect *module,
     // make sure we don't leak file descriptors from g_file_open_tmp
     close(tempfd_out);
 
-    // FIXME: convert to utf8 (from "filename encoding") and unlink_utf8name
-    unlink(tempfilename_out.c_str());
+    g_unlink(tempfilename_out.c_str());
 
     /* Do something with mydoc.... */
     if (mydoc) {
@@ -937,89 +892,61 @@ int Script::execute (const std::list<std::string> &in_command,
                  const Glib::ustring &filein,
                  file_listener &fileout)
 {
-    g_return_val_if_fail(in_command.size() > 0, 0);
+    g_return_val_if_fail(!in_command.empty(), 0);
     // printf("Executing\n");
 
-    std::vector <std::string> argv;
-
-/*
-    for (std::list<std::string>::const_iterator i = in_command.begin();
-            i != in_command.end(); i++) {
-        argv.push_back(*i);
-    }
-*/
-    // according to http://www.gtk.org/api/2.6/glib/glib-Spawning-Processes.html spawn quotes parameter containing spaces
-    // we tokenize so that spwan does not need to quote over all params
-    for (std::list<std::string>::const_iterator i = in_command.begin();
-            i != in_command.end(); i++) {
-        std::string param_str = *i;
-        do {
-            //g_message("param: %s", param_str.c_str());
-            size_t first_space = param_str.find_first_of(' ');
-            size_t first_quote = param_str.find_first_of('"');
-            //std::cout << "first space " << first_space << std::endl;
-            //std::cout << "first quote " << first_quote << std::endl;
-
-            if ((first_quote != std::string::npos) && (first_quote == 0)) {
-                size_t next_quote = param_str.find_first_of('"', first_quote + 1);
-                //std::cout << "next quote " << next_quote << std::endl;
-
-                if (next_quote != std::string::npos) {
-                    //std::cout << "now split " << next_quote << std::endl;
-                    //std::cout << "now split " << param_str.substr(1, next_quote - 1) << std::endl;
-                    //std::cout << "now split " << param_str.substr(next_quote + 1) << std::endl;
-                    std::string part_str = param_str.substr(1, next_quote - 1);
-                    if (part_str.size() > 0)
-                        argv.push_back(part_str);
-                    param_str = param_str.substr(next_quote + 1);
-
-                } else {
-                    if (param_str.size() > 0)
-                        argv.push_back(param_str);
-                    param_str = "";
-                }
-
-            } else if (first_space != std::string::npos) {
-                //std::cout << "now split " << first_space << std::endl;
-                //std::cout << "now split " << param_str.substr(0, first_space) << std::endl;
-                //std::cout << "now split " << param_str.substr(first_space + 1) << std::endl;
-                std::string part_str = param_str.substr(0, first_space);
-                if (part_str.size() > 0) {
-                    argv.push_back(part_str);
-                }
-                param_str = param_str.substr(first_space + 1);
-            } else {
-                if (param_str.size() > 0) {
-                    argv.push_back(param_str);
-                }
-                param_str = "";
-            }
-        } while (param_str.size() > 0);
-    }
-
-    for (std::list<std::string>::const_iterator i = in_params.begin();
-            i != in_params.end(); i++) {
-        //g_message("Script parameter: %s",(*i)g.c_str());
-        argv.push_back(*i);
-    }
-
-    if (!(filein.empty())) {
+    std::vector<std::string> argv;
+
+    bool interpreted = (in_command.size() == 2);
+    std::string program = in_command.front();
+    std::string script = interpreted ? in_command.back() : "";
+    std::string working_directory = "";
+
+    // Use Glib::find_program_in_path instead of the equivalent
+    // Glib::spawn_* functionality, because _wspawnp is broken on Windows:
+    // it doesn't work when PATH contains Unicode directories
+    if (!Glib::path_is_absolute(program)) {
+        program = Glib::find_program_in_path(program);
+    }
+    argv.push_back(program);
+
+    if (interpreted) {
+        // On Windows, Python garbles Unicode command line parameters
+        // in an useless way. This means extensions fail when Inkscape
+        // is run from an Unicode directory.
+        // As a workaround, we set the working directory to the one
+        // containing the script.
+        working_directory = Glib::path_get_dirname(script);
+        script = Glib::path_get_basename(script);
+        #ifdef G_OS_WIN32
+        // ANNOYING: glibmm does not wrap g_win32_locale_filename_from_utf8
+        gchar *workdir_s = g_win32_locale_filename_from_utf8(working_directory.data());
+        working_directory = workdir_s;
+        g_free(workdir_s);
+        #endif
+
+        argv.push_back(script);
+    }
+
+    // assemble the rest of argv
+    std::copy(in_params.begin(), in_params.end(), std::back_inserter(argv));
+    if (!filein.empty()) {
         argv.push_back(filein);
     }
 
     int stdout_pipe, stderr_pipe;
 
     try {
-        Inkscape::IO::spawn_async_with_pipes(Glib::get_current_dir(), // working directory
+        Glib::spawn_async_with_pipes(working_directory, // working directory
                                      argv,  // arg v
-                                     Glib::SPAWN_SEARCH_PATH /*| Glib::SPAWN_DO_NOT_REAP_CHILD*/,
+                                     static_cast<Glib::SpawnFlags>(0), // no flags
                                      sigc::slot<void>(),
                                      &_pid,          // Pid
                                      NULL,           // STDIN
                                      &stdout_pipe,   // STDOUT
                                      &stderr_pipe);  // STDERR
-    } catch (Glib::SpawnError e) {
-        printf("Can't Spawn!!! spawn returns: %d\n", e.code());
+    } catch (Glib::Error e) {
+        printf("Can't Spawn!!! spawn returns: %s\n", e.what().data());
         return 0;
     }
 
index e0b6701bf105cb5b8435c1c04a0692f0f28558f6..f37f2796656b05678c1ada8daa93058c5ee54779 100644 (file)
@@ -115,31 +115,14 @@ private:
       */
     Glib::ustring helper_extension;
 
-    /**
-     * Just a quick function to find and resolve relative paths for
-     * the incoming scripts
-     */
-    Glib::ustring solve_reldir (Inkscape::XML::Node *reprin);
-
-    /**
-     *
-     */
-    bool check_existance (const Glib::ustring &command);
-
-    /**
-     *
-     */
+    std::string solve_reldir (Inkscape::XML::Node *reprin);
+    bool check_existence (const std::string &command);
     void copy_doc (Inkscape::XML::Node * olddoc,
                    Inkscape::XML::Node * newdoc);
-
-    /**
-     *
-     */
     void checkStderr (const Glib::ustring &filename,
                       Gtk::MessageType type,
                       const Glib::ustring &message);
 
-
     class file_listener {
         Glib::ustring _string;
         sigc::connection _conn;
@@ -184,7 +167,6 @@ private:
             return true;
         };
 
-        // Note, doing a copy here, on purpose
         Glib::ustring string (void) { return _string; };
 
         bool toFile (const Glib::ustring &name) {
@@ -215,7 +197,7 @@ private:
     };
     static interpreter_t const interpreterTab[];
 
-    Glib::ustring resolveInterpreterExecutable(const Glib::ustring &interpNameArg);
+    std::string resolveInterpreterExecutable(const Glib::ustring &interpNameArg);
 
 }; // class Script
 
index 34160b64801f2c195a98515f47d7e92415d3d2ed..a68d027079816059886210824230c2e57ecf41ff 100644 (file)
 #include "sys.h"
 
 #ifdef WIN32
-
-#define BYPASS_GLIB_SPAWN 1
-
-#ifdef BYPASS_GLIB_SPAWN
-
-#include <process.h>   // declares spawn functions
-#include <wchar.h>     // declares _wspawn functions
-
-#ifndef __MINGW32__
-# ifdef __cplusplus
-extern "C" {
-# endif
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnl   (int, const wchar_t*, const wchar_t*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnle  (int, const wchar_t*, const wchar_t*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnlp  (int, const wchar_t*, const wchar_t*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnlpe (int, const wchar_t*, const wchar_t*, ...);
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnv   (int, const wchar_t*, const wchar_t* const*);
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnve  (int, const wchar_t*, const wchar_t* const*, const wchar_t* const*);
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnvp  (int, const wchar_t*, const wchar_t* const*);
-_CRTIMP int __cdecl __MINGW_NOTHROW _wspawnvpe (int, const wchar_t*, const wchar_t* const*, const wchar_t* const*);
-# ifdef __cplusplus
-}
-# endif
-#endif
-#include <unistd.h>
-#include <glibmm/i18n.h>
-#include <fcntl.h>
-#include <io.h>
-
-#endif // BYPASS_GLIB_SPAWN
-
 // For now to get at is_os_wide().
 #include "extension/internal/win32.h"
 using Inkscape::Extension::Internal::PrintWin32;
-
 #endif // WIN32
 
 //#define INK_DUMP_FILENAME_CONV 1
@@ -217,32 +185,7 @@ int Inkscape::IO::mkdir_utf8name( char const *utf8name )
  * */
 int Inkscape::IO::file_open_tmp(std::string& name_used, const std::string& prefix)
 {
-#ifndef WIN32
     return Glib::file_open_tmp(name_used, prefix);
-#else
-    /* Special case for WIN32 due to a bug in glibmm
-     * (only needed for Windows Vista, but since there is only one windows build all builds get the workaround)
-     * The workaround can be removed if the bug is fixed in glibmm
-     * 
-     * The code is mostly identical to the implementation in glibmm
-     * http://svn.gnome.org/svn/glibmm/branches/glibmm-2-12/glib/src/fileutils.ccg
-     * */
-    
-    std::string basename_template (prefix);
-    basename_template += "XXXXXX"; // this sillyness shouldn't be in the interface
-    
-    GError* error = 0;
-    gchar *buf_name_used;
-    
-    gint fileno = g_file_open_tmp(basename_template.c_str(), &buf_name_used, &error);
-    
-    if(error)
-        Glib::Error::throw_exception(error);
-    
-    name_used = g_strdup(buf_name_used);
-    g_free(buf_name_used);
-    return fileno;
-#endif
 }
 
 bool Inkscape::IO::file_test( char const *utf8name, GFileTest test )
@@ -372,842 +315,6 @@ gchar* Inkscape::IO::locale_to_utf8_fallback( const gchar *opsysstring,
     return result;
 }
 
-#ifdef BYPASS_GLIB_SPAWN
-/*
-       this code was taken from the original glib sources
-*/
-#define GSPAWN_HELPER
-enum
-{
-  CHILD_NO_ERROR,
-  CHILD_CHDIR_FAILED,
-  CHILD_SPAWN_FAILED,
-};
-
-enum {
-  ARG_CHILD_ERR_REPORT = 1,
-  ARG_HELPER_SYNC,
-  ARG_STDIN,
-  ARG_STDOUT,
-  ARG_STDERR,
-  ARG_WORKING_DIRECTORY,
-  ARG_CLOSE_DESCRIPTORS,
-  ARG_USE_PATH,
-  ARG_WAIT,
-  ARG_PROGRAM,
-  ARG_COUNT = ARG_PROGRAM
-};
-static int debug = 0;
-#define HELPER_PROCESS "gspawn-win32-helper"
-
-
-static int
-dup_noninherited (int fd,
-                 int mode)
-{
-  HANDLE filehandle;
-
-  DuplicateHandle (GetCurrentProcess (), (LPHANDLE) _get_osfhandle (fd),
-                  GetCurrentProcess (), &filehandle,
-                  0, FALSE, DUPLICATE_SAME_ACCESS);
-  close (fd);
-  return _open_osfhandle(reinterpret_cast<LONG_PTR>(filehandle), mode | _O_NOINHERIT);
-}
-
-/* The helper process writes a status report back to us, through a
- * pipe, consisting of two ints.
- */
-static gboolean
-read_helper_report (int      fd,
-                   gint     report[2],
-                   GError **error)
-{
-  gint bytes = 0;
-
-  while (bytes < sizeof(gint)*2)
-    {
-      gint chunk;
-
-      if (debug)
-       g_print ("%s:read_helper_report: read %d...\n",
-                __FILE__,
-                sizeof(gint)*2 - bytes);
-
-      chunk = read (fd, ((gchar*)report) + bytes,
-                   sizeof(gint)*2 - bytes);
-
-      if (debug)
-       g_print ("...got %d bytes\n", chunk);
-
-      if (chunk < 0)
-        {
-          /* Some weird shit happened, bail out */
-
-          g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                       _("Failed to read from child pipe (%s)"),
-                       g_strerror (errno));
-
-          return FALSE;
-        }
-      else if (chunk == 0)
-       {
-         g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                      _("Failed to read from child pipe (%s)"),
-                      "EOF");
-         break; /* EOF */
-       }
-      else
-       bytes += chunk;
-    }
-
-  if (bytes < sizeof(gint)*2)
-    return FALSE;
-
-  return TRUE;
-}
-
-
-static void
-set_child_error (gint         report[2],
-                const gchar *working_directory,
-                GError     **error)
-{
-  switch (report[0])
-    {
-    case CHILD_CHDIR_FAILED:
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
-                  _("Failed to change to directory '%s' (%s)"),
-                  working_directory,
-                  g_strerror (report[1]));
-      break;
-    case CHILD_SPAWN_FAILED:
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                  _("Failed to execute child process (%s)"),
-                  g_strerror (report[1]));
-      break;
-    default:
-      g_assert_not_reached ();
-    }
-}
-
-static gchar *
-protect_argv_string (const gchar *string)
-{
-  const gchar *p = string;
-  gchar *retval, *q;
-  gint len = 0;
-  gboolean need_dblquotes = FALSE;
-  while (*p)
-    {
-      if (*p == ' ' || *p == '\t')
-       need_dblquotes = TRUE;
-      else if (*p == '"')
-       len++;
-      else if (*p == '\\')
-       {
-         const gchar *pp = p;
-         while (*pp && *pp == '\\')
-           pp++;
-         if (*pp == '"')
-           len++;
-       }
-      len++;
-      p++;
-    }
-
-  q = retval = (gchar *)g_malloc (len + need_dblquotes*2 + 1);
-  p = string;
-
-  if (need_dblquotes)
-    *q++ = '"';
-
-  while (*p)
-    {
-      if (*p == '"')
-       *q++ = '\\';
-      else if (*p == '\\')
-       {
-         const gchar *pp = p;
-         while (*pp && *pp == '\\')
-           pp++;
-         if (*pp == '"')
-           *q++ = '\\';
-       }
-      *q++ = *p;
-      p++;
-    }
-
-  if (need_dblquotes)
-    *q++ = '"';
-  *q++ = '\0';
-
-  return retval;
-}
-
-
-static gint
-protect_argv (gchar  **argv,
-             gchar ***new_argv)
-{
-  gint i;
-  gint argc = 0;
-
-  while (argv[argc])
-    ++argc;
-  *new_argv = g_new (gchar *, argc+1);
-
-  /* Quote each argv element if necessary, so that it will get
-   * reconstructed correctly in the C runtime startup code.  Note that
-   * the unquoting algorithm in the C runtime is really weird, and
-   * rather different than what Unix shells do. See stdargv.c in the C
-   * runtime sources (in the Platform SDK, in src/crt).
-   *
-   * Note that an new_argv[0] constructed by this function should
-   * *not* be passed as the filename argument to a spawn* or exec*
-   * family function. That argument should be the real file name
-   * without any quoting.
-   */
-  for (i = 0; i < argc; i++)
-    (*new_argv)[i] = protect_argv_string (argv[i]);
-
-  (*new_argv)[argc] = NULL;
-
-  return argc;
-}
-
-
-static gboolean
-utf8_charv_to_wcharv (char     **utf8_charv,
-                     wchar_t ***wcharv,
-                     int       *error_index,
-                     GError   **error)
-{
-  wchar_t **retval = NULL;
-
-  *wcharv = NULL;
-  if (utf8_charv != NULL)
-    {
-      int n = 0, i;
-
-      while (utf8_charv[n])
-       n++;
-      retval = g_new (wchar_t *, n + 1);
-
-      for (i = 0; i < n; i++)
-       {
-         retval[i] = (wchar_t *)g_utf8_to_utf16 (utf8_charv[i], -1, NULL, NULL, error);
-         if (retval[i] == NULL)
-           {
-             if (error_index)
-               *error_index = i;
-             while (i)
-               g_free (retval[--i]);
-             g_free (retval);
-             return FALSE;
-           }
-       }
-
-      retval[n] = NULL;
-    }
-  *wcharv = retval;
-  return TRUE;
-}
-
-
-/* Avoids a danger in threaded situations (calling close()
- * on a file descriptor twice, and another thread has
- * re-opened it since the first close)
- */
-static void
-close_and_invalidate (gint *fd)
-{
-  if (*fd < 0)
-    return;
-
-  close (*fd);
-  *fd = -1;
-}
-
-
-static gboolean
-do_spawn_directly (gint                 *exit_status,
-                  gboolean              do_return_handle,
-                  GSpawnFlags           flags,
-                  gchar               **argv,
-                  char                **envp,
-                  char                **protected_argv,
-                  GSpawnChildSetupFunc  child_setup,
-                  gpointer              user_data,
-                  GPid                 *child_handle,
-                  GError              **error)
-{
-  const int mode = (exit_status == NULL) ? P_NOWAIT : P_WAIT;
-  char **new_argv;
-  int rc = -1;
-  int saved_errno;
-  GError *conv_error = NULL;
-  gint conv_error_index;
-  wchar_t *wargv0, **wargv, **wenvp;
-
-  new_argv = (flags & G_SPAWN_FILE_AND_ARGV_ZERO) ? protected_argv + 1 : protected_argv;
-
-  wargv0 = (wchar_t *)g_utf8_to_utf16 (argv[0], -1, NULL, NULL, &conv_error);
-  if (wargv0 == NULL)
-    {
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                  _("Invalid program name: %s"),
-                  conv_error->message);
-      g_error_free (conv_error);
-
-      return FALSE;
-    }
-
-  if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error))
-    {
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                  _("Invalid string in argument vector at %d: %s"),
-                  conv_error_index, conv_error->message);
-      g_error_free (conv_error);
-      g_free (wargv0);
-
-      return FALSE;
-    }
-
-  if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error))
-    {
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                  _("Invalid string in environment: %s"),
-                  conv_error->message);
-      g_error_free (conv_error);
-      g_free (wargv0);
-      g_strfreev ((gchar **) wargv);
-
-      return FALSE;
-    }
-
-  if (child_setup)
-    (* child_setup) (user_data);
-
-  if (flags & G_SPAWN_SEARCH_PATH)
-    if (wenvp != NULL)
-      rc = _wspawnvpe (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
-    else
-      rc = _wspawnvp (mode, wargv0, (const wchar_t **) wargv);
-  else
-    if (wenvp != NULL)
-      rc = _wspawnve (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
-    else
-      rc = _wspawnv (mode, wargv0, (const wchar_t **) wargv);
-
-  g_free (wargv0);
-  g_strfreev ((gchar **) wargv);
-  g_strfreev ((gchar **) wenvp);
-
-  saved_errno = errno;
-
-  if (rc == -1 && saved_errno != 0)
-    {
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                  _("Failed to execute child process (%s)"),
-                  g_strerror (saved_errno));
-      return FALSE;
-    }
-
-  if (exit_status == NULL)
-    {
-      if (child_handle && do_return_handle)
-       *child_handle = (GPid) rc;
-      else
-       {
-         CloseHandle ((HANDLE) rc);
-         if (child_handle)
-           *child_handle = 0;
-       }
-    }
-  else
-    *exit_status = rc;
-
-  return TRUE;
-}
-
-static gboolean
-make_pipe (gint     p[2],
-           GError **error)
-{
-  if (_pipe (p, 4096, _O_BINARY) < 0)
-    {
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                   _("Failed to create pipe for communicating with child process (%s)"),
-                   g_strerror (errno));
-      return FALSE;
-    }
-  else
-    return TRUE;
-}
-
-
-static gboolean
-do_spawn_with_pipes (gint                 *exit_status,
-                    gboolean              do_return_handle,
-                    const gchar          *working_directory,
-                    gchar               **argv,
-                    char                **envp,
-                    GSpawnFlags           flags,
-                    GSpawnChildSetupFunc  child_setup,
-                    gpointer              user_data,
-                    GPid                 *child_handle,
-                    gint                 *standard_input,
-                    gint                 *standard_output,
-                    gint                 *standard_error,
-                    gint                 *err_report,
-                    GError              **error)
-{
-  char **protected_argv;
-  char args[ARG_COUNT][10];
-  char **new_argv;
-  int i;
-  int rc = -1;
-  int saved_errno;
-  int argc;
-  int stdin_pipe[2] = { -1, -1 };
-  int stdout_pipe[2] = { -1, -1 };
-  int stderr_pipe[2] = { -1, -1 };
-  int child_err_report_pipe[2] = { -1, -1 };
-  int helper_sync_pipe[2] = { -1, -1 };
-  int helper_report[2];
-  static gboolean warned_about_child_setup = FALSE;
-  GError *conv_error = NULL;
-  gint conv_error_index;
-  gchar *helper_process;
-  CONSOLE_CURSOR_INFO cursor_info;
-  wchar_t *whelper, **wargv, **wenvp;
-  //extern gchar *_glib_get_installation_directory (void);
-  gchar *glib_top;
-
-  if (child_setup && !warned_about_child_setup)
-    {
-      warned_about_child_setup = TRUE;
-      g_warning ("passing a child setup function to the g_spawn functions is pointless and dangerous on Win32");
-    }
-
-  argc = protect_argv (argv, &protected_argv);
-
-  if (!standard_input && !standard_output && !standard_error &&
-      (flags & G_SPAWN_CHILD_INHERITS_STDIN) &&
-      !(flags & G_SPAWN_STDOUT_TO_DEV_NULL) &&
-      !(flags & G_SPAWN_STDERR_TO_DEV_NULL) &&
-      (working_directory == NULL || !*working_directory) &&
-      (flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN))
-    {
-      /* We can do without the helper process */
-      gboolean retval =
-       do_spawn_directly (exit_status, do_return_handle, flags,
-                          argv, envp, protected_argv,
-                          child_setup, user_data, child_handle,
-                          error);
-      g_strfreev (protected_argv);
-      return retval;
-    }
-
-  if (standard_input && !make_pipe (stdin_pipe, error))
-    goto cleanup_and_fail;
-
-  if (standard_output && !make_pipe (stdout_pipe, error))
-    goto cleanup_and_fail;
-
-  if (standard_error && !make_pipe (stderr_pipe, error))
-    goto cleanup_and_fail;
-
-  if (!make_pipe (child_err_report_pipe, error))
-    goto cleanup_and_fail;
-
-  if (!make_pipe (helper_sync_pipe, error))
-    goto cleanup_and_fail;
-
-  new_argv = g_new (char *, argc + 1 + ARG_COUNT);
-  if (GetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info))
-    helper_process = HELPER_PROCESS "-console.exe";
-  else
-    helper_process = HELPER_PROCESS ".exe";
-
-  glib_top = NULL;
-  if (glib_top != NULL)
-    {
-      helper_process = g_build_filename (glib_top, "bin", helper_process, NULL);
-      g_free (glib_top);
-    }
-  else
-    helper_process = g_strdup (helper_process);
-
-  new_argv[0] = protect_argv_string (helper_process);
-
-  sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_pipe[1]);
-  new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT];
-
-  /* Make the read end of the child error report pipe
-   * noninherited. Otherwise it will needlessly be inherited by the
-   * helper process, and the started actual user process. As such that
-   * shouldn't harm, but it is unnecessary.
-   */
-  child_err_report_pipe[0] = dup_noninherited (child_err_report_pipe[0], _O_RDONLY);
-
-  if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
-    {
-      /* Overload ARG_CHILD_ERR_REPORT to also encode the
-       * G_SPAWN_FILE_AND_ARGV_ZERO functionality.
-       */
-      strcat (args[ARG_CHILD_ERR_REPORT], "#");
-    }
-
-  sprintf (args[ARG_HELPER_SYNC], "%d", helper_sync_pipe[0]);
-  new_argv[ARG_HELPER_SYNC] = args[ARG_HELPER_SYNC];
-
-  /* Make the write end of the sync pipe noninherited. Otherwise the
-   * helper process will inherit it, and thus if this process happens
-   * to crash before writing the sync byte to the pipe, the helper
-   * process won't read but won't get any EOF either, as it has the
-   * write end open itself.
-   */
-  helper_sync_pipe[1] = dup_noninherited (helper_sync_pipe[1], _O_WRONLY);
-
-  if (standard_input)
-    {
-      sprintf (args[ARG_STDIN], "%d", stdin_pipe[0]);
-      new_argv[ARG_STDIN] = args[ARG_STDIN];
-    }
-  else if (flags & G_SPAWN_CHILD_INHERITS_STDIN)
-    {
-      /* Let stdin be alone */
-      new_argv[ARG_STDIN] = "-";
-    }
-  else
-    {
-      /* Keep process from blocking on a read of stdin */
-      new_argv[ARG_STDIN] = "z";
-    }
-
-  if (standard_output)
-    {
-      sprintf (args[ARG_STDOUT], "%d", stdout_pipe[1]);
-      new_argv[ARG_STDOUT] = args[ARG_STDOUT];
-    }
-  else if (flags & G_SPAWN_STDOUT_TO_DEV_NULL)
-    {
-      new_argv[ARG_STDOUT] = "z";
-    }
-  else
-    {
-      new_argv[ARG_STDOUT] = "-";
-    }
-
-  if (standard_error)
-    {
-      sprintf (args[ARG_STDERR], "%d", stderr_pipe[1]);
-     new_argv[ARG_STDERR] = args[ARG_STDERR];
-    }
-  else if (flags & G_SPAWN_STDERR_TO_DEV_NULL)
-    {
-      new_argv[ARG_STDERR] = "z";
-    }
-  else
-    {
-      new_argv[ARG_STDERR] = "-";
-    }
-
-  if (working_directory && *working_directory)
-    new_argv[ARG_WORKING_DIRECTORY] = protect_argv_string (working_directory);
-  else
-    new_argv[ARG_WORKING_DIRECTORY] = g_strdup ("-");
-
-  if (!(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN))
-    new_argv[ARG_CLOSE_DESCRIPTORS] = "y";
-  else
-    new_argv[ARG_CLOSE_DESCRIPTORS] = "-";
-
-  if (flags & G_SPAWN_SEARCH_PATH)
-    new_argv[ARG_USE_PATH] = "y";
-  else
-    new_argv[ARG_USE_PATH] = "-";
-
-  if (exit_status == NULL)
-    new_argv[ARG_WAIT] = "-";
-  else
-    new_argv[ARG_WAIT] = "w";
-
-  for (i = 0; i <= argc; i++)
-    new_argv[ARG_PROGRAM + i] = protected_argv[i];
-
-  //SETUP_DEBUG();
-
-  if (debug)
-    {
-      g_print ("calling %s with argv:\n", helper_process);
-      for (i = 0; i < argc + 1 + ARG_COUNT; i++)
-       g_print ("argv[%d]: %s\n", i, (new_argv[i] ? new_argv[i] : "NULL"));
-    }
-
-  if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error))
-    {
-      if (conv_error_index == ARG_WORKING_DIRECTORY)
-       g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
-                    _("Invalid working directory: %s"),
-                    conv_error->message);
-      else
-       g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                    _("Invalid string in argument vector at %d: %s"),
-                    conv_error_index - ARG_PROGRAM, conv_error->message);
-      g_error_free (conv_error);
-      g_strfreev (protected_argv);
-      g_free (new_argv[0]);
-      g_free (new_argv[ARG_WORKING_DIRECTORY]);
-      g_free (new_argv);
-      g_free (helper_process);
-
-      goto cleanup_and_fail;
-    }
-
-  if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error))
-    {
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                  _("Invalid string in environment: %s"),
-                  conv_error->message);
-      g_error_free (conv_error);
-      g_strfreev (protected_argv);
-      g_free (new_argv[0]);
-      g_free (new_argv[ARG_WORKING_DIRECTORY]);
-      g_free (new_argv);
-      g_free (helper_process);
-      g_strfreev ((gchar **) wargv);
-
-      goto cleanup_and_fail;
-    }
-
-  if (child_setup)
-    (* child_setup) (user_data);
-
-  whelper = (wchar_t *)g_utf8_to_utf16 (helper_process, -1, NULL, NULL, NULL);
-  g_free (helper_process);
-
-  if (wenvp != NULL)
-    rc = _wspawnvpe (P_NOWAIT, whelper, (const wchar_t **) wargv, (const wchar_t **) wenvp);
-  else
-    rc = _wspawnvp (P_NOWAIT, whelper, (const wchar_t **) wargv);
-
-  saved_errno = errno;
-
-  g_free (whelper);
-  g_strfreev ((gchar **) wargv);
-  g_strfreev ((gchar **) wenvp);
-
-  /* Close the other process's ends of the pipes in this process,
-   * otherwise the reader will never get EOF.
-   */
-  close_and_invalidate (&child_err_report_pipe[1]);
-  close_and_invalidate (&helper_sync_pipe[0]);
-  close_and_invalidate (&stdin_pipe[0]);
-  close_and_invalidate (&stdout_pipe[1]);
-  close_and_invalidate (&stderr_pipe[1]);
-
-  g_strfreev (protected_argv);
-
-  g_free (new_argv[0]);
-  g_free (new_argv[ARG_WORKING_DIRECTORY]);
-  g_free (new_argv);
-
-  /* Check if gspawn-win32-helper couldn't be run */
-  if (rc == -1 && saved_errno != 0)
-    {
-      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
-                  _("Failed to execute helper program (%s)"),
-                  g_strerror (saved_errno));
-      goto cleanup_and_fail;
-    }
-
-  if (exit_status != NULL)
-    {
-      /* Synchronous case. Pass helper's report pipe back to caller,
-       * which takes care of reading it after the grandchild has
-       * finished.
-       */
-      g_assert (err_report != NULL);
-      *err_report = child_err_report_pipe[0];
-      write (helper_sync_pipe[1], " ", 1);
-      close_and_invalidate (&helper_sync_pipe[1]);
-    }
-  else
-    {
-      /* Asynchronous case. We read the helper's report right away. */
-      if (!read_helper_report (child_err_report_pipe[0], helper_report, error))
-       goto cleanup_and_fail;
-
-      close_and_invalidate (&child_err_report_pipe[0]);
-
-      switch (helper_report[0])
-       {
-       case CHILD_NO_ERROR:
-         if (child_handle && do_return_handle)
-           {
-             /* rc is our HANDLE for gspawn-win32-helper. It has
-              * told us the HANDLE of its child. Duplicate that into
-              * a HANDLE valid in this process.
-              */
-             if (!DuplicateHandle ((HANDLE) rc, (HANDLE) helper_report[1],
-                                   GetCurrentProcess (), (LPHANDLE) child_handle,
-                                   0, TRUE, DUPLICATE_SAME_ACCESS))
-               {
-                 char *emsg = g_win32_error_message (GetLastError ());
-                 g_print("%s\n", emsg);
-                 *child_handle = 0;
-               }
-           }
-         else if (child_handle)
-           *child_handle = 0;
-         write (helper_sync_pipe[1], " ", 1);
-         close_and_invalidate (&helper_sync_pipe[1]);
-         break;
-
-       default:
-         write (helper_sync_pipe[1], " ", 1);
-         close_and_invalidate (&helper_sync_pipe[1]);
-         set_child_error (helper_report, working_directory, error);
-         goto cleanup_and_fail;
-       }
-    }
-
-  /* Success against all odds! return the information */
-
-  if (standard_input)
-    *standard_input = stdin_pipe[1];
-  if (standard_output)
-    *standard_output = stdout_pipe[0];
-  if (standard_error)
-    *standard_error = stderr_pipe[0];
-  if (rc != -1)
-    CloseHandle ((HANDLE) rc);
-
-  return TRUE;
-
-  cleanup_and_fail:
-
-  if (rc != -1)
-    CloseHandle ((HANDLE) rc);
-  if (child_err_report_pipe[0] != -1)
-    close (child_err_report_pipe[0]);
-  if (child_err_report_pipe[1] != -1)
-    close (child_err_report_pipe[1]);
-  if (helper_sync_pipe[0] != -1)
-    close (helper_sync_pipe[0]);
-  if (helper_sync_pipe[1] != -1)
-    close (helper_sync_pipe[1]);
-  if (stdin_pipe[0] != -1)
-    close (stdin_pipe[0]);
-  if (stdin_pipe[1] != -1)
-    close (stdin_pipe[1]);
-  if (stdout_pipe[0] != -1)
-    close (stdout_pipe[0]);
-  if (stdout_pipe[1] != -1)
-    close (stdout_pipe[1]);
-  if (stderr_pipe[0] != -1)
-    close (stderr_pipe[0]);
-  if (stderr_pipe[1] != -1)
-    close (stderr_pipe[1]);
-
-  return FALSE;
-}
-
-gboolean
-my_spawn_async_with_pipes_utf8 (const gchar          *working_directory,
-                              gchar               **argv,
-                              gchar               **envp,
-                              GSpawnFlags           flags,
-                              GSpawnChildSetupFunc  child_setup,
-                              gpointer              user_data,
-                              GPid                 *child_handle,
-                              gint                 *standard_input,
-                              gint                 *standard_output,
-                              gint                 *standard_error,
-                              GError              **error)
-{
-  g_return_val_if_fail (argv != NULL, FALSE);
-  g_return_val_if_fail (standard_output == NULL ||
-                        !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
-  g_return_val_if_fail (standard_error == NULL ||
-                        !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
-  /* can't inherit stdin if we have an input pipe. */
-  g_return_val_if_fail (standard_input == NULL ||
-                        !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
-
-  return do_spawn_with_pipes (NULL,
-                             (flags & G_SPAWN_DO_NOT_REAP_CHILD),
-                             working_directory,
-                             argv,
-                             envp,
-                             flags,
-                             child_setup,
-                             user_data,
-                             child_handle,
-                             standard_input,
-                             standard_output,
-                             standard_error,
-                             NULL,
-                             error);
-}
-
-typedef GPid Pid;
-
-// _WRAP_ENUM(SpawnFlags, GSpawnFlags, NO_GTYPE)
-
-/* Helper callback to invoke the actual sigc++ slot.
- * We don't need to worry about (un)referencing, since the
- * child process gets its own copy of the parent's memory anyway.
- */
-static void child_setup_callback(void* user_data)
-{
-  #ifdef GLIBMM_EXCEPTIONS_ENABLED
-  try
-  {
-  #endif //GLIBMM_EXCEPTIONS_ENABLED
-    (*reinterpret_cast<sigc::slot<void>*>(user_data))();
-  #ifdef GLIBMM_EXCEPTIONS_ENABLED
-  }
-  catch(...)
-  {
-    Glib::exception_handlers_invoke();
-  }
-  #endif //GLIBMM_EXCEPTIONS_ENABLED
-}
-
-
-void my_spawn_async_with_pipes(const std::string& working_directory,
-                            const Glib::ArrayHandle<std::string>& argv,
-                            GSpawnFlags flags,
-                            const sigc::slot<void>& child_setup,
-                            Pid* child_pid,
-                            int* standard_input,
-                            int* standard_output,
-                            int* standard_error)
-{
-  const bool setup_slot = !child_setup.empty();
-  sigc::slot<void> child_setup_ = child_setup;
-  GError* error = 0;
-
-  my_spawn_async_with_pipes_utf8(
-      working_directory.c_str(),
-      const_cast<char**>(argv.data()), 0,
-      static_cast<GSpawnFlags>(unsigned(flags)),
-      (setup_slot) ? &child_setup_callback : 0,
-      (setup_slot) ? &child_setup_         : 0,
-      child_pid,
-      standard_input, standard_output, standard_error,
-      &error);
-
-  if(error)
-    Glib::Error::throw_exception(error);
-}
-
-#endif
-
 void
 Inkscape::IO::spawn_async_with_pipes( const std::string& working_directory,
                                       const Glib::ArrayHandle<std::string>& argv,
@@ -1218,7 +325,6 @@ Inkscape::IO::spawn_async_with_pipes( const std::string& working_directory,
                                       int* standard_output,
                                       int* standard_error)
 {
-#ifndef BYPASS_GLIB_SPAWN
     Glib::spawn_async_with_pipes(working_directory,
                                  argv,
                                  flags,
@@ -1227,16 +333,6 @@ Inkscape::IO::spawn_async_with_pipes( const std::string& working_directory,
                                  standard_input,
                                  standard_output,
                                  standard_error);
-#else
-    my_spawn_async_with_pipes(working_directory,
-                              argv,
-                              static_cast<GSpawnFlags>(flags),
-                              child_setup,
-                              child_pid,
-                              standard_input,
-                              standard_output,
-                              standard_error);
-#endif
 }
 
 
index d11222203778b3728d0fec669d76494fae9bec3f..a4ed5d77bf47dc88de096fc0c6e978c83ec23f10 100644 (file)
@@ -47,6 +47,8 @@
 #endif /* Not def: POPT_TABLEEND */
 
 #include <libxml/tree.h>
+#include <glib.h>
+#include <glib/gprintf.h>
 #include <glib-object.h>
 #include <gtk/gtk.h>
 #include <gtk/gtkmain.h>
@@ -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
index f1fa3c2cdfae7e9eaff1da5c14b134de645d1103..8c1dd4f0022857dff53fef33a80e8c10f77c961b 100644 (file)
 #endif
 
 
-/* PLEASE NOTE:  We use GThreads now for portability */
-/* @see http://developer.gnome.org/doc/API/2.0/glib/glib-Threads.html */
-#ifndef BR_THREADS
-    /* Change 1 to 0 if you don't want thread support */
-    #define BR_THREADS 1
-    #include <glib.h> //for GThreads
-#endif /* BR_THREADS */
-
+#include <glib.h>
 #include <cstdlib>
 #include <cstdio>
 #include <cstring>
@@ -55,9 +48,9 @@ extern "C" {
 #define NULL ((void *) 0)
 
 #ifdef __GNUC__
-       #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;}
+    #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;}
 #else
-       #define br_return_val_if_fail(expr,val) if (!(expr)) return val
+    #define br_return_val_if_fail(expr,val) if (!(expr)) return val
 #endif /* __GNUC__ */
 
 
@@ -72,8 +65,8 @@ extern "C" {
  * br_locate:
  * symbol: A symbol that belongs to the app/library you want to locate.
  * Returns: A newly allocated string containing the full path of the
- *         app/library that func belongs to, or NULL on error. This
- *         string should be freed when not when no longer needed.
+ *        app/library that func belongs to, or NULL on error. This
+ *        string should be freed when not when no longer needed.
  *
  * Finds out to which application or library symbol belongs, then locate
  * the full path of that application or library.
@@ -85,70 +78,70 @@ extern "C" {
  * #include "libfoo.h"
  *
  * int main (int argc, char *argv[]) {
- *     printf ("Full path of this app: %s\n", br_locate (&argc));
- *     libfoo_start ();
- *     return 0;
+ *    printf ("Full path of this app: %s\n", br_locate (&argc));
+ *    libfoo_start ();
+ *    return 0;
  * }
  *
  * --> libfoo.c starts here
  * #include "prefix.h"
  *
  * void libfoo_start () {
- *     --> "" is a symbol that belongs to libfoo (because it's called
- *     --> from libfoo_start()); that's why this works.
- *     printf ("libfoo is located in: %s\n", br_locate (""));
+ *    --> "" is a symbol that belongs to libfoo (because it's called
+ *    --> from libfoo_start()); that's why this works.
+ *    printf ("libfoo is located in: %s\n", br_locate (""));
  * }
  */
 char *
 br_locate (void *symbol)
 {
-       char line[5000];
-       FILE *f;
-       char *path;
-
-       br_return_val_if_fail (symbol != NULL, NULL);
-
-       f = fopen ("/proc/self/maps", "r");
-       if (!f)
-               return NULL;
-
-       while (!feof (f))
-       {
-               unsigned long start, end;
-
-               if (!fgets (line, sizeof (line), f))
-                       continue;
-               if (!strstr (line, " r-xp ") || !strchr (line, '/'))
-                       continue;
-
-               sscanf (line, "%lx-%lx ", &start, &end);
-               if (symbol >= (void *) start && symbol < (void *) end)
-               {
-                       char *tmp;
-                       size_t len;
-
-                       /* Extract the filename; it is always an absolute path */
-                       path = strchr (line, '/');
-
-                       /* Get rid of the newline */
-                       tmp = strrchr (path, '\n');
-                       if (tmp) *tmp = 0;
-
-                       /* Get rid of "(deleted)" */
-                       len = strlen (path);
-                       if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0)
-                       {
-                               tmp = path + len - 10;
-                               *tmp = 0;
-                       }
-
-                       fclose(f);
-                       return strdup (path);
-               }
-       }
-
-       fclose (f);
-       return NULL;
+    char line[5000];
+    FILE *f;
+    char *path;
+
+    br_return_val_if_fail (symbol != NULL, NULL);
+
+    f = fopen ("/proc/self/maps", "r");
+    if (!f)
+        return NULL;
+
+    while (!feof (f))
+    {
+        unsigned long start, end;
+
+        if (!fgets (line, sizeof (line), f))
+            continue;
+        if (!strstr (line, " r-xp ") || !strchr (line, '/'))
+            continue;
+
+        sscanf (line, "%lx-%lx ", &start, &end);
+        if (symbol >= (void *) start && symbol < (void *) end)
+        {
+            char *tmp;
+            size_t len;
+
+            /* Extract the filename; it is always an absolute path */
+            path = strchr (line, '/');
+
+            /* Get rid of the newline */
+            tmp = strrchr (path, '\n');
+            if (tmp) *tmp = 0;
+
+            /* Get rid of "(deleted)" */
+            len = strlen (path);
+            if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0)
+            {
+                tmp = path + len - 10;
+                *tmp = 0;
+            }
+
+            fclose(f);
+            return strdup (path);
+        }
+    }
+
+    fclose (f);
+    return NULL;
 }
 
 
@@ -168,16 +161,16 @@ br_locate (void *symbol)
 char *
 br_locate_prefix (void *symbol)
 {
-       char *path, *prefix;
+    char *path, *prefix;
 
-       br_return_val_if_fail (symbol != NULL, NULL);
+    br_return_val_if_fail (symbol != NULL, NULL);
 
-       path = br_locate (symbol);
-       if (!path) return NULL;
+    path = br_locate (symbol);
+    if (!path) return NULL;
 
-       prefix = br_extract_prefix (path);
-       free (path);
-       return prefix;
+    prefix = br_extract_prefix (path);
+    free (path);
+    return prefix;
 }
 
 
@@ -186,7 +179,7 @@ br_locate_prefix (void *symbol)
  * symbol: A symbol that belongs to the app/library you want to locate.
  * path: The path that you want to prepend the prefix to.
  * Returns: The new path, or NULL on error. This string should be freed when no
- *         longer needed.
+ *        longer needed.
  *
  * Gets the prefix of the app/library that symbol belongs to. Prepend that prefix to path.
  * Note that symbol cannot be a pointer to a function. That will not work.
@@ -198,24 +191,24 @@ br_locate_prefix (void *symbol)
 char *
 br_prepend_prefix (void *symbol, char *path)
 {
-       char *tmp, *newpath;
+    char *tmp, *newpath;
 
-       br_return_val_if_fail (symbol != NULL, NULL);
-       br_return_val_if_fail (path != NULL, NULL);
+    br_return_val_if_fail (symbol != NULL, NULL);
+    br_return_val_if_fail (path != NULL, NULL);
 
-       tmp = br_locate_prefix (symbol);
-       if (!tmp) return NULL;
+    tmp = br_locate_prefix (symbol);
+    if (!tmp) return NULL;
 
-       if (strcmp (tmp, "/") == 0)
-               newpath = strdup (path);
-       else
-               newpath = br_strcat (tmp, path);
+    if (strcmp (tmp, "/") == 0)
+        newpath = strdup (path);
+    else
+        newpath = br_strcat (tmp, path);
 
-       /* Get rid of compiler warning ("br_prepend_prefix never used") */
-       if (0) br_prepend_prefix (NULL, NULL);
+    /* Get rid of compiler warning ("br_prepend_prefix never used") */
+    if (0) br_prepend_prefix (NULL, NULL);
 
-       free (tmp);
-       return newpath;
+    free (tmp);
+    return newpath;
 }
 
 #endif /* ENABLE_BINRELOC */
@@ -264,33 +257,33 @@ br_free_last_value ()
 const char *
 br_thread_local_store (char *str)
 {
-       #if BR_THREADS
+    #if BR_THREADS
                 if (!g_thread_supported ())
                     {
                     g_thread_init ((GThreadFunctions *)NULL);
                     br_thread_key = g_private_new (g_free);
                     }
 
-               char *specific = (char *) g_private_get (br_thread_key);
-               if (specific)
+        char *specific = (char *) g_private_get (br_thread_key);
+        if (specific)
                     free (specific);
                 g_private_set (br_thread_key, str);
 
-       #else /* !BR_THREADS */
-               static int initialized = 0;
+    #else /* !BR_THREADS */
+        static int initialized = 0;
 
-               if (!initialized)
-               {
-                       atexit (br_free_last_value);
-                       initialized = 1;
-               }
+        if (!initialized)
+        {
+            atexit (br_free_last_value);
+            initialized = 1;
+        }
 
-               if (br_last_value)
-                       free (br_last_value);
-               br_last_value = str;
-       #endif /* BR_THREADS */
+        if (br_last_value)
+            free (br_last_value);
+        br_last_value = str;
+    #endif /* BR_THREADS */
 
-       return (const char *) str;
+    return (const char *) str;
 }
 
 
@@ -305,21 +298,21 @@ br_thread_local_store (char *str)
 char *
 br_strcat (const char *str1, const char *str2)
 {
-       char *result;
-       size_t len1, len2;
+    char *result;
+    size_t len1, len2;
 
-       if (!str1) str1 = "";
-       if (!str2) str2 = "";
+    if (!str1) str1 = "";
+    if (!str2) str2 = "";
 
-       len1 = strlen (str1);
-       len2 = strlen (str2);
+    len1 = strlen (str1);
+    len2 = strlen (str2);
 
-       result = (char *) malloc (len1 + len2 + 1);
-       memcpy (result, str1, len1);
-       memcpy (result + len1, str2, len2);
-       result[len1 + len2] = '\0';
+    result = (char *) malloc (len1 + len2 + 1);
+    memcpy (result, str1, len1);
+    memcpy (result + len1, str2, len2);
+    result[len1 + len2] = '\0';
 
-       return result;
+    return result;
 }
 
 
@@ -327,18 +320,18 @@ br_strcat (const char *str1, const char *str2)
 static char *
 br_strndup (char *str, size_t size)
 {
-       char *result = (char*)NULL;
-       size_t len;
+    char *result = (char*)NULL;
+    size_t len;
 
-       br_return_val_if_fail (str != (char*)NULL, (char*)NULL);
+    br_return_val_if_fail (str != (char*)NULL, (char*)NULL);
 
-       len = strlen (str);
-       if (!len) return strdup ("");
-       if (size > len) size = len;
+    len = strlen (str);
+    if (!len) return strdup ("");
+    if (size > len) size = len;
 
-       result = (char *) calloc (sizeof (char), len + 1);
-       memcpy (result, str, size);
-       return result;
+    result = (char *) calloc (sizeof (char), len + 1);
+    memcpy (result, str, size);
+    return result;
 }
 
 
@@ -356,23 +349,23 @@ br_strndup (char *str, size_t size)
 char *
 br_extract_dir (const char *path)
 {
-       const char *end;
-       char *result;
-
-       br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
-
-       end = strrchr (path, '/');
-       if (!end) return strdup (".");
-
-       while (end > path && *end == '/')
-               end--;
-       result = br_strndup ((char *) path, end - path + 1);
-       if (!*result)
-       {
-               free (result);
-               return strdup ("/");
-       } else
-               return result;
+    const char *end;
+    char *result;
+
+    br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
+
+    end = strrchr (path, '/');
+    if (!end) return strdup (".");
+
+    while (end > path && *end == '/')
+        end--;
+    result = br_strndup ((char *) path, end - path + 1);
+    if (!*result)
+    {
+        free (result);
+        return strdup ("/");
+    } else
+        return result;
 }
 
 
@@ -392,34 +385,34 @@ br_extract_dir (const char *path)
 char *
 br_extract_prefix (const char *path)
 {
-       const char *end;
-       char *tmp, *result;
-
-       br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
-
-       if (!*path) return strdup ("/");
-       end = strrchr (path, '/');
-       if (!end) return strdup (path);
-
-       tmp = br_strndup ((char *) path, end - path);
-       if (!*tmp)
-       {
-               free (tmp);
-               return strdup ("/");
-       }
-       end = strrchr (tmp, '/');
-       if (!end) return tmp;
-
-       result = br_strndup (tmp, end - tmp);
-       free (tmp);
-
-       if (!*result)
-       {
-               free (result);
-               result = strdup ("/");
-       }
-
-       return result;
+    const char *end;
+    char *tmp, *result;
+
+    br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
+
+    if (!*path) return strdup ("/");
+    end = strrchr (path, '/');
+    if (!end) return strdup (path);
+
+    tmp = br_strndup ((char *) path, end - path);
+    if (!*tmp)
+    {
+        free (tmp);
+        return strdup ("/");
+    }
+    end = strrchr (tmp, '/');
+    if (!end) return tmp;
+
+    result = br_strndup (tmp, end - tmp);
+    free (tmp);
+
+    if (!*result)
+    {
+        free (result);
+        result = strdup ("/");
+    }
+
+    return result;
 }
 
 
@@ -444,13 +437,14 @@ br_extract_prefix (const char *path)
  */
 static Glib::ustring win32_getExePath()
 {
-    char exeName[MAX_PATH+1];
-    GetModuleFileName(NULL, exeName, MAX_PATH);
-    char *slashPos = strrchr(exeName, '\\');
-    if (slashPos)
-        *slashPos = '\0';
-    Glib::ustring s = exeName;
-    return s;
+    gunichar2 path[2048];
+    GetModuleFileNameW(NULL, (WCHAR*) path, 2048);
+    gchar *exe = g_utf16_to_utf8(path, -1, NULL, NULL, NULL);
+    gchar *dir = g_path_get_dirname(exe);
+    Glib::ustring ret = dir;
+    g_free(dir);
+    g_free(exe);
+    return ret;
 }
 
 
@@ -461,8 +455,8 @@ static Glib::ustring win32_getExePath()
 static Glib::ustring win32_getDataDir()
 {
     Glib::ustring dir = win32_getExePath();
-    if (INKSCAPE_DATADIR  && *INKSCAPE_DATADIR &&
-           strcmp(INKSCAPE_DATADIR, ".") != 0)
+    if (INKSCAPE_DATADIR && *INKSCAPE_DATADIR &&
+        strcmp(INKSCAPE_DATADIR, ".") != 0)
         {
         dir += "\\";
         dir += INKSCAPE_DATADIR;
index 2017f50c756b6ccb4fdf7f4eeaf882420cfdd20d..af41c3eaf963807e35293d8bebfc49a03fd358db 100644 (file)
@@ -60,6 +60,7 @@ bool RegistryTool::setStringValue(const Glib::ustring &keyNameArg,
                                   const Glib::ustring &value)
 {
     Glib::ustring keyName = keyNameArg;
+    bool ret = false;
 
     HKEY rootKey = HKEY_LOCAL_MACHINE; //default root
     //Trim out the root key if necessary
@@ -74,28 +75,35 @@ bool RegistryTool::setStringValue(const Glib::ustring &keyNameArg,
     //printf("trimmed string: '%s'\n", keyName.c_str());
 
     //Get or create the key
+    gunichar2 *keyw       = g_utf8_to_utf16(keyName.data(), -1, 0,0,0);
+    gunichar2 *valuenamew = g_utf8_to_utf16(valueName.data(), -1, 0,0,0);
+
     HKEY key;
-    if (RegCreateKeyEx(rootKey, keyName.c_str(),
+    if (RegCreateKeyExW(rootKey, (WCHAR*) keyw,
                        0, NULL, REG_OPTION_NON_VOLATILE,
                        KEY_WRITE, NULL, &key, NULL))
-       {
+    {
        fprintf(stderr, "RegistryTool: Could not create the registry key '%s'\n", keyName.c_str());
-       return false;
-       }
+       goto fail;
+    }
 
-    //Set the value
-    if (RegSetValueEx(key, valueName.c_str(),
-          0,  REG_SZ, (LPBYTE) value.c_str(), (DWORD) value.size()))
-       {
+    // Set the value
+    if (RegSetValueExW(key, (WCHAR*) valuenamew,
+          0,  REG_SZ, (LPBYTE) value.data(), (DWORD) (value.size() + 1)))
+    {
        fprintf(stderr, "RegistryTool: Could not set the value '%s'\n", value.c_str());
-       RegCloseKey(key);
-       return false;
-       }
-
+       goto failkey;
+    }
 
+    ret = true;
+    
+    failkey:
     RegCloseKey(key);
-
-    return true;
+    
+    fail:
+    g_free(keyw);
+    g_free(valuenamew);
+    return ret;
 }
 
 
@@ -107,19 +115,14 @@ bool RegistryTool::getExeInfo(Glib::ustring &fullPath,
                               Glib::ustring &path,
                               Glib::ustring &exeName)
 {
+    const int pathbuf = 2048;
+    gunichar2 pathw[pathbuf];
+    GetModuleFileNameW(NULL, (WCHAR*) pathw, pathbuf);
 
-    char buf[MAX_PATH+1];
-    if (!GetModuleFileName(NULL, buf, MAX_PATH))
-        {
-        fprintf(stderr, "Could not fetch executable file name\n");
-        return false;
-        }
-    else
-        {
-        //printf("Executable file name: '%s'\n", buf);
-        }
+    gchar *utf8path = g_utf16_to_utf8(pathw, -1, 0,0,0);
+    fullPath = utf8path;
+    g_free(utf8path);
 
-    fullPath = buf;
     path     = "";
     exeName  = "";
     Glib::ustring::size_type pos = fullPath.rfind('\\');