mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
QAPI represents union members with wrapper structs and pointer indirections. They are useful at the QMP boundary, but unnecessary for QEMU's internal input events and make handlers more verbose. Define QemuInputEvent as a plain internal tagged union and convert input handlers, queues, and replay code to access payloads directly. Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-ID: <20260520-input-v3-2-7c9e4c7abe34@rsg.ci.i.u-tokyo.ac.jp>
98 lines
2.8 KiB
C
98 lines
2.8 KiB
C
/*
|
|
* Gamepad style buttons connected to IRQ/GPIO lines
|
|
*
|
|
* Copyright (c) 2007 CodeSourcery.
|
|
* Written by Paul Brook
|
|
*
|
|
* This code is licensed under the GPL.
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qapi/error.h"
|
|
#include "hw/input/stellaris_gamepad.h"
|
|
#include "hw/core/irq.h"
|
|
#include "hw/core/qdev-properties.h"
|
|
#include "migration/vmstate.h"
|
|
#include "ui/console.h"
|
|
|
|
static void stellaris_gamepad_event(DeviceState *dev, QemuConsole *src,
|
|
QemuInputEvent *evt)
|
|
{
|
|
StellarisGamepad *s = STELLARIS_GAMEPAD(dev);
|
|
int qcode = qemu_input_key_value_to_qcode(&evt->key.key);
|
|
int i;
|
|
|
|
for (i = 0; i < s->num_buttons; i++) {
|
|
if (s->keycodes[i] == qcode && s->pressed[i] != evt->key.down) {
|
|
s->pressed[i] = evt->key.down;
|
|
qemu_set_irq(s->irqs[i], evt->key.down);
|
|
}
|
|
}
|
|
}
|
|
|
|
static const VMStateDescription vmstate_stellaris_gamepad = {
|
|
.name = "stellaris_gamepad",
|
|
.version_id = 4,
|
|
.minimum_version_id = 4,
|
|
.fields = (const VMStateField[]) {
|
|
VMSTATE_VARRAY_UINT32(pressed, StellarisGamepad, num_buttons,
|
|
0, vmstate_info_uint8, uint8_t),
|
|
VMSTATE_END_OF_LIST()
|
|
}
|
|
};
|
|
|
|
static const QemuInputHandler stellaris_gamepad_handler = {
|
|
.name = "Stellaris Gamepad",
|
|
.mask = INPUT_EVENT_MASK_KEY,
|
|
.event = stellaris_gamepad_event,
|
|
};
|
|
|
|
static void stellaris_gamepad_realize(DeviceState *dev, Error **errp)
|
|
{
|
|
StellarisGamepad *s = STELLARIS_GAMEPAD(dev);
|
|
|
|
if (s->num_buttons == 0) {
|
|
error_setg(errp, "keycodes property array must be set");
|
|
return;
|
|
}
|
|
|
|
s->irqs = g_new0(qemu_irq, s->num_buttons);
|
|
s->pressed = g_new0(uint8_t, s->num_buttons);
|
|
qdev_init_gpio_out(dev, s->irqs, s->num_buttons);
|
|
qemu_input_handler_register(dev, &stellaris_gamepad_handler);
|
|
}
|
|
|
|
static void stellaris_gamepad_reset_enter(Object *obj, ResetType type)
|
|
{
|
|
StellarisGamepad *s = STELLARIS_GAMEPAD(obj);
|
|
|
|
memset(s->pressed, 0, s->num_buttons * sizeof(uint8_t));
|
|
}
|
|
|
|
static const Property stellaris_gamepad_properties[] = {
|
|
DEFINE_PROP_ARRAY("keycodes", StellarisGamepad, num_buttons,
|
|
keycodes, qdev_prop_uint32, uint32_t),
|
|
};
|
|
|
|
static void stellaris_gamepad_class_init(ObjectClass *klass, const void *data)
|
|
{
|
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
|
ResettableClass *rc = RESETTABLE_CLASS(klass);
|
|
|
|
rc->phases.enter = stellaris_gamepad_reset_enter;
|
|
dc->realize = stellaris_gamepad_realize;
|
|
dc->vmsd = &vmstate_stellaris_gamepad;
|
|
device_class_set_props(dc, stellaris_gamepad_properties);
|
|
}
|
|
|
|
static const TypeInfo stellaris_gamepad_info[] = {
|
|
{
|
|
.name = TYPE_STELLARIS_GAMEPAD,
|
|
.parent = TYPE_SYS_BUS_DEVICE,
|
|
.instance_size = sizeof(StellarisGamepad),
|
|
.class_init = stellaris_gamepad_class_init,
|
|
},
|
|
};
|
|
|
|
DEFINE_TYPES(stellaris_gamepad_info);
|