input-linux: switch over to -object
This patches makes input-linux use -object instead of a new command line switch. So, instead of the switch ... -input-linux /dev/input/event$nr ... you must create an object this way: -object input-linux,id=$name,evdev=/dev/input/event$nr Bonus is that you can hot-add and hot-remove them via monitor now. Suggested-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-id: 1457681901-30916-1-git-send-email-kraxel@redhat.com
This commit is contained in:
parent
2538039f2c
commit
0e066b2cc5
|
@ -1226,15 +1226,6 @@ STEXI
|
|||
Set the initial graphical resolution and depth (PPC, SPARC only).
|
||||
ETEXI
|
||||
|
||||
DEF("input-linux", 1, QEMU_OPTION_input_linux,
|
||||
"-input-linux <evdev>\n"
|
||||
" Use input device.\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -input-linux @var{dev}
|
||||
@findex -input-linux
|
||||
Use input device.
|
||||
ETEXI
|
||||
|
||||
DEF("vnc", HAS_ARG, QEMU_OPTION_vnc ,
|
||||
"-vnc display start a VNC server on display\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
|
|
152
ui/input-linux.c
152
ui/input-linux.c
|
@ -10,6 +10,7 @@
|
|||
#include "qemu/sockets.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "ui/input.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include "standard-headers/linux/input.h"
|
||||
|
@ -127,10 +128,21 @@ static int qemu_input_linux_to_qcode(unsigned int lnx)
|
|||
return linux_to_qcode[lnx];
|
||||
}
|
||||
|
||||
#define TYPE_INPUT_LINUX "input-linux"
|
||||
#define INPUT_LINUX(obj) \
|
||||
OBJECT_CHECK(InputLinux, (obj), TYPE_INPUT_LINUX)
|
||||
#define INPUT_LINUX_GET_CLASS(obj) \
|
||||
OBJECT_GET_CLASS(InputLinuxClass, (obj), TYPE_INPUT_LINUX)
|
||||
#define INPUT_LINUX_CLASS(klass) \
|
||||
OBJECT_CLASS_CHECK(InputLinuxClass, (klass), TYPE_INPUT_LINUX)
|
||||
|
||||
typedef struct InputLinux InputLinux;
|
||||
typedef struct InputLinuxClass InputLinuxClass;
|
||||
|
||||
struct InputLinux {
|
||||
const char *evdev;
|
||||
Object parent;
|
||||
|
||||
char *evdev;
|
||||
int fd;
|
||||
bool repeat;
|
||||
bool grab_request;
|
||||
|
@ -139,9 +151,14 @@ struct InputLinux {
|
|||
bool keydown[KEY_CNT];
|
||||
int keycount;
|
||||
int wheel;
|
||||
bool initialized;
|
||||
QTAILQ_ENTRY(InputLinux) next;
|
||||
};
|
||||
|
||||
struct InputLinuxClass {
|
||||
ObjectClass parent_class;
|
||||
};
|
||||
|
||||
static QTAILQ_HEAD(, InputLinux) inputs = QTAILQ_HEAD_INITIALIZER(inputs);
|
||||
|
||||
static void input_linux_toggle_grab(InputLinux *il)
|
||||
|
@ -309,25 +326,21 @@ static void input_linux_event_mouse(void *opaque)
|
|||
}
|
||||
}
|
||||
|
||||
int input_linux_init(void *opaque, QemuOpts *opts, Error **errp)
|
||||
static void input_linux_complete(UserCreatable *uc, Error **errp)
|
||||
{
|
||||
InputLinux *il = g_new0(InputLinux, 1);
|
||||
InputLinux *il = INPUT_LINUX(uc);
|
||||
uint32_t evtmap;
|
||||
int rc, ver;
|
||||
|
||||
il->evdev = qemu_opt_get(opts, "evdev");
|
||||
il->grab_all = qemu_opt_get_bool(opts, "grab-all", false);
|
||||
il->repeat = qemu_opt_get_bool(opts, "repeat", false);
|
||||
|
||||
if (!il->evdev) {
|
||||
error_setg(errp, "no input device specified");
|
||||
goto err_free;
|
||||
return;
|
||||
}
|
||||
|
||||
il->fd = open(il->evdev, O_RDWR);
|
||||
if (il->fd < 0) {
|
||||
error_setg_file_open(errp, errno, il->evdev);
|
||||
goto err_free;
|
||||
return;
|
||||
}
|
||||
qemu_set_nonblock(il->fd);
|
||||
|
||||
|
@ -356,36 +369,111 @@ int input_linux_init(void *opaque, QemuOpts *opts, Error **errp)
|
|||
}
|
||||
input_linux_toggle_grab(il);
|
||||
QTAILQ_INSERT_TAIL(&inputs, il, next);
|
||||
return 0;
|
||||
il->initialized = true;
|
||||
return;
|
||||
|
||||
err_close:
|
||||
close(il->fd);
|
||||
err_free:
|
||||
g_free(il);
|
||||
return -1;
|
||||
return;
|
||||
}
|
||||
|
||||
static QemuOptsList qemu_input_linux_opts = {
|
||||
.name = "input-linux",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_input_linux_opts.head),
|
||||
.implied_opt_name = "evdev",
|
||||
.desc = {
|
||||
static void input_linux_instance_finalize(Object *obj)
|
||||
{
|
||||
.name = "evdev",
|
||||
.type = QEMU_OPT_STRING,
|
||||
},{
|
||||
.name = "grab-all",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
},{
|
||||
.name = "repeat",
|
||||
.type = QEMU_OPT_BOOL,
|
||||
},
|
||||
{ /* end of list */ }
|
||||
},
|
||||
InputLinux *il = INPUT_LINUX(obj);
|
||||
|
||||
if (il->initialized) {
|
||||
QTAILQ_REMOVE(&inputs, il, next);
|
||||
close(il->fd);
|
||||
}
|
||||
g_free(il->evdev);
|
||||
}
|
||||
|
||||
static char *input_linux_get_evdev(Object *obj, Error **errp)
|
||||
{
|
||||
InputLinux *il = INPUT_LINUX(obj);
|
||||
|
||||
return g_strdup(il->evdev);
|
||||
}
|
||||
|
||||
static void input_linux_set_evdev(Object *obj, const char *value,
|
||||
Error **errp)
|
||||
{
|
||||
InputLinux *il = INPUT_LINUX(obj);
|
||||
|
||||
if (il->evdev) {
|
||||
error_setg(errp, "evdev property already set");
|
||||
return;
|
||||
}
|
||||
il->evdev = g_strdup(value);
|
||||
}
|
||||
|
||||
static bool input_linux_get_grab_all(Object *obj, Error **errp)
|
||||
{
|
||||
InputLinux *il = INPUT_LINUX(obj);
|
||||
|
||||
return il->grab_all;
|
||||
}
|
||||
|
||||
static void input_linux_set_grab_all(Object *obj, bool value,
|
||||
Error **errp)
|
||||
{
|
||||
InputLinux *il = INPUT_LINUX(obj);
|
||||
|
||||
il->grab_all = value;
|
||||
}
|
||||
|
||||
static bool input_linux_get_repeat(Object *obj, Error **errp)
|
||||
{
|
||||
InputLinux *il = INPUT_LINUX(obj);
|
||||
|
||||
return il->repeat;
|
||||
}
|
||||
|
||||
static void input_linux_set_repeat(Object *obj, bool value,
|
||||
Error **errp)
|
||||
{
|
||||
InputLinux *il = INPUT_LINUX(obj);
|
||||
|
||||
il->repeat = value;
|
||||
}
|
||||
|
||||
static void input_linux_instance_init(Object *obj)
|
||||
{
|
||||
object_property_add_str(obj, "evdev",
|
||||
input_linux_get_evdev,
|
||||
input_linux_set_evdev, NULL);
|
||||
object_property_add_bool(obj, "grab_all",
|
||||
input_linux_get_grab_all,
|
||||
input_linux_set_grab_all, NULL);
|
||||
object_property_add_bool(obj, "repeat",
|
||||
input_linux_get_repeat,
|
||||
input_linux_set_repeat, NULL);
|
||||
}
|
||||
|
||||
static void input_linux_class_init(ObjectClass *oc, void *data)
|
||||
{
|
||||
UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
|
||||
|
||||
ucc->complete = input_linux_complete;
|
||||
}
|
||||
|
||||
static const TypeInfo input_linux_info = {
|
||||
.name = TYPE_INPUT_LINUX,
|
||||
.parent = TYPE_OBJECT,
|
||||
.class_size = sizeof(InputLinuxClass),
|
||||
.class_init = input_linux_class_init,
|
||||
.instance_size = sizeof(InputLinux),
|
||||
.instance_init = input_linux_instance_init,
|
||||
.instance_finalize = input_linux_instance_finalize,
|
||||
.interfaces = (InterfaceInfo[]) {
|
||||
{ TYPE_USER_CREATABLE },
|
||||
{ }
|
||||
}
|
||||
};
|
||||
|
||||
static void input_linux_register_config(void)
|
||||
static void register_types(void)
|
||||
{
|
||||
qemu_add_opts(&qemu_input_linux_opts);
|
||||
type_register_static(&input_linux_info);
|
||||
}
|
||||
opts_init(input_linux_register_config);
|
||||
|
||||
type_init(register_types);
|
||||
|
|
10
vl.c
10
vl.c
|
@ -3729,12 +3729,6 @@ int main(int argc, char **argv, char **envp)
|
|||
#endif
|
||||
break;
|
||||
}
|
||||
case QEMU_OPTION_input_linux:
|
||||
if (!qemu_opts_parse_noisily(qemu_find_opts("input-linux"),
|
||||
optarg, true)) {
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case QEMU_OPTION_no_acpi:
|
||||
acpi_enabled = 0;
|
||||
break;
|
||||
|
@ -4598,10 +4592,6 @@ int main(int argc, char **argv, char **envp)
|
|||
qemu_spice_display_init();
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_LINUX
|
||||
qemu_opts_foreach(qemu_find_opts("input-linux"),
|
||||
input_linux_init, NULL, &error_fatal);
|
||||
#endif
|
||||
|
||||
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
|
||||
exit(1);
|
||||
|
|
Loading…
Reference in New Issue