aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--audio/audio.c12
-rw-r--r--audio/paaudio.c15
-rwxr-xr-xconfigure81
-rw-r--r--contrib/gitdm/filetypes.txt2
-rw-r--r--docs/devel/qapi-code-gen.txt12
-rw-r--r--hw/audio/pcspk.c35
-rw-r--r--hw/i386/pc.c4
-rw-r--r--include/hw/virtio/virtio-net.h2
-rw-r--r--include/qapi/qmp-event.h6
-rw-r--r--io/channel-socket.c19
-rw-r--r--monitor.c4
-rw-r--r--qapi/misc.json36
-rw-r--r--qapi/qmp-event.c12
-rw-r--r--qapi/ui.json10
-rw-r--r--qobject/json-parser.c10
-rw-r--r--scripts/qapi/events.py24
-rw-r--r--stubs/monitor.c5
-rw-r--r--target/ppc/translate_init.inc.c8
-rw-r--r--tests/Makefile.include4
-rw-r--r--tests/check-qjson.c5
-rw-r--r--tests/test-io-channel-socket.c86
-rw-r--r--tests/test-qmp-event.c6
-rw-r--r--ui/input-linux.c66
24 files changed, 313 insertions, 153 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 060db23661..59e1f24d68 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1631,7 +1631,7 @@ F: include/hw/display/edid.h
F: qemu-edid.c
Firmware configuration (fw_cfg)
-M: Philippe Mathieu-Daudé <philmd@redhat.com>
+M: Philippe Mathieu-Daudé <philmd@redhat.com>
R: Laszlo Ersek <lersek@redhat.com>
R: Gerd Hoffmann <kraxel@redhat.com>
S: Supported
diff --git a/audio/audio.c b/audio/audio.c
index 1ace47f510..d163ffbc88 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1762,7 +1762,7 @@ void AUD_help (void)
);
}
-static int audio_driver_init (AudioState *s, struct audio_driver *drv)
+static int audio_driver_init(AudioState *s, struct audio_driver *drv, bool msg)
{
if (drv->options) {
audio_process_options (drv->name, drv->options);
@@ -1776,7 +1776,9 @@ static int audio_driver_init (AudioState *s, struct audio_driver *drv)
return 0;
}
else {
- dolog ("Could not init `%s' audio driver\n", drv->name);
+ if (msg) {
+ dolog("Could not init `%s' audio driver\n", drv->name);
+ }
return -1;
}
}
@@ -1901,7 +1903,7 @@ static void audio_init (void)
if (drvname) {
driver = audio_driver_lookup(drvname);
if (driver) {
- done = !audio_driver_init(s, driver);
+ done = !audio_driver_init(s, driver, true);
} else {
dolog ("Unknown audio driver `%s'\n", drvname);
dolog ("Run with -audio-help to list available drivers\n");
@@ -1912,14 +1914,14 @@ static void audio_init (void)
for (i = 0; !done && i < ARRAY_SIZE(audio_prio_list); i++) {
driver = audio_driver_lookup(audio_prio_list[i]);
if (driver && driver->can_be_default) {
- done = !audio_driver_init(s, driver);
+ done = !audio_driver_init(s, driver, false);
}
}
}
if (!done) {
driver = audio_driver_lookup("none");
- done = !audio_driver_init(s, driver);
+ done = !audio_driver_init(s, driver, false);
assert(done);
dolog("warning: Using timer based audio emulation\n");
}
diff --git a/audio/paaudio.c b/audio/paaudio.c
index 4c100bc318..6153b908da 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -814,6 +814,21 @@ static PAConf glob_conf = {
static void *qpa_audio_init (void)
{
+ if (glob_conf.server == NULL) {
+ char pidfile[64];
+ char *runtime;
+ struct stat st;
+
+ runtime = getenv("XDG_RUNTIME_DIR");
+ if (!runtime) {
+ return NULL;
+ }
+ snprintf(pidfile, sizeof(pidfile), "%s/pulse/pid", runtime);
+ if (stat(pidfile, &st) != 0) {
+ return NULL;
+ }
+ }
+
paaudio *g = g_malloc(sizeof(paaudio));
g->conf = glob_conf;
g->mainloop = NULL;
diff --git a/configure b/configure
index 8f312ac3e2..b18281c61f 100755
--- a/configure
+++ b/configure
@@ -794,13 +794,13 @@ MINGW32*)
;;
GNU/kFreeBSD)
bsd="yes"
- audio_drv_list="oss"
+ audio_drv_list="oss try-sdl"
audio_possible_drivers="oss sdl pa"
;;
FreeBSD)
bsd="yes"
make="${MAKE-gmake}"
- audio_drv_list="oss"
+ audio_drv_list="oss try-sdl"
audio_possible_drivers="oss sdl pa"
# needed for kinfo_getvmmap(3) in libutil.h
LIBS="-lutil $LIBS"
@@ -813,14 +813,14 @@ FreeBSD)
DragonFly)
bsd="yes"
make="${MAKE-gmake}"
- audio_drv_list="oss"
+ audio_drv_list="oss try-sdl"
audio_possible_drivers="oss sdl pa"
HOST_VARIANT_DIR="dragonfly"
;;
NetBSD)
bsd="yes"
make="${MAKE-gmake}"
- audio_drv_list="oss"
+ audio_drv_list="oss try-sdl"
audio_possible_drivers="oss sdl"
oss_lib="-lossaudio"
HOST_VARIANT_DIR="netbsd"
@@ -829,7 +829,7 @@ NetBSD)
OpenBSD)
bsd="yes"
make="${MAKE-gmake}"
- audio_drv_list="sdl"
+ audio_drv_list="try-sdl"
audio_possible_drivers="sdl"
HOST_VARIANT_DIR="openbsd"
supported_os="yes"
@@ -845,7 +845,7 @@ Darwin)
LDFLAGS="-arch x86_64 $LDFLAGS"
fi
cocoa="yes"
- audio_drv_list="coreaudio"
+ audio_drv_list="coreaudio try-sdl"
audio_possible_drivers="coreaudio sdl"
LDFLAGS="-framework CoreFoundation -framework IOKit $LDFLAGS"
libs_softmmu="-F/System/Library/Frameworks -framework Cocoa -framework IOKit $libs_softmmu"
@@ -861,7 +861,7 @@ SunOS)
install="${INSTALL-ginstall}"
smbd="${SMBD-/usr/sfw/sbin/smbd}"
if test -f /usr/include/sys/soundcard.h ; then
- audio_drv_list="oss"
+ audio_drv_list="oss try-sdl"
fi
audio_possible_drivers="oss sdl"
# needed for CMSG_ macros in sys/socket.h
@@ -879,7 +879,7 @@ Haiku)
LIBS="-lposix_error_mapper -lnetwork $LIBS"
;;
Linux)
- audio_drv_list="oss"
+ audio_drv_list="try-pa try-alsa try-sdl oss"
audio_possible_drivers="oss alsa sdl pa"
linux="yes"
linux_user="yes"
@@ -3342,39 +3342,40 @@ fi
##########################################
# Sound support libraries probe
-audio_drv_probe()
-{
- drv=$1
- hdr=$2
- lib=$3
- exp=$4
- cfl=$5
- cat > $TMPC << EOF
-#include <$hdr>
-int main(void) { $exp }
-EOF
- if compile_prog "$cfl" "$lib" ; then
- :
- else
- error_exit "$drv check failed" \
- "Make sure to have the $drv libs and headers installed."
- fi
-}
-
audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/,/ /g')
for drv in $audio_drv_list; do
case $drv in
- alsa)
- audio_drv_probe $drv alsa/asoundlib.h -lasound \
- "return snd_pcm_close((snd_pcm_t *)0);"
- alsa_libs="-lasound"
+ alsa | try-alsa)
+ if $pkg_config alsa --exists; then
+ alsa_libs=$($pkg_config alsa --libs)
+ if test "$drv" = "try-alsa"; then
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-alsa/alsa/')
+ fi
+ else
+ if test "$drv" = "try-alsa"; then
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-alsa//')
+ else
+ error_exit "$drv check failed" \
+ "Make sure to have the $drv libs and headers installed."
+ fi
+ fi
;;
- pa)
- audio_drv_probe $drv pulse/pulseaudio.h "-lpulse" \
- "pa_context_set_source_output_volume(NULL, 0, NULL, NULL, NULL); return 0;"
- pulse_libs="-lpulse"
- audio_pt_int="yes"
+ pa | try-pa)
+ if $pkg_config libpulse --exists; then
+ pulse_libs=$($pkg_config libpulse --libs)
+ audio_pt_int="yes"
+ if test "$drv" = "try-pa"; then
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-pa/pa/')
+ fi
+ else
+ if test "$drv" = "try-pa"; then
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-pa//')
+ else
+ error_exit "$drv check failed" \
+ "Make sure to have the $drv libs and headers installed."
+ fi
+ fi
;;
sdl)
@@ -3383,6 +3384,14 @@ for drv in $audio_drv_list; do
fi
;;
+ try-sdl)
+ if test "$sdl" = "no"; then
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-sdl//')
+ else
+ audio_drv_list=$(echo "$audio_drv_list" | sed -e 's/try-sdl/sdl/')
+ fi
+ ;;
+
coreaudio)
coreaudio_libs="-framework CoreAudio"
;;
diff --git a/contrib/gitdm/filetypes.txt b/contrib/gitdm/filetypes.txt
index 15d6f803b9..165b71b3f9 100644
--- a/contrib/gitdm/filetypes.txt
+++ b/contrib/gitdm/filetypes.txt
@@ -4,7 +4,7 @@
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
-# (at your option any later version.
+# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/docs/devel/qapi-code-gen.txt b/docs/devel/qapi-code-gen.txt
index 43bd853e69..87183d3a09 100644
--- a/docs/devel/qapi-code-gen.txt
+++ b/docs/devel/qapi-code-gen.txt
@@ -1369,8 +1369,8 @@ Example:
void qapi_event_send_my_event(void);
typedef enum example_QAPIEvent {
- EXAMPLE_QAPI_EVENT_MY_EVENT = 0,
- EXAMPLE_QAPI_EVENT__MAX = 1,
+ EXAMPLE_QAPI_EVENT_MY_EVENT,
+ EXAMPLE_QAPI_EVENT__MAX,
} example_QAPIEvent;
#define example_QAPIEvent_str(val) \
@@ -1385,16 +1385,10 @@ Example:
void qapi_event_send_my_event(void)
{
QDict *qmp;
- QMPEventFuncEmit emit;
-
- emit = qmp_event_get_func_emit();
- if (!emit) {
- return;
- }
qmp = qmp_event_build_dict("MY_EVENT");
- emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp);
+ example_qapi_event_emit(EXAMPLE_QAPI_EVENT_MY_EVENT, qmp);
qobject_unref(qmp);
}
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 908696d483..b80a62ce90 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -57,7 +57,6 @@ typedef struct {
} PCSpkState;
static const char *s_spk = "pcspk";
-static PCSpkState *pcspk_state;
static inline void generate_samples(PCSpkState *s)
{
@@ -111,22 +110,6 @@ static void pcspk_callback(void *opaque, int free)
}
}
-static int pcspk_audio_init(ISABus *bus)
-{
- PCSpkState *s = pcspk_state;
- struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUD_FMT_U8, 0};
-
- AUD_register_card(s_spk, &s->card);
-
- s->voice = AUD_open_out(&s->card, s->voice, s_spk, s, pcspk_callback, &as);
- if (!s->voice) {
- AUD_log(s_spk, "Could not open voice\n");
- return -1;
- }
-
- return 0;
-}
-
static uint64_t pcspk_io_read(void *opaque, hwaddr addr,
unsigned size)
{
@@ -179,12 +162,20 @@ static void pcspk_initfn(Object *obj)
static void pcspk_realizefn(DeviceState *dev, Error **errp)
{
+ struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUD_FMT_U8, 0};
ISADevice *isadev = ISA_DEVICE(dev);
PCSpkState *s = PC_SPEAKER(dev);
isa_register_ioport(isadev, &s->ioport, s->iobase);
- pcspk_state = s;
+ AUD_register_card(s_spk, &s->card);
+
+ s->voice = AUD_open_out(&s->card, s->voice, s_spk, s, pcspk_callback, &as);
+ if (!s->voice) {
+ error_setg(errp, "Initializing audio voice failed");
+ AUD_remove_card(&s->card);
+ return;
+ }
}
static bool migrate_needed(void *opaque)
@@ -221,8 +212,6 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->vmsd = &vmstate_spk;
dc->props = pcspk_properties;
- /* Reason: realize sets global pcspk_state */
- dc->user_creatable = false;
}
static const TypeInfo pcspk_info = {
@@ -233,6 +222,12 @@ static const TypeInfo pcspk_info = {
.class_init = pcspk_class_initfn,
};
+static int pcspk_audio_init(ISABus *bus)
+{
+ isa_create_simple(bus, TYPE_PC_SPEAKER);
+ return 0;
+}
+
static void pcspk_register(void)
{
type_register_static(&pcspk_info);
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 73d688f842..747548b7aa 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -2285,7 +2285,7 @@ static void pc_machine_device_unplug_cb(HotplugHandler *hotplug_dev,
}
}
-static HotplugHandler *pc_get_hotpug_handler(MachineState *machine,
+static HotplugHandler *pc_get_hotplug_handler(MachineState *machine,
DeviceState *dev)
{
if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) ||
@@ -2615,7 +2615,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data)
pcmc->save_tsc_khz = true;
pcmc->linuxboot_dma_enabled = true;
assert(!mc->get_hotplug_handler);
- mc->get_hotplug_handler = pc_get_hotpug_handler;
+ mc->get_hotplug_handler = pc_get_hotplug_handler;
mc->cpu_index_to_instance_props = pc_cpu_index_to_props;
mc->get_default_cpu_node_id = pc_get_default_cpu_node_id;
mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index bd662752d2..a1a0be3bea 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -94,7 +94,7 @@ typedef struct VirtioNetRscUnit {
uint16_t payload; /* pure payload without virtio/eth/ip/tcp */
} VirtioNetRscUnit;
-/* Coalesced segmant */
+/* Coalesced segment */
typedef struct VirtioNetRscSeg {
QTAILQ_ENTRY(VirtioNetRscSeg) next;
void *buf;
diff --git a/include/qapi/qmp-event.h b/include/qapi/qmp-event.h
index 23e588ccf8..b60f1d3a89 100644
--- a/include/qapi/qmp-event.h
+++ b/include/qapi/qmp-event.h
@@ -14,11 +14,5 @@
#ifndef QMP_EVENT_H
#define QMP_EVENT_H
-typedef void (*QMPEventFuncEmit)(unsigned event, QDict *dict);
-
-void qmp_event_set_func_emit(QMPEventFuncEmit emit);
-
-QMPEventFuncEmit qmp_event_get_func_emit(void);
-
QDict *qmp_event_build_dict(const char *event_name);
#endif
diff --git a/io/channel-socket.c b/io/channel-socket.c
index b50e63a053..bc5f80e780 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -688,10 +688,13 @@ qio_channel_socket_close(QIOChannel *ioc,
int rc = 0;
if (sioc->fd != -1) {
- SocketAddress *addr = socket_local_address(sioc->fd, errp);
#ifdef WIN32
WSAEventSelect(sioc->fd, NULL, 0);
#endif
+ if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_LISTEN)) {
+ socket_listen_cleanup(sioc->fd, errp);
+ }
+
if (closesocket(sioc->fd) < 0) {
sioc->fd = -1;
error_setg_errno(errp, errno,
@@ -699,20 +702,6 @@ qio_channel_socket_close(QIOChannel *ioc,
return -1;
}
sioc->fd = -1;
-
- if (addr && addr->type == SOCKET_ADDRESS_TYPE_UNIX
- && addr->u.q_unix.path) {
- if (unlink(addr->u.q_unix.path) < 0 && errno != ENOENT) {
- error_setg_errno(errp, errno,
- "Failed to unlink socket %s",
- addr->u.q_unix.path);
- rc = -1;
- }
- }
-
- if (addr) {
- qapi_free_SocketAddress(addr);
- }
}
return rc;
}
diff --git a/monitor.c b/monitor.c
index eb39fb015b..c09fa63940 100644
--- a/monitor.c
+++ b/monitor.c
@@ -590,8 +590,7 @@ monitor_qapi_event_queue_no_reenter(QAPIEvent event, QDict *qdict)
qemu_mutex_unlock(&monitor_lock);
}
-static void
-monitor_qapi_event_queue(QAPIEvent event, QDict *qdict)
+void qapi_event_emit(QAPIEvent event, QDict *qdict)
{
/*
* monitor_qapi_event_queue_no_reenter() is not reentrant: it
@@ -704,7 +703,6 @@ static void monitor_qapi_event_init(void)
{
monitor_qapi_event_state = g_hash_table_new(qapi_event_throttle_hash,
qapi_event_throttle_equal);
- qmp_event_set_func_emit(monitor_qapi_event_queue);
}
static void handle_hmp_command(Monitor *mon, const char *cmdline);
diff --git a/qapi/misc.json b/qapi/misc.json
index 24d20a880a..426274ecf8 100644
--- a/qapi/misc.json
+++ b/qapi/misc.json
@@ -1380,6 +1380,16 @@
# object.
#
# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "qom-list",
+# "arguments": { "path": "/chardevs" } }
+# <- { "return": [ { "name": "type", "type": "string" },
+# { "name": "parallel0", "type": "child<chardev-vc>" },
+# { "name": "serial0", "type": "child<chardev-vc>" },
+# { "name": "mon0", "type": "child<chardev-stdio>" } ] }
+#
##
{ 'command': 'qom-list',
'data': { 'path': 'str' },
@@ -1417,6 +1427,23 @@
# returned as #int.
#
# Since: 1.2
+#
+# Example:
+#
+# 1. Use absolute path
+#
+# -> { "execute": "qom-get",
+# "arguments": { "path": "/machine/unattached/device[0]",
+# "property": "hotplugged" } }
+# <- { "return": false }
+#
+# 2. Use partial path
+#
+# -> { "execute": "qom-get",
+# "arguments": { "path": "unattached/sysbus",
+# "property": "type" } }
+# <- { "return": "System" }
+#
##
{ 'command': 'qom-get',
'data': { 'path': 'str', 'property': 'str' },
@@ -1436,6 +1463,15 @@
# for a description of type mapping.
#
# Since: 1.2
+#
+# Example:
+#
+# -> { "execute": "qom-set",
+# "arguments": { "path": "/machine",
+# "property": "graphics",
+# "value": false } }
+# <- { "return": {} }
+#
##
{ 'command': 'qom-set',
'data': { 'path': 'str', 'property': 'str', 'value': 'any' },
diff --git a/qapi/qmp-event.c b/qapi/qmp-event.c
index 5b8854043e..81ddd5331f 100644
--- a/qapi/qmp-event.c
+++ b/qapi/qmp-event.c
@@ -19,18 +19,6 @@
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qjson.h"
-static QMPEventFuncEmit qmp_emit;
-
-void qmp_event_set_func_emit(QMPEventFuncEmit emit)
-{
- qmp_emit = emit;
-}
-
-QMPEventFuncEmit qmp_event_get_func_emit(void)
-{
- return qmp_emit;
-}
-
static void timestamp_put(QDict *qdict)
{
int err;
diff --git a/qapi/ui.json b/qapi/ui.json
index 5ad13248d5..7d9c4bddaf 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -1016,6 +1016,16 @@
'*head' : 'int',
'events' : [ 'InputEvent' ] } }
+##
+# @GrabToggleKeys:
+#
+# Keys to toggle input-linux between host and guest.
+#
+# Since: 4.0
+#
+##
+{ 'enum': 'GrabToggleKeys',
+ 'data': [ 'ctrl-ctrl', 'alt-alt', 'meta-meta', 'scrolllock', 'ctrl-scrolllock' ] }
##
# @DisplayGTK:
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index 7a7ae9e8d1..d8eb210c0c 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -208,11 +208,13 @@ static QString *parse_string(JSONParserContext *ctxt, JSONToken *token)
}
break;
case '%':
- if (ctxt->ap && ptr[1] != '%') {
- parse_error(ctxt, token, "can't interpolate into string");
- goto out;
+ if (ctxt->ap) {
+ if (ptr[1] != '%') {
+ parse_error(ctxt, token, "can't interpolate into string");
+ goto out;
+ }
+ ptr++;
}
- ptr++;
/* fall through */
default:
cp = mod_utf8_codepoint(ptr, 6, &end);
diff --git a/scripts/qapi/events.py b/scripts/qapi/events.py
index 37ee5de682..d86a2d2b3e 100644
--- a/scripts/qapi/events.py
+++ b/scripts/qapi/events.py
@@ -58,7 +58,7 @@ def gen_param_var(typ):
return ret
-def gen_event_send(name, arg_type, boxed, event_enum_name):
+def gen_event_send(name, arg_type, boxed, event_enum_name, event_emit):
# FIXME: Our declaration of local variables (and of 'errp' in the
# parameter list) can collide with exploded members of the event's
# data type passed in as parameters. If this collision ever hits in
@@ -70,7 +70,6 @@ def gen_event_send(name, arg_type, boxed, event_enum_name):
%(proto)s
{
QDict *qmp;
- QMPEventFuncEmit emit;
''',
proto=build_event_send_proto(name, arg_type, boxed))
@@ -86,11 +85,6 @@ def gen_event_send(name, arg_type, boxed, event_enum_name):
ret += mcgen('''
- emit = qmp_event_get_func_emit();
- if (!emit) {
- return;
- }
-
qmp = qmp_event_build_dict("%(name)s");
''',
@@ -121,9 +115,10 @@ def gen_event_send(name, arg_type, boxed, event_enum_name):
''')
ret += mcgen('''
- emit(%(c_enum)s, qmp);
+ %(event_emit)s(%(c_enum)s, qmp);
''',
+ event_emit=event_emit,
c_enum=c_enum_const(event_enum_name, name))
if arg_type and not arg_type.is_empty():
@@ -145,6 +140,7 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
' * Schema-defined QAPI/QMP events', __doc__)
self._event_enum_name = c_name(prefix + 'QAPIEvent', protect=False)
self._event_enum_members = []
+ self._event_emit_name = c_name(prefix + 'qapi_event_emit')
def _begin_module(self, name):
types = self._module_basename('qapi-types', name)
@@ -170,15 +166,23 @@ class QAPISchemaGenEventVisitor(QAPISchemaModularCVisitor):
def visit_end(self):
(genc, genh) = self._module[self._main_module]
- genh.add(gen_enum(self._event_enum_name, self._event_enum_members))
+ genh.add(gen_enum(self._event_enum_name,
+ self._event_enum_members))
genc.add(gen_enum_lookup(self._event_enum_name,
self._event_enum_members))
+ genh.add(mcgen('''
+
+void %(event_emit)s(%(event_enum)s event, QDict *qdict);
+''',
+ event_emit=self._event_emit_name,
+ event_enum=self._event_enum_name))
def visit_event(self, name, info, ifcond, arg_type, boxed):
with ifcontext(ifcond, self._genh, self._genc):
self._genh.add(gen_event_send_decl(name, arg_type, boxed))
self._genc.add(gen_event_send(name, arg_type, boxed,
- self._event_enum_name))
+ self._event_enum_name,
+ self._event_emit_name))
self._event_enum_members.append(QAPISchemaMember(name, ifcond))
diff --git a/stubs/monitor.c b/stubs/monitor.c
index 3890771bb5..32bd7012c3 100644
--- a/stubs/monitor.c
+++ b/stubs/monitor.c
@@ -1,5 +1,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qapi/qapi-events.h"
#include "qemu-common.h"
#include "monitor/monitor.h"
@@ -14,3 +15,7 @@ int monitor_get_fd(Monitor *mon, const char *name, Error **errp)
void monitor_init(Chardev *chr, int flags)
{
}
+
+void qapi_event_emit(QAPIEvent event, QDict *qdict)
+{
+}
diff --git a/target/ppc/translate_init.inc.c b/target/ppc/translate_init.inc.c
index ade06cc773..59e0b86762 100644
--- a/target/ppc/translate_init.inc.c
+++ b/target/ppc/translate_init.inc.c
@@ -4947,14 +4947,6 @@ static void init_proc_e500(CPUPPCState *env, int version)
}
if (version == fsl_e6500) {
- spr_register(env, SPR_BOOKE_SPRG8, "SPRG8",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
- spr_register(env, SPR_BOOKE_SPRG9, "SPRG9",
- SPR_NOACCESS, SPR_NOACCESS,
- &spr_read_generic, &spr_write_generic,
- 0x00000000);
/* Thread identification */
spr_register(env, SPR_TIR, "TIR",
SPR_NOACCESS, SPR_NOACCESS,
diff --git a/tests/Makefile.include b/tests/Makefile.include
index f5e6eb5152..19b4c0a696 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -529,7 +529,7 @@ QEMU_CFLAGS += -I$(SRC_PATH)/tests
test-util-obj-y = libqemuutil.a
test-qom-obj-y = $(qom-obj-y) $(test-util-obj-y)
test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \
- tests/test-qapi-events.o tests/test-qapi-introspect.o \
+ tests/test-qapi-introspect.o \
$(test-qom-obj-y)
benchmark-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
@@ -621,7 +621,7 @@ tests/qapi-schema/doc-good.test.texi: $(SRC_PATH)/tests/qapi-schema/doc-good.jso
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y)
tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
-tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y)
+tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y) tests/test-qapi-events.o
tests/test-qobject-output-visitor$(EXESUF): tests/test-qobject-output-visitor.o $(test-qapi-obj-y)
tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y)
tests/test-qobject-input-visitor$(EXESUF): tests/test-qobject-input-visitor.o $(test-qapi-obj-y)
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index d876a7a96e..fa2afccb0a 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -176,6 +176,11 @@ static void utf8_string(void)
"\xCE\xBA\xE1\xBD\xB9\xCF\x83\xCE\xBC\xCE\xB5",
"\\u03BA\\u1F79\\u03C3\\u03BC\\u03B5",
},
+ /* '%' character when not interpolating */
+ {
+ "100%",
+ "100%",
+ },
/* 2 Boundary condition test cases */
/* 2.1 First possible sequence of a certain length */
/*
diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c
index 0597213f93..c253ae30f5 100644
--- a/tests/test-io-channel-socket.c
+++ b/tests/test-io-channel-socket.c
@@ -49,6 +49,7 @@ static void test_io_channel_set_socket_bufs(QIOChannel *src,
static void test_io_channel_setup_sync(SocketAddress *listen_addr,
SocketAddress *connect_addr,
+ QIOChannel **srv,
QIOChannel **src,
QIOChannel **dst)
{
@@ -78,7 +79,7 @@ static void test_io_channel_setup_sync(SocketAddress *listen_addr,
test_io_channel_set_socket_bufs(*src, *dst);
- object_unref(OBJECT(lioc));
+ *srv = QIO_CHANNEL(lioc);
}
@@ -99,6 +100,7 @@ static void test_io_channel_complete(QIOTask *task,
static void test_io_channel_setup_async(SocketAddress *listen_addr,
SocketAddress *connect_addr,
+ QIOChannel **srv,
QIOChannel **src,
QIOChannel **dst)
{
@@ -146,21 +148,34 @@ static void test_io_channel_setup_async(SocketAddress *listen_addr,
qio_channel_set_delay(*src, false);
test_io_channel_set_socket_bufs(*src, *dst);
- object_unref(OBJECT(lioc));
+ *srv = QIO_CHANNEL(lioc);
g_main_loop_unref(data.loop);
}
+static void test_io_channel_socket_path_exists(SocketAddress *addr,
+ bool expectExists)
+{
+ if (addr->type != SOCKET_ADDRESS_TYPE_UNIX) {
+ return;
+ }
+
+ g_assert(g_file_test(addr->u.q_unix.path,
+ G_FILE_TEST_EXISTS) == expectExists);
+}
+
+
static void test_io_channel(bool async,
SocketAddress *listen_addr,
SocketAddress *connect_addr,
bool passFD)
{
- QIOChannel *src, *dst;
+ QIOChannel *src, *dst, *srv;
QIOChannelTest *test;
if (async) {
- test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_async(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -169,14 +184,25 @@ static void test_io_channel(bool async,
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
test = qio_channel_test_new();
qio_channel_test_run_threads(test, true, src, dst);
qio_channel_test_validate(test);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ /* unref without close, to ensure finalize() cleans up */
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
- test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
+
+ test_io_channel_setup_async(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -189,10 +215,24 @@ static void test_io_channel(bool async,
qio_channel_test_run_threads(test, false, src, dst);
qio_channel_test_validate(test);
+ /* close before unref, to ensure finalize copes with already closed */
+
+ qio_channel_close(src, &error_abort);
+ qio_channel_close(dst, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ qio_channel_close(srv, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, false);
+
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
} else {
- test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_sync(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -201,14 +241,25 @@ static void test_io_channel(bool async,
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
test = qio_channel_test_new();
qio_channel_test_run_threads(test, true, src, dst);
qio_channel_test_validate(test);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ /* unref without close, to ensure finalize() cleans up */
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
- test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_sync(listen_addr, connect_addr,
+ &srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@@ -221,8 +272,23 @@ static void test_io_channel(bool async,
qio_channel_test_run_threads(test, false, src, dst);
qio_channel_test_validate(test);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ /* close before unref, to ensure finalize copes with already closed */
+
+ qio_channel_close(src, &error_abort);
+ qio_channel_close(dst, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, true);
+
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ test_io_channel_socket_path_exists(listen_addr, true);
+
+ qio_channel_close(srv, &error_abort);
+ test_io_channel_socket_path_exists(listen_addr, false);
+
+ object_unref(OBJECT(srv));
+ test_io_channel_socket_path_exists(listen_addr, false);
}
}
@@ -316,7 +382,6 @@ static void test_io_channel_unix(bool async)
qapi_free_SocketAddress(listen_addr);
qapi_free_SocketAddress(connect_addr);
- g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS) == FALSE);
}
@@ -335,7 +400,7 @@ static void test_io_channel_unix_fd_pass(void)
{
SocketAddress *listen_addr = g_new0(SocketAddress, 1);
SocketAddress *connect_addr = g_new0(SocketAddress, 1);
- QIOChannel *src, *dst;
+ QIOChannel *src, *dst, *srv;
int testfd;
int fdsend[3];
int *fdrecv = NULL;
@@ -359,7 +424,7 @@ static void test_io_channel_unix_fd_pass(void)
connect_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
connect_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
- test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
+ test_io_channel_setup_sync(listen_addr, connect_addr, &srv, &src, &dst);
memcpy(bufsend, "Hello World", G_N_ELEMENTS(bufsend));
@@ -412,6 +477,7 @@ static void test_io_channel_unix_fd_pass(void)
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
+ object_unref(OBJECT(srv));
qapi_free_SocketAddress(listen_addr);
qapi_free_SocketAddress(connect_addr);
unlink(TEST_SOCKET);
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
index 9cddd72adb..bf900f14f4 100644
--- a/tests/test-qmp-event.c
+++ b/tests/test-qmp-event.c
@@ -93,9 +93,7 @@ static bool qdict_cmp_simple(QDict *a, QDict *b)
return d.result;
}
-/* This function is hooked as final emit function, which can verify the
- correctness. */
-static void event_test_emit(test_QAPIEvent event, QDict *d)
+void test_qapi_event_emit(test_QAPIEvent event, QDict *d)
{
QDict *t;
int64_t s, ms;
@@ -241,8 +239,6 @@ static void test_event_d(TestEventData *data,
int main(int argc, char **argv)
{
- qmp_event_set_func_emit(event_test_emit);
-
g_test_init(&argc, &argv, NULL);
event_test_add("/event/event_a", test_event_a);
diff --git a/ui/input-linux.c b/ui/input-linux.c
index 9720333b2c..ba550dd274 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -12,6 +12,8 @@
#include "sysemu/sysemu.h"
#include "ui/input.h"
#include "qom/object_interfaces.h"
+#include "sysemu/iothread.h"
+#include "block/aio.h"
#include <sys/ioctl.h>
#include "standard-headers/linux/input.h"
@@ -63,6 +65,8 @@ struct InputLinux {
struct input_event event;
int read_offset;
+ enum GrabToggleKeys grab_toggle;
+
QTAILQ_ENTRY(InputLinux) next;
};
@@ -98,6 +102,44 @@ static void input_linux_toggle_grab(InputLinux *il)
}
}
+static bool input_linux_check_toggle(InputLinux *il)
+{
+ switch (il->grab_toggle) {
+ case GRAB_TOGGLE_KEYS_CTRL_CTRL:
+ return il->keydown[KEY_LEFTCTRL] &&
+ il->keydown[KEY_RIGHTCTRL];
+
+ case GRAB_TOGGLE_KEYS_ALT_ALT:
+ return il->keydown[KEY_LEFTALT] &&
+ il->keydown[KEY_RIGHTALT];
+
+ case GRAB_TOGGLE_KEYS_META_META:
+ return il->keydown[KEY_LEFTMETA] &&
+ il->keydown[KEY_RIGHTMETA];
+
+ case GRAB_TOGGLE_KEYS_SCROLLLOCK:
+ return il->keydown[KEY_SCROLLLOCK];
+
+ case GRAB_TOGGLE_KEYS_CTRL_SCROLLLOCK:
+ return (il->keydown[KEY_LEFTCTRL] ||
+ il->keydown[KEY_RIGHTCTRL]) &&
+ il->keydown[KEY_SCROLLLOCK];
+
+ case GRAB_TOGGLE_KEYS__MAX:
+ /* avoid gcc error */
+ break;
+ }
+ return false;
+}
+
+static bool input_linux_should_skip(InputLinux *il,
+ struct input_event *event)
+{
+ return (il->grab_toggle == GRAB_TOGGLE_KEYS_SCROLLLOCK ||
+ il->grab_toggle == GRAB_TOGGLE_KEYS_CTRL_SCROLLLOCK) &&
+ event->code == KEY_SCROLLLOCK;
+}
+
static void input_linux_handle_keyboard(InputLinux *il,
struct input_event *event)
{
@@ -128,14 +170,13 @@ static void input_linux_handle_keyboard(InputLinux *il,
}
/* send event to guest when grab is active */
- if (il->grab_active) {
+ if (il->grab_active && !input_linux_should_skip(il, event)) {
int qcode = qemu_input_linux_to_qcode(event->code);
qemu_input_event_send_key_qcode(NULL, qcode, event->value);
}
/* hotkey -> record switch request ... */
- if (il->keydown[KEY_LEFTCTRL] &&
- il->keydown[KEY_RIGHTCTRL]) {
+ if (input_linux_check_toggle(il)) {
il->grab_request = true;
}
@@ -410,6 +451,21 @@ static void input_linux_set_repeat(Object *obj, bool value,
il->repeat = value;
}
+static int input_linux_get_grab_toggle(Object *obj, Error **errp)
+{
+ InputLinux *il = INPUT_LINUX(obj);
+
+ return il->grab_toggle;
+}
+
+static void input_linux_set_grab_toggle(Object *obj, int value,
+ Error **errp)
+{
+ InputLinux *il = INPUT_LINUX(obj);
+
+ il->grab_toggle = value;
+}
+
static void input_linux_instance_init(Object *obj)
{
object_property_add_str(obj, "evdev",
@@ -421,6 +477,10 @@ static void input_linux_instance_init(Object *obj)
object_property_add_bool(obj, "repeat",
input_linux_get_repeat,
input_linux_set_repeat, NULL);
+ object_property_add_enum(obj, "grab-toggle", "GrabToggleKeys",
+ &GrabToggleKeys_lookup,
+ input_linux_get_grab_toggle,
+ input_linux_set_grab_toggle, NULL);
}
static void input_linux_class_init(ObjectClass *oc, void *data)