cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

input-legacy.c (8133B)


      1/*
      2 * QEMU System Emulator
      3 *
      4 * Copyright (c) 2003-2008 Fabrice Bellard
      5 *
      6 * Permission is hereby granted, free of charge, to any person obtaining a copy
      7 * of this software and associated documentation files (the "Software"), to deal
      8 * in the Software without restriction, including without limitation the rights
      9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10 * copies of the Software, and to permit persons to whom the Software is
     11 * furnished to do so, subject to the following conditions:
     12 *
     13 * The above copyright notice and this permission notice shall be included in
     14 * all copies or substantial portions of the Software.
     15 *
     16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
     19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     22 * THE SOFTWARE.
     23 */
     24
     25#include "qemu/osdep.h"
     26#include "qapi/qapi-commands-ui.h"
     27#include "ui/console.h"
     28#include "keymaps.h"
     29#include "ui/input.h"
     30
     31struct QEMUPutMouseEntry {
     32    QEMUPutMouseEvent *qemu_put_mouse_event;
     33    void *qemu_put_mouse_event_opaque;
     34    int qemu_put_mouse_event_absolute;
     35
     36    /* new input core */
     37    QemuInputHandler h;
     38    QemuInputHandlerState *s;
     39    int axis[INPUT_AXIS__MAX];
     40    int buttons;
     41};
     42
     43struct QEMUPutKbdEntry {
     44    QEMUPutKBDEvent *put_kbd;
     45    void *opaque;
     46    QemuInputHandlerState *s;
     47};
     48
     49struct QEMUPutLEDEntry {
     50    QEMUPutLEDEvent *put_led;
     51    void *opaque;
     52    QTAILQ_ENTRY(QEMUPutLEDEntry) next;
     53};
     54
     55static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
     56    QTAILQ_HEAD_INITIALIZER(led_handlers);
     57
     58int index_from_key(const char *key, size_t key_length)
     59{
     60    int i;
     61
     62    for (i = 0; i < Q_KEY_CODE__MAX; i++) {
     63        if (!strncmp(key, QKeyCode_str(i), key_length) &&
     64            !QKeyCode_str(i)[key_length]) {
     65            break;
     66        }
     67    }
     68
     69    /* Return Q_KEY_CODE__MAX if the key is invalid */
     70    return i;
     71}
     72
     73static KeyValue *copy_key_value(KeyValue *src)
     74{
     75    KeyValue *dst = g_new(KeyValue, 1);
     76    memcpy(dst, src, sizeof(*src));
     77    if (dst->type == KEY_VALUE_KIND_NUMBER) {
     78        QKeyCode code = qemu_input_key_number_to_qcode(dst->u.number.data);
     79        dst->type = KEY_VALUE_KIND_QCODE;
     80        dst->u.qcode.data = code;
     81    }
     82    return dst;
     83}
     84
     85void qmp_send_key(KeyValueList *keys, bool has_hold_time, int64_t hold_time,
     86                  Error **errp)
     87{
     88    KeyValueList *p;
     89    KeyValue **up = NULL;
     90    int count = 0;
     91
     92    if (!has_hold_time) {
     93        hold_time = 0; /* use default */
     94    }
     95
     96    for (p = keys; p != NULL; p = p->next) {
     97        qemu_input_event_send_key(NULL, copy_key_value(p->value), true);
     98        qemu_input_event_send_key_delay(hold_time);
     99        up = g_realloc(up, sizeof(*up) * (count+1));
    100        up[count] = copy_key_value(p->value);
    101        count++;
    102    }
    103    while (count) {
    104        count--;
    105        qemu_input_event_send_key(NULL, up[count], false);
    106        qemu_input_event_send_key_delay(hold_time);
    107    }
    108    g_free(up);
    109}
    110
    111static void legacy_kbd_event(DeviceState *dev, QemuConsole *src,
    112                             InputEvent *evt)
    113{
    114    QEMUPutKbdEntry *entry = (QEMUPutKbdEntry *)dev;
    115    int scancodes[3], i, count;
    116    InputKeyEvent *key = evt->u.key.data;
    117
    118    if (!entry || !entry->put_kbd) {
    119        return;
    120    }
    121    count = qemu_input_key_value_to_scancode(key->key,
    122                                             key->down,
    123                                             scancodes);
    124    for (i = 0; i < count; i++) {
    125        entry->put_kbd(entry->opaque, scancodes[i]);
    126    }
    127}
    128
    129static QemuInputHandler legacy_kbd_handler = {
    130    .name  = "legacy-kbd",
    131    .mask  = INPUT_EVENT_MASK_KEY,
    132    .event = legacy_kbd_event,
    133};
    134
    135QEMUPutKbdEntry *qemu_add_kbd_event_handler(QEMUPutKBDEvent *func, void *opaque)
    136{
    137    QEMUPutKbdEntry *entry;
    138
    139    entry = g_new0(QEMUPutKbdEntry, 1);
    140    entry->put_kbd = func;
    141    entry->opaque = opaque;
    142    entry->s = qemu_input_handler_register((DeviceState *)entry,
    143                                           &legacy_kbd_handler);
    144    qemu_input_handler_activate(entry->s);
    145    return entry;
    146}
    147
    148static void legacy_mouse_event(DeviceState *dev, QemuConsole *src,
    149                               InputEvent *evt)
    150{
    151    static const int bmap[INPUT_BUTTON__MAX] = {
    152        [INPUT_BUTTON_LEFT]   = MOUSE_EVENT_LBUTTON,
    153        [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON,
    154        [INPUT_BUTTON_RIGHT]  = MOUSE_EVENT_RBUTTON,
    155    };
    156    QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
    157    InputBtnEvent *btn;
    158    InputMoveEvent *move;
    159
    160    switch (evt->type) {
    161    case INPUT_EVENT_KIND_BTN:
    162        btn = evt->u.btn.data;
    163        if (btn->down) {
    164            s->buttons |= bmap[btn->button];
    165        } else {
    166            s->buttons &= ~bmap[btn->button];
    167        }
    168        if (btn->down && btn->button == INPUT_BUTTON_WHEEL_UP) {
    169            s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
    170                                    s->axis[INPUT_AXIS_X],
    171                                    s->axis[INPUT_AXIS_Y],
    172                                    -1,
    173                                    s->buttons);
    174        }
    175        if (btn->down && btn->button == INPUT_BUTTON_WHEEL_DOWN) {
    176            s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
    177                                    s->axis[INPUT_AXIS_X],
    178                                    s->axis[INPUT_AXIS_Y],
    179                                    1,
    180                                    s->buttons);
    181        }
    182        break;
    183    case INPUT_EVENT_KIND_ABS:
    184        move = evt->u.abs.data;
    185        s->axis[move->axis] = move->value;
    186        break;
    187    case INPUT_EVENT_KIND_REL:
    188        move = evt->u.rel.data;
    189        s->axis[move->axis] += move->value;
    190        break;
    191    default:
    192        break;
    193    }
    194}
    195
    196static void legacy_mouse_sync(DeviceState *dev)
    197{
    198    QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev;
    199
    200    s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque,
    201                            s->axis[INPUT_AXIS_X],
    202                            s->axis[INPUT_AXIS_Y],
    203                            0,
    204                            s->buttons);
    205
    206    if (!s->qemu_put_mouse_event_absolute) {
    207        s->axis[INPUT_AXIS_X] = 0;
    208        s->axis[INPUT_AXIS_Y] = 0;
    209    }
    210}
    211
    212QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,
    213                                                void *opaque, int absolute,
    214                                                const char *name)
    215{
    216    QEMUPutMouseEntry *s;
    217
    218    s = g_new0(QEMUPutMouseEntry, 1);
    219
    220    s->qemu_put_mouse_event = func;
    221    s->qemu_put_mouse_event_opaque = opaque;
    222    s->qemu_put_mouse_event_absolute = absolute;
    223
    224    s->h.name = name;
    225    s->h.mask = INPUT_EVENT_MASK_BTN |
    226        (absolute ? INPUT_EVENT_MASK_ABS : INPUT_EVENT_MASK_REL);
    227    s->h.event = legacy_mouse_event;
    228    s->h.sync = legacy_mouse_sync;
    229    s->s = qemu_input_handler_register((DeviceState *)s,
    230                                       &s->h);
    231
    232    return s;
    233}
    234
    235void qemu_activate_mouse_event_handler(QEMUPutMouseEntry *entry)
    236{
    237    qemu_input_handler_activate(entry->s);
    238}
    239
    240void qemu_remove_mouse_event_handler(QEMUPutMouseEntry *entry)
    241{
    242    qemu_input_handler_unregister(entry->s);
    243
    244    g_free(entry);
    245}
    246
    247QEMUPutLEDEntry *qemu_add_led_event_handler(QEMUPutLEDEvent *func,
    248                                            void *opaque)
    249{
    250    QEMUPutLEDEntry *s;
    251
    252    s = g_new0(QEMUPutLEDEntry, 1);
    253
    254    s->put_led = func;
    255    s->opaque = opaque;
    256    QTAILQ_INSERT_TAIL(&led_handlers, s, next);
    257    return s;
    258}
    259
    260void qemu_remove_led_event_handler(QEMUPutLEDEntry *entry)
    261{
    262    if (entry == NULL)
    263        return;
    264    QTAILQ_REMOVE(&led_handlers, entry, next);
    265    g_free(entry);
    266}
    267
    268void kbd_put_ledstate(int ledstate)
    269{
    270    QEMUPutLEDEntry *cursor;
    271
    272    QTAILQ_FOREACH(cursor, &led_handlers, next) {
    273        cursor->put_led(cursor->opaque, ledstate);
    274    }
    275}