[Ekiga-devel-list] Win32 UTF-8 vs. Codepage or what so ever



Ekiga's handling of Windows file names and device names is done mostly in UTF-8 which works as long as there are no national characters in the names. I have a German Windows and a USB headset which in Ekiga shows up as "USB-Ger" instead of "USB-Gerät" (USB device). Ok, I can click Ekiga's update devices and then there is a "USB-Gerät" which I can select thanks to the g_locale_to_utf8 support in ekiga/lib/gui/gmpreferences.c. However, the next time Ekiga is started it complains because it is unable to open the "USB-Ger".

I tried a similar approach as Eugen did when fixing bug #575907 (git c9aedde44825, 2009-04-21). But similar changes at the level of lib/components/ptlib device managers using g_locale_to_utf8 and back would not work for Windows. Presumably some library calls have been in between. For Win32 Ekiga the separation of (UTF-8) vs. (Codepage) with respect to Ptlib's device names is
(GUI + gconf) vs. (C-library + device strings).
A good place to convert the device strings to UTF-8 is gm_prefs_window_convert_string_list in ekiga/src/gui/preferences.cpp. Conversion from UTF-8 can only be done where we know that it is a device string, i. e. in the device gmconf-bridges. I have prepared three patches and tested them under Windows and for adverse effects also Linux.

ekiga01_filename.diff is not so important but easy. It allows special characters in the sound files. It shows the principle of converting from UTF-8, i.e having a specialized routine in lib/gmconf/gmconf-glib.c which is called for WIN32 from audiooutput-gmconf-bridge.cpp.

ekiga02_devstring.diff involves quite a few files. It does the device string conversions summarized above.

ekiga03_isutf8.diff cleans up ekiga/lib/gui/gmpreferences.c. Linux is completely UTF-8 and for Win32 we have done the conversion to UTF-8 with the second patch earlier. Moreover double conversion to UTF-8 does not work when there are any special characters.

In some parts the patches seem a bit bulky. Do you have any idea how to solve the device string issue for Win32 in a more elegant way?
Regards
Michael
diff -ur ekiga.orig/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp ekiga/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp
--- ekiga.orig/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp	2009-07-16 14:24:01.000000000 +0200
+++ ekiga/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp	2009-07-16 13:49:41.000000000 +0200
@@ -131,7 +131,7 @@
        (key == SOUND_EVENTS_KEY "enable_busy_tone_sound") ) {
 
     gchar *c_file_name = NULL;
-    c_file_name = gm_conf_get_string (SOUND_EVENTS_KEY "busy_tone_sound");
+    c_file_name = GM_CONF_GET_FILE_NAME (SOUND_EVENTS_KEY "busy_tone_sound");
     if (c_file_name == NULL) {
       PTRACE(1, "AudioOutputCoreConfBridge\t" << SOUND_EVENTS_KEY "busy_tone_sound" << " is NULL");
       return;
@@ -148,7 +148,7 @@
        (key == SOUND_EVENTS_KEY "enable_incoming_call_sound") ) {
 
     gchar *c_file_name = NULL;
-    c_file_name = gm_conf_get_string (SOUND_EVENTS_KEY "incoming_call_sound");
+    c_file_name = GM_CONF_GET_FILE_NAME (SOUND_EVENTS_KEY "incoming_call_sound");
     if (c_file_name == NULL) {
       PTRACE(1, "AudioOutputCoreConfBridge\t" <<  SOUND_EVENTS_KEY "incoming_call_sound" << " is NULL");
       return;
@@ -165,7 +165,7 @@
        (key == SOUND_EVENTS_KEY "enable_new_message_sound") ) {
 
     gchar *c_file_name = NULL;
-    c_file_name = gm_conf_get_string (SOUND_EVENTS_KEY "new_message_sound");
+    c_file_name = GM_CONF_GET_FILE_NAME (SOUND_EVENTS_KEY "new_message_sound");
     if (c_file_name == NULL) {
       PTRACE(1, "AudioOutputCoreConfBridge\t" <<  SOUND_EVENTS_KEY "new_message_sound" << " is NULL");
       return;
@@ -183,7 +183,7 @@
        (key == SOUND_EVENTS_KEY "enable_new_voicemail_sound") ) {
 
     gchar *c_file_name = NULL;
-    c_file_name = gm_conf_get_string (SOUND_EVENTS_KEY "new_voicemail_sound");
+    c_file_name = GM_CONF_GET_FILE_NAME (SOUND_EVENTS_KEY "new_voicemail_sound");
     if (c_file_name == NULL) {
       PTRACE(1, "AudioOutputCoreConfBridge\t" <<  SOUND_EVENTS_KEY "new_voicemail_sound" << " is NULL");
       return;
@@ -200,7 +200,7 @@
        (key == SOUND_EVENTS_KEY "enable_ring_tone_sound") ) {
 
     gchar *c_file_name = NULL;
-    c_file_name = gm_conf_get_string (SOUND_EVENTS_KEY "ring_tone_sound");
+    c_file_name = GM_CONF_GET_FILE_NAME (SOUND_EVENTS_KEY "ring_tone_sound");
     if (c_file_name == NULL) {
       PTRACE(1, "AudioOutputCoreConfBridge\t" <<  SOUND_EVENTS_KEY "ring_tone_sound" << " is NULL");
       return;
diff -ur ekiga.orig/lib/gmconf/gmconf-glib.c ekiga/lib/gmconf/gmconf-glib.c
--- ekiga.orig/lib/gmconf/gmconf-glib.c	2009-07-16 14:24:01.000000000 +0200
+++ ekiga/lib/gmconf/gmconf-glib.c	2009-07-16 14:26:12.000000000 +0200
@@ -1564,6 +1564,24 @@
   return string_list_deep_copy (entry_get_list (entry));
 }
 
+#ifdef WIN32
+gchar *
+gm_conf_get_file_name(const gchar *key)
+{
+  gchar *utf8_str;
+  gchar *result;
+
+  utf8_str = gm_conf_get_string(key);
+  if (utf8_str != NULL)
+    result = g_win32_locale_filename_from_utf8 (utf8_str);
+  else
+    result = utf8_str;
+
+  g_free (utf8_str);
+  return result;
+}
+#endif
+
 void
 gm_conf_destroy (const gchar *namespac)
 {
diff -ur ekiga.orig/lib/gmconf/gmconf.h ekiga/lib/gmconf/gmconf.h
--- ekiga.orig/lib/gmconf/gmconf.h	2009-07-16 14:24:01.000000000 +0200
+++ ekiga/lib/gmconf/gmconf.h	2009-07-16 14:25:25.000000000 +0200
@@ -42,6 +42,12 @@
 
 #include <glib.h>
 
+#ifdef WIN32
+#define GM_CONF_GET_FILE_NAME(af) gm_conf_get_file_name(af)
+#else
+#define GM_CONF_GET_FILE_NAME(af) gm_conf_get_string(af)
+#endif
+
 G_BEGIN_DECLS
 
 
@@ -122,6 +128,10 @@
 void gm_conf_set_string_list (const gchar *, GSList *);
 /* Should be freed! */
 GSList *gm_conf_get_string_list (const gchar *);
+#ifdef WIN32
+/* Should be freed! */
+gchar *gm_conf_get_file_name(const gchar *key);
+#endif
 
 /* to destroy a part of the config */
 void gm_conf_destroy (const gchar *namespac);
diff -ur ekiga.orig/lib/engine/audioinput/audioinput-gmconf-bridge.cpp ekiga/lib/engine/audioinput/audioinput-gmconf-bridge.cpp
--- ekiga.orig/lib/engine/audioinput/audioinput-gmconf-bridge.cpp	2009-07-16 13:39:58.000000000 +0200
+++ ekiga/lib/engine/audioinput/audioinput-gmconf-bridge.cpp	2009-07-16 13:54:55.000000000 +0200
@@ -63,12 +63,22 @@
     PTRACE(4, "AudioInputCoreConfBridge\tUpdating device");
 
     AudioInputDevice device;
-    if (gm_conf_entry_get_string (entry) == NULL) {
+#ifdef WIN32
+    gchar *audio_device = NULL;
+    audio_device = gm_conf_entry_get_locale_string (entry);
+#else
+    const gchar *audio_device = NULL;
+    audio_device = gm_conf_entry_get_string (entry);
+#endif
+    if (audio_device == NULL) {
       PTRACE(1, "AudioInputCoreConfBridge\t" << AUDIO_DEVICES_KEY "input_device" << " is NULL");
     }
     else {
-      device.SetFromString(gm_conf_entry_get_string (entry));
+      device.SetFromString(audio_device);
     }
+#ifdef WIN32
+    g_free(audio_device);
+#endif
 
     if ( (device.type == "" )   ||
          (device.source == "")  ||
diff -ur ekiga.orig/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp ekiga/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp
--- ekiga.orig/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp	2009-07-16 13:49:41.000000000 +0200
+++ ekiga/lib/engine/audiooutput/audiooutput-gmconf-bridge.cpp	2009-07-16 13:54:55.000000000 +0200
@@ -80,8 +80,13 @@
     PTRACE(4, "AudioOutputCoreConfBridge\tUpdating device");
 
     AudioOutputDevice device;
+#ifdef WIN32
+    gchar *audio_device = NULL;
+    audio_device = gm_conf_entry_get_locale_string (entry);
+#else
     const gchar *audio_device = NULL;
     audio_device = gm_conf_entry_get_string (entry);
+#endif
 
     if (audio_device == NULL) {
       PTRACE(1, "AudioOutputCoreConfBridge\t" << AUDIO_DEVICES_KEY "output_device" << " is NULL");
@@ -89,6 +94,9 @@
     else {
       device.SetFromString(audio_device);
     }
+#ifdef WIN32
+    g_free(audio_device);
+#endif
   
     if ( (device.type   == "" )   ||
          (device.source == "")  ||
@@ -106,8 +114,13 @@
 
     PTRACE(4, "AudioOutputCoreConfBridge\tUpdating device");
     AudioOutputDevice device;
+#ifdef WIN32
+    gchar *audio_device = NULL;
+    audio_device = gm_conf_entry_get_locale_string (entry);
+#else
     const gchar *audio_device = NULL;
     audio_device = gm_conf_entry_get_string (entry);
+#endif
 
     if (audio_device == NULL) {
       PTRACE(1, "AudioOutputCoreConfBridge\t" << AUDIO_DEVICES_KEY "output_device" << " is NULL");
@@ -115,6 +128,9 @@
     else {
       device.SetFromString(audio_device);
     }
+#ifdef WIN32
+    g_free(audio_device);
+#endif
 
     if ( (device.type   == "" )   ||
          (device.source == "")  ||
diff -ur ekiga.orig/lib/engine/videoinput/videoinput-gmconf-bridge.cpp ekiga/lib/engine/videoinput/videoinput-gmconf-bridge.cpp
--- ekiga.orig/lib/engine/videoinput/videoinput-gmconf-bridge.cpp	2009-07-16 13:39:58.000000000 +0200
+++ ekiga/lib/engine/videoinput/videoinput-gmconf-bridge.cpp	2009-07-16 14:01:33.000000000 +0200
@@ -92,7 +92,7 @@
 
     VideoInputDevice device;
     gchar *input_device = NULL;
-    input_device = gm_conf_get_string (VIDEO_DEVICES_KEY "input_device");
+    input_device = GM_CONF_GET_DEVICE_STRING (VIDEO_DEVICES_KEY "input_device");
     if (input_device == NULL) {
       PTRACE(1, "VidInputCoreConfBridge\t" << VIDEO_DEVICES_KEY "input_device" << " is NULL");
     }
diff -ur ekiga.orig/lib/gmconf/gmconf-glib.c ekiga/lib/gmconf/gmconf-glib.c
--- ekiga.orig/lib/gmconf/gmconf-glib.c	2009-07-16 14:26:12.000000000 +0200
+++ ekiga/lib/gmconf/gmconf-glib.c	2009-07-16 14:09:50.000000000 +0200
@@ -1566,6 +1566,32 @@
 
 #ifdef WIN32
 gchar *
+gm_conf_entry_get_locale_string (GmConfEntry *entry)
+{
+  g_return_val_if_fail (entry != NULL, NULL);
+
+  return g_locale_from_utf8 (entry_get_string (entry),
+                             -1, NULL, NULL, NULL);
+}
+
+gchar *
+gm_conf_get_locale_string(const gchar *key)
+{
+  gchar *utf8_str;
+  gchar *result;
+
+  utf8_str = gm_conf_get_string(key);
+  if (utf8_str != NULL)
+    result = g_locale_from_utf8 (utf8_str, -1,
+                                 NULL, NULL, NULL);
+  else
+    result = utf8_str;
+
+  g_free (utf8_str);
+  return result;
+}
+
+gchar *
 gm_conf_get_file_name(const gchar *key)
 {
   gchar *utf8_str;
diff -ur ekiga.orig/lib/gmconf/gmconf.h ekiga/lib/gmconf/gmconf.h
--- ekiga.orig/lib/gmconf/gmconf.h	2009-07-16 14:25:25.000000000 +0200
+++ ekiga/lib/gmconf/gmconf.h	2009-07-16 14:07:01.000000000 +0200
@@ -43,8 +43,10 @@
 #include <glib.h>
 
 #ifdef WIN32
+#define GM_CONF_GET_DEVICE_STRING(as) gm_conf_get_locale_string(as)
 #define GM_CONF_GET_FILE_NAME(af) gm_conf_get_file_name(af)
 #else
+#define GM_CONF_GET_DEVICE_STRING(as) gm_conf_get_string(as)
 #define GM_CONF_GET_FILE_NAME(af) gm_conf_get_string(af)
 #endif
 
@@ -130,6 +132,10 @@
 GSList *gm_conf_get_string_list (const gchar *);
 #ifdef WIN32
 /* Should be freed! */
+gchar *gm_conf_entry_get_locale_string (GmConfEntry *);
+/* Should be freed! */
+gchar *gm_conf_get_locale_string(const gchar *key);
+/* Should be freed! */
 gchar *gm_conf_get_file_name(const gchar *key);
 #endif
 
diff -ur ekiga.orig/src/gui/preferences.cpp ekiga/src/gui/preferences.cpp
--- ekiga.orig/src/gui/preferences.cpp	2009-07-16 13:39:56.000000000 +0200
+++ ekiga/src/gui/preferences.cpp	2009-07-16 13:54:55.000000000 +0200
@@ -299,6 +299,9 @@
 gchar**
 gm_prefs_window_convert_string_list (const std::vector<std::string> & list);
 
+void
+gm_prefs_window_free_string_array (gchar **array);
+
 void 
 gm_prefs_window_update_devices_list (GtkWidget *prefs_window);
 
@@ -769,14 +772,14 @@
     gnome_prefs_string_option_menu_new (subsection, _("Ringing Device"), (const gchar **)array, SOUND_EVENTS_KEY "output_device", _("Select the ringing audio device to use"), 0, "Default (PTLIB/ALSA)");
   pw->audio_player =
     gnome_prefs_string_option_menu_new (subsection, _("Output device:"), (const gchar **)array, AUDIO_DEVICES_KEY "output_device", _("Select the audio output device to use"), 1, "Default (PTLIB/ALSA)");
-  g_free (array);
+  gm_prefs_window_free_string_array (array);
 
   /* The recorder */
   gm_prefs_window_get_audioinput_devices_list (pw->core, device_list);
   array = gm_prefs_window_convert_string_list(device_list);
   pw->audio_recorder =
     gnome_prefs_string_option_menu_new (subsection, _("Input device:"), (const gchar **)array, AUDIO_DEVICES_KEY "input_device", _("Select the audio input device to use"), 2, "Default (PTLIB/ALSA)");
-  g_free (array);
+  gm_prefs_window_free_string_array (array);
 
 
   /* That button will refresh the device list */
@@ -861,13 +864,32 @@
   unsigned i;
 
   array = (gchar**) g_malloc (sizeof(gchar*) * (list.size() + 1));
-  for (i = 0; i < list.size(); i++)
+  for (i = 0; i < list.size(); i++) {
+#ifdef WIN32
+    array[i] = g_locale_to_utf8 (list[i].c_str(), -1,
+                                 NULL, NULL, NULL);
+    if (array[i] == NULL)
+      return array;
+#else
     array[i] = (gchar*) list[i].c_str();
+#endif
+  }
   array[i] = NULL;
 
   return array;
 }
 
+void
+gm_prefs_window_free_string_array (gchar **array)
+{
+#ifdef WIN32
+  unsigned i;
+
+  for (i = 0; array[i] != NULL; i++)
+    g_free(array[i]);
+#endif
+  g_free(array);
+}
 
 static void
 gm_pw_init_video_devices_page (GtkWidget *prefs_window,
@@ -924,7 +946,7 @@
   array = gm_prefs_window_convert_string_list(device_list);
   pw->video_device =
     gnome_prefs_string_option_menu_new (subsection, _("Input device:"), (const gchar **)array, VIDEO_DEVICES_KEY "input_device", _("Select the video input device to use. If an error occurs when using this device a test picture will be transmitted."), 0, NULL);
-  g_free (array);
+  gm_prefs_window_free_string_array (array);
 
   /* Video Channel */
   gnome_prefs_spin_new (subsection, _("Channel:"), VIDEO_DEVICES_KEY "channel", _("The video channel number to use (to select camera, tv or other sources)"), 0.0, 10.0, 1.0, 3, NULL, false);
@@ -1289,7 +1311,7 @@
                                          (const gchar **)array,
                                          SOUND_EVENTS_KEY "output_device",
                                          "Default (PTLIB/ALSA)");
-  g_free (array);
+  gm_prefs_window_free_string_array (array);
 
   /* The recorder */
   gm_prefs_window_get_audioinput_devices_list (pw->core, device_list);
@@ -1298,7 +1320,7 @@
  					 (const gchar **)array,
  					 AUDIO_DEVICES_KEY "input_device",
                                          "Default (PTLIB/ALSA)");
-  g_free (array);
+  gm_prefs_window_free_string_array (array);
 
 
   /* The Video player */
@@ -1308,7 +1330,7 @@
 					 (const gchar **)array,
 					 VIDEO_DEVICES_KEY "input_device",
                                          NULL);
-  g_free (array);
+  gm_prefs_window_free_string_array (array);
 }
 
 
diff -ur ekiga.orig/lib/gui/gmpreferences.c ekiga/lib/gui/gmpreferences.c
--- ekiga.orig/lib/gui/gmpreferences.c	2009-05-17 09:09:35.460980991 +0200
+++ ekiga/lib/gui/gmpreferences.c	2009-05-17 09:07:57.696084676 +0200
@@ -729,7 +729,6 @@
   GtkTreeIter iter;
 
   gchar *conf_string = NULL;
-  gchar *options_string = NULL;
   
   int history = -1;
   int cpt = 0;
@@ -748,17 +747,15 @@
   cpt = 0;
   while (options [cpt]) {
 
-    options_string = g_locale_to_utf8 (options [cpt], -1, NULL, NULL, NULL);
     if (conf_string && !strcmp (options [cpt], conf_string)) 
       history = cpt;
 
     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
     gtk_list_store_set (GTK_LIST_STORE (model), &iter, 
                         COLUMN_STRING_RAW, options [cpt],
-                        COLUMN_STRING_TRANSLATED, options_string,
+                        COLUMN_STRING_TRANSLATED, options [cpt],
                         COLUMN_SENSITIVE, TRUE, 
                         -1);
-    g_free (options_string);
     cpt++;
   }
 
@@ -791,14 +788,12 @@
 {
   GtkTreeModel *model = NULL;
   GtkTreeIter iter;
-  gchar *option_string = NULL;
   gboolean found = FALSE;
 
   if (!option)
     return;
 
   model = gtk_combo_box_get_model (GTK_COMBO_BOX (option_menu));
-  option_string = g_locale_to_utf8 (option, -1, NULL, NULL, NULL);
 
   if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter)) {
 
@@ -824,13 +819,12 @@
     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
     gtk_list_store_set (GTK_LIST_STORE (model), &iter, 
                         COLUMN_STRING_RAW, option,
-                        COLUMN_STRING_TRANSLATED, option_string, 
+                        COLUMN_STRING_TRANSLATED, option, 
                         COLUMN_SENSITIVE, TRUE,
                         -1);
   }
   if (active == TRUE)
     gtk_combo_box_set_active_iter (GTK_COMBO_BOX (option_menu), &iter);
-  g_free (option_string);
 }
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]