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/osdep.h"
10 #include <linux/input.h>
13 #include "qemu/bswap.h"
14 #include "qemu/sockets.h"
15 #include "contrib/libvhost-user/libvhost-user.h"
16 #include "contrib/libvhost-user/libvhost-user-glib.h"
17 #include "standard-headers/linux/virtio_input.h"
18 #include "qapi/error.h"
20 typedef struct virtio_input_event virtio_input_event
;
21 typedef struct virtio_input_config virtio_input_config
;
23 typedef struct VuInput
{
28 virtio_input_config
*sel_config
;
30 virtio_input_event event
;
33 uint32_t qindex
, qsize
;
36 static void vi_input_send(VuInput
*vi
, struct virtio_input_event
*event
)
38 VuDev
*dev
= &vi
->dev
.parent
;
39 VuVirtq
*vq
= vu_get_queue(dev
, 0);
43 /* queue up events ... */
44 if (vi
->qindex
== vi
->qsize
) {
46 vi
->queue
= g_realloc_n(vi
->queue
, vi
->qsize
, sizeof(vi
->queue
[0]));
48 vi
->queue
[vi
->qindex
++].event
= *event
;
50 /* ... until we see a report sync ... */
51 if (event
->type
!= htole16(EV_SYN
) ||
52 event
->code
!= htole16(SYN_REPORT
)) {
56 /* ... then check available space ... */
57 for (i
= 0; i
< vi
->qindex
; i
++) {
58 elem
= vu_queue_pop(dev
, vq
, sizeof(VuVirtqElement
));
61 vu_queue_unpop(dev
, vq
, vi
->queue
[i
].elem
, 0);
64 g_warning("virtio-input queue full");
67 vi
->queue
[i
].elem
= elem
;
70 /* ... and finally pass them to the guest */
71 for (i
= 0; i
< vi
->qindex
; i
++) {
72 elem
= vi
->queue
[i
].elem
;
73 len
= iov_from_buf(elem
->in_sg
, elem
->in_num
,
74 0, &vi
->queue
[i
].event
, sizeof(virtio_input_event
));
75 vu_queue_push(dev
, vq
, elem
, len
);
79 vu_queue_notify(&vi
->dev
.parent
, vq
);
84 vi_evdev_watch(VuDev
*dev
, int condition
, void *data
)
89 g_debug("Got evdev condition %x", condition
);
91 struct virtio_input_event virtio
;
92 struct input_event evdev
;
96 rc
= read(fd
, &evdev
, sizeof(evdev
));
97 if (rc
!= sizeof(evdev
)) {
101 g_debug("input %d %d %d", evdev
.type
, evdev
.code
, evdev
.value
);
103 virtio
.type
= htole16(evdev
.type
);
104 virtio
.code
= htole16(evdev
.code
);
105 virtio
.value
= htole32(evdev
.value
);
106 vi_input_send(vi
, &virtio
);
111 static void vi_handle_status(VuInput
*vi
, virtio_input_event
*event
)
113 struct input_event evdev
;
116 if (gettimeofday(&evdev
.time
, NULL
)) {
117 perror("vi_handle_status: gettimeofday");
121 evdev
.type
= le16toh(event
->type
);
122 evdev
.code
= le16toh(event
->code
);
123 evdev
.value
= le32toh(event
->value
);
125 rc
= write(vi
->evdevfd
, &evdev
, sizeof(evdev
));
127 perror("vi_host_handle_status: write");
131 static void vi_handle_sts(VuDev
*dev
, int qidx
)
133 VuInput
*vi
= container_of(dev
, VuInput
, dev
.parent
);
134 VuVirtq
*vq
= vu_get_queue(dev
, qidx
);
135 virtio_input_event event
;
136 VuVirtqElement
*elem
;
139 g_debug("%s", G_STRFUNC
);
142 elem
= vu_queue_pop(dev
, vq
, sizeof(VuVirtqElement
));
147 memset(&event
, 0, sizeof(event
));
148 len
= iov_to_buf(elem
->out_sg
, elem
->out_num
,
149 0, &event
, sizeof(event
));
150 vi_handle_status(vi
, &event
);
151 vu_queue_push(dev
, vq
, elem
, len
);
155 vu_queue_notify(&vi
->dev
.parent
, vq
);
159 vi_panic(VuDev
*dev
, const char *msg
)
161 g_critical("%s\n", msg
);
166 vi_queue_set_started(VuDev
*dev
, int qidx
, bool started
)
168 VuInput
*vi
= container_of(dev
, VuInput
, dev
.parent
);
169 VuVirtq
*vq
= vu_get_queue(dev
, qidx
);
171 g_debug("queue started %d:%d", qidx
, started
);
174 vu_set_queue_handler(dev
, vq
, started
? vi_handle_sts
: NULL
);
177 started
= vu_queue_started(dev
, vu_get_queue(dev
, 0)) &&
178 vu_queue_started(dev
, vu_get_queue(dev
, 1));
180 if (started
&& !vi
->evsrc
) {
181 vi
->evsrc
= vug_source_new(&vi
->dev
, vi
->evdevfd
,
182 G_IO_IN
, vi_evdev_watch
, vi
);
185 if (!started
&& vi
->evsrc
) {
186 g_source_destroy(vi
->evsrc
);
191 static virtio_input_config
*
192 vi_find_config(VuInput
*vi
, uint8_t select
, uint8_t subsel
)
194 virtio_input_config
*cfg
;
197 for (i
= 0; i
< vi
->config
->len
; i
++) {
198 cfg
= &g_array_index(vi
->config
, virtio_input_config
, i
);
199 if (select
== cfg
->select
&& subsel
== cfg
->subsel
) {
207 static int vi_get_config(VuDev
*dev
, uint8_t *config
, uint32_t len
)
209 VuInput
*vi
= container_of(dev
, VuInput
, dev
.parent
);
211 g_return_val_if_fail(len
<= sizeof(*vi
->sel_config
), -1);
213 if (vi
->sel_config
) {
214 memcpy(config
, vi
->sel_config
, len
);
216 memset(config
, 0, len
);
222 static int vi_set_config(VuDev
*dev
, const uint8_t *data
,
223 uint32_t offset
, uint32_t size
,
226 VuInput
*vi
= container_of(dev
, VuInput
, dev
.parent
);
227 virtio_input_config
*config
= (virtio_input_config
*)data
;
229 vi
->sel_config
= vi_find_config(vi
, config
->select
, config
->subsel
);
234 static const VuDevIface vuiface
= {
235 .queue_set_started
= vi_queue_set_started
,
236 .get_config
= vi_get_config
,
237 .set_config
= vi_set_config
,
241 vi_bits_config(VuInput
*vi
, int type
, int count
)
243 virtio_input_config bits
;
246 memset(&bits
, 0, sizeof(bits
));
247 rc
= ioctl(vi
->evdevfd
, EVIOCGBIT(type
, count
/ 8), bits
.u
.bitmap
);
252 for (i
= 0; i
< count
/ 8; i
++) {
253 if (bits
.u
.bitmap
[i
]) {
261 bits
.select
= VIRTIO_INPUT_CFG_EV_BITS
;
264 g_array_append_val(vi
->config
, bits
);
267 static char *opt_evdev
;
268 static int opt_fdnum
= -1;
269 static char *opt_socket_path
;
270 static gboolean opt_nograb
;
271 static gboolean opt_print_caps
;
273 static GOptionEntry entries
[] = {
274 { "print-capabilities", 'c', 0, G_OPTION_ARG_NONE
, &opt_print_caps
,
275 "Print capabilities", NULL
},
276 { "no-grab", 'n', 0, G_OPTION_ARG_NONE
, &opt_nograb
,
277 "Don't grab device", NULL
},
278 { "fd", 'f', 0, G_OPTION_ARG_INT
, &opt_fdnum
,
279 "Use inherited fd socket", "FDNUM" },
280 { "socket-path", 's', 0, G_OPTION_ARG_FILENAME
, &opt_socket_path
,
281 "Use UNIX socket path", "PATH" },
282 { "evdev-path", 'p', 0, G_OPTION_ARG_FILENAME
, &opt_evdev
,
283 "evdev input device path", "PATH" },
288 main(int argc
, char *argv
[])
290 GMainLoop
*loop
= NULL
;
293 virtio_input_config id
;
295 GError
*error
= NULL
;
296 GOptionContext
*context
;
298 context
= g_option_context_new(NULL
);
299 g_option_context_add_main_entries(context
, entries
, NULL
);
300 if (!g_option_context_parse(context
, &argc
, &argv
, &error
)) {
301 g_printerr("Option parsing failed: %s\n", error
->message
);
304 if (opt_print_caps
) {
306 g_print(" \"type\": \"input\",\n");
307 g_print(" \"features\": [\n");
308 g_print(" \"evdev-path\",\n");
309 g_print(" \"no-grab\"\n");
315 g_printerr("Please specify an evdev path\n");
318 if ((!!opt_socket_path
+ (opt_fdnum
!= -1)) != 1) {
319 g_printerr("Please specify either --fd or --socket-path\n");
323 vi
.evdevfd
= open(opt_evdev
, O_RDWR
);
324 if (vi
.evdevfd
< 0) {
325 g_printerr("Failed to open evdev: %s\n", g_strerror(errno
));
329 rc
= ioctl(vi
.evdevfd
, EVIOCGVERSION
, &ver
);
331 g_printerr("%s: is not an evdev device\n", argv
[1]);
336 rc
= ioctl(vi
.evdevfd
, EVIOCGRAB
, 1);
338 g_printerr("Failed to grab device\n");
343 vi
.config
= g_array_new(false, false, sizeof(virtio_input_config
));
344 memset(&id
, 0, sizeof(id
));
345 ioctl(vi
.evdevfd
, EVIOCGNAME(sizeof(id
.u
.string
) - 1), id
.u
.string
);
346 id
.select
= VIRTIO_INPUT_CFG_ID_NAME
;
347 id
.size
= strlen(id
.u
.string
);
348 g_array_append_val(vi
.config
, id
);
350 if (ioctl(vi
.evdevfd
, EVIOCGID
, &ids
) == 0) {
351 memset(&id
, 0, sizeof(id
));
352 id
.select
= VIRTIO_INPUT_CFG_ID_DEVIDS
;
353 id
.size
= sizeof(struct virtio_input_devids
);
354 id
.u
.ids
.bustype
= cpu_to_le16(ids
.bustype
);
355 id
.u
.ids
.vendor
= cpu_to_le16(ids
.vendor
);
356 id
.u
.ids
.product
= cpu_to_le16(ids
.product
);
357 id
.u
.ids
.version
= cpu_to_le16(ids
.version
);
358 g_array_append_val(vi
.config
, id
);
361 vi_bits_config(&vi
, EV_KEY
, KEY_CNT
);
362 vi_bits_config(&vi
, EV_REL
, REL_CNT
);
363 vi_bits_config(&vi
, EV_ABS
, ABS_CNT
);
364 vi_bits_config(&vi
, EV_MSC
, MSC_CNT
);
365 vi_bits_config(&vi
, EV_SW
, SW_CNT
);
366 g_debug("config length: %u", vi
.config
->len
);
368 if (opt_socket_path
) {
369 int lsock
= unix_listen(opt_socket_path
, &error_fatal
);
370 fd
= accept(lsock
, NULL
, NULL
);
376 g_printerr("Invalid socket");
379 vug_init(&vi
.dev
, fd
, vi_panic
, &vuiface
);
381 loop
= g_main_loop_new(NULL
, FALSE
);
382 g_main_loop_run(loop
);
383 g_main_loop_unref(loop
);
388 g_source_unref(vi
.evsrc
);
390 g_array_free(vi
.config
, TRUE
);