[Ekiga-devel-list] Win32 UTF-8 vs. Codepage or what so ever
- From: Michael Rickmann <mrickma gwdg de>
- To: Ekiga development mailing list <ekiga-devel-list gnome org>
- Subject: [Ekiga-devel-list] Win32 UTF-8 vs. Codepage or what so ever
- Date: Fri, 17 Jul 2009 19:48:29 +0200
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]