mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Merge branch 'master' of git://0pointer.de/pulseaudio
This commit is contained in:
		
						commit
						ed7642ebac
					
				
					 20 changed files with 255 additions and 75 deletions
				
			
		| 
						 | 
					@ -20,21 +20,6 @@ pulseconfdir=$(sysconfdir)/pulse
 | 
				
			||||||
CLEANFILES = \
 | 
					CLEANFILES = \
 | 
				
			||||||
	$(noinst_DATA)
 | 
						$(noinst_DATA)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
dist_man_MANS = \
 | 
					 | 
				
			||||||
	pulseaudio.1 \
 | 
					 | 
				
			||||||
	esdcompat.1 \
 | 
					 | 
				
			||||||
	pax11publish.1 \
 | 
					 | 
				
			||||||
	paplay.1 \
 | 
					 | 
				
			||||||
	pacat.1 \
 | 
					 | 
				
			||||||
	pacmd.1 \
 | 
					 | 
				
			||||||
	pactl.1 \
 | 
					 | 
				
			||||||
	pasuspender.1 \
 | 
					 | 
				
			||||||
	padsp.1 \
 | 
					 | 
				
			||||||
	pabrowse.1 \
 | 
					 | 
				
			||||||
	pulse-daemon.conf.5 \
 | 
					 | 
				
			||||||
	pulse-client.conf.5 \
 | 
					 | 
				
			||||||
	default.pa.5
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
noinst_DATA = \
 | 
					noinst_DATA = \
 | 
				
			||||||
	pulseaudio.1.xml \
 | 
						pulseaudio.1.xml \
 | 
				
			||||||
	esdcompat.1.xml \
 | 
						esdcompat.1.xml \
 | 
				
			||||||
| 
						 | 
					@ -50,24 +35,39 @@ noinst_DATA = \
 | 
				
			||||||
	pulse-client.conf.5.xml \
 | 
						pulse-client.conf.5.xml \
 | 
				
			||||||
	default.pa.5.xml
 | 
						default.pa.5.xml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if BUILD_MANPAGES
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CLEANFILES += \
 | 
					 | 
				
			||||||
	$(dist_man_MANS)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
%.xml: %.xml.in Makefile
 | 
					%.xml: %.xml.in Makefile
 | 
				
			||||||
	sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
 | 
						sed -e 's,@pulseconfdir\@,$(pulseconfdir),g' \
 | 
				
			||||||
	    -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
 | 
						    -e 's,@PACKAGE_BUGREPORT\@,$(PACKAGE_BUGREPORT),g' \
 | 
				
			||||||
            -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
 | 
					            -e 's,@PACKAGE_URL\@,$(PACKAGE_URL),g' $< > $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%: %.xml Makefile
 | 
					 | 
				
			||||||
	perl $(srcdir)/xmltoman $< > $@ || rm -f $@
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
xmllint: $(noinst_DATA)
 | 
					xmllint: $(noinst_DATA)
 | 
				
			||||||
	for f in $(noinst_DATA) ; do \
 | 
						for f in $(noinst_DATA) ; do \
 | 
				
			||||||
			xmllint --noout --valid "$$f" || exit 1 ; \
 | 
								xmllint --noout --valid "$$f" || exit 1 ; \
 | 
				
			||||||
	done
 | 
						done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if BUILD_MANPAGES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dist_man_MANS = \
 | 
				
			||||||
 | 
						pulseaudio.1 \
 | 
				
			||||||
 | 
						esdcompat.1 \
 | 
				
			||||||
 | 
						pax11publish.1 \
 | 
				
			||||||
 | 
						paplay.1 \
 | 
				
			||||||
 | 
						pacat.1 \
 | 
				
			||||||
 | 
						pacmd.1 \
 | 
				
			||||||
 | 
						pactl.1 \
 | 
				
			||||||
 | 
						pasuspender.1 \
 | 
				
			||||||
 | 
						padsp.1 \
 | 
				
			||||||
 | 
						pabrowse.1 \
 | 
				
			||||||
 | 
						pulse-daemon.conf.5 \
 | 
				
			||||||
 | 
						pulse-client.conf.5 \
 | 
				
			||||||
 | 
						default.pa.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CLEANFILES += \
 | 
				
			||||||
 | 
						$(dist_man_MANS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					%: %.xml Makefile
 | 
				
			||||||
 | 
						perl $(srcdir)/xmltoman $< > $@ || rm -f $@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXTRA_DIST = \
 | 
					EXTRA_DIST = \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -648,7 +648,6 @@ int main(int argc, char *argv[]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (conf->daemonize) {
 | 
					    if (conf->daemonize) {
 | 
				
			||||||
        pid_t child;
 | 
					        pid_t child;
 | 
				
			||||||
        int tty_fd;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (pa_stdio_acquire() < 0) {
 | 
					        if (pa_stdio_acquire() < 0) {
 | 
				
			||||||
            pa_log(_("Failed to acquire stdio."));
 | 
					            pa_log(_("Failed to acquire stdio."));
 | 
				
			||||||
| 
						 | 
					@ -781,6 +780,8 @@ int main(int argc, char *argv[]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
 | 
					    pa_log_debug(_("Running in valgrind mode: %s"), pa_yes_no(pa_in_valgrind()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_log_debug(_("Running in VM: %s"), pa_yes_no(pa_running_in_vm()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __OPTIMIZE__
 | 
					#ifdef __OPTIMIZE__
 | 
				
			||||||
    pa_log_debug(_("Optimized build: yes"));
 | 
					    pa_log_debug(_("Optimized build: yes"));
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -130,6 +130,7 @@ pa_cvolume_get_balance;
 | 
				
			||||||
pa_cvolume_get_fade;
 | 
					pa_cvolume_get_fade;
 | 
				
			||||||
pa_cvolume_get_position;
 | 
					pa_cvolume_get_position;
 | 
				
			||||||
pa_cvolume_inc;
 | 
					pa_cvolume_inc;
 | 
				
			||||||
 | 
					pa_cvolume_inc_clamp;
 | 
				
			||||||
pa_cvolume_init;
 | 
					pa_cvolume_init;
 | 
				
			||||||
pa_cvolume_max;
 | 
					pa_cvolume_max;
 | 
				
			||||||
pa_cvolume_max_mask;
 | 
					pa_cvolume_max_mask;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1712,7 +1712,9 @@ static int option_verify(pa_alsa_option *o) {
 | 
				
			||||||
        { "input-boost-on",            N_("Boost") },
 | 
					        { "input-boost-on",            N_("Boost") },
 | 
				
			||||||
        { "input-boost-off",           N_("No Boost") },
 | 
					        { "input-boost-off",           N_("No Boost") },
 | 
				
			||||||
        { "output-amplifier-on",       N_("Amplifier") },
 | 
					        { "output-amplifier-on",       N_("Amplifier") },
 | 
				
			||||||
        { "output-amplifier-off",      N_("No Amplifier") }
 | 
					        { "output-amplifier-off",      N_("No Amplifier") },
 | 
				
			||||||
 | 
					        { "output-speaker",            N_("Speaker") },
 | 
				
			||||||
 | 
					        { "output-headphones",         N_("Headphones") }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(o);
 | 
					    pa_assert(o);
 | 
				
			||||||
| 
						 | 
					@ -1770,15 +1772,17 @@ static int element_verify(pa_alsa_element *e) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int path_verify(pa_alsa_path *p) {
 | 
					static int path_verify(pa_alsa_path *p) {
 | 
				
			||||||
    static const struct description_map well_known_descriptions[] = {
 | 
					    static const struct description_map well_known_descriptions[] = {
 | 
				
			||||||
        { "analog-input",              N_("Analog Input") },
 | 
					        { "analog-input",               N_("Analog Input") },
 | 
				
			||||||
        { "analog-input-microphone",   N_("Analog Microphone") },
 | 
					        { "analog-input-microphone",    N_("Analog Microphone") },
 | 
				
			||||||
        { "analog-input-linein",       N_("Analog Line-In") },
 | 
					        { "analog-input-linein",        N_("Analog Line-In") },
 | 
				
			||||||
        { "analog-input-radio",        N_("Analog Radio") },
 | 
					        { "analog-input-radio",         N_("Analog Radio") },
 | 
				
			||||||
        { "analog-input-video",        N_("Analog Video") },
 | 
					        { "analog-input-video",         N_("Analog Video") },
 | 
				
			||||||
        { "analog-output",             N_("Analog Output") },
 | 
					        { "analog-output",              N_("Analog Output") },
 | 
				
			||||||
        { "analog-output-headphones",  N_("Analog Headphones") },
 | 
					        { "analog-output-headphones",   N_("Analog Headphones") },
 | 
				
			||||||
        { "analog-output-lfe-on-mono", N_("Analog Output (LFE)") },
 | 
					        { "analog-output-lfe-on-mono",  N_("Analog Output (LFE)") },
 | 
				
			||||||
        { "analog-output-mono",        N_("Analog Mono Output") }
 | 
					        { "analog-output-mono",         N_("Analog Mono Output") },
 | 
				
			||||||
 | 
					        { "analog-output-headphones-2", N_("Analog Headphones 2") },
 | 
				
			||||||
 | 
					        { "analog-output-speaker",      N_("Analog Speaker") }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_alsa_element *e;
 | 
					    pa_alsa_element *e;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1698,10 +1698,7 @@ pa_sink *pa_alsa_sink_new(pa_module *m, pa_modargs *ma, const char*driver, pa_ca
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (use_tsched && !pa_rtclock_hrtimer()) {
 | 
					    use_tsched = pa_alsa_may_tsched(use_tsched);
 | 
				
			||||||
        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
 | 
					 | 
				
			||||||
        use_tsched = FALSE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u = pa_xnew0(struct userdata, 1);
 | 
					    u = pa_xnew0(struct userdata, 1);
 | 
				
			||||||
    u->core = m->core;
 | 
					    u->core = m->core;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1541,10 +1541,7 @@ pa_source *pa_alsa_source_new(pa_module *m, pa_modargs *ma, const char*driver, p
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (use_tsched && !pa_rtclock_hrtimer()) {
 | 
					    use_tsched = pa_alsa_may_tsched(use_tsched);
 | 
				
			||||||
        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
 | 
					 | 
				
			||||||
        use_tsched = FALSE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    u = pa_xnew0(struct userdata, 1);
 | 
					    u = pa_xnew0(struct userdata, 1);
 | 
				
			||||||
    u->core = m->core;
 | 
					    u->core = m->core;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,6 +43,7 @@
 | 
				
			||||||
#include <pulsecore/once.h>
 | 
					#include <pulsecore/once.h>
 | 
				
			||||||
#include <pulsecore/thread.h>
 | 
					#include <pulsecore/thread.h>
 | 
				
			||||||
#include <pulsecore/conf-parser.h>
 | 
					#include <pulsecore/conf-parser.h>
 | 
				
			||||||
 | 
					#include <pulsecore/core-rtclock.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "alsa-util.h"
 | 
					#include "alsa-util.h"
 | 
				
			||||||
#include "alsa-mixer.h"
 | 
					#include "alsa-mixer.h"
 | 
				
			||||||
| 
						 | 
					@ -1308,3 +1309,26 @@ const char* pa_alsa_strerror(int errnum) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return translated;
 | 
					    return translated;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_bool_t pa_alsa_may_tsched(pa_bool_t want) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!want)
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!pa_rtclock_hrtimer()) {
 | 
				
			||||||
 | 
					        /* We cannot depend on being woken up in time when the timers
 | 
				
			||||||
 | 
					        are inaccurate, so let's fallback to classic IO based playback
 | 
				
			||||||
 | 
					        then. */
 | 
				
			||||||
 | 
					        pa_log_notice("Disabling timer-based scheduling because high-resolution timers are not available from the kernel.");
 | 
				
			||||||
 | 
					        return FALSE; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_running_in_vm()) {
 | 
				
			||||||
 | 
					        /* We cannot depend on being woken up when we ask for in a VM,
 | 
				
			||||||
 | 
					         * so let's fallback to classic IO based playback then. */
 | 
				
			||||||
 | 
					        pa_log_notice("Disabling timer-based scheduling because running inside a VM.");
 | 
				
			||||||
 | 
					        return FALSE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return TRUE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -142,4 +142,6 @@ pa_bool_t pa_alsa_pcm_is_modem(snd_pcm_t *pcm);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char* pa_alsa_strerror(int errnum);
 | 
					const char* pa_alsa_strerror(int errnum);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_bool_t pa_alsa_may_tsched(pa_bool_t want);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,3 +109,20 @@ priority = 10
 | 
				
			||||||
[Option External Amplifier:off]
 | 
					[Option External Amplifier:off]
 | 
				
			||||||
name = output-amplifier-off
 | 
					name = output-amplifier-off
 | 
				
			||||||
priority = 0
 | 
					priority = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					;;; 'Analog Output'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Element Analog Output]
 | 
				
			||||||
 | 
					enumeration = select
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Option Analog Output:Speakers]
 | 
				
			||||||
 | 
					name = output-speaker
 | 
				
			||||||
 | 
					priority = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Option Analog Output:Headphones]
 | 
				
			||||||
 | 
					name = output-headphones
 | 
				
			||||||
 | 
					priority = 9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Option Analog Output:FP Headphones]
 | 
				
			||||||
 | 
					name = output-headphones
 | 
				
			||||||
 | 
					priority = 8
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,7 +334,7 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
 | 
					    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsInput);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    channels = 0;
 | 
					    channels = 0;
 | 
				
			||||||
    for (p = ports; *p; p++)
 | 
					    for (p = ports; *p; p++)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -286,7 +286,7 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ports = jack_get_ports(u->client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
 | 
					    ports = jack_get_ports(u->client, NULL, JACK_DEFAULT_AUDIO_TYPE, JackPortIsPhysical|JackPortIsOutput);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    channels = 0;
 | 
					    channels = 0;
 | 
				
			||||||
    for (p = ports; *p; p++)
 | 
					    for (p = ports; *p; p++)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,12 +45,14 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 | 
				
			||||||
PA_MODULE_DESCRIPTION("LIRC volume control");
 | 
					PA_MODULE_DESCRIPTION("LIRC volume control");
 | 
				
			||||||
PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
					PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
				
			||||||
PA_MODULE_LOAD_ONCE(TRUE);
 | 
					PA_MODULE_LOAD_ONCE(TRUE);
 | 
				
			||||||
PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name>");
 | 
					PA_MODULE_USAGE("config=<config file> sink=<sink name> appname=<lirc application name> volume_limit=<volume limit> volume_step=<volume change step>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char* const valid_modargs[] = {
 | 
					static const char* const valid_modargs[] = {
 | 
				
			||||||
    "config",
 | 
					    "config",
 | 
				
			||||||
    "sink",
 | 
					    "sink",
 | 
				
			||||||
    "appname",
 | 
					    "appname",
 | 
				
			||||||
 | 
					    "volume_limit",
 | 
				
			||||||
 | 
					    "volume_step",
 | 
				
			||||||
    NULL,
 | 
					    NULL,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -61,10 +63,10 @@ struct userdata {
 | 
				
			||||||
    char *sink_name;
 | 
					    char *sink_name;
 | 
				
			||||||
    pa_module *module;
 | 
					    pa_module *module;
 | 
				
			||||||
    float mute_toggle_save;
 | 
					    float mute_toggle_save;
 | 
				
			||||||
 | 
					    pa_volume_t volume_limit;
 | 
				
			||||||
 | 
					    pa_volume_t volume_step;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DELTA (PA_VOLUME_NORM/20)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
 | 
					static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
 | 
				
			||||||
    struct userdata *u = userdata;
 | 
					    struct userdata *u = userdata;
 | 
				
			||||||
    char *name = NULL, *code = NULL;
 | 
					    char *name = NULL, *code = NULL;
 | 
				
			||||||
| 
						 | 
					@ -125,12 +127,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    switch (volchange) {
 | 
					                    switch (volchange) {
 | 
				
			||||||
                        case UP:
 | 
					                        case UP:
 | 
				
			||||||
                            pa_cvolume_inc(&cv, DELTA);
 | 
					                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
 | 
				
			||||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
					                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        case DOWN:
 | 
					                        case DOWN:
 | 
				
			||||||
                            pa_cvolume_dec(&cv, DELTA);
 | 
					                            pa_cvolume_dec(&cv, u->volume_step);
 | 
				
			||||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
					                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -170,6 +172,8 @@ fail:
 | 
				
			||||||
int pa__init(pa_module*m) {
 | 
					int pa__init(pa_module*m) {
 | 
				
			||||||
    pa_modargs *ma = NULL;
 | 
					    pa_modargs *ma = NULL;
 | 
				
			||||||
    struct userdata *u;
 | 
					    struct userdata *u;
 | 
				
			||||||
 | 
					    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
 | 
				
			||||||
 | 
					    pa_volume_t volume_step = PA_VOLUME_NORM/20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(m);
 | 
					    pa_assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,6 +182,16 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
 | 
				
			||||||
 | 
					        pa_log("Failed to parse volume limit");
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
 | 
				
			||||||
 | 
					        pa_log("Failed to parse volume step");
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
					    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
				
			||||||
    u->module = m;
 | 
					    u->module = m;
 | 
				
			||||||
    u->io = NULL;
 | 
					    u->io = NULL;
 | 
				
			||||||
| 
						 | 
					@ -185,6 +199,8 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
					    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
				
			||||||
    u->lirc_fd = -1;
 | 
					    u->lirc_fd = -1;
 | 
				
			||||||
    u->mute_toggle_save = 0;
 | 
					    u->mute_toggle_save = 0;
 | 
				
			||||||
 | 
					    u->volume_limit = volume_limit;
 | 
				
			||||||
 | 
					    u->volume_step = volume_step;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {
 | 
					    if ((u->lirc_fd = lirc_init((char*) pa_modargs_get_value(ma, "appname", "pulseaudio"), 1)) < 0) {
 | 
				
			||||||
        pa_log("lirc_init() failed.");
 | 
					        pa_log("lirc_init() failed.");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,13 +48,15 @@ PA_MODULE_AUTHOR("Lennart Poettering");
 | 
				
			||||||
PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev");
 | 
					PA_MODULE_DESCRIPTION("Multimedia keyboard support via Linux evdev");
 | 
				
			||||||
PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
					PA_MODULE_VERSION(PACKAGE_VERSION);
 | 
				
			||||||
PA_MODULE_LOAD_ONCE(FALSE);
 | 
					PA_MODULE_LOAD_ONCE(FALSE);
 | 
				
			||||||
PA_MODULE_USAGE("device=<evdev device> sink=<sink name>");
 | 
					PA_MODULE_USAGE("device=<evdev device> sink=<sink name> volume_limit=<volume limit> volume_step=<volume change step>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DEFAULT_DEVICE "/dev/input/event0"
 | 
					#define DEFAULT_DEVICE "/dev/input/event0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char* const valid_modargs[] = {
 | 
					static const char* const valid_modargs[] = {
 | 
				
			||||||
    "device",
 | 
					    "device",
 | 
				
			||||||
    "sink",
 | 
					    "sink",
 | 
				
			||||||
 | 
					    "volume_limit",
 | 
				
			||||||
 | 
					    "volume_step",
 | 
				
			||||||
    NULL,
 | 
					    NULL,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,10 +65,10 @@ struct userdata {
 | 
				
			||||||
    pa_io_event *io;
 | 
					    pa_io_event *io;
 | 
				
			||||||
    char *sink_name;
 | 
					    char *sink_name;
 | 
				
			||||||
    pa_module *module;
 | 
					    pa_module *module;
 | 
				
			||||||
 | 
					    pa_volume_t volume_limit;
 | 
				
			||||||
 | 
					    pa_volume_t volume_step;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DELTA (PA_VOLUME_NORM/20)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
 | 
					static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
 | 
				
			||||||
    struct userdata *u = userdata;
 | 
					    struct userdata *u = userdata;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -120,12 +122,12 @@ static void io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    switch (volchange) {
 | 
					                    switch (volchange) {
 | 
				
			||||||
                        case UP:
 | 
					                        case UP:
 | 
				
			||||||
                            pa_cvolume_inc(&cv, DELTA);
 | 
					                            pa_cvolume_inc_clamp(&cv, u->volume_step, u->volume_limit);
 | 
				
			||||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
					                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        case DOWN:
 | 
					                        case DOWN:
 | 
				
			||||||
                            pa_cvolume_dec(&cv, DELTA);
 | 
					                            pa_cvolume_dec(&cv, u->volume_step);
 | 
				
			||||||
                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
					                            pa_sink_set_volume(s, &cv, TRUE, TRUE);
 | 
				
			||||||
                            break;
 | 
					                            break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,6 +162,8 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
    struct input_id input_id;
 | 
					    struct input_id input_id;
 | 
				
			||||||
    char name[256];
 | 
					    char name[256];
 | 
				
			||||||
    uint8_t evtype_bitmask[EV_MAX/8 + 1];
 | 
					    uint8_t evtype_bitmask[EV_MAX/8 + 1];
 | 
				
			||||||
 | 
					    pa_volume_t volume_limit = PA_VOLUME_NORM*3/2;
 | 
				
			||||||
 | 
					    pa_volume_t volume_step = PA_VOLUME_NORM/20;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(m);
 | 
					    pa_assert(m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,12 +172,24 @@ int pa__init(pa_module*m) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_modargs_get_value_u32(ma, "volume_limit", &volume_limit) < 0) {
 | 
				
			||||||
 | 
					        pa_log("Failed to parse volume limit");
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_modargs_get_value_u32(ma, "volume_step", &volume_step) < 0) {
 | 
				
			||||||
 | 
					        pa_log("Failed to parse volume step");
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
					    m->userdata = u = pa_xnew(struct userdata, 1);
 | 
				
			||||||
    u->module = m;
 | 
					    u->module = m;
 | 
				
			||||||
    u->io = NULL;
 | 
					    u->io = NULL;
 | 
				
			||||||
    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
					    u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
 | 
				
			||||||
    u->fd = -1;
 | 
					    u->fd = -1;
 | 
				
			||||||
    u->fd_type = 0;
 | 
					    u->fd_type = 0;
 | 
				
			||||||
 | 
					    u->volume_limit = volume_limit;
 | 
				
			||||||
 | 
					    u->volume_step = volume_step;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {
 | 
					    if ((u->fd = pa_open_cloexec(pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), O_RDONLY, 0)) < 0) {
 | 
				
			||||||
        pa_log("Failed to open evdev device: %s", pa_cstrerror(errno));
 | 
					        pa_log("Failed to open evdev device: %s", pa_cstrerror(errno));
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,7 +39,7 @@ typedef struct pa_ext_device_manager_role_priority_info {
 | 
				
			||||||
} pa_ext_device_manager_role_priority_info;
 | 
					} pa_ext_device_manager_role_priority_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Stores information about one device in the device database that is
 | 
					/** Stores information about one device in the device database that is
 | 
				
			||||||
 * maintained by module-device-manager. \since 0.9.19 */
 | 
					 * maintained by module-device-manager. \since 0.9.20 */
 | 
				
			||||||
typedef struct pa_ext_device_manager_info {
 | 
					typedef struct pa_ext_device_manager_info {
 | 
				
			||||||
    const char *name;            /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */
 | 
					    const char *name;            /**< Identifier string of the device. A string like "sink:" or similar followed by the name of the device. */
 | 
				
			||||||
    const char *description;     /**< The description of the device when it was last seen, if applicable and saved */
 | 
					    const char *description;     /**< The description of the device when it was last seen, if applicable and saved */
 | 
				
			||||||
| 
						 | 
					@ -49,32 +49,32 @@ typedef struct pa_ext_device_manager_info {
 | 
				
			||||||
    pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */
 | 
					    pa_ext_device_manager_role_priority_info *role_priorities; /**< An array of role priority structures or NULL */
 | 
				
			||||||
} pa_ext_device_manager_info;
 | 
					} pa_ext_device_manager_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.19 */
 | 
					/** Callback prototype for pa_ext_device_manager_test(). \since 0.9.20 */
 | 
				
			||||||
typedef void (*pa_ext_device_manager_test_cb_t)(
 | 
					typedef void (*pa_ext_device_manager_test_cb_t)(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        uint32_t version,
 | 
					        uint32_t version,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Test if this extension module is available in the server. \since 0.9.19 */
 | 
					/** Test if this extension module is available in the server. \since 0.9.20 */
 | 
				
			||||||
pa_operation *pa_ext_device_manager_test(
 | 
					pa_operation *pa_ext_device_manager_test(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        pa_ext_device_manager_test_cb_t cb,
 | 
					        pa_ext_device_manager_test_cb_t cb,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.19 */
 | 
					/** Callback prototype for pa_ext_device_manager_read(). \since 0.9.20 */
 | 
				
			||||||
typedef void (*pa_ext_device_manager_read_cb_t)(
 | 
					typedef void (*pa_ext_device_manager_read_cb_t)(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        const pa_ext_device_manager_info *info,
 | 
					        const pa_ext_device_manager_info *info,
 | 
				
			||||||
        int eol,
 | 
					        int eol,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Read all entries from the device database. \since 0.9.19 */
 | 
					/** Read all entries from the device database. \since 0.9.20 */
 | 
				
			||||||
pa_operation *pa_ext_device_manager_read(
 | 
					pa_operation *pa_ext_device_manager_read(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        pa_ext_device_manager_read_cb_t cb,
 | 
					        pa_ext_device_manager_read_cb_t cb,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Sets the description for a device. \since 0.9.19 */
 | 
					/** Sets the description for a device. \since 0.9.20 */
 | 
				
			||||||
pa_operation *pa_ext_device_manager_set_device_description(
 | 
					pa_operation *pa_ext_device_manager_set_device_description(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        const char* device,
 | 
					        const char* device,
 | 
				
			||||||
| 
						 | 
					@ -82,21 +82,21 @@ pa_operation *pa_ext_device_manager_set_device_description(
 | 
				
			||||||
        pa_context_success_cb_t cb,
 | 
					        pa_context_success_cb_t cb,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Delete entries from the device database. \since 0.9.19 */
 | 
					/** Delete entries from the device database. \since 0.9.20 */
 | 
				
			||||||
pa_operation *pa_ext_device_manager_delete(
 | 
					pa_operation *pa_ext_device_manager_delete(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        const char *const s[],
 | 
					        const char *const s[],
 | 
				
			||||||
        pa_context_success_cb_t cb,
 | 
					        pa_context_success_cb_t cb,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Enable the role-based device-priority routing mode. \since 0.9.19 */
 | 
					/** Enable the role-based device-priority routing mode. \since 0.9.20 */
 | 
				
			||||||
pa_operation *pa_ext_device_manager_enable_role_device_priority_routing(
 | 
					pa_operation *pa_ext_device_manager_enable_role_device_priority_routing(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        int enable,
 | 
					        int enable,
 | 
				
			||||||
        pa_context_success_cb_t cb,
 | 
					        pa_context_success_cb_t cb,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Prefer a given device in the priority list. \since 0.9.19 */
 | 
					/** Prefer a given device in the priority list. \since 0.9.20 */
 | 
				
			||||||
pa_operation *pa_ext_device_manager_reorder_devices_for_role(
 | 
					pa_operation *pa_ext_device_manager_reorder_devices_for_role(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        const char* role,
 | 
					        const char* role,
 | 
				
			||||||
| 
						 | 
					@ -104,20 +104,20 @@ pa_operation *pa_ext_device_manager_reorder_devices_for_role(
 | 
				
			||||||
        pa_context_success_cb_t cb,
 | 
					        pa_context_success_cb_t cb,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Subscribe to changes in the device database. \since 0.9.19 */
 | 
					/** Subscribe to changes in the device database. \since 0.9.20 */
 | 
				
			||||||
pa_operation *pa_ext_device_manager_subscribe(
 | 
					pa_operation *pa_ext_device_manager_subscribe(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        int enable,
 | 
					        int enable,
 | 
				
			||||||
        pa_context_success_cb_t cb,
 | 
					        pa_context_success_cb_t cb,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.19 */
 | 
					/** Callback prototype for pa_ext_device_manager_set_subscribe_cb(). \since 0.9.20 */
 | 
				
			||||||
typedef void (*pa_ext_device_manager_subscribe_cb_t)(
 | 
					typedef void (*pa_ext_device_manager_subscribe_cb_t)(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        void *userdata);
 | 
					        void *userdata);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Set the subscription callback that is called when
 | 
					/** Set the subscription callback that is called when
 | 
				
			||||||
 * pa_ext_device_manager_subscribe() was called. \since 0.9.19 */
 | 
					 * pa_ext_device_manager_subscribe() was called. \since 0.9.20 */
 | 
				
			||||||
void pa_ext_device_manager_set_subscribe_cb(
 | 
					void pa_ext_device_manager_set_subscribe_cb(
 | 
				
			||||||
        pa_context *c,
 | 
					        pa_context *c,
 | 
				
			||||||
        pa_ext_device_manager_subscribe_cb_t cb,
 | 
					        pa_ext_device_manager_subscribe_cb_t cb,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -885,7 +885,7 @@ pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvo
 | 
				
			||||||
    return dest;
 | 
					    return dest;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {
 | 
					pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit) {
 | 
				
			||||||
    pa_volume_t m;
 | 
					    pa_volume_t m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pa_assert(v);
 | 
					    pa_assert(v);
 | 
				
			||||||
| 
						 | 
					@ -895,14 +895,18 @@ pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    m = pa_cvolume_max(v);
 | 
					    m = pa_cvolume_max(v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (m >= PA_VOLUME_MAX - inc)
 | 
					    if (m >= limit - inc)
 | 
				
			||||||
        m = PA_VOLUME_MAX;
 | 
					        m = limit;
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        m += inc;
 | 
					        m += inc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return pa_cvolume_scale(v, m);
 | 
					    return pa_cvolume_scale(v, m);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc){
 | 
				
			||||||
 | 
					    return pa_cvolume_inc_clamp(v, inc, PA_VOLUME_MAX);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
 | 
					pa_cvolume* pa_cvolume_dec(pa_cvolume *v, pa_volume_t dec) {
 | 
				
			||||||
    pa_volume_t m;
 | 
					    pa_volume_t m;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -348,6 +348,10 @@ pa_volume_t pa_cvolume_get_position(pa_cvolume *cv, const pa_channel_map *map, p
 | 
				
			||||||
 * and dest may point to the same structure. \since 0.9.16 */
 | 
					 * and dest may point to the same structure. \since 0.9.16 */
 | 
				
			||||||
pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
 | 
					pa_cvolume* pa_cvolume_merge(pa_cvolume *dest, const pa_cvolume *a, const pa_cvolume *b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Increase the volume passed in by 'inc', but not exceeding 'limit'.
 | 
				
			||||||
 | 
					 * The proportions between the channels are kept. \since 0.9.19 */
 | 
				
			||||||
 | 
					pa_cvolume* pa_cvolume_inc_clamp(pa_cvolume *v, pa_volume_t inc, pa_volume_t limit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Increase the volume passed in by 'inc'. The proportions between
 | 
					/** Increase the volume passed in by 'inc'. The proportions between
 | 
				
			||||||
 * the channels are kept. \since 0.9.16 */
 | 
					 * the channels are kept. \since 0.9.16 */
 | 
				
			||||||
pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
 | 
					pa_cvolume* pa_cvolume_inc(pa_cvolume *v, pa_volume_t inc);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,6 +117,7 @@
 | 
				
			||||||
#include <pulsecore/strbuf.h>
 | 
					#include <pulsecore/strbuf.h>
 | 
				
			||||||
#include <pulsecore/usergroup.h>
 | 
					#include <pulsecore/usergroup.h>
 | 
				
			||||||
#include <pulsecore/strlist.h>
 | 
					#include <pulsecore/strlist.h>
 | 
				
			||||||
 | 
					#include <pulsecore/cpu-x86.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core-util.h"
 | 
					#include "core-util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2944,6 +2945,7 @@ int pa_pipe_cloexec(int pipefd[2]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (errno != EINVAL && errno != ENOSYS)
 | 
					    if (errno != EINVAL && errno != ENOSYS)
 | 
				
			||||||
        return r;
 | 
					        return r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((r = pipe(pipefd)) < 0)
 | 
					    if ((r = pipe(pipefd)) < 0)
 | 
				
			||||||
| 
						 | 
					@ -2965,6 +2967,7 @@ int pa_accept_cloexec(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (errno != EINVAL && errno != ENOSYS)
 | 
					    if (errno != EINVAL && errno != ENOSYS)
 | 
				
			||||||
        return fd;
 | 
					        return fd;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((fd = accept(sockfd, addr, addrlen)) < 0)
 | 
					    if ((fd = accept(sockfd, addr, addrlen)) < 0)
 | 
				
			||||||
| 
						 | 
					@ -3015,3 +3018,93 @@ void pa_nullify_stdfds(void) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *pa_read_line_from_file(const char *fn) {
 | 
				
			||||||
 | 
					    FILE *f;
 | 
				
			||||||
 | 
					    char ln[256] = "", *r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!(f = pa_fopen_cloexec(fn, "r")))
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    r = fgets(ln, sizeof(ln)-1, f);
 | 
				
			||||||
 | 
					    fclose(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!r) {
 | 
				
			||||||
 | 
					        errno = EIO;
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pa_strip_nl(ln);
 | 
				
			||||||
 | 
					    return pa_xstrdup(ln);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pa_bool_t pa_running_in_vm(void) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(__i386__) || defined(__x86_64__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Both CPUID and DMI are x86 specific interfaces... */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t eax = 0x40000000;
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint32_t sig32[3];
 | 
				
			||||||
 | 
					        char text[13];
 | 
				
			||||||
 | 
					    } sig;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
					    const char *const dmi_vendors[] = {
 | 
				
			||||||
 | 
					        "/sys/class/dmi/id/sys_vendor",
 | 
				
			||||||
 | 
					        "/sys/class/dmi/id/board_vendor",
 | 
				
			||||||
 | 
					        "/sys/class/dmi/id/bios_vendor"
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsigned i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < PA_ELEMENTSOF(dmi_vendors); i++) {
 | 
				
			||||||
 | 
					        char *s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((s = pa_read_line_from_file(dmi_vendors[i]))) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (pa_startswith(s, "QEMU") ||
 | 
				
			||||||
 | 
					                /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
 | 
				
			||||||
 | 
					                pa_startswith(s, "VMware") ||
 | 
				
			||||||
 | 
					                pa_startswith(s, "VMW") ||
 | 
				
			||||||
 | 
					                pa_startswith(s, "Microsoft Corporation") ||
 | 
				
			||||||
 | 
					                pa_startswith(s, "innotek GmbH") ||
 | 
				
			||||||
 | 
					                pa_startswith(s, "Xen")) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                pa_xfree(s);
 | 
				
			||||||
 | 
					                return TRUE;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            pa_xfree(s);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* http://lwn.net/Articles/301888/ */
 | 
				
			||||||
 | 
					    pa_zero(sig);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __asm__ __volatile__ (
 | 
				
			||||||
 | 
					        /* ebx/rbx is being used for PIC! */
 | 
				
			||||||
 | 
					        "  push %%"PA_REG_b"         \n\t"
 | 
				
			||||||
 | 
					        "  cpuid                     \n\t"
 | 
				
			||||||
 | 
					        "  mov %%ebx, %1             \n\t"
 | 
				
			||||||
 | 
					        "  pop %%"PA_REG_b"          \n\t"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        : "=a" (eax), "=r" (sig.sig32[0]), "=c" (sig.sig32[1]), "=d" (sig.sig32[2])
 | 
				
			||||||
 | 
					        : "0" (eax)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (pa_streq(sig.text, "XenVMMXenVMM") ||
 | 
				
			||||||
 | 
					        pa_streq(sig.text, "KVMKVMKVM") ||
 | 
				
			||||||
 | 
					        /* http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1009458 */
 | 
				
			||||||
 | 
					        pa_streq(sig.text, "VMwareVMware") ||
 | 
				
			||||||
 | 
					        /* http://msdn.microsoft.com/en-us/library/bb969719.aspx */
 | 
				
			||||||
 | 
					        pa_streq(sig.text, "Microsoft Hv"))
 | 
				
			||||||
 | 
					        return TRUE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return FALSE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -267,4 +267,7 @@ FILE* pa_fopen_cloexec(const char *path, const char *mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void pa_nullify_stdfds(void);
 | 
					void pa_nullify_stdfds(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char *pa_read_line_from_file(const char *fn);
 | 
				
			||||||
 | 
					pa_bool_t pa_running_in_vm(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2631,7 +2631,7 @@ static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint3
 | 
				
			||||||
    pa_tagstruct_put_usec(reply, s->current_monitor_latency);
 | 
					    pa_tagstruct_put_usec(reply, s->current_monitor_latency);
 | 
				
			||||||
    pa_tagstruct_put_usec(reply,
 | 
					    pa_tagstruct_put_usec(reply,
 | 
				
			||||||
                          s->current_source_latency +
 | 
					                          s->current_source_latency +
 | 
				
			||||||
                          pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->sample_spec));
 | 
					                          pa_bytes_to_usec(s->on_the_fly_snapshot, &s->source_output->source->sample_spec));
 | 
				
			||||||
    pa_tagstruct_put_boolean(reply,
 | 
					    pa_tagstruct_put_boolean(reply,
 | 
				
			||||||
                             pa_source_get_state(s->source_output->source) == PA_SOURCE_RUNNING &&
 | 
					                             pa_source_get_state(s->source_output->source) == PA_SOURCE_RUNNING &&
 | 
				
			||||||
                             pa_source_output_get_state(s->source_output) == PA_SOURCE_OUTPUT_RUNNING);
 | 
					                             pa_source_output_get_state(s->source_output) == PA_SOURCE_OUTPUT_RUNNING);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -717,14 +717,15 @@ void pa_sink_input_peek(pa_sink_input *i, size_t slength /* in sink frames */, p
 | 
				
			||||||
                pa_memchunk rchunk;
 | 
					                pa_memchunk rchunk;
 | 
				
			||||||
                pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
 | 
					                pa_resampler_run(i->thread_info.resampler, &wchunk, &rchunk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (nvfs) {
 | 
					 | 
				
			||||||
                    pa_memchunk_make_writable(&rchunk, 0);
 | 
					 | 
				
			||||||
                    pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
 | 
					/*                 pa_log_debug("pushing %lu", (unsigned long) rchunk.length); */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (rchunk.memblock) {
 | 
					                if (rchunk.memblock) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (nvfs) {
 | 
				
			||||||
 | 
					                        pa_memchunk_make_writable(&rchunk, 0);
 | 
				
			||||||
 | 
					                        pa_volume_memchunk(&rchunk, &i->sink->sample_spec, &i->volume_factor_sink);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
 | 
					                    pa_memblockq_push_align(i->thread_info.render_memblockq, &rchunk);
 | 
				
			||||||
                    pa_memblock_unref(rchunk.memblock);
 | 
					                    pa_memblock_unref(rchunk.memblock);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue