/*
 * 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-common.h"
#include "console.h"
#include "sysemu.h"

#include <curses.h>

#ifndef _WIN32
#include <signal.h>
#include <sys/ioctl.h>
#include <termios.h>
#endif

#define FONT_HEIGHT 16
#define FONT_WIDTH 8

static console_ch_t screen[160 * 100];
static WINDOW *screenpad = NULL;
static int width, height, gwidth, gheight, invalidate;
static int px, py, sminx, sminy, smaxx, smaxy;

static void curses_update(DisplayState *ds, int x, int y, int w, int h)
{
    chtype *line;

    line = ((chtype *) screen) + y * width;
    for (h += y; y < h; y ++, line += width)
        mvwaddchnstr(screenpad, y, 0, line, width);

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

static void curses_calc_pad(void)
{
    if (is_graphic_console()) {
        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(DisplayState *ds, int w, int h)
{
    if (w == gwidth && h == gheight)
        return;

    gwidth = w;
    gheight = h;

    curses_calc_pad();
}

#ifndef _WIN32
#if defined(SIGWINCH) && defined(KEY_RESIZE)
static void curses_winch_handler(int signum)
{
    struct winsize {
        unsigned short ws_row;
        unsigned short ws_col;
        unsigned short ws_xpixel;   /* unused */
        unsigned short ws_ypixel;   /* unused */
    } ws;

    /* terminal size changed */
    if (ioctl(1, TIOCGWINSZ, &ws) == -1)
        return;

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

    /* some systems require this */
    signal(SIGWINCH, curses_winch_handler);
}
#endif
#endif

static void curses_cursor_position(DisplayState *ds, 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 (!is_graphic_console())
                curs_set(2);
            return;
        }
    }

    curs_set(0);
}

/* generic keyboard conversion */

#include "curses_keys.h"
#include "keymaps.c"

static kbd_layout_t *kbd_layout = 0;
static int keycode2keysym[CURSES_KEYS];

static void curses_refresh(DisplayState *ds)
{
    int chr, nextchr, keysym, keycode;

    if (invalidate) {
        clear();
        refresh();
        curses_calc_pad();
        ds->width = FONT_WIDTH * width;
        ds->height = FONT_HEIGHT * height;
        vga_hw_invalidate();
        invalidate = 0;
    }

    vga_hw_text_update(screen);

    nextchr = ERR;
    while (1) {
        /* while there are any pending key strokes to process */
        if (nextchr == ERR)
            chr = getch();
        else {
            chr = nextchr;
            nextchr = ERR;
        }

        if (chr == ERR)
            break;

#ifdef KEY_RESIZE
        /* this shouldn't occur when we use a custom SIGWINCH handler */
        if (chr == KEY_RESIZE) {
            clear();
            refresh();
            curses_calc_pad();
            curses_update(ds, 0, 0, width, height);
            ds->width = FONT_WIDTH * width;
            ds->height = FONT_HEIGHT * height;
            continue;
        }
#endif

        keycode = curses2keycode[chr];
        if (keycode == -1)
            continue;

        /* alt key */
        if (keycode == 1) {
            nextchr = getch();

            if (nextchr != ERR) {
                keycode = curses2keycode[nextchr];
                nextchr = ERR;
                if (keycode == -1)
                    continue;

                keycode |= ALT;

                /* process keys reserved for qemu */
                if (keycode >= QEMU_KEY_CONSOLE0 &&
                        keycode < QEMU_KEY_CONSOLE0 + 9) {
                    erase();
                    wnoutrefresh(stdscr);
                    console_select(keycode - QEMU_KEY_CONSOLE0);

                    invalidate = 1;
                    continue;
                }
            }
        }

        if (kbd_layout && !(keycode & GREY)) {
            keysym = keycode2keysym[keycode & KEY_MASK];
            if (keysym == -1)
                keysym = chr;

            keycode &= ~KEY_MASK;
            keycode |= keysym2scancode(kbd_layout, keysym);
        }

        if (is_graphic_console()) {
            /* since terminals don't know about key press and release
             * events, we need to emit both for each key received */
            if (keycode & SHIFT)
                kbd_put_keycode(SHIFT_CODE);
            if (keycode & CNTRL)
                kbd_put_keycode(CNTRL_CODE);
            if (keycode & ALT)
                kbd_put_keycode(ALT_CODE);
            if (keycode & GREY)
                kbd_put_keycode(GREY_CODE);
            kbd_put_keycode(keycode & KEY_MASK);
            if (keycode & GREY)
                kbd_put_keycode(GREY_CODE);
            kbd_put_keycode((keycode & KEY_MASK) | KEY_RELEASE);
            if (keycode & ALT)
                kbd_put_keycode(ALT_CODE | KEY_RELEASE);
            if (keycode & CNTRL)
                kbd_put_keycode(CNTRL_CODE | KEY_RELEASE);
            if (keycode & SHIFT)
                kbd_put_keycode(SHIFT_CODE | KEY_RELEASE);
        } else {
            keysym = curses2keysym[chr];
            if (keysym == -1)
                keysym = chr;

            kbd_put_keysym(keysym);
        }
    }
}

static void curses_cleanup(void *opaque) 
{
    endwin();
}

static void curses_atexit(void)
{
    curses_cleanup(NULL);
}

static void curses_setup(void)
{
    int i, colour_default[8] = {
        COLOR_BLACK, COLOR_BLUE, COLOR_GREEN, COLOR_CYAN,
        COLOR_RED, COLOR_MAGENTA, COLOR_YELLOW, 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);

    for (i = 0; i < 64; i ++)
        init_pair(i, colour_default[i & 7], colour_default[i >> 3]);
}

static void curses_keyboard_setup(void)
{
    int i, keycode, keysym;

#if defined(__APPLE__)
    /* always use generic keymaps */
    if (!keyboard_layout)
        keyboard_layout = "en-us";
#endif
    if(keyboard_layout) {
        kbd_layout = init_keyboard_layout(keyboard_layout);
        if (!kbd_layout)
            exit(1);
    }

    for (i = 0; i < CURSES_KEYS; i ++)
        keycode2keysym[i] = -1;

    for (i = 0; i < CURSES_KEYS; i ++) {
        if (curses2keycode[i] == -1)
            continue;

        keycode = curses2keycode[i] & KEY_MASK;
        if (keycode2keysym[keycode] >= 0)
            continue;

        for (keysym = 0; keysym < CURSES_KEYS; keysym ++)
            if (curses2keycode[keysym] == keycode) {
                keycode2keysym[keycode] = keysym;
                break;
            }

        if (keysym >= CURSES_KEYS)
            keycode2keysym[keycode] = i;
    }
}

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

    curses_setup();
    curses_keyboard_setup();
    atexit(curses_atexit);

#ifndef _WIN32
    signal(SIGINT, SIG_DFL);
    signal(SIGQUIT, SIG_DFL);
#if defined(SIGWINCH) && defined(KEY_RESIZE)
    /* some curses implementations provide a handler, but we
     * want to be sure this is handled regardless of the library */
    signal(SIGWINCH, curses_winch_handler);
#endif
#endif

    ds->data = (void *) screen;
    ds->linesize = 0;
    ds->depth = 0;
    ds->width = 640;
    ds->height = 400;
    ds->dpy_update = curses_update;
    ds->dpy_resize = curses_resize;
    ds->dpy_refresh = curses_refresh;
    ds->dpy_text_cursor = curses_cursor_position;

    invalidate = 1;

    /* Standard VGA initial text mode dimensions */
    curses_resize(ds, 80, 25);
}
