#include <stdlib.h>
#include "unicode.h"
-struct kmscon_char;
struct kmscon_font;
struct kmscon_buffer;
struct kmscon_console;
-/* single printable characters */
-
-int kmscon_char_new(struct kmscon_char **out);
-int kmscon_char_new_u8(struct kmscon_char **out, const char *str, size_t len);
-int kmscon_char_new_ucs4(struct kmscon_char **out, const uint32_t *str,
- size_t len);
-int kmscon_char_dup(struct kmscon_char **out, const struct kmscon_char *orig);
-void kmscon_char_free(struct kmscon_char *ch);
-void kmscon_char_reset(struct kmscon_char *ch);
-
-int kmscon_char_set(struct kmscon_char *ch, const struct kmscon_char *orig);
-int kmscon_char_set_u8(struct kmscon_char *ch, const char *str, size_t len);
-int kmscon_char_set_ucs4(struct kmscon_char *ch, const uint32_t *str,
- size_t len);
-const char *kmscon_char_get_u8(const struct kmscon_char *ch);
-size_t kmscon_char_get_len(const struct kmscon_char *ch);
-int kmscon_char_append_u8(struct kmscon_char *ch, const char *str, size_t len);
-
/* font objects with cached glyphs */
int kmscon_font_new(struct kmscon_font **out, unsigned int height,
#include "log.h"
#include "unicode.h"
-/* maximum size of a single character */
-#define KMSCON_CHAR_SIZE 6
-
-struct kmscon_char {
- char *buf;
- size_t size;
- size_t len;
-};
-
enum glyph_type {
GLYPH_NONE,
GLYPH_LAYOUT,
static int kmscon_font_lookup(struct kmscon_font *font, kmscon_symbol_t key,
struct kmscon_glyph **out);
-static int new_char(struct kmscon_char **out, size_t size)
-{
- struct kmscon_char *ch;
-
- if (!out)
- return -EINVAL;
-
- if (!size)
- size = KMSCON_CHAR_SIZE;
-
- ch = malloc(sizeof(*ch));
- if (!ch)
- return -ENOMEM;
-
- memset(ch, 0, sizeof(*ch));
-
- ch->size = size;
- ch->buf = malloc(ch->size);
- if (!ch->buf) {
- free(ch);
- return -ENOMEM;
- }
-
- memset(ch->buf, 0, ch->size);
-
- *out = ch;
- return 0;
-}
-
-int kmscon_char_new(struct kmscon_char **out)
-{
- return new_char(out, 0);
-}
-
-int kmscon_char_new_u8(struct kmscon_char **out, const char *str, size_t len)
-{
- int ret;
- struct kmscon_char *ch;
-
- if (!len)
- return kmscon_char_new(out);
-
- if (!out || !str)
- return -EINVAL;
-
- ret = new_char(&ch, len);
- if (ret)
- return ret;
-
- ret = kmscon_char_set_u8(ch, str, len);
- if (ret) {
- kmscon_char_free(ch);
- return ret;
- }
-
- *out = ch;
- return 0;
-}
-
-int kmscon_char_new_ucs4(struct kmscon_char **out, const uint32_t *str,
- size_t len)
-{
- int ret;
- struct kmscon_char *ch;
- char *str8;
- glong siz;
-
- if (!len)
- return kmscon_char_new(out);
-
- if (!out || !str)
- return -EINVAL;
-
- str8 = g_ucs4_to_utf8(str, len, NULL, &siz, NULL);
- if (!str8 || siz < 0)
- return -EFAULT;
-
- ret = new_char(&ch, siz);
- if (ret)
- goto err_free;
-
- ret = kmscon_char_set_u8(ch, str8, siz);
- if (ret)
- goto err_char;
-
- g_free(str8);
- *out = ch;
-
- return 0;
-
-err_char:
- kmscon_char_free(ch);
-err_free:
- g_free(str8);
- return ret;
-}
-
-int kmscon_char_dup(struct kmscon_char **out, const struct kmscon_char *orig)
-{
- struct kmscon_char *ch;
- int ret;
-
- if (!out || !orig)
- return -EINVAL;
-
- ret = new_char(&ch, orig->size);
- if (ret)
- return ret;
-
- ret = kmscon_char_set_u8(ch, orig->buf, orig->len);
- if (ret) {
- kmscon_char_free(ch);
- return ret;
- }
-
- *out = ch;
- return 0;
-}
-
-void kmscon_char_free(struct kmscon_char *ch)
-{
- if (!ch)
- return;
-
- free(ch->buf);
- free(ch);
-}
-
-void kmscon_char_reset(struct kmscon_char *ch)
-{
- if (!ch)
- return;
-
- ch->len = 0;
-}
-
-int kmscon_char_set(struct kmscon_char *ch, const struct kmscon_char *orig)
-{
- return kmscon_char_set_u8(ch, orig->buf, orig->len);
-}
-
-int kmscon_char_set_u8(struct kmscon_char *ch, const char *str, size_t len)
-{
- char *buf;
-
- if (!ch)
- return -EINVAL;
-
- if (ch->size < len) {
- buf = realloc(ch->buf, len);
- if (!buf)
- return -ENOMEM;
- ch->buf = buf;
- ch->size = len;
- }
-
- memcpy(ch->buf, str, len);
- ch->len = len;
-
- return 0;
-}
-
-int kmscon_char_set_ucs4(struct kmscon_char *ch, const uint32_t *str,
- size_t len)
-{
- char *str8;
- glong siz;
- int ret;
-
- if (!ch)
- return -EINVAL;
-
- str8 = g_ucs4_to_utf8(str, len, NULL, &siz, NULL);
- if (!str8 || siz < 0) {
- g_free(str8);
- return -EFAULT;
- }
-
- ret = kmscon_char_set_u8(ch, str8, siz);
- g_free(str8);
-
- return ret;
-}
-
-const char *kmscon_char_get_u8(const struct kmscon_char *ch)
-{
- if (!ch)
- return NULL;
-
- return ch->buf;
-}
-
-size_t kmscon_char_get_len(const struct kmscon_char *ch)
-{
- if (!ch)
- return 0;
-
- return ch->len;
-}
-
-int kmscon_char_append_u8(struct kmscon_char *ch, const char *str, size_t len)
-{
- char *buf;
- size_t nlen;
-
- if (!ch)
- return -EINVAL;
-
- nlen = ch->len + len;
-
- if (ch->size < nlen) {
- buf = realloc(ch->buf, nlen);
- if (!buf)
- return -EINVAL;
- ch->buf = buf;
- ch->size = nlen;
- }
-
- memcpy(&ch->buf[ch->len], str, len);
- ch->len += len;
-
- return 0;
-}
-
/*
* Glyphs
* Glyphs are for internal use only! The outside world uses kmscon_char