From 22b177ea06ff72f94398570bc3ccbd662f101236 Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Sun, 23 May 2004 16:11:36 +0000 Subject: [PATCH] Localisation/UTF8 fixed. SVN revision: 10335 --- COMPLIANCE | 4 +- src/E.h | 16 ++++---- src/borders.c | 6 ++- src/ewmh.c | 12 ++++-- src/lang.c | 107 +++++++++++++++++++++++++++++++++++++++++++++----- src/main.c | 8 ++-- src/menus.c | 27 ++----------- src/tclass.c | 15 +++---- src/text.c | 78 +++++++++++++++--------------------- 9 files changed, 165 insertions(+), 108 deletions(-) diff --git a/COMPLIANCE b/COMPLIANCE index d0b03b2e..4515b9db 100644 --- a/COMPLIANCE +++ b/COMPLIANCE @@ -44,9 +44,9 @@ Other Root Window Messages Application Window Properties ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -[ ] _NET_WM_NAME +[+] _NET_WM_NAME [ ] _NET_WM_VISIBLE_NAME -[ ] _NET_WM_ICON_NAME +[+] _NET_WM_ICON_NAME [ ] _NET_WM_VISIBLE_ICON_NAME [+] _NET_WM_DESKTOP [/] _NET_WM_WINDOW_TYPE diff --git a/src/E.h b/src/E.h index c5f575e1..e36d6aa9 100644 --- a/src/E.h +++ b/src/E.h @@ -719,6 +719,7 @@ typedef struct _textstate XFontStruct *xfont; XFontSet xfontset; int xfontset_ascent; + char need_utf8; } TextState; @@ -1277,7 +1278,8 @@ typedef struct } move; struct { - char utf8; /* Use UTF8 internally */ + char utf8_int; /* Use UTF-8 internally */ + char utf8_loc; /* Locale is UTF-8 */ } text; int debug; int mode; @@ -2337,7 +2339,10 @@ void ButtonIPC(int val, void *data); /* lang.c */ void LangInit(void); -char *Eiconv(const char *txt, size_t len); +char *EstrLoc2Int(const char *str, int len); +char *EstrUtf82Int(const char *str, int len); +const char *EstrInt2Enc(const char *str, int want_utf8); +void EstrInt2EncFree(const char *str, int want_utf8); /* lists.c */ void *FindItem(const char *name, int id, int find_by, int type); @@ -2619,11 +2624,8 @@ void TclassApply(ImageClass * iclass, Window win, int w, int h, TextClass * tclass, const char *text); /* text.c */ -int ExTextExtents(XFontSet font_set, const char *string, - int len, XRectangle * oir, XRectangle * olr); -void ExDrawString(Display * display, Drawable d, - XFontSet font_set, GC gc, int x, int y, - const char *string, int len); +#define ExTextExtents XmbTextExtents +#define ExDrawString XmbDrawString TextState *TextGetState(TextClass * tclass, int active, int sticky, int state); void TextStateLoadFont(TextState * ts); diff --git a/src/borders.c b/src/borders.c index bbc60b5d..5927a486 100644 --- a/src/borders.c +++ b/src/borders.c @@ -1357,10 +1357,12 @@ EwinDestroy(EWin * ewin) Efree(ewin->icccm.wm_command); if (ewin->icccm.wm_machine) Efree(ewin->icccm.wm_machine); +#if ENABLE_EWMH if (ewin->ewmh.wm_name) Efree(ewin->ewmh.wm_name); if (ewin->ewmh.wm_icon_name) Efree(ewin->ewmh.wm_icon_name); +#endif if (ewin->icccm.wm_icon_name) Efree(ewin->icccm.wm_icon_name); if (ewin->win) @@ -3095,7 +3097,7 @@ EwinGetTitle(const EWin * ewin) { const char *name; -#if 0 /* ENABLE_EWMH */ +#if ENABLE_EWMH name = ewin->ewmh.wm_name; if (name) goto done; @@ -3113,7 +3115,7 @@ EwinGetIconName(const EWin * ewin) { const char *name; -#if 0 /* ENABLE_EWMH */ +#if ENABLE_EWMH name = ewin->ewmh.wm_icon_name; if (name) goto done; diff --git a/src/ewmh.c b/src/ewmh.c index ea5ed340..ddb43c5f 100644 --- a/src/ewmh.c +++ b/src/ewmh.c @@ -448,7 +448,13 @@ EWMH_SetShowingDesktop(int on) void EWMH_SetWindowName(Window win, const char *name) { - _ATOM_SET_UTF8_STRING(_NET_WM_NAME, win, name); + const char *str; + + EDBUG(6, "EWMH_SetWindowName"); + str = EstrInt2Enc(name, 1); + _ATOM_SET_UTF8_STRING(_NET_WM_NAME, win, str); + EstrInt2EncFree(str, 1); + EDBUG_RETURN_; } void @@ -514,7 +520,7 @@ EWMH_GetWindowName(EWin * ewin) if (ewin->ewmh.wm_name) Efree(ewin->ewmh.wm_name); - ewin->ewmh.wm_name = Estrndup(val, size); + ewin->ewmh.wm_name = EstrUtf82Int(val, size); Efree(val); EwinChange(ewin, EWIN_CHANGE_NAME); @@ -537,7 +543,7 @@ EWMH_GetWindowIconName(EWin * ewin) if (ewin->ewmh.wm_icon_name) Efree(ewin->ewmh.wm_icon_name); - ewin->ewmh.wm_icon_name = Estrndup(val, size); + ewin->ewmh.wm_icon_name = EstrUtf82Int(val, size); Efree(val); EwinChange(ewin, EWIN_CHANGE_ICON_NAME); diff --git a/src/lang.c b/src/lang.c index 35ff83bb..a58140b4 100644 --- a/src/lang.c +++ b/src/lang.c @@ -27,13 +27,16 @@ #include #endif -#if 0 /* Not used yet */ +#if HAVE_ICONV #include -static iconv_t iconv_cd = NULL; +static iconv_t iconv_cd_int2utf8 = NULL; +static iconv_t iconv_cd_utf82int = NULL; +static iconv_t iconv_cd_int2loc = NULL; +static iconv_t iconv_cd_loc2int = NULL; -char * -Eiconv(const char *txt, size_t len) +static char * +Eiconv(iconv_t icd, const char *txt, size_t len) { char buf[4096]; char *pi, *po; @@ -43,7 +46,7 @@ Eiconv(const char *txt, size_t len) po = buf; ni = (len > 0) ? len : strlen(txt); no = sizeof(buf); - err = iconv(iconv_cd, &pi, &ni, &po, &no); + err = iconv(icd, &pi, &ni, &po, &no); po = Estrndup(buf, sizeof(buf) - no); @@ -52,10 +55,73 @@ Eiconv(const char *txt, size_t len) #endif +/* Convert locale to internal format (alloc always) */ +char * +EstrLoc2Int(const char *str, int len) +{ + if (str == NULL) + return NULL; + +#if HAVE_ICONV + if (iconv_cd_loc2int) + return Eiconv(iconv_cd_loc2int, str, len); +#endif + + if (len <= 0) + len = strlen(str); + return Estrndup(str, len); +} + +/* Convert UTF-8 to internal format (alloc always) */ +char * +EstrUtf82Int(const char *str, int len) +{ + if (str == NULL) + return NULL; + +#if HAVE_ICONV + if (iconv_cd_utf82int) + return Eiconv(iconv_cd_utf82int, str, len); +#endif + + if (len <= 0) + len = strlen(str); + return Estrndup(str, len); +} + +/* Convert internal to required (alloc only if necessary) */ +const char * +EstrInt2Enc(const char *str, int want_utf8) +{ +#if HAVE_ICONV + if (Mode.text.utf8_int == want_utf8) + return (char *)str; + + if (want_utf8) + return Eiconv(iconv_cd_int2utf8, str, strlen(str)); + + return Eiconv(iconv_cd_int2loc, str, strlen(str)); +#else + return (char *)str; +#endif +} + +/* Free string returned by EstrInt2Enc() */ +void +EstrInt2EncFree(const char *str, int want_utf8) +{ +#if HAVE_ICONV + if (Mode.text.utf8_int == want_utf8) + return; + + Efree((char *)str); +#endif +} + void LangInit(void) { - const char *enc_env, *enc_int; + const char *enc_loc, *enc_int; /* Set up things according to env vars */ setlocale(LC_ALL, ""); @@ -72,9 +138,9 @@ LangInit(void) /* Get the environment character encoding */ #if HAVE_LANGINFO_CODESET - enc_env = nl_langinfo(CODESET); + enc_loc = nl_langinfo(CODESET); #else - enc_env = "ISO-8859-1"; + enc_loc = "ISO-8859-1"; #endif /* Debug - possibility to set desired internal representation */ @@ -82,10 +148,31 @@ LangInit(void) if (enc_int) bind_textdomain_codeset(PACKAGE, enc_int); else - enc_int = enc_env; + enc_int = enc_loc; + if (Mode.debug >= 1) + Eprintf("Locale: %s Character encoding: locale=%s internal=%s\n", + setlocale(LC_ALL, NULL), enc_loc, enc_int); + + if (!strcasecmp(enc_loc, "utf8") || !strcasecmp(enc_loc, "utf-8")) + Mode.text.utf8_loc = 1; if (!strcasecmp(enc_int, "utf8") || !strcasecmp(enc_int, "utf-8")) - Mode.text.utf8 = 1; + Mode.text.utf8_int = 1; + +#if HAVE_ICONV + if (Mode.text.utf8_int) + { + iconv_cd_loc2int = iconv_open("UTF-8", enc_loc); + iconv_cd_int2loc = iconv_open(enc_loc, "UTF-8"); + iconv_cd_utf82int = iconv_cd_int2utf8 = NULL; + } + else + { + iconv_cd_loc2int = iconv_cd_int2loc = NULL; + iconv_cd_utf82int = iconv_open(enc_loc, "UTF-8"); + iconv_cd_int2utf8 = iconv_open("UTF-8", enc_loc); + } +#endif } #if 0 /* Not used yet */ diff --git a/src/main.c b/src/main.c index 89c2c1a5..d6590e7c 100644 --- a/src/main.c +++ b/src/main.c @@ -67,11 +67,6 @@ main(int argc, char **argv) Mode.wm.startup = 1; Mode.move.check = 1; -/* unsetenv("LD_PRELOAD"); */ - - /* Initialise internationalisation */ - LangInit(); - str = getenv("EDBUG"); if (str) Mode.debug = atoi(str); @@ -97,6 +92,9 @@ main(int argc, char **argv) if (!e_machine_name) e_machine_name = Estrdup("localhost"); + /* Initialise internationalisation */ + LangInit(); + SetSMProgName(argv[0]); themepath[0] = 0; diff --git a/src/menus.c b/src/menus.c index 4affa681..e18e5856 100644 --- a/src/menus.c +++ b/src/menus.c @@ -425,36 +425,17 @@ MenuItemCreate(const char *text, ImageClass * iclass, int action_id, EDBUG(5, "MenuItemCreate"); mi = Emalloc(sizeof(MenuItem)); + memset(mi, 0, sizeof(MenuItem)); mi->icon_iclass = iclass; if (iclass) iclass->ref_count++; - mi->text = Estrdup(text); + + mi->text = EstrLoc2Int(text, 0); mi->act_id = action_id; - if (action_params) - { - mi->params = Estrdup(action_params); - } - else - { - mi->params = NULL; - } + mi->params = Estrdup(action_params); mi->child = child; mi->state = STATE_NORMAL; - mi->win = 0; - mi->pmm[0].pmap = 0; - mi->pmm[1].pmap = 0; - mi->pmm[2].pmap = 0; - mi->pmm[0].mask = 0; - mi->pmm[1].mask = 0; - mi->pmm[2].mask = 0; - mi->icon_win = 0; - mi->icon_w = 0; - mi->icon_h = 0; - mi->text_w = 0; - mi->text_h = 0; - mi->text_x = 0; - mi->text_y = 0; EDBUG_RETURN(mi); } diff --git a/src/tclass.c b/src/tclass.c index d65994e9..7f015e52 100644 --- a/src/tclass.c +++ b/src/tclass.c @@ -23,24 +23,19 @@ #include "E.h" TextClass * -CreateTclass() +CreateTclass(void) { TextClass *t; EDBUG(5, "CreateTclass"); + t = Emalloc(sizeof(TextClass)); if (!t) EDBUG_RETURN(NULL); - t->name = NULL; - t->norm.normal = t->norm.hilited = t->norm.clicked = t->norm.disabled = NULL; - t->active.normal = t->active.hilited = t->active.clicked = - t->active.disabled = NULL; - t->sticky.normal = t->sticky.hilited = t->sticky.clicked = - t->sticky.disabled = NULL; - t->sticky_active.normal = t->sticky_active.hilited = - t->sticky_active.clicked = t->sticky_active.disabled = NULL; + + memset(t, 0, sizeof(TextClass)); t->justification = 512; - t->ref_count = 0; + EDBUG_RETURN(t); } diff --git a/src/text.c b/src/text.c index 7a011257..a203fc70 100644 --- a/src/text.c +++ b/src/text.c @@ -28,34 +28,6 @@ static void TextDrawRotTo(Window win, Drawable * drawable, int x, int y, static void TextDrawRotBack(Window win, Drawable drawable, int x, int y, int w, int h, TextState * ts); -int -ExTextExtents(XFontSet font_set, const char *string, int len, - XRectangle * oir, XRectangle * olr) -{ -#ifdef X_HAVE_UTF8_STRING - if (Mode.text.utf8) - { - return Xutf8TextExtents(font_set, string, len, oir, olr); - } -#endif - - return XmbTextExtents(font_set, string, len, oir, olr); -} - -void -ExDrawString(Display * display, Drawable d, XFontSet font_set, GC - gc, int x, int y, const char *string, int len) -{ -#ifdef X_HAVE_UTF8_STRING - if (Mode.text.utf8) - { - Xutf8DrawString(display, d, font_set, gc, x, y, string, len); - return; - } -#endif - XmbDrawString(display, d, font_set, gc, x, y, string, len); -} - TextState * TextGetState(TextClass * tclass, int active, int sticky, int state) { @@ -208,6 +180,10 @@ TextStateLoadFont(TextState * ts) } if (s2) Efree(s2); +#if USE_IMLIB2 + if (ts->efont) + ts->need_utf8 = 1; +#endif } if (ts->efont) goto done; @@ -259,6 +235,7 @@ void TextSize(TextClass * tclass, int active, int sticky, int state, const char *text, int *width, int *height, int fsize) { + const char *str; char **lines; int i, num_lines; TextState *ts; @@ -268,16 +245,19 @@ TextSize(TextClass * tclass, int active, int sticky, int state, *width = 0; *height = 0; - lines = TextGetLines(text, &num_lines); - if (!lines) - EDBUG_RETURN_; - ts = TextGetState(tclass, active, sticky, state); if (!ts) EDBUG_RETURN_; TextStateLoadFont(ts); + /* Do encoding conversion, if necessary */ + str = EstrInt2Enc(text, ts->need_utf8); + lines = TextGetLines(str, &num_lines); + EstrInt2EncFree(str, ts->need_utf8); + if (!lines) + EDBUG_RETURN_; + #if USE_FNLIB if (ts->font) { @@ -341,9 +321,8 @@ TextSize(TextClass * tclass, int active, int sticky, int state, { int wid; - wid = - XTextWidth16(ts->xfont, (XChar2b *) lines[i], - strlen(lines[i]) / 2); + wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i], + strlen(lines[i]) / 2); *height += ts->xfont->ascent + ts->xfont->descent; if (wid > *width) *width = wid; @@ -359,35 +338,43 @@ TextDraw(TextClass * tclass, Window win, int active, int sticky, int state, const char *text, int x, int y, int w, int h, int fsize, int justification) { + const char *str; char **lines; int i, num_lines; TextState *ts; int xx, yy; XGCValues gcv; static GC gc = 0; - int textwidth_limit, offset_x, offset_y; Pixmap drawable; EDBUG(4, "TextDraw"); - lines = TextGetLines(text, &num_lines); - if (!lines) - EDBUG_RETURN_; + ts = TextGetState(tclass, active, sticky, state); if (!ts) EDBUG_RETURN_; + TextStateLoadFont(ts); - xx = x; - yy = y; + + /* Do encoding conversion, if necessary */ + str = EstrInt2Enc(text, ts->need_utf8); + lines = TextGetLines(str, &num_lines); + EstrInt2EncFree(str, ts->need_utf8); + if (!lines) + EDBUG_RETURN_; + if (!gc) gc = XCreateGC(disp, win, 0, &gcv); - if (ts->style.orientation == FONT_TO_RIGHT - || ts->style.orientation == FONT_TO_LEFT) + if (ts->style.orientation == FONT_TO_RIGHT || + ts->style.orientation == FONT_TO_LEFT) textwidth_limit = w; else textwidth_limit = h; + xx = x; + yy = y; + #if USE_FNLIB if (ts->font) { @@ -747,9 +734,8 @@ TextDraw(TextClass * tclass, Window win, int active, int sticky, int state, { int wid, ascent, descent; - wid = - XTextWidth16(ts->xfont, (XChar2b *) lines[i], - strlen(lines[i]) / 2); + wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i], + strlen(lines[i]) / 2); ascent = ts->xfont->ascent; descent = ts->xfont->descent; if (wid > textwidth_limit)