Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 1 | /* |
| 2 | * replay-input.c |
| 3 | * |
| 4 | * Copyright (c) 2010-2015 Institute for System Programming |
| 5 | * of the Russian Academy of Sciences. |
| 6 | * |
| 7 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 8 | * See the COPYING file in the top-level directory. |
| 9 | * |
| 10 | */ |
| 11 | |
Peter Maydell | d38ea87 | 2016-01-29 17:50:05 +0000 | [diff] [blame] | 12 | #include "qemu/osdep.h" |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 13 | #include "sysemu/replay.h" |
| 14 | #include "replay-internal.h" |
| 15 | #include "qemu/notify.h" |
| 16 | #include "ui/input.h" |
Eric Blake | b695471 | 2016-06-09 10:48:46 -0600 | [diff] [blame] | 17 | #include "qapi/clone-visitor.h" |
Markus Armbruster | 9af2398 | 2018-02-11 10:36:01 +0100 | [diff] [blame] | 18 | #include "qapi/qapi-visit-ui.h" |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 19 | |
| 20 | void replay_save_input_event(InputEvent *evt) |
| 21 | { |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 22 | InputKeyEvent *key; |
| 23 | InputBtnEvent *btn; |
| 24 | InputMoveEvent *move; |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 25 | replay_put_dword(evt->type); |
| 26 | |
| 27 | switch (evt->type) { |
| 28 | case INPUT_EVENT_KIND_KEY: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 29 | key = evt->u.key.data; |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 30 | replay_put_dword(key->key->type); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 31 | |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 32 | switch (key->key->type) { |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 33 | case KEY_VALUE_KIND_NUMBER: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 34 | replay_put_qword(key->key->u.number.data); |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 35 | replay_put_byte(key->down); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 36 | break; |
| 37 | case KEY_VALUE_KIND_QCODE: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 38 | replay_put_dword(key->key->u.qcode.data); |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 39 | replay_put_byte(key->down); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 40 | break; |
Eric Blake | 7fb1cf1 | 2015-11-18 01:52:57 -0700 | [diff] [blame] | 41 | case KEY_VALUE_KIND__MAX: |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 42 | /* keep gcc happy */ |
| 43 | break; |
| 44 | } |
| 45 | break; |
| 46 | case INPUT_EVENT_KIND_BTN: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 47 | btn = evt->u.btn.data; |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 48 | replay_put_dword(btn->button); |
| 49 | replay_put_byte(btn->down); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 50 | break; |
| 51 | case INPUT_EVENT_KIND_REL: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 52 | move = evt->u.rel.data; |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 53 | replay_put_dword(move->axis); |
| 54 | replay_put_qword(move->value); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 55 | break; |
| 56 | case INPUT_EVENT_KIND_ABS: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 57 | move = evt->u.abs.data; |
Eric Blake | b5a1b44 | 2016-03-03 09:16:49 -0700 | [diff] [blame] | 58 | replay_put_dword(move->axis); |
| 59 | replay_put_qword(move->value); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 60 | break; |
Eric Blake | 7fb1cf1 | 2015-11-18 01:52:57 -0700 | [diff] [blame] | 61 | case INPUT_EVENT_KIND__MAX: |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 62 | /* keep gcc happy */ |
| 63 | break; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | InputEvent *replay_read_input_event(void) |
| 68 | { |
| 69 | InputEvent evt; |
| 70 | KeyValue keyValue; |
| 71 | InputKeyEvent key; |
| 72 | key.key = &keyValue; |
| 73 | InputBtnEvent btn; |
| 74 | InputMoveEvent rel; |
| 75 | InputMoveEvent abs; |
| 76 | |
| 77 | evt.type = replay_get_dword(); |
| 78 | switch (evt.type) { |
| 79 | case INPUT_EVENT_KIND_KEY: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 80 | evt.u.key.data = &key; |
| 81 | evt.u.key.data->key->type = replay_get_dword(); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 82 | |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 83 | switch (evt.u.key.data->key->type) { |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 84 | case KEY_VALUE_KIND_NUMBER: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 85 | evt.u.key.data->key->u.number.data = replay_get_qword(); |
| 86 | evt.u.key.data->down = replay_get_byte(); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 87 | break; |
| 88 | case KEY_VALUE_KIND_QCODE: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 89 | evt.u.key.data->key->u.qcode.data = (QKeyCode)replay_get_dword(); |
| 90 | evt.u.key.data->down = replay_get_byte(); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 91 | break; |
Eric Blake | 7fb1cf1 | 2015-11-18 01:52:57 -0700 | [diff] [blame] | 92 | case KEY_VALUE_KIND__MAX: |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 93 | /* keep gcc happy */ |
| 94 | break; |
| 95 | } |
| 96 | break; |
| 97 | case INPUT_EVENT_KIND_BTN: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 98 | evt.u.btn.data = &btn; |
| 99 | evt.u.btn.data->button = (InputButton)replay_get_dword(); |
| 100 | evt.u.btn.data->down = replay_get_byte(); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 101 | break; |
| 102 | case INPUT_EVENT_KIND_REL: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 103 | evt.u.rel.data = &rel; |
| 104 | evt.u.rel.data->axis = (InputAxis)replay_get_dword(); |
| 105 | evt.u.rel.data->value = replay_get_qword(); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 106 | break; |
| 107 | case INPUT_EVENT_KIND_ABS: |
Eric Blake | 32bafa8 | 2016-03-17 16:48:37 -0600 | [diff] [blame] | 108 | evt.u.abs.data = &abs; |
| 109 | evt.u.abs.data->axis = (InputAxis)replay_get_dword(); |
| 110 | evt.u.abs.data->value = replay_get_qword(); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 111 | break; |
Eric Blake | 7fb1cf1 | 2015-11-18 01:52:57 -0700 | [diff] [blame] | 112 | case INPUT_EVENT_KIND__MAX: |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 113 | /* keep gcc happy */ |
| 114 | break; |
| 115 | } |
| 116 | |
Eric Blake | b695471 | 2016-06-09 10:48:46 -0600 | [diff] [blame] | 117 | return QAPI_CLONE(InputEvent, &evt); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | void replay_input_event(QemuConsole *src, InputEvent *evt) |
| 121 | { |
| 122 | if (replay_mode == REPLAY_MODE_PLAY) { |
| 123 | /* Nothing */ |
| 124 | } else if (replay_mode == REPLAY_MODE_RECORD) { |
Eric Blake | b695471 | 2016-06-09 10:48:46 -0600 | [diff] [blame] | 125 | replay_add_input_event(QAPI_CLONE(InputEvent, evt)); |
Pavel Dovgalyuk | ee31299 | 2015-09-17 19:25:24 +0300 | [diff] [blame] | 126 | } else { |
| 127 | qemu_input_event_send_impl(src, evt); |
| 128 | } |
| 129 | } |
| 130 | |
| 131 | void replay_input_sync_event(void) |
| 132 | { |
| 133 | if (replay_mode == REPLAY_MODE_PLAY) { |
| 134 | /* Nothing */ |
| 135 | } else if (replay_mode == REPLAY_MODE_RECORD) { |
| 136 | replay_add_input_sync_event(); |
| 137 | } else { |
| 138 | qemu_input_event_sync_impl(); |
| 139 | } |
| 140 | } |