Exemple #1
0
 def do_make_screenshot_packet(self):
     log("grabbing screenshot")
     regions = []
     OR_regions = []
     for wid in reversed(sorted(self._id_to_window.keys())):
         window = self._id_to_window.get(wid)
         log("screenshot: window(%s)=%s", wid, window)
         if window is None or window.is_tray() or not window.is_managed():
             continue
         pixmap = window.get_property("client-contents")
         log("screenshot: pixmap(%s)=%s", window, pixmap)
         if pixmap is None:
             continue
         if window.is_OR():
             x, y = window.get_property("geometry")[:2]
         else:
             x, y = self._desktop_manager.window_geometry(window)[:2]
         log("screenshot: position(%s)=%s,%s", window, x, y)
         w, h = pixmap.get_size()
         log("screenshot: size(%s)=%sx%s", pixmap, w, h)
         item = (wid, x, y, w, h, pixmap)
         if window.is_OR():
             OR_regions.append(item)
         elif self._has_focus==wid:
             #window with focus first (drawn last)
             regions.insert(0, item)
         else:
             regions.append(item)
     all_regions = OR_regions+regions
     if len(all_regions)==0:
         log("screenshot: no regions found, returning empty 0x0 image!")
         return ["screenshot", 0, 0, "png", -1, ""]
     log("screenshot: found regions=%s, OR_regions=%s", regions, OR_regions)
     minx = min([x for (_,x,_,_,_,_) in all_regions])
     miny = min([y for (_,_,y,_,_,_) in all_regions])
     maxx = max([(x+w) for (_,x,_,w,_,_) in all_regions])
     maxy = max([(y+h) for (_,_,y,_,h,_) in all_regions])
     width = maxx-minx
     height = maxy-miny
     log("screenshot: %sx%s, min x=%s y=%s", width, height, minx, miny)
     from PIL import Image
     image = Image.new("RGBA", (width, height))
     for wid, x, y, w, h, pixmap in reversed(all_regions):
         _, _, wid, _, _, w, h, _, raw_data, rowstride, _, _ = get_rgb_rawdata(0, 0, wid, pixmap, 0, 0, w, h, "rgb24", -1, None, logger=log.debug)
         window_image = Image.fromstring("RGB", (w, h), raw_data, "raw", "RGB", rowstride)
         tx = x-minx
         ty = y-miny
         image.paste(window_image, (tx, ty))
     buf = StringIO()
     image.save(buf, "png")
     data = buf.getvalue()
     buf.close()
     packet = ["screenshot", width, height, "png", rowstride, Compressed("png", data)]
     log("screenshot: %sx%s %s", packet[1], packet[2], packet[-1])
     return packet
Exemple #2
0
    def process_damage_region(self, damage_time, window, x, y, w, h, coding,
                              options):
        """
            Called by 'damage' or 'send_delayed_regions' to process a damage region,
            we extract the rgb data from the pixmap and place it on the damage queue.
            This runs in the UI thread.
        """
        if w == 0 or h == 0:
            return
        # It's important to acknowledge changes *before* we extract them,
        # to avoid a race condition.
        if not window.is_managed():
            log.warn("the window %s is not composited!?", window)
            return
        window.acknowledge_changes()

        self._sequence += 1
        sequence = self._sequence
        pixmap = window.get_property("client-contents")
        if self.is_cancelled(sequence):
            log("get_window_pixmap: dropping damage request with sequence=%s",
                sequence)
            return None
        if pixmap is None:
            log.error(
                "get_window_pixmap: wtf, pixmap is None for window %s, wid=%s",
                window, self.wid)
            return
        process_damage_time = time.time()
        data = get_rgb_rawdata(damage_time, process_damage_time, self.wid,
                               pixmap, x, y, w, h, coding, sequence, options)
        if not data:
            return
        log(
            "process_damage_regions: adding pixel data %s to queue, elapsed time: %s ms",
            data[:6], dec1(1000 * (time.time() - damage_time)))

        def make_data_packet(*args):
            #NOTE: this function is called from the damage data thread!
            packet = self.make_data_packet(*data)
            if packet:
                self.queue_damage_packet(pixmap, packet, damage_time,
                                         process_damage_time)
                if self.encoding in ("png", "rgb24"):
                    #primary encoding is lossless, no need for auto-refresh
                    return
                #auto-refresh:
                if self.auto_refresh_delay > 0 and not self.is_cancelled(
                        sequence):
                    client_options = packet[
                        10]  #info about this packet from the encoder
                    gobject.idle_add(self.schedule_auto_refresh, window, w, h,
                                     coding, options, client_options)

        self.queue_damage(make_data_packet)
Exemple #3
0
    def process_damage_region(self, damage_time, window, x, y, w, h, coding, options):
        """
            Called by 'damage' or 'send_delayed_regions' to process a damage region,
            we extract the rgb data from the pixmap and place it on the damage queue.
            This runs in the UI thread.
        """
        if w==0 or h==0:
            return
        # It's important to acknowledge changes *before* we extract them,
        # to avoid a race condition.
        if not window.is_managed():
            log.warn("the window %s is not composited!?", window)
            return
        window.acknowledge_changes()

        self._sequence += 1
        sequence = self._sequence
        pixmap = window.get_property("client-contents")
        if self.is_cancelled(sequence):
            log("get_window_pixmap: dropping damage request with sequence=%s", sequence)
            return  None
        if pixmap is None:
            log.error("get_window_pixmap: wtf, pixmap is None for window %s, wid=%s", window, self.wid)
            return
        process_damage_time = time.time()
        data = get_rgb_rawdata(damage_time, process_damage_time, self.wid, pixmap, x, y, w, h, coding, sequence, options)
        if not data:
            return
        log("process_damage_regions: adding pixel data %s to queue, elapsed time: %s ms", data[:6], dec1(1000*(time.time()-damage_time)))
        def make_data_packet(*args):
            #NOTE: this function is called from the damage data thread!
            packet = self.make_data_packet(*data)
            if packet:
                self.queue_damage_packet(pixmap, packet, damage_time, process_damage_time)
                if self.encoding in ("png", "rgb24"):
                    #primary encoding is lossless, no need for auto-refresh
                    return
                #auto-refresh:
                if self.auto_refresh_delay>0 and not self.is_cancelled(sequence):
                    client_options = packet[10]     #info about this packet from the encoder
                    gobject.idle_add(self.schedule_auto_refresh, window, w, h, coding, options, client_options)
        self.queue_damage(make_data_packet)
Exemple #4
0
    def process_damage_region(self, damage_time, pixmap, x, y, w, h, coding,
                              sequence, options):
        """
            Called by 'damage_now' or 'send_delayed_regions' to process a damage region,
            we extract the rgb data from the pixmap and place it on the damage queue.
        """
        if w == 0 or h == 0:
            return
        process_damage_time = time.time()
        data = get_rgb_rawdata(damage_time, process_damage_time, self.wid,
                               pixmap, x, y, w, h, coding, sequence, options)
        if data:
            log(
                "process_damage_regions: adding pixel data %s to queue, elapsed time: %s ms",
                data[:6], dec1(1000 * (time.time() - damage_time)))

            def make_data_packet(*args):
                #NOTE: this function is called from the damage data thread!
                packet = self.make_data_packet(*data)
                if packet:
                    self.queue_damage_packet(packet, damage_time,
                                             process_damage_time)

            self.queue_damage(make_data_packet)
Exemple #5
0
 def do_make_screenshot_packet(self):
     log("grabbing screenshot")
     regions = []
     OR_regions = []
     for wid in reversed(sorted(self._id_to_window.keys())):
         window = self._id_to_window.get(wid)
         log("screenshot: window(%s)=%s", wid, window)
         if window is None or window.is_tray() or not window.is_managed():
             continue
         pixmap = window.get_property("client-contents")
         log("screenshot: pixmap(%s)=%s", window, pixmap)
         if pixmap is None:
             continue
         if window.is_OR():
             x, y = window.get_property("geometry")[:2]
         else:
             x, y = self._desktop_manager.window_geometry(window)[:2]
         log("screenshot: position(%s)=%s,%s", window, x, y)
         w, h = pixmap.get_size()
         log("screenshot: size(%s)=%sx%s", pixmap, w, h)
         item = (wid, x, y, w, h, pixmap)
         if window.is_OR():
             OR_regions.append(item)
         elif self._has_focus == wid:
             #window with focus first (drawn last)
             regions.insert(0, item)
         else:
             regions.append(item)
     all_regions = OR_regions + regions
     if len(all_regions) == 0:
         log("screenshot: no regions found, returning empty 0x0 image!")
         return ["screenshot", 0, 0, "png", -1, ""]
     log("screenshot: found regions=%s, OR_regions=%s", regions, OR_regions)
     minx = min([x for (_, x, _, _, _, _) in all_regions])
     miny = min([y for (_, _, y, _, _, _) in all_regions])
     maxx = max([(x + w) for (_, x, _, w, _, _) in all_regions])
     maxy = max([(y + h) for (_, _, y, _, h, _) in all_regions])
     width = maxx - minx
     height = maxy - miny
     log("screenshot: %sx%s, min x=%s y=%s", width, height, minx, miny)
     from PIL import Image
     image = Image.new("RGBA", (width, height))
     for wid, x, y, w, h, pixmap in reversed(all_regions):
         _, _, wid, _, _, w, h, _, raw_data, rowstride, _, _ = get_rgb_rawdata(
             0,
             0,
             wid,
             pixmap,
             0,
             0,
             w,
             h,
             "rgb24",
             -1,
             None,
             logger=log.debug)
         window_image = Image.fromstring("RGB", (w, h), raw_data, "raw",
                                         "RGB", rowstride)
         tx = x - minx
         ty = y - miny
         image.paste(window_image, (tx, ty))
     buf = StringIO()
     image.save(buf, "png")
     data = buf.getvalue()
     buf.close()
     packet = [
         "screenshot", width, height, "png", rowstride,
         Compressed("png", data)
     ]
     log("screenshot: %sx%s %s", packet[1], packet[2], packet[-1])
     return packet