def query_opengl(self): self.opengl_props = {} try: import subprocess from xpra.platform.paths import get_xpra_command cmd = self.get_full_child_command(get_xpra_command() + ["opengl"]) env = self.get_child_env() proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, shell=False, close_fds=True) out, err = proc.communicate() gllog("out(xpra opengl)=%s", out) gllog("err(xpra opengl)=%s", err) if proc.returncode == 0: #parse output: for line in out.splitlines(): parts = line.split("=") if len(parts) != 2: continue k = parts[0].strip() v = parts[1].strip() self.opengl_props[k] = v else: self.opengl_props["error"] = str(err).strip("\n\r") except Exception as e: gllog.warn("Warning: failed to query OpenGL properties") gllog.warn(" %s", e) self.opengl_props["error"] = str(e) gllog("OpenGL: %s", self.opengl_props)
def query_opengl(self): self.opengl_props = {} blacklisted_kernel_modules = [] for mod in ("vboxguest", "vboxvideo"): if os.path.exists("/sys/module/%s" % mod): blacklisted_kernel_modules.append(mod) if blacklisted_kernel_modules: gllog.warn("Warning: skipped OpenGL probing,") gllog.warn(" found %i blacklisted kernel module%s:", len(blacklisted_kernel_modules), engs(blacklisted_kernel_modules)) gllog.warn(" %s", csv(blacklisted_kernel_modules)) self.opengl_props["error"] = "VirtualBox guest detected: %s" % csv( blacklisted_kernel_modules) else: try: import subprocess from xpra.platform.paths import get_xpra_command cmd = self.get_full_child_command(get_xpra_command() + ["opengl"]) env = self.get_child_env() proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, shell=False, close_fds=True) out, err = proc.communicate() gllog("out(%s)=%s", cmd, out) gllog("err(%s)=%s", cmd, err) if proc.returncode == 0: #parse output: for line in out.splitlines(): parts = line.split(b"=") if len(parts) != 2: continue k = bytestostr(parts[0].strip()) v = bytestostr(parts[1].strip()) self.opengl_props[k] = v log.info(" OpenGL is supported on this display") else: self.opengl_props["error-details"] = str(err).strip("\n\r") error = "unknown error" for x in str(err).splitlines(): if x.startswith("RuntimeError: "): error = x[len("RuntimeError: "):] break if x.startswith("ImportError: "): error = x[len("ImportError: "):] break self.opengl_props["error"] = error log.warn("Warning: OpenGL support check failed:") log.warn(" %s", error) except Exception as e: gllog("query_opengl()", exc_info=True) gllog.error("Error: OpenGL support check failed") gllog.error(" '%s'", e) self.opengl_props["error"] = str(e) gllog("OpenGL: %s", self.opengl_props)
def attach(self, key, uri): self.warning.set_text("") cmd = get_xpra_command() + ["attach", uri] env = os.environ.copy() env["XPRA_NOTTY"] = "1" proc = subprocess.Popen(cmd, env=env) log("attach() Popen(%s)=%s", cmd, proc) def proc_exit(*args): log("proc_exit%s", args) c = proc.poll() if key in self.clients_disconnecting: self.clients_disconnecting.remove(key) elif c not in (0, None): self.warning.set_text( EXIT_STR.get(c, "exit code %s" % c).replace("_", " ")) try: del self.clients[key] except KeyError: pass else: def update(): self.update() self.populate() glib.idle_add(update) self.child_reaper.add_process(proc, "client-%s" % uri, cmd, True, True, proc_exit) self.clients[key] = proc self.populate()
def run_command(self, *_args): self.hide() if xdg: if self.desktop_entry.getTryExec(): try: command = self.desktop_entry.findTryExec() except: command = self.desktop_entry.getTryExec() else: command = self.desktop_entry.getExec() else: command = self.entry.get_text() cmd = get_xpra_command() if self.seamless: cmd.append("start") else: cmd.append("start-desktop") ewc = self.exit_with_children_cb.get_active() cmd.append("--attach=%s" % self.attach_cb.get_active()) cmd.append("--exit-with-children=%s" % ewc) if ewc: cmd.append("--start-child=%s" % command) else: cmd.append("--start=%s" % command) exec_command(cmd)
def run_xpra(cls, command, env=None): xpra_cmd = get_xpra_command() if xpra_cmd == ["xpra"]: xpra_cmd = [cls.which("xpra")] cmd = ["python%i" % sys.version_info[0] ] + xpra_cmd + command + cls.default_xpra_args return cls.run_command(cmd, env)
def query_opengl(self): self.opengl_props = {} try: import subprocess from xpra.platform.paths import get_xpra_command cmd = self.get_full_child_command(get_xpra_command()+["opengl"]) env = self.get_child_env() proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, shell=False, close_fds=True) out,err = proc.communicate() gllog("out(xpra opengl)=%s", out) gllog("err(xpra opengl)=%s", err) if proc.returncode==0: #parse output: for line in out.splitlines(): parts = line.split("=") if len(parts)!=2: continue k = parts[0].strip() v = parts[1].strip() self.opengl_props[k] = v else: self.opengl_props["error"] = str(err).strip("\n\r") except Exception as e: gllog.warn("Warning: failed to query OpenGL properties") gllog.warn(" %s", e) self.opengl_props["error"] = str(e) gllog("OpenGL: %s", self.opengl_props)
def query_opengl(self): props = {} if self.opengl.lower() == "noprobe" or self.opengl.lower( ) in FALSE_OPTIONS: gllog("query_opengl() skipped because opengl=%s", self.opengl) return props try: from subprocess import Popen, PIPE from xpra.platform.paths import get_xpra_command cmd = self.get_full_child_command(get_xpra_command() + ["opengl", "--opengl=yes"]) env = self.get_child_env() #we want the output so we can parse it: env["XPRA_REDIRECT_OUTPUT"] = "0" proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, env=env) out, err = proc.communicate() gllog("out(%s)=%s", cmd, out) gllog("err(%s)=%s", cmd, err) if proc.returncode == 0: #parse output: for line in out.splitlines(): parts = line.split(b"=") if len(parts) != 2: continue k = bytestostr(parts[0].strip()) v = bytestostr(parts[1].strip()) props[k] = v gllog("opengl props=%s", props) if props: gllog.info("OpenGL is supported on display '%s'", self.display_name) renderer = props.get("renderer") if renderer: gllog.info(" using '%s' renderer", renderer) else: gllog.info("No OpenGL information available") else: props["error-details"] = str(err).strip("\n\r") error = "unknown error" for x in str(err).splitlines(): if x.startswith("RuntimeError: "): error = x[len("RuntimeError: "):] break if x.startswith("ImportError: "): error = x[len("ImportError: "):] break props["error"] = error log.warn("Warning: OpenGL support check failed:") log.warn(" %s", error) except Exception as e: gllog("query_opengl()", exc_info=True) gllog.error("Error: OpenGL support check failed") gllog.error(" '%s'", e) props["error"] = str(e) gllog("OpenGL: %s", props) return props
def dialog_confirm(title, prompt, qinfo="", icon="", buttons=[("OK", 1)]): cmd = get_xpra_command() + [ "_dialog", nonl(title), nonl(prompt), nonl("\\n".join(qinfo)), icon ] for label, code in buttons: cmd.append(nonl(label)) cmd.append(str(code)) return exec_dialog_subprocess(cmd)
def browse(self, *_args): subcommand = "mdns-gui" try: from xpra.net import mdns assert mdns except ImportError: subcommand = "sessions" cmd = get_xpra_command() + [subcommand] proc = exec_command(cmd) if proc.poll() is None: self.busy_cursor(self.browse_button)
def get_xpra_cmd(cls): xpra_cmd = get_xpra_command() if xpra_cmd == ["xpra"]: xpra_cmd = [bytestostr(cls.which("xpra"))] cmd = xpra_cmd + cls.default_xpra_args pyexename = "python%i" % sys.version_info[0] exe = bytestostr(xpra_cmd[0]).rstrip(".exe") if not (exe.endswith("python") or exe.endswith(pyexename)): #prepend python2 / python3: cmd = [pyexename] + xpra_cmd + cls.default_xpra_args return cmd
def _run_subcommand(self, args, wait=60, **kwargs): cmd = get_xpra_command() + shlex.split(args) if "stdout" not in kwargs: kwargs["stdout"] = DEVNULL if "stderr" not in kwargs: kwargs["stderr"] = DEVNULL try: proc = Popen(cmd, **kwargs) pollwait(proc, wait) return proc except Exception as e: raise Exception("failed on %s" % (cmd, )) from e
def get_run_command(self, attach=False): localhost = self.localhost_btn.get_active() if xdg and localhost: if self.desktop_entry.getTryExec(): try: command = self.desktop_entry.findTryExec() except Exception: command = self.desktop_entry.getTryExec() else: command = self.desktop_entry.getExec() else: command = self.entry.get_text() cmd = get_xpra_command() shadow = self.shadow_btn.get_active() seamless = self.seamless_btn.get_active() if seamless: cmd.append("start") elif shadow: cmd.append("shadow") else: cmd.append("start-desktop") ewc = self.exit_with_client_cb.get_active() cmd.append("--exit-with-client=%s" % ewc) if not shadow: ewc = self.exit_with_children_cb.get_active() cmd.append("--exit-with-children=%s" % ewc) if ewc: cmd.append("--start-child=%s" % command) else: cmd.append("--start=%s" % command) cmd.append("--attach=%s" % attach) localhost = self.localhost_btn.get_active() display = self.display_entry.get_text().lstrip(":") if localhost: uri = ":" + display if display else "" else: mode = self.mode_combo.get_active_text() uri = "%s://" % mode.lower() username = self.username_entry.get_text() if username: uri += "%s@" % username host = self.host_entry.get_text() if host: uri += host port = self.port_entry.get_text() if port != self.get_default_port(mode): uri += ":%s" % port uri += "/" if display: uri += display if uri: cmd.append(uri) return cmd
def get_xpra_cmd(cls): cmd = get_xpra_command() if cmd==["xpra"]: cmd = [bytestostr(cls.which("xpra"))] pyexename = "python3" exe = bytestostr(cmd[0]) if exe.endswith(".exe"): exe = exe[:-4] if not (exe.endswith("python") or exe.endswith(pyexename) or exe=="coverage"): #prepend python / python3: cmd = [pyexename] + cmd return cmd
def browse(self, *_args): subcommand = "sessions" try: from xpra.net.mdns import get_listener_class listener = get_listener_class() if listener: subcommand = "mdns-gui" except ImportError: pass cmd = get_xpra_command() + [subcommand] proc = exec_command(cmd) if proc.poll() is None: self.busy_cursor(self.browse_button)
def get_xpra_cmd(cls): xpra_cmd = get_xpra_command() if xpra_cmd == ["xpra"]: xpra_cmd = [cls.which("xpra")] cmd = xpra_cmd + cls.default_xpra_args pyexename = "python%i" % sys.version_info[0] exe = bytestostr(xpra_cmd[0]) if exe.endswith(pyexename): pass elif WIN32 and exe.endswith("%s.exe" % pyexename): pass else: cmd = [pyexename] + xpra_cmd + cls.default_xpra_args return cmd
def load_displays(self): log("load_displays()") while self.exit_code is None: time.sleep(1) if not self.shadow_btn.get_active( ) or not self.localhost_btn.get_active(): GLib.idle_add(self.no_display_combo) continue try: from subprocess import Popen, PIPE cmd = get_xpra_command() + ["displays"] proc = Popen(cmd, stdout=PIPE, stderr=PIPE) out = proc.communicate(None, 5)[0] except Exception: log("failed to query the list of displays", exc_info=True) else: new_display_list = [] if out: for line in out.decode().splitlines(): if line.lower().startswith( "#") or line.lower().startswith("found"): #empty or header line continue if line.lower().find("mode=") >= 0: #this is an xpra display, don't shadow it continue new_display_list.append(line.lstrip(" ").split(" ")[0]) def populate_display_combo(): changed = self.display_list != new_display_list self.display_list = new_display_list if not new_display_list: self.no_display_combo() return self.display_entry.hide() self.display_combo.show() if not changed: return current = self.display_combo.get_active_text() model = self.display_combo.get_model() if model: model.clear() selected = 0 for i, display in enumerate(new_display_list): self.display_combo.append_text(display) if display == current: selected = i self.display_combo.set_active(selected) GLib.idle_add(populate_display_combo)
def attach(self, uri): self.warning.set_text("") cmd = get_xpra_command() + ["attach", uri] proc = subprocess.Popen(cmd) log.info("attach() Popen(%s)=%s", cmd, proc) def proc_exit(*args): log("proc_exit%s", args) c = proc.poll() if c not in (0, None): self.warning.set_text( EXIT_STR.get(c, "exit code %s" % c).replace("_", " ")) self.child_reaper.add_process(proc, "client-%s" % uri, cmd, True, True, proc_exit)
def query_opengl(self): self.opengl_props = {} blacklisted_kernel_modules = [] for mod in ("vboxguest", "vboxvideo"): if os.path.exists("/sys/module/%s" % mod): blacklisted_kernel_modules.append(mod) if blacklisted_kernel_modules: gllog.warn("Warning: skipped OpenGL probing,") gllog.warn(" found %i blacklisted kernel module%s:", len(blacklisted_kernel_modules), engs(blacklisted_kernel_modules)) gllog.warn(" %s", csv(blacklisted_kernel_modules)) self.opengl_props["error"] = "VirtualBox guest detected: %s" % csv( blacklisted_kernel_modules) else: try: import subprocess from xpra.platform.paths import get_xpra_command cmd = self.get_full_child_command(get_xpra_command() + ["opengl"]) env = self.get_child_env() proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, shell=False, close_fds=True) out, err = proc.communicate() gllog("out(xpra opengl)=%s", out) gllog("err(xpra opengl)=%s", err) if proc.returncode == 0: #parse output: for line in out.splitlines(): parts = line.split(b"=") if len(parts) != 2: continue k = bytestostr(parts[0].strip()) v = bytestostr(parts[1].strip()) self.opengl_props[k] = v else: self.opengl_props["error"] = str(err).strip("\n\r") except Exception as e: gllog("query_opengl()", exc_info=True) gllog.warn("Warning: failed to query OpenGL properties") gllog.warn(" %s", e) self.opengl_props["error"] = str(e) gllog("OpenGL: %s", self.opengl_props)
def do_get_nodock_command(): #try to use the subapp: from xpra.platform.paths import get_app_dir base = get_app_dir() subapp = os.path.join(base, "Xpra_NoDock.app", "Contents") if os.path.exists(subapp) and os.path.isdir(subapp): base = subapp #appstore builds have script wrappers: helper = os.path.join(base, "Resources", "scripts", "Xpra") if not os.path.exists(helper): helper = os.path.join(base, "Helpers", "Xpra") if not os.path.exists(helper): #having a dock is still better than #trying to run a command that does not exist! from xpra.platform.paths import get_xpra_command return get_xpra_command() return [helper]
def exec_subcommand(self, subcommand, arg): log("exec_subcommand(%s, %s)", subcommand, arg) cmd = get_xpra_command() cmd.append(subcommand) cmd.append(arg) proc = exec_command(cmd) if proc.poll() is None: self.hide() def may_exit(): if proc.poll() is None: self.quit() else: self.show() #don't ask me why, #but on macos we can get file descriptor errors #if we exit immediately after we spawn the attach command GLib.timeout_add(2000, may_exit)
def show_launcher(self, *_args): cmd = get_xpra_command() + ["launcher"] proc = exec_command(cmd) if proc.poll() is None: self.busy_cursor(self.connect_button)
def start_shadow(self, *_args): cmd = get_xpra_command() + ["shadow"] proc = exec_command(cmd) if proc.poll() is None: self.busy_cursor(self.shadow_button)
def get_run_command(self, attach=False): localhost = self.localhost_btn.get_active() if xdg and localhost: if self.desktop_entry.getTryExec(): try: command = self.desktop_entry.findTryExec() except Exception: command = self.desktop_entry.getTryExec() else: command = self.desktop_entry.getExec() else: command = self.entry.get_text() cmd = get_xpra_command() + [self.get_run_mode()] ewc = self.exit_with_client_cb.get_active() cmd.append("--exit-with-client=%s" % ewc) shadow = self.shadow_btn.get_active() if not shadow: ewc = self.exit_with_children_cb.get_active() cmd.append("--exit-with-children=%s" % ewc) if ewc: cmd.append("--start-child=%s" % command) else: cmd.append("--start=%s" % command) cmd.append("--attach=%s" % attach) #process session_config if we have one: for k in ( "splash", "border", "headerbar", "notifications", "system-tray", "cursors", "bell", "modal-windows", "pixel-depth", "mousewheel", ): fn = k.replace("-", "_") if not hasattr(self.session_options, fn): continue value = getattr(self.session_options, fn) default_value = self.default_config.get(k) ot = OPTION_TYPES.get(k) if ot is bool: value = parse_bool(k, value) if value!=default_value: log.info("%s=%s (%s) - not %s (%s)", k, value, type(value), default_value, type(default_value)) cmd.append("--%s=%s" % (k, value)) localhost = self.localhost_btn.get_active() if self.display_entry.is_visible(): display = self.display_entry.get_text().lstrip(":") else: display = self.display_combo.get_active_text() if localhost: uri = ":"+display if display else "" else: mode = self.mode_combo.get_active_text() uri = "%s://" % mode.lower() username = self.username_entry.get_text() if username: uri += "%s@" % username host = self.host_entry.get_text() if host: uri += host port = self.port_entry.get_text() if port!=self.get_default_port(mode): uri += ":%s" % port uri += "/" if display: uri += display if uri: cmd.append(uri) return cmd
def do_get_sound_command(): from xpra.platform.paths import get_xpra_command return get_xpra_command()
def do_get_sound_command(): from xpra.platform.paths import get_xpra_command if SOUND_PYTHON3: return ["python3"] + get_xpra_command() return get_xpra_command()
def dialog_pass(title="Password Input", prompt="enter password", icon=""): cmd = get_xpra_command() + ["_pass", nonl(title), nonl(prompt), icon] return exec_dialog_subprocess(cmd)
def proxy_start(self, channel, subcommand, args): log("ssh proxy-start(%s, %s, %s)", channel, subcommand, args) server_mode = { "_proxy_start": "seamless", "_proxy_start_desktop": "desktop", "_proxy_shadow_start": "shadow", }.get(subcommand, subcommand.replace("_proxy", "")) log.info("ssh channel starting proxy %s session", server_mode) cmd = get_xpra_command() + [subcommand] + args try: proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, bufsize=0, close_fds=True) proc.poll() except OSError: log.error("Error starting proxy subcommand %s", subcommand, exc_info=True) log.error(" with args=%s", args) return from xpra.child_reaper import getChildReaper def proxy_ended(*args): log("proxy_ended(%s)", args) def close(): if proc.poll() is None: proc.terminate() getChildReaper().add_process(proc, "proxy-start-%s" % subcommand, cmd, True, True, proxy_ended) def proc_to_channel(read, send): while proc.poll() is None: #log("proc_to_channel(%s, %s) waiting for data", read, send) try: r = read(4096) except paramiko.buffered_pipe.PipeTimeout: log("proc_to_channel(%s, %s)", read, send, exc_info=True) close() break #log("proc_to_channel(%s, %s) %i bytes: %s", read, send, len(r or b""), ellipsizer(r)) if r: try: chan_send(send, r) except OSError: log("proc_to_channel(%s, %s)", read, send, exc_info=True) close() break #forward to/from the process and the channel: def stderr_reader(): proc_to_channel(proc.stderr.read, channel.send_stderr) def stdout_reader(): proc_to_channel(proc.stdout.read, channel.send) def stdin_reader(): stdin = proc.stdin while proc.poll() is None: r = channel.recv(4096) if not r: close() break #log("stdin_reader() %i bytes: %s", len(r or b""), ellipsizer(r)) stdin.write(r) stdin.flush() tname = subcommand.replace("_proxy_", "proxy-") start_thread(stderr_reader, "%s-stderr" % tname, True) start_thread(stdout_reader, "%s-stdout" % tname, True) start_thread(stdin_reader, "%s-stdin" % tname, True) channel.proxy_process = proc
--- xpra/platform/xposix/paths.py.orig 2019-09-24 13:54:00 UTC +++ xpra/platform/xposix/paths.py @@ -177,12 +177,12 @@ def do_get_default_log_dirs(): def do_get_sound_command(): from xpra.platform.paths import get_xpra_command if SOUND_PYTHON3: - return ["python3"]+get_xpra_command() + return ["python%i.%i" % (sys.version_info.major, sys.version_info.minor)]+get_xpra_command() return get_xpra_command() def do_get_xpra_command(): #try to use the same "xpra" executable that launched this server, #whilst also preserving the python interpreter version: if sys.argv and sys.argv[0].lower().endswith("/xpra"): - return ["python%i" % sys.version_info[0], sys.argv[0]] + return ["python%i.%i" % (sys.version_info.major, sys.version_info.minor), sys.argv[0]] return ["xpra"]
def do_get_sound_command(): from xpra.platform.paths import get_xpra_command if SOUND_PYTHON3: return ["python3"]+get_xpra_command() return get_xpra_command()
def browse(self, *_args): cmd = get_xpra_command() + ["sessions"] proc = exec_command(cmd) if proc.poll() is None: self.busy_cursor(self.browse_button)