def next_packet(self): if self._ordinary_packets: packet = self._ordinary_packets.pop(0) elif self._damage: id, (window, damage) = self._damage.items()[0] (x, y, w, h) = get_rectangle_from_region(damage) rect = gtk.gdk.Rectangle(x, y, w, h) damage.subtract(gtk.gdk.region_rectangle(rect)) if damage.empty(): del self._damage[id] # It's important to acknowledge changes *before* we extract them, # to avoid a race condition. window.acknowledge_changes(x, y, w, h) pixmap = window.get_property("client-contents") if pixmap is None: log.error("wtf, pixmap is None?") packet = None else: (x2, y2, w2, h2, data) = self._get_rgb_data(pixmap, x, y, w, h) if not w2 or not h2: packet = None else: packet = ["draw", id, x2, y2, w2, h2, "rgb24", data] else: packet = None return packet, self._have_more()
def send_delayed_regions(self, damage_time, window, damage, coding, sequence, options): """ Called by 'send_delayed' when we expire a delayed region, There may be many rectangles within this delayed region, so figure out if we want to send them all or if we just send one full screen update instead. """ log("send_delayed_regions: processing sequence=%s", sequence) if self.is_cancelled(sequence): log("send_delayed_regions: dropping request with sequence=%s", sequence) return regions = [] ww, wh = window.get_dimensions() def send_full_screen_update(): log("send_delayed_regions: using full screen update") pixmap = self.get_window_pixmap(window, sequence) if pixmap: self.process_damage_region(damage_time, pixmap, 0, 0, ww, wh, coding, sequence, options) try: count_threshold = 60 pixels_threshold = ww * wh * 9 / 10 packet_cost = 1024 if self._mmap and self._mmap_size > 0: #with mmap, we can move lots of data around easily #so favour large screen updates over many small packets pixels_threshold = ww * wh / 2 packet_cost = 4096 pixel_count = 0 while not damage.empty(): try: if self.is_cancelled(sequence): return (x, y, w, h) = get_rectangle_from_region(damage) pixel_count += w * h #favor full screen updates over many regions: if len( regions ) > count_threshold or pixel_count + packet_cost * len( regions) >= pixels_threshold: send_full_screen_update() return regions.append((x, y, w, h)) rect = gtk.gdk.Rectangle(x, y, w, h) damage.subtract(gtk.gdk.region_rectangle(rect)) except ValueError: log.error("send_delayed_regions: damage is empty: %s", damage) break log("send_delayed_regions: to regions: %s items, %s pixels", len(regions), pixel_count) except Exception, e: log.error("send_delayed_regions: error processing region %s: %s", damage, e) return
def test_get_rectangle_from_region(self): print(1) region = gtk.gdk.Region() assert_raises(ValueError, l.get_rectangle_from_region, region) print(2) rect1 = gtk.gdk.Rectangle(1, 2, 3, 4) region = gtk.gdk.region_rectangle(rect1) (x, y, w, h) = l.get_rectangle_from_region(region) assert (x, y, w, h) == (1, 2, 3, 4) print(3) region.union_with_rect(gtk.gdk.Rectangle(10, 11, 12, 13)) (x, y, w, h) = l.get_rectangle_from_region(region) assert (x, y, w, h) in [(1, 2, 3, 4), (10, 11, 12, 13)] print(4) region.subtract(gtk.gdk.region_rectangle(rect1)) (x, y, w, h) = l.get_rectangle_from_region(region) assert (x, y, w, h) == (10, 11, 12, 13) print(5)
def send_delayed_regions(self, damage_time, window, damage, coding, options): """ Called by 'send_delayed' when we expire a delayed region, There may be many rectangles within this delayed region, so figure out if we want to send them all or if we just send one full screen update instead. """ regions = [] ww,wh = window.get_dimensions() def send_full_screen_update(actual_encoding): actual_encoding = self.get_best_encoding(window.is_OR(), pixel_count, ww, wh, coding) log("send_delayed_regions: using full screen update with %s", actual_encoding) self.process_damage_region(damage_time, window, 0, 0, ww, wh, actual_encoding, options) try: count_threshold = 60 pixels_threshold = ww*wh*9/10 packet_cost = 1024 if self._mmap and self._mmap_size>0: #with mmap, we can move lots of data around easily #so favour large screen updates over many small packets pixels_threshold = ww*wh/2 packet_cost = 4096 pixel_count = 0 while not damage.empty(): try: x, y, w, h = get_rectangle_from_region(damage) pixel_count += w*h #favor full screen updates over many regions: if len(regions)>count_threshold or pixel_count+packet_cost*len(regions)>=pixels_threshold: send_full_screen_update(coding) return regions.append((x, y, w, h)) rect = gtk.gdk.Rectangle(x, y, w, h) damage.subtract(gtk.gdk.region_rectangle(rect)) except ValueError: log.error("send_delayed_regions: damage is empty: %s", damage) break log("send_delayed_regions: to regions: %s items, %s pixels", len(regions), pixel_count) except Exception, e: log.error("send_delayed_regions: error processing region %s: %s", damage, e, exc_info=True) return