Пример #1
0
    def _do_paint_rgb(self, cairo_format, has_alpha, img_data, x, y, width,
                      height, rowstride, options):
        """ must be called from UI thread """
        log("cairo._do_paint_rgb(%s, %s, %s bytes,%s,%s,%s,%s,%s,%s)",
            cairo_format, has_alpha, len(img_data), x, y, width, height,
            rowstride, options)
        rgb_format = options.strget("rgb_format", "RGB")

        if rgb_format in ("ARGB", ):
            #the pixel format is also what cairo expects
            #maybe we should also check that the stride is acceptable for cairo?
            #cairo_stride = cairo.ImageSurface.format_stride_for_width(cairo_format, width)
            #log("cairo_stride=%s, stride=%s", cairo_stride, rowstride)
            pix_data = bytearray(img_data)
            img_surface = cairo.ImageSurface.create_for_data(
                pix_data, cairo_format, width, height, rowstride)
            self.cairo_paint_surface(img_surface, x, y, options)
            return True

        if rgb_format in ("RGBA", "RGBX", "RGB"):
            #with GTK2, we can use a pixbuf from RGB(A) pixels
            if rgb_format == "RGBA":
                #we have to unpremultiply for pixbuf!
                img_data = self.unpremultiply(img_data)
            #Pixbuf cannot use the memoryview directly:
            img_data = memoryview_to_bytes(img_data)
            pixbuf = pixbuf_new_from_data(img_data, COLORSPACE_RGB, has_alpha,
                                          8, width, height, rowstride)
            self.cairo_paint_pixbuf(pixbuf, x, y, options)
            return True

        self.nasty_rgb_via_png_paint(cairo_format, has_alpha, img_data, x, y,
                                     width, height, rowstride, rgb_format)
        return True
Пример #2
0
    def _do_paint_rgb(self, cairo_format, has_alpha, img_data, x, y, width, height, rowstride, options):
        """ must be called from UI thread """
        log("cairo._do_paint_rgb(%s, %s, %s bytes,%s,%s,%s,%s,%s,%s)", cairo_format, has_alpha, len(img_data), x, y, width, height, rowstride, options)
        rgb_format = options.strget("rgb_format", "RGB")

        if rgb_format in ("ARGB", ):
            #the pixel format is also what cairo expects
            #maybe we should also check that the stride is acceptable for cairo?
            #cairo_stride = cairo.ImageSurface.format_stride_for_width(cairo_format, width)
            #log("cairo_stride=%s, stride=%s", cairo_stride, rowstride)
            pix_data = bytearray(img_data)
            img_surface = cairo.ImageSurface.create_for_data(pix_data, cairo_format, width, height, rowstride)
            self.cairo_paint_surface(img_surface, x, y)
            return True

        if rgb_format in ("RGBA", "RGBX", "RGB"):
            #with GTK2, we can use a pixbuf from RGB(A) pixels
            if rgb_format=="RGBA":
                #we have to unpremultiply for pixbuf!
                img_data = self.unpremultiply(img_data)
            #Pixbuf cannot use the memoryview directly:
            img_data = memoryview_to_bytes(img_data)
            pixbuf = pixbuf_new_from_data(img_data, COLORSPACE_RGB, has_alpha, 8, width, height, rowstride)
            self.cairo_paint_pixbuf(pixbuf, x, y)
            return True

        self.nasty_rgb_via_png_paint(cairo_format, has_alpha, img_data, x, y, width, height, rowstride, rgb_format)
        return True
Пример #3
0
def cairo_paint_pointer_overlay(context, cursor_data, px, py, start_time):
    if not cursor_data:
        return
    elapsed = max(0, monotonic_time() - start_time)
    if elapsed > 6:
        return
    cw = cursor_data[3]
    ch = cursor_data[4]
    xhot = cursor_data[5]
    yhot = cursor_data[6]
    pixels = cursor_data[8]
    x = px - xhot
    y = py - yhot
    alpha = max(0, (5.0 - elapsed) / 5.0)
    log("cairo_paint_pointer_overlay%s drawing pointer with cairo, alpha=%s",
        (context, x, y, start_time), alpha)
    context.translate(x, y)
    context.rectangle(0, 0, cw, ch)
    argb = unpremultiply_argb(pixels)
    img_data = memoryview_to_bytes(argb)
    pixbuf = pixbuf_new_from_data(img_data, COLORSPACE_RGB, True, 8, cw, ch,
                                  cw * 4)
    context.set_operator(cairo.OPERATOR_OVER)
    cairo_set_source_pixbuf(context, pixbuf, 0, 0)
    context.paint()
Пример #4
0
    def _do_paint_rgb(self, cairo_format, has_alpha, img_data, x, y, width,
                      height, rowstride, options):
        """ must be called from UI thread """
        log("cairo._do_paint_rgb(%s, %s, %s bytes,%s,%s,%s,%s,%s,%s)",
            cairo_format, has_alpha, len(img_data), x, y, width, height,
            rowstride, options)
        rgb_format = options.strget("rgb_format", "RGB")
        if _memoryview and isinstance(img_data, _memoryview):
            #Pixbuf cannot use the memoryview directly:
            img_data = img_data.tobytes()
        #"cairo.ImageSurface.create_for_data" is not implemented in GTK3! ARGH!
        # http://cairographics.org/documentation/pycairo/3/reference/surfaces.html#cairo.ImageSurface.create_for_data
        # "Not yet available in Python 3"
        #
        #It is available in the cffi cairo bindings, which can be used instead of pycairo
        # but then we can't use it from the draw callbacks:
        # https://mail.gnome.org/archives/python-hackers-list/2011-December/msg00004.html
        # "PyGObject just lacks the glue code that allows it to pass the statically-wrapped
        # cairo.Pattern to introspected methods"

        if not is_gtk3() and rgb_format in ("ARGB", "XRGB"):
            #the pixel format is also what cairo expects
            #maybe we should also check that the stride is acceptable for cairo?
            #cairo_stride = cairo.ImageSurface.format_stride_for_width(cairo_format, width)
            #log("cairo_stride=%s, stride=%s", cairo_stride, rowstride)
            img_surface = cairo.ImageSurface.create_for_data(
                img_data, cairo_format, width, height, rowstride)
            return self.cairo_paint_surface(img_surface, x, y)

        if not is_gtk3() and rgb_format in ("RGBA", "RGBX"):
            #with GTK2, we can use a pixbuf from RGB(A) pixels
            if rgb_format == "RGBA":
                #we have to unpremultiply for pixbuf!
                img_data = self.unpremultiply(img_data)
            pixbuf = pixbuf_new_from_data(img_data, COLORSPACE_RGB, has_alpha,
                                          8, width, height, rowstride)
            return self.cairo_paint_pixbuf(pixbuf, x, y)

        #PIL fallback
        PIL = get_codec("PIL")
        if has_alpha:
            oformat = "RGBA"
        else:
            oformat = "RGB"
        img = PIL.Image.frombuffer(oformat, (width, height), img_data, "raw",
                                   rgb_format, rowstride, 1)
        #This is insane, the code below should work, but it doesn't:
        # img_data = bytearray(img.tostring('raw', oformat, 0, 1))
        # pixbuf = pixbuf_new_from_data(img_data, COLORSPACE_RGB, True, 8, width, height, rowstride)
        # success = self.cairo_paint_pixbuf(pixbuf, x, y)
        #So we still rountrip via PNG:
        png = BytesIOClass()
        img.save(png, format="PNG")
        reader = BytesIOClass(png.getvalue())
        png.close()
        img = cairo.ImageSurface.create_from_png(reader)
        return self.cairo_paint_surface(img, x, y)
Пример #5
0
 def set_icon_from_data(self,
                        pixels,
                        has_alpha,
                        w,
                        h,
                        rowstride,
                        options={}):
     tray_icon = pixbuf_new_from_data(pixels, COLORSPACE_RGB, has_alpha, 8,
                                      w, h, rowstride)
     self.macapp.set_dock_icon_pixbuf(tray_icon)
     self.icon_timestamp = monotonic_time()
Пример #6
0
    def _do_paint_rgb(self, cairo_format, has_alpha, img_data, x, y, width, height, rowstride, options):
        """ must be called from UI thread """
        log("cairo._do_paint_rgb(%s, %s, %s bytes,%s,%s,%s,%s,%s,%s)", cairo_format, has_alpha, len(img_data), x, y, width, height, rowstride, options)
        rgb_format = options.strget("rgb_format", "RGB")
        if _memoryview and isinstance(img_data, _memoryview):
            #Pixbuf cannot use the memoryview directly:
            img_data = img_data.tobytes()
        #"cairo.ImageSurface.create_for_data" is not implemented in GTK3! ARGH!
        # http://cairographics.org/documentation/pycairo/3/reference/surfaces.html#cairo.ImageSurface.create_for_data
        # "Not yet available in Python 3"
        #
        #It is available in the cffi cairo bindings, which can be used instead of pycairo
        # but then we can't use it from the draw callbacks:
        # https://mail.gnome.org/archives/python-hackers-list/2011-December/msg00004.html
        # "PyGObject just lacks the glue code that allows it to pass the statically-wrapped
        # cairo.Pattern to introspected methods"

        if not is_gtk3() and rgb_format in ("ARGB", "XRGB"):
            #the pixel format is also what cairo expects
            #maybe we should also check that the stride is acceptable for cairo?
            #cairo_stride = cairo.ImageSurface.format_stride_for_width(cairo_format, width)
            #log("cairo_stride=%s, stride=%s", cairo_stride, rowstride)
            img_surface = cairo.ImageSurface.create_for_data(img_data, cairo_format, width, height, rowstride)
            return self.cairo_paint_surface(img_surface, x, y)

        if not is_gtk3() and rgb_format in ("RGBA", "RGBX"):
            #with GTK2, we can use a pixbuf from RGB(A) pixels
            if rgb_format=="RGBA":
                #we have to unpremultiply for pixbuf!
                img_data = self.unpremultiply(img_data)
            pixbuf = pixbuf_new_from_data(img_data, COLORSPACE_RGB, has_alpha, 8, width, height, rowstride)
            return self.cairo_paint_pixbuf(pixbuf, x, y)

        #PIL fallback
        PIL = get_codec("PIL")
        if has_alpha:
            oformat = "RGBA"
        else:
            oformat = "RGB"
        img = PIL.Image.frombuffer(oformat, (width,height), img_data, "raw", rgb_format, rowstride, 1)
        #This is insane, the code below should work, but it doesn't:
        # img_data = bytearray(img.tostring('raw', oformat, 0, 1))
        # pixbuf = pixbuf_new_from_data(img_data, COLORSPACE_RGB, True, 8, width, height, rowstride)
        # success = self.cairo_paint_pixbuf(pixbuf, x, y)
        #So we still rountrip via PNG:
        png = BytesIOClass()
        img.save(png, format="PNG")
        reader = BytesIOClass(png.getvalue())
        png.close()
        img = cairo.ImageSurface.create_from_png(reader)
        return self.cairo_paint_surface(img, x, y)
Пример #7
0
 def set_icon_from_data(self, pixels, has_alpha, w, h, rowstride, _options=None):
     #use a temporary file (yuk)
     from xpra.gtk_common.gtk_util import COLORSPACE_RGB, pixbuf_new_from_data
     import tempfile
     try:
         filename = tempfile.mkstemp(suffix=".png")[1]
         log("set_icon_from_data%s using temporary file %s",
             ("%s pixels" % len(pixels), has_alpha, w, h, rowstride), filename)
         tray_icon = pixbuf_new_from_data(pixels, COLORSPACE_RGB, has_alpha, 8, w, h, rowstride)
         tray_icon.save(filename, "png")
         self.do_set_icon_from_file(filename)
     finally:
         if DELETE_TEMP_FILE:
             os.unlink(filename)
Пример #8
0
 def set_icon_from_data(self, pixels, has_alpha, w, h, rowstride, _options=None):
     self.clean_last_tmp_icon()
     #use a temporary file (yuk)
     from xpra.gtk_common.gtk_util import COLORSPACE_RGB, pixbuf_new_from_data, pixbuf_save_to_memory
     import tempfile
     tmp_dir = osexpand(get_xpra_tmp_dir())
     if not os.path.exists(tmp_dir):
         os.mkdir(tmp_dir, 0o755)
     self.tmp_filename = tempfile.mkstemp(prefix="tray", suffix=".png", dir=tmp_dir)[1]
     log("set_icon_from_data%s using temporary file %s",
         ("%s pixels" % len(pixels), has_alpha, w, h, rowstride), self.tmp_filename)
     tray_icon = pixbuf_new_from_data(pixels, COLORSPACE_RGB, has_alpha, 8, w, h, rowstride)
     png_data = pixbuf_save_to_memory(tray_icon)
     with open(self.tmp_filename, "wb") as f:
         f.write(png_data)
     self.do_set_icon_from_file(self.tmp_filename)
Пример #9
0
 def update_icon(self, width, height, coding, data):
     log("%s.update_icon(%s, %s, %s, %s bytes)", self, width, height, coding, len(data))
     coding = bytestostr(coding)
     if coding == "premult_argb32":
         if unpremultiply_argb is None:
             #we could use PIL here with mode 'RGBa'
             log.warn("cannot process premult_argb32 icon without the argb module")
             return
         #we usually cannot do in-place and this is not performance critical
         data = byte_buffer_to_buffer(unpremultiply_argb(data))
         pixbuf = pixbuf_new_from_data(data, COLORSPACE_RGB, True, 8, width, height, width*4)
     else:
         loader = PixbufLoader()
         loader.write(data)
         loader.close()
         pixbuf = loader.get_pixbuf()
     log("%s.set_icon(%s)", self, pixbuf)
     self.set_icon(pixbuf)
Пример #10
0
 def update_icon(self, width, height, coding, data):
     log("%s.update_icon(%s, %s, %s, %s bytes)", self, width, height,
         coding, len(data))
     coding = bytestostr(coding)
     if coding == "premult_argb32":
         if unpremultiply_argb is None:
             #we could use PIL here with mode 'RGBa'
             log.warn(
                 "cannot process premult_argb32 icon without the argb module"
             )
             return
         #we usually cannot do in-place and this is not performance critical
         data = byte_buffer_to_buffer(unpremultiply_argb(data))
         pixbuf = pixbuf_new_from_data(data, COLORSPACE_RGB, True, 8, width,
                                       height, width * 4)
     else:
         loader = PixbufLoader()
         loader.write(data)
         loader.close()
         pixbuf = loader.get_pixbuf()
     log("%s.set_icon(%s)", self, pixbuf)
     self.set_icon(pixbuf)