def parse_server_capabilities(self, c: typedict) -> bool: self.server_av_sync = c.boolget("av-sync.enabled") avsynclog("av-sync: server=%s, client=%s", self.server_av_sync, self.av_sync) self.server_pulseaudio_id = c.strget("sound.pulseaudio.id") self.server_pulseaudio_server = c.strget("sound.pulseaudio.server") self.server_sound_decoders = c.strtupleget("sound.decoders") self.server_sound_encoders = c.strtupleget("sound.encoders") self.server_sound_receive = c.boolget("sound.receive") self.server_sound_send = c.boolget("sound.send") log( "pulseaudio id=%s, server=%s, sound decoders=%s, sound encoders=%s, receive=%s, send=%s", self.server_pulseaudio_id, self.server_pulseaudio_server, csv(self.server_sound_decoders), csv(self.server_sound_encoders), self.server_sound_receive, self.server_sound_send) if self.server_sound_send and self.speaker_enabled: self.show_progress(90, "starting speaker forwarding") self.start_receiving_sound() if self.server_sound_receive and self.microphone_enabled: #call via idle_add because we may query X11 properties #to find the pulseaudio server: GLib.idle_add(self.start_sending_sound) return True
def parse_client_caps(self, c : typedict): #general features: self.info_namespace = c.boolget("info-namespace") self.share = c.boolget("share") self.lock = c.boolget("lock") self.control_commands = c.strtupleget("control_commands") self.xdg_menu_update = c.boolget("xdg-menu-update") bandwidth_limit = c.intget("bandwidth-limit", 0) server_bandwidth_limit = self.server_bandwidth_limit if self.server_bandwidth_limit is None: server_bandwidth_limit = self.get_socket_bandwidth_limit() or bandwidth_limit self.bandwidth_limit = min(server_bandwidth_limit, bandwidth_limit) if self.bandwidth_detection: self.bandwidth_detection = c.boolget("bandwidth-detection", True) self.client_connection_data = c.dictget("connection-data", {}) ccd = typedict(self.client_connection_data) self.adapter_type = ccd.strget("adapter-type", "") self.jitter = ccd.intget("jitter", 0) bandwidthlog("server bandwidth-limit=%s, client bandwidth-limit=%s, value=%s, detection=%s", server_bandwidth_limit, bandwidth_limit, self.bandwidth_limit, self.bandwidth_detection) if getattr(self, "mmap_size", 0)>0: log("mmap enabled, ignoring bandwidth-limit") self.bandwidth_limit = 0
def parse_client_caps(self, c: typedict): #general features: self.info_namespace = c.boolget("info-namespace") self.send_notifications = c.boolget("notifications") self.send_notifications_actions = c.boolget("notifications.actions") log("notifications=%s, actions=%s", self.send_notifications, self.send_notifications_actions) self.share = c.boolget("share") self.lock = c.boolget("lock") self.control_commands = c.strtupleget("control_commands") self.xdg_menu_update = c.boolget("xdg-menu-update") bandwidth_limit = c.intget("bandwidth-limit", 0) server_bandwidth_limit = self.server_bandwidth_limit if self.server_bandwidth_limit is None: server_bandwidth_limit = self.get_socket_bandwidth_limit( ) or bandwidth_limit self.bandwidth_limit = min(server_bandwidth_limit, bandwidth_limit) if self.bandwidth_detection: self.bandwidth_detection = c.boolget("bandwidth-detection", True) self.client_connection_data = c.dictget("connection-data", {}) self.jitter = typedict(self.client_connection_data).intget("jitter", 0) bandwidthlog( "server bandwidth-limit=%s, client bandwidth-limit=%s, value=%s, detection=%s", server_bandwidth_limit, bandwidth_limit, self.bandwidth_limit, self.bandwidth_detection) if getattr(self, "mmap_size", 0) > 0: log("mmap enabled, ignoring bandwidth-limit") self.bandwidth_limit = 0 #adjust max packet size if file transfers are enabled: #TODO: belongs in mixin: file_transfer = getattr(self, "file_transfer", None) if file_transfer: self.protocol.max_packet_size = max( self.protocol.max_packet_size, self.file_size_limit * 1024 * 1024)
def parse_server_capabilities(self, c: typedict) -> bool: for cb in CLIENT_BASES: if not cb.parse_server_capabilities(self, c): log.info("failed to parse server capabilities in %s", cb) return False self.server_session_name = strtobytes(c.rawget("session_name", b"")).decode("utf-8") set_name("Xpra", self.session_name or self.server_session_name or "Xpra") self.server_platform = c.strget("platform") self.server_sharing = c.boolget("sharing") self.server_sharing_toggle = c.boolget("sharing-toggle") self.server_lock = c.boolget("lock") self.server_lock_toggle = c.boolget("lock-toggle") self.server_keyboard = c.boolget("keyboard", True) self.server_pointer = c.boolget("pointer", True) self.server_start_new_commands = c.boolget("start-new-commands") if self.server_start_new_commands: self.server_xdg_menu = c.dictget("xdg-menu", None) if self.start_new_commands or self.start_child_new_commands: if self.server_start_new_commands: self.after_handshake(self.send_start_new_commands) else: log.warn("Warning: cannot start new commands") log.warn(" the feature is currently disabled on the server") self.server_commands_info = c.boolget("server-commands-info") self.server_commands_signals = c.strtupleget("server-commands-signals") self.server_readonly = c.boolget("readonly") if self.server_readonly and not self.readonly: log.info("server is read only") self.readonly = True if not self.server_keyboard and self.keyboard_helper: #swallow packets: def nosend(*_args): pass self.keyboard_helper.send = nosend i = platform_name( self._remote_platform, c.strtupleget("platform.linux_distribution") or c.strget("platform.release", "")) r = self._remote_version if self._remote_revision: r += "-r%s" % self._remote_revision mode = c.strget("server.mode", "server") bits = c.intget("python.bits", 32) log.info("Xpra %s server version %s %i-bit", mode, std(r), bits) if i: log.info(" running on %s", std(i)) if c.boolget("desktop") or c.boolget("shadow"): v = c.intpair("actual_desktop_size") if v: w, h = v ss = c.tupleget("screen_sizes") if ss: log.info(" remote desktop size is %sx%s with %s screen%s:", w, h, len(ss), engs(ss)) log_screen_sizes(w, h, ss) else: log.info(" remote desktop size is %sx%s", w, h) if c.boolget("proxy"): proxy_hostname = c.strget("proxy.hostname") proxy_platform = c.strget("proxy.platform") proxy_release = c.strget("proxy.platform.release") proxy_version = c.strget("proxy.version") proxy_version = c.strget("proxy.build.version", proxy_version) proxy_distro = c.strget("proxy.linux_distribution") msg = "via: %s proxy version %s" % (platform_name( proxy_platform, proxy_distro or proxy_release), std(proxy_version or "unknown")) if proxy_hostname: msg += " on '%s'" % std(proxy_hostname) log.info(msg) return True
def is_needed(cls, caps : typedict) -> bool: return bool(caps.strtupleget("encodings"))
def parse_client_caps(self, c : typedict): #batch options: def batch_value(prop, default, minv=None, maxv=None): assert default is not None def parse_batch_int(value, varname): if value is not None: try: return int(value) except (TypeError, ValueError): log.error("Error: invalid value '%s' for batch option %s", value, varname) return None #from client caps first: cpname = "batch.%s" % prop v = parse_batch_int(c.get(cpname), cpname) #try env: if v is None: evname = "XPRA_BATCH_%s" % prop.upper() v = parse_batch_int(os.environ.get(evname), evname) #fallback to default: if v is None: v = default if minv is not None: v = max(minv, v) if maxv is not None: v = min(maxv, v) assert v is not None return v #general features: self.zlib = c.boolget("zlib", True) self.lz4 = c.boolget("lz4", False) and use("lz4") self.brotli = c.boolget("brotli", False) and use("brotli") log("compressors: zlib=%s, lz4=%s, brotli=%s", self.zlib, self.lz4, self.brotli) delay = batch_config.START_DELAY dbc = self.default_batch_config dbc.always = bool(batch_value("always", batch_config.ALWAYS)) dbc.min_delay = batch_value("min_delay", batch_config.MIN_DELAY, 0, 1000) dbc.max_delay = batch_value("max_delay", batch_config.MAX_DELAY, 1, 15000) dbc.max_events = batch_value("max_events", batch_config.MAX_EVENTS) dbc.max_pixels = batch_value("max_pixels", batch_config.MAX_PIXELS) dbc.time_unit = batch_value("time_unit", batch_config.TIME_UNIT, 1) self.vrefresh = c.intget("vrefresh", -1) dbc.match_vrefresh(self.vrefresh) dbc.delay = batch_value("delay", delay, dbc.min_delay) log("default batch config: %s", dbc) #encodings: self.encodings_packet = c.boolget("encodings.packet", False) self.encodings = c.strtupleget("encodings") self.core_encodings = c.strtupleget("encodings.core", self.encodings) log("encodings=%s, core_encodings=%s", self.encodings, self.core_encodings) #we can't assume that the window mixin is loaded, #or that the ui_client flag exists: send_ui = getattr(self, "ui_client", True) and getattr(self, "send_windows", True) if send_ui and not self.core_encodings: raise ClientException("client failed to specify any supported encodings") self.window_icon_encodings = c.strtupleget("encodings.window-icon", ("premult_argb32",)) #try both spellings for older versions: for x in ("encodings", "encoding",): self.rgb_formats = c.strtupleget(x+".rgb_formats", self.rgb_formats) #skip all other encoding related settings if we don't send pixels: if not send_ui: log("windows/pixels forwarding is disabled for this client") else: self.parse_encoding_caps(c)