/*
 * replay-input.c
 *
 * Copyright (c) 2010-2015 Institute for System Programming
 *                         of the Russian Academy of Sciences.
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "qemu-common.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
#include "qemu/notify.h"
#include "ui/input.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-ui.h"

void replay_save_input_event(InputEvent *evt)
{
    InputKeyEvent *key;
    InputBtnEvent *btn;
    InputMoveEvent *move;
    replay_put_dword(evt->type);

    switch (evt->type) {
    case INPUT_EVENT_KIND_KEY:
        key = evt->u.key.data;
        replay_put_dword(key->key->type);

        switch (key->key->type) {
        case KEY_VALUE_KIND_NUMBER:
            replay_put_qword(key->key->u.number.data);
            replay_put_byte(key->down);
            break;
        case KEY_VALUE_KIND_QCODE:
            replay_put_dword(key->key->u.qcode.data);
            replay_put_byte(key->down);
            break;
        case KEY_VALUE_KIND__MAX:
            /* keep gcc happy */
            break;
        }
        break;
    case INPUT_EVENT_KIND_BTN:
        btn = evt->u.btn.data;
        replay_put_dword(btn->button);
        replay_put_byte(btn->down);
        break;
    case INPUT_EVENT_KIND_REL:
        move = evt->u.rel.data;
        replay_put_dword(move->axis);
        replay_put_qword(move->value);
        break;
    case INPUT_EVENT_KIND_ABS:
        move = evt->u.abs.data;
        replay_put_dword(move->axis);
        replay_put_qword(move->value);
        break;
    case INPUT_EVENT_KIND__MAX:
        /* keep gcc happy */
        break;
    }
}

InputEvent *replay_read_input_event(void)
{
    InputEvent evt;
    KeyValue keyValue;
    InputKeyEvent key;
    key.key = &keyValue;
    InputBtnEvent btn;
    InputMoveEvent rel;
    InputMoveEvent abs;

    evt.type = replay_get_dword();
    switch (evt.type) {
    case INPUT_EVENT_KIND_KEY:
        evt.u.key.data = &key;
        evt.u.key.data->key->type = replay_get_dword();

        switch (evt.u.key.data->key->type) {
        case KEY_VALUE_KIND_NUMBER:
            evt.u.key.data->key->u.number.data = replay_get_qword();
            evt.u.key.data->down = replay_get_byte();
            break;
        case KEY_VALUE_KIND_QCODE:
            evt.u.key.data->key->u.qcode.data = (QKeyCode)replay_get_dword();
            evt.u.key.data->down = replay_get_byte();
            break;
        case KEY_VALUE_KIND__MAX:
            /* keep gcc happy */
            break;
        }
        break;
    case INPUT_EVENT_KIND_BTN:
        evt.u.btn.data = &btn;
        evt.u.btn.data->button = (InputButton)replay_get_dword();
        evt.u.btn.data->down = replay_get_byte();
        break;
    case INPUT_EVENT_KIND_REL:
        evt.u.rel.data = &rel;
        evt.u.rel.data->axis = (InputAxis)replay_get_dword();
        evt.u.rel.data->value = replay_get_qword();
        break;
    case INPUT_EVENT_KIND_ABS:
        evt.u.abs.data = &abs;
        evt.u.abs.data->axis = (InputAxis)replay_get_dword();
        evt.u.abs.data->value = replay_get_qword();
        break;
    case INPUT_EVENT_KIND__MAX:
        /* keep gcc happy */
        break;
    }

    return QAPI_CLONE(InputEvent, &evt);
}

void replay_input_event(QemuConsole *src, InputEvent *evt)
{
    if (replay_mode == REPLAY_MODE_PLAY) {
        /* Nothing */
    } else if (replay_mode == REPLAY_MODE_RECORD) {
        replay_add_input_event(QAPI_CLONE(InputEvent, evt));
    } else {
        qemu_input_event_send_impl(src, evt);
    }
}

void replay_input_sync_event(void)
{
    if (replay_mode == REPLAY_MODE_PLAY) {
        /* Nothing */
    } else if (replay_mode == REPLAY_MODE_RECORD) {
        replay_add_input_sync_event();
    } else {
        qemu_input_event_sync_impl();
    }
}
