def sound_option_or_all(name, options, all_values): all_values = legacy_to_new(all_values) if not options: v = all_values #not specified on command line: use default else: v = [] invalid_options = [] for x in options: #options is a list, but it may have csv embedded: for o in x.split(","): o = o.strip() o = NEW_CODEC_NAMES.get(o, o) if o not in all_values: invalid_options.append(o) else: v.append(o) if len(invalid_options) > 0: if all_values: log.warn("Warning: invalid value%s for %s: %s", engs(invalid_options), name, csv(invalid_options)) log.warn(" valid option%s: %s", engs(all_values), csv(all_values)) else: log.warn("Warning: no %ss available", name) log("%s=%s", name, csv(v)) return v
def sound_option_or_all(name, options, all_values): log("sound_option_or_all%s", (name, options, all_values)) if not options: v = all_values #not specified on command line: use default else: v = [] invalid_options = [] for x in options: #options is a list, but it may have csv embedded: for o in x.split(","): o = o.strip() if o not in all_values: invalid_options.append(o) else: v.append(o) if invalid_options: if all_values: log.warn("Warning: invalid value%s for '%s': %s", engs(invalid_options), name, csv(invalid_options)) log.warn(" valid option%s: %s", engs(all_values), csv(all_values)) else: log.warn("Warning: no '%ss' available", name) log("%s=%s", name, csv(v)) return v
def get_directsound_source_defaults(device_name_match=None, want_monitor_device=True, remote=None): try: from win32com.directsound import directsound except ImportError as e: log.warn("Warning: failed to import directsound") log.warn(" %s", e) return {} try: if not want_monitor_device: devices = directsound.DirectSoundEnumerate() log("DirectSoundEnumerate found %i device%s", len(devices), engs(devices)) else: devices = directsound.DirectSoundCaptureEnumerate() log("DirectSoundCaptureEnumerate found %i device%s", len(devices), engs(devices)) names = [] if devices: for guid, name, mod in devices: if mod or guid: log("* %-32s %s : %s", name, mod, guid) else: log("* %s", name) names.append(name) device_name = None if device_name_match: for name in names: if name.lower().find(device_name_match) >= 0: device_name = name break if device_name is None: for name in names: if name.lower().find("primary") >= 0: device_name = name break log("best matching %sdevice: %s", ["", "capture "][want_monitor_device], device_name) if device_name is None and want_monitor_device: #we have to choose one because the default device #may not be a capture device? device_name = names[0] if device_name: log.info("using directsound %sdevice:", ["", "capture "][want_monitor_device]) log.info(" '%s'", device_name) return { "device-name": device_name, } except Exception as e: log.error("Error quering sound devices using %s:", directsound) log.error(" %s", e) return {}
def get_directsound_source_defaults(device_name_match=None, want_monitor_device=True, remote=None): try: from xpra.platform.win32.directsound import get_devices, get_capture_devices if not want_monitor_device: devices = get_devices() log("DirectSoundEnumerate found %i device%s", len(devices), engs(devices)) else: devices = get_capture_devices() log("DirectSoundCaptureEnumerate found %i device%s", len(devices), engs(devices)) names = [] if devices: for guid, name in devices: if guid: log("* %-32s %s : %s", name, guid) else: log("* %s", name) names.append(name) device_name = None if device_name_match: for name in names: if name.lower().find(device_name_match) >= 0: device_name = name break if device_name is None: for name in names: if name.lower().find("primary") >= 0: device_name = name break log("best matching %sdevice: %s", ["", "capture "][want_monitor_device], device_name) if device_name is None and want_monitor_device: #we have to choose one because the default device #may not be a capture device? device_name = names[0] if device_name: log.info("using directsound %sdevice:", ["", "capture "][want_monitor_device]) log.info(" '%s'", device_name) return { "device-name": device_name, } except Exception as e: log("get_directsound_source_defaults%s", (device_name_match, want_monitor_device, remote), exc_info=True) log.error("Error quering sound devices:") log.error(" %s", e) return {}
def log_platforms_info(): log("found %s OpenCL platform%s:", len(opencl_platforms), engs(opencl_platforms)) for platform in opencl_platforms: devices = platform.get_devices() p = "*" if not is_supported(platform.name): p = "-" log("%s %s - %s device%s:", p, platform_info(platform), len(devices), engs(devices)) for d in devices: p = "-" if d.available and d.compiler_available and d.get_info(pyopencl.device_info.IMAGE_SUPPORT) and is_supported(platform.name): p = "+" log(" %s %s: %s", p, device_type(d), device_info(d))
def get_directsound_source_defaults(device_name_match=None, want_monitor_device=True, remote=None): try: from win32com.directsound import directsound except ImportError as e: log.warn("Warning: failed to import directsound") log.warn(" %s", e) return {} try: if not want_monitor_device: devices = directsound.DirectSoundEnumerate() log("DirectSoundEnumerate found %i device%s", len(devices), engs(devices)) else: devices = directsound.DirectSoundCaptureEnumerate() log("DirectSoundCaptureEnumerate found %i device%s", len(devices), engs(devices)) names = [] if devices: for guid, name, mod in devices: if mod or guid: log("* %-32s %s : %s", name, mod, guid) else: log("* %s", name) names.append(name) device_name = None if device_name_match: for name in names: if name.lower().find(device_name_match)>=0: device_name = name break if device_name is None: for name in names: if name.lower().find("primary")>=0: device_name = name break log("best matching %sdevice: %s", ["","capture "][want_monitor_device], device_name) if device_name is None and want_monitor_device: #we have to choose one because the default device #may not be a capture device? device_name = names[0] if device_name: log.info("using directsound %sdevice:", ["","capture "][want_monitor_device]) log.info(" '%s'", device_name) return { "device-name" : device_name, } except Exception as e: log.error("Error quering sound devices using %s:", directsound) log.error(" %s", e) return {}
def _process_desktop_size(self, proto, packet): width, height = packet[1:3] ss = self._server_sources.get(proto) if ss is None: return ss.desktop_size = (width, height) if len(packet) >= 10: #added in 0.16 for scaled client displays: xdpi, ydpi = packet[8:10] if xdpi != self.xdpi or ydpi != self.ydpi: self.xdpi, self.ydpi = xdpi, ydpi log("new dpi: %ix%i", self.xdpi, self.ydpi) self.dpi = iround((self.xdpi + self.ydpi) / 2.0) self.dpi_changed() if len(packet) >= 8: #added in 0.16 for scaled client displays: ss.desktop_size_unscaled = packet[6:8] if len(packet) >= 6: desktops, desktop_names = packet[4:6] ss.set_desktops(desktops, desktop_names) self.calculate_desktops() if len(packet) >= 4: ss.set_screen_sizes(packet[3]) log("client requesting new size: %sx%s", width, height) self.set_screen_size(width, height) if len(packet) >= 4: log.info("received updated display dimensions") log.info("client display size is %sx%s with %s screen%s:", width, height, len(ss.screen_sizes), engs(ss.screen_sizes)) log_screen_sizes(width, height, ss.screen_sizes) self.calculate_workarea(width, height) #ensures that DPI and antialias information gets reset: self.update_all_server_settings()
def get_client_backlog(self): packets_backlog, pixels_backlog, bytes_backlog = 0, 0, 0 if len(self.damage_ack_pending) > 0: sent_before = monotonic_time() - (self.target_latency + TARGET_LATENCY_TOLERANCE) dropped_acks_time = monotonic_time() - 60 #1 minute drop_missing_acks = [] for sequence, (start_send_at, _, start_bytes, end_send_at, end_bytes, pixels, _) in self.damage_ack_pending.items(): if end_send_at == 0 or start_send_at > sent_before: continue if start_send_at < dropped_acks_time: drop_missing_acks.append(sequence) else: packets_backlog += 1 pixels_backlog += pixels bytes_backlog += (end_bytes - start_bytes) log("get_client_backlog missing acks: %s", drop_missing_acks) #this should never happen... if len(drop_missing_acks) > 0: log.error("Error: expiring %i missing damage ACK%s,", len(drop_missing_acks), engs(drop_missing_acks)) log.error(" connection may be closed or closing,") log.error(" sequence numbers missing: %s", csv(drop_missing_acks)) for sequence in drop_missing_acks: try: del self.damage_ack_pending[sequence] except: pass return packets_backlog, pixels_backlog, bytes_backlog
def get_virtual_video_devices(): log("get_virtual_video_devices") v4l2_virtual_dir = "/sys/devices/virtual/video4linux" if not os.path.exists(v4l2_virtual_dir) or not os.path.isdir(v4l2_virtual_dir): log.warn("Warning: webcam forwarding is disabled") log.warn(" the virtual video directory '%s' was not found", v4l2_virtual_dir) log.warn(" make sure that the 'v4l2loopback' kernel module is installed and loaded") return [] contents = os.listdir(v4l2_virtual_dir) devices = {} for f in contents: if not f.startswith("video"): continue try: no = int(f[len("video"):]) assert no>=0 except: continue dev_dir = os.path.join(v4l2_virtual_dir, f) if not os.path.isdir(dev_dir): continue dev_name = os.path.join(dev_dir, "name") try: name = open(dev_name).read().replace("\n", "") log("found %s: %s", f, name) except: continue dev_file = "/dev/%s" % f devices[no] = dev_file log("devices: %s", devices) log("found %i virtual video device%s", len(devices), engs(devices)) return devices
def send_data_request(self, action, dtype, url, mimetype="", data="", filesize=0, printit=False, openit=True, options={}): send_id = uuid.uuid4().hex if len(self.pending_send_data) >= MAX_CONCURRENT_FILES: filelog.warn("Warning: %s dropped", action) filelog.warn(" %i transfer%s already waiting for a response", len(self.pending_send_data), engs(self.pending_send_data)) return None self.pending_send_data[send_id] = (dtype, url, mimetype, data, filesize, printit, openit, options) self.pending_send_data_timers[send_id] = self.timeout_add( self.remote_file_ask_timeout * 1000, self.send_data_ask_timeout, send_id) filelog("sending data request for %s '%s' with send-id=%s", bytestostr(dtype), url, send_id) self.send("send-data-request", dtype, send_id, url, mimetype, filesize, printit, openit) return send_id
def get_virtual_video_devices(capture_only=True): log("get_virtual_video_devices(%s) CHECK_VIRTUAL_CAPTURE=%s", capture_only, CHECK_VIRTUAL_CAPTURE) if not check_virtual_dir(False): return {} contents = os.listdir(v4l2_virtual_dir) devices = {} for f in contents: if not f.startswith("video"): continue try: no = int(f[len("video"):]) assert no>=0 except: continue dev_file = "/dev/%s" % f dev_info = query_video_device(dev_file) if CHECK_VIRTUAL_CAPTURE and capture_only and not _can_capture_video(dev_file, dev_info): continue info = {"device" : dev_file} info.update(dev_info) if "card" not in dev_info: #look up the name from the v4l2 virtual dir: dev_dir = os.path.join(v4l2_virtual_dir, f) if not os.path.isdir(dev_dir): continue dev_name = os.path.join(dev_dir, "name") try: name = open(dev_name).read().replace("\n", "") info["card"] = name except: pass devices[no] = info log("devices: %s", devices) log("found %i virtual video device%s", len(devices), engs(devices)) return devices
def print_files(printer, filenames, title, options): if printer not in get_printers(): raise Exception("invalid printer: '%s'" % printer) log("pycups.print_files%s", (printer, filenames, title, options)) actual_options = DEFAULT_CUPS_OPTIONS.copy() used_options = dict((str(k),str(v)) for k,v in options.items() if str(k) in CUPS_OPTIONS_WHITELIST) unused_options = dict((str(k),str(v)) for k,v in options.items() if str(k) not in CUPS_OPTIONS_WHITELIST) log("used options=%s", used_options) log("unused options=%s", unused_options) actual_options.update(used_options) if SIMULATE_PRINT_FAILURE: log.warn("Warning: simulating print failure") conn = None printpid = -1 else: conn = cups.Connection() log("calling printFiles on %s", conn) printpid = conn.printFiles(printer, filenames, title, actual_options) if printpid<=0: log.error("Error: pycups printing on '%s' failed for file%s", printer, engs(filenames)) for f in filenames: log.error(" %s", f) log.error(" using cups server connection: %s", conn) if actual_options: log.error(" printer options:") for k,v in actual_options.items(): log.error(" %-24s : %s", k, v) else: log("pycups %s.printFiles%s=%s", conn, (printer, filenames, title, actual_options), printpid) return printpid
def get_client_backlog(self): packets_backlog, pixels_backlog, bytes_backlog = 0, 0, 0 if self.damage_ack_pending: sent_before = monotonic() - (self.target_latency + TARGET_LATENCY_TOLERANCE) dropped_acks_time = monotonic() - 60 #1 minute drop_missing_acks = [] for sequence, item in tuple(self.damage_ack_pending.items()): start_send_at = item[0] end_send_at = item[3] if end_send_at == 0 or start_send_at > sent_before: continue if start_send_at < dropped_acks_time: drop_missing_acks.append(sequence) else: start_bytes = item[2] end_bytes = item[4] pixels = item[5] packets_backlog += 1 pixels_backlog += pixels bytes_backlog += (end_bytes - start_bytes) log("get_client_backlog missing acks: %s", drop_missing_acks) #this should never happen... if drop_missing_acks: log.error("Error: expiring %i missing damage ACK%s,", len(drop_missing_acks), engs(drop_missing_acks)) log.error(" connection may be closed or closing,") log.error(" sequence numbers missing: %s", csv(drop_missing_acks)) for sequence in drop_missing_acks: self.damage_ack_pending.pop(sequence, None) return packets_backlog, pixels_backlog, bytes_backlog
def print_files(printer, filenames, title, options): if printer not in get_printers(): raise Exception("invalid printer: '%s'" % printer) log("pycups.print_files%s", (printer, filenames, title, options)) actual_options = DEFAULT_CUPS_OPTIONS.copy() actual_options.update(options) if SIMULATE_PRINT_FAILURE: log.warn("Warning: simulating print failure") conn = None printpid = -1 else: conn = cups.Connection() printpid = conn.printFiles(printer, filenames, title, actual_options) if printpid <= 0: log.error("Error: pycups printing on '%s' failed for file%s", printer, engs(filenames)) for f in filenames: log.error(" %s", f) log.error(" using cups server connection: %s", conn) if actual_options: log.error(" printer options:") for k, v in actual_options.items(): log.error(" %-24s : %s", k, v) else: log("pycups %s.printFiles%s=%s", conn, (printer, filenames, title, actual_options), printpid) return printpid
def do_parse_screen_info(self, ss, desktop_size): log("do_parse_screen_info%s", (ss, desktop_size)) dw, dh = None, None if desktop_size: try: dw, dh = desktop_size if not ss.screen_sizes: log.info(" client root window size is %sx%s", dw, dh) else: log.info( " client root window size is %sx%s with %s display%s:", dw, dh, len(ss.screen_sizes), engs(ss.screen_sizes)) log_screen_sizes(dw, dh, ss.screen_sizes) except Exception: dw, dh = None, None sw, sh = self.configure_best_screen_size() log("configure_best_screen_size()=%s", (sw, sh)) #we will tell the client about the size chosen in the hello we send back, #so record this size as the current server desktop size to avoid change notifications: ss.desktop_size_server = sw, sh #prefer desktop size, fallback to screen size: w = dw or sw h = dh or sh #clamp to max supported: maxw, maxh = self.get_max_screen_size() w = min(w, maxw) h = min(h, maxh) self.set_desktop_geometry_attributes(w, h) self.set_icc_profile() return w, h
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 main(): if "-v" in sys.argv or "--verbose" in sys.argv: log.enable_debug() from xpra.platform import program_context with program_context("Nvidia-Info", "Nvidia Info"): #this will log the version number: get_nvidia_module_version() if is_blacklisted(): log.warn("Warning: this driver version is blacklisted") log.info("NVENC license keys:") for v in (0, 8): keys = get_license_keys(v) log.info("* version %s: %s key(s)", v or "common", len(keys)) for k in keys: log.info(" %s", k) try: import pynvml assert pynvml except ImportError: log.warn("Warning: the pynvml library is missing") log.warn(" cannot identify the GPUs installed") else: cards = get_cards() if cards: log.info("") log.info("%i card%s:", len(cards), engs(cards)) print_nested_dict(cards, print_fn=log.info)
def select_best_free_memory(min_compute=0): #load preferences: preferred_device_name = get_pref("device-name") devices = init_all_devices() global DEVICE_STATE free_pct = 0 #split device list according to device state: ok_devices = [ device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is True ] nok_devices = [ device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is not True ] for list_name, device_list in { "OK": ok_devices, "failing": nok_devices }.items(): selected_device_id = -1 selected_device = None log("will test %s device%s from %s list: %s", len(device_list), engs(device_list), list_name, device_list) for device_id in device_list: context = None dct = make_device_context(device_id) if not dct: continue try: device, context, tpct = dct compute = compute_capability(device) if compute < min_compute: log( "ignoring device %s: compute capability %#x (minimum %#x required)", device_info(device), compute, min_compute) elif preferred_device_name and device_info(device).find( preferred_device_name) >= 0: log("device matches preferred device name: %s", preferred_device_name) return device_id, device elif tpct >= MIN_FREE_MEMORY and tpct > free_pct: log( "device has enough free memory: %i (min=%i, current best device=%i)", tpct, MIN_FREE_MEMORY, free_pct) selected_device = device selected_device_id = device_id free_pct = tpct finally: if context: context.pop() context.detach() if selected_device_id >= 0 and selected_device: l = log if len(devices) > 1: l = log.info l("selected device %s: %s", selected_device_id, device_info(selected_device)) return selected_device_id, selected_device return -1, None
def send_challenge_reply(self, packet, password): if not password: if self.password_file: self.auth_error( EXIT_PASSWORD_FILE_ERROR, "failed to load password from file%s %s" % (engs(self.password_file), csv(self.password_file)), "no password available") else: self.auth_error( EXIT_PASSWORD_REQUIRED, "this server requires authentication and no password is available" ) return if self.encryption: assert len( packet ) >= 3, "challenge does not contain encryption details to use for the response" server_cipher = typedict(packet[2]) key = self.get_encryption_key() if key is None: self.auth_error(EXIT_ENCRYPTION, "the server does not use any encryption", "client requires encryption") return if not self.set_server_encryption(server_cipher, key): return #all server versions support a client salt, #they also tell us which digest to use: server_salt = bytestostr(packet[1]) digest = bytestostr(packet[3]) actual_digest = digest.split(":", 1)[0] l = len(server_salt) salt_digest = "xor" if len(packet) >= 5: salt_digest = bytestostr(packet[4]) if salt_digest == "xor": #with xor, we have to match the size assert l >= 16, "server salt is too short: only %i bytes, minimum is 16" % l assert l <= 256, "server salt is too long: %i bytes, maximum is 256" % l else: #other digest, 32 random bytes is enough: l = 32 client_salt = get_salt(l) salt = gendigest(salt_digest, client_salt, server_salt) authlog("combined %s salt(%s, %s)=%s", salt_digest, hexstr(server_salt), hexstr(client_salt), hexstr(salt)) challenge_response = gendigest(actual_digest, password, salt) if not challenge_response: log("invalid digest module '%s': %s", actual_digest) self.auth_error( EXIT_UNSUPPORTED, "server requested '%s' digest but it is not supported" % actual_digest, "invalid digest") return authlog("%s(%s, %s)=%s", actual_digest, repr(password), repr(salt), repr(challenge_response)) self.do_send_challenge_reply(challenge_response, client_salt)
def select_device(preferred_device_id=-1, preferred_device_name=None, min_compute=0): if preferred_device_name is None: preferred_device_name = get_pref("device-name") if preferred_device_id<0: device_id = get_pref("device-id") if device_id is not None and device_id>=0: preferred_device_id = device_id devices = init_all_devices() global DEVICE_STATE free_pct = 0 cf = driver.ctx_flags #split device list according to device state: ok_devices = [device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is True] nok_devices = [device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is not True] for list_name, device_list in {"OK" : ok_devices, "failing" : nok_devices}.items(): selected_device_id = -1 selected_device = None log("will test %s device%s from %s list: %s", len(device_list), engs(device_list), list_name, device_list) for device_id in device_list: context = None try: log("device %i", device_id) device = driver.Device(device_id) log("select_device: testing device %s: %s", device_id, device_info(device)) context = device.make_context(flags=cf.SCHED_YIELD | cf.MAP_HOST) log("created context=%s", context) free, total = driver.mem_get_info() log("memory: free=%sMB, total=%sMB", int(free/1024/1024), int(total/1024/1024)) tpct = 100*free/total SMmajor, SMminor = device.compute_capability() compute = (SMmajor<<4) + SMminor if compute<min_compute: log("ignoring device %s: compute capability %#x (minimum %#x required)", device_info(device), compute, min_compute) elif device_id==preferred_device_id: l = log if len(device_list)>1: l = log.info l("device matches preferred device id %s: %s", preferred_device_id, device_info(device)) return device_id, device elif preferred_device_name and device_info(device).find(preferred_device_name)>=0: log("device matches preferred device name: %s", preferred_device_name) return device_id, device elif tpct>=MIN_FREE_MEMORY and tpct>free_pct: log("device has enough free memory: %i (min=%i, current best device=%i)", tpct, MIN_FREE_MEMORY, free_pct) selected_device = device selected_device_id = device_id free_pct = tpct finally: if context: context.pop() context.detach() if selected_device_id>=0 and selected_device: l = log if len(devices)>1: l = log.info l("selected device %s: %s", device_id, device_info(device)) return selected_device_id, selected_device return -1, None
def client_reset(self): ClipboardProtocolHelperCore.client_reset(self) #timeout all pending requests cor = self._clipboard_outstanding_requests if cor: log.info("cancelling %i clipboard request%s", len(cor), engs(cor)) self._clipboard_outstanding_requests = {} for request_id in cor: self._clipboard_got_contents(request_id)
def do_update_screen(self): #c = self.stdscr.getch() #if c==curses.KEY_RESIZE: height, width = self.stdscr.getmaxyx() #log.info("update_screen() %ix%i", height, width) title = get_title() x = max(0, width//2-len(title)//2) try: hpos = 0 self.stdscr.addstr(hpos, x, title, curses.A_BOLD) hpos += 1 if height<=hpos: return sd = self.dotxpra.socket_details() #group them by display instead of socket dir: displays = {} for sessions in sd.values(): for state, display, path in sessions: displays.setdefault(display, []).append((state, path)) self.stdscr.addstr(hpos, 0, "found %i display%s" % (len(displays), engs(displays))) self.position = min(len(displays), self.position) self.selected_session = None hpos += 1 if height<=hpos: return if self.message: ts, txt, attr = self.message if monotonic_time()-ts<10: self.stdscr.addstr(hpos, 0, txt, attr) hpos += 1 if height<=hpos: return else: self.message = None n = len(displays) for i, (display, state_paths) in enumerate(displays.items()): if height<=hpos: return info = self.get_display_info(display, state_paths) l = len(info) if height<=hpos+l+2: break self.box(1, hpos, width-2, l+2, open_top=i>0, open_bottom=i<n-1) hpos += 1 if i==self.position: self.selected_session = display attr = curses.A_REVERSE else: attr = 0 for s in info: if len(s)>=width-4: s = s[:width-6]+".." s = s.ljust(width-4) self.stdscr.addstr(hpos, 2, s, attr) hpos += 1 except Exception as e: curses_err(self.stdscr, e)
def main(): import sys if "-v" in sys.argv or "--verbose" in sys.argv: from xpra.log import add_debug_category, enable_debug_for enable_debug_for("webcam") add_debug_category("webcam") run = "-r" in sys.argv or "--run" in sys.argv if run: from xpra.gtk_common.gobject_compat import import_glib, import_gobject glib = import_glib() gobject = import_gobject() gobject.threads_init() from xpra.util import engs, print_nested_dict from xpra.platform import program_context with program_context("Webcam Info", "Webcam Info"): devices = get_virtual_video_devices() or {} log.info("Found %i virtual video device%s:", len(devices), engs(devices)) print_nested_dict(devices) all_devices = get_all_video_devices() or {} log.info("Found %i video device%s in total:", len(all_devices), engs(all_devices)) print_nested_dict(all_devices) if run: log.info("add watch for video device changes") def callback(added=None, device=None): if added is not None or device: log.info("video device %s: %s", ["removed", "added"][added], device) else: log.info("device change") log.info("starting main loop") main_loop = glib.MainLoop() glib.idle_add(add_video_device_change_callback, callback) try: main_loop.run() except KeyboardInterrupt: pass log.info("terminating, removing callback") remove_video_device_change_callback(callback)
def select_device(preferred_device_id=-1, preferred_device_name=None, min_compute=0): if preferred_device_name is None: preferred_device_name = get_pref("device-name") if preferred_device_id<0: device_id = get_pref("device-id") if device_id>=0: preferred_device_id = device_id devices = init_all_devices() global DEVICE_STATE free_pct = 0 cf = driver.ctx_flags #split device list according to device state: ok_devices = [device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is True] nok_devices = [device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is not True] for list_name, device_list in {"OK" : ok_devices, "failing" : nok_devices}.items(): selected_device_id = None selected_device = None log("will test %s device%s from %s list: %s", len(device_list), engs(device_list), list_name, device_list) for device_id in device_list: context = None try: device = driver.Device(device_id) log("select_device: testing device %s: %s", device_id, device_info(device)) context = device.make_context(flags=cf.SCHED_YIELD | cf.MAP_HOST) log("created context=%s", context) free, total = driver.mem_get_info() log("memory: free=%sMB, total=%sMB", int(free/1024/1024), int(total/1024/1024)) tpct = 100*free/total SMmajor, SMminor = device.compute_capability() compute = (SMmajor<<4) + SMminor if compute<min_compute: log("ignoring device %s: compute capability %#x (minimum %#x required)", device_info(device), compute, min_compute) elif device_id==preferred_device_id: l = log if len(device_list)>1: l = log.info l("device matches preferred device id %s: %s", preferred_device_id, device_info(device)) return device_id, device elif preferred_device_name and device_info(device).find(preferred_device_name)>=0: log("device matches preferred device name: %s", preferred_device_name) return device_id, device elif tpct>free_pct: selected_device = device selected_device_id = device_id free_pct = tpct finally: if context: context.pop() context.detach() if selected_device_id>=0 and selected_device: l = log if len(devices)>1: l = log.info l("selected device %s: %s", device_id, device_info(device)) return selected_device_id, selected_device return -1, None
def init_video_decoders_options(self): log("init_video_decoders_options()") log(" will try video decoders: %s", csv(self.video_decoders)) for x in self.video_decoders: try: mod = get_decoder_module_name(x) self.init_video_decoder_option(mod) except: log.warn("Warning: cannot add %s decoder", x, exc_info=True) log("found %s video decoder%s: %s", len(self._video_decoder_specs), engs(self._video_decoder_specs), csv(self._video_decoder_specs))
def authenticate(filename, username, password): a = Authenticator(username, filename=filename) passwords = a.get_passwords() assert passwords assert password in passwords sessions = a.get_sessions() assert sessions print("success, found %i session%s: %s" % (len(sessions), engs(sessions), sessions)) return 0
def select_device(preferred_device_id=-1, min_compute=0): log("select_device(%s, %s)", preferred_device_id, min_compute) for device_id in (preferred_device_id, get_pref("device-id")): if device_id is not None and device_id>=0: #try to honour the device specified: try: device, context, compute, tpct = load_device(device_id) finally: context.pop() context.detach() if compute<min_compute: log.warn("Warning: GPU device %i only supports compute %#x", device_id, compute) if tpct<MIN_FREE_MEMORY: log.warn("Warning: GPU device %i is low on memory: %i%%", device_id, tpct) return device_id, device #load preferences: preferred_device_name = get_pref("device-name") devices = init_all_devices() global DEVICE_STATE free_pct = 0 #split device list according to device state: ok_devices = [device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is True] nok_devices = [device_id for device_id in devices if DEVICE_STATE.get(device_id, True) is not True] for list_name, device_list in {"OK" : ok_devices, "failing" : nok_devices}.items(): selected_device_id = -1 selected_device = None log("will test %s device%s from %s list: %s", len(device_list), engs(device_list), list_name, device_list) for device_id in device_list: context = None try: device, context, compute, tpct = load_device(device_id) if compute<min_compute: log("ignoring device %s: compute capability %#x (minimum %#x required)", device_info(device), compute, min_compute) elif preferred_device_name and device_info(device).find(preferred_device_name)>=0: log("device matches preferred device name: %s", preferred_device_name) return device_id, device elif tpct>=MIN_FREE_MEMORY and tpct>free_pct: log("device has enough free memory: %i (min=%i, current best device=%i)", tpct, MIN_FREE_MEMORY, free_pct) selected_device = device selected_device_id = device_id free_pct = tpct finally: if context: context.pop() context.detach() if selected_device_id>=0 and selected_device: l = log if len(devices)>1: l = log.info l("selected device %s: %s", selected_device_id, device_info(selected_device)) return selected_device_id, selected_device return -1, None
def _process_startup_complete(self, packet): log("all the existing windows and system trays have been received") XpraClientBase._process_startup_complete(self, packet) gui_ready() if self.tray: self.tray.ready() self.send_info_request() msg = "running" try: windows = tuple(self._id_to_window.values()) except AttributeError: pass else: trays = sum(1 for w in windows if w.is_tray()) wins = sum(1 for w in windows if not w.is_tray()) if wins: msg += ", %i window%s" % (wins, engs(wins)) if trays: msg += ", %i tray%s" % (trays, engs(trays)) log.info(msg)
def get_license_keys(version=0, basefilename="nvenc"): global license_keys filename = "%s%s.keys" % (basefilename, version or "") keys = license_keys.get(filename) if keys is not None: return keys env_name = "XPRA_%s_CLIENT_KEY" % basefilename.upper() env_keys = os.environ.get(env_name, "") if env_keys: keys = [x.strip() for x in env_keys.split(",")] log("using %s keys from environment variable %s: %s", basefilename, env_name, csv(keys)) else: #try to load the license file keys = [] try: #see read_xpra_defaults for an explanation of paths from xpra.platform.paths import get_default_conf_dirs, get_system_conf_dirs, get_user_conf_dirs dirs = get_default_conf_dirs() + get_system_conf_dirs( ) + get_user_conf_dirs() for d in dirs: if not d: continue keys_file = os.path.join(d, filename) keys_file = os.path.expanduser(keys_file) if not os.path.exists(keys_file): log("get_license_keys(%s, %s) '%s' does not exist", basefilename, version, keys_file) continue log("loading %s version %s keys from %s", basefilename, version, keys_file) with open(keys_file, "rb") as f: fkeys = [] for line in f: sline = bytestostr( line.strip().rstrip(b'\r\n').strip()) if not sline: log("skipping empty line") continue if sline[0] in ('!', '#'): log("skipping comments") continue fkeys.append(sline) log("added key: %s", sline) log("added %i key%s from %s", len(fkeys), engs(fkeys), keys_file) keys += fkeys except Exception: log.error("Error loading %s license keys", basefilename, exc_info=True) license_keys[filename] = keys log("get_nvenc_license_keys(%s)=%s", version, keys) return keys
def clean_pulseaudio_private_dir(self): if self.pulseaudio_private_dir: if os.path.exists(self.pulseaudio_private_socket): log.warn( "Warning: the pulseaudio private socket file still exists:" ) log.warn(" '%s'", self.pulseaudio_private_socket) log.warn( " the private pulseaudio directory containing it will not be removed" ) else: import glob pulse = os.path.join(self.pulseaudio_private_dir, "pulse") native = os.path.join(pulse, "native") dirs = [] dbus_dirs = glob.glob("%s/dbus-*" % self.pulseaudio_private_dir) if len(dbus_dirs) == 1: dbus_dir = dbus_dirs[0] if os.path.isdir(dbus_dir): services_dir = os.path.join(dbus_dir, "services") dirs.append(services_dir) dirs.append(dbus_dir) dirs += [native, pulse, self.pulseaudio_private_dir] path = None try: for d in dirs: path = os.path.abspath(d) soundlog("removing private directory '%s'", path) if os.path.exists(path) and os.path.isdir(path): os.rmdir(path) log.info("removing private directory '%s'", self.pulseaudio_private_dir) except OSError as e: soundlog("cleanup_pulseaudio() error removing '%s'", path, exc_info=True) soundlog.error( "Error: failed to cleanup the pulseaudio private directory" ) soundlog.error(" '%s'", self.pulseaudio_private_dir) soundlog.error(" %s", e) try: files = os.listdir(path) if files: soundlog.error(" found %i file%s in '%s':", len(files), engs(files), path) for f in files: soundlog.error(" - '%s'", f) except OSError: soundlog.error( "cleanup_pulseaudio() error accessing '%s'", path, exc_info=True)
def main(): import sys if "-v" in sys.argv or "--verbose" in sys.argv: from xpra.log import add_debug_category add_debug_category("webcam") from xpra.platform import program_context with program_context("Webcam Info", "Webcam Info"): devices = get_virtual_video_devices() log.info("Found %i virtual video device%s:", len(devices), engs(devices)) for no, d in devices.items(): log.info("%-2i: %s", no, d)
def get_nvenc_license_keys(nvenc_version=0): global nvenc_license_keys keys = nvenc_license_keys.get(nvenc_version) if keys is not None: return keys env_keys = os.environ.get("XPRA_NVENC_CLIENT_KEY", "") if env_keys: keys = [ x.strip() for x in os.environ.get("XPRA_NVENC_CLIENT_KEY", "").split(",") ] log( "using nvenc keys from environment variable XPRA_NVENC_CLIENT_KEY: %s", nvenc_license_keys) else: #try the license file keys = [] try: #see read_xpra_defaults for an explanation of paths from xpra.platform.paths import get_default_conf_dirs, get_system_conf_dirs, get_user_conf_dirs dirs = get_default_conf_dirs() + get_system_conf_dirs( ) + get_user_conf_dirs() for d in dirs: if not d: continue keys_file = os.path.join( d, "nvenc%s.keys" % (nvenc_version or "")) keys_file = os.path.expanduser(keys_file) if not os.path.exists(keys_file): log("get_nvenc_license_keys(%s) '%s' does not exist", nvenc_version, keys_file) continue log("loading nvenc%s keys from %s", nvenc_version, keys_file) with open(keys_file, "rU") as f: fkeys = [] for line in f: sline = line.strip().rstrip('\r\n').strip() if len(sline) == 0: log("skipping empty line") continue if sline[0] in ('!', '#'): log("skipping comments") continue fkeys.append(sline) log("added key: %s", sline) log("added %i key%s from %s", len(fkeys), engs(fkeys), keys_file) keys += fkeys except Exception as e: log.error("error loading nvenc license keys: %s", e, exc_info=True) nvenc_license_keys[nvenc_version] = keys log("get_nvenc_license_keys(%s)=%s", nvenc_version, keys) return keys
def send_updated_screen_size(self): max_w, max_h = self.get_max_screen_size() root_w, root_h = self.get_root_window_size() root_w = min(root_w, max_w) root_h = min(root_h, max_h) count = 0 for ss in self._server_sources.values(): if ss.updated_desktop_size(root_w, root_h, max_w, max_h): count +=1 if count>0: log.info("sent updated screen size to %s client%s: %sx%s (max %sx%s)", count, engs(count), root_w, root_h, max_w, max_h)
def sound_option_or_all(name, options, all_values): if not options: v = all_values #not specified on command line: use default else: v = [] invalid_options = [] for x in options: #options is a list, but it may have csv embedded: for o in x.split(","): o = o.strip() if o not in all_values: invalid_options.append(o) else: v.append(o) if len(invalid_options)>0: if all_values: log.warn("Warning: invalid value%s for %s: %s", engs(invalid_options), name, csv(invalid_options)) log.warn(" valid option%s: %s", engs(all_values), csv(all_values)) else: log.warn("Warning: no %ss available", name) log("%s=%s", name, csv(v)) return v
def main(): import sys if "-v" in sys.argv or "--verbose" in sys.argv: from xpra.log import add_debug_category add_debug_category("webcam") run = "-r" in sys.argv or "--run" in sys.argv if run: from xpra.gtk_common.gobject_compat import import_glib, import_gobject glib = import_glib() gobject = import_gobject() gobject.threads_init() from xpra.util import engs, print_nested_dict from xpra.platform import program_context with program_context("Webcam Info", "Webcam Info"): devices = get_virtual_video_devices() or {} log.info("Found %i virtual video device%s:", len(devices), engs(devices)) print_nested_dict(devices) all_devices = get_all_video_devices() or {} log.info("Found %i video device%s in total:", len(all_devices), engs(all_devices)) print_nested_dict(all_devices) if run: log.info("add watch for video device changes") def callback(added=None, device=None): if added is not None or device: log.info("video device %s: %s", ["removed", "added"][added], device) else: log.info("device change") log.info("starting main loop") main_loop = glib.MainLoop() glib.idle_add(add_video_device_change_callback, callback) try: main_loop.run() except KeyboardInterrupt: pass log.info("terminating, removing callback") remove_video_device_change_callback(callback)
def authenticate_check(self, challenge_response: str, client_salt: str = None) -> bool: log("authenticate_check(%s, %s)", repr(challenge_response), repr(client_salt)) user_presence, counter = struct.unpack( b">BI", strtobytes(challenge_response)[:5]) sig = strtobytes(challenge_response[5:]) log("u2f user_presence=%s, counter=%s, signature=%s", user_presence, counter, hexstr(sig)) app_param = sha256(self.app_id.encode('utf8')).digest() server_challenge_b64 = base64.urlsafe_b64encode(self.salt).decode() server_challenge_b64 = server_challenge_b64.rstrip('=') log("challenge_b64(%s)=%s", repr(self.salt), server_challenge_b64) client_data = { "challenge": server_challenge_b64, "origin": client_salt, "typ": "navigator.id.getAssertion", } client_param = sha256( json.dumps(client_data, sort_keys=True).encode('utf8')).digest() param = app_param + \ struct.pack(b'>B', user_presence) + \ struct.pack(b'>I', counter) + \ client_param #check all the public keys: #pylint: disable=import-outside-toplevel from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec errors = {} for origin, public_key in self.public_keys.items(): verifier = public_key.verifier(sig, ec.ECDSA(hashes.SHA256())) verifier.update(param) try: verifier.verify() log("ECDSA SHA256 verification passed for '%s'", origin) return True except Exception as e: log("authenticate failed for '%s' / %s", origin, public_key, exc_info=True) errors[origin] = str(e) or type(e) log.error("Error: authentication failed,") log.error(" checked against %i key%s", len(self.public_keys), engs(self.public_keys)) for origin, error in errors.items(): log.error(" '%s': %s", origin, error) return False
def run(self, *args): if self.min_args is not None and len(args)<self.min_args: self.raise_error("at least %i argument%s required" % (self.min_args, engs(self.min_args))) if self.max_args is not None and len(args)>self.max_args: self.raise_error("too many arguments, %i maximum" % self.max_args) args = list(args) for i,validation in enumerate(self.validation): v = args[i] log("running '%s' validation for argument %i: %s (value=%s, type=%s)", self.name, i, validation, v, type(v)) if not validation: continue try: args[i] = validation(v) except ValueError as e: self.raise_error("argument %i failed validation: %s" % (i+1, e)) return super(ArgsControlCommand, self).run(*args)
def init_video_encoders_options(self): log("init_video_encoders_options()") log(" will try video encoders: %s", csv(self.video_encoders)) for x in self.video_encoders: try: mods = get_encoder_module_names(x) log(" modules for %s: %s", x, csv(mods)) for mod in mods: try: self.init_video_encoder_option(mod) break except Exception as e: log(" init_video_encoder_option(%s) error", mod, exc_info=True) log.warn("Warning: cannot load %s video encoder:", mod) log.warn(" %s", e) except Exception as e: log.warn("Warning: cannot add %s encoder: %s", x, e) log("found %i video encoder%s: %s", len(self._video_encoder_specs), engs(self._video_encoder_specs), csv(self._video_encoder_specs))
def get_nvenc_license_keys(nvenc_version=0): global nvenc_license_keys keys = nvenc_license_keys.get(nvenc_version) if keys is not None: return keys env_keys = os.environ.get("XPRA_NVENC_CLIENT_KEY", "") if env_keys: keys = [x.strip() for x in os.environ.get("XPRA_NVENC_CLIENT_KEY", "").split(",")] log("using nvenc keys from environment variable XPRA_NVENC_CLIENT_KEY: %s", nvenc_license_keys) else: #try the license file keys = [] try: #see read_xpra_defaults for an explanation of paths from xpra.platform.paths import get_default_conf_dirs, get_system_conf_dirs, get_user_conf_dirs dirs = get_default_conf_dirs() + get_system_conf_dirs() + get_user_conf_dirs() for d in dirs: if not d: continue keys_file = os.path.join(d, "nvenc%s.keys" % (nvenc_version or "")) keys_file = os.path.expanduser(keys_file) if not os.path.exists(keys_file): log("get_nvenc_license_keys(%s) '%s' does not exist", nvenc_version, keys_file) continue log("loading nvenc%s keys from %s", nvenc_version, keys_file) with open(keys_file, "rU") as f: fkeys = [] for line in f: sline = line.strip().rstrip('\r\n').strip() if len(sline) == 0: log("skipping empty line") continue if sline[0] in ( '!', '#' ): log("skipping comments") continue fkeys.append(sline) log("added key: %s", sline) log("added %i key%s from %s", len(fkeys), engs(fkeys), keys_file) keys += fkeys except Exception as e: log.error("error loading nvenc license keys: %s", e, exc_info=True) nvenc_license_keys[nvenc_version] = keys log("get_nvenc_license_keys(%s)=%s", nvenc_version, keys) return keys
def main(): if "-v" in sys.argv or "--verbose" in sys.argv: log.enable_debug() from xpra.platform import program_context with program_context("Nvidia-Info", "Nvidia Info"): #this will log the version number: get_nvidia_module_version() if is_blacklisted(): log.warn("Warning: this driver version is blacklisted") log.info("NVENC license keys:") for v in (0, 7): keys = get_nvenc_license_keys(v) log.info("* version %s: %s key(s)", v or "common", len(keys)) for k in keys: log.info(" %s", k) cards = get_cards() if cards: log.info("") log.info("%i card%s:", len(cards), engs(cards)) print_nested_dict(cards, print_fn=log.info)
def get_virtual_video_devices(capture_only=True): log("get_virtual_video_devices") if not check_virtual_dir(False): return [] contents = os.listdir(v4l2_virtual_dir) devices = {} try: from xpra.codecs.v4l2.pusher import query_video_device except ImportError: def query_video_device(device): return {} for f in contents: if not f.startswith("video"): continue try: no = int(f[len("video"):]) assert no>=0 except: continue dev_file = "/dev/%s" % f dev_info = query_video_device(dev_file) if capture_only and not _can_capture_video(dev_file, dev_info): continue info = {"device" : dev_file} info.update(dev_info) if "card" not in dev_info: #look up the name from the v4l2 virtual dir: dev_dir = os.path.join(v4l2_virtual_dir, f) if not os.path.isdir(dev_dir): continue dev_name = os.path.join(dev_dir, "name") try: name = open(dev_name).read().replace("\n", "") info["card"] = name except: pass devices[no] = info log("devices: %s", devices) log("found %i virtual video device%s", len(devices), engs(devices)) return devices
def init_all_devices(): global DEVICES, DEVICE_INFO if DEVICES is not None: return DEVICES log.info("CUDA initialization (this may take a few seconds)") DEVICES = [] DEVICE_INFO = {} try: driver.init() except Exception as e: log.error("Error: cannot initialize CUDA") log.error(" %s", e) return DEVICES log("CUDA driver version=%s", driver.get_driver_version()) ngpus = driver.Device.count() if ngpus==0: log.info("CUDA %s / PyCUDA %s, no devices found", ".".join([str(x) for x in driver.get_version()]), pycuda.VERSION_TEXT) return DEVICES cuda_device_blacklist = get_pref("blacklist") da = driver.device_attribute cf = driver.ctx_flags for i in range(ngpus): device = None context = None devinfo = "gpu %i" % i try: device = driver.Device(i) devinfo = device_info(device) if cuda_device_blacklist: blacklisted = [x for x in cuda_device_blacklist if x and devinfo.find(x)>=0] log("blacklisted(%s / %s)=%s", devinfo, cuda_device_blacklist, blacklisted) if blacklisted: log.warn("Warning: device '%s' is blacklisted and will not be used", devinfo) continue log(" + testing device %s: %s", i, devinfo) DEVICE_INFO[i] = devinfo host_mem = device.get_attribute(da.CAN_MAP_HOST_MEMORY) if not host_mem: log.warn("skipping device %s (cannot map host memory)", devinfo) continue context = device.make_context(flags=cf.SCHED_YIELD | cf.MAP_HOST) try: log(" created context=%s", context) log(" api version=%s", context.get_api_version()) free, total = driver.mem_get_info() log(" memory: free=%sMB, total=%sMB", int(free/1024/1024), int(total/1024/1024)) log(" multi-processors: %s, clock rate: %s", device.get_attribute(da.MULTIPROCESSOR_COUNT), device.get_attribute(da.CLOCK_RATE)) log(" max block sizes: (%s, %s, %s)", device.get_attribute(da.MAX_BLOCK_DIM_X), device.get_attribute(da.MAX_BLOCK_DIM_Y), device.get_attribute(da.MAX_BLOCK_DIM_Z)) log(" max grid sizes: (%s, %s, %s)", device.get_attribute(da.MAX_GRID_DIM_X), device.get_attribute(da.MAX_GRID_DIM_Y), device.get_attribute(da.MAX_GRID_DIM_Z)) max_width = device.get_attribute(da.MAXIMUM_TEXTURE2D_WIDTH) max_height = device.get_attribute(da.MAXIMUM_TEXTURE2D_HEIGHT) log(" maximum texture size: %sx%s", max_width, max_height) log(" max pitch: %s", device.get_attribute(da.MAX_PITCH)) SMmajor, SMminor = device.compute_capability() compute = (SMmajor<<4) + SMminor log(" compute capability: %#x (%s.%s)", compute, SMmajor, SMminor) if i==0: #we print the list info "header" from inside the loop #so that the log output is bunched up together log.info("CUDA %s / PyCUDA %s, found %s device%s:", ".".join([str(x) for x in driver.get_version()]), pycuda.VERSION_TEXT, ngpus, engs(ngpus)) if SMmajor>=2: DEVICES.append(i) else: log.info(" this device is too old!") log.info(" + %s (memory: %s%% free, compute: %s.%s)", device_info(device), 100*free/total, SMmajor, SMminor) finally: context.pop() except Exception as e: log.error("error on device %s: %s", devinfo, e) return DEVICES
def select_device(): global context, selected_device,selected_platform,selected_device_max_size,AMD_WARNING_SHOWN if context is not None: return log_version_info() log_platforms_info() #try to choose a platform and device using *our* heuristics / env options: options = {} log("select_device() environment preferred DEVICE_NAME=%s, DEVICE_TYPE=%s, DEVICE_PLATFORM=%s", PREFERRED_DEVICE_NAME, PREFERRED_DEVICE_TYPE, PREFERRED_DEVICE_PLATFORM) for platform in opencl_platforms: log("evaluating platform=%s", platform.name) if platform.name.startswith("AMD") and not AMD_WARNING_SHOWN: log.warn("Warning: the AMD OpenCL is loaded, it is known to interfere with signal delivery!") log.warn(" please consider disabling OpenCL or removing the AMD icd") AMD_WARNING_SHOWN = True devices = platform.get_devices() is_cuda = platform.name.find("CUDA")>=0 for d in devices: if d.available and d.compiler_available and d.get_info(pyopencl.device_info.IMAGE_SUPPORT): if not is_supported(platform.name) and (len(PREFERRED_DEVICE_PLATFORM)==0 or str(platform.name).find(PREFERRED_DEVICE_PLATFORM)<0): log("ignoring unsupported platform/device: %s / %s", platform.name, d.name) continue dtype = device_type(d) log("evaluating device type=%s, name=%s", dtype, d.name) if is_cuda: score = 0 elif dtype==PREFERRED_DEVICE_TYPE: score = 40 else: score = 10 if len(PREFERRED_DEVICE_NAME)>0 and d.name.find(PREFERRED_DEVICE_NAME)>=0: score += 50 if len(PREFERRED_DEVICE_PLATFORM)>0 and str(platform.name).find(PREFERRED_DEVICE_PLATFORM)>=0: score += 50 #Intel SDK does not work (well?) on AMD CPUs #and CUDA has problems doing YUV to RGB.. if platform.name.startswith("Intel"): if d.name.find("AMD")>=0 or is_cuda: score = max(0, score - 20) elif d.name.find("Intel")>=0: score += 10 options.setdefault(score, []).append((d, platform)) log("best device/platform option%s: %s", engs(options), options) for score in reversed(sorted(options.keys())): for d, p in options.get(score): try: log("trying platform: %s", platform_info(p)) log("with %s device: %s", device_type(d), device_info(d)) context = pyopencl.Context([d]) selected_device_max_size = d.get_info(pyopencl.device_info.IMAGE2D_MAX_WIDTH), d.get_info(pyopencl.device_info.IMAGE2D_MAX_HEIGHT) selected_platform = p selected_device = d log.info(" using platform: %s", platform_info(selected_platform)) log_device_info(selected_device) #save device costs: global selected_device_cpu_cost, selected_device_gpu_cost, selected_device_setup_cost if device_type(d)=="GPU": selected_device_cpu_cost = 0 selected_device_gpu_cost = 50 selected_device_setup_cost = 40 else: selected_device_cpu_cost = 100 selected_device_gpu_cost = 0 selected_device_setup_cost = 20 log("device is a %s, using CPU cost=%s, GPU cost=%s", device_type(d), selected_device_cpu_cost, selected_device_gpu_cost) log(" max image 2d size: %s", selected_device_max_size) return except Exception as e: log.warn(" failed to use %s", platform_info(p)) log.warn(" with %s device %s", device_type(d), device_info(d)) log.warn(" Error: %s", e) #fallback to pyopencl auto mode: log.warn("OpenCL Error: failed to find a working platform and device combination... trying with pyopencl's 'create_some_context'") context = pyopencl.create_some_context(interactive=False) devices = context.get_info(pyopencl.context_info.DEVICES) log.info("chosen context has %s device%s:", len(devices), engs(devices)) for d in devices: log_device_info(d) assert len(devices)==1, "we only handle a single device at a time, sorry!" selected_device = devices[0] assert context is not None and selected_device is not None
def get_client_backlog(self): packets_backlog, pixels_backlog, bytes_backlog = 0, 0, 0 if len(self.damage_ack_pending)>0: sent_before = time.time()-(self.target_latency+0.020) dropped_acks_time = time.time()-60 #1 minute drop_missing_acks = [] for sequence, (start_send_at, start_bytes, end_send_at, end_bytes, pixels) in self.damage_ack_pending.items(): if end_send_at==0 or start_send_at>sent_before: continue if start_send_at<dropped_acks_time: drop_missing_acks.append(sequence) else: packets_backlog += 1 pixels_backlog += pixels bytes_backlog += (end_bytes - start_bytes) log("get_client_backlog missing acks: %s", drop_missing_acks) #this should never happen... if len(drop_missing_acks)>0: log.error("Error: expiring %i missing damage ACK%s,", len(drop_missing_acks), engs(drop_missing_acks)) log.error(" connection may be closed or closing,") log.error(" sequence numbers missing: %s", csv(drop_missing_acks)) for sequence in drop_missing_acks: try: del self.damage_ack_pending[sequence] except: pass return packets_backlog, pixels_backlog, bytes_backlog
def get_pulse_device(device_name_match=None, want_monitor_device=True, input_or_output=None, remote=None, xpra_device_name=None): """ choose the device to use """ try: from xpra.sound.pulseaudio.pulseaudio_util import has_pa, get_pa_device_options, get_default_sink, get_pulse_server, get_pulse_id 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() if remote: 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 #one that starts with {UUID}unix:/.. if pa_server and pa_server.startswith("{") and \ remote.pulseaudio_server and remote.pulseaudio_server==pa_server: log.error("Error: sound is disabled to prevent a sound loop") log.error(" identical Pulseaudio server '%s'", pa_server) return None pa_id = get_pulse_id() log("start sound, client id=%s, server id=%s", remote.pulseaudio_id, pa_id) if remote.pulseaudio_id and remote.pulseaudio_id==pa_id: log.error("Error: sound is disabled to prevent a sound loop") log.error(" identical Pulseaudio ID '%s'", pa_id) return None device_type_str = "" if input_or_output is not None: device_type_str = ["output", "input"][input_or_output] if want_monitor_device: device_type_str += " monitor" #def get_pa_device_options(monitors=False, input_or_output=None, ignored_devices=["bell-window-system"], log_errors=True) devices = get_pa_device_options(want_monitor_device, input_or_output) log("found %i pulseaudio %s device%s: %s", len(devices), device_type_str, engs(devices), devices) if len(devices)==0: log.error("Error: sound forwarding is disabled") log.error(" could not detect any Pulseaudio %s devices", device_type_str) return None #try to match one of the devices using the device name filters: if len(devices)>1: filters = [] matches = [] for match in (device_name_match, PULSEAUDIO_DEVICE_NAME, xpra_device_name): if not match: continue if match!=xpra_device_name: filters.append(match) match = match.lower() matches = dict((k,v) for k,v in devices.items() if k.lower().find(match)>=0 or v.lower().find(match)>=0) #log("matches(%s, %s)=%s", devices, match, matches) if len(matches)==1: log("found name match for '%s': %s", match, matches.items()[0]) break elif len(matches)>1: log.warn("Warning: Pulseaudio %s device name filter '%s'", device_type_str, match) log.warn(" matched %i devices", len(matches)) if filters or len(matches)>0: if len(matches)==0: log.warn("Warning: Pulseaudio %s device name filter%s:", device_type_str, engs(filters)) log.warn(" %s", csv("'%s'" % x for x in filters)) log.warn(" did not match any of the devices found:") for k,v in devices.items(): log.warn(" * '%s'", k) log.warn(" '%s'", v) return None devices = matches #still have too many devices to choose from? if len(devices)>1: if want_monitor_device: #use the monitor of the default sink if we find it: default_sink = get_default_sink() default_monitor = default_sink+".monitor" if default_monitor in devices: device_name = devices.get(default_monitor) log.info("using monitor of default sink: %s", device_name) return default_monitor global WARNED_MULTIPLE_DEVICES if not WARNED_MULTIPLE_DEVICES: WARNED_MULTIPLE_DEVICES = True if not PULSEAUDIO_DEVICE_NAME: #warned already dtype = "audio" if want_monitor_device: dtype = "output monitor" elif input_or_output is False: dtype = "audio input" elif input_or_output is True: dtype = "audio output" log.warn("Warning: found %i %s devices:", len(devices), dtype) for k,v in devices.items(): log.warn(" * %s", v) log.warn(" %s", k) if not PULSEAUDIO_DEVICE_NAME: #used already! log.warn(" to select a specific one,") log.warn(" use the environment variable XPRA_PULSEAUDIO_DEVICE_NAME") #default to first one: if USE_DEFAULT_DEVICE: log.info("using default pulseaudio device") return None #default to first one: device, device_name = devices.items()[0] log.info("using pulseaudio device:") log.info(" '%s'", device_name) return device