From b178ee6cb6d8510a148da797389e661eefdfc819 Mon Sep 17 00:00:00 2001 From: Kalle Olavi Niemitalo Date: Mon, 11 Apr 2011 21:38:52 +0300 Subject: [PATCH] Recode X11 window title when saving and restoring MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gnome-terminal 2.30.2 expects UTF-8 in the "OSC Ps ; Pt BEL" sequence that sets the window title. However, XGetWMName typically returns the title in "STRING" (Latin-1) or "COMPOUND_TEXT" (escape sequences) encoding. Recode the title to restore it correctly. This helps especially in the fi_FI.UTF-8 locale, where gnome-terminal has "Pääte" as the default title. Related to bugs 885 and 336. (cherry picked from commit d1245c73a8788a1a27e752f5bd36eded85b92a8c) --- src/osdep/os2/os2.c | 2 +- src/osdep/osdep.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- src/osdep/osdep.h | 2 +- src/terminal/kbd.c | 3 ++- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/osdep/os2/os2.c b/src/osdep/os2/os2.c index 16875c14..6477bb46 100644 --- a/src/osdep/os2/os2.c +++ b/src/osdep/os2/os2.c @@ -255,7 +255,7 @@ set_clipboard_text(unsigned char *data) } unsigned char * -get_window_title(void) +get_window_title(int codepage) { #ifndef DEBUG_OS2 unsigned char *org_switch_title; diff --git a/src/osdep/osdep.c b/src/osdep/osdep.c index e45716d9..078434b0 100644 --- a/src/osdep/osdep.c +++ b/src/osdep/osdep.c @@ -492,8 +492,48 @@ catch_x_error(void) } #endif +/** Convert a STRING XTextProperty to a string in the specified codepage. + * + * @return the string that the caller must free with mem_free(), + * or NULL on error. */ +static unsigned char * +xprop_to_string(Display *display, const XTextProperty *text_prop, int to_cp) +{ + int from_cp; + char **list = NULL; + int count = 0; + struct conv_table *convert_table; + unsigned char *ret = NULL; + + /* defines X_HAVE_UTF8_STRING if + * Xutf8TextPropertyToTextList is available. */ +#if defined(CONFIG_UTF8) && defined(X_HAVE_UTF8_STRING) + + from_cp = get_cp_index("UTF-8"); + if (Xutf8TextPropertyToTextList(display, text_prop, &list, + &count) != Success) + return NULL; + +#else /* !defined(X_HAVE_UTF8_STRING) || !defined(CONFIG_UTF8) */ + + from_cp = get_cp_index("System"); + if (XmbTextPropertyToTextList(display, text_prop, &list, + &count) != Success) + return NULL; + +#endif /* !defined(X_HAVE_UTF8_STRING) || !defined(CONFIG_UTF8) */ + + convert_table = get_translation_table(from_cp, to_cp); + if (count >= 1 && convert_table) + ret = convert_string(convert_table, list[0], strlen(list[0]), + to_cp, CSM_NONE, NULL, NULL, NULL); + + XFreeStringList(list); + return ret; +} + unsigned char * -get_window_title(void) +get_window_title(int codepage) { #ifdef HAVE_X11 /* Following code is stolen from our beloved vim. */ @@ -537,7 +577,7 @@ get_window_title(void) } if (!x_error && status && text_prop.value) { - ret = stracpy(text_prop.value); + ret = xprop_to_string(display, &text_prop, codepage); XFree(text_prop.value); } diff --git a/src/osdep/osdep.h b/src/osdep/osdep.h index 15cefc3b..c31d5ace 100644 --- a/src/osdep/osdep.h +++ b/src/osdep/osdep.h @@ -39,7 +39,7 @@ int start_thread(void (*)(void *, int), void *, int); unsigned char *get_clipboard_text(void); void set_clipboard_text(unsigned char *); void set_window_title(unsigned char *, int codepage); -unsigned char *get_window_title(void); +unsigned char *get_window_title(int codepage); void block_stdin(void); void unblock_stdin(void); int exe(unsigned char *); diff --git a/src/terminal/kbd.c b/src/terminal/kbd.c index 32a4ec8e..79b662c2 100644 --- a/src/terminal/kbd.c +++ b/src/terminal/kbd.c @@ -504,7 +504,8 @@ dispatch_special(unsigned char *text) * ditrm->orig_title should be NULL, * but check it to prevent any leak. */ if (!ditrm->orig_title && !ditrm->touched_title) - ditrm->orig_title = get_window_title(); + ditrm->orig_title = get_window_title( + ditrm->title_codepage); ditrm->touched_title = 1; } /* TODO: Is it really possible to get here with