Esempio n. 1
0
    def __init__(self, queue_damage, queue_packet, statistics, wid,
                 batch_config, encoding, encodings, encoding_client_options,
                 mmap, mmap_size):
        self.queue_damage = queue_damage  #callback to add damage data which is ready to compress to the damage processing queue
        self.queue_packet = queue_packet  #callback to add a network packet to the outgoing queue
        self.wid = wid
        self.global_statistics = statistics  #shared/global statistics from ServerSource
        self.statistics = WindowPerformanceStatistics()
        self.encoding = encoding  #the current encoding
        self.encodings = encodings  #all the encodings supported by the client
        self.encoding_client_options = encoding_client_options  #does the client support encoding options?
        self.batch_config = batch_config
        # mmap:
        self._mmap = mmap
        self._mmap_size = mmap_size
        if self._mmap and self._mmap_size > 0:
            self._mmap_data_start = ctypes.c_uint.from_buffer(self._mmap, 0)
            self._mmap_data_end = ctypes.c_uint.from_buffer(self._mmap, 4)

        # video codecs:
        self._video_encoder = None
        self._video_encoder_lock = Lock(
        )  #to ensure we serialize access to the encoder and its internals
        self._video_encoder_quality = maxdeque(
            NRECS
        )  #keep track of the target encoding_quality: (event time, encoding speed)
        self._video_encoder_speed = maxdeque(
            NRECS
        )  #keep track of the target encoding_speed: (event time, encoding speed)
        # for managing/cancelling damage requests:
        self._damage_delayed = None  #may store a delayed region when batching in progress
        self._sequence = 1  #increase with every region we process or delay
        self._damage_cancelled = 0  #stores the highest _sequence cancelled
        self._damage_packet_sequence = 1  #increase with every damage packet created
Esempio n. 2
0
    def __init__(self):
        dotxpra = DotXpra()
        display = os.environ.get("DISPLAY")
        from xpra.scripts.config import make_defaults_struct
        opts = make_defaults_struct()
        target = dotxpra.socket_path(display)
        log.info("attempting to connect to socket: %s", target)
        sock = socket.socket(socket.AF_UNIX)
        sock.connect(target)
        conn = SocketConnection(sock, sock.getsockname(), sock.getpeername(), target, "scroll-test")
        log.info("successfully created our socket connection: %s", conn)
        self.server = ServerMessenger(conn, opts)

        self.vscroll_events = maxdeque(1000)
        self.hscroll_events = maxdeque(1000)

        browser = WebBrowser()
        #hook some events:
        browser.content_tabs.connect("focus-view-title-changed", self.title_changed)
        vscroll_listeners.append(self.vscroll)
        hscroll_listeners.append(self.hscroll)
        #the things we tune:
        self.quality = -1
        self.speed = -1
        self.encoding = None
        self.strict = False
Esempio n. 3
0
    def reset(self):
        self.client_decode_time = maxdeque(NRECS)       #records how long it took the client to decode frames:
                                                        #(ack_time, no of pixels, decoding_time*1000*1000)
        self.encoding_stats = maxdeque(NRECS)           #encoding: (coding, pixels, bpp, compressed_size, encoding_time)
        # statistics:
        self.damage_in_latency = maxdeque(NRECS)        #records how long it took for a damage request to be sent
                                                        #last NRECS: (sent_time, no of pixels, actual batch delay, damage_latency)
        self.damage_out_latency = maxdeque(NRECS)       #records how long it took for a damage request to be processed
                                                        #last NRECS: (processed_time, no of pixels, actual batch delay, damage_latency)
        self.damage_send_speed = maxdeque(NRECS)        #how long it took to send damage packets (this is not a sustained speed)
                                                        #last NRECS: (sent_time, no_of_pixels, elapsed_time)
        self.damage_ack_pending = {}                    #records when damage packets are sent
                                                        #so we can calculate the "client_latency" when the client sends
                                                        #the corresponding ack ("damage-sequence" packet - see "client_ack_damage")
        self.encoding_totals = {}                       #for each encoding, how many frames we sent and how many pixels in total
        self.encoding_pending = {}                      #damage regions waiting to be picked up by the encoding thread:
                                                        #for each sequence no: (damage_time, w, h)
        self.last_damage_event_time = None
        self.damage_events_count = 0
        self.packet_count = 0

        #these values are calculated from the values above (see update_averages)
        self.target_latency = self.DEFAULT_TARGET_LATENCY
        self.avg_damage_in_latency = self.DEFAULT_DAMAGE_LATENCY
        self.recent_damage_in_latency = self.DEFAULT_DAMAGE_LATENCY
        self.avg_damage_out_latency = self.DEFAULT_DAMAGE_LATENCY + self.DEFAULT_NETWORK_LATENCY
        self.recent_damage_out_latency = self.DEFAULT_DAMAGE_LATENCY + self.DEFAULT_NETWORK_LATENCY
        self.max_latency = self.DEFAULT_DAMAGE_LATENCY + self.DEFAULT_NETWORK_LATENCY
        self.avg_decode_speed = None
        self.recent_decode_speed = None
        self.avg_send_speed = None
        self.recent_send_speed = None
Esempio n. 4
0
 def video_encoder_cleanup(self):
     """ Video encoders (x264 and vpx) require us to run
         cleanup code to free the memory they use.
     """
     try:
         self._video_encoder_lock.acquire()
         if self._video_encoder:
             self._video_encoder.clean()
             self._video_encoder = None
             self._video_encoder_speed = maxdeque(NRECS)
             self._video_encoder_quality = maxdeque(NRECS)
     finally:
         self._video_encoder_lock.release()
Esempio n. 5
0
 def __init__(self):
     self.always = self.ALWAYS
     self.max_events = self.MAX_EVENTS
     self.max_pixels = self.MAX_PIXELS
     self.time_unit = self.TIME_UNIT
     self.min_delay = self.MIN_DELAY
     self.max_delay = self.MAX_DELAY
     self.delay = self.START_DELAY
     self.recalculate_delay = self.RECALCULATE_DELAY
     self.last_delays = maxdeque(64)                 #the delays we have tried to use (milliseconds)
     self.last_actual_delays = maxdeque(64)          #the delays we actually used (milliseconds)
     self.last_updated = 0
     self.wid = 0
Esempio n. 6
0
    def reset(self):
        # mmap state:
        self.mmap_size = 0
        self.mmap_bytes_sent = 0
        self.mmap_free_size = 0  #how much of the mmap space is left (may be negative if we failed to write the last chunk)
        # queue statistics:
        self.damage_data_qsizes = maxdeque(
            NRECS
        )  #size of the damage_data_queue before we add a new record to it
        #(event_time, size)
        self.damage_packet_qsizes = maxdeque(
            NRECS
        )  #size of the damage_packet_queue before we add a new packet to it
        #(event_time, size)
        self.damage_packet_qpixels = maxdeque(
            NRECS
        )  #number of pixels waiting in the damage_packet_queue for a specific window,
        #before we add a new packet to it
        #(event_time, wid, size)
        self.damage_last_events = maxdeque(
            NRECS)  #records the x11 damage requests as they are received:
        #(wid, event time, no of pixels)
        self.client_decode_time = maxdeque(
            NRECS)  #records how long it took the client to decode frames:
        #(wid, event_time, no of pixels, decoding_time)
        self.min_client_latency = None  #The lowest client latency ever recorded
        self.client_latency = maxdeque(
            NRECS
        )  #how long it took for a packet to get to the client and get the echo back.
        #(wid, event_time, no of pixels, client_latency)

        self.client_ping_latency = maxdeque(NRECS)
        self.server_ping_latency = maxdeque(NRECS)
        self.client_load = None
Esempio n. 7
0
 def __init__(self):
     self.always = self.ALWAYS
     self.max_events = self.MAX_EVENTS
     self.max_pixels = self.MAX_PIXELS
     self.time_unit = self.TIME_UNIT
     self.min_delay = self.MIN_DELAY
     self.max_delay = self.MAX_DELAY
     self.delay = self.START_DELAY
     self.recalculate_delay = self.RECALCULATE_DELAY
     self.last_delays = maxdeque(
         64)  #the delays we have tried to use (milliseconds)
     self.last_actual_delays = maxdeque(
         64)  #the delays we actually used (milliseconds)
     self.last_updated = 0
     self.wid = 0
Esempio n. 8
0
 def reset(self):
     self.client_decode_time = maxdeque(NRECS)       #records how long it took the client to decode frames:
                                                     #(ack_time, no of pixels, decoding_time*1000*1000)
     self.encoding_stats = maxdeque(NRECS)           #encoding: (coding, pixels, compressed_size, encoding_time)
     # statistics:
     self.damage_in_latency = maxdeque(NRECS)        #records how long it took for a damage request to be sent
                                                     #last NRECS: (sent_time, no of pixels, actual batch delay, damage_latency)
     self.damage_out_latency = maxdeque(NRECS)       #records how long it took for a damage request to be processed
                                                     #last NRECS: (processed_time, no of pixels, actual batch delay, damage_latency)
     self.damage_send_speed = maxdeque(NRECS)        #how long it took to send damage packets (this is not a sustained speed)
                                                     #last NRECS: (sent_time, no_of_pixels, elapsed_time)
     self.damage_ack_pending = {}                    #records when damage packets are sent
                                                     #so we can calculate the "client_latency" when the client sends
                                                     #the corresponding ack ("damage-sequence" packet - see "client_ack_damage")
     self.encoding_totals = {}                       #for each encoding, how many frames we sent and how many pixels in total
Esempio n. 9
0
 def __init__(self):
     self.always = self.ALWAYS
     self.max_events = self.MAX_EVENTS
     self.max_pixels = self.MAX_PIXELS
     self.time_unit = self.TIME_UNIT
     self.min_delay = self.MIN_DELAY
     self.max_delay = self.MAX_DELAY
     self.delay = self.START_DELAY
     self.last_delays = maxdeque(64)                 #the delays we have tried to use (milliseconds)
     self.last_actual_delays = maxdeque(64)          #the delays we actually used (milliseconds)
     self.last_updated = 0
     self.wid = 0
     #the metrics derived from statistics which we use for calculating the new batch delay:
     #(see batch delay calculator)
     self.factors = []
Esempio n. 10
0
    def __init__(self, queue_damage, queue_packet, statistics, wid,
                 batch_config, auto_refresh_delay, encoding, encodings,
                 default_damage_options, encoding_client_options,
                 supports_rgb24zlib, uses_swscale, mmap, mmap_size):
        self.queue_damage = queue_damage  #callback to add damage data which is ready to compress to the damage processing queue
        self.queue_packet = queue_packet  #callback to add a network packet to the outgoing queue
        self.wid = wid
        self.global_statistics = statistics  #shared/global statistics from ServerSource
        self.statistics = WindowPerformanceStatistics()
        self.encoding = encoding  #the current encoding
        self.encodings = encodings  #all the encodings supported by the client
        self.default_damage_options = default_damage_options  #default encoding options, like "quality"
        #may change at runtime (ie: see ServerSource.set_quality)
        self.encoding_client_options = encoding_client_options  #does the client support encoding options?
        self.supports_rgb24zlib = supports_rgb24zlib  #supports rgb24 compression outside network layer (unwrapped)
        self.uses_swscale = uses_swscale  #client uses uses_swscale (has extra limits on sizes)
        self.batch_config = batch_config
        #auto-refresh:
        self.auto_refresh_delay = auto_refresh_delay
        self.refresh_timer = None
        self.timeout_timer = None
        self.expire_timer = None

        # mmap:
        self._mmap = mmap
        self._mmap_size = mmap_size
        if self._mmap and self._mmap_size > 0:
            self._mmap_data_start = ctypes.c_uint.from_buffer(self._mmap, 0)
            self._mmap_data_end = ctypes.c_uint.from_buffer(self._mmap, 4)

        # video codecs:
        self._video_encoder = None
        self._video_encoder_lock = Lock(
        )  #to ensure we serialize access to the encoder and its internals
        self._video_encoder_quality = maxdeque(
            NRECS
        )  #keep track of the target encoding_quality: (event time, encoding speed)
        self._video_encoder_speed = maxdeque(
            NRECS
        )  #keep track of the target encoding_speed: (event time, encoding speed)
        # for managing/cancelling damage requests:
        self._damage_delayed = None  #may store a delayed region when batching in progress
        self._damage_delayed_expired = False  #when this is True, the region should have expired
        #but it is now waiting for the backlog to clear
        self._sequence = 1  #increase with every region we process or delay
        self._last_sequence_queued = 0  #the latest sequence we queued for sending (after encoding it)
        self._damage_cancelled = 0  #stores the highest _sequence cancelled
        self._damage_packet_sequence = 1  #increase with every damage packet created
Esempio n. 11
0
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("destroy", self.destroy)
        self.window.set_default_size(540, 800)
        self.window.set_border_width(20)

        # Title
        vbox = gtk.VBox(False, 0)
        vbox.set_spacing(15)
        label = gtk.Label("Keyboard State")
        label.modify_font(pango.FontDescription("sans 13"))
        vbox.pack_start(label)

        self.modifiers = gtk.Label()
        vbox.add(self.modifiers)

        self.mouse = gtk.Label()
        vbox.add(self.mouse)

        self.keys = gtk.Label()
        fixed = pango.FontDescription('monospace 9')
        self.keys.modify_font(fixed)
        vbox.add(self.keys)

        self.window.add(vbox)
        self.window.show_all()
        gobject.timeout_add(100, self.populate_modifiers)

        self.key_events = maxdeque(maxlen=35)
        self.window.connect("key-press-event", self.key_press)
        self.window.connect("key-release-event", self.key_release)
        self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
Esempio n. 12
0
 def __init__(self, client, opts):
     ClientExtrasBase.__init__(self, client, opts)
     self.setup_menu()
     self.setup_tray(opts.tray_icon)
     self.setup_clipboard_helper(ClipboardProtocolHelper)
     self._last_key_events = maxdeque(maxlen=5)
     self._dropped_num_lock_press = False
Esempio n. 13
0
	def	__init__(self):
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.connect("destroy", self.destroy)
		self.window.set_default_size(540, 800)
		self.window.set_border_width(20)

		# Title
		vbox = gtk.VBox(False, 0)
		vbox.set_spacing(15)
		label = gtk.Label("Keyboard State")
		label.modify_font(pango.FontDescription("sans 13"))
		vbox.pack_start(label)
		
		self.modifiers = gtk.Label()
		vbox.add(self.modifiers)

		self.mouse = gtk.Label()
		vbox.add(self.mouse)
		
		self.keys = gtk.Label()
		fixed = pango.FontDescription('monospace 9')
		self.keys.modify_font(fixed)
		vbox.add(self.keys)

		self.window.add(vbox)
		self.window.show_all()
		gobject.timeout_add(100, self.populate_modifiers)

		self.key_events = maxdeque(maxlen=35)
		self.window.connect("key-press-event", self.key_press)
		self.window.connect("key-release-event", self.key_release)
		self.window.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
Esempio n. 14
0
 def __init__(self, client, opts):
     ClientExtrasBase.__init__(self, client, opts)
     self.setup_menu()
     self.setup_tray(opts.tray_icon)
     self.setup_clipboard_helper(ClipboardProtocolHelper)
     self._last_key_events = maxdeque(maxlen=5)
     self._dropped_num_lock_press = False
Esempio n. 15
0
 def __init__(self):
     self.always = self.ALWAYS
     self.max_events = self.MAX_EVENTS
     self.max_pixels = self.MAX_PIXELS
     self.time_unit = self.TIME_UNIT
     self.min_delay = self.MIN_DELAY
     self.max_delay = self.MAX_DELAY
     self.delay = self.START_DELAY
     self.last_delays = maxdeque(
         64)  #the delays we have tried to use (milliseconds)
     self.last_actual_delays = maxdeque(
         64)  #the delays we actually used (milliseconds)
     self.last_updated = 0
     self.wid = 0
     #the metrics derived from statistics which we use for calculating the new batch delay:
     #(see batch delay calculator)
     self.factors = []
Esempio n. 16
0
    def __init__(self):
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.connect("destroy", self.destroy)
        self.window.set_default_size(640, 300)
        self.window.set_border_width(20)

        vbox = gtk.VBox(False, 0)
        vbox.set_spacing(15)

        self.log = maxdeque(maxlen=25)
        for x in range(25):
            self.log.append("")
        self.events = gtk.Label()
        fixed = pango.FontDescription('monospace 9')
        self.events.modify_font(fixed)

        #how many clipboards to show:
        self.clipboards = ["CLIPBOARD", "PRIMARY", "SECONDARY"]
        if sys.platform.startswith("win"):
            self.clipboards = ["CLIPBOARD"]

        tb = TableBuilder()
        table = tb.get_table()
        labels = [label("Selection")]
        labels += [
            label("Value"),
            label("Clear"),
            label("Targets"),
            label("Actions")
        ]
        tb.add_row(*labels)
        for selection in self.clipboards:
            cs = ClipboardInstance(selection, self.add_event)
            get_actions = gtk.HBox()
            for x in (cs.get_get_targets_btn, cs.get_target_btn,
                      cs.get_string_btn):
                get_actions.pack_start(x)
            tb.add_row(label(selection), cs.value_label, cs.clear_label_btn,
                       cs.get_targets, get_actions)
            set_actions = gtk.HBox()
            for x in (cs.set_target_btn, cs.set_string_btn):
                set_actions.pack_start(x)
            tb.add_row(None, cs.value_entry, cs.clear_entry_btn,
                       cs.set_targets, set_actions)
        vbox.pack_start(table)
        vbox.add(self.events)

        self.window.add(vbox)
        self.window.show_all()
        icon = get_icon("clipboard.png")
        if icon:
            self.window.set_icon(icon)
        try:
            self.add_event(
                "ALL", "window=%s, xid=%s" %
                (self.window, hex(self.window.get_window().xid)))
        except:
            self.add_event("ALL", "window=%s" % self.window)
Esempio n. 17
0
    def __init__(self, queue_damage, queue_packet, statistics,
                    wid, batch_config, auto_refresh_delay,
                    encoding, encodings,
                    default_damage_options,
                    encoding_client_options, supports_rgb24zlib, uses_swscale,
                    mmap, mmap_size):
        self.queue_damage = queue_damage                #callback to add damage data which is ready to compress to the damage processing queue
        self.queue_packet = queue_packet                #callback to add a network packet to the outgoing queue
        self.wid = wid
        self.global_statistics = statistics             #shared/global statistics from ServerSource
        self.statistics = WindowPerformanceStatistics()
        self.encoding = encoding                        #the current encoding
        self.encodings = encodings                      #all the encodings supported by the client
        self.default_damage_options = default_damage_options    #default encoding options, like "quality"
                                                        #may change at runtime (ie: see ServerSource.set_quality)
        self.encoding_client_options = encoding_client_options  #does the client support encoding options?
        self.supports_rgb24zlib = supports_rgb24zlib    #supports rgb24 compression outside network layer (unwrapped)
        self.uses_swscale = uses_swscale                #client uses uses_swscale (has extra limits on sizes)
        self.batch_config = batch_config
        #auto-refresh:
        self.auto_refresh_delay = auto_refresh_delay
        self.refresh_timer = None
        self.timeout_timer = None
        self.expire_timer = None

        # mmap:
        self._mmap = mmap
        self._mmap_size = mmap_size
        if self._mmap and self._mmap_size>0:
            self._mmap_data_start = ctypes.c_uint.from_buffer(self._mmap, 0)
            self._mmap_data_end = ctypes.c_uint.from_buffer(self._mmap, 4)

        # video codecs:
        self._video_encoder = None
        self._video_encoder_lock = Lock()               #to ensure we serialize access to the encoder and its internals
        self._video_encoder_quality = maxdeque(NRECS)   #keep track of the target encoding_quality: (event time, encoding speed)
        self._video_encoder_speed = maxdeque(NRECS)     #keep track of the target encoding_speed: (event time, encoding speed)
        # for managing/cancelling damage requests:
        self._damage_delayed = None                     #may store a delayed region when batching in progress
        self._damage_delayed_expired = False            #when this is True, the region should have expired
                                                        #but it is now waiting for the backlog to clear
        self._sequence = 1                              #increase with every region we process or delay
        self._last_sequence_queued = 0                  #the latest sequence we queued for sending (after encoding it)
        self._damage_cancelled = 0                      #stores the highest _sequence cancelled
        self._damage_packet_sequence = 1                #increase with every damage packet created
Esempio n. 18
0
 def __init__(self, *args):
     log.info("DebugInfoClientWindow.__init__(%s)", args)
     TopBarClientWindow.__init__(self, *args)
     if self._has_custom_decorations:
         self.log_buffer = maxdeque(100)
         self.capture_log = True
         self.debug = lambda *x: self._add_log_event("debug", *x)
         self.info = lambda *x: self._add_log_event("info", *x)
         self.warn = lambda *x: self._add_log_event("warn", *x)
         self.error = lambda *x: self._add_log_event("error", *x)
Esempio n. 19
0
 def __init__(self, *args):
     log.info("DebugInfoClientWindow.__init__(%s)", args)
     TopBarClientWindow.__init__(self, *args)
     if self._has_custom_decorations:
         self.log_buffer = maxdeque(100)
         self.capture_log = True
         self.debug = lambda *x : self._add_log_event("debug", *x)
         self.info = lambda *x : self._add_log_event("info", *x)
         self.warn = lambda *x : self._add_log_event("warn", *x)
         self.error = lambda *x : self._add_log_event("error", *x)
Esempio n. 20
0
    def reset(self):
        self.client_decode_time = maxdeque(
            NRECS)  #records how long it took the client to decode frames:
        #(ack_time, no of pixels, decoding_time*1000*1000)
        self.encoding_stats = maxdeque(
            NRECS
        )  #encoding: (coding, pixels, bpp, compressed_size, encoding_time)
        # statistics:
        self.damage_in_latency = maxdeque(
            NRECS)  #records how long it took for a damage request to be sent
        #last NRECS: (sent_time, no of pixels, actual batch delay, damage_latency)
        self.damage_out_latency = maxdeque(
            NRECS
        )  #records how long it took for a damage request to be processed
        #last NRECS: (processed_time, no of pixels, actual batch delay, damage_latency)
        self.damage_send_speed = maxdeque(
            NRECS
        )  #how long it took to send damage packets (this is not a sustained speed)
        #last NRECS: (sent_time, no_of_pixels, elapsed_time)
        self.damage_ack_pending = {}  #records when damage packets are sent
        #so we can calculate the "client_latency" when the client sends
        #the corresponding ack ("damage-sequence" packet - see "client_ack_damage")
        self.encoding_totals = {
        }  #for each encoding, how many frames we sent and how many pixels in total
        self.encoding_pending = {
        }  #damage regions waiting to be picked up by the encoding thread:
        #for each sequence no: (damage_time, w, h)
        self.last_damage_event_time = None
        self.damage_events_count = 0
        self.packet_count = 0

        #these values are calculated from the values above (see update_averages)
        self.target_latency = self.DEFAULT_TARGET_LATENCY
        self.avg_damage_in_latency = self.DEFAULT_DAMAGE_LATENCY
        self.recent_damage_in_latency = self.DEFAULT_DAMAGE_LATENCY
        self.avg_damage_out_latency = self.DEFAULT_DAMAGE_LATENCY + self.DEFAULT_NETWORK_LATENCY
        self.recent_damage_out_latency = self.DEFAULT_DAMAGE_LATENCY + self.DEFAULT_NETWORK_LATENCY
        self.max_latency = self.DEFAULT_DAMAGE_LATENCY + self.DEFAULT_NETWORK_LATENCY
        self.avg_decode_speed = None
        self.recent_decode_speed = None
        self.avg_send_speed = None
        self.recent_send_speed = None
Esempio n. 21
0
 def init_context(self, width, height, src_format, encoding, quality, speed, scaling, options):
     self.encoding = encoding
     self.width = width
     self.height = height
     self.quality = quality
     self.speed = speed
     self.scaling = scaling
     self.src_format = src_format
     self.last_frame_times = maxdeque(200)
     self.frames = 0
     self.time = 0
Esempio n. 22
0
 def __init__(self):
     self.enabled = self.ENABLED
     self.always = self.ALWAYS
     self.max_events = self.MAX_EVENTS
     self.max_pixels = self.MAX_PIXELS
     self.time_unit = self.TIME_UNIT
     self.min_delay = self.MIN_DELAY
     self.max_delay = self.MAX_DELAY
     self.delay = self.START_DELAY
     self.recalculate_delay = self.RECALCULATE_DELAY
     self.last_delays = maxdeque(64)
     self.last_updated = 0
     self.wid = 0
Esempio n. 23
0
 def reset(self):
     # mmap state:
     self.mmap_size = 0
     self.mmap_bytes_sent = 0
     self.mmap_free_size = 0  #how much of the mmap space is left (may be negative if we failed to write the last chunk)
     # queue statistics:
     self.damage_data_qsizes = maxdeque(
         NRECS
     )  #size of the damage_data_queue before we add a new record to it
     #(event_time, size)
     self.damage_packet_qsizes = maxdeque(
         NRECS
     )  #size of the damage_packet_queue before we add a new packet to it
     #(event_time, size)
     self.damage_packet_qpixels = maxdeque(
         NRECS
     )  #number of pixels waiting in the damage_packet_queue for a specific window,
     #before we add a new packet to it
     #(event_time, wid, size)
     self.damage_last_events = maxdeque(
         NRECS)  #records the x11 damage requests as they are received:
     #(wid, event time, no of pixels)
     self.client_decode_time = maxdeque(
         NRECS)  #records how long it took the client to decode frames:
     #(wid, event_time, no of pixels, decoding_time*1000*1000)
     self.client_latency = maxdeque(
         NRECS
     )  #how long it took for a packet to get to the client and get the echo back.
     #(wid, event_time, no of pixels, client_latency)
     self.client_ping_latency = maxdeque(
         NRECS)  #time it took to get a ping_echo back from the client:
     #(event_time, elapsed_time_in_seconds)
     self.server_ping_latency = maxdeque(
         NRECS
     )  #time it took for the client to get a ping_echo back from us:
     #(event_time, elapsed_time_in_seconds)
     self.client_load = None
     self.damage_events_count = 0
     self.packet_count = 0
     #these values are calculated from the values above (see update_averages)
     self.min_client_latency = self.DEFAULT_LATENCY
     self.avg_client_latency = self.DEFAULT_LATENCY
     self.recent_client_latency = self.DEFAULT_LATENCY
     self.min_client_ping_latency = self.DEFAULT_LATENCY
     self.avg_client_ping_latency = self.DEFAULT_LATENCY
     self.recent_client_ping_latency = self.DEFAULT_LATENCY
     self.min_server_ping_latency = self.DEFAULT_LATENCY
     self.avg_server_ping_latency = self.DEFAULT_LATENCY
     self.recent_server_ping_latency = self.DEFAULT_LATENCY
Esempio n. 24
0
 def reset(self):
     self.client_decode_time = maxdeque(
         NRECS
     )  #records how long it took the client to decode frames: (ack_time, no of pixels, decoding_time)
     self.encoding_stats = maxdeque(
         NRECS)  #encoding: (coding, pixels, compressed_size, encoding_time)
     # statistics:
     self.damage_in_latency = maxdeque(
         NRECS)  #records how long it took for a damage request to be sent
     #last NRECS: (sent_time, no of pixels, actual batch delay, damage_latency)
     self.damage_out_latency = maxdeque(
         NRECS
     )  #records how long it took for a damage request to be processed
     #last NRECS: (processed_time, no of pixels, actual batch delay, damage_latency)
     self.damage_send_speed = maxdeque(
         NRECS
     )  #how long it took to send damage packets (this is not a sustained speed)
     #last NRECS: (sent_time, no_of_pixels, elapsed_time)
     self.damage_ack_pending = {}  #records when damage packets are sent
     #so we can calculate the "client_latency" when the client sends
     #the corresponding ack ("damage-sequence" packet - see "client_ack_damage")
     self.last_packet_send_stats = None  #used by _damage_send_speed
     self.last_client_delta = 0, 0  #records how far behind the client was last time we checked
Esempio n. 25
0
 def reset(self):
     self.client_decode_time = maxdeque(
         NRECS)  #records how long it took the client to decode frames:
     #(ack_time, no of pixels, decoding_time*1000*1000)
     self.encoding_stats = maxdeque(
         NRECS)  #encoding: (coding, pixels, compressed_size, encoding_time)
     # statistics:
     self.damage_in_latency = maxdeque(
         NRECS)  #records how long it took for a damage request to be sent
     #last NRECS: (sent_time, no of pixels, actual batch delay, damage_latency)
     self.damage_out_latency = maxdeque(
         NRECS
     )  #records how long it took for a damage request to be processed
     #last NRECS: (processed_time, no of pixels, actual batch delay, damage_latency)
     self.damage_send_speed = maxdeque(
         NRECS
     )  #how long it took to send damage packets (this is not a sustained speed)
     #last NRECS: (sent_time, no_of_pixels, elapsed_time)
     self.damage_ack_pending = {}  #records when damage packets are sent
     #so we can calculate the "client_latency" when the client sends
     #the corresponding ack ("damage-sequence" packet - see "client_ack_damage")
     self.encoding_totals = {
     }  #for each encoding, how many frames we sent and how many pixels in total
Esempio n. 26
0
 def __init__(self, menu, tooltip, icon_filename, size_changed_cb, click_cb, mouseover_cb, exit_cb):
     self.menu = menu
     self.tooltip = tooltip
     self.size_changed_cb = size_changed_cb
     self.click_cb = click_cb
     self.mouseover_cb = mouseover_cb
     self.exit_cb = exit_cb
     self.tray_widget = None
     self.default_icon_filename = icon_filename
     self.default_icon_extension = "png"
     self.default_icon_name = "xpra.png"
     #some implementations need this for guessing the geometry (see recalculate_geometry):
     self.geometry_guess = None
     self.tray_event_locations = maxdeque(512)
Esempio n. 27
0
class ClientExtras(ClientExtrasBase):
    def __init__(self, client, opts):
        ClientExtrasBase.__init__(self, client, opts)
        try:
            from xpra.platform.gdk_clipboard import TranslatedClipboardProtocolHelper
            self.setup_clipboard_helper(TranslatedClipboardProtocolHelper)
        except ImportError, e:
            log.error(
                "GDK Translated Clipboard failed to load: %s - using default fallback",
                e)
            self.setup_clipboard_helper(DefaultClipboardProtocolHelper)
        self.setup_menu()
        self.setup_tray(opts.no_tray, opts.notifications, opts.tray_icon)
        self._last_key_events = maxdeque(maxlen=5)
Esempio n. 28
0
 def __init__(self, menu, tooltip, icon_filename, size_changed_cb, click_cb,
              mouseover_cb, exit_cb):
     self.menu = menu
     self.tooltip = tooltip
     self.size_changed_cb = size_changed_cb
     self.click_cb = click_cb
     self.mouseover_cb = mouseover_cb
     self.exit_cb = exit_cb
     self.tray_widget = None
     self.default_icon_filename = icon_filename
     self.default_icon_extension = "png"
     self.default_icon_name = "xpra.png"
     #some implementations need this for guessing the geometry (see recalculate_geometry):
     self.geometry_guess = None
     self.tray_event_locations = maxdeque(512)
Esempio n. 29
0
	def	__init__(self):
		self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
		self.window.connect("destroy", self.destroy)
		self.window.set_default_size(640, 300)
		self.window.set_border_width(20)

		vbox = gtk.VBox(False, 0)
		vbox.set_spacing(15)

		self.log = maxdeque(maxlen=25)
		for x in range(25):
			self.log.append("")
		self.events = gtk.Label()
		fixed = pango.FontDescription('monospace 9')
		self.events.modify_font(fixed)

		#how many clipboards to show:
		self.clipboards = ["CLIPBOARD", "PRIMARY", "SECONDARY"]
		if sys.platform.startswith("win"):
			self.clipboards = ["CLIPBOARD"]

		tb = TableBuilder()
		table = tb.get_table()
		labels = [label("Selection")]
		labels += [label("Value"), label("Clear"), label("Targets"), label("Actions")]
		tb.add_row(*labels)
		for selection in self.clipboards:
			cs = ClipboardInstance(selection, self.add_event)
			get_actions = gtk.HBox()
			for x in (cs.get_get_targets_btn, cs.get_target_btn, cs.get_string_btn):
				get_actions.pack_start(x)
			tb.add_row(label(selection), cs.value_label, cs.clear_label_btn, cs.get_targets, get_actions)
			set_actions = gtk.HBox()
			for x in (cs.set_target_btn, cs.set_string_btn):
				set_actions.pack_start(x)
			tb.add_row(None, cs.value_entry, cs.clear_entry_btn, cs.set_targets, set_actions)
		vbox.pack_start(table)
		vbox.add(self.events)

		self.window.add(vbox)
		self.window.show_all()
		icon = get_icon("clipboard.png")
		if icon:
			self.window.set_icon(icon)
		try:
			self.add_event("ALL", "window=%s, xid=%s" % (self.window, hex(self.window.get_window().xid)))
		except:
			self.add_event("ALL", "window=%s" % self.window)
Esempio n. 30
0
 def reset(self):
     # mmap state:
     self.mmap_size = 0
     self.mmap_bytes_sent = 0
     self.mmap_free_size = 0  #how much of the mmap space is left (may be negative if we failed to write the last chunk)
     # queue statistics:
     self.damage_data_qsizes = maxdeque(
         NRECS
     )  #size of the damage_data_queue before we add a new record to it
     #(event_time, size)
     self.damage_packet_qsizes = maxdeque(
         NRECS
     )  #size of the damage_packet_queue before we add a new packet to it
     #(event_time, size)
     self.damage_packet_qpixels = maxdeque(
         NRECS
     )  #number of pixels waiting in the damage_packet_queue for a specific window,
     #before we add a new packet to it
     #(event_time, wid, size)
     self.damage_last_events = maxdeque(
         NRECS)  #records the x11 damage requests as they are received:
     #(wid, event time, no of pixels)
     self.client_decode_time = maxdeque(
         NRECS)  #records how long it took the client to decode frames:
     #(wid, event_time, no of pixels, decoding_time*1000*1000)
     self.min_client_latency = None  #The lowest client latency ever recorded: the time it took
     #from the moment the damage packet got sent until we got the ack packet
     #(but not including time spent decoding on the client)
     self.client_latency = maxdeque(
         NRECS
     )  #how long it took for a packet to get to the client and get the echo back.
     #(wid, event_time, no of pixels, client_latency)
     self.avg_client_latency = None
     self.client_ping_latency = maxdeque(
         NRECS)  #time it took to get a ping_echo back from the client:
     #(event_time, elapsed_time_in_seconds)
     self.server_ping_latency = maxdeque(
         NRECS
     )  #time it took for the client to get a ping_echo back from us:
     #(event_time, elapsed_time_in_seconds)
     self.client_load = None
Esempio n. 31
0
    def reset(self):
        # mmap state:
        self.mmap_size = 0
        self.mmap_bytes_sent = 0
        self.mmap_free_size = 0                        #how much of the mmap space is left (may be negative if we failed to write the last chunk)
        # queue statistics:
        self.damage_data_qsizes = maxdeque(NRECS)       #size of the damage_data_queue before we add a new record to it
                                                        #(event_time, size)
        self.damage_packet_qsizes = maxdeque(NRECS)     #size of the damage_packet_queue before we add a new packet to it
                                                        #(event_time, size)
        self.damage_packet_qpixels = maxdeque(NRECS)    #number of pixels waiting in the damage_packet_queue for a specific window,
                                                        #before we add a new packet to it
                                                        #(event_time, wid, size)
        self.damage_last_events = maxdeque(NRECS)       #records the x11 damage requests as they are received:
                                                        #(wid, event time, no of pixels)
        self.client_decode_time = maxdeque(NRECS)       #records how long it took the client to decode frames:
                                                        #(wid, event_time, no of pixels, decoding_time)
        self.min_client_latency = None                  #The lowest client latency ever recorded
        self.client_latency = maxdeque(NRECS)           #how long it took for a packet to get to the client and get the echo back.
                                                        #(wid, event_time, no of pixels, client_latency)

        self.client_ping_latency = maxdeque(NRECS)
        self.server_ping_latency = maxdeque(NRECS)
        self.client_load = None
Esempio n. 32
0
 def reset(self):
     # mmap state:
     self.mmap_size = 0
     self.mmap_bytes_sent = 0
     self.mmap_free_size = 0                         #how much of the mmap space is left (may be negative if we failed to write the last chunk)
     # queue statistics:
     self.damage_data_qsizes = maxdeque(NRECS)       #size of the damage_data_queue before we add a new record to it
                                                     #(event_time, size)
     self.damage_packet_qsizes = maxdeque(NRECS)     #size of the damage_packet_queue before we add a new packet to it
                                                     #(event_time, size)
     self.damage_packet_qpixels = maxdeque(NRECS)    #number of pixels waiting in the damage_packet_queue for a specific window,
                                                     #before we add a new packet to it
                                                     #(event_time, wid, size)
     self.damage_last_events = maxdeque(NRECS)       #records the x11 damage requests as they are received:
                                                     #(wid, event time, no of pixels)
     self.client_decode_time = maxdeque(NRECS)       #records how long it took the client to decode frames:
                                                     #(wid, event_time, no of pixels, decoding_time*1000*1000)
     self.client_latency = maxdeque(NRECS)           #how long it took for a packet to get to the client and get the echo back.
                                                     #(wid, event_time, no of pixels, client_latency)
     self.client_ping_latency = maxdeque(NRECS)      #time it took to get a ping_echo back from the client:
                                                     #(event_time, elapsed_time_in_seconds)
     self.server_ping_latency = maxdeque(NRECS)      #time it took for the client to get a ping_echo back from us:
                                                     #(event_time, elapsed_time_in_seconds)
     self.client_load = None
     self.damage_events_count = 0
     self.packet_count = 0
     #these values are calculated from the values above (see update_averages)
     self.min_client_latency = self.DEFAULT_LATENCY
     self.avg_client_latency = self.DEFAULT_LATENCY
     self.recent_client_latency = self.DEFAULT_LATENCY
     self.min_client_ping_latency = self.DEFAULT_LATENCY
     self.avg_client_ping_latency = self.DEFAULT_LATENCY
     self.recent_client_ping_latency = self.DEFAULT_LATENCY
     self.min_server_ping_latency = self.DEFAULT_LATENCY
     self.avg_server_ping_latency = self.DEFAULT_LATENCY
     self.recent_server_ping_latency = self.DEFAULT_LATENCY
Esempio n. 33
0
 def do_video_encoder_cleanup(self):
     self._video_encoder.clean()
     self._video_encoder = None
     self._video_encoder_speed = maxdeque(NRECS)
     self._video_encoder_quality = maxdeque(NRECS)
Esempio n. 34
0
 def init_counters(self):
     self.avg_batch_delay = maxdeque(N_SAMPLES+4)
     self.avg_damage_out_latency = maxdeque(N_SAMPLES+4)
     self.avg_ping_latency = maxdeque(N_SAMPLES+4)
     self.avg_decoding_latency = maxdeque(N_SAMPLES+4)
     self.avg_total = maxdeque(N_SAMPLES+4)
Esempio n. 35
0
    def __init__(self, conn, opts):
        XpraClientBase.__init__(self, opts)
        self.start_time = time.time()
        self._window_to_id = {}
        self._id_to_window = {}
        self.title = opts.title
        self.readonly = opts.readonly
        self.session_name = opts.session_name
        self.compression_level = opts.compression_level
        self.auto_refresh_delay = opts.auto_refresh_delay
        self.max_bandwidth = opts.max_bandwidth
        if self.max_bandwidth > 0.0 and self.jpegquality == 0:
            """ jpegquality was not set, use a better start value """
            self.jpegquality = 50

        self.mmap_enabled = False
        self.server_start_time = -1
        self.server_platform = ""
        self.server_actual_desktop_size = None
        self.server_randr = False
        self.pixel_counter = maxdeque(maxlen=100)
        self.server_latency = maxdeque(maxlen=100)
        self.server_load = None
        self.client_latency = maxdeque(maxlen=100)
        self.toggle_cursors_bell_notify = False
        self.toggle_keyboard_sync = False
        self.bell_enabled = True
        self.cursors_enabled = True
        self.notifications_enabled = True
        self.clipboard_enabled = False
        self.window_configure = False
        self.mmap = None
        self.mmap_token = None
        self.mmap_file = None
        self.mmap_size = 0
        self.last_ping_echoed_time = 0

        self._client_extras = ClientExtras(self, opts)
        self.clipboard_enabled = not self.readonly and opts.clipboard and self._client_extras.supports_clipboard(
        )
        self.supports_mmap = opts.mmap and (
            "rgb24" in ENCODINGS) and self._client_extras.supports_mmap()
        if self.supports_mmap:
            try:
                import mmap
                import tempfile
                import uuid
                from stat import S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP
                mmap_dir = os.getenv("TMPDIR", "/tmp")
                if not os.path.exists(mmap_dir):
                    raise Exception("TMPDIR %s does not exist!" % mmap_dir)
                #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures
                #that the file is readable and writable only by the creating user ID
                temp = tempfile.NamedTemporaryFile(prefix="xpra.",
                                                   suffix=".mmap",
                                                   dir=mmap_dir)
                #keep a reference to it so it does not disappear!
                self._mmap_temp_file = temp
                self.mmap_file = temp.name
                fd = temp.file.fileno()
                #set the group permissions and gid if the mmap-group option is specified
                if opts.mmap_group and type(
                        conn.target) == str and os.path.exists(conn.target):
                    s = os.stat(conn.target)
                    os.fchown(fd, -1, s.st_gid)
                    os.fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)
                self.mmap_size = max(
                    4096, mmap.PAGESIZE) * 32 * 1024  #generally 128MB
                log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd,
                    self.mmap_size)
                os.lseek(fd, self.mmap_size - 1, os.SEEK_SET)
                assert os.write(fd, '\x00')
                os.lseek(fd, 0, os.SEEK_SET)
                self.mmap = mmap.mmap(fd, length=self.mmap_size)
                #write the 16 byte token one byte at a time - no endianness
                self.mmap_token = uuid.uuid4().int
                log.debug("mmap_token=%s", self.mmap_token)
                v = self.mmap_token
                for i in range(0, 16):
                    poke = ctypes.c_ubyte.from_buffer(self.mmap, 512 + i)
                    poke.value = v % 256
                    v = v >> 8
                assert v == 0
            except Exception, e:
                log.error("failed to setup mmap: %s", e)
                self.supports_mmap = False
                self.clean_mmap()
                self.mmap = None
                self.mmap_file = None
                self.mmap_size = 0
Esempio n. 36
0
    def __init__(self, client, session_name, window_icon_pixbuf, conn,
                 get_pixbuf):
        gtk.Window.__init__(self)
        self.client = client
        self.session_name = session_name
        self.connection = conn
        self.last_populate_time = 0
        self.last_populate_statistics = 0
        self.is_closed = False
        self.get_pixbuf = get_pixbuf
        self.set_title(self.session_name or "Session Info")
        self.set_destroy_with_parent(True)
        self.set_resizable(True)
        self.set_decorated(True)
        if window_icon_pixbuf:
            self.set_icon(window_icon_pixbuf)
        if is_gtk3():
            self.set_position(gtk.WindowPosition.CENTER)
        else:
            self.set_position(gtk.WIN_POS_CENTER)

        #tables on the left in a vbox with buttons at the top:
        self.tab_box = gtk.VBox(False, 0)
        self.tab_button_box = gtk.HBox(True, 0)
        self.tabs = []  #pairs of button, table
        self.populate_cb = None
        self.tab_box.pack_start(self.tab_button_box,
                                expand=False,
                                fill=True,
                                padding=0)

        #Package Table:
        tb = self.table_tab("package.png", "Software", self.populate_package)
        #title row:
        tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Client"),
                  1,
                  xoptions=gtk.EXPAND | gtk.FILL,
                  xpadding=0)
        tb.attach(title_box("Server"),
                  2,
                  xoptions=gtk.EXPAND | gtk.FILL,
                  xpadding=0)
        tb.inc()

        scaps = self.client.server_capabilities
        from xpra.__init__ import __version__
        tb.new_row("Xpra", label(__version__),
                   label(self.client._remote_version or "unknown"))
        cl_rev, cl_ch, cl_date = "unknown", "", ""
        try:
            from xpra.build_info import BUILD_DATE as cl_date, REVISION as cl_rev, LOCAL_MODIFICATIONS as cl_ch
        except:
            pass
        tb.new_row("Revision", label(cl_rev),
                   label(self.client._remote_revision or "unknown"))
        tb.new_row("Local Changes", label(cl_ch),
                   label(scaps.get("local_modifications", "unknown")))
        tb.new_row("Build date", label(cl_date),
                   label(scaps.get("build_date", "unknown")))

        def make_version_str(version):
            if version and type(version) in (tuple, list):
                version = ".".join([str(x) for x in version])
            return version or "unknown"

        def server_version_info(prop_name):
            return make_version_str(scaps.get(prop_name))

        def client_version_info(prop_name):
            info = "unknown"
            if hasattr(gtk, prop_name):
                info = make_version_str(getattr(gtk, prop_name))
            return info

        if is_gtk3():
            tb.new_row("PyGobject", label(gobject._version))
            tb.new_row("Client GDK", label(gdk._version))
            tb.new_row("GTK", label(gtk._version),
                       label(server_version_info("gtk_version")))
        else:
            tb.new_row("PyGTK", label(client_version_info("pygtk_version")),
                       label(server_version_info("pygtk_version")))
            tb.new_row("GTK", label(client_version_info("gtk_version")),
                       label(server_version_info("gtk_version")))
        tb.new_row("Python", label(platform.python_version()),
                   label(server_version_info("python_version")))
        cl_gst_v, cl_pygst_v = "", ""
        from xpra.scripts.main import HAS_SOUND
        if HAS_SOUND:
            try:
                from xpra.sound.gstreamer_util import gst_version as cl_gst_v, pygst_version as cl_pygst_v
            except:
                pass
        tb.new_row("GStreamer", label(make_version_str(cl_gst_v)),
                   label(server_version_info("gst_version")))
        tb.new_row("pygst", label(make_version_str(cl_pygst_v)),
                   label(server_version_info("pygst_version")))
        tb.new_row(
            "OpenGL",
            label(
                make_version_str(self.client.opengl_props.get("opengl",
                                                              "n/a"))),
            label("n/a"))
        tb.new_row(
            "OpenGL Vendor",
            label(make_version_str(self.client.opengl_props.get("vendor",
                                                                ""))),
            label("n/a"))
        tb.new_row(
            "PyOpenGL",
            label(
                make_version_str(
                    self.client.opengl_props.get("pyopengl", "n/a"))),
            label("n/a"))

        # Features Table:
        tb = self.table_tab("features.png", "Features", self.populate_features)
        randr_box = gtk.HBox(False, 20)
        self.server_randr_label = label()
        self.server_randr_icon = gtk.Image()
        randr_box.add(self.server_randr_icon)
        randr_box.add(self.server_randr_label)
        tb.new_row("RandR Support", randr_box)
        self.server_encodings_label = label()
        tb.new_row("Server Encodings", self.server_encodings_label)
        self.client_encodings_label = label()
        tb.new_row("Client Encodings", self.client_encodings_label)
        self.server_mmap_icon = gtk.Image()
        tb.new_row("Memory Mapped Transfers", self.server_mmap_icon)
        self.server_clipboard_icon = gtk.Image()
        tb.new_row("Clipboard", self.server_clipboard_icon)
        self.server_notifications_icon = gtk.Image()
        tb.new_row("Notification Forwarding", self.server_notifications_icon)
        self.server_bell_icon = gtk.Image()
        tb.new_row("Bell Forwarding", self.server_bell_icon)
        self.server_cursors_icon = gtk.Image()
        tb.new_row("Cursor Forwarding", self.server_cursors_icon)
        speaker_box = gtk.HBox(False, 20)
        self.server_speaker_icon = gtk.Image()
        speaker_box.add(self.server_speaker_icon)
        self.speaker_codec_label = label()
        speaker_box.add(self.speaker_codec_label)
        tb.new_row("Speaker Forwarding", speaker_box)
        self.server_speaker_codecs_label = label()
        tb.new_row("Server Codecs", self.server_speaker_codecs_label)
        self.client_speaker_codecs_label = label()
        tb.new_row("Client Codecs", self.client_speaker_codecs_label)
        microphone_box = gtk.HBox(False, 20)
        self.server_microphone_icon = gtk.Image()
        microphone_box.add(self.server_microphone_icon)
        self.microphone_codec_label = label()
        microphone_box.add(self.microphone_codec_label)
        tb.new_row("Microphone Forwarding", microphone_box)
        self.server_microphone_codecs_label = label()
        tb.new_row("Server Codecs", self.server_microphone_codecs_label)
        self.client_microphone_codecs_label = label()
        tb.new_row("Client Codecs", self.client_microphone_codecs_label)

        # Connection Table:
        tb = self.table_tab("connect.png", "Connection",
                            self.populate_connection)
        tb.new_row("Server Endpoint", label(self.connection.target))
        if self.client.server_display:
            tb.new_row("Server Display", label(self.client.server_display))
        if "hostname" in scaps:
            tb.new_row("Server Hostname", label(scaps.get("hostname")))
        if self.client.server_platform:
            tb.new_row("Server Platform", label(self.client.server_platform))
        self.server_load_label = label()
        tb.new_row("Server Load",
                   self.server_load_label,
                   label_text="Average over 1, 5 and 15 minutes")
        self.session_started_label = label()
        tb.new_row("Session Started", self.session_started_label)
        self.session_connected_label = label()
        tb.new_row("Session Connected", self.session_connected_label)
        self.input_packets_label = label()
        tb.new_row("Packets Received", self.input_packets_label)
        self.input_bytes_label = label()
        tb.new_row("Bytes Received", self.input_bytes_label)
        self.output_packets_label = label()
        tb.new_row("Packets Sent", self.output_packets_label)
        self.output_bytes_label = label()
        tb.new_row("Bytes Sent", self.output_bytes_label)
        self.compression_label = label()
        tb.new_row("Compression Level", self.compression_label)
        self.connection_type_label = label()
        tb.new_row("Connection Type", self.connection_type_label)
        self.input_encryption_label = label()
        tb.new_row("Input Encryption", self.input_encryption_label)
        self.output_encryption_label = label()
        tb.new_row("Output Encryption", self.output_encryption_label)

        # Details:
        tb = self.table_tab("browse.png", "Statistics",
                            self.populate_statistics)
        tb.widget_xalign = 1.0
        tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Latest"),
                  1,
                  xoptions=gtk.EXPAND | gtk.FILL,
                  xpadding=0)
        tb.attach(title_box("Minimum"),
                  2,
                  xoptions=gtk.EXPAND | gtk.FILL,
                  xpadding=0)
        tb.attach(title_box("Average"),
                  3,
                  xoptions=gtk.EXPAND | gtk.FILL,
                  xpadding=0)
        tb.attach(title_box("90 percentile"),
                  4,
                  xoptions=gtk.EXPAND | gtk.FILL,
                  xpadding=0)
        tb.attach(title_box("Maximum"),
                  5,
                  xoptions=gtk.EXPAND | gtk.FILL,
                  xpadding=0)
        tb.inc()

        def maths_labels():
            return label(), label(), label(), label(), label()

        self.server_latency_labels = maths_labels()
        tb.add_row(label("Server Latency (ms)"), *self.server_latency_labels)
        self.client_latency_labels = maths_labels()
        tb.add_row(label("Client Latency (ms)"), *self.client_latency_labels)
        if self.client.windows_enabled:
            if self.client.server_info_request:
                self.batch_labels = maths_labels()
                tb.add_row(label("Batch Delay (ms)"), *self.batch_labels)
                self.damage_labels = maths_labels()
                tb.add_row(label("Damage Latency (ms)"), *self.damage_labels)

            self.regions_per_second_labels = maths_labels()
            tb.add_row(label("Regions/s"), *self.regions_per_second_labels)
            self.regions_sizes_labels = maths_labels()
            tb.add_row(label("Pixels/region"), *self.regions_sizes_labels)
            self.pixels_per_second_labels = maths_labels()
            tb.add_row(label("Pixels/s"), *self.pixels_per_second_labels)

            self.windows_managed_label = label()
            tb.new_row("Regular Windows", self.windows_managed_label),
            self.transient_managed_label = label()
            tb.new_row("Transient Windows", self.transient_managed_label),
            self.trays_managed_label = label()
            tb.new_row("Trays Managed", self.trays_managed_label),
            if self.client.opengl_enabled:
                self.opengl_label = label()
                tb.new_row("OpenGL Windows", self.opengl_label),

        self.graph_box = gtk.VBox(False, 10)
        self.add_tab("statistics.png", "Graphs", self.populate_graphs,
                     self.graph_box)
        bandwidth_label = "Number of bytes measured by the networks sockets"
        if SHOW_PIXEL_STATS:
            bandwidth_label += ",\nand number of pixels rendered"
        self.bandwidth_graph = self.add_graph_button(bandwidth_label,
                                                     self.save_graphs)
        self.latency_graph = self.add_graph_button(
            "The time it takes to send an echo packet and get the reply",
            self.save_graphs)
        self.pixel_in_data = maxdeque(N_SAMPLES + 4)
        self.net_in_data = maxdeque(N_SAMPLES + 4)
        self.net_out_data = maxdeque(N_SAMPLES + 4)

        self.set_border_width(15)
        self.add(self.tab_box)
        if not is_gtk3():
            self.set_geometry_hints(self.tab_box)

        def window_deleted(*args):
            self.is_closed = True

        self.connect('delete_event', window_deleted)
        self.show_tab(self.tabs[0][1])
        self.set_size_request(-1, 480)
        self.populate()
        self.populate_all()
        gobject.timeout_add(1000, self.populate)
        gobject.timeout_add(100, self.populate_tab)
        self.connect("realize", self.populate_graphs)
        add_close_accel(self, self.destroy)
Esempio n. 37
0
    def __init__(self, conn, opts):
        XpraClientBase.__init__(self, opts)
        self.start_time = time.time()
        self._window_to_id = {}
        self._id_to_window = {}
        title = opts.title
        if opts.title_suffix is not None:
            title = "@title@ %s" % opts.title_suffix
        self.title = title
        self.readonly = opts.readonly
        self.session_name = opts.session_name
        self.compression_level = opts.compression_level
        self.auto_refresh_delay = opts.auto_refresh_delay
        self.max_bandwidth = opts.max_bandwidth
        if self.max_bandwidth>0.0 and self.jpegquality==0:
            """ jpegquality was not set, use a better start value """
            self.jpegquality = 50

        self.server_capabilities = {}

        self.mmap_enabled = False
        self.server_start_time = -1
        self.server_platform = ""
        self.server_actual_desktop_size = None
        self.server_desktop_size = None
        self.server_randr = False
        self.pixel_counter = maxdeque(maxlen=100)
        self.server_latency = maxdeque(maxlen=100)
        self.server_load = None
        self.client_latency = maxdeque(maxlen=100)
        self.toggle_cursors_bell_notify = False
        self.bell_enabled = True
        self.cursors_enabled = True
        self.notifications_enabled = True
        self.clipboard_enabled = False
        self.mmap = None
        self.mmap_token = None
        self.mmap_file = None
        self.mmap_size = 0

        self._client_extras = ClientExtras(self, opts)
        self.clipboard_enabled = not self.readonly and opts.clipboard and self._client_extras.supports_clipboard()
        self.supports_mmap = opts.mmap and ("rgb24" in ENCODINGS) and self._client_extras.supports_mmap()
        if self.supports_mmap:
            try:
                import mmap
                import tempfile
                import uuid
                from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP
                mmap_dir = os.getenv("TMPDIR", "/tmp")
                if not os.path.exists(mmap_dir):
                    raise Exception("TMPDIR %s does not exist!" % mmap_dir)
                #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures
                #that the file is readable and writable only by the creating user ID
                temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir)
                #keep a reference to it so it does not disappear!
                self._mmap_temp_file = temp
                self.mmap_file = temp.name
                fd = temp.file.fileno()
                #set the group permissions and gid if the mmap-group option is specified
                if opts.mmap_group and type(conn.target)==str and os.path.exists(conn.target):
                    s = os.stat(conn.target)
                    os.fchown(fd, -1, s.st_gid)
                    os.fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
                self.mmap_size = max(4096, mmap.PAGESIZE)*32*1024   #generally 128MB
                log("using mmap file %s, fd=%s, size=%s", self.mmap_file, fd, self.mmap_size)
                os.lseek(fd, self.mmap_size-1, os.SEEK_SET)
                assert os.write(fd, '\x00')
                os.lseek(fd, 0, os.SEEK_SET)
                self.mmap = mmap.mmap(fd, length=self.mmap_size)
                #write the 16 byte token one byte at a time - no endianness
                self.mmap_token = uuid.uuid4().int
                log.debug("mmap_token=%s", self.mmap_token)
                v = self.mmap_token
                for i in range(0,16):
                    poke = ctypes.c_ubyte.from_buffer(self.mmap, 512+i)
                    poke.value = v % 256
                    v = v>>8
                assert v==0
            except Exception, e:
                log.error("failed to setup mmap: %s", e)
                self.supports_mmap = False
                self.clean_mmap()
                self.mmap = None
                self.mmap_file = None
                self.mmap_size = 0
Esempio n. 38
0
    def __init__(self, client, session_name, window_icon_pixbuf, conn, get_pixbuf):
        gtk.Window.__init__(self)
        self.client = client
        self.session_name = session_name
        self.connection = conn
        self.last_populate_time = 0
        self.last_populate_statistics = 0
        self.is_closed = False
        self.get_pixbuf = get_pixbuf
        if self.session_name == "Xpra":
            title = "Session Info"
        else:
            title = "%s: Session Info" % self.session_name
        self.set_title(title)
        self.set_destroy_with_parent(True)
        self.set_resizable(True)
        self.set_decorated(True)
        if window_icon_pixbuf:
            self.set_icon(window_icon_pixbuf)
        if is_gtk3():
            self.set_position(gtk.WindowPosition.CENTER)
        else:
            self.set_position(gtk.WIN_POS_CENTER)

        # tables on the left in a vbox with buttons at the top:
        self.tab_box = gtk.VBox(False, 0)
        self.tab_button_box = gtk.HBox(True, 0)
        self.tabs = []  # pairs of button, table
        self.populate_cb = None
        self.tab_box.pack_start(self.tab_button_box, expand=False, fill=True, padding=0)

        # Package Table:
        tb = self.table_tab("package.png", "Software", self.populate_package)
        # title row:
        tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Client"), 1, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Server"), 2, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.inc()

        def make_os_str(sys_platform, platform_release, platform_platform, platform_linux_distribution):
            s = platform_name(sys_platform, platform_release)
            if (
                platform_linux_distribution
                and len(platform_linux_distribution) == 3
                and len(platform_linux_distribution[0]) > 0
            ):
                s += "\n%s" % (" ".join(platform_linux_distribution))
            elif platform_platform:
                s += "\n%s" % platform_platform
            return s

        LOCAL_PLATFORM_NAME = make_os_str(
            sys.platform, python_platform.release(), python_platform.platform(), python_platform.linux_distribution()
        )
        SERVER_PLATFORM_NAME = make_os_str(
            self.client._remote_platform,
            self.client._remote_platform_release,
            self.client._remote_platform_platform,
            self.client._remote_platform_linux_distribution,
        )
        tb.new_row("Operating System", label(LOCAL_PLATFORM_NAME), label(SERVER_PLATFORM_NAME))
        scaps = self.client.server_capabilities
        from xpra.__init__ import __version__

        tb.new_row("Xpra", label(__version__), label(self.client._remote_version or "unknown"))
        cl_rev, cl_ch, cl_date = "unknown", "", ""
        try:
            from xpra.build_info import BUILD_DATE as cl_date
            from xpra.src_info import REVISION as cl_rev, LOCAL_MODIFICATIONS as cl_ch
        except:
            pass

        def make_version_str(version):
            if version and type(version) in (tuple, list):
                version = ".".join([str(x) for x in version])
            return version or "unknown"

        def server_info(*prop_names):
            for x in prop_names:
                v = scaps.get(x)
                if v is not None:
                    return v
            return None

        def server_version_info(*prop_names):
            return make_version_str(server_info(*prop_names))

        tb.new_row("Revision", label(cl_rev), label(make_version_str(self.client._remote_revision)))
        tb.new_row(
            "Local Changes",
            label(cl_ch),
            label(server_version_info("build.local_modifications", "local_modifications")),
        )
        tb.new_row("Build date", label(cl_date), label(server_info("build_date", "build.date")))

        def client_version_info(prop_name):
            info = "unknown"
            if hasattr(gtk, prop_name):
                info = make_version_str(getattr(gtk, prop_name))
            return info

        if is_gtk3():
            tb.new_row("PyGobject", label(gobject._version))
            tb.new_row("Client GDK", label(gdk._version))
            tb.new_row("GTK", label(gtk._version), label(server_version_info("gtk_version")))
        else:
            tb.new_row(
                "PyGTK",
                label(client_version_info("pygtk_version")),
                label(server_version_info("pygtk.version", "pygtk_version")),
            )
            tb.new_row(
                "GTK",
                label(client_version_info("gtk_version")),
                label(server_version_info("gtk.version", "gtk_version")),
            )
        tb.new_row(
            "Python",
            label(python_platform.python_version()),
            label(server_version_info("server.python.version", "python_version")),
        )
        cl_gst_v, cl_pygst_v = "", ""
        if HAS_SOUND:
            try:
                from xpra.sound.gstreamer_util import gst_version as cl_gst_v, pygst_version as cl_pygst_v
            except:
                pass
        tb.new_row(
            "GStreamer",
            label(make_version_str(cl_gst_v)),
            label(server_version_info("sound.gst.version", "gst_version")),
        )
        tb.new_row(
            "pygst",
            label(make_version_str(cl_pygst_v)),
            label(server_version_info("sound.pygst.version", "pygst_version")),
        )
        tb.new_row("OpenGL", label(make_version_str(self.client.opengl_props.get("opengl", "n/a"))), label("n/a"))
        tb.new_row("OpenGL Vendor", label(make_version_str(self.client.opengl_props.get("vendor", ""))), label("n/a"))
        tb.new_row("PyOpenGL", label(make_version_str(self.client.opengl_props.get("pyopengl", "n/a"))), label("n/a"))

        # Features Table:
        tb = self.table_tab("features.png", "Features", self.populate_features)
        randr_box = gtk.HBox(False, 20)
        self.server_randr_label = label()
        self.server_randr_icon = gtk.Image()
        randr_box.add(self.server_randr_icon)
        randr_box.add(self.server_randr_label)
        tb.new_row("RandR Support", randr_box)
        opengl_box = gtk.HBox(False, 20)
        self.client_opengl_label = label()
        self.client_opengl_label.set_line_wrap(True)
        self.client_opengl_icon = gtk.Image()
        opengl_box.add(self.client_opengl_icon)
        opengl_box.add(self.client_opengl_label)
        tb.new_row("Client OpenGL", opengl_box)
        self.opengl_buffering = label()
        tb.new_row("OpenGL Buffering", self.opengl_buffering)
        self.server_encodings_label = label()
        tb.new_row("Server Encodings", self.server_encodings_label)
        self.client_encodings_label = label()
        tb.new_row("Client Encodings", self.client_encodings_label)
        self.server_mmap_icon = gtk.Image()
        tb.new_row("Memory Mapped Transfers", self.server_mmap_icon)
        self.server_clipboard_icon = gtk.Image()
        tb.new_row("Clipboard", self.server_clipboard_icon)
        self.server_notifications_icon = gtk.Image()
        tb.new_row("Notification Forwarding", self.server_notifications_icon)
        self.server_bell_icon = gtk.Image()
        tb.new_row("Bell Forwarding", self.server_bell_icon)
        self.server_cursors_icon = gtk.Image()
        tb.new_row("Cursor Forwarding", self.server_cursors_icon)
        speaker_box = gtk.HBox(False, 20)
        self.server_speaker_icon = gtk.Image()
        speaker_box.add(self.server_speaker_icon)
        self.speaker_codec_label = label()
        speaker_box.add(self.speaker_codec_label)
        tb.new_row("Speaker Forwarding", speaker_box)
        self.server_speaker_codecs_label = label()
        tb.new_row("Server Codecs", self.server_speaker_codecs_label)
        self.client_speaker_codecs_label = label()
        tb.new_row("Client Codecs", self.client_speaker_codecs_label)
        microphone_box = gtk.HBox(False, 20)
        self.server_microphone_icon = gtk.Image()
        microphone_box.add(self.server_microphone_icon)
        self.microphone_codec_label = label()
        microphone_box.add(self.microphone_codec_label)
        tb.new_row("Microphone Forwarding", microphone_box)
        self.server_microphone_codecs_label = label()
        tb.new_row("Server Codecs", self.server_microphone_codecs_label)
        self.client_microphone_codecs_label = label()
        tb.new_row("Client Codecs", self.client_microphone_codecs_label)

        # Connection Table:
        tb = self.table_tab("connect.png", "Connection", self.populate_connection)
        tb.new_row("Server Endpoint", label(self.connection.target))
        if self.client.server_display:
            tb.new_row("Server Display", label(self.client.server_display))
        if "hostname" in scaps:
            tb.new_row("Server Hostname", label(scaps.get("hostname")))
        if self.client.server_platform:
            tb.new_row("Server Platform", label(self.client.server_platform))
        self.server_load_label = label()
        tb.new_row("Server Load", self.server_load_label, label_tooltip="Average over 1, 5 and 15 minutes")
        self.session_started_label = label()
        tb.new_row("Session Started", self.session_started_label)
        self.session_connected_label = label()
        tb.new_row("Session Connected", self.session_connected_label)
        self.input_packets_label = label()
        tb.new_row("Packets Received", self.input_packets_label)
        self.input_bytes_label = label()
        tb.new_row("Bytes Received", self.input_bytes_label)
        self.output_packets_label = label()
        tb.new_row("Packets Sent", self.output_packets_label)
        self.output_bytes_label = label()
        tb.new_row("Bytes Sent", self.output_bytes_label)
        self.compression_label = label()
        tb.new_row("Compression Level", self.compression_label)
        self.connection_type_label = label()
        tb.new_row("Connection Type", self.connection_type_label)
        self.input_encryption_label = label()
        tb.new_row("Input Encryption", self.input_encryption_label)
        self.output_encryption_label = label()
        tb.new_row("Output Encryption", self.output_encryption_label)

        self.speaker_label = label()
        self.speaker_details = label(font="monospace 10")
        tb.new_row("Speaker", self.speaker_label, self.speaker_details)
        self.microphone_label = label()
        tb.new_row("Microphone", self.microphone_label)

        # Details:
        tb = self.table_tab("browse.png", "Statistics", self.populate_statistics)
        tb.widget_xalign = 1.0
        tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Latest"), 1, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Minimum"), 2, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Average"), 3, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("90 percentile"), 4, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.attach(title_box("Maximum"), 5, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0)
        tb.inc()

        def maths_labels():
            return label(), label(), label(), label(), label()

        self.server_latency_labels = maths_labels()
        tb.add_row(label("Server Latency (ms)"), *self.server_latency_labels)
        self.client_latency_labels = maths_labels()
        tb.add_row(label("Client Latency (ms)"), *self.client_latency_labels)
        if self.client.windows_enabled:
            if self.client.server_info_request:
                self.batch_labels = maths_labels()
                tb.add_row(label("Batch Delay (ms)"), *self.batch_labels)
                self.damage_labels = maths_labels()
                tb.add_row(label("Damage Latency (ms)"), *self.damage_labels)
                self.quality_labels = maths_labels()
                tb.add_row(label("Encoding Quality (pct)"), *self.quality_labels)
                self.speed_labels = maths_labels()
                tb.add_row(label("Encoding Speed (pct)"), *self.speed_labels)

            self.decoding_labels = maths_labels()
            tb.add_row(label("Decoding Latency (ms)"), *self.decoding_labels)
            self.regions_per_second_labels = maths_labels()
            tb.add_row(label("Regions/s"), *self.regions_per_second_labels)
            self.regions_sizes_labels = maths_labels()
            tb.add_row(label("Pixels/region"), *self.regions_sizes_labels)
            self.pixels_per_second_labels = maths_labels()
            tb.add_row(label("Pixels/s"), *self.pixels_per_second_labels)

            self.windows_managed_label = label()
            tb.new_row("Regular Windows", self.windows_managed_label),
            self.transient_managed_label = label()
            tb.new_row("Transient Windows", self.transient_managed_label),
            self.trays_managed_label = label()
            tb.new_row("Trays Managed", self.trays_managed_label),
            if self.client.client_supports_opengl:
                self.opengl_label = label()
                tb.new_row("OpenGL Windows", self.opengl_label),

        self.graph_box = gtk.VBox(False, 10)
        self.add_tab("statistics.png", "Graphs", self.populate_graphs, self.graph_box)
        bandwidth_label = "Number of bytes measured by the networks sockets"
        if SHOW_PIXEL_STATS:
            bandwidth_label += ",\nand number of pixels rendered"
        self.bandwidth_graph = self.add_graph_button(bandwidth_label, self.save_graphs)
        self.latency_graph = self.add_graph_button(
            "The time it takes to send an echo packet and get the reply", self.save_graphs
        )
        self.pixel_in_data = maxdeque(N_SAMPLES + 4)
        self.net_in_bytecount = maxdeque(N_SAMPLES + 4)
        self.net_out_bytecount = maxdeque(N_SAMPLES + 4)

        self.set_border_width(15)
        self.add(self.tab_box)
        if not is_gtk3():
            self.set_geometry_hints(self.tab_box)

        def window_deleted(*args):
            self.is_closed = True

        self.connect("delete_event", window_deleted)
        self.show_tab(self.tabs[0][1])
        self.set_size_request(-1, 480)
        self.populate()
        self.populate_all()
        gobject.timeout_add(1000, self.populate)
        gobject.timeout_add(100, self.populate_tab)
        self.connect("realize", self.populate_graphs)
        add_close_accel(self, self.destroy)
Esempio n. 39
0
 def do_video_encoder_cleanup(self):
     self._video_encoder.clean()
     self._video_encoder = None
     self._video_encoder_speed = maxdeque(NRECS)
     self._video_encoder_quality = maxdeque(NRECS)
Esempio n. 40
0
def main():
    import time
    import sys
    assert len(sys.argv) == 2, "usage: %s :DISPLAY" % sys.argv[0]
    display = sys.argv[1]

    from xpra.scripts.config import make_defaults_struct
    opts = make_defaults_struct()
    from xpra.dotxpra import DotXpra
    target = DotXpra().socket_path(display)
    print("will attempt to connect to socket: %s" % target)

    import socket
    sock = socket.socket(socket.AF_UNIX)
    sock.connect(target)

    from xpra.net.bytestreams import SocketConnection
    conn = SocketConnection(sock, sock.getsockname(), sock.getpeername(),
                            target, "scroll-test")
    print("socket connection=%s" % conn)

    app = ServerMessenger(conn, opts)
    window = ScrolledWindowExample()

    from xpra.deque import maxdeque
    vscroll_events = maxdeque(1000)
    hscroll_events = maxdeque(1000)

    def vscroll(scrollbar, scrolltype, value):
        #print("vscroll(%s) n=%s" % ((scrollbar, scrolltype, value), len(vscroll_events)))
        now = time.time()
        needs_reset = False
        if len(vscroll_events) > 0:
            #get the previous event
            t, _ = vscroll_events[-1]
            #print("last vscroll event was %sms ago" % (now-t))
            if now - t < 1:
                #last event was less than a second ago
                print("lowering quality to jpeg @ 1%!")
                app.send("command_request", "encoding", "jpeg", "strict")
                app.send("command_request", "quality", 1, "*")
                app.send("command_request", "speed", 100, "*")
                needs_reset = True
        vscroll_events.append((now, value))
        if needs_reset:

            def may_reset_quality(*args):
                #if no new events since, reset quality:
                t, _ = vscroll_events[-1]
                if now == t:
                    print("resetting quality to h264")
                    app.send("command_request", "encoding", "h264", "nostrict")
                    app.send("command_request", "quality", -1,
                             "*")  #means auto
                    app.send("command_request", "speed", -1, "*")  #means auto

            gobject.timeout_add(1000, may_reset_quality)

    def hscroll(scrollbar, scrolltype, value):
        print("hscroll(%s)" % (scrollbar, scrolltype, value))
        hscroll_events.append((time.time(), value))

    window.vscroll.connect("change-value", vscroll)
    window.hscroll.connect("change-value", hscroll)
    try:
        app.run()
    finally:
        app.cleanup()
Esempio n. 41
0
    def __init__(self, conn, opts):
        XpraClientBase.__init__(self, opts)
        self.start_time = time.time()
        self._window_to_id = {}
        self._id_to_window = {}
        self._ui_events = 0
        self.title = opts.title
        self.readonly = opts.readonly
        self.session_name = opts.session_name
        self.compression_level = opts.compression_level
        self.auto_refresh_delay = opts.auto_refresh_delay
        self.max_bandwidth = opts.max_bandwidth
        if self.max_bandwidth>0.0 and self.jpegquality==0:
            """ jpegquality was not set, use a better start value """
            self.jpegquality = 50
        self.dpi = int(opts.dpi)

        #statistics:
        self.server_start_time = -1
        self.server_platform = ""
        self.server_actual_desktop_size = None
        self.server_randr = False
        self.pixel_counter = maxdeque(maxlen=100)
        self.server_latency = maxdeque(maxlen=100)
        self.server_load = None
        self.client_latency = maxdeque(maxlen=100)
        self.last_ping_echoed_time = 0

        #features:
        self.toggle_cursors_bell_notify = False
        self.toggle_keyboard_sync = False
        self.window_configure = False
        self._client_extras = ClientExtras(self, opts)
        self.client_supports_notifications = opts.notifications and self._client_extras.can_notify()
        self.client_supports_clipboard = opts.clipboard and self._client_extras.supports_clipboard() and not self.readonly
        self.client_supports_cursors = opts.cursors
        self.client_supports_bell = opts.bell
        self.client_supports_sharing = opts.sharing
        self.notifications_enabled = self.client_supports_notifications
        self.clipboard_enabled = self.client_supports_clipboard
        self.cursors_enabled = self.client_supports_cursors
        self.bell_enabled = self.client_supports_bell

        #mmap:
        self.mmap_enabled = False
        self.mmap = None
        self.mmap_token = None
        self.mmap_file = None
        self.mmap_size = 0
        self.supports_mmap = opts.mmap and ("rgb24" in ENCODINGS) and self._client_extras.supports_mmap()
        if self.supports_mmap:
            self.init_mmap(opts.mmap_group, conn.filename)

        self.init_packet_handlers()
        self.ready(conn)

        #keyboard:
        self.keyboard_sync = opts.keyboard_sync
        self.key_repeat_delay = -1
        self.key_repeat_interval = -1
        self.keys_pressed = {}
        self._remote_version = None
        self._keymap_changing = False
        try:
            self._keymap = gdk.keymap_get_default()
        except:
            self._keymap = None
        self._do_keys_changed()
        self.key_shortcuts = self.parse_shortcuts(opts.key_shortcuts)
        log.info("xpra client version %s" % __version__)
        self.send_hello()

        if self._keymap:
            self._keymap.connect("keys-changed", self._keys_changed)

        self._focused = None
        def compute_receive_bandwidth(delay):
            bytecount = self._protocol.input_bytecount
            bw = ((bytecount - self.last_input_bytecount) / 1024) * 1000 / delay
            self.last_input_bytecount = bytecount;
            log.debug("Bandwidth is ", bw, "kB/s, max ", self.max_bandwidth, "kB/s")
            q = self.jpegquality
            if bw > self.max_bandwidth:
                q -= 10
            elif bw < self.max_bandwidth:
                q += 5
            q = max(10, min(95 ,q))
            self.send_jpeg_quality(q)
            return True
        if (self.max_bandwidth):
            self.last_input_bytecount = 0
            gobject.timeout_add(2000, compute_receive_bandwidth, 2000)
        if opts.send_pings:
            gobject.timeout_add(1000, self.send_ping)
        else:
            gobject.timeout_add(20*1000, self.send_ping)
Esempio n. 42
0
    def __init__(self, conn, opts):
        XpraClientBase.__init__(self, opts)
        self.start_time = time.time()
        self._window_to_id = {}
        self._id_to_window = {}
        self.title = opts.title
        self.readonly = opts.readonly
        self.session_name = opts.session_name
        self.compression_level = opts.compression_level
        self.auto_refresh_delay = opts.auto_refresh_delay
        self.max_bandwidth = opts.max_bandwidth
        if self.max_bandwidth > 0.0 and self.jpegquality == 0:
            """ jpegquality was not set, use a better start value """
            self.jpegquality = 50
        self.dpi = int(opts.dpi)

        #statistics:
        self.server_start_time = -1
        self.server_platform = ""
        self.server_actual_desktop_size = None
        self.server_randr = False
        self.pixel_counter = maxdeque(maxlen=100)
        self.server_latency = maxdeque(maxlen=100)
        self.server_load = None
        self.client_latency = maxdeque(maxlen=100)
        self.last_ping_echoed_time = 0

        #features:
        self.toggle_cursors_bell_notify = False
        self.toggle_keyboard_sync = False
        self.window_configure = False
        self._client_extras = ClientExtras(self, opts)
        self.client_supports_notifications = opts.notifications and self._client_extras.can_notify(
        )
        self.client_supports_clipboard = opts.clipboard and self._client_extras.supports_clipboard(
        ) and not self.readonly
        self.client_supports_cursors = opts.cursors
        self.client_supports_bell = opts.bell
        self.notifications_enabled = self.client_supports_notifications
        self.clipboard_enabled = self.client_supports_clipboard
        self.cursors_enabled = self.client_supports_cursors
        self.bell_enabled = self.client_supports_bell

        #mmap:
        self.mmap_enabled = False
        self.mmap = None
        self.mmap_token = None
        self.mmap_file = None
        self.mmap_size = 0
        self.supports_mmap = opts.mmap and (
            "rgb24" in ENCODINGS) and self._client_extras.supports_mmap()
        if self.supports_mmap:
            self.init_mmap(opts.mmap_group, conn.filename)

        self.init_packet_handlers()
        self.ready(conn)

        #keyboard:
        self.keyboard_sync = opts.keyboard_sync
        self.key_repeat_delay = -1
        self.key_repeat_interval = -1
        self.keys_pressed = {}
        self._remote_version = None
        self._keymap_changing = False
        try:
            self._keymap = gdk.keymap_get_default()
        except:
            self._keymap = None
        self._do_keys_changed()
        self.key_shortcuts = self.parse_shortcuts(opts.key_shortcuts)
        self.send_hello()

        if self._keymap:
            self._keymap.connect("keys-changed", self._keys_changed)

        self._focused = None

        def compute_receive_bandwidth(delay):
            bytecount = self._protocol.input_bytecount
            bw = (
                (bytecount - self.last_input_bytecount) / 1024) * 1000 / delay
            self.last_input_bytecount = bytecount
            log.debug("Bandwidth is ", bw, "kB/s, max ", self.max_bandwidth,
                      "kB/s")
            q = self.jpegquality
            if bw > self.max_bandwidth:
                q -= 10
            elif bw < self.max_bandwidth:
                q += 5
            q = max(10, min(95, q))
            self.send_jpeg_quality(q)
            return True

        if (self.max_bandwidth):
            self.last_input_bytecount = 0
            gobject.timeout_add(2000, compute_receive_bandwidth, 2000)
        if opts.send_pings:
            gobject.timeout_add(1000, self.send_ping)
        else:
            gobject.timeout_add(20 * 1000, self.send_ping)
Esempio n. 43
0
class SessionInfo(gtk.Window):

    def __init__(self, client, session_name, window_icon_pixbuf, conn, get_pixbuf):
        gtk.Window.__init__(self)
        self.client = client
        self.session_name = session_name
        self.connection = conn
        self.last_populate_time = 0
        self.last_populate_statistics = 0
        self.is_closed = False
        self.get_pixbuf = get_pixbuf
        if not self.session_name or self.session_name=="Xpra":
            title = "Session Info"
        else:
            title = "%s: Session Info" % self.session_name
        self.set_title(title)
        self.set_destroy_with_parent(True)
        self.set_resizable(True)
        self.set_decorated(True)
        if window_icon_pixbuf:
            self.set_icon(window_icon_pixbuf)
        self.set_position(WIN_POS_CENTER)

        #tables on the left in a vbox with buttons at the top:
        self.tab_box = gtk.VBox(False, 0)
        self.tab_button_box = gtk.HBox(True, 0)
        self.tabs = []          #pairs of button, table
        self.populate_cb = None
        self.tab_box.pack_start(self.tab_button_box, expand=False, fill=True, padding=0)

        #Package Table:
        tb, _ = self.table_tab("package.png", "Software", self.populate_package)
        #title row:
        tb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Client"), 1, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Server"), 2, xoptions=EXPAND|FILL, xpadding=0)
        tb.inc()

        def make_os_str(*args):
            s = os_info(*args)
            return "\n".join(s)
        distro = ""
        if hasattr(python_platform, "linux_distribution"):
            distro = python_platform.linux_distribution()
        LOCAL_PLATFORM_NAME = make_os_str(sys.platform, python_platform.release(), python_platform.platform(), distro)
        SERVER_PLATFORM_NAME = make_os_str(self.client._remote_platform, self.client._remote_platform_release, self.client._remote_platform_platform, self.client._remote_platform_linux_distribution)
        tb.new_row("Operating System", label(LOCAL_PLATFORM_NAME), label(SERVER_PLATFORM_NAME))
        scaps = self.client.server_capabilities
        from xpra.__init__ import __version__
        tb.new_row("Xpra", label(__version__), label(self.client._remote_version or "unknown"))
        cl_rev, cl_ch, cl_date = "unknown", "", ""
        try:
            from xpra.build_info import BUILD_DATE as cl_date, BUILD_TIME as cl_time
            from xpra.src_info import REVISION as cl_rev, LOCAL_MODIFICATIONS as cl_ch      #@UnresolvedImport
        except:
            pass
        def make_version_str(version):
            if version and type(version) in (tuple, list):
                version = ".".join([str(x) for x in version])
            return version or "unknown"
        def server_info(*prop_names):
            for x in prop_names:
                v = scaps.capsget(x)
                if v is not None:
                    return v
                if self.client.server_last_info:
                    v = self.client.server_last_info.get(x)
                if v is not None:
                    return v
            return None
        def server_version_info(*prop_names):
            return make_version_str(server_info(*prop_names))
        def make_revision_str(rev, changes):
            if not changes:
                return rev
            return "%s (%s changes)" % (rev, changes)
        def make_datetime(date, time):
            if not time:
                return date
            return "%s %s" % (date, time)
        tb.new_row("Revision", label(make_revision_str(cl_rev, cl_ch)),
                               label(make_revision_str(self.client._remote_revision, server_version_info("build.local_modifications", "local_modifications"))))
        tb.new_row("Build date", label(make_datetime(cl_date, cl_time)),
                                 label(make_datetime(server_info("build_date", "build.date"), server_info("build.time"))))
        gtk_version_info = get_gtk_version_info()
        def client_vinfo(prop, fallback="unknown"):
            k = "%s.version" % prop
            return label(make_version_str(gtk_version_info.get(k, fallback)))
        tb.new_row("Glib",      client_vinfo("glib"),       label(server_version_info("glib.version")))
        tb.new_row("Gobject",   client_vinfo("gobject"),    label(server_version_info("gobject.version", "pygtk_version")))
        tb.new_row("PyGTK",     client_vinfo("pygtk", ""),  label(server_version_info("pygtk.version", "pygtk_version")))
        tb.new_row("GTK",       client_vinfo("gtk"),        label(server_version_info("gtk.version", "gtk_version")))
        tb.new_row("GDK",       client_vinfo("gdk"),        label(server_version_info("gdk.version", "gdk_version")))
        tb.new_row("Cairo",     client_vinfo("cairo"),      label(server_version_info("cairo.version", "cairo_version")))
        tb.new_row("Pango",     client_vinfo("pango"),      label(server_version_info("pango.version", "cairo_version")))
        tb.new_row("Python", label(python_platform.python_version()), label(server_version_info("server.python.version", "python_version", "python.version")))

        cl_gst_v, cl_pygst_v = "", ""
        try:
            from xpra.sound.gstreamer_util import gst_version as cl_gst_v, pygst_version as cl_pygst_v
        except Exception, e:
            log("cannot load gstreamer: %s", e)
        tb.new_row("GStreamer", label(make_version_str(cl_gst_v)), label(server_version_info("sound.gst.version", "gst_version")))
        tb.new_row("pygst", label(make_version_str(cl_pygst_v)), label(server_version_info("sound.pygst.version", "pygst_version")))
        tb.new_row("OpenGL", label(make_version_str(self.client.opengl_props.get("opengl", "n/a"))), label("n/a"))
        tb.new_row("OpenGL Vendor", label(make_version_str(self.client.opengl_props.get("vendor", ""))), label("n/a"))
        tb.new_row("PyOpenGL", label(make_version_str(self.client.opengl_props.get("pyopengl", "n/a"))), label("n/a"))

        # Features Table:
        vbox = self.vbox_tab("features.png", "Features", self.populate_features)
        #add top table:
        tb = TableBuilder(rows=1, columns=2)
        table = tb.get_table()
        al = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=1.0)
        al.add(table)
        vbox.pack_start(al, expand=True, fill=False, padding=10)
        #top table contents:
        randr_box = gtk.HBox(False, 20)
        self.server_randr_label = label()
        self.server_randr_icon = gtk.Image()
        randr_box.add(self.server_randr_icon)
        randr_box.add(self.server_randr_label)
        tb.new_row("RandR Support", randr_box)
        opengl_box = gtk.HBox(False, 20)
        self.client_opengl_label = label()
        self.client_opengl_label.set_line_wrap(True)
        self.client_opengl_icon = gtk.Image()
        opengl_box.add(self.client_opengl_icon)
        opengl_box.add(self.client_opengl_label)
        tb.new_row("Client OpenGL", opengl_box)
        self.opengl_buffering = label()
        tb.new_row("OpenGL Buffering", self.opengl_buffering)
        self.server_mmap_icon = gtk.Image()
        tb.new_row("Memory Mapped Transfers", self.server_mmap_icon)
        self.server_clipboard_icon = gtk.Image()
        tb.new_row("Clipboard", self.server_clipboard_icon)
        self.server_notifications_icon = gtk.Image()
        tb.new_row("Notification Forwarding", self.server_notifications_icon)
        self.server_bell_icon = gtk.Image()
        tb.new_row("Bell Forwarding", self.server_bell_icon)
        self.server_cursors_icon = gtk.Image()
        tb.new_row("Cursor Forwarding", self.server_cursors_icon)
        speaker_box = gtk.HBox(False, 20)
        self.server_speaker_icon = gtk.Image()
        speaker_box.add(self.server_speaker_icon)
        self.speaker_codec_label = label()
        speaker_box.add(self.speaker_codec_label)
        tb.new_row("Speaker Forwarding", speaker_box)
        microphone_box = gtk.HBox(False, 20)
        self.server_microphone_icon = gtk.Image()
        microphone_box.add(self.server_microphone_icon)
        self.microphone_codec_label = label()
        microphone_box.add(self.microphone_codec_label)
        tb.new_row("Microphone Forwarding", microphone_box)
        #add bottom table:
        tb = TableBuilder(rows=1, columns=3)
        table = tb.get_table()
        vbox.pack_start(table, expand=True, fill=True, padding=20)
        #bottom table headings:
        tb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Client"), 1, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Server"), 2, xoptions=EXPAND|FILL, xpadding=0)
        tb.inc()
        #bottom table contents:
        self.client_encodings_label = label()
        self.client_encodings_label.set_line_wrap(True)
        self.client_encodings_label.set_size_request(250, -1)
        self.server_encodings_label = label()
        self.server_encodings_label.set_line_wrap(True)
        self.server_encodings_label.set_size_request(250, -1)
        tb.new_row("Encodings", self.client_encodings_label, self.server_encodings_label)
        self.client_speaker_codecs_label = label()
        self.server_speaker_codecs_label = label()
        tb.new_row("Speaker Codecs", self.client_speaker_codecs_label, self.server_speaker_codecs_label)
        self.client_microphone_codecs_label = label()
        self.server_microphone_codecs_label = label()
        tb.new_row("Microphone Codecs", self.client_microphone_codecs_label, self.server_microphone_codecs_label)
        self.client_packet_encoders_label = label()
        self.server_packet_encoders_label = label()
        tb.new_row("Packet Encoders", self.client_packet_encoders_label, self.server_packet_encoders_label)
        self.client_packet_compressors_label = label()
        self.server_packet_compressors_label = label()
        tb.new_row("Packet Compressors", self.client_packet_compressors_label, self.server_packet_compressors_label)

        # Connection Table:
        tb, _ = self.table_tab("connect.png", "Connection", self.populate_connection)
        tb.new_row("Server Endpoint", label(self.connection.target))
        if self.client.server_display:
            tb.new_row("Server Display", label(self.client.server_display))
        hostname = scaps.strget("hostname")
        if hostname:
            tb.new_row("Server Hostname", label(hostname))
        if self.client.server_platform:
            tb.new_row("Server Platform", label(self.client.server_platform))
        self.server_load_label = label()
        tb.new_row("Server Load", self.server_load_label, label_tooltip="Average over 1, 5 and 15 minutes")
        self.session_started_label = label()
        tb.new_row("Session Started", self.session_started_label)
        self.session_connected_label = label()
        tb.new_row("Session Connected", self.session_connected_label)
        self.input_packets_label = label()
        tb.new_row("Packets Received", self.input_packets_label)
        self.input_bytes_label = label()
        tb.new_row("Bytes Received", self.input_bytes_label)
        self.output_packets_label = label()
        tb.new_row("Packets Sent", self.output_packets_label)
        self.output_bytes_label = label()
        tb.new_row("Bytes Sent", self.output_bytes_label)
        self.compression_label = label()
        tb.new_row("Compression + Encoding", self.compression_label)
        self.connection_type_label = label()
        tb.new_row("Connection Type", self.connection_type_label)
        self.input_encryption_label = label()
        tb.new_row("Input Encryption", self.input_encryption_label)
        self.output_encryption_label = label()
        tb.new_row("Output Encryption", self.output_encryption_label)

        self.speaker_label = label()
        self.speaker_details = label(font="monospace 10")
        tb.new_row("Speaker", self.speaker_label, self.speaker_details)
        self.microphone_label = label()
        tb.new_row("Microphone", self.microphone_label)

        # Details:
        tb, stats_box = self.table_tab("browse.png", "Statistics", self.populate_statistics)
        tb.widget_xalign = 1.0
        tb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Latest"), 1, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Minimum"), 2, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Average"), 3, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("90 percentile"), 4, xoptions=EXPAND|FILL, xpadding=0)
        tb.attach(title_box("Maximum"), 5, xoptions=EXPAND|FILL, xpadding=0)
        tb.inc()

        def maths_labels():
            return label(), label(), label(), label(), label()
        self.server_latency_labels = maths_labels()
        tb.add_row(label("Server Latency (ms)", "The time it takes for the server to respond to pings"),
                   *self.server_latency_labels)
        self.client_latency_labels = maths_labels()
        tb.add_row(label("Client Latency (ms)", "The time it takes for the client to respond to pings, as measured by the server"),
                   *self.client_latency_labels)
        if self.client.windows_enabled:
            if self.client.server_info_request:
                self.batch_labels = maths_labels()
                tb.add_row(label("Batch Delay (ms)", "How long the server waits for new screen updates to accumulate before processing them"),
                           *self.batch_labels)
                self.damage_labels = maths_labels()
                tb.add_row(label("Damage Latency (ms)", "The time it takes to compress a frame and pass it to the OS network layer"),
                           *self.damage_labels)
                self.quality_labels = maths_labels()
                tb.add_row(label("Encoding Quality (pct)"), *self.quality_labels)
                self.speed_labels = maths_labels()
                tb.add_row(label("Encoding Speed (pct)"), *self.speed_labels)

            self.decoding_labels = maths_labels()
            tb.add_row(label("Decoding Latency (ms)", "How long it takes the client to decode a screen update"), *self.decoding_labels)
            self.regions_per_second_labels = maths_labels()
            tb.add_row(label("Regions/s", "The number of screen updates per second (includes both partial and full screen updates)"), *self.regions_per_second_labels)
            self.regions_sizes_labels = maths_labels()
            tb.add_row(label("Pixels/region", "The number of pixels per screen update"), *self.regions_sizes_labels)
            self.pixels_per_second_labels = maths_labels()
            tb.add_row(label("Pixels/s", "The number of pixels processed per second"), *self.pixels_per_second_labels)

            #Window count stats:
            wtb = TableBuilder()
            stats_box.add(wtb.get_table())
            #title row:
            wtb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0)
            wtb.attach(title_box("Regular"), 1, xoptions=EXPAND|FILL, xpadding=0)
            wtb.attach(title_box("Transient"), 2, xoptions=EXPAND|FILL, xpadding=0)
            wtb.attach(title_box("Trays"), 3, xoptions=EXPAND|FILL, xpadding=0)
            if self.client.client_supports_opengl:
                wtb.attach(title_box("OpenGL"), 4, xoptions=EXPAND|FILL, xpadding=0)
            wtb.inc()

            wtb.attach(label("Windows:"), 0, xoptions=EXPAND|FILL, xpadding=0)
            self.windows_managed_label = label()
            wtb.attach(self.windows_managed_label, 1)
            self.transient_managed_label = label()
            wtb.attach(self.transient_managed_label, 2)
            self.trays_managed_label = label()
            wtb.attach(self.trays_managed_label, 3)
            if self.client.client_supports_opengl:
                self.opengl_label = label()
                wtb.attach(self.opengl_label, 4)

            #add encoder info:
            etb = TableBuilder()
            stats_box.add(etb.get_table())
            self.encoder_info_box = gtk.HBox(spacing=4)
            etb.new_row("Window Encoders", self.encoder_info_box)

        if not is_gtk3():
            #needs porting to cairo...
            self.graph_box = gtk.VBox(False, 10)
            self.add_tab("statistics.png", "Graphs", self.populate_graphs, self.graph_box)
            bandwidth_label = "Bandwidth used"
            if SHOW_PIXEL_STATS:
                bandwidth_label += ",\nand number of pixels rendered"
            self.bandwidth_graph = self.add_graph_button(bandwidth_label, self.save_graphs)
            self.connect("realize", self.populate_graphs)
            self.latency_graph = self.add_graph_button(None, self.save_graphs)
        self.pixel_in_data = maxdeque(N_SAMPLES+4)
        self.net_in_bytecount = maxdeque(N_SAMPLES+4)
        self.net_out_bytecount = maxdeque(N_SAMPLES+4)

        self.set_border_width(15)
        self.add(self.tab_box)
        if not is_gtk3():
            self.set_geometry_hints(self.tab_box)
        def window_deleted(*args):
            self.is_closed = True
        self.connect('delete_event', window_deleted)
        self.show_tab(self.tabs[0][2])
        self.set_size_request(-1, 480)
        self.init_counters()
        self.populate()
        self.populate_all()
        gobject.timeout_add(1000, self.populate)
        gobject.timeout_add(100, self.populate_tab)
        add_close_accel(self, self.destroy)
Esempio n. 44
0
def main():
    if "-v" in sys.argv or "--verbose" in sys.argv:
        log.enable_debug()
        sslog.enable_debug()

    log("main()")
    def refresh_cb(window, regions):
        log("refresh_cb(%s, %s)", window, regions)
    r = VideoSubregion(gobject.timeout_add, gobject.source_remove, refresh_cb, 150)

    ww = 1024
    wh = 768

    log.info("* checking that we need some events")
    last_damage_events = []
    for x in range(MIN_EVENTS):
        last_damage_events.append((0, 0, 0, 1, 1))
    r.identify_video_subregion(ww, wh, MIN_EVENTS, last_damage_events)
    assert r.rectangle is None

    vr = (time.time(), 100, 100, 320, 240)
    log.info("* easiest case: all updates in one region")
    last_damage_events = []
    for _ in range(50):
        last_damage_events.append(vr)
    r.identify_video_subregion(ww, wh, 50, last_damage_events)
    assert r.rectangle
    assert r.rectangle==rectangle(*vr[1:])

    log.info("* checking that empty damage events does not cause errors")
    r.reset()
    r.identify_video_subregion(ww, wh, 0, [])
    assert r.rectangle is None

    log.info("* checking that full window is not a region")
    vr = (time.time(), 0, 0, ww, wh)
    last_damage_events = []
    for _ in range(50):
        last_damage_events.append(vr)
    r.identify_video_subregion(ww, wh, 50, last_damage_events)
    assert r.rectangle is None

    log.info("* checking that regions covering the whole window give the same result")
    last_damage_events = maxdeque(150)
    for x in range(4):
        for y in range(4):
            vr = (time.time(), ww*x/4, wh*y/4, ww/4, wh/4)
            last_damage_events.append(vr)
            last_damage_events.append(vr)
            last_damage_events.append(vr)
    r.identify_video_subregion(ww, wh, 150, last_damage_events)
    assert r.rectangle is None

    vr = (time.time(), ww/4, wh/4, ww/2, wh/2)
    log.info("* mixed with region using 1/5 of window and 1/3 of updates: %s", vr)
    for _ in range(30):
        last_damage_events.append(vr)
    r.identify_video_subregion(ww, wh, 200, last_damage_events)
    assert r.rectangle is not None

    log.info("* info=%s", r.get_info())

    log.info("* checking that two video regions with the same characteristics get merged")
    last_damage_events = maxdeque(150)
    r.reset()
    v1 = (time.time(), 100, 100, 320, 240)
    v2 = (time.time(), 500, 500, 320, 240)
    for _ in range(50):
        last_damage_events.append(v1)
        last_damage_events.append(v2)
    r.identify_video_subregion(ww, wh, 100, last_damage_events)
    m = merge_all([rectangle(*v1[1:]), rectangle(*v2[1:])])
    assert r.rectangle==m, "expected %s but got %s" % (m, r.rectangle)

    log.info("* but not if they are too far apart")
    last_damage_events = maxdeque(150)
    r.reset()
    v1 = (time.time(), 20, 20, 320, 240)
    v2 = (time.time(), ww-20-320, wh-240-20, 320, 240)
    for _ in range(50):
        last_damage_events.append(v1)
        last_damage_events.append(v2)
    r.identify_video_subregion(ww, wh, 100, last_damage_events)
    assert r.rectangle is None
Esempio n. 45
0
def main():
    import time
    import sys
    assert len(sys.argv)==2, "usage: %s :DISPLAY" % sys.argv[0]
    display = sys.argv[1]

    from xpra.scripts.config import make_defaults_struct
    opts = make_defaults_struct()
    from xpra.dotxpra import DotXpra
    target = DotXpra().socket_path(display)
    print("will attempt to connect to socket: %s" % target)

    import socket
    sock = socket.socket(socket.AF_UNIX)
    sock.connect(target)

    from xpra.net.bytestreams import SocketConnection
    conn = SocketConnection(sock, sock.getsockname(), sock.getpeername(), target, "scroll-test")
    print("socket connection=%s" % conn)

    app = ServerMessenger(conn, opts)
    window = ScrolledWindowExample()

    from xpra.deque import maxdeque
    vscroll_events = maxdeque(1000)
    hscroll_events = maxdeque(1000)
    def vscroll(scrollbar, scrolltype, value):
        #print("vscroll(%s) n=%s" % ((scrollbar, scrolltype, value), len(vscroll_events)))
        now = time.time()
        needs_reset = False
        if len(vscroll_events)>0:
            #get the previous event
            t, _ = vscroll_events[-1]
            #print("last vscroll event was %sms ago" % (now-t))
            if now-t<1:
                #last event was less than a second ago
                print("lowering quality to jpeg @ 1%!")
                app.send("command_request", "encoding", "jpeg", "strict")
                app.send("command_request", "quality", 1, "*")
                app.send("command_request", "speed", 100, "*")
                needs_reset = True
        vscroll_events.append((now, value))
        if needs_reset:
            def may_reset_quality(*args):
                #if no new events since, reset quality:
                t, _ = vscroll_events[-1]
                if now==t:
                    print("resetting quality to h264")
                    app.send("command_request", "encoding", "h264", "nostrict")
                    app.send("command_request", "quality", -1, "*")     #means auto
                    app.send("command_request", "speed", -1, "*")       #means auto
            gobject.timeout_add(1000, may_reset_quality)
    def hscroll(scrollbar, scrolltype, value):
        print("hscroll(%s)" % (scrollbar, scrolltype, value))
        hscroll_events.append((time.time(), value))
    window.vscroll.connect("change-value", vscroll)
    window.hscroll.connect("change-value", hscroll)
    try:
        app.run()
    finally:
        app.cleanup()