draw: fix UTF-8 string len computation upon conversion
Signed-off-by: Julien Danjou <julien@danjou.info>
This commit is contained in:
parent
9adf3fd869
commit
a4d914f0e4
29
draw.c
29
draw.c
|
@ -39,13 +39,14 @@ extern awesome_t globalconf;
|
||||||
/** Convert text from any charset to UTF-8 using iconv.
|
/** Convert text from any charset to UTF-8 using iconv.
|
||||||
* \param iso The ISO string to convert.
|
* \param iso The ISO string to convert.
|
||||||
* \param len The string size.
|
* \param len The string size.
|
||||||
* \return NULL if error, otherwise pointer to the new converted string.
|
* \param dest The destination pointer. Memory will be allocated, up to you to
|
||||||
|
* free, like any char *.
|
||||||
|
* \param dlen The destination length, can be NULL.
|
||||||
|
* \return True if conversion was done.
|
||||||
*/
|
*/
|
||||||
char *
|
bool
|
||||||
draw_iso2utf8(const char *iso, size_t len)
|
draw_iso2utf8(const char *iso, size_t len, char **dest, ssize_t *dlen)
|
||||||
{
|
{
|
||||||
size_t utf8len;
|
|
||||||
char *utf8, *utf8p;
|
|
||||||
static iconv_t iso2utf8 = (iconv_t) -1;
|
static iconv_t iso2utf8 = (iconv_t) -1;
|
||||||
static int8_t dont_need_convert = -1;
|
static int8_t dont_need_convert = -1;
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ draw_iso2utf8(const char *iso, size_t len)
|
||||||
dont_need_convert = !a_strcmp(nl_langinfo(CODESET), "UTF-8");
|
dont_need_convert = !a_strcmp(nl_langinfo(CODESET), "UTF-8");
|
||||||
|
|
||||||
if(!len || dont_need_convert)
|
if(!len || dont_need_convert)
|
||||||
return NULL;
|
return false;
|
||||||
|
|
||||||
if(iso2utf8 == (iconv_t) -1)
|
if(iso2utf8 == (iconv_t) -1)
|
||||||
{
|
{
|
||||||
|
@ -66,20 +67,26 @@ draw_iso2utf8(const char *iso, size_t len)
|
||||||
else
|
else
|
||||||
warn("unable to convert text: %s", strerror(errno));
|
warn("unable to convert text: %s", strerror(errno));
|
||||||
|
|
||||||
return NULL;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utf8len = 2 * len + 1;
|
size_t orig_utf8len, utf8len;
|
||||||
utf8 = utf8p = p_new(char, utf8len);
|
char *utf8;
|
||||||
|
|
||||||
|
orig_utf8len = utf8len = 2 * len + 1;
|
||||||
|
utf8 = *dest = p_new(char, utf8len);
|
||||||
|
|
||||||
if(iconv(iso2utf8, (char **) &iso, &len, &utf8, &utf8len) == (size_t) -1)
|
if(iconv(iso2utf8, (char **) &iso, &len, &utf8, &utf8len) == (size_t) -1)
|
||||||
{
|
{
|
||||||
warn("text conversion failed: %s", strerror(errno));
|
warn("text conversion failed: %s", strerror(errno));
|
||||||
p_delete(&utf8p);
|
p_delete(dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
return utf8p;
|
if(dlen)
|
||||||
|
*dlen = orig_utf8len - utf8len;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static xcb_visualtype_t *
|
static xcb_visualtype_t *
|
||||||
|
|
22
draw.h
22
draw.h
|
@ -141,18 +141,26 @@ draw_context_wipe(draw_context_t *ctx)
|
||||||
font_t *draw_font_new(const char *);
|
font_t *draw_font_new(const char *);
|
||||||
void draw_font_delete(font_t **);
|
void draw_font_delete(font_t **);
|
||||||
|
|
||||||
char * draw_iso2utf8(const char *, size_t);
|
bool draw_iso2utf8(const char *, size_t, char **, ssize_t *);
|
||||||
|
|
||||||
|
/** Convert a string to UTF-8.
|
||||||
|
* \param str The string to convert.
|
||||||
|
* \param len The string length.
|
||||||
|
* \param dest The destination string that will be allocated.
|
||||||
|
* \param dlen The destination string length allocated, can be NULL.
|
||||||
|
* \return True if the conversion happened, false otherwise. In both case, dest
|
||||||
|
* and dlen will have value and dest have to be free().
|
||||||
|
*/
|
||||||
static inline bool
|
static inline bool
|
||||||
a_iso2utf8(char **dest, const char *str, ssize_t len)
|
a_iso2utf8(const char *str, ssize_t len, char **dest, ssize_t *dlen)
|
||||||
{
|
{
|
||||||
char *utf8;
|
if(draw_iso2utf8(str, len, dest, dlen))
|
||||||
if((utf8 = draw_iso2utf8(str, len)))
|
|
||||||
{
|
|
||||||
*dest = utf8;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
*dest = a_strdup(str);
|
*dest = a_strdup(str);
|
||||||
|
if(dlen)
|
||||||
|
*dlen = len;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -273,8 +273,9 @@ property_update_wm_name(client_t *c)
|
||||||
|
|
||||||
p_delete(&c->name);
|
p_delete(&c->name);
|
||||||
|
|
||||||
if((utf8 = draw_iso2utf8(name, len)))
|
/* if no conversion needed, just point to name */
|
||||||
c->name = utf8;
|
if(draw_iso2utf8(name, len, &utf8, NULL))
|
||||||
|
p_delete(&name);
|
||||||
else
|
else
|
||||||
c->name = name;
|
c->name = name;
|
||||||
|
|
||||||
|
@ -298,8 +299,8 @@ property_update_wm_icon_name(client_t *c)
|
||||||
|
|
||||||
p_delete(&c->icon_name);
|
p_delete(&c->icon_name);
|
||||||
|
|
||||||
if((utf8 = draw_iso2utf8(name, len)))
|
if(draw_iso2utf8(name, len, &utf8, NULL))
|
||||||
c->icon_name = utf8;
|
p_delete(&name);
|
||||||
else
|
else
|
||||||
c->icon_name = name;
|
c->icon_name = name;
|
||||||
|
|
||||||
|
|
4
tag.c
4
tag.c
|
@ -54,7 +54,7 @@ tag_new(const char *name, ssize_t len)
|
||||||
tag_t *tag;
|
tag_t *tag;
|
||||||
|
|
||||||
tag = p_new(tag_t, 1);
|
tag = p_new(tag_t, 1);
|
||||||
a_iso2utf8(&tag->name, name, len);
|
a_iso2utf8(name, len, &tag->name, NULL);
|
||||||
|
|
||||||
/* to avoid error */
|
/* to avoid error */
|
||||||
tag->screen = SCREEN_UNDEF;
|
tag->screen = SCREEN_UNDEF;
|
||||||
|
@ -357,7 +357,7 @@ luaA_tag_newindex(lua_State *L)
|
||||||
{
|
{
|
||||||
const char *buf = luaL_checklstring(L, 3, &len);
|
const char *buf = luaL_checklstring(L, 3, &len);
|
||||||
p_delete(&(*tag)->name);
|
p_delete(&(*tag)->name);
|
||||||
a_iso2utf8(&(*tag)->name, buf, len);
|
a_iso2utf8(buf, len, &(*tag)->name, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case A_TK_SCREEN:
|
case A_TK_SCREEN:
|
||||||
|
|
|
@ -30,7 +30,7 @@ typedef struct
|
||||||
/** Textbox text */
|
/** Textbox text */
|
||||||
char *text;
|
char *text;
|
||||||
/** Textbox text length */
|
/** Textbox text length */
|
||||||
size_t len;
|
ssize_t len;
|
||||||
/** Textbox width */
|
/** Textbox width */
|
||||||
int width;
|
int width;
|
||||||
/** Extents */
|
/** Extents */
|
||||||
|
@ -244,16 +244,17 @@ luaA_textbox_newindex(lua_State *L, awesome_token_t token)
|
||||||
draw_parser_data_init(&d->pdata);
|
draw_parser_data_init(&d->pdata);
|
||||||
p_delete(&d->text);
|
p_delete(&d->text);
|
||||||
|
|
||||||
/* re-init */
|
|
||||||
d->len = len;
|
|
||||||
if(buf)
|
if(buf)
|
||||||
{
|
{
|
||||||
a_iso2utf8(&d->text, buf, len);
|
a_iso2utf8(buf, len, &d->text, &d->len);
|
||||||
d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata);
|
d->extents = draw_text_extents(globalconf.font, d->text, d->len, &d->pdata);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
d->len = 0;
|
||||||
p_clear(&d->extents, 1);
|
p_clear(&d->extents, 1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case A_TK_WIDTH:
|
case A_TK_WIDTH:
|
||||||
d->width = luaL_checknumber(L, 3);
|
d->width = luaL_checknumber(L, 3);
|
||||||
|
|
Loading…
Reference in New Issue