9
#include "qemu/module.h"
10
#include "qemu/sockets.h"
12
#include "hw/virtio/virtio.h"
13
#include "hw/qdev-properties.h"
14
#include "hw/virtio/virtio-input.h"
17
#include "standard-headers/linux/input.h"
21
static struct virtio_input_config virtio_input_host_config[] = {
25
static void virtio_input_host_event(void *opaque)
27
VirtIOInputHost *vih = opaque;
28
VirtIOInput *vinput = VIRTIO_INPUT(vih);
29
struct virtio_input_event virtio;
30
struct input_event evdev;
34
rc = read(vih->fd, &evdev, sizeof(evdev));
35
if (rc != sizeof(evdev)) {
39
virtio.type = cpu_to_le16(evdev.type);
40
virtio.code = cpu_to_le16(evdev.code);
41
virtio.value = cpu_to_le32(evdev.value);
42
virtio_input_send(vinput, &virtio);
46
static void virtio_input_bits_config(VirtIOInputHost *vih,
49
virtio_input_config bits;
52
memset(&bits, 0, sizeof(bits));
53
rc = ioctl(vih->fd, EVIOCGBIT(type, count/8), bits.u.bitmap);
58
for (i = 0; i < count/8; i++) {
59
if (bits.u.bitmap[i]) {
67
bits.select = VIRTIO_INPUT_CFG_EV_BITS;
70
virtio_input_add_config(VIRTIO_INPUT(vih), &bits);
73
static void virtio_input_abs_config(VirtIOInputHost *vih, int axis)
75
virtio_input_config config;
76
struct input_absinfo absinfo;
79
rc = ioctl(vih->fd, EVIOCGABS(axis), &absinfo);
84
memset(&config, 0, sizeof(config));
85
config.select = VIRTIO_INPUT_CFG_ABS_INFO;
87
config.size = sizeof(virtio_input_absinfo);
89
config.u.abs.min = cpu_to_le32(absinfo.minimum);
90
config.u.abs.max = cpu_to_le32(absinfo.maximum);
91
config.u.abs.fuzz = cpu_to_le32(absinfo.fuzz);
92
config.u.abs.flat = cpu_to_le32(absinfo.flat);
93
config.u.abs.res = cpu_to_le32(absinfo.resolution);
95
virtio_input_add_config(VIRTIO_INPUT(vih), &config);
98
static void virtio_input_host_realize(DeviceState *dev, Error **errp)
100
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
101
VirtIOInput *vinput = VIRTIO_INPUT(dev);
102
virtio_input_config id, *abs;
104
int rc, ver, i, axis;
108
error_setg(errp, "evdev property is required");
112
vih->fd = open(vih->evdev, O_RDWR);
114
error_setg_file_open(errp, errno, vih->evdev);
117
if (!g_unix_set_fd_nonblocking(vih->fd, true, NULL)) {
118
error_setg_errno(errp, errno, "Failed to set FD nonblocking");
122
rc = ioctl(vih->fd, EVIOCGVERSION, &ver);
124
error_setg(errp, "%s: is not an evdev device", vih->evdev);
128
rc = ioctl(vih->fd, EVIOCGRAB, 1);
130
error_setg_errno(errp, errno, "%s: failed to get exclusive access",
135
memset(&id, 0, sizeof(id));
136
ioctl(vih->fd, EVIOCGNAME(sizeof(id.u.string)-1), id.u.string);
137
id.select = VIRTIO_INPUT_CFG_ID_NAME;
138
id.size = strlen(id.u.string);
139
virtio_input_add_config(vinput, &id);
141
if (ioctl(vih->fd, EVIOCGID, &ids) == 0) {
142
memset(&id, 0, sizeof(id));
143
id.select = VIRTIO_INPUT_CFG_ID_DEVIDS;
144
id.size = sizeof(struct virtio_input_devids);
145
id.u.ids.bustype = cpu_to_le16(ids.bustype);
146
id.u.ids.vendor = cpu_to_le16(ids.vendor);
147
id.u.ids.product = cpu_to_le16(ids.product);
148
id.u.ids.version = cpu_to_le16(ids.version);
149
virtio_input_add_config(vinput, &id);
152
virtio_input_bits_config(vih, EV_KEY, KEY_CNT);
153
virtio_input_bits_config(vih, EV_REL, REL_CNT);
154
virtio_input_bits_config(vih, EV_ABS, ABS_CNT);
155
virtio_input_bits_config(vih, EV_MSC, MSC_CNT);
156
virtio_input_bits_config(vih, EV_SW, SW_CNT);
157
virtio_input_bits_config(vih, EV_LED, LED_CNT);
159
abs = virtio_input_find_config(VIRTIO_INPUT(vih),
160
VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
162
for (i = 0; i < abs->size; i++) {
163
byte = abs->u.bitmap[i];
167
virtio_input_abs_config(vih, axis);
175
qemu_set_fd_handler(vih->fd, virtio_input_host_event, NULL, vih);
184
static void virtio_input_host_unrealize(DeviceState *dev)
186
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(dev);
189
qemu_set_fd_handler(vih->fd, NULL, NULL, NULL);
194
static void virtio_input_host_handle_status(VirtIOInput *vinput,
195
virtio_input_event *event)
197
VirtIOInputHost *vih = VIRTIO_INPUT_HOST(vinput);
198
struct input_event evdev;
202
if (gettimeofday(&tval, NULL)) {
203
perror("virtio_input_host_handle_status: gettimeofday");
207
evdev.input_event_sec = tval.tv_sec;
208
evdev.input_event_usec = tval.tv_usec;
209
evdev.type = le16_to_cpu(event->type);
210
evdev.code = le16_to_cpu(event->code);
211
evdev.value = le32_to_cpu(event->value);
213
rc = write(vih->fd, &evdev, sizeof(evdev));
215
perror("virtio_input_host_handle_status: write");
219
static const VMStateDescription vmstate_virtio_input_host = {
220
.name = "virtio-input-host",
224
static Property virtio_input_host_properties[] = {
225
DEFINE_PROP_STRING("evdev", VirtIOInputHost, evdev),
226
DEFINE_PROP_END_OF_LIST(),
229
static void virtio_input_host_class_init(ObjectClass *klass, void *data)
231
VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
232
DeviceClass *dc = DEVICE_CLASS(klass);
234
dc->vmsd = &vmstate_virtio_input_host;
235
device_class_set_props(dc, virtio_input_host_properties);
236
vic->realize = virtio_input_host_realize;
237
vic->unrealize = virtio_input_host_unrealize;
238
vic->handle_status = virtio_input_host_handle_status;
241
static void virtio_input_host_init(Object *obj)
243
VirtIOInput *vinput = VIRTIO_INPUT(obj);
245
virtio_input_init_config(vinput, virtio_input_host_config);
248
static const TypeInfo virtio_input_host_info = {
249
.name = TYPE_VIRTIO_INPUT_HOST,
250
.parent = TYPE_VIRTIO_INPUT,
251
.instance_size = sizeof(VirtIOInputHost),
252
.instance_init = virtio_input_host_init,
253
.class_init = virtio_input_host_class_init,
258
static void virtio_register_types(void)
260
type_register_static(&virtio_input_host_info);
263
type_init(virtio_register_types)