Hello community,

here is the log from the commit of package spice-vdagent for openSUSE:Factory 
checked in at 2015-08-01 11:38:29
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/spice-vdagent (Old)
 and      /work/SRC/openSUSE:Factory/.spice-vdagent.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "spice-vdagent"

Changes:
--------
--- /work/SRC/openSUSE:Factory/spice-vdagent/spice-vdagent.changes      
2014-07-16 16:22:14.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.spice-vdagent.new/spice-vdagent.changes 
2015-08-01 11:38:30.000000000 +0200
@@ -1,0 +2,13 @@
+Tue Jul 21 18:52:21 UTC 2015 - [email protected]
+
+- Update tp 0.16.0
+  * Xspice support
+  * Release clipboard on client disconnect if owned by client 
+    (rhbz#1003977)
+  * Turn some error messages into debugging messages (rhbz#918310)
+  * Not having the virtio channel is not an error; instead silently 
+    do nothing
+- Cleanup spec file with spec-cleaner
+- Actually apply spice-vdagent-var_run.patch
+
+-------------------------------------------------------------------

Old:
----
  spice-vdagent-0.15.0.tar.bz2

New:
----
  spice-vdagent-0.16.0.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ spice-vdagent.spec ++++++
--- /var/tmp/diff_new_pack.fFMrlW/_old  2015-08-01 11:38:30.000000000 +0200
+++ /var/tmp/diff_new_pack.fFMrlW/_new  2015-08-01 11:38:30.000000000 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package spice-vdagent
 #
-# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany.
 # Copyright (c) 2014 B1 Systems GmbH, Vohburg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
@@ -18,7 +18,7 @@
 
 
 Name:           spice-vdagent
-Version:        0.15.0
+Version:        0.16.0
 Release:        0
 Summary:        Agent for Spice guests
 License:        GPL-3.0+
@@ -26,6 +26,7 @@
 Url:            http://spice-space.org/
 Source0:        
http://spice-space.org/download/releases/%{name}-%{version}.tar.bz2
 Patch0:         spice-vdagent-var_run.patch
+BuildRequires:  alsa-devel
 BuildRequires:  desktop-file-utils
 BuildRequires:  glib2-devel
 BuildRequires:  libXfixes-devel
@@ -36,8 +37,8 @@
 BuildRequires:  spice-protocol-devel >= 0.12.6
 BuildRequires:  systemd
 BuildRequires:  systemd-devel
-%{?systemd_requires}
 Supplements:    modalias(xorg-x11-server:virtio:d00000003v*)
+%{?systemd_requires}
 
 %description
 Spice agent for Linux guests offering the following features:
@@ -53,9 +54,12 @@
 
 %prep
 %setup -q
+%patch0 -p1
 
 %build
-%configure --with-session-info=systemd --with-init-script=systemd
+%configure \
+  --with-session-info=systemd \
+  --with-init-script=systemd
 make %{?_smp_mflags} V=2
 
 %install

++++++ spice-vdagent-0.15.0.tar.bz2 -> spice-vdagent-0.16.0.tar.bz2 ++++++
++++ 3331 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/Makefile.am new/spice-vdagent-0.16.0/Makefile.am
--- old/spice-vdagent-0.15.0/Makefile.am        2013-10-14 14:52:01.000000000 
+0200
+++ new/spice-vdagent-0.16.0/Makefile.am        2015-06-30 17:08:42.000000000 
+0200
@@ -4,9 +4,14 @@
 bin_PROGRAMS = src/spice-vdagent
 sbin_PROGRAMS = src/spice-vdagentd
 
-src_spice_vdagent_CFLAGS = $(X_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS)
-src_spice_vdagent_LDADD = $(X_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS)
-src_spice_vdagent_SOURCES = src/vdagent.c src/vdagent-x11.c 
src/vdagent-x11-randr.c src/vdagent-file-xfers.c src/udscs.c
+src_spice_vdagent_CFLAGS = $(X_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS) 
$(ALSA_CFLAGS)
+src_spice_vdagent_LDADD = $(X_LIBS) $(SPICE_LIBS) $(GLIB2_LIBS) $(ALSA_LIBS)
+src_spice_vdagent_SOURCES = src/vdagent.c \
+                            src/vdagent-x11.c \
+                            src/vdagent-x11-randr.c \
+                            src/vdagent-file-xfers.c \
+                            src/vdagent-audio.c \
+                            src/udscs.c
 
 src_spice_vdagentd_CFLAGS = $(DBUS_CFLAGS) $(LIBSYSTEMD_LOGIN_CFLAGS) \
   $(PCIACCESS_CFLAGS) $(SPICE_CFLAGS) $(GLIB2_CFLAGS) $(PIE_CFLAGS)
@@ -30,6 +35,7 @@
 noinst_HEADERS = src/glib-compat.h \
                  src/session-info.h \
                  src/udscs.h \
+                 src/vdagent-audio.h \
                  src/vdagent-file-xfers.h \
                  src/vdagent-virtio-port.h \
                  src/vdagent-x11.h \
@@ -42,15 +48,15 @@
 xdgautostartdir = $(sysconfdir)/xdg/autostart
 xdgautostart_DATA = $(top_srcdir)/data/spice-vdagent.desktop
 
-gdmautostartdir = $(datadir)/gdm/autostart/LoginWindow
+gdmautostartdir = $(datadir)/gdm/greeter/autostart
 gdmautostart_DATA = $(top_srcdir)/data/spice-vdagent.desktop
 
+gdmautostart2dir = $(datadir)/gdm/autostart/LoginWindow
+gdmautostart2_DATA = $(top_srcdir)/data/spice-vdagent.desktop
+
 install-data-local:
        $(mkdir_p) $(DESTDIR)$(localstatedir)/run/spice-vdagentd
 
-rsyslogdir = $(sysconfdir)/rsyslog.d
-rsyslog_DATA = $(top_srcdir)/data/rsyslog.d/spice-vdagentd.conf
-
 if INIT_SCRIPT_RED_HAT
 initdir = $(sysconfdir)/rc.d/init.d
 init_SCRIPTS = $(top_srcdir)/data/spice-vdagentd
@@ -74,9 +80,9 @@
                data/spice-vdagentd.1
 
 EXTRA_DIST =                                   \
+       NEWS                                    \
        README.RHEL-5                           \
        data/70-spice-vdagentd.rules            \
-       data/rsyslog.d/spice-vdagentd.conf      \
        data/spice-vdagent.desktop              \
        data/spice-vdagentd                     \
        data/spice-vdagentd.service             \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/NEWS new/spice-vdagent-0.16.0/NEWS
--- old/spice-vdagent-0.15.0/NEWS       1970-01-01 01:00:00.000000000 +0100
+++ new/spice-vdagent-0.16.0/NEWS       2015-06-30 17:08:42.000000000 +0200
@@ -0,0 +1,10 @@
+Overview of changes in SPICE vdagent 0.16.0
+===========================================
+
+- Add audio volume synchronization support
+- Add support for maximum clipboard size
+- Add support for more clipboard targets (STRING and TIMESTAMP)
+- Improve handling of transfers of multiple files
+- Fix transfer of >2GB files on 32 bit systems
+- XSpice improvements
+- Various bug fixes related to resolution changes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/compile new/spice-vdagent-0.16.0/compile
--- old/spice-vdagent-0.15.0/compile    2013-10-14 14:52:18.000000000 +0200
+++ new/spice-vdagent-0.16.0/compile    2015-06-30 17:24:22.000000000 +0200
@@ -3,7 +3,7 @@
 
 scriptversion=2012-10-14.11; # UTC
 
-# Copyright (C) 1999-2013 Free Software Foundation, Inc.
+# Copyright (C) 1999-2014 Free Software Foundation, Inc.
 # Written by Tom Tromey <[email protected]>.
 #
 # This program is free software; you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/configure.ac new/spice-vdagent-0.16.0/configure.ac
--- old/spice-vdagent-0.15.0/configure.ac       2013-10-14 14:52:01.000000000 
+0200
+++ new/spice-vdagent-0.16.0/configure.ac       2015-06-30 17:08:42.000000000 
+0200
@@ -1,5 +1,5 @@
 AC_PREREQ(2.59)
-AC_INIT([spice-vdagent], [0.15.0])
+AC_INIT([spice-vdagent], [0.16.0])
 AC_CONFIG_SRCDIR([configure.ac])
 
 AM_CONFIG_HEADER([src/config.h])
@@ -10,6 +10,7 @@
 AC_PROG_CC
 AM_PROG_CC_C_O
 AC_HEADER_STDC
+AC_SYS_LARGEFILE
 AC_PROG_INSTALL
 AC_PROG_LN_S
 AC_DEFINE(_GNU_SOURCE, [1], [Enable GNU extensions])
@@ -78,7 +79,8 @@
 
 PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.12])
 PKG_CHECK_MODULES(X, [xfixes xrandr >= 1.3 xinerama x11])
-PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.5])
+PKG_CHECK_MODULES(SPICE, [spice-protocol >= 0.12.8])
+PKG_CHECK_MODULES(ALSA, [alsa >= 1.0.22])
 
 if test "$with_session_info" = "auto" || test "$with_session_info" = 
"systemd"; then
     PKG_CHECK_MODULES([LIBSYSTEMD_LOGIN],
@@ -128,7 +130,7 @@
 
 # If no CFLAGS are set, set some sane default CFLAGS
 if test "$ac_test_CFLAGS" != set; then
-  DEFAULT_CFLAGS="-Wall -Werror -Wp,-D_FORTIFY_SOURCE=2 -fstack-protector 
--param=ssp-buffer-size=4"
+  DEFAULT_CFLAGS="-Wall -Werror -Wp,-D_FORTIFY_SOURCE=2 -fno-strict-aliasing 
-fstack-protector --param=ssp-buffer-size=4"
   for F in $DEFAULT_CFLAGS; do
     AC_MSG_CHECKING([whether $CC supports $F])
     save_CFLAGS="$CFLAGS"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/data/rsyslog.d/spice-vdagentd.conf 
new/spice-vdagent-0.16.0/data/rsyslog.d/spice-vdagentd.conf
--- old/spice-vdagent-0.15.0/data/rsyslog.d/spice-vdagentd.conf 2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/data/rsyslog.d/spice-vdagentd.conf 1970-01-01 
01:00:00.000000000 +0100
@@ -1,4 +0,0 @@
-# A template to for higher precision timestamps + severity logging
-$template SpiceTmpl,"%TIMESTAMP%.%TIMESTAMP:::date-subseconds% %syslogtag% 
%syslogseverity-text%:%msg:::sp-if-no-1st-sp%%msg:::drop-last-lf%\n"
-
-:programname, startswith, "spice-vdagent"      
/var/log/spice-vdagent.log;SpiceTmpl
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/data/spice-vdagentd.1.in 
new/spice-vdagent-0.16.0/data/spice-vdagentd.1.in
--- old/spice-vdagent-0.15.0/data/spice-vdagentd.1.in   2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/data/spice-vdagentd.1.in   2015-06-30 
17:00:57.000000000 +0200
@@ -29,6 +29,13 @@
 \fB-d\fP
 Log debug messages (use twice for extra info)
 .TP
+\fB-f\fP
+Treat uinput device as fake; no ioctls.
+This is useful in combination with Xspice.
+.TP
+\fB-o\fP
+The daemon will exit after processing a single session.
+.TP
 \fB-s\fP \fIport\fR
 Set virtio serial \fIport\fR (default: /dev/virtio-ports/com.redhat.spice.0)
 .TP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/missing new/spice-vdagent-0.16.0/missing
--- old/spice-vdagent-0.15.0/missing    2013-10-14 14:52:18.000000000 +0200
+++ new/spice-vdagent-0.16.0/missing    2015-06-30 17:24:22.000000000 +0200
@@ -1,9 +1,9 @@
 #! /bin/sh
 # Common wrapper for a few potentially missing GNU programs.
 
-scriptversion=2012-06-26.16; # UTC
+scriptversion=2013-10-28.13; # UTC
 
-# Copyright (C) 1996-2013 Free Software Foundation, Inc.
+# Copyright (C) 1996-2014 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <[email protected]>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
@@ -160,7 +160,7 @@
       ;;
    autom4te*)
       echo "You might have modified some maintainer files that require"
-      echo "the 'automa4te' program to be rebuilt."
+      echo "the 'autom4te' program to be rebuilt."
       program_details 'autom4te'
       ;;
     bison*|yacc*)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/config.h.in 
new/spice-vdagent-0.16.0/src/config.h.in
--- old/spice-vdagent-0.15.0/src/config.h.in    2013-10-14 14:52:17.000000000 
+0200
+++ new/spice-vdagent-0.16.0/src/config.h.in    2015-06-30 17:24:22.000000000 
+0200
@@ -9,9 +9,6 @@
 /* If defined, vdagentd will be compiled with pciaccess support */
 #undef HAVE_PCIACCESS
 
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-#undef NO_MINUS_C_MINUS_O
-
 /* Name of package */
 #undef PACKAGE
 
@@ -42,5 +39,16 @@
 /* If defined, vdagentd will use a static uinput device */
 #undef WITH_STATIC_UINPUT
 
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
 /* Enable GNU extensions */
 #undef _GNU_SOURCE
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent-audio.c 
new/spice-vdagent-0.16.0/src/vdagent-audio.c
--- old/spice-vdagent-0.15.0/src/vdagent-audio.c        1970-01-01 
01:00:00.000000000 +0100
+++ new/spice-vdagent-0.16.0/src/vdagent-audio.c        2015-05-26 
11:22:43.000000000 +0200
@@ -0,0 +1,168 @@
+/*  vdagent-audio.c vdagentd audio handling code
+
+    Copyright 2015 Red Hat, Inc.
+
+    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 3 of the License, or
+    (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
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <syslog.h>
+#include <stdbool.h>
+#include <alsa/asoundlib.h>
+#include <alsa/mixer.h>
+#include <alsa/error.h>
+#include "vdagent-audio.h"
+
+#define ALSA_MUTE   0
+#define ALSA_UNMUTE 1
+
+static snd_mixer_elem_t *
+get_alsa_default_mixer_by_name(snd_mixer_t **handle, const char *name)
+{
+    snd_mixer_selem_id_t *sid;
+    int err = 0;
+
+    if ((err = snd_mixer_open(handle, 0)) < 0)
+        goto fail;
+
+    if ((err = snd_mixer_attach(*handle, "default")) < 0)
+        goto fail;
+
+    if ((err = snd_mixer_selem_register(*handle, NULL, NULL)) < 0)
+        goto fail;
+
+    if ((err = snd_mixer_load(*handle)) < 0)
+        goto fail;
+
+    snd_mixer_selem_id_alloca(&sid);
+    snd_mixer_selem_id_set_index(sid, 0);
+    snd_mixer_selem_id_set_name(sid, name);
+    return snd_mixer_find_selem(*handle, sid);
+
+fail:
+    syslog(LOG_WARNING, "%s fail: %s", __func__, snd_strerror(err));
+    return NULL;
+}
+
+static bool set_alsa_capture(uint8_t mute, uint8_t nchannels, uint16_t *volume)
+{
+    snd_mixer_t *handle = NULL;
+    snd_mixer_elem_t *e;
+    long min, max, vol;
+    bool ret = true;
+    int alsa_mute;
+
+    e = get_alsa_default_mixer_by_name (&handle, "Capture");
+    if (e == NULL) {
+        syslog(LOG_WARNING, "vdagent-audio: can't get default alsa mixer");
+        ret = false;
+        goto end;
+    }
+
+    alsa_mute = (mute) ? ALSA_MUTE : ALSA_UNMUTE;
+    snd_mixer_selem_set_capture_switch_all(e, alsa_mute);
+
+    snd_mixer_selem_get_capture_volume_range(e, &min, &max);
+    switch (nchannels) {
+    case 1: /* MONO */
+        vol = CLAMP(volume[0], min, max);
+        snd_mixer_selem_set_capture_volume(e, SND_MIXER_SCHN_MONO, vol);
+        syslog(LOG_DEBUG, "vdagent-audio: (capture-mono) %lu (%%%0.2f)",
+               vol, (float) (100*vol/max));
+        break;
+    case 2: /* LEFT-RIGHT */
+        vol = CLAMP(volume[0], min, max);
+        snd_mixer_selem_set_capture_volume(e, SND_MIXER_SCHN_FRONT_LEFT, vol);
+        syslog(LOG_DEBUG, "vdagent-audio: (capture-left) %lu (%%%0.2f)",
+               vol, (float) (100*vol/max));
+        vol = CLAMP(volume[1], min, max);
+        snd_mixer_selem_set_capture_volume(e, SND_MIXER_SCHN_FRONT_RIGHT, vol);
+        syslog(LOG_DEBUG, "vdagent-audio: (capture-right) %lu (%%%0.2f)",
+               vol, (float) (100*vol/max));
+        break;
+    default:
+        syslog(LOG_WARNING, "vdagent-audio: number of channels not supported");
+        ret = false;
+    }
+end:
+    if (handle != NULL)
+        snd_mixer_close(handle);
+    return ret;
+}
+
+static bool set_alsa_playback (uint8_t mute, uint8_t nchannels, uint16_t 
*volume)
+{
+    snd_mixer_t *handle = NULL;
+    snd_mixer_elem_t* e;
+    long min, max, vol;
+    bool ret = true;
+    int alsa_mute;
+
+    e = get_alsa_default_mixer_by_name (&handle, "Master");
+    if (e == NULL) {
+        syslog(LOG_WARNING, "vdagent-audio: can't get default alsa mixer");
+        ret = false;
+        goto end;
+    }
+
+    alsa_mute = (mute) ? ALSA_MUTE : ALSA_UNMUTE;
+    snd_mixer_selem_set_playback_switch_all(e, alsa_mute);
+
+    snd_mixer_selem_get_playback_volume_range(e, &min, &max);
+    switch (nchannels) {
+    case 1: /* MONO */
+        vol = CLAMP(volume[0], min, max);
+        snd_mixer_selem_set_playback_volume(e, SND_MIXER_SCHN_MONO, vol);
+        syslog(LOG_DEBUG, "vdagent-audio: (playback-mono) %lu (%%%0.2f)",
+               vol, (float) (100*vol/max));
+        break;
+    case 2: /* LEFT-RIGHT */
+        vol = CLAMP(volume[0], min, max);
+        snd_mixer_selem_set_playback_volume(e, SND_MIXER_SCHN_FRONT_LEFT, vol);
+        syslog(LOG_DEBUG, "vdagent-audio: (playback-left) %lu (%%%0.2f)",
+               vol, (float) (100*vol/max));
+        vol = CLAMP(volume[1], min, max);
+        snd_mixer_selem_set_playback_volume(e, SND_MIXER_SCHN_FRONT_RIGHT, 
vol);
+        syslog(LOG_DEBUG, "vdagent-audio: (playback-right) %lu (%%%0.2f)",
+               vol, (float) (100*vol/max));
+        break;
+    default:
+        syslog(LOG_WARNING, "vdagent-audio: number of channels not supported");
+        ret = false;
+    }
+end:
+    if (handle != NULL)
+        snd_mixer_close(handle);
+    return ret;
+}
+
+void vdagent_audio_playback_sync(uint8_t mute, uint8_t nchannels, uint16_t 
*volume)
+{
+    syslog(LOG_DEBUG, "%s mute=%s nchannels=%u",
+           __func__, (mute) ? "yes" : "no", nchannels);
+    if (set_alsa_playback (mute, nchannels, volume) == false)
+        syslog(LOG_WARNING, "Fail to sync playback volume");
+}
+
+void vdagent_audio_record_sync(uint8_t mute, uint8_t nchannels, uint16_t 
*volume)
+{
+    syslog(LOG_DEBUG, "%s mute=%s nchannels=%u",
+           __func__, (mute) ? "yes" : "no", nchannels);
+    if (set_alsa_capture (mute, nchannels, volume) == false)
+        syslog(LOG_WARNING, "Fail to sync record volume");
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent-audio.h 
new/spice-vdagent-0.16.0/src/vdagent-audio.h
--- old/spice-vdagent-0.15.0/src/vdagent-audio.h        1970-01-01 
01:00:00.000000000 +0100
+++ new/spice-vdagent-0.16.0/src/vdagent-audio.h        2015-05-26 
11:22:43.000000000 +0200
@@ -0,0 +1,27 @@
+/*  vdagent-audio.h vdagentd audio handling header
+
+    Copyright 2015 Red Hat, Inc.
+
+    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 3 of the License, or
+    (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
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#ifndef __VDAGENT_AUDIO_H
+#define __VDAGENT_AUDIO_H
+
+#include <stdio.h>
+#include <stdint.h>
+
+void vdagent_audio_playback_sync(uint8_t mute, uint8_t nchannels, uint16_t 
*volume);
+void vdagent_audio_record_sync(uint8_t mute, uint8_t nchannels, uint16_t 
*volume);
+
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent-file-xfers.c 
new/spice-vdagent-0.16.0/src/vdagent-file-xfers.c
--- old/spice-vdagent-0.15.0/src/vdagent-file-xfers.c   2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/src/vdagent-file-xfers.c   2015-04-01 
10:57:14.000000000 +0200
@@ -97,6 +97,8 @@
 
 void vdagent_file_xfers_destroy(struct vdagent_file_xfers *xfers)
 {
+    g_return_if_fail(xfers != NULL);
+
     g_hash_table_destroy(xfers->xfers);
     g_free(xfers->save_dir);
     g_free(xfers);
@@ -107,6 +109,8 @@
 {
     AgentFileXferTask *task;
 
+    g_return_val_if_fail(xfers != NULL, NULL);
+
     task = g_hash_table_lookup(xfers->xfers, GUINT_TO_POINTER(id));
     if (task == NULL)
         syslog(LOG_ERR, "file-xfer: error can not find task %u", id);
@@ -173,6 +177,8 @@
     struct stat st;
     int i;
 
+    g_return_if_fail(xfers != NULL);
+
     if (g_hash_table_lookup(xfers->xfers, GUINT_TO_POINTER(msg->id))) {
         syslog(LOG_ERR, "file-xfer: error id %u already exists, ignoring!",
                msg->id);
@@ -246,6 +252,8 @@
 {
     AgentFileXferTask *task;
 
+    g_return_if_fail(xfers != NULL);
+
     task = vdagent_file_xfers_get_task(xfers, msg->id);
     if (!task)
         return;
@@ -267,6 +275,8 @@
     AgentFileXferTask *task;
     int len, status = -1;
 
+    g_return_if_fail(xfers != NULL);
+
     task = vdagent_file_xfers_get_task(xfers, msg->id);
     if (!task)
         return;
@@ -282,7 +292,8 @@
                 close(task->file_fd);
                 task->file_fd = -1;
                 if (xfers->open_save_dir &&
-                        task->file_xfer_nr == task->file_xfer_total) {
+                        task->file_xfer_nr == task->file_xfer_total &&
+                        g_hash_table_size(xfers->xfers) == 1) {
                     char buf[PATH_MAX];
                     snprintf(buf, PATH_MAX, "xdg-open '%s'&", xfers->save_dir);
                     status = system(buf);
@@ -305,3 +316,11 @@
         g_hash_table_remove(xfers->xfers, GUINT_TO_POINTER(msg->id));
     }
 }
+
+void vdagent_file_xfers_error(struct udscs_connection *vdagentd, uint32_t 
msg_id)
+{
+    g_return_if_fail(vdagentd != NULL);
+
+    udscs_write(vdagentd, VDAGENTD_FILE_XFER_STATUS,
+                msg_id, VD_AGENT_FILE_XFER_STATUS_ERROR, NULL, 0);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent-file-xfers.h 
new/spice-vdagent-0.16.0/src/vdagent-file-xfers.h
--- old/spice-vdagent-0.15.0/src/vdagent-file-xfers.h   2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/src/vdagent-file-xfers.h   2015-04-01 
10:57:14.000000000 +0200
@@ -37,5 +37,7 @@
     VDAgentFileXferStatusMessage *msg);
 void vdagent_file_xfers_data(struct vdagent_file_xfers *xfers,
     VDAgentFileXferDataMessage *msg);
+void vdagent_file_xfers_error(struct udscs_connection *vdagentd,
+    uint32_t msg_id);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent-x11-priv.h 
new/spice-vdagent-0.16.0/src/vdagent-x11-priv.h
--- old/spice-vdagent-0.15.0/src/vdagent-x11-priv.h     2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/src/vdagent-x11-priv.h     2015-04-10 
16:37:26.000000000 +0200
@@ -64,8 +64,8 @@
 };
 
 static const struct clipboard_format_tmpl clipboard_format_templates[] = {
-    { VD_AGENT_CLIPBOARD_UTF8_TEXT, { "UTF8_STRING",
-      "text/plain;charset=UTF-8", "text/plain;charset=utf-8", NULL }, },
+    { VD_AGENT_CLIPBOARD_UTF8_TEXT, { "UTF8_STRING", 
"text/plain;charset=UTF-8",
+      "text/plain;charset=utf-8", "STRING", NULL }, },
     { VD_AGENT_CLIPBOARD_IMAGE_PNG, { "image/png", NULL }, },
     { VD_AGENT_CLIPBOARD_IMAGE_BMP, { "image/bmp", "image/x-bmp",
       "image/x-MS-bmp", "image/x-win-bitmap", NULL }, },
@@ -83,6 +83,7 @@
     Atom targets_atom;
     Atom incr_atom;
     Atom multiple_atom;
+    Atom timestamp_atom;
     Window root_window[MAX_SCREENS];
     Window selection_window;
     struct udscs_connection *vdagentd;
@@ -94,6 +95,7 @@
     int height[MAX_SCREENS];
     int has_xfixes;
     int xfixes_event_base;
+    int xrandr_event_base;
     int max_prop_size;
     int expected_targets_notifies[256];
     int clipboard_owner[256];
@@ -144,7 +146,8 @@
                                             int update);
 void vdagent_x11_randr_handle_root_size_change(struct vdagent_x11 *x11,
                                             int screen, int width, int height);
-
+int vdagent_x11_randr_handle_event(struct vdagent_x11 *x11,
+    XEvent event);
 void vdagent_x11_set_error_handler(struct vdagent_x11 *x11,
     int (*handler)(Display *, XErrorEvent *));
 int vdagent_x11_restore_error_handler(struct vdagent_x11 *x11);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent-x11-randr.c 
new/spice-vdagent-0.16.0/src/vdagent-x11-randr.c
--- old/spice-vdagent-0.15.0/src/vdagent-x11-randr.c    2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/src/vdagent-x11-randr.c    2015-05-26 
11:22:43.000000000 +0200
@@ -21,6 +21,8 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <glib.h>
+#include <glib/gstdio.h>
 #include <string.h>
 #include <syslog.h>
 #include <stdlib.h>
@@ -32,6 +34,8 @@
 #include "vdagent-x11.h"
 #include "vdagent-x11-priv.h"
 
+#define MM_PER_INCH (25.4)
+
 static int error_handler(Display *display, XErrorEvent *error)
 {
     vdagent_x11_caught_error = 1;
@@ -129,12 +133,15 @@
         return;
     }
 
-    if (XRRQueryExtension(x11->display, &i, &i)) {
+    if (XRRQueryExtension(x11->display, &x11->xrandr_event_base, &i)) {
         XRRQueryVersion(x11->display, &x11->xrandr_major, &x11->xrandr_minor);
         if (x11->xrandr_major == 1 && x11->xrandr_minor >= 3)
             x11->has_xrandr = 1;
     }
 
+    XRRSelectInput(x11->display, x11->root_window[0],
+        RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask);
+
     if (x11->has_xrandr) {
         update_randr_res(x11, 0);
     } else {
@@ -364,11 +371,11 @@
     x11->randr.monitor_sizes[output].width = width;
     x11->randr.monitor_sizes[output].height = height;
     outputs[0] = xid;
+    vdagent_x11_set_error_handler(x11, error_handler);
     s = XRRSetCrtcConfig(x11->display, x11->randr.res, 
x11->randr.res->crtcs[output],
                          CurrentTime, x, y, mode->id, RR_Rotate_0, outputs,
                          1);
-
-    if (s != RRSetConfigSuccess) {
+    if (vdagent_x11_restore_error_handler(x11) || (s != RRSetConfigSuccess)) {
         syslog(LOG_ERR, "failed to XRRSetCrtcConfig");
         x11->set_crtc_config_not_functional = 1;
         return 0;
@@ -463,6 +470,8 @@
 void vdagent_x11_randr_handle_root_size_change(struct vdagent_x11 *x11,
     int screen, int width, int height)
 {
+    update_randr_res(x11, 0);
+
     if (width == x11->width[screen] && height == x11->height[screen]) {
         return;
     }
@@ -478,6 +487,33 @@
     }
 }
 
+int vdagent_x11_randr_handle_event(struct vdagent_x11 *x11,
+    XEvent event)
+{
+    int handled = TRUE;
+
+    switch (event.type - x11->xrandr_event_base) {
+        case RRScreenChangeNotify: {
+            XRRScreenChangeNotifyEvent *sce =
+                (XRRScreenChangeNotifyEvent *) &event;
+            vdagent_x11_randr_handle_root_size_change(x11, 0,
+                sce->width, sce->height);
+            break;
+        }
+        case RRNotify: {
+            update_randr_res(x11, 0);
+            if (!x11->dont_send_guest_xorg_res)
+                vdagent_x11_send_daemon_guest_xorg_res(x11, 1);
+            break;
+        }
+        default:
+            handled = FALSE;
+            break;
+    }
+
+    return handled;
+}
+
 static int min_int(int x, int y)
 {
     return x > y ? y : x;
@@ -688,8 +724,6 @@
                                     VDAgentMonitorsConfig *mon_config,
                                     int fallback)
 {
-    int width, height;
-    int x, y;
     int primary_w, primary_h;
     int i, real_num_of_monitors = 0;
     VDAgentMonitorsConfig *curr = NULL;
@@ -735,6 +769,8 @@
     }
 
     curr = get_current_mon_config(x11);
+    if (!curr)
+        goto exit;
     if (same_monitor_configs(mon_config, curr) &&
            x11->width[0] == primary_w && x11->height[0] == primary_h) {
         goto exit;
@@ -745,38 +781,59 @@
         goto exit;
     }
 
+    gchar *config = g_build_filename (g_get_user_config_dir (), 
"monitors.xml", NULL);
+    g_unlink(config);
+    g_free(config);
+
     for (i = mon_config->num_of_monitors; i < x11->randr.res->noutput; i++)
         xrandr_disable_output(x11, i);
 
+    /* First, disable disabled CRTCs... */
     for (i = 0; i < mon_config->num_of_monitors; ++i) {
         if (!monitor_enabled(&mon_config->monitors[i])) {
             xrandr_disable_output(x11, i);
-            continue;
         }
-        /* Try to create the requested resolution */
-        width = mon_config->monitors[i].width;
-        height = mon_config->monitors[i].height;
-        x = mon_config->monitors[i].x;
-        y = mon_config->monitors[i].y;
-        if (!xrandr_add_and_set(x11, i, x, y, width, height) &&
-                enabled_monitors(mon_config) == 1) {
-            set_screen_to_best_size(x11, width, height,
-                                    &primary_w, &primary_h);
-            goto update;
+    }
+
+    /* ... and disable the ones that would be bigger than
+     * the new RandR screen once it is resized. If they are enabled the
+     * XRRSetScreenSize call will fail with BadMatch. They will be
+     * reenabled after hanging the screen size.
+     */
+    for (i = 0; i < curr->num_of_monitors; ++i) {
+        int width, height;
+        int x, y;
+
+        width = curr->monitors[i].width;
+        height = curr->monitors[i].height;
+        x = curr->monitors[i].x;
+        y = curr->monitors[i].y;
+
+        if ((x + width > primary_w) || (y + height > primary_h)) {
+            if (x11->debug)
+                syslog(LOG_DEBUG, "Disabling monitor %d: "
+                       "%dx%d+%d+%d > (%d,%d)",
+                       i, width, height, x, y, primary_w, primary_h);
+
+            xrandr_disable_output(x11, i);
         }
     }
 
+    /* Then we can resize the RandR screen. */
     if (primary_w != x11->width[0] || primary_h != x11->height[0]) {
+        const int dpi = 96; /* FIXME: read settings from desktop or get from 
client dpi? */
+        int width_mm = (MM_PER_INCH * primary_w) / dpi;
+        int height_mm = (MM_PER_INCH * primary_h) / dpi;
+
         if (x11->debug)
             syslog(LOG_DEBUG, "Changing screen size to %dx%d",
                    primary_w, primary_h);
         vdagent_x11_set_error_handler(x11, error_handler);
         XRRSetScreenSize(x11->display, x11->root_window[0], primary_w, 
primary_h,
-                         DisplayWidthMM(x11->display, 0),
-                         DisplayHeightMM(x11->display, 0));
+                         width_mm, height_mm);
         if (vdagent_x11_restore_error_handler(x11)) {
             syslog(LOG_ERR, "XRRSetScreenSize failed, not enough mem?");
-            if (!fallback && curr) {
+            if (!fallback) {
                 syslog(LOG_WARNING, "Restoring previous config");
                 vdagent_x11_set_monitor_config(x11, curr, 1);
                 free(curr);
@@ -793,7 +850,28 @@
         }
     }
 
-update:
+    /* Finally, we set the new resolutions on RandR CRTCs now that the
+     * RandR screen is big enough to hold these.  */
+    for (i = 0; i < mon_config->num_of_monitors; ++i) {
+        int width, height;
+        int x, y;
+
+        if (!monitor_enabled(&mon_config->monitors[i])) {
+            continue;
+        }
+        /* Try to create the requested resolution */
+        width = mon_config->monitors[i].width;
+        height = mon_config->monitors[i].height;
+        x = mon_config->monitors[i].x;
+        y = mon_config->monitors[i].y;
+        if (!xrandr_add_and_set(x11, i, x, y, width, height) &&
+                enabled_monitors(mon_config) == 1) {
+            set_screen_to_best_size(x11, width, height,
+                                    &primary_w, &primary_h);
+            break;
+        }
+    }
+
     update_randr_res(x11,
         x11->randr.num_monitors != enabled_monitors(mon_config));
     x11->width[0] = primary_w;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent-x11.c 
new/spice-vdagent-0.16.0/src/vdagent-x11.c
--- old/spice-vdagent-0.15.0/src/vdagent-x11.c  2013-10-14 14:52:01.000000000 
+0200
+++ new/spice-vdagent-0.16.0/src/vdagent-x11.c  2015-04-10 16:37:26.000000000 
+0200
@@ -218,6 +218,7 @@
     x11->targets_atom = XInternAtom(x11->display, "TARGETS", False);
     x11->incr_atom = XInternAtom(x11->display, "INCR", False);
     x11->multiple_atom = XInternAtom(x11->display, "MULTIPLE", False);
+    x11->timestamp_atom = XInternAtom(x11->display, "TIMESTAMP", False);
     for(i = 0; i < clipboard_format_count; i++) {
         x11->clipboard_formats[i].type = clipboard_format_templates[i].type;
         for(j = 0; clipboard_format_templates[i].atom_names[j]; j++) {
@@ -502,9 +503,11 @@
         return;
     }
 
+    if (vdagent_x11_randr_handle_event(x11, event))
+        return;
+
     switch (event.type) {
     case ConfigureNotify:
-        // TODO: handle CrtcConfigureNotify, OutputConfigureNotify can be 
ignored.
         for (i = 0; i < x11->screen_count; i++)
             if (event.xconfigure.window == x11->root_window[i])
                 break;
@@ -753,7 +756,7 @@
     int i, j;
 
     for (i = 0; i < clipboard_format_count; i++) {
-        for (j = 0; j < x11->clipboard_formats[i].atom_count; i++) {
+        for (j = 0; j < x11->clipboard_formats[i].atom_count; j++) {
             if (x11->clipboard_formats[i].atoms[j] == target) {
                 return x11->clipboard_formats[i].type;
             }
@@ -1036,6 +1039,20 @@
         return;
     }
 
+    if (event->xselectionrequest.target == x11->timestamp_atom) {
+        /* TODO: use more accurate selection time */
+        guint32 timestamp = event->xselectionrequest.time;
+
+        XChangeProperty(x11->display, event->xselectionrequest.requestor,
+                       event->xselectionrequest.property,
+                        event->xselectionrequest.target, 32, PropModeReplace,
+                        (guint8*)&timestamp, 1);
+        vdagent_x11_send_selection_notify(x11,
+                       event->xselectionrequest.property, NULL);
+       return;
+    }
+
+
     if (event->xselectionrequest.target == x11->targets_atom) {
         vdagent_x11_send_targets(x11, selection, event);
         return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagent.c new/spice-vdagent-0.16.0/src/vdagent.c
--- old/spice-vdagent-0.15.0/src/vdagent.c      2013-10-14 14:52:01.000000000 
+0200
+++ new/spice-vdagent-0.16.0/src/vdagent.c      2015-06-30 17:08:40.000000000 
+0200
@@ -35,10 +35,12 @@
 #include <sys/stat.h>
 #include <spice/vd_agent.h>
 #include <glib.h>
+#include <poll.h>
 
 #include "udscs.h"
 #include "vdagentd-proto.h"
 #include "vdagentd-proto-strings.h"
+#include "vdagent-audio.h"
 #include "vdagent-x11.h"
 #include "vdagent-file-xfers.h"
 
@@ -89,25 +91,52 @@
         }
         break;
     case VDAGENTD_FILE_XFER_START:
-        vdagent_file_xfers_start(vdagent_file_xfers,
-                                 (VDAgentFileXferStartMessage *)data);
+        if (vdagent_file_xfers != NULL) {
+            vdagent_file_xfers_start(vdagent_file_xfers,
+                                     (VDAgentFileXferStartMessage *)data);
+        } else {
+            vdagent_file_xfers_error(*connp,
+                                     ((VDAgentFileXferStartMessage 
*)data)->id);
+        }
         free(data);
         break;
     case VDAGENTD_FILE_XFER_STATUS:
-        vdagent_file_xfers_status(vdagent_file_xfers,
-                                  (VDAgentFileXferStatusMessage *)data);
+        if (vdagent_file_xfers != NULL) {
+            vdagent_file_xfers_status(vdagent_file_xfers,
+                                      (VDAgentFileXferStatusMessage *)data);
+        } else {
+            vdagent_file_xfers_error(*connp,
+                                     ((VDAgentFileXferStatusMessage 
*)data)->id);
+        }
         free(data);
         break;
+    case VDAGENTD_AUDIO_VOLUME_SYNC: {
+        VDAgentAudioVolumeSync *avs = (VDAgentAudioVolumeSync *)data;
+        if (avs->is_playback) {
+            vdagent_audio_playback_sync(avs->mute, avs->nchannels, 
avs->volume);
+        } else {
+            vdagent_audio_record_sync(avs->mute, avs->nchannels, avs->volume);
+        }
+        free(data);
+        break;
+    }
     case VDAGENTD_FILE_XFER_DATA:
-        vdagent_file_xfers_data(vdagent_file_xfers,
-                                (VDAgentFileXferDataMessage *)data);
+        if (vdagent_file_xfers != NULL) {
+            vdagent_file_xfers_data(vdagent_file_xfers,
+                                    (VDAgentFileXferDataMessage *)data);
+        } else {
+            vdagent_file_xfers_error(*connp,
+                                     ((VDAgentFileXferDataMessage *)data)->id);
+        }
         free(data);
         break;
     case VDAGENTD_CLIENT_DISCONNECTED:
         vdagent_x11_client_disconnected(x11);
-        vdagent_file_xfers_destroy(vdagent_file_xfers);
-        vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir,
-                                                       fx_open_dir, debug);
+        if (vdagent_file_xfers != NULL) {
+            vdagent_file_xfers_destroy(vdagent_file_xfers);
+            vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir,
+                                                           fx_open_dir, debug);
+        }
         break;
     default:
         syslog(LOG_ERR, "Unknown message from vdagentd type: %d, ignoring",
@@ -151,9 +180,34 @@
     quit = 1;
 }
 
-void daemonize(void)
+/* When we daemonize, it is useful to have the main process
+   wait to make sure the X connection worked.  We wait up
+   to 10 seconds to get an 'all clear' from the child
+   before we exit.  If we don't, we're able to exit with a
+   status that indicates an error occured */
+void wait_and_exit(int s)
+{
+    char buf[4];
+    struct pollfd p;
+    p.fd = s;
+    p.events = POLLIN;
+
+    if (poll(&p, 1, 10000) > 0)
+        if (read(s, buf, sizeof(buf)) > 0)
+            exit(0);
+
+    exit(1);
+}
+
+int daemonize(void)
 {
-    int x, retval = 0;
+    int x;
+    int fd[2];
+
+    if (socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)) {
+        syslog(LOG_ERR, "socketpair : %s", strerror(errno));
+        exit(1);
+    }
 
     /* detach from terminal */
     switch (fork()) {
@@ -161,13 +215,17 @@
         close(0); close(1); close(2);
         setsid();
         x = open("/dev/null", O_RDWR); x = dup(x); x = dup(x);
-        break;
+        close(fd[0]);
+        return fd[1];
     case -1:
         syslog(LOG_ERR, "fork: %s", strerror(errno));
-        retval = 1;
+        exit(1);
     default:
-        exit(retval);
+        close(fd[1]);
+        wait_and_exit(fd[0]);
     }
+
+    return 0;
 }
 
 static int file_test(const char *path)
@@ -182,6 +240,7 @@
     fd_set readfds, writefds;
     int c, n, nfds, x11_fd;
     int do_daemonize = 1;
+    int parent_socket = 0;
     int x11_sync = 0;
     struct sigaction act;
 
@@ -236,7 +295,7 @@
     }
 
     if (do_daemonize)
-        daemonize();
+        parent_socket = daemonize();
 
 reconnect:
     if (version_mismatch) {
@@ -267,13 +326,21 @@
         fx_dir = g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP);
     else if (!strcmp(fx_dir, "xdg-download"))
         fx_dir = g_get_user_special_dir(G_USER_DIRECTORY_DOWNLOAD);
-    if (!fx_dir) {
+    if (fx_dir) {
+        vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir,
+                                                       fx_open_dir, debug);
+    } else {
         syslog(LOG_WARNING,
-               "warning could not get file xfer save dir, using cwd");
-        fx_dir = ".";
+               "warning could not get file xfer save dir, file transfers will 
be disabled");
+        vdagent_file_xfers = NULL;
+    }
+
+    if (parent_socket) {
+        if (write(parent_socket, "OK", 2) != 2)
+            syslog(LOG_WARNING, "Parent already gone.");
+        close(parent_socket);
+        parent_socket = 0;
     }
-    vdagent_file_xfers = vdagent_file_xfers_create(client, fx_dir,
-                                                   fx_open_dir, debug);
 
     while (client && !quit) {
         FD_ZERO(&readfds);
@@ -298,7 +365,9 @@
         udscs_client_handle_fds(&client, &readfds, &writefds);
     }
 
-    vdagent_file_xfers_destroy(vdagent_file_xfers);
+    if (vdagent_file_xfers != NULL) {
+        vdagent_file_xfers_destroy(vdagent_file_xfers);
+    }
     vdagent_x11_destroy(x11, client == NULL);
     udscs_destroy_connection(&client);
     if (!quit && do_daemonize)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagentd-proto-strings.h 
new/spice-vdagent-0.16.0/src/vdagentd-proto-strings.h
--- old/spice-vdagent-0.15.0/src/vdagentd-proto-strings.h       2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/src/vdagentd-proto-strings.h       2015-05-26 
11:22:43.000000000 +0200
@@ -30,6 +30,7 @@
         "clipboard data",
         "clipboard release",
         "version",
+        "audio volume sync",
         "file xfer start",
         "file xfer status",
         "file xfer data",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagentd-proto.h 
new/spice-vdagent-0.16.0/src/vdagentd-proto.h
--- old/spice-vdagent-0.15.0/src/vdagentd-proto.h       2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/src/vdagentd-proto.h       2015-05-26 
11:22:43.000000000 +0200
@@ -36,6 +36,7 @@
     VDAGENTD_CLIPBOARD_DATA,    /* arg1: sel, arg 2: type, data: data */
     VDAGENTD_CLIPBOARD_RELEASE, /* arg1: selection */
     VDAGENTD_VERSION,           /* daemon -> client, data: version string */
+    VDAGENTD_AUDIO_VOLUME_SYNC,
     VDAGENTD_FILE_XFER_START,
     VDAGENTD_FILE_XFER_STATUS,
     VDAGENTD_FILE_XFER_DATA,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagentd-uinput.c 
new/spice-vdagent-0.16.0/src/vdagentd-uinput.c
--- old/spice-vdagent-0.15.0/src/vdagentd-uinput.c      2013-10-14 
14:52:01.000000000 +0200
+++ new/spice-vdagent-0.16.0/src/vdagentd-uinput.c      2015-04-01 
10:57:23.000000000 +0200
@@ -76,6 +76,10 @@
 
     if (uinput->fd != -1)
         close(uinput->fd);
+
+    if (uinput->screen_info != NULL)
+        free(uinput->screen_info);
+
     free(uinput);
     *uinputp = NULL;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/spice-vdagent-0.15.0/src/vdagentd.c new/spice-vdagent-0.16.0/src/vdagentd.c
--- old/spice-vdagent-0.15.0/src/vdagentd.c     2013-10-14 14:52:01.000000000 
+0200
+++ new/spice-vdagent-0.16.0/src/vdagentd.c     2015-06-30 17:00:55.000000000 
+0200
@@ -59,6 +59,7 @@
 static const char *uinput_device = "/dev/uinput";
 static int debug = 0;
 static int uinput_fake = 0;
+static int only_once = 0;
 static struct udscs_server *server = NULL;
 static struct vdagent_virtio_port *virtio_port = NULL;
 static GHashTable *active_xfers = NULL;
@@ -74,6 +75,7 @@
 static int quit = 0;
 static int retval = 0;
 static int client_connected = 0;
+static int max_clipboard = -1;
 
 /* utility functions */
 /* vdagentd <-> spice-client communication handling */
@@ -98,6 +100,8 @@
     VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_CLIPBOARD_SELECTION);
     VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_SPARSE_MONITORS_CONFIG);
     VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_GUEST_LINEEND_LF);
+    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_MAX_CLIPBOARD);
+    VD_AGENT_SET_CAPABILITY(caps->caps, VD_AGENT_CAP_AUDIO_VOLUME_SYNC);
 
     vdagent_virtio_port_write(vport, VDP_CLIENT_PORT,
                               VD_AGENT_ANNOUNCE_CAPABILITIES, 0,
@@ -153,6 +157,19 @@
                               (uint8_t *)&reply, sizeof(reply));
 }
 
+static void do_client_volume_sync(struct vdagent_virtio_port *vport, int 
port_nr,
+    VDAgentMessage *message_header,
+    VDAgentAudioVolumeSync *avs)
+{
+    if (active_session_conn == NULL) {
+        syslog(LOG_DEBUG, "No active session - Can't volume-sync");
+        return;
+    }
+
+    udscs_write(active_session_conn, VDAGENTD_AUDIO_VOLUME_SYNC, 0, 0,
+                (uint8_t *)avs, message_header->size);
+}
+
 static void do_client_capabilities(struct vdagent_virtio_port *vport,
     VDAgentMessage *message_header,
     VDAgentAnnounceCapabilities *caps)
@@ -369,6 +386,20 @@
         vdagent_virtio_port_reset(vport, VDP_CLIENT_PORT);
         do_client_disconnect();
         break;
+    case VD_AGENT_MAX_CLIPBOARD:
+        if (message_header->size != sizeof(VDAgentMaxClipboard))
+            goto size_error;
+        VDAgentMaxClipboard *msg = (VDAgentMaxClipboard *)data;
+        syslog(LOG_DEBUG, "Set max clipboard: %d", msg->max);
+        max_clipboard = msg->max;
+        break;
+    case VD_AGENT_AUDIO_VOLUME_SYNC:
+        if (message_header->size < sizeof(VDAgentAudioVolumeSync))
+            goto size_error;
+
+        do_client_volume_sync(vport, port_nr, message_header,
+                (VDAgentAudioVolumeSync *)data);
+        break;
     default:
         syslog(LOG_WARNING, "unknown message type %d, ignoring",
                message_header->type);
@@ -382,6 +413,34 @@
     return 0;
 }
 
+static void virtio_write_clipboard(uint8_t selection, uint32_t msg_type,
+    uint32_t data_type, const uint8_t *data, uint32_t data_size)
+{
+    uint32_t size = data_size;
+
+    if (VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size,
+                                VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+        size += 4;
+    }
+    if (data_type != -1) {
+        size += 4;
+    }
+
+    vdagent_virtio_port_write_start(virtio_port, VDP_CLIENT_PORT, msg_type,
+                                    0, size);
+
+    if (VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size,
+                                VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
+        uint8_t sel[4] = { selection, 0, 0, 0 };
+        vdagent_virtio_port_write_append(virtio_port, sel, 4);
+    }
+    if (data_type != -1) {
+        vdagent_virtio_port_write_append(virtio_port, (uint8_t*)&data_type, 4);
+    }
+
+    vdagent_virtio_port_write_append(virtio_port, data, data_size);
+}
+
 /* vdagentd <-> vdagent communication handling */
 int do_agent_clipboard(struct udscs_connection *conn,
         struct udscs_message_header *header, const uint8_t *data)
@@ -425,12 +484,21 @@
     case VDAGENTD_CLIPBOARD_DATA:
         msg_type = VD_AGENT_CLIPBOARD;
         data_type = header->arg2;
+        if (max_clipboard != -1 && size > max_clipboard) {
+            syslog(LOG_WARNING, "clipboard is too large (%d > %d), discarding",
+                   size, max_clipboard);
+            virtio_write_clipboard(selection, msg_type, data_type, NULL, 0);
+            return 0;
+        }
         break;
     case VDAGENTD_CLIPBOARD_RELEASE:
         msg_type = VD_AGENT_CLIPBOARD_RELEASE;
         size = 0;
         agent_owns_clipboard[selection] = 0;
         break;
+    default:
+        syslog(LOG_WARNING, "unexpected clipboard message type");
+        goto error;
     }
 
     if (size != header->size) {
@@ -439,27 +507,7 @@
         return -1;
     }
 
-    if (VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size,
-                                VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
-        size += 4;
-    }
-    if (data_type != -1) {
-        size += 4;
-    }
-
-    vdagent_virtio_port_write_start(virtio_port, VDP_CLIENT_PORT, msg_type,
-                                    0, size);
-
-    if (VD_AGENT_HAS_CAPABILITY(capabilities, capabilities_size,
-                                VD_AGENT_CAP_CLIPBOARD_SELECTION)) {
-        uint8_t sel[4] = { selection, 0, 0, 0 };
-        vdagent_virtio_port_write_append(virtio_port, sel, 4);
-    }
-    if (data_type != -1) {
-        vdagent_virtio_port_write_append(virtio_port, (uint8_t*)&data_type, 4);
-    }
-
-    vdagent_virtio_port_write_append(virtio_port, data, header->size);
+    virtio_write_clipboard(selection, msg_type, data_type, data, header->size);
 
     return 0;
 
@@ -730,7 +778,9 @@
             "  -s <port>      set virtio serial port  [%s]\n"
             "  -S <filename>  set udcs socket [%s]\n"
             "  -u <dev>       set uinput device       [%s]\n"
+            "  -f             treat uinput device as fake; no ioctls\n"
             "  -x             don't daemonize\n"
+            "  -o             Only handle one virtio serial session.\n"
 #ifdef HAVE_CONSOLE_KIT
             "  -X             Disable console kit integration\n"
 #endif
@@ -771,6 +821,7 @@
     fd_set readfds, writefds;
     int n, nfds;
     int ck_fd = 0;
+    int once = 0;
 
     while (!quit) {
         FD_ZERO(&readfds);
@@ -800,6 +851,7 @@
         udscs_server_handle_fds(server, &readfds, &writefds);
 
         if (virtio_port) {
+            once = 1;
             vdagent_virtio_port_handle_fds(&virtio_port, &readfds, &writefds);
             if (!virtio_port) {
                 int old_client_connected = client_connected;
@@ -818,6 +870,11 @@
                 client_connected = old_client_connected;
             }
         }
+        else if (only_once && once)
+        {
+            syslog(LOG_INFO, "Exiting after one client session.");
+            break;
+        }
 
         if (session_info && FD_ISSET(ck_fd, &readfds)) {
             active_session = session_info_get_active_session(session_info);
@@ -839,7 +896,7 @@
     struct sigaction act;
 
     for (;;) {
-        if (-1 == (c = getopt(argc, argv, "-dhxXs:u:S:")))
+        if (-1 == (c = getopt(argc, argv, "-dhxXfos:u:S:")))
             break;
         switch (c) {
         case 'd':
@@ -854,6 +911,12 @@
         case 'u':
             uinput_device = optarg;
             break;
+        case 'f':
+            uinput_fake = 1;
+            break;
+        case 'o':
+            only_once = 1;
+            break;
         case 'x':
             do_daemonize = 0;
             break;
@@ -870,11 +933,6 @@
         }
     }
 
-    if (strncmp(uinput_device, "/dev", 4) != 0) {
-        syslog(LOG_INFO, "using fake uinput");
-        uinput_fake = 1;
-    }
-
     memset(&act, 0, sizeof(act));
     act.sa_flags = SA_RESTART;
     act.sa_handler = quit_handler;

++++++ spice-vdagent-var_run.patch ++++++
--- /var/tmp/diff_new_pack.fFMrlW/_old  2015-08-01 11:38:31.000000000 +0200
+++ /var/tmp/diff_new_pack.fFMrlW/_new  2015-08-01 11:38:31.000000000 +0200
@@ -5,23 +5,23 @@
  data/spice-vdagentd.service |    1 +
  4 files changed, 2 insertions(+), 2 deletions(-)
 
-Index: spice-vdagent-0.15.0/Makefile.am
+Index: spice-vdagent-0.16.0/Makefile.am
 ===================================================================
---- spice-vdagent-0.15.0.orig/Makefile.am
-+++ spice-vdagent-0.15.0/Makefile.am
-@@ -46,7 +46,6 @@ gdmautostartdir = $(datadir)/gdm/autosta
- gdmautostart_DATA = $(top_srcdir)/data/spice-vdagent.desktop
+--- spice-vdagent-0.16.0.orig/Makefile.am
++++ spice-vdagent-0.16.0/Makefile.am
+@@ -55,7 +55,6 @@ gdmautostart2dir = $(datadir)/gdm/autost
+ gdmautostart2_DATA = $(top_srcdir)/data/spice-vdagent.desktop
  
  install-data-local:
 -      $(mkdir_p) $(DESTDIR)$(localstatedir)/run/spice-vdagentd
  
- rsyslogdir = $(sysconfdir)/rsyslog.d
- rsyslog_DATA = $(top_srcdir)/data/rsyslog.d/spice-vdagentd.conf
-Index: spice-vdagent-0.15.0/Makefile.in
+ if INIT_SCRIPT_RED_HAT
+ initdir = $(sysconfdir)/rc.d/init.d
+Index: spice-vdagent-0.16.0/Makefile.in
 ===================================================================
---- spice-vdagent-0.15.0.orig/Makefile.in
-+++ spice-vdagent-0.15.0/Makefile.in
-@@ -1366,7 +1366,6 @@ uninstall-am: uninstall-binPROGRAMS unin
+--- spice-vdagent-0.16.0.orig/Makefile.in
++++ spice-vdagent-0.16.0/Makefile.in
+@@ -1413,7 +1413,6 @@ uninstall-am: uninstall-binPROGRAMS unin
  
  
  install-data-local:
@@ -29,10 +29,10 @@
  
  # Tell versions [3.59,3.63) of GNU make to not export all variables.
  # Otherwise a system limit (for SysV at least) may be exceeded.
-Index: spice-vdagent-0.15.0/data/spice-vdagentd
+Index: spice-vdagent-0.16.0/data/spice-vdagentd
 ===================================================================
---- spice-vdagent-0.15.0.orig/data/spice-vdagentd
-+++ spice-vdagent-0.15.0/data/spice-vdagentd
+--- spice-vdagent-0.16.0.orig/data/spice-vdagentd
++++ spice-vdagent-0.16.0/data/spice-vdagentd
 @@ -37,6 +37,7 @@ start() {
      [ -x $exec ] || exit 5
      [ -c $port ] || exit 0


Reply via email to