/*
 * QEMU curses/ncurses display driver
 *
 * Copyright (c) 2005 Andrzej Zaborowski  <balrog@zabor.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"

#ifndef _WIN32
#include <sys/ioctl.h>
#include <termios.h>
#endif
#include <locale.h>
#include <wchar.h>
#include <iconv.h>

#include "qapi/error.h"
#include "qemu/module.h"
#include "ui/console.h"
#include "ui/input.h"
#include "system/system.h"

#ifdef __APPLE__
#define _XOPEN_SOURCE_EXTENDED 1
#endif

/* KEY_EVENT is defined in wincon.h and in curses.h. Avoid redefinition. */
#undef KEY_EVENT
#include <curses.h>
#undef KEY_EVENT

#define FONT_HEIGHT 16
#define FONT_WIDTH 8

enum maybe_keycode {
    CURSES_KEYCODE,
    CURSES_CHAR,
    CURSES_CHAR_OR_KEYCODE,
};

static DisplayChangeListener *dcl;
static uint32_t *screen;
static WINDOW *screenpad = NULL;
static int width, height, gwidth, gheight, invalidate;
static int px, py, sminx, sminy, smaxx, smaxy;

static const char *font_charset = "CP437";
static cchar_t *vga_to_curses;

static void curses_update(DisplayChangeListener *dcl,
                          int x, int y, int w, int h)
{
    uint32_t *line;
    g_autofree cchar_t *curses_line = g_new(cchar_t, width);
    wchar_t wch[CCHARW_MAX];
    attr_t attrs;
    short colors;
    int ret;

    line = screen + y * width;
    for (h += y; y < h; y ++, line += width) {
        for (x = 0; x < width; x++) {
            chtype ch = line[x] & A_CHARTEXT;
            chtype at = line[x] & A_ATTRIBUTES;
            short color_pair = PAIR_NUMBER(line[x]);

            ret = getcchar(&vga_to_curses[ch], wch, &attrs, &colors, NULL);
            if (ret == ERR || wch[0] == 0) {
                wch[0] = ch;
                wch[1] = 0;
            }
            setcchar(&curses_line[x], wch, at, color_pair, NULL);
        }
        mvwadd_wchnstr(screenpad, y, 0, curses_line, width);
    }

    pnoutrefresh(screenpad, py, px, sminy, sminx, smaxy - 1, smaxx - 1);
    refresh();
}

static void curses_calc_pad(void)
{
    if (qemu_console_is_fixedsize(dcl->con)) {
        width = gwidth;
        height = gheight;
    } else {
        width = COLS;
        height = LINES;
    }

    if (screenpad)
        delwin(screenpad);

    clear();
    refresh();

    screenpad = newpad(height, width);

    if (width > COLS) {
        px = (width - COLS) / 2;
        sminx = 0;
        smaxx = COLS;
    } else {
        px = 0;
        sminx = (COLS - width) / 2;
        smaxx = sminx + width;
    }

    if (height > LINES) {
        py = (height - LINES) / 2;
        sminy = 0;
        smaxy = LINES;
    } else {
        py = 0;
        sminy = (LINES - height) / 2;
        smaxy = sminy + height;
    }
}

static void curses_resize(DisplayChangeListener *dcl,
                          int width, int height)
{
    if (width == gwidth && height == gheight) {
        return;
    }

    gwidth = width;
    gheight = height;

    curses_calc_pad();
}

#if !defined(_WIN32) && defined(SIGWINCH) && defined(KEY_RESIZE)
static volatile sig_atomic_t got_sigwinch;
static void curses_winch_check(void)
{
    struct winsize {
        unsigned short ws_row;
        unsigned short ws_col;
        unsigned short ws_xpixel;   /* unused */
        unsigned short ws_ypixel;   /* unused */
    } ws;

    if (!got_sigwinch) {
        return;
    }
    got_sigwinch = false;

    if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
        return;
    }

    resize_term(ws.ws_row, ws.ws_col);
    invalidate = 1;
}

static void curses_winch_handler(int signum)
{
    got_sigwinch = true;
}

static void curses_winch_init(void)
{
    struct sigaction old, winch = {
        .sa_handler  = curses_winch_handler,
    };
    sigaction(SIGWINCH, &winch, &old);
}
#else
static void curses_winch_check(void) {}
static void curses_winch_init(void) {}
#endif

static void curses_cursor_position(DisplayChangeListener *dcl,
                                   int x, int y)
{
    if (x >= 0) {
        x = sminx + x - px;
        y = sminy + y - py;

        if (x >= 0 && y >= 0 && x < COLS && y < LINES) {
            move(y, x);
            curs_set(1);
            /* it seems that curs_set(1) must always be called before
             * curs_set(2) for the latter to have effect */
            if (!qemu_console_is_graphic(dcl->con)) {
                curs_set(2);
            }
            return;
        }
    }

    curs_set(0);
}

/* generic keyboard conversion */

#include "curses_keys.h"

static kbd_layout_t *kbd_layout = NULL;

static wint_t console_getch(enum maybe_keycode *maybe_keycode)
{
    wint_t ret;
    switch (get_wch(&ret)) {
    case KEY_CODE_YES:
        *maybe_keycode = CURSES_KEYCODE;
        break;
    case OK:
        *maybe_keycode = CURSES_CHAR;
        break;
    case ERR:
        ret = -1;
        break;
    default:
        abort();
    }
    return ret;
}

static int curses2foo(const int _curses2foo[], const int _curseskey2foo[],
                      int chr, enum maybe_keycode maybe_keycode)
{
    int ret = -1;
    if (maybe_keycode == CURSES_CHAR) {
        if (chr < CURSES_CHARS) {
            ret = _curses2foo[chr];
        }
    } else {
        if (chr < CURSES_KEYS) {
            ret = _curseskey2foo[chr];
        }
        if (ret == -1 && maybe_keycode == CURSES_CHAR_OR_KEYCODE &&
            chr < CURSES_CHARS) {
            ret = _curses2foo[chr];
        }
    }
    return ret;
}

#define curses2keycode(chr, maybe_keycode) \
    curses2foo(_curses2keycode, _curseskey2keycode, chr, maybe_keycode)
#define curses2keysym(chr, maybe_keycode) \
    curses2foo(_curses2keysym, _curseskey2keysym, chr, maybe_keycode)
#define curses2qemu(chr, maybe_keycode) \
    curses2foo(_curses2qemu, _curseskey2qemu, chr, maybe_keycode)

static void curses_refresh(DisplayChangeListener *dcl)
{
    wint_t chr = 0;
    int keysym, keycode, keycode_alt;
    enum maybe_keycode maybe_keycode = CURSES_KEYCODE;

    curses_winch_check();

    if (invalidate) {
        clear();
        refresh();
        curses_calc_pad();
        qemu_console_hw_invalidate(dcl->con);
        invalidate = 0;
    }

    qemu_console_hw_text_update(dcl->con, screen);

    while (1) {
        /* while there are any pending key strokes to process */
        chr = console_getch(&maybe_keycode);

        if (chr == WEOF) {
            break;
        }

#ifdef KEY_RESIZE
        /* this shouldn't occur when we use a custom SIGWINCH handler */
        if (maybe_keycode != CURSES_CHAR && chr == KEY_RESIZE) {
            clear();
            refresh();
            curses_calc_pad();
            curses_update(dcl, 0, 0, width, height);
            continue;
        }
#endif

        keycode = curses2keycode(chr, maybe_keycode);
        keycode_alt = 0;

        /* alt or esc key */
        if (keycode == 1) {
            enum maybe_keycode next_maybe_keycode = CURSES_KEYCODE;
            wint_t nextchr = console_getch(&next_maybe_keycode);

            if (nextchr != WEOF) {
                chr = nextchr;
                maybe_keycode = next_maybe_keycode;
                keycode_alt = ALT;
                keycode = curses2keycode(chr, maybe_keycode);

                if (keycode != -1) {
                    keycode |= ALT;

                    /* process keys reserved for qemu */
                    if (keycode >= QEMU_KEY_CONSOLE0 &&
                            keycode < QEMU_KEY_CONSOLE0 + 9) {
                        QemuConsole *con = qemu_console_lookup_by_index(keycode - QEMU_KEY_CONSOLE0);
                        if (con) {
                            erase();
                            wnoutrefresh(stdscr);
                            qemu_console_unregister_listener(dcl);
                            qemu_console_register_listener(con, dcl, dcl->ops);

                            invalidate = 1;
                        }
                        continue;
                    }
                }
            }
        }

        if (kbd_layout) {
            keysym = curses2keysym(chr, maybe_keycode);

            if (keysym == -1) {
                if (chr < ' ') {
                    keysym = chr + '@';
                    if (keysym >= 'A' && keysym <= 'Z')
                        keysym += 'a' - 'A';
                    keysym |= KEYSYM_CNTRL;
                } else
                    keysym = chr;
            }

            keycode = keysym2scancode(kbd_layout, keysym & KEYSYM_MASK,
                                      NULL, false);
            if (keycode == 0)
                continue;

            keycode |= (keysym & ~KEYSYM_MASK) >> 16;
            keycode |= keycode_alt;
        }

        if (keycode == -1)
            continue;

        if (qemu_console_is_graphic(dcl->con)) {
            /* since terminals don't know about key press and release
             * events, we need to emit both for each key received */
            if (keycode & SHIFT) {
                qemu_input_event_send_key_number(dcl->con, SHIFT_CODE, true);
                qemu_input_event_send_key_delay(0);
            }
            if (keycode & CNTRL) {
                qemu_input_event_send_key_number(dcl->con, CNTRL_CODE, true);
                qemu_input_event_send_key_delay(0);
            }
            if (keycode & ALT) {
                qemu_input_event_send_key_number(dcl->con, ALT_CODE, true);
                qemu_input_event_send_key_delay(0);
            }
            if (keycode & ALTGR) {
                qemu_input_event_send_key_number(dcl->con, GREY | ALT_CODE, true);
                qemu_input_event_send_key_delay(0);
            }

            qemu_input_event_send_key_number(dcl->con, keycode & KEY_MASK, true);
            qemu_input_event_send_key_delay(0);
            qemu_input_event_send_key_number(dcl->con, keycode & KEY_MASK, false);
            qemu_input_event_send_key_delay(0);

            if (keycode & ALTGR) {
                qemu_input_event_send_key_number(dcl->con, GREY | ALT_CODE, false);
                qemu_input_event_send_key_delay(0);
            }
            if (keycode & ALT) {
                qemu_input_event_send_key_number(dcl->con, ALT_CODE, false);
                qemu_input_event_send_key_delay(0);
            }
            if (keycode & CNTRL) {
                qemu_input_event_send_key_number(dcl->con, CNTRL_CODE, false);
                qemu_input_event_send_key_delay(0);
            }
            if (keycode & SHIFT) {
                qemu_input_event_send_key_number(dcl->con, SHIFT_CODE, false);
                qemu_input_event_send_key_delay(0);
            }
        } else {
            keysym = curses2qemu(chr, maybe_keycode);
            if (keysym == -1)
                keysym = chr;

            qemu_text_console_put_keysym(QEMU_TEXT_CONSOLE(dcl->con), keysym);
        }
    }
}

static void curses_atexit(void)
{
    endwin();
    g_free(vga_to_curses);
    g_free(screen);
}

/*
 * In the following:
 * - fch is the font glyph number
 * - uch is the unicode value
 * - wch is the wchar_t value (may not be unicode, e.g. on BSD/solaris)
 * - mbch is the native local-dependent multibyte representation
 */

/* Setup wchar glyph for one UCS-2 char */
static void convert_ucs(unsigned char fch, uint16_t uch, iconv_t conv)
{
    char mbch[MB_LEN_MAX];
    wchar_t wch[2];
    char *puch, *pmbch;
    size_t such, smbch;
    mbstate_t ps;

    puch = (char *) &uch;
    pmbch = (char *) mbch;
    such = sizeof(uch);
    smbch = sizeof(mbch);

    if (iconv(conv, &puch, &such, &pmbch, &smbch) == (size_t) -1) {
        fprintf(stderr, "Could not convert 0x%04x "
                        "from UCS-2 to a multibyte character: %s\n",
                        uch, strerror(errno));
        return;
    }

    memset(&ps, 0, sizeof(ps));
    if (mbrtowc(&wch[0], mbch, sizeof(mbch) - smbch, &ps) == -1) {
        fprintf(stderr, "Could not convert 0x%04x "
                        "from a multibyte character to wchar_t: %s\n",
                        uch, strerror(errno));
        return;
    }

    wch[1] = 0;
    setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
}

/* Setup wchar glyph for one font character */
static void convert_font(unsigned char fch, iconv_t conv)
{
    char mbch[MB_LEN_MAX];
    wchar_t wch[2];
    char *pfch, *pmbch;
    size_t sfch, smbch;
    mbstate_t ps;

    pfch = (char *) &fch;
    pmbch = (char *) &mbch;
    sfch = sizeof(fch);
    smbch = sizeof(mbch);

    if (iconv(conv, &pfch, &sfch, &pmbch, &smbch) == (size_t) -1) {
        fprintf(stderr, "Could not convert font glyph 0x%02x "
                        "from %s to a multibyte character: %s\n",
                        fch, font_charset, strerror(errno));
        return;
    }

    memset(&ps, 0, sizeof(ps));
    if (mbrtowc(&wch[0], mbch, sizeof(mbch) - smbch, &ps) == -1) {
        fprintf(stderr, "Could not convert font glyph 0x%02x "
                        "from a multibyte character to wchar_t: %s\n",
                        fch, strerror(errno));
        return;
    }

    wch[1] = 0;
    setcchar(&vga_to_curses[fch], wch, 0, 0, NULL);
}

/* Convert one wchar to UCS-2 */
static uint16_t get_ucs(wchar_t wch, iconv_t conv)
{
    char mbch[MB_LEN_MAX];
    uint16_t uch;
    char *pmbch, *puch;
    size_t smbch, such;
    mbstate_t ps;
    int ret;

    memset(&ps, 0, sizeof(ps));
    ret = wcrtomb(mbch, wch, &ps);
    if (ret == -1) {
        fprintf(stderr, "Could not convert 0x%04lx "
                        "from wchar_t to a multibyte character: %s\n",
                        (unsigned long)wch, strerror(errno));
        return 0xFFFD;
    }

    pmbch = (char *) mbch;
    puch = (char *) &uch;
    smbch = ret;
    such = sizeof(uch);

    if (iconv(conv, &pmbch, &smbch, &puch, &such) == (size_t) -1) {
        fprintf(stderr, "Could not convert 0x%04lx "
                        "from a multibyte character to UCS-2 : %s\n",
                        (unsigned long)wch, strerror(errno));
        return 0xFFFD;
    }

    return uch;
}

/*
 * Setup mapping for vga to curses line graphics.
 */
static void font_setup(void)
{
    iconv_t ucs2_to_nativecharset;
    iconv_t nativecharset_to_ucs2;
    iconv_t font_conv;
    int i;
    g_autofree gchar *local_codeset = g_get_codeset();

    /*
     * Control characters are normally non-printable, but VGA does have
     * well-known glyphs for them.
     */
    static const uint16_t control_characters[0x20] = {
      0x0020,
      0x263a,
      0x263b,
      0x2665,
      0x2666,
      0x2663,
      0x2660,
      0x2022,
      0x25d8,
      0x25cb,
      0x25d9,
      0x2642,
      0x2640,
      0x266a,
      0x266b,
      0x263c,
      0x25ba,
      0x25c4,
      0x2195,
      0x203c,
      0x00b6,
      0x00a7,
      0x25ac,
      0x21a8,
      0x2191,
      0x2193,
      0x2192,
      0x2190,
      0x221f,
      0x2194,
      0x25b2,
      0x25bc
    };

    ucs2_to_nativecharset = iconv_open(local_codeset, "UCS-2");
    if (ucs2_to_nativecharset == (iconv_t) -1) {
        fprintf(stderr, "Could not convert font glyphs from UCS-2: '%s'\n",
                        strerror(errno));
        exit(1);
    }

    nativecharset_to_ucs2 = iconv_open("UCS-2", local_codeset);
    if (nativecharset_to_ucs2 == (iconv_t) -1) {
        iconv_close(ucs2_to_nativecharset);
        fprintf(stderr, "Could not convert font glyphs to UCS-2: '%s'\n",
                        strerror(errno));
        exit(1);
    }

    font_conv = iconv_open(local_codeset, font_charset);
    if (font_conv == (iconv_t) -1) {
        iconv_close(ucs2_to_nativecharset);
        iconv_close(nativecharset_to_ucs2);
        fprintf(stderr, "Could not convert font glyphs from %s: '%s'\n",
                        font_charset, strerror(errno));
        exit(1);
    }

    /* Control characters */
    for (i = 0; i <= 0x1F; i++) {
        convert_ucs(i, control_characters[i], ucs2_to_nativecharset);
    }

    for (i = 0x20; i <= 0xFF; i++) {
        convert_font(i, font_conv);
    }

    /* DEL */
    convert_ucs(0x7F, 0x2302, ucs2_to_nativecharset);

    if (strcmp(local_codeset, "UTF-8")) {
        /* Non-Unicode capable, use termcap equivalents for those available */
        for (i = 0; i <= 0xFF; i++) {
            wchar_t wch[CCHARW_MAX];
            attr_t attr;
            short color;
            int ret;

            ret = getcchar(&vga_to_curses[i], wch, &attr, &color, NULL);
            if (ret == ERR)
                continue;

            switch (get_ucs(wch[0], nativecharset_to_ucs2)) {
            case 0x00a3:
                vga_to_curses[i] = *WACS_STERLING;
                break;
            case 0x2591:
                vga_to_curses[i] = *WACS_BOARD;
                break;
            case 0x2592:
                vga_to_curses[i] = *WACS_CKBOARD;
                break;
            case 0x2502:
                vga_to_curses[i] = *WACS_VLINE;
                break;
            case 0x2524:
                vga_to_curses[i] = *WACS_RTEE;
                break;
            case 0x2510:
                vga_to_curses[i] = *WACS_URCORNER;
                break;
            case 0x2514:
                vga_to_curses[i] = *WACS_LLCORNER;
                break;
            case 0x2534:
                vga_to_curses[i] = *WACS_BTEE;
                break;
            case 0x252c:
                vga_to_curses[i] = *WACS_TTEE;
                break;
            case 0x251c:
                vga_to_curses[i] = *WACS_LTEE;
                break;
            case 0x2500:
                vga_to_curses[i] = *WACS_HLINE;
                break;
            case 0x253c:
                vga_to_curses[i] = *WACS_PLUS;
                break;
            case 0x256c:
                vga_to_curses[i] = *WACS_LANTERN;
                break;
            case 0x256a:
                vga_to_curses[i] = *WACS_NEQUAL;
                break;
            case 0x2518:
                vga_to_curses[i] = *WACS_LRCORNER;
                break;
            case 0x250c:
                vga_to_curses[i] = *WACS_ULCORNER;
                break;
            case 0x2588:
                vga_to_curses[i] = *WACS_BLOCK;
                break;
            case 0x03c0:
                vga_to_curses[i] = *WACS_PI;
                break;
            case 0x00b1:
                vga_to_curses[i] = *WACS_PLMINUS;
                break;
            case 0x2265:
                vga_to_curses[i] = *WACS_GEQUAL;
                break;
            case 0x2264:
                vga_to_curses[i] = *WACS_LEQUAL;
                break;
            case 0x00b0:
                vga_to_curses[i] = *WACS_DEGREE;
                break;
            case 0x25a0:
                vga_to_curses[i] = *WACS_BULLET;
                break;
            case 0x2666:
                vga_to_curses[i] = *WACS_DIAMOND;
                break;
            case 0x2192:
                vga_to_curses[i] = *WACS_RARROW;
                break;
            case 0x2190:
                vga_to_curses[i] = *WACS_LARROW;
                break;
            case 0x2191:
                vga_to_curses[i] = *WACS_UARROW;
                break;
            case 0x2193:
                vga_to_curses[i] = *WACS_DARROW;
                break;
            case 0x23ba:
                vga_to_curses[i] = *WACS_S1;
                break;
            case 0x23bb:
                vga_to_curses[i] = *WACS_S3;
                break;
            case 0x23bc:
                vga_to_curses[i] = *WACS_S7;
                break;
            case 0x23bd:
                vga_to_curses[i] = *WACS_S9;
                break;
            }
        }
    }
    iconv_close(ucs2_to_nativecharset);
    iconv_close(nativecharset_to_ucs2);
    iconv_close(font_conv);
}

static void curses_setup(void)
{
    int i, colour_default[8] = {
        [QEMU_COLOR_BLACK]   = COLOR_BLACK,
        [QEMU_COLOR_BLUE]    = COLOR_BLUE,
        [QEMU_COLOR_GREEN]   = COLOR_GREEN,
        [QEMU_COLOR_CYAN]    = COLOR_CYAN,
        [QEMU_COLOR_RED]     = COLOR_RED,
        [QEMU_COLOR_MAGENTA] = COLOR_MAGENTA,
        [QEMU_COLOR_YELLOW]  = COLOR_YELLOW,
        [QEMU_COLOR_WHITE]   = COLOR_WHITE,
    };

    /* input as raw as possible, let everything be interpreted
     * by the guest system */
    initscr(); noecho(); intrflush(stdscr, FALSE);
    nodelay(stdscr, TRUE); nonl(); keypad(stdscr, TRUE);
    start_color(); raw(); scrollok(stdscr, FALSE);
    set_escdelay(25);

    /* Make color pair to match color format (3bits bg:3bits fg) */
    for (i = 0; i < 64; i++) {
        init_pair(i, colour_default[i & 7], colour_default[i >> 3]);
    }
    /* Set default color for more than 64 for safety. */
    for (i = 64; i < COLOR_PAIRS; i++) {
        init_pair(i, COLOR_WHITE, COLOR_BLACK);
    }

    font_setup();
}

static void curses_keyboard_setup(void)
{
#if defined(__APPLE__)
    /* always use generic keymaps */
    if (!keyboard_layout)
        keyboard_layout = "en-us";
#endif
    if(keyboard_layout) {
        kbd_layout = kbd_layout_new(name2keysym, keyboard_layout,
                                    &error_fatal);
    }
}

static const DisplayChangeListenerOps dcl_ops = {
    .dpy_name        = "curses",
    .dpy_text_update = curses_update,
    .dpy_text_resize = curses_resize,
    .dpy_refresh     = curses_refresh,
    .dpy_text_cursor = curses_cursor_position,
};

static void curses_display_init(DisplayState *ds, DisplayOptions *opts)
{
#ifndef _WIN32
    if (!isatty(1)) {
        fprintf(stderr, "We need a terminal output\n");
        exit(1);
    }
#endif

    setlocale(LC_CTYPE, "");
    if (opts->u.curses.charset) {
        font_charset = opts->u.curses.charset;
    }
    screen = g_new0(uint32_t, 160 * 100);
    vga_to_curses = g_new0(cchar_t, 256);
    curses_setup();
    curses_keyboard_setup();
    atexit(curses_atexit);

    curses_winch_init();

    dcl = g_new0(DisplayChangeListener, 1);
    qemu_console_register_listener(qemu_console_lookup_default(), dcl, &dcl_ops);

    invalidate = 1;
}

static QemuDisplay qemu_display_curses = {
    .type       = DISPLAY_TYPE_CURSES,
    .init       = curses_display_init,
};

static void register_curses(void)
{
    qemu_display_register(&qemu_display_curses);
}

type_init(register_curses);
