示例#1
0
文件: tsm_screen.c 项目: carld/libtsm
SHL_EXPORT
int tsm_screen_new(struct tsm_screen **out, tsm_log_t log, void *log_data)
{
	struct tsm_screen *con;
	int ret;
	unsigned int i;

	if (!out)
		return -EINVAL;

	con = malloc(sizeof(*con));
	if (!con)
		return -ENOMEM;

	memset(con, 0, sizeof(*con));
	con->ref = 1;
	con->llog = log;
	con->llog_data = log_data;
	con->age_cnt = 1;
	con->age = con->age_cnt;
	con->def_attr.fr = 255;
	con->def_attr.fg = 255;
	con->def_attr.fb = 255;

	ret = tsm_symbol_table_new(&con->sym_table);
	if (ret)
		goto err_free;

	ret = tsm_screen_resize(con, 80, 24);
	if (ret)
		goto err_free;

	llog_debug(con, "new screen");
	*out = con;

	return 0;

err_free:
	for (i = 0; i < con->line_num; ++i) {
		line_free(con->main_lines[i]);
		line_free(con->alt_lines[i]);
	}
	free(con->main_lines);
	free(con->alt_lines);
	free(con->tab_ruler);
	tsm_symbol_table_unref(con->sym_table);
	free(con);
	return ret;
}
示例#2
0
/*
 * 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.
 * Therefore, the returned value may get destroyed if your \sym argument gets
 * destroyed.
 * If \sym is a composed ucs4 string, then the returned value points into the
 * hash table of the symbol table and lives as long as the symbol table does.
 *
 * 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.
 */
SHL_EXPORT
const uint32_t *tsm_symbol_get(struct tsm_symbol_table *tbl,
			       tsm_symbol_t *sym, size_t *size)
{
	uint32_t *ucs4, idx;
	int ret;

	if (*sym <= TSM_UCS4_MAX) {
		if (size)
			*size = 1;
		return sym;
	}

	if (!tbl)
		tbl = tsm_symbol_table_default;

	if (!tbl) {
		ret = tsm_symbol_table_new(&tbl);
		if (ret) {
			if (size)
				*size = 1;
			return &tsm_symbol_default;
		}
		tsm_symbol_table_default = tbl;
	}

	idx = *sym - (TSM_UCS4_MAX + 1);
	if (idx >= shl_array_get_length(tbl->index))
		ucs4 = NULL;
	else
		ucs4 = *SHL_ARRAY_AT(tbl->index, uint32_t*, idx);

	if (!ucs4) {
		if (size)
			*size = 1;
		return &tsm_symbol_default;
	}

	if (size) {
		*size = 0;
		while (ucs4[*size] <= TSM_UCS4_MAX)
			++*size;
	}

	return ucs4;
}
示例#3
0
SHL_EXPORT
unsigned int tsm_symbol_get_width(struct tsm_symbol_table *tbl,
				  tsm_symbol_t sym)
{
	int ret;
	const uint32_t *ch;
	size_t len;

	if (!tbl)
		tbl = tsm_symbol_table_default;

	if (!tbl) {
		ret = tsm_symbol_table_new(&tbl);
		if (ret)
			return sym;
		tsm_symbol_table_default = tbl;
	}

	ch = tsm_symbol_get(tbl, &sym, &len);
	if (len == 0)
		return 0;

	return tsm_ucs4_get_width(*ch);
}
示例#4
0
SHL_EXPORT
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;
	size_t s;
	void *tmp;
	bool res;
	int ret;

	if (!tbl)
		tbl = tsm_symbol_table_default;

	if (!tbl) {
		ret = tsm_symbol_table_new(&tbl);
		if (ret)
			return sym;
		tsm_symbol_table_default = tbl;
	}

	if (ucs4 > TSM_UCS4_MAX)
		return sym;

	ptr = tsm_symbol_get(tbl, &sym, &s);
	if (s >= TSM_UCS4_MAXLEN)
		return sym;

	memcpy(buf, ptr, s * sizeof(uint32_t));
	buf[s++] = ucs4;
	buf[s++] = TSM_UCS4_MAX + 1;

	res = shl_hashtable_find(tbl->symbols, &tmp, buf);
	if (res)
		return (uint32_t)(long)tmp;

	nval = malloc(sizeof(uint32_t) * s);
	if (!nval)
		return sym;

	memcpy(nval, buf, s * sizeof(uint32_t));
	nsym = tbl->next_id + 1;
	/* Out of IDs; we actually have 2 Billion IDs so this seems
	 * very unlikely but lets be safe here */
	if (nsym <= tbl->next_id++)
		goto err_id;

	ret = shl_hashtable_insert(tbl->symbols, nval, (void*)(long)nsym);
	if (ret)
		goto err_id;

	ret = shl_array_push(tbl->index, &nval);
	if (ret)
		goto err_symbol;

	return nsym;

err_symbol:
	shl_hashtable_remove(tbl->symbols, nval);
err_id:
	--tbl->next_id;
	free(nval);
	return sym;
}