| /* |
| * 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-common.h" |
| #include "sysemu/replay.h" |
| #include "replay-internal.h" |
| #include "qemu/notify.h" |
| #include "ui/input.h" |
| #include "qapi/qmp-output-visitor.h" |
| #include "qapi/qmp-input-visitor.h" |
| #include "qapi-visit.h" |
| |
| static InputEvent *qapi_clone_InputEvent(InputEvent *src) |
| { |
| QmpOutputVisitor *qov; |
| QmpInputVisitor *qiv; |
| Visitor *ov, *iv; |
| QObject *obj; |
| InputEvent *dst = NULL; |
| |
| qov = qmp_output_visitor_new(); |
| ov = qmp_output_get_visitor(qov); |
| visit_type_InputEvent(ov, &src, NULL, &error_abort); |
| obj = qmp_output_get_qobject(qov); |
| qmp_output_visitor_cleanup(qov); |
| if (!obj) { |
| return NULL; |
| } |
| |
| qiv = qmp_input_visitor_new(obj); |
| iv = qmp_input_get_visitor(qiv); |
| visit_type_InputEvent(iv, &dst, NULL, &error_abort); |
| qmp_input_visitor_cleanup(qiv); |
| qobject_decref(obj); |
| |
| return dst; |
| } |
| |
| void replay_save_input_event(InputEvent *evt) |
| { |
| replay_put_dword(evt->type); |
| |
| switch (evt->type) { |
| case INPUT_EVENT_KIND_KEY: |
| replay_put_dword(evt->u.key->key->type); |
| |
| switch (evt->u.key->key->type) { |
| case KEY_VALUE_KIND_NUMBER: |
| replay_put_qword(evt->u.key->key->u.number); |
| replay_put_byte(evt->u.key->down); |
| break; |
| case KEY_VALUE_KIND_QCODE: |
| replay_put_dword(evt->u.key->key->u.qcode); |
| replay_put_byte(evt->u.key->down); |
| break; |
| case KEY_VALUE_KIND__MAX: |
| /* keep gcc happy */ |
| break; |
| } |
| break; |
| case INPUT_EVENT_KIND_BTN: |
| replay_put_dword(evt->u.btn->button); |
| replay_put_byte(evt->u.btn->down); |
| break; |
| case INPUT_EVENT_KIND_REL: |
| replay_put_dword(evt->u.rel->axis); |
| replay_put_qword(evt->u.rel->value); |
| break; |
| case INPUT_EVENT_KIND_ABS: |
| replay_put_dword(evt->u.abs->axis); |
| replay_put_qword(evt->u.abs->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 = &key; |
| evt.u.key->key->type = replay_get_dword(); |
| |
| switch (evt.u.key->key->type) { |
| case KEY_VALUE_KIND_NUMBER: |
| evt.u.key->key->u.number = replay_get_qword(); |
| evt.u.key->down = replay_get_byte(); |
| break; |
| case KEY_VALUE_KIND_QCODE: |
| evt.u.key->key->u.qcode = (QKeyCode)replay_get_dword(); |
| evt.u.key->down = replay_get_byte(); |
| break; |
| case KEY_VALUE_KIND__MAX: |
| /* keep gcc happy */ |
| break; |
| } |
| break; |
| case INPUT_EVENT_KIND_BTN: |
| evt.u.btn = &btn; |
| evt.u.btn->button = (InputButton)replay_get_dword(); |
| evt.u.btn->down = replay_get_byte(); |
| break; |
| case INPUT_EVENT_KIND_REL: |
| evt.u.rel = &rel; |
| evt.u.rel->axis = (InputAxis)replay_get_dword(); |
| evt.u.rel->value = replay_get_qword(); |
| break; |
| case INPUT_EVENT_KIND_ABS: |
| evt.u.abs = &abs; |
| evt.u.abs->axis = (InputAxis)replay_get_dword(); |
| evt.u.abs->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(); |
| } |
| } |