mirror of https://github.com/xemu-project/xemu.git
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).
|
Set the initial graphical resolution and depth (PPC, SPARC only).
|
||||||
ETEXI
|
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 ,
|
DEF("vnc", HAS_ARG, QEMU_OPTION_vnc ,
|
||||||
"-vnc display start a VNC server on display\n", QEMU_ARCH_ALL)
|
"-vnc display start a VNC server on display\n", QEMU_ARCH_ALL)
|
||||||
STEXI
|
STEXI
|
||||||
|
|
154
ui/input-linux.c
154
ui/input-linux.c
|
@ -10,6 +10,7 @@
|
||||||
#include "qemu/sockets.h"
|
#include "qemu/sockets.h"
|
||||||
#include "sysemu/sysemu.h"
|
#include "sysemu/sysemu.h"
|
||||||
#include "ui/input.h"
|
#include "ui/input.h"
|
||||||
|
#include "qom/object_interfaces.h"
|
||||||
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include "standard-headers/linux/input.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];
|
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 InputLinux InputLinux;
|
||||||
|
typedef struct InputLinuxClass InputLinuxClass;
|
||||||
|
|
||||||
struct InputLinux {
|
struct InputLinux {
|
||||||
const char *evdev;
|
Object parent;
|
||||||
|
|
||||||
|
char *evdev;
|
||||||
int fd;
|
int fd;
|
||||||
bool repeat;
|
bool repeat;
|
||||||
bool grab_request;
|
bool grab_request;
|
||||||
|
@ -139,9 +151,14 @@ struct InputLinux {
|
||||||
bool keydown[KEY_CNT];
|
bool keydown[KEY_CNT];
|
||||||
int keycount;
|
int keycount;
|
||||||
int wheel;
|
int wheel;
|
||||||
|
bool initialized;
|
||||||
QTAILQ_ENTRY(InputLinux) next;
|
QTAILQ_ENTRY(InputLinux) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct InputLinuxClass {
|
||||||
|
ObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
static QTAILQ_HEAD(, InputLinux) inputs = QTAILQ_HEAD_INITIALIZER(inputs);
|
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)
|
||||||
|
@ -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;
|
uint32_t evtmap;
|
||||||
int rc, ver;
|
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) {
|
if (!il->evdev) {
|
||||||
error_setg(errp, "no input device specified");
|
error_setg(errp, "no input device specified");
|
||||||
goto err_free;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
il->fd = open(il->evdev, O_RDWR);
|
il->fd = open(il->evdev, O_RDWR);
|
||||||
if (il->fd < 0) {
|
if (il->fd < 0) {
|
||||||
error_setg_file_open(errp, errno, il->evdev);
|
error_setg_file_open(errp, errno, il->evdev);
|
||||||
goto err_free;
|
return;
|
||||||
}
|
}
|
||||||
qemu_set_nonblock(il->fd);
|
qemu_set_nonblock(il->fd);
|
||||||
|
|
||||||
|
@ -356,36 +369,111 @@ int input_linux_init(void *opaque, QemuOpts *opts, Error **errp)
|
||||||
}
|
}
|
||||||
input_linux_toggle_grab(il);
|
input_linux_toggle_grab(il);
|
||||||
QTAILQ_INSERT_TAIL(&inputs, il, next);
|
QTAILQ_INSERT_TAIL(&inputs, il, next);
|
||||||
return 0;
|
il->initialized = true;
|
||||||
|
return;
|
||||||
|
|
||||||
err_close:
|
err_close:
|
||||||
close(il->fd);
|
close(il->fd);
|
||||||
err_free:
|
return;
|
||||||
g_free(il);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static QemuOptsList qemu_input_linux_opts = {
|
static void input_linux_instance_finalize(Object *obj)
|
||||||
.name = "input-linux",
|
{
|
||||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_input_linux_opts.head),
|
InputLinux *il = INPUT_LINUX(obj);
|
||||||
.implied_opt_name = "evdev",
|
|
||||||
.desc = {
|
if (il->initialized) {
|
||||||
{
|
QTAILQ_REMOVE(&inputs, il, next);
|
||||||
.name = "evdev",
|
close(il->fd);
|
||||||
.type = QEMU_OPT_STRING,
|
}
|
||||||
},{
|
g_free(il->evdev);
|
||||||
.name = "grab-all",
|
}
|
||||||
.type = QEMU_OPT_BOOL,
|
|
||||||
},{
|
static char *input_linux_get_evdev(Object *obj, Error **errp)
|
||||||
.name = "repeat",
|
{
|
||||||
.type = QEMU_OPT_BOOL,
|
InputLinux *il = INPUT_LINUX(obj);
|
||||||
},
|
|
||||||
{ /* end of list */ }
|
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
|
#endif
|
||||||
break;
|
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:
|
case QEMU_OPTION_no_acpi:
|
||||||
acpi_enabled = 0;
|
acpi_enabled = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -4598,10 +4592,6 @@ int main(int argc, char **argv, char **envp)
|
||||||
qemu_spice_display_init();
|
qemu_spice_display_init();
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
if (foreach_device_config(DEV_GDB, gdbserver_start) < 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
Loading…
Reference in New Issue