- default stuff from GTK+ (not much I guess, and much probably in
US-ASCII - some people have actual ideas about it?)
I forgot to handle cases of Strings got from GTK+ to represent file
paths (from GtkFileChooser for example). There, the system encoding is
used and we must handle that specifically.
After reading GtkFileChooser documentation, it confirms my memories.
“filenames are always returned in the character set specified by the
G_FILENAME_ENCODING environment variable”. Also, “while you can pass
the result of gtk_file_chooser_get_filename() to open(2) or fopen(3),
you may not be able to directly set it as the text of a GtkLabel
widget unless you convert it first to UTF-8, which all GTK+ widgets
expect. You should use g_filename_to_utf8() to convert filenames into
strings that can be passed to GTK+ widgets.”
Also, I wasn’t sure what is the behaviour of File methods in Ruby 1.9.
My experimentation shows that the bytes from the encoding of the
String passed are used, e.g. without converting. For example in a
UTF-8 system, File.new(“mémé”) isn’t the same as
File.new(“mémé”.encode(“ISO-8859-1”)) (the last one gives ENOENT).
So, I think Strings representing files got from GTK+ in rg2 should:
1- have an associated encoding, so that they can be displayed in GTK+
without the programmer needing to do conversions (because my new
RVAL2CSTR will send UTF-8 char* to GtkLabel etc)
2- use the encoding expected by the operating system so that File.new
will work
First step is to use g_filename_to_utf8(), so that we are 100%
confident we can create a correct String (by using these bytes in Ruby
UTF-8 encoding).
Second step is to change the encoding of the String for realizing the
(2) item above. After looking at Glib documentation, it seems that
using the first item from g_get_filename_charsets() should be fine.
I have made a patch for doing this. I have tested in a UTF-8 system
with a file with an accent, with default settings and also by forcing
filename encoding to ISO-8859-1 (by launching the program with
LC_ALL=en_US in parameter), all works great! The patch is
“string-encoding-for-files.diff” and my little test program was:
-=-=—=-=—=-=—=-=–
#! /usr/bin/ruby
require ‘gtk2’
Gtk.init
fc = Gtk::FileChooserDialog.new(“Foo”,
nil,
Gtk::FileChooser::ACTION_OPEN,
nil,
[Gtk::Stock::OK,
Gtk::Dialog::RESPONSE_ACCEPT], [Gtk::Stock::CANCEL,
Gtk::Dialog::RESPONSE_CANCEL])
if fc.run == Gtk::Dialog::RESPONSE_ACCEPT
puts fc.filename
puts fc.filename.encoding
puts File.exists?(fc.filename)
end
-=-=—=-=—=-=—=-=–
Of course, the patch is not commitable right now: if the principle of
the patch is fine, it should probably be placed into glib2 and shared
accross other APIs of RG2 returning filenames, and an opposite process
be used for APIs receiving filenames.
What do you think of that analysis and patch?
 * But there are some cases that GTK+ doesn’t return
  UTF-8. e.g. g_convert()(*1), g_utf8_to_utf16()(*2) and
  so on. So, we need to provide an API for specify
  encoding like CSTR2RVAL_ENCODING().
  (*1) GLib – 2.0
  (*2) GLib – 2.0
I am not sure… Normally, in Ruby I would say the charset/encoding
conversions should be realized in Ruby. Also, specifying a charset to
convert “from” doesn’t make sense in Ruby 1.9 because Ruby Strings
have an encoding already. What is the use of these functions in Ruby
1.9 where Strings already carry an encoding and allow encoding
conversions? In my opinion, there should be no binding for these
functions anymore. Or maybe I missing something, what do you think we
should do for these?
Notice: RVAL2CSTR would be now an alias to RVAL2CSTR_ACCEPT_NIL, and I
think it is more safe because it’s always better to properly handle
NIL case.
We need to RVAL2CSTR with nil check because there are many
API that doesn’t accept NULL as gchar * argument. We will
need a function that do StringValuePtr() with encoding handling.
Sorry, I didn’t properly understand that. I see now.
Please see the patch “string-encoding-glib2.diff”, RVAL2CSTR has same
behaviour with nil passed as before.
Thanks,