diff -rc glib2.0-2.18.2-orig/glib/goption.c glib2.0-2.18.2/glib/goption.c
*** glib2.0-2.18.2-orig/glib/goption.c	2008-10-16 16:31:58.000000000 +0200
--- glib2.0-2.18.2/glib/goption.c	2008-12-16 01:34:08.000000000 +0100
***************
*** 33,38 ****
--- 33,44 ----
  #include <stdio.h>
  #include <errno.h>
  
+ #ifdef G_OS_WIN32
+ #define STRICT
+ #include <windows.h>
+ #undef STRICT
+ #endif
+ 
  #define TRANSLATE(group, str) (((group)->translate_func ? (* (group)->translate_func) ((str), (group)->translate_data) : (str)))
  
  #define NO_ARG(entry) ((entry)->arg == G_OPTION_ARG_NONE ||       \
***************
*** 616,628 ****
  
    if (rest_description)
      {
!       g_string_append (string, " ");
        g_string_append (string, rest_description);
      }
  
    if (context->parameter_string)
      {
!       g_string_append (string, " ");
        g_string_append (string, TRANSLATE (context, context->parameter_string));
      }
  
--- 622,634 ----
  
    if (rest_description)
      {
!       g_string_append_c (string, ' ');
        g_string_append (string, rest_description);
      }
  
    if (context->parameter_string)
      {
!       g_string_append_c (string, ' ');
        g_string_append (string, TRANSLATE (context, context->parameter_string));
      }
  
***************
*** 737,743 ****
  	  list = list->next;
  	}
  
!       g_string_append (string, "\n");
      }
  
    if (group)
--- 743,749 ----
  	  list = list->next;
  	}
  
!       g_string_append_c (string, '\n');
      }
  
    if (group)
***************
*** 747,756 ****
        if (group_has_visible_entries (context, group, FALSE))
          {
            g_string_append (string, TRANSLATE (group, group->description));
!           g_string_append (string, "\n");
            for (i = 0; i < group->n_entries; i++)
              print_entry (group, max_length, &group->entries[i], string);
!           g_string_append (string, "\n");
          }
      }
    else if (!main_help)
--- 753,762 ----
        if (group_has_visible_entries (context, group, FALSE))
          {
            g_string_append (string, TRANSLATE (group, group->description));
!           g_string_append_c (string, '\n');
            for (i = 0; i < group->n_entries; i++)
              print_entry (group, max_length, &group->entries[i], string);
!           g_string_append_c (string, '\n');
          }
      }
    else if (!main_help)
***************
*** 766,777 ****
  	  if (group_has_visible_entries (context, group, FALSE))
  	    {
  	      g_string_append (string, group->description);
! 	      g_string_append (string, "\n");
  	      for (i = 0; i < group->n_entries; i++)
  		if (!(group->entries[i].flags & G_OPTION_FLAG_IN_MAIN))
  		  print_entry (group, max_length, &group->entries[i], string);
  	  
! 	      g_string_append (string, "\n");
  	    }
  
  	  list = list->next;
--- 772,783 ----
  	  if (group_has_visible_entries (context, group, FALSE))
  	    {
  	      g_string_append (string, group->description);
! 	      g_string_append_c (string, '\n');
  	      for (i = 0; i < group->n_entries; i++)
  		if (!(group->entries[i].flags & G_OPTION_FLAG_IN_MAIN))
  		  print_entry (group, max_length, &group->entries[i], string);
  	  
! 	      g_string_append_c (string, '\n');
  	    }
  
  	  list = list->next;
***************
*** 786,792 ****
        list = context->groups;
  
        g_string_append (string,  _("Application Options:"));
!       g_string_append (string, "\n");
        if (context->main_group)
  	for (i = 0; i < context->main_group->n_entries; i++) 
  	  print_entry (context->main_group, max_length, 
--- 792,798 ----
        list = context->groups;
  
        g_string_append (string,  _("Application Options:"));
!       g_string_append_c (string, '\n');
        if (context->main_group)
  	for (i = 0; i < context->main_group->n_entries; i++) 
  	  print_entry (context->main_group, max_length, 
***************
*** 804,816 ****
  	  list = list->next;
  	}
  
!       g_string_append (string, "\n");
      }
   
    if (context->description)
      {
        g_string_append (string, TRANSLATE (context, context->description));
!       g_string_append (string, "\n");
      }
  
    return g_string_free (string, FALSE);
--- 810,822 ----
  	  list = list->next;
  	}
  
!       g_string_append_c (string, '\n');
      }
   
    if (context->description)
      {
        g_string_append (string, TRANSLATE (context, context->description));
!       g_string_append_c (string, '\n');
      }
  
    return g_string_free (string, FALSE);
***************
*** 1002,1012 ****
      case G_OPTION_ARG_STRING:
        {
  	gchar *data;
! 	
  	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
  
  	if (!data)
  	  return FALSE;
  
  	change = get_change (context, G_OPTION_ARG_STRING,
  			     entry->arg_data);
--- 1008,1024 ----
      case G_OPTION_ARG_STRING:
        {
  	gchar *data;
! #ifdef G_OS_WIN32
! 	data = g_strdup (value);
! #else
  	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
  
  	if (!data)
  	  return FALSE;
+ #endif
+ 
+ 	if (!data)
+ 	  return FALSE;
  
  	change = get_change (context, G_OPTION_ARG_STRING,
  			     entry->arg_data);
***************
*** 1021,1031 ****
      case G_OPTION_ARG_STRING_ARRAY:
        {
  	gchar *data;
! 
  	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
  
  	if (!data)
  	  return FALSE;
  
  	change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
  			     entry->arg_data);
--- 1033,1049 ----
      case G_OPTION_ARG_STRING_ARRAY:
        {
  	gchar *data;
! #ifdef G_OS_WIN32
! 	data = g_strdup (value);
! #else
  	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
  
  	if (!data)
  	  return FALSE;
+ #endif
+ 
+ 	if (!data)
+ 	  return FALSE;
  
  	change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
  			     entry->arg_data);
***************
*** 1054,1067 ****
        {
  	gchar *data;
  
- #ifdef G_OS_WIN32
- 	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
- 	
- 	if (!data)
- 	  return FALSE;
- #else
  	data = g_strdup (value);
! #endif
  	change = get_change (context, G_OPTION_ARG_FILENAME,
  			     entry->arg_data);
  	g_free (change->allocated.str);
--- 1072,1079 ----
        {
  	gchar *data;
  
  	data = g_strdup (value);
! 
  	change = get_change (context, G_OPTION_ARG_FILENAME,
  			     entry->arg_data);
  	g_free (change->allocated.str);
***************
*** 1077,1090 ****
        {
  	gchar *data;
  	
- #ifdef G_OS_WIN32
- 	data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
- 	
- 	if (!data)
- 	  return FALSE;
- #else
  	data = g_strdup (value);
! #endif
  	change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
  			     entry->arg_data);
  
--- 1089,1096 ----
        {
  	gchar *data;
  	
  	data = g_strdup (value);
! 
  	change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
  			     entry->arg_data);
  
***************
*** 1134,1147 ****
  	  data = NULL;
  	else if (entry->flags & G_OPTION_FLAG_FILENAME)
  	  {
  #ifdef G_OS_WIN32
-   	    data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
- #else
  	    data = g_strdup (value);
  #endif
  	  }
- 	else
- 	  data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
  
  	if (!(entry->flags & (G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_OPTIONAL_ARG)) && 
  	    !data)
--- 1140,1158 ----
  	  data = NULL;
  	else if (entry->flags & G_OPTION_FLAG_FILENAME)
  	  {
+ 	    data = g_strdup (value);
+ 	  }
+ 	else
+ 	  {
  #ifdef G_OS_WIN32
  	    data = g_strdup (value);
+ #else
+ 	    data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+ 
+ 	    if (!data)
+ 	      return FALSE;
  #endif
  	  }
  
  	if (!(entry->flags & (G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_OPTIONAL_ARG)) && 
  	    !data)
***************
*** 1502,1507 ****
--- 1513,1581 ----
    context->pending_nulls = NULL;
  }
  
+ #ifdef G_OS_WIN32
+ /* Returns a newly allocated argument vector converted to UTF-8. Tries to use
+  * the process's Unicode command line if possible. */
+ static gchar **
+ prepare_utf8_argv (const gint    *argc,
+ 		   const gchar ***argv)
+ {
+   gint unicode_argc, i, j, original_argc = __argc;
+   gchar **replacement_argv = NULL, **original_argv = __argv;
+   gchar **unicode_argv = (gchar **) CommandLineToArgvW (GetCommandLineW (), &unicode_argc);
+ 
+   if (G_UNLIKELY (!unicode_argv))
+     return NULL;
+ 
+   if (argc && argv)
+     {
+       gboolean argv_comes_from_main = ( *argv == original_argv &&
+ 					*argc == original_argc &&
+ 					*argc == unicode_argc );
+ 
+       /* build a replacement UTF-8 argument vector */
+       replacement_argv = g_malloc0 (*argc * sizeof (gchar*));
+ 
+       for (i = 0; i < *argc; ++i)
+ 	{
+ 	  /* If argv comes from the parameters of main(), convert the Unicode
+ 	   * command line, ignoring contents of argv */
+ 	  if (argv_comes_from_main)
+ 	    replacement_argv[i] = g_convert (unicode_argv[i], wcslen (unicode_argv[i]) * 2,
+ 					     "UTF-8", "UTF-16", NULL, NULL, NULL);
+ 	  else
+ 	    {
+ 	      /* If argv doesn't come from main(), check whether any
+ 	       * of the argument pointers are identical; if they are, convert
+ 	       * the corresponding Unicode argument */
+ 	      for (j = 0; j < unicode_argc; ++j)
+ 		{
+ 		  if ((*argv)[i] == original_argv[j])
+ 		    {
+ 		      replacement_argv[i] = g_convert (unicode_argv[j], wcslen (unicode_argv[j]) * 2,
+ 						       "UTF-8", "UTF-16", NULL, NULL, NULL);
+ 		      break;
+ 		    }
+ 		}
+ 	      if (!replacement_argv[i])
+ 		replacement_argv[i] =  g_locale_to_utf8 ((*argv)[i], -1, NULL, NULL, NULL);
+ 	    }
+ 
+ 	  if (G_UNLIKELY (!replacement_argv[i]))
+ 	    {
+ 	      /* clean up after conversion attempt */
+ 	      for (j = 0; j < i; ++j)
+ 		g_free (replacement_argv[j]);
+ 
+ 	      g_free (replacement_argv);
+ 	      return NULL;
+ 	    }
+ 	}
+     }
+   return replacement_argv;
+ }
+ #endif
+ 
  /**
   * g_option_context_parse:
   * @context: a #GOptionContext
***************
*** 1527,1537 ****
   * this function will produce help output to stdout and
   * call <literal>exit (0)</literal>.
   *
!  * Note that function depends on the 
   * <link linkend="setlocale">current locale</link> for 
   * automatic character set conversion of string and filename
!  * arguments.
!  * 
   * Return value: %TRUE if the parsing was successful, 
   *               %FALSE if an error occurred
   *
--- 1601,1625 ----
   * this function will produce help output to stdout and
   * call <literal>exit (0)</literal>.
   *
!  * On Windows, some filenames may not be representable in the
!  * system codepage. This will cause the arguments of main()
!  * to contain broken filenames. To fix them, the original
!  * Unicode command line retrieved using <literal>GetCommandLineW</literal>
!  * is looked up. If @argc and @argv point to arguments of main(),
!  * and the Unicode command line has the same argument count,
!  * the Unicode command line is used. Otherwise, @argv and @argc
!  * are used, but when a <type>char</type> pointer in @argv is
!  * the same as in the argument of main(), the corresponding
!  * Unicode argument is used instead. Effectively, this means that
!  * this function will not behave correctly on Windows if you modify
!  * the arguments of main(). Use copies of them if you want to
!  * manipulate them in some way before parsing with this function.
!  *
!  * Note that the function depends on the 
   * <link linkend="setlocale">current locale</link> for 
   * automatic character set conversion of string and filename
!  * arguments - it assumes that @argv is in locale encoding.
!  *
   * Return value: %TRUE if the parsing was successful, 
   *               %FALSE if an error occurred
   *
***************
*** 1546,1551 ****
--- 1634,1655 ----
    gint i, j, k;
    GList *list;
  
+ #ifdef G_OS_WIN32
+   gchar ***passed_argv = argv;
+ 
+   if (argc && argv)
+     {
+       gchar **replacement_argv = prepare_utf8_argv (argc, argv);
+       if (!replacement_argv)
+ 	{
+ 	  g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+ 		       "Failed to convert the command line to UTF-8");
+ 	  goto fail;
+ 	}
+       argv = &replacement_argv;
+     }
+ #endif
+ 
    /* Set program name */
    if (!g_get_prgname())
      {
***************
*** 1831,1836 ****
--- 1935,1946 ----
  	}      
      }
  
+ #ifdef G_OS_WIN32
+   /* return unparsed arguments */
+   if (argc && passed_argv)
+     *passed_argv = *argv;
+ #endif
+ 
    return TRUE;
  
   fail:
