2 * This work is licensed under the terms of the GNU GPL, version 2 or
3 * (at your option) any later version. See the COPYING file in the
7 #include "qemu-common.h"
8 #include "qemu/sockets.h"
11 #include "hw/virtio/virtio.h"
12 #include "hw/virtio/virtio-input.h"
14 #include <sys/ioctl.h>
15 #include "standard-headers/linux/input.h"
17 /* ----------------------------------------------------------------- */
19 static struct virtio_input_config virtio_input_host_config
[] = {
23 static void virtio_input_host_event(void *opaque
)
25 VirtIOInputHost
*vih
= opaque
;
26 VirtIOInput
*vinput
= VIRTIO_INPUT(vih
);
27 struct virtio_input_event virtio
;
28 struct input_event evdev
;
32 rc
= read(vih
->fd
, &evdev
, sizeof(evdev
));
33 if (rc
!= sizeof(evdev
)) {
37 virtio
.type
= cpu_to_le16(evdev
.type
);
38 virtio
.code
= cpu_to_le16(evdev
.code
);
39 virtio
.value
= cpu_to_le32(evdev
.value
);
40 virtio_input_send(vinput
, &virtio
);
44 static void virtio_input_bits_config(VirtIOInputHost
*vih
,
47 virtio_input_config bits
;
50 memset(&bits
, 0, sizeof(bits
));
51 rc
= ioctl(vih
->fd
, EVIOCGBIT(type
, count
/8), bits
.u
.bitmap
);
56 for (i
= 0; i
< count
/8; i
++) {
57 if (bits
.u
.bitmap
[i
]) {
65 bits
.select
= VIRTIO_INPUT_CFG_EV_BITS
;
68 virtio_input_add_config(VIRTIO_INPUT(vih
), &bits
);
71 static void virtio_input_host_realize(DeviceState
*dev
, Error
**errp
)
73 VirtIOInputHost
*vih
= VIRTIO_INPUT_HOST(dev
);
74 VirtIOInput
*vinput
= VIRTIO_INPUT(dev
);
75 virtio_input_config id
;
80 error_setg(errp
, "evdev property is required");
84 vih
->fd
= open(vih
->evdev
, O_RDWR
);
86 error_setg_file_open(errp
, errno
, vih
->evdev
);
89 qemu_set_nonblock(vih
->fd
);
91 rc
= ioctl(vih
->fd
, EVIOCGVERSION
, &ver
);
93 error_setg(errp
, "%s: is not an evdev device", vih
->evdev
);
97 rc
= ioctl(vih
->fd
, EVIOCGRAB
, 1);
99 error_setg_errno(errp
, errno
, "%s: failed to get exclusive access",
104 memset(&id
, 0, sizeof(id
));
105 ioctl(vih
->fd
, EVIOCGNAME(sizeof(id
.u
.string
)-1), id
.u
.string
);
106 id
.select
= VIRTIO_INPUT_CFG_ID_NAME
;
107 id
.size
= strlen(id
.u
.string
);
108 virtio_input_add_config(vinput
, &id
);
110 if (ioctl(vih
->fd
, EVIOCGID
, &ids
) == 0) {
111 memset(&id
, 0, sizeof(id
));
112 id
.select
= VIRTIO_INPUT_CFG_ID_DEVIDS
;
113 id
.size
= sizeof(struct virtio_input_devids
);
114 id
.u
.ids
.bustype
= cpu_to_le16(ids
.bustype
);
115 id
.u
.ids
.vendor
= cpu_to_le16(ids
.vendor
);
116 id
.u
.ids
.product
= cpu_to_le16(ids
.product
);
117 id
.u
.ids
.version
= cpu_to_le16(ids
.version
);
118 virtio_input_add_config(vinput
, &id
);
121 virtio_input_bits_config(vih
, EV_KEY
, KEY_CNT
);
122 virtio_input_bits_config(vih
, EV_REL
, REL_CNT
);
123 virtio_input_bits_config(vih
, EV_ABS
, ABS_CNT
);
124 virtio_input_bits_config(vih
, EV_MSC
, MSC_CNT
);
125 virtio_input_bits_config(vih
, EV_SW
, SW_CNT
);
127 qemu_set_fd_handler(vih
->fd
, virtio_input_host_event
, NULL
, vih
);
136 static void virtio_input_host_unrealize(DeviceState
*dev
, Error
**errp
)
138 VirtIOInputHost
*vih
= VIRTIO_INPUT_HOST(dev
);
141 qemu_set_fd_handler(vih
->fd
, NULL
, NULL
, NULL
);
146 static const VMStateDescription vmstate_virtio_input_host
= {
147 .name
= "virtio-input-host",
151 static Property virtio_input_host_properties
[] = {
152 DEFINE_PROP_STRING("evdev", VirtIOInputHost
, evdev
),
153 DEFINE_PROP_END_OF_LIST(),
156 static void virtio_input_host_class_init(ObjectClass
*klass
, void *data
)
158 VirtIOInputClass
*vic
= VIRTIO_INPUT_CLASS(klass
);
159 DeviceClass
*dc
= DEVICE_CLASS(klass
);
161 dc
->vmsd
= &vmstate_virtio_input_host
;
162 dc
->props
= virtio_input_host_properties
;
163 vic
->realize
= virtio_input_host_realize
;
164 vic
->unrealize
= virtio_input_host_unrealize
;
167 static void virtio_input_host_init(Object
*obj
)
169 VirtIOInput
*vinput
= VIRTIO_INPUT(obj
);
171 virtio_input_init_config(vinput
, virtio_input_host_config
);
174 static const TypeInfo virtio_input_host_info
= {
175 .name
= TYPE_VIRTIO_INPUT_HOST
,
176 .parent
= TYPE_VIRTIO_INPUT
,
177 .instance_size
= sizeof(VirtIOInputHost
),
178 .instance_init
= virtio_input_host_init
,
179 .class_init
= virtio_input_host_class_init
,
182 /* ----------------------------------------------------------------- */
184 static void virtio_register_types(void)
186 type_register_static(&virtio_input_host_info
);
189 type_init(virtio_register_types
)