unicode: use static global symbol table
A symbol table should never be created twice therefore we can make it static and global. We add locks so it is totally thread-safe, too. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
This commit is contained in:
parent
a31455a10b
commit
c9ea08d9b5
@ -41,8 +41,7 @@
|
|||||||
struct kmscon_font_factory;
|
struct kmscon_font_factory;
|
||||||
struct kmscon_font;
|
struct kmscon_font;
|
||||||
|
|
||||||
int kmscon_font_factory_new(struct kmscon_font_factory **out,
|
int kmscon_font_factory_new(struct kmscon_font_factory **out);
|
||||||
struct kmscon_symbol_table *st);
|
|
||||||
void kmscon_font_factory_ref(struct kmscon_font_factory *ff);
|
void kmscon_font_factory_ref(struct kmscon_font_factory *ff);
|
||||||
void kmscon_font_factory_unref(struct kmscon_font_factory *ff);
|
void kmscon_font_factory_unref(struct kmscon_font_factory *ff);
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@
|
|||||||
|
|
||||||
struct kmscon_font_factory {
|
struct kmscon_font_factory {
|
||||||
unsigned long ref;
|
unsigned long ref;
|
||||||
struct kmscon_symbol_table *st;
|
|
||||||
FT_Library lib;
|
FT_Library lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,7 +92,7 @@ static int kmscon_glyph_new(struct kmscon_glyph **out, kmscon_symbol_t key,
|
|||||||
|
|
||||||
memset(glyph, 0, sizeof(*glyph));
|
memset(glyph, 0, sizeof(*glyph));
|
||||||
|
|
||||||
val = kmscon_symbol_get(font->ff->st, &key, &len);
|
val = kmscon_symbol_get(&key, &len);
|
||||||
|
|
||||||
if (!val[0])
|
if (!val[0])
|
||||||
goto ready;
|
goto ready;
|
||||||
@ -164,14 +163,13 @@ static void kmscon_glyph_destroy(struct kmscon_glyph *glyph)
|
|||||||
free(glyph);
|
free(glyph);
|
||||||
}
|
}
|
||||||
|
|
||||||
int kmscon_font_factory_new(struct kmscon_font_factory **out,
|
int kmscon_font_factory_new(struct kmscon_font_factory **out)
|
||||||
struct kmscon_symbol_table *st)
|
|
||||||
{
|
{
|
||||||
struct kmscon_font_factory *ff;
|
struct kmscon_font_factory *ff;
|
||||||
FT_Error err;
|
FT_Error err;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!out || !st)
|
if (!out)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
log_debug("font: new font factory\n");
|
log_debug("font: new font factory\n");
|
||||||
@ -182,7 +180,6 @@ int kmscon_font_factory_new(struct kmscon_font_factory **out,
|
|||||||
|
|
||||||
memset(ff, 0, sizeof(*ff));
|
memset(ff, 0, sizeof(*ff));
|
||||||
ff->ref = 1;
|
ff->ref = 1;
|
||||||
ff->st = st;
|
|
||||||
|
|
||||||
err = FT_Init_FreeType(&ff->lib);
|
err = FT_Init_FreeType(&ff->lib);
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -191,7 +188,6 @@ int kmscon_font_factory_new(struct kmscon_font_factory **out,
|
|||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
kmscon_symbol_table_ref(ff->st);
|
|
||||||
*out = ff;
|
*out = ff;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -225,7 +221,6 @@ void kmscon_font_factory_unref(struct kmscon_font_factory *ff)
|
|||||||
if (err)
|
if (err)
|
||||||
log_warn("font: cannot deinitialize FreeType library\n");
|
log_warn("font: cannot deinitialize FreeType library\n");
|
||||||
|
|
||||||
kmscon_symbol_table_unref(ff->st);
|
|
||||||
free(ff);
|
free(ff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +249,6 @@ static void input_event(struct kmscon_input *input,
|
|||||||
|
|
||||||
int kmscon_terminal_new(struct kmscon_terminal **out,
|
int kmscon_terminal_new(struct kmscon_terminal **out,
|
||||||
struct ev_eloop *loop,
|
struct ev_eloop *loop,
|
||||||
struct kmscon_symbol_table *st,
|
|
||||||
struct kmscon_font_factory *ff,
|
struct kmscon_font_factory *ff,
|
||||||
struct uterm_video *video,
|
struct uterm_video *video,
|
||||||
struct kmscon_input *input)
|
struct kmscon_input *input)
|
||||||
@ -257,7 +256,7 @@ int kmscon_terminal_new(struct kmscon_terminal **out,
|
|||||||
struct kmscon_terminal *term;
|
struct kmscon_terminal *term;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!out || !loop || !st || !ff || !video || !input)
|
if (!out || !loop || !ff || !video || !input)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
term = malloc(sizeof(*term));
|
term = malloc(sizeof(*term));
|
||||||
@ -278,7 +277,7 @@ int kmscon_terminal_new(struct kmscon_terminal **out,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err_idle;
|
goto err_idle;
|
||||||
|
|
||||||
ret = kmscon_vte_new(&term->vte, st);
|
ret = kmscon_vte_new(&term->vte);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_con;
|
goto err_con;
|
||||||
kmscon_vte_bind(term->vte, term->console);
|
kmscon_vte_bind(term->vte, term->console);
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "gl.h"
|
#include "gl.h"
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "unicode.h"
|
|
||||||
#include "uterm.h"
|
#include "uterm.h"
|
||||||
|
|
||||||
struct kmscon_terminal;
|
struct kmscon_terminal;
|
||||||
@ -56,7 +55,6 @@ typedef void (*kmscon_terminal_event_cb)
|
|||||||
|
|
||||||
int kmscon_terminal_new(struct kmscon_terminal **out,
|
int kmscon_terminal_new(struct kmscon_terminal **out,
|
||||||
struct ev_eloop *loop,
|
struct ev_eloop *loop,
|
||||||
struct kmscon_symbol_table *st,
|
|
||||||
struct kmscon_font_factory *ff,
|
struct kmscon_font_factory *ff,
|
||||||
struct uterm_video *video,
|
struct uterm_video *video,
|
||||||
struct kmscon_input *input);
|
struct kmscon_input *input);
|
||||||
|
13
src/ui.c
13
src/ui.c
@ -38,7 +38,6 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "unicode.h"
|
|
||||||
#include "uterm.h"
|
#include "uterm.h"
|
||||||
|
|
||||||
#define LOG_SUBSYSTEM "config"
|
#define LOG_SUBSYSTEM "config"
|
||||||
@ -47,7 +46,6 @@ struct kmscon_ui {
|
|||||||
struct ev_eloop *eloop;
|
struct ev_eloop *eloop;
|
||||||
struct uterm_video *video;
|
struct uterm_video *video;
|
||||||
struct kmscon_input *input;
|
struct kmscon_input *input;
|
||||||
struct kmscon_symbol_table *st;
|
|
||||||
struct kmscon_font_factory *ff;
|
struct kmscon_font_factory *ff;
|
||||||
struct kmscon_terminal *term;
|
struct kmscon_terminal *term;
|
||||||
};
|
};
|
||||||
@ -97,15 +95,11 @@ int kmscon_ui_new(struct kmscon_ui **out,
|
|||||||
ui->video = video;
|
ui->video = video;
|
||||||
ui->input = input;
|
ui->input = input;
|
||||||
|
|
||||||
ret = kmscon_symbol_table_new(&ui->st);
|
ret = kmscon_font_factory_new(&ui->ff);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
ret = kmscon_font_factory_new(&ui->ff, ui->st);
|
ret = kmscon_terminal_new(&ui->term, eloop, ui->ff, ui->video,
|
||||||
if (ret)
|
|
||||||
goto err_st;
|
|
||||||
|
|
||||||
ret = kmscon_terminal_new(&ui->term, eloop, ui->st, ui->ff, ui->video,
|
|
||||||
ui->input);
|
ui->input);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_ff;
|
goto err_ff;
|
||||||
@ -136,8 +130,6 @@ err_term:
|
|||||||
kmscon_terminal_unref(ui->term);
|
kmscon_terminal_unref(ui->term);
|
||||||
err_ff:
|
err_ff:
|
||||||
kmscon_font_factory_unref(ui->ff);
|
kmscon_font_factory_unref(ui->ff);
|
||||||
err_st:
|
|
||||||
kmscon_symbol_table_unref(ui->st);
|
|
||||||
err_free:
|
err_free:
|
||||||
free(ui);
|
free(ui);
|
||||||
return ret;
|
return ret;
|
||||||
@ -152,7 +144,6 @@ void kmscon_ui_free(struct kmscon_ui *ui)
|
|||||||
uterm_video_unregister_cb(ui->video, video_event, ui);
|
uterm_video_unregister_cb(ui->video, video_event, ui);
|
||||||
kmscon_terminal_unref(ui->term);
|
kmscon_terminal_unref(ui->term);
|
||||||
kmscon_font_factory_unref(ui->ff);
|
kmscon_font_factory_unref(ui->ff);
|
||||||
kmscon_symbol_table_unref(ui->st);
|
|
||||||
kmscon_input_unref(ui->input);
|
kmscon_input_unref(ui->input);
|
||||||
uterm_video_unref(ui->video);
|
uterm_video_unref(ui->video);
|
||||||
ev_eloop_unref(ui->eloop);
|
ev_eloop_unref(ui->eloop);
|
||||||
|
246
src/unicode.c
246
src/unicode.c
@ -2,7 +2,7 @@
|
|||||||
* kmscon - Unicode Handling
|
* kmscon - Unicode Handling
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
|
* Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
|
||||||
* Copyright (c) 2011 University of Tuebingen
|
* Copyright (c) 2011-2012 University of Tuebingen
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
* a copy of this software and associated documentation files
|
* a copy of this software and associated documentation files
|
||||||
@ -64,9 +64,12 @@
|
|||||||
* push the new symbol into the symbol table.
|
* push the new symbol into the symbol table.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* TODO: Remove the glib dependencies */
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -81,12 +84,10 @@
|
|||||||
const kmscon_symbol_t kmscon_symbol_default = 0;
|
const kmscon_symbol_t kmscon_symbol_default = 0;
|
||||||
static const char default_u8[] = { 0 };
|
static const char default_u8[] = { 0 };
|
||||||
|
|
||||||
struct kmscon_symbol_table {
|
static pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
unsigned long ref;
|
static uint32_t table_next_id;
|
||||||
GArray *index;
|
static GArray *table_index;
|
||||||
GHashTable *symbols;
|
static GHashTable *table_symbols;
|
||||||
uint32_t next_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
static guint hash_ucs4(gconstpointer key)
|
static guint hash_ucs4(gconstpointer key)
|
||||||
{
|
{
|
||||||
@ -126,66 +127,43 @@ static gboolean cmp_ucs4(gconstpointer a, gconstpointer b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int kmscon_symbol_table_new(struct kmscon_symbol_table **out)
|
static void table_lock()
|
||||||
|
{
|
||||||
|
pthread_mutex_lock(&table_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void table_unlock()
|
||||||
|
{
|
||||||
|
pthread_mutex_unlock(&table_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int table__init()
|
||||||
{
|
{
|
||||||
struct kmscon_symbol_table *st;
|
|
||||||
int ret;
|
|
||||||
static const uint32_t *val = NULL; /* we need an lvalue for glib */
|
static const uint32_t *val = NULL; /* we need an lvalue for glib */
|
||||||
|
|
||||||
if (!out)
|
if (table_symbols)
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
st = malloc(sizeof(*st));
|
|
||||||
if (!st)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
memset(st, 0, sizeof(*st));
|
|
||||||
st->ref = 1;
|
|
||||||
st->next_id = KMSCON_UCS4_MAX + 2;
|
|
||||||
|
|
||||||
st->index = g_array_new(FALSE, TRUE, sizeof(uint32_t*));
|
|
||||||
if (!st->index) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_free;
|
|
||||||
}
|
|
||||||
g_array_append_val(st->index, val);
|
|
||||||
|
|
||||||
st->symbols = g_hash_table_new_full(hash_ucs4, cmp_ucs4,
|
|
||||||
(GDestroyNotify) free, NULL);
|
|
||||||
if (!st->symbols) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
goto err_arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
*out = st;
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_arr:
|
table_next_id = KMSCON_UCS4_MAX + 2;
|
||||||
g_array_unref(st->index);
|
|
||||||
err_free:
|
|
||||||
free(st);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kmscon_symbol_table_ref(struct kmscon_symbol_table *st)
|
table_index = g_array_new(FALSE, TRUE, sizeof(uint32_t*));
|
||||||
{
|
if (!table_index) {
|
||||||
if (!st)
|
log_err("cannot allocate table-index");
|
||||||
return;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
++st->ref;
|
/* first entry is not used so add dummy */
|
||||||
}
|
g_array_append_val(table_index, val);
|
||||||
|
|
||||||
void kmscon_symbol_table_unref(struct kmscon_symbol_table *st)
|
table_symbols = g_hash_table_new_full(hash_ucs4, cmp_ucs4,
|
||||||
{
|
(GDestroyNotify) free, NULL);
|
||||||
if (!st || !st->ref)
|
if (!table_symbols) {
|
||||||
return;
|
log_err("cannot allocate hash-table");
|
||||||
|
g_array_unref(table_index);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
if (--st->ref)
|
return 0;
|
||||||
return;
|
|
||||||
|
|
||||||
g_hash_table_unref(st->symbols);
|
|
||||||
g_array_unref(st->index);
|
|
||||||
free(st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kmscon_symbol_t kmscon_symbol_make(uint32_t ucs4)
|
kmscon_symbol_t kmscon_symbol_make(uint32_t ucs4)
|
||||||
@ -198,47 +176,6 @@ kmscon_symbol_t kmscon_symbol_make(uint32_t ucs4)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kmscon_symbol_t kmscon_symbol_append(struct kmscon_symbol_table *st,
|
|
||||||
kmscon_symbol_t sym, uint32_t ucs4)
|
|
||||||
{
|
|
||||||
uint32_t buf[KMSCON_UCS4_MAXLEN + 1], nsym, *nval;
|
|
||||||
const uint32_t *ptr;
|
|
||||||
size_t s;
|
|
||||||
|
|
||||||
if (!st)
|
|
||||||
return sym;
|
|
||||||
|
|
||||||
if (ucs4 > KMSCON_UCS4_MAX) {
|
|
||||||
log_warn("invalid ucs4 character");
|
|
||||||
return sym;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = kmscon_symbol_get(st, &sym, &s);
|
|
||||||
if (s >= KMSCON_UCS4_MAXLEN)
|
|
||||||
return sym;
|
|
||||||
|
|
||||||
memcpy(buf, ptr, s * sizeof(uint32_t));
|
|
||||||
buf[s++] = ucs4;
|
|
||||||
buf[s++] = KMSCON_UCS4_MAX + 1;
|
|
||||||
|
|
||||||
nsym = GPOINTER_TO_UINT(g_hash_table_lookup(st->symbols, buf));
|
|
||||||
if (nsym)
|
|
||||||
return nsym;
|
|
||||||
|
|
||||||
log_debug("adding new composed symbol");
|
|
||||||
|
|
||||||
nval = malloc(sizeof(uint32_t) * s);
|
|
||||||
if (!nval)
|
|
||||||
return sym;
|
|
||||||
|
|
||||||
memcpy(nval, buf, s * sizeof(uint32_t));
|
|
||||||
nsym = st->next_id++;
|
|
||||||
g_hash_table_insert(st->symbols, nval, GUINT_TO_POINTER(nsym));
|
|
||||||
g_array_append_val(st->index, nval);
|
|
||||||
|
|
||||||
return nsym;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This decomposes a symbol into a ucs4 string and a size value. If \sym is a
|
* This decomposes a symbol into a ucs4 string and a size value. If \sym is a
|
||||||
* valid UCS4 character, this returns a pointer to \sym and writes 1 into \size.
|
* valid UCS4 character, this returns a pointer to \sym and writes 1 into \size.
|
||||||
@ -250,8 +187,7 @@ kmscon_symbol_t kmscon_symbol_append(struct kmscon_symbol_table *st,
|
|||||||
* This always returns a valid value. If an error happens, the default character
|
* 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.
|
* is returned. If \size is NULL, then the size value is omitted.
|
||||||
*/
|
*/
|
||||||
const uint32_t *kmscon_symbol_get(const struct kmscon_symbol_table *st,
|
static const uint32_t *table__get(kmscon_symbol_t *sym, size_t *size)
|
||||||
kmscon_symbol_t *sym, size_t *size)
|
|
||||||
{
|
{
|
||||||
uint32_t *ucs4;
|
uint32_t *ucs4;
|
||||||
|
|
||||||
@ -261,13 +197,19 @@ const uint32_t *kmscon_symbol_get(const struct kmscon_symbol_table *st,
|
|||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!st)
|
if (table__init()) {
|
||||||
goto def_value;
|
if (size)
|
||||||
|
*size = 1;
|
||||||
|
return &kmscon_symbol_default;
|
||||||
|
}
|
||||||
|
|
||||||
ucs4 = g_array_index(st->index, uint32_t*,
|
ucs4 = g_array_index(table_index, uint32_t*,
|
||||||
*sym - (KMSCON_UCS4_MAX + 1));
|
*sym - (KMSCON_UCS4_MAX + 1));
|
||||||
if (!ucs4)
|
if (!ucs4) {
|
||||||
goto def_value;
|
if (size)
|
||||||
|
*size = 1;
|
||||||
|
return &kmscon_symbol_default;
|
||||||
|
}
|
||||||
|
|
||||||
if (size) {
|
if (size) {
|
||||||
*size = 0;
|
*size = 0;
|
||||||
@ -276,35 +218,91 @@ const uint32_t *kmscon_symbol_get(const struct kmscon_symbol_table *st,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return ucs4;
|
return ucs4;
|
||||||
|
|
||||||
def_value:
|
|
||||||
if (size)
|
|
||||||
*size = 1;
|
|
||||||
return &kmscon_symbol_default;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *kmscon_symbol_get_u8(const struct kmscon_symbol_table *st,
|
const uint32_t *kmscon_symbol_get(kmscon_symbol_t *sym, size_t *size)
|
||||||
kmscon_symbol_t sym, size_t *size)
|
{
|
||||||
|
const uint32_t *res;
|
||||||
|
|
||||||
|
table_lock();
|
||||||
|
res = table__get(sym, size);
|
||||||
|
table_unlock();
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmscon_symbol_t kmscon_symbol_append(kmscon_symbol_t sym, uint32_t ucs4)
|
||||||
|
{
|
||||||
|
uint32_t buf[KMSCON_UCS4_MAXLEN + 1], nsym, *nval;
|
||||||
|
const uint32_t *ptr;
|
||||||
|
size_t s;
|
||||||
|
kmscon_symbol_t rsym;
|
||||||
|
|
||||||
|
table_lock();
|
||||||
|
|
||||||
|
if (table__init()) {
|
||||||
|
rsym = sym;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ucs4 > KMSCON_UCS4_MAX) {
|
||||||
|
log_warn("invalid ucs4 character");
|
||||||
|
rsym = sym;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = table__get(&sym, &s);
|
||||||
|
if (s >= KMSCON_UCS4_MAXLEN) {
|
||||||
|
rsym = sym;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(buf, ptr, s * sizeof(uint32_t));
|
||||||
|
buf[s++] = ucs4;
|
||||||
|
buf[s++] = KMSCON_UCS4_MAX + 1;
|
||||||
|
|
||||||
|
nsym = GPOINTER_TO_UINT(g_hash_table_lookup(table_symbols, buf));
|
||||||
|
if (nsym) {
|
||||||
|
rsym = nsym;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug("adding new composed symbol");
|
||||||
|
|
||||||
|
nval = malloc(sizeof(uint32_t) * s);
|
||||||
|
if (!nval) {
|
||||||
|
rsym = sym;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(nval, buf, s * sizeof(uint32_t));
|
||||||
|
nsym = table_next_id++;
|
||||||
|
g_hash_table_insert(table_symbols, nval, GUINT_TO_POINTER(nsym));
|
||||||
|
g_array_append_val(table_index, nval);
|
||||||
|
rsym = nsym;
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
table_unlock();
|
||||||
|
return rsym;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *kmscon_symbol_get_u8(kmscon_symbol_t sym, size_t *size)
|
||||||
{
|
{
|
||||||
const uint32_t *ucs4;
|
const uint32_t *ucs4;
|
||||||
gchar *val;
|
gchar *val;
|
||||||
glong len;
|
glong len;
|
||||||
|
|
||||||
if (!st)
|
ucs4 = kmscon_symbol_get(&sym, size);
|
||||||
goto def_value;
|
|
||||||
|
|
||||||
ucs4 = kmscon_symbol_get(st, &sym, size);
|
|
||||||
val = g_ucs4_to_utf8(ucs4, *size, NULL, &len, NULL);
|
val = g_ucs4_to_utf8(ucs4, *size, NULL, &len, NULL);
|
||||||
if (!val || len < 0)
|
if (!val || len < 0) {
|
||||||
goto def_value;
|
|
||||||
|
|
||||||
*size = len;
|
|
||||||
return val;
|
|
||||||
|
|
||||||
def_value:
|
|
||||||
if (size)
|
if (size)
|
||||||
*size = 1;
|
*size = 1;
|
||||||
return default_u8;
|
return default_u8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
*size = len;
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void kmscon_symbol_free_u8(const char *s)
|
void kmscon_symbol_free_u8(const char *s)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* kmscon - Unicode Handling
|
* kmscon - Unicode Handling
|
||||||
*
|
*
|
||||||
* Copyright (c) 2011 David Herrmann <dh.herrmann@googlemail.com>
|
* Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
|
||||||
* Copyright (c) 2011 University of Tuebingen
|
* Copyright (c) 2011 University of Tuebingen
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining
|
* Permission is hereby granted, free of charge, to any person obtaining
|
||||||
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Unicode Handling
|
* Unicode Handling
|
||||||
* The main goal of the symbol(_table) functions is to provide a datatype which
|
* The main goal of the kmscon_symbol_* functions is to provide a datatype which
|
||||||
* can contain the representation of any printable character. This includes all
|
* can contain the representation of any printable character. This includes all
|
||||||
* basic Unicode characters but also combined characters.
|
* basic Unicode characters but also combined characters.
|
||||||
* To avoid all the memory management we still represent a character as a single
|
* To avoid all the memory management we still represent a character as a single
|
||||||
@ -38,7 +38,7 @@
|
|||||||
* every UCS4 characters is a valid kmscon_symbol_t object.
|
* every UCS4 characters is a valid kmscon_symbol_t object.
|
||||||
* However, Unicode standard allows combining marks. Therefore, some characters
|
* However, Unicode standard allows combining marks. Therefore, some characters
|
||||||
* consists of more than one Unicode character.
|
* consists of more than one Unicode character.
|
||||||
* A kmscon_symbol_table object provides all those combined characters as single
|
* A global symbol-table provides all those combined characters as single
|
||||||
* integers. You simply create a valid base character and append your combining
|
* integers. You simply create a valid base character and append your combining
|
||||||
* marks and the table will return a new valid kmscon_symbol_t. It is no longer
|
* marks and the table will return a new valid kmscon_symbol_t. It is no longer
|
||||||
* a valid UCS4 value, though. But no memory management is needed as all
|
* a valid UCS4 value, though. But no memory management is needed as all
|
||||||
@ -51,24 +51,16 @@
|
|||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/* symbols and symbol table */
|
/* symbols */
|
||||||
|
|
||||||
struct kmscon_symbol_table;
|
|
||||||
typedef uint32_t kmscon_symbol_t;
|
typedef uint32_t kmscon_symbol_t;
|
||||||
|
|
||||||
extern const kmscon_symbol_t kmscon_symbol_default;
|
extern const kmscon_symbol_t kmscon_symbol_default;
|
||||||
|
|
||||||
int kmscon_symbol_table_new(struct kmscon_symbol_table **out);
|
|
||||||
void kmscon_symbol_table_ref(struct kmscon_symbol_table *st);
|
|
||||||
void kmscon_symbol_table_unref(struct kmscon_symbol_table *st);
|
|
||||||
|
|
||||||
kmscon_symbol_t kmscon_symbol_make(uint32_t ucs4);
|
kmscon_symbol_t kmscon_symbol_make(uint32_t ucs4);
|
||||||
kmscon_symbol_t kmscon_symbol_append(struct kmscon_symbol_table *st,
|
kmscon_symbol_t kmscon_symbol_append(kmscon_symbol_t sym, uint32_t ucs4);
|
||||||
kmscon_symbol_t sym, uint32_t ucs4);
|
const uint32_t *kmscon_symbol_get(kmscon_symbol_t *sym, size_t *size);
|
||||||
const uint32_t *kmscon_symbol_get(const struct kmscon_symbol_table *st,
|
const char *kmscon_symbol_get_u8(kmscon_symbol_t sym, size_t *size);
|
||||||
kmscon_symbol_t *sym, size_t *size);
|
|
||||||
const char *kmscon_symbol_get_u8(const struct kmscon_symbol_table *st,
|
|
||||||
kmscon_symbol_t sym, size_t *size);
|
|
||||||
void kmscon_symbol_free_u8(const char *s);
|
void kmscon_symbol_free_u8(const char *s);
|
||||||
|
|
||||||
/* utf8 state machine */
|
/* utf8 state machine */
|
||||||
|
@ -104,7 +104,6 @@ enum parser_action {
|
|||||||
|
|
||||||
struct kmscon_vte {
|
struct kmscon_vte {
|
||||||
unsigned long ref;
|
unsigned long ref;
|
||||||
struct kmscon_symbol_table *st;
|
|
||||||
struct kmscon_console *con;
|
struct kmscon_console *con;
|
||||||
|
|
||||||
const char *kbd_sym;
|
const char *kbd_sym;
|
||||||
@ -115,7 +114,7 @@ struct kmscon_vte {
|
|||||||
int csi_argv[CSI_ARG_MAX];
|
int csi_argv[CSI_ARG_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_symbol_table *st)
|
int kmscon_vte_new(struct kmscon_vte **out)
|
||||||
{
|
{
|
||||||
struct kmscon_vte *vte;
|
struct kmscon_vte *vte;
|
||||||
int ret;
|
int ret;
|
||||||
@ -131,14 +130,12 @@ int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_symbol_table *st)
|
|||||||
|
|
||||||
memset(vte, 0, sizeof(*vte));
|
memset(vte, 0, sizeof(*vte));
|
||||||
vte->ref = 1;
|
vte->ref = 1;
|
||||||
vte->st = st;
|
|
||||||
vte->state = STATE_GROUND;
|
vte->state = STATE_GROUND;
|
||||||
|
|
||||||
ret = kmscon_utf8_mach_new(&vte->mach);
|
ret = kmscon_utf8_mach_new(&vte->mach);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
kmscon_symbol_table_ref(vte->st);
|
|
||||||
*out = vte;
|
*out = vte;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -166,7 +163,6 @@ void kmscon_vte_unref(struct kmscon_vte *vte)
|
|||||||
kmscon_console_unref(vte->con);
|
kmscon_console_unref(vte->con);
|
||||||
kmscon_utf8_mach_free(vte->mach);
|
kmscon_utf8_mach_free(vte->mach);
|
||||||
kmscon_symbol_free_u8(vte->kbd_sym);
|
kmscon_symbol_free_u8(vte->kbd_sym);
|
||||||
kmscon_symbol_table_unref(vte->st);
|
|
||||||
free(vte);
|
free(vte);
|
||||||
log_debug("vte: destroying vte object\n");
|
log_debug("vte: destroying vte object\n");
|
||||||
}
|
}
|
||||||
@ -926,7 +922,7 @@ int kmscon_vte_handle_keyboard(struct kmscon_vte *vte,
|
|||||||
if (ev->unicode != KMSCON_INPUT_INVALID) {
|
if (ev->unicode != KMSCON_INPUT_INVALID) {
|
||||||
kmscon_symbol_free_u8(vte->kbd_sym);
|
kmscon_symbol_free_u8(vte->kbd_sym);
|
||||||
sym = kmscon_symbol_make(ev->unicode);
|
sym = kmscon_symbol_make(ev->unicode);
|
||||||
vte->kbd_sym = kmscon_symbol_get_u8(vte->st, sym, len);
|
vte->kbd_sym = kmscon_symbol_get_u8(sym, len);
|
||||||
*u8 = vte->kbd_sym;
|
*u8 = vte->kbd_sym;
|
||||||
return KMSCON_VTE_SEND;
|
return KMSCON_VTE_SEND;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ enum kmscon_vte_keyboard_action {
|
|||||||
KMSCON_VTE_SEND,
|
KMSCON_VTE_SEND,
|
||||||
};
|
};
|
||||||
|
|
||||||
int kmscon_vte_new(struct kmscon_vte **out, struct kmscon_symbol_table *st);
|
int kmscon_vte_new(struct kmscon_vte **out);
|
||||||
void kmscon_vte_ref(struct kmscon_vte *vte);
|
void kmscon_vte_ref(struct kmscon_vte *vte);
|
||||||
void kmscon_vte_unref(struct kmscon_vte *vte);
|
void kmscon_vte_unref(struct kmscon_vte *vte);
|
||||||
|
|
||||||
|
@ -102,34 +102,26 @@ static void test1(struct kmscon_buffer *buf)
|
|||||||
|
|
||||||
static void test2()
|
static void test2()
|
||||||
{
|
{
|
||||||
struct kmscon_symbol_table *st;
|
|
||||||
int ret;
|
|
||||||
kmscon_symbol_t sym, sym2, sym3, sym4;
|
kmscon_symbol_t sym, sym2, sym3, sym4;
|
||||||
const uint32_t *str;
|
const uint32_t *str;
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
|
|
||||||
log_info("Test2:\n");
|
log_info("Test2:\n");
|
||||||
|
|
||||||
ret = kmscon_symbol_table_new(&st);
|
|
||||||
if (ret)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sym = kmscon_symbol_make('a');
|
sym = kmscon_symbol_make('a');
|
||||||
sym2 = kmscon_symbol_append(st, sym, '^');
|
sym2 = kmscon_symbol_append(sym, '^');
|
||||||
sym3 = kmscon_symbol_append(st, sym2, '^');
|
sym3 = kmscon_symbol_append(sym2, '^');
|
||||||
sym4 = kmscon_symbol_append(st, sym, '^');
|
sym4 = kmscon_symbol_append(sym, '^');
|
||||||
|
|
||||||
log_info("equality: %i %i %i\n", sym == sym2, sym2 == sym4,
|
log_info("equality: %i %i %i\n", sym == sym2, sym2 == sym4,
|
||||||
sym3 == sym2);
|
sym3 == sym2);
|
||||||
|
|
||||||
str = kmscon_symbol_get(st, &sym3, &len);
|
str = kmscon_symbol_get(&sym3, &len);
|
||||||
|
|
||||||
printf("sym3: ");
|
printf("sym3: ");
|
||||||
for (i = 0; i < len; ++i)
|
for (i = 0; i < len; ++i)
|
||||||
printf("%c", str[i]);
|
printf("%c", str[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
kmscon_symbol_table_unref(st);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test3()
|
static void test3()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user