Example #1
0
File: audio.py Project: chewi/xpra
 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
Example #2
0
    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
Example #3
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)
Example #4
0
    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
Example #5
0
 def is_needed(cls, caps : typedict) -> bool:
     return bool(caps.strtupleget("encodings"))
Example #6
0
    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)