mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
Fix input-linux reading from device
The evdev devices in input-linux.c are read in blocks of one whole event. If there are not enough bytes available, they are discarded, instead of being kept for the next read operation. This results in lost events, of even non-working devices. This patch keeps track of the number of bytes to be read to fill up a whole event, and then handle it. Changes from v1 to v2: - Fix: Calculate offset on each iteration Changes from v2 to v3: - Fix coding style - Store offset instead of bytes to be read Signed-off-by: Javier Celaya <jcelaya@gmail.com> Message-id: 20170327182624.2914-1-jcelaya@gmail.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
243afe858b
commit
1684907c92
1 changed files with 12 additions and 5 deletions
|
@ -169,6 +169,8 @@ struct InputLinux {
|
|||
bool has_abs_x;
|
||||
int num_keys;
|
||||
int num_btns;
|
||||
struct input_event event;
|
||||
int read_offset;
|
||||
|
||||
QTAILQ_ENTRY(InputLinux) next;
|
||||
};
|
||||
|
@ -327,25 +329,30 @@ static void input_linux_handle_mouse(InputLinux *il, struct input_event *event)
|
|||
static void input_linux_event(void *opaque)
|
||||
{
|
||||
InputLinux *il = opaque;
|
||||
struct input_event event;
|
||||
int rc;
|
||||
int read_size;
|
||||
uint8_t *p = (uint8_t *)&il->event;
|
||||
|
||||
for (;;) {
|
||||
rc = read(il->fd, &event, sizeof(event));
|
||||
if (rc != sizeof(event)) {
|
||||
read_size = sizeof(il->event) - il->read_offset;
|
||||
rc = read(il->fd, &p[il->read_offset], read_size);
|
||||
if (rc != read_size) {
|
||||
if (rc < 0 && errno != EAGAIN) {
|
||||
fprintf(stderr, "%s: read: %s\n", __func__, strerror(errno));
|
||||
qemu_set_fd_handler(il->fd, NULL, NULL, NULL);
|
||||
close(il->fd);
|
||||
} else if (rc > 0) {
|
||||
il->read_offset += rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
il->read_offset = 0;
|
||||
|
||||
if (il->num_keys) {
|
||||
input_linux_handle_keyboard(il, &event);
|
||||
input_linux_handle_keyboard(il, &il->event);
|
||||
}
|
||||
if (il->has_rel_x && il->num_btns) {
|
||||
input_linux_handle_mouse(il, &event);
|
||||
input_linux_handle_mouse(il, &il->event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue