diff --git a/src/setup.py b/src/setup.py index 1496d55658..eaef3961fb 100755 --- a/src/setup.py +++ b/src/setup.py @@ -344,6 +344,13 @@ def add_packages(*pkgs): add_modules(*pkgs) def add_modules(*mods): + def add(v): + global modules + if v not in modules: + modules.append(v) + do_add_modules(add, *mods) + +def do_add_modules(op, *mods): """ adds the packages and any .py module found in the packages to the "modules" list """ global modules @@ -358,8 +365,7 @@ def add_modules(*mods): #is this a file module? f = "%s.py" % pathname if os.path.exists(f) and os.path.isfile(f): - if x not in modules: - modules.append(x) + op(x) if os.path.exists(pathname) and os.path.isdir(pathname): #add all file modules found in this directory for f in os.listdir(pathname): @@ -369,7 +375,7 @@ def add_modules(*mods): fname = os.path.join(pathname, f) if os.path.isfile(fname): modname = "%s.%s" % (x, f.replace(".py", "")) - modules.append(modname) + op(modname) def toggle_packages(enabled, *module_names): if enabled: @@ -377,6 +383,17 @@ def toggle_packages(enabled, *module_names): else: remove_packages(*module_names) +def toggle_modules(enabled, *module_names): + if enabled: + def op(v): + global modules + if v not in modules: + modules.append(v) + do_add_modules(op, *module_names) + else: + remove_packages(*module_names) + + #always included: add_modules("xpra", "xpra.platform", "xpra.net") add_packages("xpra.scripts") @@ -1425,8 +1442,8 @@ def add_gui_exe(*args): #END OF py2exe SECTION #UI applications (detached from shell: no text output if ran from cmd.exe) - add_gui_exe("scripts/xpra", "xpra_txt.ico", "Xpra") if client_ENABLED and (gtk2_ENABLED or gtk3_ENABLED): + add_gui_exe("scripts/xpra", "xpra_txt.ico", "Xpra") add_gui_exe("scripts/xpra_launcher", "xpra.ico", "Xpra-Launcher") add_gui_exe("xpra/gtk_common/gtk_view_keyboard.py", "keyboard.ico", "GTK_Keyboard_Test") add_gui_exe("xpra/scripts/bug_report.py", "bugs.ico", "Bug_Report") @@ -1452,8 +1469,8 @@ def add_gui_exe(*args): add_console_exe("xpra/platform/win32/gui.py", "loop.ico", "Events_Test") if sound_ENABLED: add_console_exe("xpra/sound/gstreamer_util.py", "gstreamer.ico", "GStreamer_info") - add_console_exe("xpra/sound/src.py", "microphone.ico", "Sound_Record") - add_console_exe("xpra/sound/sink.py", "speaker.ico", "Sound_Play") + #add_console_exe("xpra/sound/src.py", "microphone.ico", "Sound_Record") + #add_console_exe("xpra/sound/sink.py", "speaker.ico", "Sound_Play") if opengl_ENABLED: add_console_exe("xpra/client/gl/gl_check.py", "opengl.ico", "OpenGL_check") if printing_ENABLED: @@ -1982,7 +1999,8 @@ def cython_add(*args, **kwargs): for x in ("gl_check", "gl_colorspace_conversions", "gl_window_backing_base", "gtk_compat"): toggle_packages(client_ENABLED and opengl_ENABLED, "xpra.client.gl.%s" % x) -toggle_packages(sound_ENABLED, "xpra.sound") +toggle_modules(sound_ENABLED, "xpra.sound") +toggle_modules(sound_ENABLED and not (OSX or WIN32), "xpra.sound.pulseaudio") toggle_packages(clipboard_ENABLED, "xpra.clipboard") if clipboard_ENABLED: diff --git a/src/xpra/client/ui_client_base.py b/src/xpra/client/ui_client_base.py index a366cdc467..42109df19a 100644 --- a/src/xpra/client/ui_client_base.py +++ b/src/xpra/client/ui_client_base.py @@ -386,11 +386,12 @@ def show_tray(*args): #audio tagging: if tray_icon_filename and os.path.exists(tray_icon_filename): try: - from xpra.sound.pulseaudio_util import set_icon_path + from xpra.sound.pulseaudio.pulseaudio_util import set_icon_path set_icon_path(tray_icon_filename) except ImportError as e: - log.warn("Warning: failed to set pulseaudio tagging icon:") - log.warn(" %s", e) + if os.name=="posix" and not sys.platform.startswith("darwin"): + log.warn("Warning: failed to set pulseaudio tagging icon:") + log.warn(" %s", e) if ClientExtras is not None: self.client_extras = ClientExtras(self, opts) @@ -1405,7 +1406,7 @@ def make_hello(self): sound_caps["send"] = self.microphone_allowed sound_caps["receive"] = self.speaker_allowed try: - from xpra.sound.pulseaudio_util import get_info as get_pa_info + from xpra.sound.pulseaudio.pulseaudio_util import get_info as get_pa_info sound_caps.update(get_pa_info()) except Exception: pass diff --git a/src/xpra/server/server_base.py b/src/xpra/server/server_base.py index 1005813624..350c433c37 100644 --- a/src/xpra/server/server_base.py +++ b/src/xpra/server/server_base.py @@ -458,12 +458,13 @@ def vinfo(k): self.supports_microphone = False if bool(self.sound_properties): try: - from xpra.sound.pulseaudio_util import set_icon_path, get_info as get_pa_info + from xpra.sound.pulseaudio.pulseaudio_util import set_icon_path, get_info as get_pa_info self.sound_properties.update(get_pa_info()) set_icon_path(get_icon_filename("xpra.png")) - except Exception as e: - log.warn("Warning: failed to set pulseaudio tagging icon:") - log.warn(" %s", e) + except ImportError as e: + if os.name=="posix" and not sys.platform.startswith("darwin"): + log.warn("Warning: failed to set pulseaudio tagging icon:") + log.warn(" %s", e) soundlog("init_sound_options speaker: supported=%s, encoders=%s", self.supports_speaker, csv(self.speaker_codecs)) soundlog("init_sound_options microphone: supported=%s, decoders=%s", self.supports_microphone, csv(self.microphone_codecs)) soundlog("init_sound_options sound properties=%s", self.sound_properties) diff --git a/src/xpra/sound/gstreamer_util.py b/src/xpra/sound/gstreamer_util.py index 4a7cc5bedc..b34a8d1fa0 100755 --- a/src/xpra/sound/gstreamer_util.py +++ b/src/xpra/sound/gstreamer_util.py @@ -463,12 +463,15 @@ def plugin_str(plugin, options): def get_source_plugins(): sources = [] - from xpra.sound.pulseaudio_util import has_pa - #we have to put pulsesrc first if pulseaudio is installed - #because using autoaudiosource does not work properly for us: - #it may still choose pulse, but without choosing the right device. - if has_pa(): - sources.append("pulsesrc") + try: + from xpra.sound.pulseaudio.pulseaudio_util import has_pa + #we have to put pulsesrc first if pulseaudio is installed + #because using autoaudiosource does not work properly for us: + #it may still choose pulse, but without choosing the right device. + if has_pa(): + sources.append("pulsesrc") + except ImportError as e: + log("get_source_plugins() no pulsesrc: %s", e) sources.append("autoaudiosrc") if OSX: sources.append("osxaudiosrc") @@ -487,10 +490,13 @@ def get_sink_plugins(): SINKS.append("osxaudiosink") elif sys.platform.startswith("win"): SINKS.append("directsoundsink") - from xpra.sound.pulseaudio_util import has_pa SINKS.append("autoaudiosink") - if has_pa(): - SINKS.append("pulsesink") + try: + from xpra.sound.pulseaudio.pulseaudio_util import has_pa + if has_pa(): + SINKS.append("pulsesink") + except ImportError as e: + log("get_sink_plugins() no pulsesink: %s", e) if os.name=="posix": SINKS += ["alsasink", "osssink", "oss4sink", "jackaudiosink"] return SINKS @@ -503,9 +509,12 @@ def get_default_sink(): log.error("invalid default sound sink: '%s' is not in %s", DEFAULT_SINK, csv(SINKS)) else: return DEFAULT_SINK - from xpra.sound.pulseaudio_util import has_pa - if has_pa(): - return "pulsesink" + try: + from xpra.sound.pulseaudio.pulseaudio_util import has_pa + if has_pa(): + return "pulsesink" + except ImportError as e: + log("get_default_sink() no pulsesink: %s", e) SINKS = get_sink_plugins() return SINKS[0] @@ -518,11 +527,16 @@ def get_pulse_defaults(remote): """ choose the device to use """ - from xpra.sound.pulseaudio_util import has_pa, get_pa_device_options, get_default_sink - from xpra.sound.pulseaudio_util import get_pulse_server, get_pulse_id, set_source_mute - if not has_pa(): - log.warn("pulseaudio is not available!") - return None + try: + from xpra.sound.pulseaudio.pulseaudio_util import has_pa, get_pa_device_options, get_default_sink + from xpra.sound.pulseaudio.pulseaudio_util import get_pulse_server, get_pulse_id, set_source_mute + if not has_pa(): + log.warn("Warning: pulseaudio is not available!") + return None + except ImportError as e: + log.warn("Warning: pulseaudio is not available!") + log.warn(" %s", e) + return None pa_server = get_pulse_server() log("start sound, remote pulseaudio server=%s, local pulseaudio server=%s", remote.pulseaudio_server, pa_server) #only worth comparing if we have a real server string diff --git a/src/xpra/sound/pulseaudio/__init__.py b/src/xpra/sound/pulseaudio/__init__.py new file mode 100644 index 0000000000..a3cd83d9e1 --- /dev/null +++ b/src/xpra/sound/pulseaudio/__init__.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python +# This file is part of Xpra. +# Copyright (C) 2010-2016 Antoine Martin +# Xpra is released under the terms of the GNU GPL v2, or, at your option, any +# later version. See the file COPYING for details. diff --git a/src/xpra/sound/pulseaudio_common_util.py b/src/xpra/sound/pulseaudio/pulseaudio_common_util.py similarity index 100% rename from src/xpra/sound/pulseaudio_common_util.py rename to src/xpra/sound/pulseaudio/pulseaudio_common_util.py diff --git a/src/xpra/sound/pulseaudio_none_util.py b/src/xpra/sound/pulseaudio/pulseaudio_none_util.py similarity index 100% rename from src/xpra/sound/pulseaudio_none_util.py rename to src/xpra/sound/pulseaudio/pulseaudio_none_util.py diff --git a/src/xpra/sound/pulseaudio_pactl_util.py b/src/xpra/sound/pulseaudio/pulseaudio_pactl_util.py similarity index 98% rename from src/xpra/sound/pulseaudio_pactl_util.py rename to src/xpra/sound/pulseaudio/pulseaudio_pactl_util.py index 57b6160167..3dd052e672 100755 --- a/src/xpra/sound/pulseaudio_pactl_util.py +++ b/src/xpra/sound/pulseaudio/pulseaudio_pactl_util.py @@ -7,7 +7,7 @@ import sys import os.path -from xpra.sound.pulseaudio_common_util import get_pulse_server_x11_property, get_pulse_id_x11_property +from xpra.sound.pulseaudio.pulseaudio_common_util import get_pulse_server_x11_property, get_pulse_id_x11_property from xpra.scripts.exec_util import safe_exec from xpra.util import nonl diff --git a/src/xpra/sound/pulseaudio_palib_util.py b/src/xpra/sound/pulseaudio/pulseaudio_palib_util.py similarity index 97% rename from src/xpra/sound/pulseaudio_palib_util.py rename to src/xpra/sound/pulseaudio/pulseaudio_palib_util.py index cafdc191b8..f7515f1201 100755 --- a/src/xpra/sound/pulseaudio_palib_util.py +++ b/src/xpra/sound/pulseaudio/pulseaudio_palib_util.py @@ -9,7 +9,7 @@ from xpra.log import Logger log = Logger("sound") #log.enable_debug() -from xpra.sound.pulseaudio_common_util import get_pulse_server_x11_property, get_pulse_id_x11_property +from xpra.sound.pulseaudio.pulseaudio_common_util import get_pulse_server_x11_property, get_pulse_id_x11_property import palib diff --git a/src/xpra/sound/pulseaudio_util.py b/src/xpra/sound/pulseaudio/pulseaudio_util.py similarity index 86% rename from src/xpra/sound/pulseaudio_util.py rename to src/xpra/sound/pulseaudio/pulseaudio_util.py index 4445ed46a2..54f2d4364f 100755 --- a/src/xpra/sound/pulseaudio_util.py +++ b/src/xpra/sound/pulseaudio/pulseaudio_util.py @@ -33,16 +33,16 @@ def add_audio_tagging_env(env_dict=os.environ, icon_path=None): try: #use "none" on win32 and osx: if sys.platform.startswith("win") or sys.platform.startswith("darwin"): - from xpra.sound import pulseaudio_none_util as _pulseaudio_util + from xpra.sound.pulseaudio import pulseaudio_none_util as _pulseaudio_util else: if os.environ.get("XPRA_USE_PALIB", "0")=="1": - from xpra.sound import pulseaudio_palib_util as _pulseaudio_util + from xpra.sound.pulseaudio import pulseaudio_palib_util as _pulseaudio_util else: - from xpra.sound import pulseaudio_pactl_util as _pulseaudio_util #@Reimport + from xpra.sound.pulseaudio import pulseaudio_pactl_util as _pulseaudio_util except ImportError as e: #fallback forks a process and parses the output: log("using pulseaudio none fallback") - from xpra.sound import pulseaudio_none_util as _pulseaudio_util + from xpra.sound.pulseaudio import pulseaudio_none_util as _pulseaudio_util get_info = _pulseaudio_util.get_info has_pa = _pulseaudio_util.has_pa diff --git a/src/xpra/sound/src.py b/src/xpra/sound/src.py index f32bc0dd10..63be2e830f 100755 --- a/src/xpra/sound/src.py +++ b/src/xpra/sound/src.py @@ -32,9 +32,14 @@ class SoundSource(SoundPipeline): def __init__(self, src_type=None, src_options={}, codecs=get_codecs(), codec_options={}, volume=1.0): if not src_type: - from xpra.sound.pulseaudio_util import get_pa_device_options - monitor_devices = get_pa_device_options(True, False) - log.info("found pulseaudio monitor devices: %s", monitor_devices) + try: + from xpra.sound.pulseaudio.pulseaudio_util import get_pa_device_options + monitor_devices = get_pa_device_options(True, False) + log.info("found pulseaudio monitor devices: %s", monitor_devices) + except ImportError as e: + log.warn("Warning: pulseaudio is not available!") + log.warn(" %s", e) + monitor_devices = [] if len(monitor_devices)==0: log.warn("could not detect any pulseaudio monitor devices") log.warn(" a test source will be used instead") @@ -273,7 +278,7 @@ def main(): try: from xpra.platform.paths import get_icon_filename f = get_icon_filename("xpra.png") - from xpra.sound.pulseaudio_util import add_audio_tagging_env + from xpra.sound.pulseaudio.pulseaudio_util import add_audio_tagging_env add_audio_tagging_env(icon_path=f) except Exception as e: log.warn("failed to setup pulseaudio tagging: %s", e) diff --git a/src/xpra/sound/wrapper.py b/src/xpra/sound/wrapper.py index a9d5019d73..03a6ea605a 100644 --- a/src/xpra/sound/wrapper.py +++ b/src/xpra/sound/wrapper.py @@ -208,12 +208,13 @@ def __init__(self, description): def get_env(self): env = subprocess_caller.get_env(self) - try: - from xpra.sound.pulseaudio_util import add_audio_tagging_env - add_audio_tagging_env(env) - except Exception as e: - log.warn("Warning: failed to set pulseaudio tagging:") - log.warn(" %s", e) + if os.name=="posix" and not sys.platform.startswith("darwin"): + try: + from xpra.sound.pulseaudio.pulseaudio_util import add_audio_tagging_env + add_audio_tagging_env(env) + except ImportError as e: + log.warn("Warning: failed to set pulseaudio tagging:") + log.warn(" %s", e) return env def start(self):