input-linux: add option to toggle grab on all devices
Maintain a list of all input devices. Add an option to make grab work across all devices (so toggling grab on the keybard can switch over the mouse too). Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 1457087116-4379-3-git-send-email-kraxel@redhat.com
This commit is contained in:
parent
e0d2bd5195
commit
46d921bebe
@ -134,14 +134,19 @@ struct InputLinux {
|
|||||||
int fd;
|
int fd;
|
||||||
bool grab_request;
|
bool grab_request;
|
||||||
bool grab_active;
|
bool grab_active;
|
||||||
|
bool grab_all;
|
||||||
bool keydown[KEY_CNT];
|
bool keydown[KEY_CNT];
|
||||||
int keycount;
|
int keycount;
|
||||||
int wheel;
|
int wheel;
|
||||||
|
QTAILQ_ENTRY(InputLinux) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static QTAILQ_HEAD(, InputLinux) inputs = QTAILQ_HEAD_INITIALIZER(inputs);
|
||||||
|
|
||||||
static void input_linux_toggle_grab(InputLinux *il)
|
static void input_linux_toggle_grab(InputLinux *il)
|
||||||
{
|
{
|
||||||
intptr_t request = !il->grab_active;
|
intptr_t request = !il->grab_active;
|
||||||
|
InputLinux *item;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = ioctl(il->fd, EVIOCGRAB, request);
|
rc = ioctl(il->fd, EVIOCGRAB, request);
|
||||||
@ -149,6 +154,19 @@ static void input_linux_toggle_grab(InputLinux *il)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
il->grab_active = !il->grab_active;
|
il->grab_active = !il->grab_active;
|
||||||
|
|
||||||
|
if (!il->grab_all) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QTAILQ_FOREACH(item, &inputs, next) {
|
||||||
|
if (item == il || item->grab_all) {
|
||||||
|
/* avoid endless loops */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (item->grab_active != il->grab_active) {
|
||||||
|
input_linux_toggle_grab(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void input_linux_event_keyboard(void *opaque)
|
static void input_linux_event_keyboard(void *opaque)
|
||||||
@ -238,6 +256,11 @@ static void input_linux_event_mouse(void *opaque)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* only send event to guest when grab is active */
|
||||||
|
if (!il->grab_active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case EV_KEY:
|
case EV_KEY:
|
||||||
switch (event.code) {
|
switch (event.code) {
|
||||||
@ -292,6 +315,8 @@ int input_linux_init(void *opaque, QemuOpts *opts, Error **errp)
|
|||||||
int rc, ver;
|
int rc, ver;
|
||||||
|
|
||||||
il->evdev = qemu_opt_get(opts, "evdev");
|
il->evdev = qemu_opt_get(opts, "evdev");
|
||||||
|
il->grab_all = qemu_opt_get_bool(opts, "grab-all", false);
|
||||||
|
|
||||||
if (!il->evdev) {
|
if (!il->evdev) {
|
||||||
error_setg(errp, "no input device specified");
|
error_setg(errp, "no input device specified");
|
||||||
goto err_free;
|
goto err_free;
|
||||||
@ -328,6 +353,7 @@ int input_linux_init(void *opaque, QemuOpts *opts, Error **errp)
|
|||||||
goto err_close;
|
goto err_close;
|
||||||
}
|
}
|
||||||
input_linux_toggle_grab(il);
|
input_linux_toggle_grab(il);
|
||||||
|
QTAILQ_INSERT_TAIL(&inputs, il, next);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_close:
|
err_close:
|
||||||
@ -345,6 +371,9 @@ static QemuOptsList qemu_input_linux_opts = {
|
|||||||
{
|
{
|
||||||
.name = "evdev",
|
.name = "evdev",
|
||||||
.type = QEMU_OPT_STRING,
|
.type = QEMU_OPT_STRING,
|
||||||
|
},{
|
||||||
|
.name = "grab-all",
|
||||||
|
.type = QEMU_OPT_BOOL,
|
||||||
},
|
},
|
||||||
{ /* end of list */ }
|
{ /* end of list */ }
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user