diff options
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | audio/audio.c | 12 | ||||
-rw-r--r-- | audio/paaudio.c | 15 | ||||
-rwxr-xr-x | configure | 81 | ||||
-rw-r--r-- | contrib/gitdm/filetypes.txt | 2 | ||||
-rw-r--r-- | docs/devel/qapi-code-gen.txt | 12 | ||||
-rw-r--r-- | hw/audio/pcspk.c | 35 | ||||
-rw-r--r-- | hw/i386/pc.c | 4 | ||||
-rw-r--r-- | include/hw/virtio/virtio-net.h | 2 | ||||
-rw-r--r-- | include/qapi/qmp-event.h | 6 | ||||
-rw-r--r-- | io/channel-socket.c | 19 | ||||
-rw-r--r-- | monitor.c | 4 | ||||
-rw-r--r-- | qapi/misc.json | 36 | ||||
-rw-r--r-- | qapi/qmp-event.c | 12 | ||||
-rw-r--r-- | qapi/ui.json | 10 | ||||
-rw-r--r-- | qobject/json-parser.c | 10 | ||||
-rw-r--r-- | scripts/qapi/events.py | 24 | ||||
-rw-r--r-- | stubs/monitor.c | 5 | ||||
-rw-r--r-- | target/ppc/translate_init.inc.c | 8 | ||||
-rw-r--r-- | tests/Makefile.include | 4 | ||||
-rw-r--r-- | tests/check-qjson.c | 5 | ||||
-rw-r--r-- | tests/test-io-channel-socket.c | 86 | ||||
-rw-r--r-- | tests/test-qmp-event.c | 6 | ||||
-rw-r--r-- | ui/input-linux.c | 66 |
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; @@ -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; } @@ -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) |