/*
 * SPDX-License-Identifier: MIT
 * QEMU VC
 */
#include "qemu/osdep.h"

#include "chardev/char.h"
#include "qapi/error.h"
#include "qemu/fifo8.h"
#include "qemu/option.h"
#include "ui/console.h"

#include "trace.h"
#include "console-priv.h"

#define DEFAULT_BACKSCROLL 512
#define CONSOLE_CURSOR_PERIOD 500

typedef struct TextAttributes {
    uint8_t fgcol:4;
    uint8_t bgcol:4;
    uint8_t bold:1;
    uint8_t uline:1;
    uint8_t blink:1;
    uint8_t invers:1;
    uint8_t unvisible:1;
} TextAttributes;

#define TEXT_ATTRIBUTES_DEFAULT ((TextAttributes) { \
    .fgcol = QEMU_COLOR_WHITE,                      \
    .bgcol = QEMU_COLOR_BLACK                       \
})

typedef struct TextCell {
    uint8_t ch;
    TextAttributes t_attrib;
} TextCell;

#define MAX_ESC_PARAMS 3

enum TTYState {
    TTY_STATE_NORM,
    TTY_STATE_ESC,
    TTY_STATE_CSI,
    TTY_STATE_G0,
    TTY_STATE_G1,
};

typedef struct QemuTextConsole {
    QemuConsole parent;

    int width;
    int height;
    int total_height;
    int backscroll_height;
    int x, y;
    int y_displayed;
    int y_base;
    TextCell *cells;
    int text_x[2], text_y[2], cursor_invalidate;
    int echo;

    int update_x0;
    int update_y0;
    int update_x1;
    int update_y1;

    Chardev *chr;
    /* fifo for key pressed */
    Fifo8 out_fifo;
} QemuTextConsole;

typedef QemuConsoleClass QemuTextConsoleClass;

OBJECT_DEFINE_TYPE(QemuTextConsole, qemu_text_console, QEMU_TEXT_CONSOLE, QEMU_CONSOLE)

typedef struct QemuFixedTextConsole {
    QemuTextConsole parent;
} QemuFixedTextConsole;

typedef QemuTextConsoleClass QemuFixedTextConsoleClass;

OBJECT_DEFINE_TYPE(QemuFixedTextConsole, qemu_fixed_text_console, QEMU_FIXED_TEXT_CONSOLE, QEMU_TEXT_CONSOLE)

struct VCChardev {
    Chardev parent;
    QemuTextConsole *console;

    enum TTYState state;
    int esc_params[MAX_ESC_PARAMS];
    int nb_esc_params;
    TextAttributes t_attrib; /* currently active text attributes */
    TextAttributes t_attrib_saved;
    int x_saved, y_saved;
};
typedef struct VCChardev VCChardev;

static const pixman_color_t color_table_rgb[2][8] = {
    {   /* dark */
        [QEMU_COLOR_BLACK]   = QEMU_PIXMAN_COLOR_BLACK,
        [QEMU_COLOR_BLUE]    = QEMU_PIXMAN_COLOR(0x00, 0x00, 0xaa),  /* blue */
        [QEMU_COLOR_GREEN]   = QEMU_PIXMAN_COLOR(0x00, 0xaa, 0x00),  /* green */
        [QEMU_COLOR_CYAN]    = QEMU_PIXMAN_COLOR(0x00, 0xaa, 0xaa),  /* cyan */
        [QEMU_COLOR_RED]     = QEMU_PIXMAN_COLOR(0xaa, 0x00, 0x00),  /* red */
        [QEMU_COLOR_MAGENTA] = QEMU_PIXMAN_COLOR(0xaa, 0x00, 0xaa),  /* magenta */
        [QEMU_COLOR_YELLOW]  = QEMU_PIXMAN_COLOR(0xaa, 0xaa, 0x00),  /* yellow */
        [QEMU_COLOR_WHITE]   = QEMU_PIXMAN_COLOR_GRAY,
    },
    {   /* bright */
        [QEMU_COLOR_BLACK]   = QEMU_PIXMAN_COLOR_BLACK,
        [QEMU_COLOR_BLUE]    = QEMU_PIXMAN_COLOR(0x00, 0x00, 0xff),  /* blue */
        [QEMU_COLOR_GREEN]   = QEMU_PIXMAN_COLOR(0x00, 0xff, 0x00),  /* green */
        [QEMU_COLOR_CYAN]    = QEMU_PIXMAN_COLOR(0x00, 0xff, 0xff),  /* cyan */
        [QEMU_COLOR_RED]     = QEMU_PIXMAN_COLOR(0xff, 0x00, 0x00),  /* red */
        [QEMU_COLOR_MAGENTA] = QEMU_PIXMAN_COLOR(0xff, 0x00, 0xff),  /* magenta */
        [QEMU_COLOR_YELLOW]  = QEMU_PIXMAN_COLOR(0xff, 0xff, 0x00),  /* yellow */
        [QEMU_COLOR_WHITE]   = QEMU_PIXMAN_COLOR(0xff, 0xff, 0xff),  /* white */
    }
};

static bool cursor_visible_phase;
static QEMUTimer *cursor_timer;

const char *
qemu_text_console_get_label(QemuTextConsole *c)
{
    return c->chr ? c->chr->label : NULL;
}

static void qemu_console_fill_rect(QemuConsole *con, int posx, int posy,
                                   int width, int height, pixman_color_t color)
{
    DisplaySurface *surface = qemu_console_surface(con);
    pixman_rectangle16_t rect = {
        .x = posx, .y = posy, .width = width, .height = height
    };

    assert(surface);
    pixman_image_fill_rectangles(PIXMAN_OP_SRC, surface->image,
                                 &color, 1, &rect);
}

/* copy from (xs, ys) to (xd, yd) a rectangle of size (w, h) */
static void qemu_console_bitblt(QemuConsole *con,
                                int xs, int ys, int xd, int yd, int w, int h)
{
    DisplaySurface *surface = qemu_console_surface(con);

    assert(surface);
    pixman_image_composite(PIXMAN_OP_SRC,
                           surface->image, NULL, surface->image,
                           xs, ys, 0, 0, xd, yd, w, h);
}

static void vga_putcharxy(QemuConsole *s, int x, int y, int ch,
                          TextAttributes *t_attrib)
{
    static pixman_image_t *glyphs[256];
    DisplaySurface *surface = qemu_console_surface(s);
    pixman_color_t fgcol, bgcol;

    assert(surface);
    if (t_attrib->invers) {
        bgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
        fgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
    } else {
        fgcol = color_table_rgb[t_attrib->bold][t_attrib->fgcol];
        bgcol = color_table_rgb[t_attrib->bold][t_attrib->bgcol];
    }

    if (!glyphs[ch]) {
        glyphs[ch] = qemu_pixman_glyph_from_vgafont(FONT_HEIGHT, vgafont16, ch);
    }
    qemu_pixman_glyph_render(glyphs[ch], surface->image,
                             &fgcol, &bgcol, x, y, FONT_WIDTH, FONT_HEIGHT);
}

static void invalidate_xy(QemuTextConsole *s, int x, int y)
{
    if (!qemu_console_is_visible(QEMU_CONSOLE(s))) {
        return;
    }
    if (s->update_x0 > x * FONT_WIDTH)
        s->update_x0 = x * FONT_WIDTH;
    if (s->update_y0 > y * FONT_HEIGHT)
        s->update_y0 = y * FONT_HEIGHT;
    if (s->update_x1 < (x + 1) * FONT_WIDTH)
        s->update_x1 = (x + 1) * FONT_WIDTH;
    if (s->update_y1 < (y + 1) * FONT_HEIGHT)
        s->update_y1 = (y + 1) * FONT_HEIGHT;
}

static void console_show_cursor(QemuTextConsole *s, int show)
{
    TextCell *c;
    int y, y1;
    int x = s->x;

    s->cursor_invalidate = 1;

    if (x >= s->width) {
        x = s->width - 1;
    }
    y1 = (s->y_base + s->y) % s->total_height;
    y = y1 - s->y_displayed;
    if (y < 0) {
        y += s->total_height;
    }
    if (y < s->height) {
        c = &s->cells[y1 * s->width + x];
        if (show && cursor_visible_phase) {
            TextAttributes t_attrib = TEXT_ATTRIBUTES_DEFAULT;
            t_attrib.invers = !(t_attrib.invers); /* invert fg and bg */
            vga_putcharxy(QEMU_CONSOLE(s), x, y, c->ch, &t_attrib);
        } else {
            vga_putcharxy(QEMU_CONSOLE(s), x, y, c->ch, &(c->t_attrib));
        }
        invalidate_xy(s, x, y);
    }
}

static void console_refresh(QemuTextConsole *s)
{
    DisplaySurface *surface = qemu_console_surface(QEMU_CONSOLE(s));
    TextCell *c;
    int x, y, y1;

    assert(surface);
    s->text_x[0] = 0;
    s->text_y[0] = 0;
    s->text_x[1] = s->width - 1;
    s->text_y[1] = s->height - 1;
    s->cursor_invalidate = 1;

    qemu_console_fill_rect(QEMU_CONSOLE(s), 0, 0, surface_width(surface), surface_height(surface),
                           color_table_rgb[0][QEMU_COLOR_BLACK]);
    y1 = s->y_displayed;
    for (y = 0; y < s->height; y++) {
        c = s->cells + y1 * s->width;
        for (x = 0; x < s->width; x++) {
            vga_putcharxy(QEMU_CONSOLE(s), x, y, c->ch,
                          &(c->t_attrib));
            c++;
        }
        if (++y1 == s->total_height) {
            y1 = 0;
        }
    }
    console_show_cursor(s, 1);
    dpy_gfx_update(QEMU_CONSOLE(s), 0, 0,
                   surface_width(surface), surface_height(surface));
}

static void console_scroll(QemuTextConsole *s, int ydelta)
{
    int i, y1;

    if (ydelta > 0) {
        for(i = 0; i < ydelta; i++) {
            if (s->y_displayed == s->y_base)
                break;
            if (++s->y_displayed == s->total_height)
                s->y_displayed = 0;
        }
    } else {
        ydelta = -ydelta;
        i = s->backscroll_height;
        if (i > s->total_height - s->height)
            i = s->total_height - s->height;
        y1 = s->y_base - i;
        if (y1 < 0)
            y1 += s->total_height;
        for(i = 0; i < ydelta; i++) {
            if (s->y_displayed == y1)
                break;
            if (--s->y_displayed < 0)
                s->y_displayed = s->total_height - 1;
        }
    }
    console_refresh(s);
}

static void kbd_send_chars(QemuTextConsole *s)
{
    uint32_t len, avail;

    len = qemu_chr_be_can_write(s->chr);
    avail = fifo8_num_used(&s->out_fifo);
    while (len > 0 && avail > 0) {
        const uint8_t *buf;
        uint32_t size;

        buf = fifo8_pop_bufptr(&s->out_fifo, MIN(len, avail), &size);
        qemu_chr_be_write(s->chr, buf, size);
        len = qemu_chr_be_can_write(s->chr);
        avail -= size;
    }
}

/* called when an ascii key is pressed */
void qemu_text_console_handle_keysym(QemuTextConsole *s, int keysym)
{
    uint8_t buf[16], *q;
    int c;
    uint32_t num_free;

    switch(keysym) {
    case QEMU_KEY_CTRL_UP:
        console_scroll(s, -1);
        break;
    case QEMU_KEY_CTRL_DOWN:
        console_scroll(s, 1);
        break;
    case QEMU_KEY_CTRL_PAGEUP:
        console_scroll(s, -10);
        break;
    case QEMU_KEY_CTRL_PAGEDOWN:
        console_scroll(s, 10);
        break;
    default:
        /* convert the QEMU keysym to VT100 key string */
        q = buf;
        if (keysym >= 0xe100 && keysym <= 0xe11f) {
            *q++ = '\033';
            *q++ = '[';
            c = keysym - 0xe100;
            if (c >= 10)
                *q++ = '0' + (c / 10);
            *q++ = '0' + (c % 10);
            *q++ = '~';
        } else if (keysym >= 0xe120 && keysym <= 0xe17f) {
            *q++ = '\033';
            *q++ = '[';
            *q++ = keysym & 0xff;
        } else if (s->echo && (keysym == '\r' || keysym == '\n')) {
            qemu_chr_write(s->chr, (uint8_t *)"\r", 1, true);
            *q++ = '\n';
        } else {
            *q++ = keysym;
        }
        if (s->echo) {
            qemu_chr_write(s->chr, buf, q - buf, true);
        }
        num_free = fifo8_num_free(&s->out_fifo);
        fifo8_push_all(&s->out_fifo, buf, MIN(num_free, q - buf));
        kbd_send_chars(s);
        break;
    }
}

static void text_console_update(void *opaque, console_ch_t *chardata)
{
    QemuTextConsole *s = QEMU_TEXT_CONSOLE(opaque);
    int i, j, src;

    if (s->text_x[0] <= s->text_x[1]) {
        src = (s->y_base + s->text_y[0]) * s->width;
        chardata += s->text_y[0] * s->width;
        for (i = s->text_y[0]; i <= s->text_y[1]; i ++)
            for (j = 0; j < s->width; j++, src++) {
                console_write_ch(chardata ++,
                                 ATTR2CHTYPE(s->cells[src].ch,
                                             s->cells[src].t_attrib.fgcol,
                                             s->cells[src].t_attrib.bgcol,
                                             s->cells[src].t_attrib.bold));
            }
        dpy_text_update(QEMU_CONSOLE(s), s->text_x[0], s->text_y[0],
                        s->text_x[1] - s->text_x[0], i - s->text_y[0]);
        s->text_x[0] = s->width;
        s->text_y[0] = s->height;
        s->text_x[1] = 0;
        s->text_y[1] = 0;
    }
    if (s->cursor_invalidate) {
        dpy_text_cursor(QEMU_CONSOLE(s), s->x, s->y);
        s->cursor_invalidate = 0;
    }
}

static void text_console_resize(QemuTextConsole *t)
{
    QemuConsole *s = QEMU_CONSOLE(t);
    TextCell *cells, *c, *c1;
    int w1, x, y, last_width, w, h;

    assert(s->scanout.kind == SCANOUT_SURFACE);

    w = surface_width(s->surface) / FONT_WIDTH;
    h = surface_height(s->surface) / FONT_HEIGHT;
    if (w == t->width && h == t->height) {
        return;
    }

    last_width = t->width;
    t->width = w;
    t->height = h;

    w1 = MIN(t->width, last_width);

    cells = g_new(TextCell, t->width * t->total_height + 1);
    for (y = 0; y < t->total_height; y++) {
        c = &cells[y * t->width];
        if (w1 > 0) {
            c1 = &t->cells[y * last_width];
            for (x = 0; x < w1; x++) {
                *c++ = *c1++;
            }
        }
        for (x = w1; x < t->width; x++) {
            c->ch = ' ';
            c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
            c++;
        }
    }
    g_free(t->cells);
    t->cells = cells;
}

static void vc_put_lf(VCChardev *vc)
{
    QemuTextConsole *s = vc->console;
    TextCell *c;
    int x, y1;

    s->y++;
    if (s->y >= s->height) {
        s->y = s->height - 1;

        if (s->y_displayed == s->y_base) {
            if (++s->y_displayed == s->total_height)
                s->y_displayed = 0;
        }
        if (++s->y_base == s->total_height)
            s->y_base = 0;
        if (s->backscroll_height < s->total_height)
            s->backscroll_height++;
        y1 = (s->y_base + s->height - 1) % s->total_height;
        c = &s->cells[y1 * s->width];
        for(x = 0; x < s->width; x++) {
            c->ch = ' ';
            c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
            c++;
        }
        if (s->y_displayed == s->y_base) {
            s->text_x[0] = 0;
            s->text_y[0] = 0;
            s->text_x[1] = s->width - 1;
            s->text_y[1] = s->height - 1;

            qemu_console_bitblt(QEMU_CONSOLE(s), 0, FONT_HEIGHT, 0, 0,
                                s->width * FONT_WIDTH,
                                (s->height - 1) * FONT_HEIGHT);
            qemu_console_fill_rect(QEMU_CONSOLE(s), 0, (s->height - 1) * FONT_HEIGHT,
                                   s->width * FONT_WIDTH, FONT_HEIGHT,
                                   color_table_rgb[0][TEXT_ATTRIBUTES_DEFAULT.bgcol]);
            s->update_x0 = 0;
            s->update_y0 = 0;
            s->update_x1 = s->width * FONT_WIDTH;
            s->update_y1 = s->height * FONT_HEIGHT;
        }
    }
}

/* Set console attributes depending on the current escape codes.
 * NOTE: I know this code is not very efficient (checking every color for it
 * self) but it is more readable and better maintainable.
 */
static void vc_handle_escape(VCChardev *vc)
{
    int i;

    for (i = 0; i < vc->nb_esc_params; i++) {
        switch (vc->esc_params[i]) {
            case 0: /* reset all console attributes to default */
                vc->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
                break;
            case 1:
                vc->t_attrib.bold = 1;
                break;
            case 4:
                vc->t_attrib.uline = 1;
                break;
            case 5:
                vc->t_attrib.blink = 1;
                break;
            case 7:
                vc->t_attrib.invers = 1;
                break;
            case 8:
                vc->t_attrib.unvisible = 1;
                break;
            case 22:
                vc->t_attrib.bold = 0;
                break;
            case 24:
                vc->t_attrib.uline = 0;
                break;
            case 25:
                vc->t_attrib.blink = 0;
                break;
            case 27:
                vc->t_attrib.invers = 0;
                break;
            case 28:
                vc->t_attrib.unvisible = 0;
                break;
            /* set foreground color */
            case 30:
                vc->t_attrib.fgcol = QEMU_COLOR_BLACK;
                break;
            case 31:
                vc->t_attrib.fgcol = QEMU_COLOR_RED;
                break;
            case 32:
                vc->t_attrib.fgcol = QEMU_COLOR_GREEN;
                break;
            case 33:
                vc->t_attrib.fgcol = QEMU_COLOR_YELLOW;
                break;
            case 34:
                vc->t_attrib.fgcol = QEMU_COLOR_BLUE;
                break;
            case 35:
                vc->t_attrib.fgcol = QEMU_COLOR_MAGENTA;
                break;
            case 36:
                vc->t_attrib.fgcol = QEMU_COLOR_CYAN;
                break;
            case 37:
                vc->t_attrib.fgcol = QEMU_COLOR_WHITE;
                break;
            /* set background color */
            case 40:
                vc->t_attrib.bgcol = QEMU_COLOR_BLACK;
                break;
            case 41:
                vc->t_attrib.bgcol = QEMU_COLOR_RED;
                break;
            case 42:
                vc->t_attrib.bgcol = QEMU_COLOR_GREEN;
                break;
            case 43:
                vc->t_attrib.bgcol = QEMU_COLOR_YELLOW;
                break;
            case 44:
                vc->t_attrib.bgcol = QEMU_COLOR_BLUE;
                break;
            case 45:
                vc->t_attrib.bgcol = QEMU_COLOR_MAGENTA;
                break;
            case 46:
                vc->t_attrib.bgcol = QEMU_COLOR_CYAN;
                break;
            case 47:
                vc->t_attrib.bgcol = QEMU_COLOR_WHITE;
                break;
        }
    }
}

static void vc_update_xy(VCChardev *vc, int x, int y)
{
    QemuTextConsole *s = vc->console;
    TextCell *c;
    int y1, y2;

    s->text_x[0] = MIN(s->text_x[0], x);
    s->text_x[1] = MAX(s->text_x[1], x);
    s->text_y[0] = MIN(s->text_y[0], y);
    s->text_y[1] = MAX(s->text_y[1], y);

    y1 = (s->y_base + y) % s->total_height;
    y2 = y1 - s->y_displayed;
    if (y2 < 0) {
        y2 += s->total_height;
    }
    if (y2 < s->height) {
        if (x >= s->width) {
            x = s->width - 1;
        }
        c = &s->cells[y1 * s->width + x];
        vga_putcharxy(QEMU_CONSOLE(s), x, y2, c->ch,
                      &(c->t_attrib));
        invalidate_xy(s, x, y2);
    }
}

static void vc_clear_xy(VCChardev *vc, int x, int y)
{
    QemuTextConsole *s = vc->console;
    int y1 = (s->y_base + y) % s->total_height;
    if (x >= s->width) {
        x = s->width - 1;
    }
    TextCell *c = &s->cells[y1 * s->width + x];
    c->ch = ' ';
    c->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
    vc_update_xy(vc, x, y);
}

static void vc_put_one(VCChardev *vc, int ch)
{
    QemuTextConsole *s = vc->console;
    TextCell *c;
    int y1;
    if (s->x >= s->width) {
        /* line wrap */
        s->x = 0;
        vc_put_lf(vc);
    }
    y1 = (s->y_base + s->y) % s->total_height;
    c = &s->cells[y1 * s->width + s->x];
    c->ch = ch;
    c->t_attrib = vc->t_attrib;
    vc_update_xy(vc, s->x, s->y);
    s->x++;
}

static void vc_respond_str(VCChardev *vc, const char *buf)
{
    QemuTextConsole *s = vc->console;

    qemu_chr_be_write(s->chr, (const uint8_t *)buf, strlen(buf));
}

/* set cursor, checking bounds */
static void vc_set_cursor(VCChardev *vc, int x, int y)
{
    QemuTextConsole *s = vc->console;

    if (x < 0) {
        x = 0;
    }
    if (y < 0) {
        y = 0;
    }
    if (y >= s->height) {
        y = s->height - 1;
    }
    if (x >= s->width) {
        x = s->width - 1;
    }

    s->x = x;
    s->y = y;
}

/**
 * vc_csi_P() - (DCH) deletes one or more characters from the cursor
 * position to the right. As characters are deleted, the remaining
 * characters between the cursor and right margin move to the
 * left. Character attributes move with the characters.
 */
static void vc_csi_P(struct VCChardev *vc, unsigned int nr)
{
    QemuTextConsole *s = vc->console;
    TextCell *c1, *c2;
    unsigned int x1, x2, y;
    unsigned int end, len;

    if (!nr) {
        nr = 1;
    }
    if (nr > s->width - s->x) {
        nr = s->width - s->x;
        if (!nr) {
            return;
        }
    }

    x1 = s->x;
    x2 = s->x + nr;
    len = s->width - x2;
    if (len) {
        y = (s->y_base + s->y) % s->total_height;
        c1 = &s->cells[y * s->width + x1];
        c2 = &s->cells[y * s->width + x2];
        memmove(c1, c2, len * sizeof(*c1));
        for (end = x1 + len; x1 < end; x1++) {
            vc_update_xy(vc, x1, s->y);
        }
    }
    /* Clear the rest */
    for (; x1 < s->width; x1++) {
        vc_clear_xy(vc, x1, s->y);
    }
}

/**
 * vc_csi_at() - (ICH) inserts `nr` blank characters with the default
 * character attribute. The cursor remains at the beginning of the
 * blank characters. Text between the cursor and right margin moves to
 * the right. Characters scrolled past the right margin are lost.
 */
static void vc_csi_at(struct VCChardev *vc, unsigned int nr)
{
    QemuTextConsole *s = vc->console;
    TextCell *c1, *c2;
    unsigned int x1, x2, y;
    unsigned int end, len;

    if (!nr) {
        nr = 1;
    }
    if (nr > s->width - s->x) {
        nr = s->width - s->x;
        if (!nr) {
            return;
        }
    }

    x1 = s->x + nr;
    x2 = s->x;
    len = s->width - x1;
    if (len) {
        y = (s->y_base + s->y) % s->total_height;
        c1 = &s->cells[y * s->width + x1];
        c2 = &s->cells[y * s->width + x2];
        memmove(c1, c2, len * sizeof(*c1));
        for (end = x1 + len; x1 < end; x1++) {
            vc_update_xy(vc, x1, s->y);
        }
    }
    /* Insert blanks */
    for (x1 = s->x; x1 < s->x + nr; x1++) {
        vc_clear_xy(vc, x1, s->y);
    }
}

/**
 * vc_save_cursor() - saves cursor position and character attributes.
 */
static void vc_save_cursor(VCChardev *vc)
{
    QemuTextConsole *s = vc->console;

    vc->x_saved = s->x;
    vc->y_saved = s->y;
    vc->t_attrib_saved = vc->t_attrib;
}

/**
 * vc_restore_cursor() - restores cursor position and character
 * attributes from saved state.
 */
static void vc_restore_cursor(VCChardev *vc)
{
    QemuTextConsole *s = vc->console;

    s->x = vc->x_saved;
    s->y = vc->y_saved;
    vc->t_attrib = vc->t_attrib_saved;
}

static void vc_putchar(VCChardev *vc, int ch)
{
    QemuTextConsole *s = vc->console;
    int i;
    int x, y;
    g_autofree char *response = NULL;

    switch(vc->state) {
    case TTY_STATE_NORM:
        switch(ch) {
        case '\r':  /* carriage return */
            s->x = 0;
            break;
        case '\n':  /* newline */
            vc_put_lf(vc);
            break;
        case '\b':  /* backspace */
            if (s->x > 0)
                s->x--;
            break;
        case '\t':  /* tabspace */
            if (s->x + (8 - (s->x % 8)) > s->width) {
                s->x = 0;
                vc_put_lf(vc);
            } else {
                s->x = s->x + (8 - (s->x % 8));
            }
            break;
        case '\a':  /* alert aka. bell */
            /* TODO: has to be implemented */
            break;
        case 14:
            /* SI (shift in), character set 0 (ignored) */
            break;
        case 15:
            /* SO (shift out), character set 1 (ignored) */
            break;
        case 27:    /* esc (introducing an escape sequence) */
            vc->state = TTY_STATE_ESC;
            break;
        default:
            vc_put_one(vc, ch);
            break;
        }
        break;
    case TTY_STATE_ESC: /* check if it is a terminal escape sequence */
        if (ch == '[') {
            for(i=0;i<MAX_ESC_PARAMS;i++)
                vc->esc_params[i] = 0;
            vc->nb_esc_params = 0;
            vc->state = TTY_STATE_CSI;
        } else if (ch == '(') {
            vc->state = TTY_STATE_G0;
        } else if (ch == ')') {
            vc->state = TTY_STATE_G1;
        } else if (ch == '7') {
            vc_save_cursor(vc);
            vc->state = TTY_STATE_NORM;
        } else if (ch == '8') {
            vc_restore_cursor(vc);
            vc->state = TTY_STATE_NORM;
        } else {
            vc->state = TTY_STATE_NORM;
        }
        break;
    case TTY_STATE_CSI: /* handle escape sequence parameters */
        if (ch >= '0' && ch <= '9') {
            if (vc->nb_esc_params < MAX_ESC_PARAMS) {
                int *param = &vc->esc_params[vc->nb_esc_params];
                int digit = (ch - '0');

                *param = (*param <= (INT_MAX - digit) / 10) ?
                         *param * 10 + digit : INT_MAX;
            }
        } else {
            if (vc->nb_esc_params < MAX_ESC_PARAMS)
                vc->nb_esc_params++;
            if (ch == ';' || ch == '?') {
                break;
            }
            trace_console_putchar_csi(vc->esc_params[0], vc->esc_params[1],
                                      ch, vc->nb_esc_params);
            vc->state = TTY_STATE_NORM;
            switch(ch) {
            case 'A':
                /* move cursor up */
                if (vc->esc_params[0] == 0) {
                    vc->esc_params[0] = 1;
                }
                vc_set_cursor(vc, s->x, s->y - vc->esc_params[0]);
                break;
            case 'B':
                /* move cursor down */
                if (vc->esc_params[0] == 0) {
                    vc->esc_params[0] = 1;
                }
                vc_set_cursor(vc, s->x, s->y + vc->esc_params[0]);
                break;
            case 'C':
                /* move cursor right */
                if (vc->esc_params[0] == 0) {
                    vc->esc_params[0] = 1;
                }
                vc_set_cursor(vc, s->x + vc->esc_params[0], s->y);
                break;
            case 'D':
                /* move cursor left */
                if (vc->esc_params[0] == 0) {
                    vc->esc_params[0] = 1;
                }
                vc_set_cursor(vc, s->x - vc->esc_params[0], s->y);
                break;
            case 'G':
                /* move cursor to column */
                vc_set_cursor(vc, vc->esc_params[0] - 1, s->y);
                break;
            case 'f':
            case 'H':
                /* move cursor to row, column */
                vc_set_cursor(vc, vc->esc_params[1] - 1, vc->esc_params[0] - 1);
                break;
            case 'J':
                switch (vc->esc_params[0]) {
                case 0:
                    /* clear to end of screen */
                    for (y = s->y; y < s->height; y++) {
                        for (x = 0; x < s->width; x++) {
                            if (y == s->y && x < s->x) {
                                continue;
                            }
                            vc_clear_xy(vc, x, y);
                        }
                    }
                    break;
                case 1:
                    /* clear from beginning of screen */
                    for (y = 0; y <= s->y; y++) {
                        for (x = 0; x < s->width; x++) {
                            if (y == s->y && x > s->x) {
                                break;
                            }
                            vc_clear_xy(vc, x, y);
                        }
                    }
                    break;
                case 2:
                    /* clear entire screen */
                    for (y = 0; y <= s->height; y++) {
                        for (x = 0; x < s->width; x++) {
                            vc_clear_xy(vc, x, y);
                        }
                    }
                    break;
                }
                break;
            case 'K':
                switch (vc->esc_params[0]) {
                case 0:
                    /* clear to eol */
                    for(x = s->x; x < s->width; x++) {
                        vc_clear_xy(vc, x, s->y);
                    }
                    break;
                case 1:
                    /* clear from beginning of line */
                    for (x = 0; x <= s->x && x < s->width; x++) {
                        vc_clear_xy(vc, x, s->y);
                    }
                    break;
                case 2:
                    /* clear entire line */
                    for(x = 0; x < s->width; x++) {
                        vc_clear_xy(vc, x, s->y);
                    }
                    break;
                }
                break;
            case 'P':
                vc_csi_P(vc, vc->esc_params[0]);
                break;
            case 'm':
                vc_handle_escape(vc);
                break;
            case 'n':
                switch (vc->esc_params[0]) {
                case 5:
                    /* report console status (always succeed)*/
                    vc_respond_str(vc, "\033[0n");
                    break;
                case 6:
                    /* report cursor position */
                    response = g_strdup_printf("\033[%d;%dR",
                                               s->y + 1, s->x + 1);
                    vc_respond_str(vc, response);
                    break;
                }
                break;
            case 's':
                vc_save_cursor(vc);
                break;
            case 'u':
                vc_restore_cursor(vc);
                break;
            case '@':
                vc_csi_at(vc, vc->esc_params[0]);
                break;
            default:
                trace_console_putchar_unhandled(ch);
                break;
            }
            break;
        }
        break;
    case TTY_STATE_G0: /* set character sets */
    case TTY_STATE_G1: /* set character sets */
        switch (ch) {
        case 'B':
            /* Latin-1 map */
            break;
        }
        vc->state = TTY_STATE_NORM;
        break;
    }
}

#define TYPE_CHARDEV_VC "chardev-vc"
DECLARE_INSTANCE_CHECKER(VCChardev, VC_CHARDEV,
                         TYPE_CHARDEV_VC)

static int vc_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
    VCChardev *drv = VC_CHARDEV(chr);
    QemuTextConsole *s = drv->console;
    int i;

    s->update_x0 = s->width * FONT_WIDTH;
    s->update_y0 = s->height * FONT_HEIGHT;
    s->update_x1 = 0;
    s->update_y1 = 0;
    console_show_cursor(s, 0);
    for(i = 0; i < len; i++) {
        vc_putchar(drv, buf[i]);
    }
    console_show_cursor(s, 1);
    if (s->update_x0 < s->update_x1) {
        dpy_gfx_update(QEMU_CONSOLE(s), s->update_x0, s->update_y0,
                       s->update_x1 - s->update_x0,
                       s->update_y1 - s->update_y0);
    }
    return len;
}

void qemu_text_console_update_cursor(void)
{
    cursor_visible_phase = !cursor_visible_phase;

    if (qemu_invalidate_text_consoles()) {
        timer_mod(cursor_timer,
                  qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + CONSOLE_CURSOR_PERIOD / 2);
    }
}

static void
cursor_timer_cb(void *opaque)
{
    qemu_text_console_update_cursor();
}

static void text_console_invalidate(void *opaque)
{
    QemuTextConsole *s = QEMU_TEXT_CONSOLE(opaque);

    if (!QEMU_IS_FIXED_TEXT_CONSOLE(s)) {
        text_console_resize(QEMU_TEXT_CONSOLE(s));
    }
    console_refresh(s);
}

static void
qemu_text_console_finalize(Object *obj)
{
}

static void
qemu_text_console_class_init(ObjectClass *oc, const void *data)
{
    if (!cursor_timer) {
        cursor_timer = timer_new_ms(QEMU_CLOCK_REALTIME, cursor_timer_cb, NULL);
    }
}

static const GraphicHwOps text_console_ops = {
    .invalidate  = text_console_invalidate,
    .text_update = text_console_update,
};

static void
qemu_text_console_init(Object *obj)
{
    QemuTextConsole *c = QEMU_TEXT_CONSOLE(obj);

    fifo8_create(&c->out_fifo, 16);
    c->total_height = DEFAULT_BACKSCROLL;
    QEMU_CONSOLE(c)->hw_ops = &text_console_ops;
    QEMU_CONSOLE(c)->hw = c;
}

static void
qemu_fixed_text_console_finalize(Object *obj)
{
}

static void
qemu_fixed_text_console_class_init(ObjectClass *oc, const void *data)
{
}

static void
qemu_fixed_text_console_init(Object *obj)
{
}

static void vc_chr_accept_input(Chardev *chr)
{
    VCChardev *drv = VC_CHARDEV(chr);

    kbd_send_chars(drv->console);
}

static void vc_chr_set_echo(Chardev *chr, bool echo)
{
    VCChardev *drv = VC_CHARDEV(chr);

    drv->console->echo = echo;
}

void qemu_text_console_update_size(QemuTextConsole *c)
{
    dpy_text_resize(QEMU_CONSOLE(c), c->width, c->height);
}

static void vc_chr_open(Chardev *chr,
                        ChardevBackend *backend,
                        bool *be_opened,
                        Error **errp)
{
    ChardevVC *vc = backend->u.vc.data;
    VCChardev *drv = VC_CHARDEV(chr);
    QemuTextConsole *s;
    unsigned width = 0;
    unsigned height = 0;

    if (vc->has_width) {
        width = vc->width;
    } else if (vc->has_cols) {
        width = vc->cols * FONT_WIDTH;
    }

    if (vc->has_height) {
        height = vc->height;
    } else if (vc->has_rows) {
        height = vc->rows * FONT_HEIGHT;
    }

    trace_console_txt_new(width, height);
    if (width == 0 || height == 0) {
        s = QEMU_TEXT_CONSOLE(object_new(TYPE_QEMU_TEXT_CONSOLE));
        width = 80 * FONT_WIDTH;
        height = 24 * FONT_HEIGHT;
    } else {
        s = QEMU_TEXT_CONSOLE(object_new(TYPE_QEMU_FIXED_TEXT_CONSOLE));
    }

    dpy_gfx_replace_surface(QEMU_CONSOLE(s), qemu_create_displaysurface(width, height));

    s->chr = chr;
    drv->console = s;

    /* set current text attributes to default */
    drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
    text_console_resize(s);

    if (chr->label) {
        char *msg;

        drv->t_attrib.bgcol = QEMU_COLOR_BLUE;
        msg = g_strdup_printf("%s console\r\n", chr->label);
        qemu_chr_write(chr, (uint8_t *)msg, strlen(msg), true);
        g_free(msg);
        drv->t_attrib = TEXT_ATTRIBUTES_DEFAULT;
    }

    *be_opened = true;
}

static void vc_chr_parse(QemuOpts *opts, ChardevBackend *backend, Error **errp)
{
    int val;
    ChardevVC *vc;

    backend->type = CHARDEV_BACKEND_KIND_VC;
    vc = backend->u.vc.data = g_new0(ChardevVC, 1);
    qemu_chr_parse_common(opts, qapi_ChardevVC_base(vc));

    val = qemu_opt_get_number(opts, "width", 0);
    if (val != 0) {
        vc->has_width = true;
        vc->width = val;
    }

    val = qemu_opt_get_number(opts, "height", 0);
    if (val != 0) {
        vc->has_height = true;
        vc->height = val;
    }

    val = qemu_opt_get_number(opts, "cols", 0);
    if (val != 0) {
        vc->has_cols = true;
        vc->cols = val;
    }

    val = qemu_opt_get_number(opts, "rows", 0);
    if (val != 0) {
        vc->has_rows = true;
        vc->rows = val;
    }
}

static void char_vc_class_init(ObjectClass *oc, const void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->parse = vc_chr_parse;
    cc->open = vc_chr_open;
    cc->chr_write = vc_chr_write;
    cc->chr_accept_input = vc_chr_accept_input;
    cc->chr_set_echo = vc_chr_set_echo;
}

static const TypeInfo char_vc_type_info = {
    .name = TYPE_CHARDEV_VC,
    .parent = TYPE_CHARDEV,
    .instance_size = sizeof(VCChardev),
    .class_init = char_vc_class_init,
};

void qemu_console_early_init(void)
{
    /* set the default vc driver */
    if (!object_class_by_name(TYPE_CHARDEV_VC)) {
        type_register_static(&char_vc_type_info);
    }
}
