From d5a0c9644c9e3a1808a80e7b6a843487d0e50636 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Tue, 18 Sep 2012 11:30:38 +0200 Subject: [PATCH] tsm: unicode: add symbol-table contexts We should avoid any global state in shared libraries. As the TSM code is becoming a shared library, we definitely need contexts for symbol tables. However, we don't want to fix up all code now so we use a default table NULL instead. This can be fixed later but is ok for now. Signed-off-by: David Herrmann --- src/text_font_8x16.c | 2 +- src/text_font_freetype2.c | 2 +- src/text_font_pango.c | 2 +- src/text_font_unifont.c | 2 +- src/tsm_unicode.c | 73 ++++++++++++++++++++++----------------- src/tsm_unicode.h | 10 ++++-- src/vte.c | 2 +- 7 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/text_font_8x16.c b/src/text_font_8x16.c index 34b8d2a..78eac77 100644 --- a/src/text_font_8x16.c +++ b/src/text_font_8x16.c @@ -88,7 +88,7 @@ static int kmscon_font_8x16_render(struct kmscon_font *font, const uint32_t *val; size_t len; - val = tsm_symbol_get(&sym, &len); + val = tsm_symbol_get(NULL, &sym, &len); if (len > 1 || *val >= 256) return -ERANGE; diff --git a/src/text_font_freetype2.c b/src/text_font_freetype2.c index 59cd99d..b22aaf0 100644 --- a/src/text_font_freetype2.c +++ b/src/text_font_freetype2.c @@ -181,7 +181,7 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, * TODO: Fix this by drawing all related characters into a single glyph * and saving it or simply refer to the pango backend which already does * that. */ - val = tsm_symbol_get(&ch, &len); + val = tsm_symbol_get(NULL, &ch, &len); if (len > 1 || !*val) { ret = -ERANGE; goto out_glyph; diff --git a/src/text_font_pango.c b/src/text_font_pango.c index 4ff396d..9cd0849 100644 --- a/src/text_font_pango.c +++ b/src/text_font_pango.c @@ -149,7 +149,7 @@ static int get_glyph(struct face *face, struct kmscon_glyph **out, /* no line spacing */ pango_layout_set_spacing(layout, 0); - val = tsm_symbol_get_u8(ch, &len); + val = tsm_symbol_get_u8(NULL, ch, &len); pango_layout_set_text(layout, val, len); tsm_symbol_free_u8(val); diff --git a/src/text_font_unifont.c b/src/text_font_unifont.c index 48fe0c2..93ecb00 100644 --- a/src/text_font_unifont.c +++ b/src/text_font_unifont.c @@ -84,7 +84,7 @@ static int kmscon_font_unifont_render(struct kmscon_font *font, const uint32_t *val; size_t len; - val = tsm_symbol_get(&sym, &len); + val = tsm_symbol_get(NULL, &sym, &len); if (len > 1 || *val >= kmscon_text_font_unifont_data_hex_len) return -ERANGE; diff --git a/src/tsm_unicode.c b/src/tsm_unicode.c index b2baccf..04f4fa2 100644 --- a/src/tsm_unicode.c +++ b/src/tsm_unicode.c @@ -56,7 +56,6 @@ #include #include -#include #include #include #include "shl_array.h" @@ -100,10 +99,14 @@ const tsm_symbol_t tsm_symbol_default = 0; static const char default_u8[] = { 0 }; -static pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER; -static uint32_t table_next_id; -static struct shl_array *table_index; -static struct shl_hashtable *table_symbols; +struct tsm_symbol_table { + uint32_t next_id; + struct shl_array *index; + struct shl_hashtable *symbols; +}; + +/* TODO: remove the default context */ +static struct tsm_symbol_table tsm_symbol_table_default; static unsigned int hash_ucs4(const void *key) { @@ -143,27 +146,27 @@ static bool cmp_ucs4(const void *a, const void *b) } } -static int table__init() +static int table__init(struct tsm_symbol_table *tbl) { static const uint32_t *val = NULL; /* we need a valid lvalue */ int ret; - if (table_symbols) + if (tbl->symbols) return 0; - table_next_id = TSM_UCS4_MAX + 2; + tbl->next_id = TSM_UCS4_MAX + 2; - ret = shl_array_new(&table_index, sizeof(uint32_t*), 4); + ret = shl_array_new(&tbl->index, sizeof(uint32_t*), 4); if (ret) return ret; /* first entry is not used so add dummy */ - shl_array_push(table_index, &val); + shl_array_push(tbl->index, &val); - ret = shl_hashtable_new(&table_symbols, hash_ucs4, cmp_ucs4, - free, NULL); + ret = shl_hashtable_new(&tbl->symbols, hash_ucs4, cmp_ucs4, + free, NULL); if (ret) { - shl_array_free(table_index); + shl_array_free(tbl->index); return -ENOMEM; } @@ -189,7 +192,8 @@ tsm_symbol_t tsm_symbol_make(uint32_t ucs4) * This always returns a valid value. If an error happens, the default character * is returned. If \size is NULL, then the size value is omitted. */ -static const uint32_t *table__get(tsm_symbol_t *sym, size_t *size) +static const uint32_t *table__get(struct tsm_symbol_table *tbl, + tsm_symbol_t *sym, size_t *size) { uint32_t *ucs4; @@ -199,13 +203,13 @@ static const uint32_t *table__get(tsm_symbol_t *sym, size_t *size) return sym; } - if (table__init()) { + if (table__init(tbl)) { if (size) *size = 1; return &tsm_symbol_default; } - ucs4 = *SHL_ARRAY_AT(table_index, uint32_t*, + ucs4 = *SHL_ARRAY_AT(tbl->index, uint32_t*, *sym - (TSM_UCS4_MAX + 1)); if (!ucs4) { if (size) @@ -222,18 +226,21 @@ static const uint32_t *table__get(tsm_symbol_t *sym, size_t *size) return ucs4; } -const uint32_t *tsm_symbol_get(tsm_symbol_t *sym, size_t *size) +const uint32_t *tsm_symbol_get(struct tsm_symbol_table *tbl, + tsm_symbol_t *sym, size_t *size) { const uint32_t *res; - pthread_mutex_lock(&table_mutex); - res = table__get(sym, size); - pthread_mutex_unlock(&table_mutex); + if (!tbl) + tbl = &tsm_symbol_table_default; + + res = table__get(tbl, sym, size); return res; } -tsm_symbol_t tsm_symbol_append(tsm_symbol_t sym, uint32_t ucs4) +tsm_symbol_t tsm_symbol_append(struct tsm_symbol_table *tbl, + tsm_symbol_t sym, uint32_t ucs4) { uint32_t buf[TSM_UCS4_MAXLEN + 1], nsym, *nval; const uint32_t *ptr; @@ -242,9 +249,10 @@ tsm_symbol_t tsm_symbol_append(tsm_symbol_t sym, uint32_t ucs4) void *tmp; bool res; - pthread_mutex_lock(&table_mutex); + if (!tbl) + tbl = &tsm_symbol_table_default; - if (table__init()) { + if (table__init(tbl)) { rsym = sym; goto unlock; } @@ -254,7 +262,7 @@ tsm_symbol_t tsm_symbol_append(tsm_symbol_t sym, uint32_t ucs4) goto unlock; } - ptr = table__get(&sym, &s); + ptr = table__get(tbl, &sym, &s); if (s >= TSM_UCS4_MAXLEN) { rsym = sym; goto unlock; @@ -264,7 +272,7 @@ tsm_symbol_t tsm_symbol_append(tsm_symbol_t sym, uint32_t ucs4) buf[s++] = ucs4; buf[s++] = TSM_UCS4_MAX + 1; - res = shl_hashtable_find(table_symbols, &tmp, buf); + res = shl_hashtable_find(tbl->symbols, &tmp, buf); if (res) { rsym = (uint32_t)(long)tmp; goto unlock; @@ -277,13 +285,12 @@ tsm_symbol_t tsm_symbol_append(tsm_symbol_t sym, uint32_t ucs4) } memcpy(nval, buf, s * sizeof(uint32_t)); - nsym = table_next_id++; - shl_hashtable_insert(table_symbols, nval, (void*)(long)nsym); - shl_array_push(table_index, &nval); + nsym = tbl->next_id++; + shl_hashtable_insert(tbl->symbols, nval, (void*)(long)nsym); + shl_array_push(tbl->index, &nval); rsym = nsym; unlock: - pthread_mutex_unlock(&table_mutex); return rsym; } @@ -321,13 +328,17 @@ static size_t ucs4_to_utf8(uint32_t g, char *txt) } } -const char *tsm_symbol_get_u8(tsm_symbol_t sym, size_t *size) +const char *tsm_symbol_get_u8(struct tsm_symbol_table *tbl, + tsm_symbol_t sym, size_t *size) { const uint32_t *ucs4; char *val; size_t i, pos, len; - ucs4 = tsm_symbol_get(&sym, &len); + if (!tbl) + tbl = &tsm_symbol_table_default; + + ucs4 = tsm_symbol_get(tbl, &sym, &len); val = malloc(4 * len); if (!val) goto err_out; diff --git a/src/tsm_unicode.h b/src/tsm_unicode.h index b6efc0b..b44c256 100644 --- a/src/tsm_unicode.h +++ b/src/tsm_unicode.h @@ -45,14 +45,18 @@ /* symbols */ +struct tsm_symbol_table; typedef uint32_t tsm_symbol_t; extern const tsm_symbol_t tsm_symbol_default; tsm_symbol_t tsm_symbol_make(uint32_t ucs4); -tsm_symbol_t tsm_symbol_append(tsm_symbol_t sym, uint32_t ucs4); -const uint32_t *tsm_symbol_get(tsm_symbol_t *sym, size_t *size); -const char *tsm_symbol_get_u8(tsm_symbol_t sym, size_t *size); +tsm_symbol_t tsm_symbol_append(struct tsm_symbol_table *tbl, + tsm_symbol_t sym, uint32_t ucs4); +const uint32_t *tsm_symbol_get(struct tsm_symbol_table *tbl, + tsm_symbol_t *sym, size_t *size); +const char *tsm_symbol_get_u8(struct tsm_symbol_table *tbl, + tsm_symbol_t sym, size_t *size); void tsm_symbol_free_u8(const char *s); /* utf8 state machine */ diff --git a/src/vte.c b/src/vte.c index c77ab66..4b4d490 100644 --- a/src/vte.c +++ b/src/vte.c @@ -2625,7 +2625,7 @@ bool kmscon_vte_handle_keyboard(struct kmscon_vte *vte, uint32_t keysym, vte_write_raw(vte, &val, 1); } else { sym = tsm_symbol_make(unicode); - u8 = tsm_symbol_get_u8(sym, &len); + u8 = tsm_symbol_get_u8(NULL, sym, &len); vte_write_raw(vte, u8, len); tsm_symbol_free_u8(u8); }