Esempio n. 1
0
 def parse_hints(self, h) -> dict:
     hints = {}
     for x in ("action-icons", "category", "desktop-entry", "resident",
               "transient", "x", "y", "urgency"):
         v = h.get(x)
         if v is not None:
             hints[x] = native_to_dbus(v)
     image_data = h.get("image-data")
     if image_data and bytestostr(image_data[0]) == "png":
         try:
             from xpra.codecs.pillow.decoder import open_only
             img_data = image_data[3]
             img = open_only(img_data, ("png", ))
             w, h = img.size
             channels = len(img.mode)
             rowstride = w * channels
             has_alpha = img.mode == "RGBA"
             pixel_data = bytearray(img.tobytes("raw", img.mode))
             log.info("pixel_data=%s", type(pixel_data))
             args = w, h, rowstride, has_alpha, 8, channels, pixel_data
             hints["image-data"] = tuple(native_to_dbus(x) for x in args)
             #hints["image-data"] = args
         except Exception as e:
             log("parse_hints(%s) error on image-data=%s",
                 h,
                 image_data,
                 exc_info=True)
             log.error("Error parsing notification image:")
             log.error(" %s", e)
     log("parse_hints(%s)=%s", h, hints)
     #return dbus.types.Dictionary(hints, signature="sv")
     return hints
Esempio n. 2
0
 def set_image_data(self, dtype, data):
     img_type = dtype.split("/")[1]  #ie: "png"
     from xpra.codecs.pillow.decoder import open_only
     img = open_only(data, (img_type, ))
     for img_type, macos_types in {
             "png": [NSPasteboardTypePNG, "image/png"],
             "tiff": [NSTIFFPboardType, "image/tiff"],
             "jpeg": ["public.jpeg", "image/jpeg"],
     }.items():
         try:
             save_img = img
             if img_type == "jpeg" and img.mode == "RGBA":
                 save_img = img.convert("RGB")
             buf = BytesIO()
             save_img.save(buf, img_type)
             data = buf.getvalue()
             buf.close()
             self.pasteboard.clearContents()
             nsdata = NSData.dataWithData_(data)
             for t in macos_types:
                 r = self.pasteboard.setData_forType_(nsdata, t)
                 log("set '%s' data type: %s", t, r)
         except Exception as e:
             log("set_image_data(%s, ..)", dtype, exc_info=True)
             log.error("Error: failed to copy %s image to clipboard",
                       img_type)
             log.error(" %s", e)
Esempio n. 3
0
 def filter_data(self,
                 dtype=None,
                 dformat=None,
                 data=None,
                 trusted=False,
                 output_dtype=None):
     log("filter_data(%s, %s, %i %s, %s, %s)", dtype, dformat, len(data),
         type(data), trusted, output_dtype)
     if not data:
         return data
     IMAGE_OVERLAY = os.environ.get("XPRA_CLIPBOARD_IMAGE_OVERLAY", None)
     if IMAGE_OVERLAY and not os.path.exists(IMAGE_OVERLAY):
         IMAGE_OVERLAY = None
     IMAGE_STAMP = envbool("XPRA_CLIPBOARD_IMAGE_STAMP", False)
     SANITIZE_IMAGES = envbool("XPRA_SANITIZE_IMAGES", True)
     if dtype in ("image/png", "image/jpeg", "image/tiff") and (
         (output_dtype is not None and dtype != output_dtype) or IMAGE_STAMP
             or IMAGE_OVERLAY or (SANITIZE_IMAGES and not trusted)):
         from xpra.codecs.pillow.decoder import open_only
         img_type = dtype.split("/")[-1]
         img = open_only(data, (img_type, ))
         has_alpha = img.mode == "RGBA"
         if not has_alpha and IMAGE_OVERLAY:
             img = img.convert("RGBA")
         w, h = img.size
         if IMAGE_OVERLAY:
             from PIL import Image  #@UnresolvedImport
             overlay = Image.open(IMAGE_OVERLAY)
             if overlay.mode != "RGBA":
                 log.warn("Warning: cannot use overlay image '%s'",
                          IMAGE_OVERLAY)
                 log.warn(" invalid mode '%s'", overlay.mode)
             else:
                 log("adding clipboard image overlay to %s", dtype)
                 overlay_resized = overlay.resize((w, h), Image.ANTIALIAS)
                 composite = Image.alpha_composite(img, overlay_resized)
                 if not has_alpha and img.mode == "RGBA":
                     composite = composite.convert("RGB")
                 img = composite
         if IMAGE_STAMP:
             log("adding clipboard image stamp to %s", dtype)
             from datetime import datetime
             from PIL import ImageDraw
             img_draw = ImageDraw.Draw(img)
             w, h = img.size
             img_draw.text((10, max(0, h // 2 - 16)),
                           'via Xpra, %s' % datetime.now().isoformat(),
                           fill='black')
         #now save it:
         img_type = (output_dtype or dtype).split("/")[-1]
         buf = BytesIO()
         img.save(buf, img_type.upper())  #ie: "PNG"
         data = buf.getvalue()
         buf.close()
     return data
Esempio n. 4
0
def notify(hwnd, app_id, title, message, timeout=5000, icon=None):
    log("notify%s", (hwnd, app_id, title, message, timeout, icon))
    if timeout <= 0:
        timeout = 5000
    szInfo = chop_string(message, 255, False)  #prevent overflow
    szInfoTitle = chop_string(title, 63)
    hicon = 0
    if icon:
        try:
            from PIL import Image
            from xpra.codecs.pillow.decoder import open_only
            w, h, data = icon[1:4]
            img = open_only(data)
            from xpra.platform.win32.win32_NotifyIcon import image_to_ICONINFO
            iw = GetSystemMetrics(SM_CXSMICON)
            ih = GetSystemMetrics(SM_CYSMICON)
            if w != iw or h != ih:
                img = img.resize((iw, ih), Image.ANTIALIAS)
                log("notification icon resized to %s", img.size)
            hicon = image_to_ICONINFO(img)
            log("notify: image_to_ICONINFO(%s)=%#x", img, hicon)
        except Exception as e:
            log("notify%s", (hwnd, app_id, title, message, timeout, icon),
                exc_info=True)
            log.error("Error: failed to set notification icon:")
            log.error(" %s", e)

    from xpra.platform.win32.win32_NotifyIcon import Shell_NotifyIconA, XPRA_GUID, getNOTIFYICONDATAClass

    nc = getNOTIFYICONDATAClass(tip_size=128)
    nid = nc()
    nid.cbSize = sizeof(nc)
    nid.hWnd = hwnd
    nid.uID = app_id
    nid.uFlags = NIF_INFO
    nid.guidItem = XPRA_GUID
    try:
        nid.szInfo = szInfo
    except:
        nid.szInfo = szInfo.decode()
    v = chop_string(title, 63)
    try:
        nid.szInfoTitle = szInfoTitle
    except:
        nid.szInfoTitle = szInfoTitle.decode()
    nid.uVersion = timeout
    nid.dwInfoFlags = NIIF_INFO
    if hicon:
        nid.hIcon = nid.hBalloonIcon = hicon
        nid.dwInfoFlags = NIIF_USER
    Shell_NotifyIconA(NIM_MODIFY, byref(nid))
    log("notify using %s", Shell_NotifyIconA)
Esempio n. 5
0
def get_appimage(app_name, icondata=None, menu_icon_size=24):
    pixbuf = None
    if app_name and not icondata:
        #try to load from our icons:
        nstr = bytestostr(app_name).lower()
        icon_filename = os.path.join(get_icon_dir(), "%s.png" % nstr)
        if os.path.exists(icon_filename):
            pixbuf = GdkPixbuf.Pixbuf.new_from_file(icon_filename)

    def err(e):
        log("failed to load icon", exc_info=True)
        log.error("Error: failed to load icon data for '%s':",
                  bytestostr(app_name))
        log.error(" %s", e)
        log.error(" data=%s", repr_ellipsized(icondata))

    if not pixbuf and icondata:
        #gtk pixbuf loader:
        try:
            pixbuf = load_pixbuf(icondata)
        except Exception as e:
            log("pixbuf loader failed", exc_info=True)
            if re.findall(INKSCAPE_RE, icondata):
                try:
                    pixbuf = load_pixbuf(re.sub(INKSCAPE_RE, b"", icondata))
                    e = None
                except Exception:
                    #there is almost no chance pillow will be able to load it
                    #(it doesn't even have svg support at time of writing)
                    #so don't bother showing another error for the same data:
                    icondata = None
            if e:
                err(e)
    if not pixbuf and icondata:
        #let's try pillow:
        try:
            from xpra.codecs.pillow.decoder import open_only  #pylint: disable=import-outside-toplevel
            img = open_only(icondata)
            has_alpha = img.mode == "RGBA"
            width, height = img.size
            rowstride = width * (3 + int(has_alpha))
            pixbuf = get_pixbuf_from_data(img.tobytes(), has_alpha, width,
                                          height, rowstride)
            return scaled_image(pixbuf, icon_size=menu_icon_size)
        except Exception:
            err(e)
    if pixbuf:
        return scaled_image(pixbuf, icon_size=menu_icon_size)
    return None
Esempio n. 6
0
 def filter_data(self, target, dtype=None, dformat=None, data=None):
     log("filter_data(%s, %s, %s, ..)", target, dtype, dformat)
     IMAGE_OVERLAY = os.environ.get("XPRA_CLIPBOARD_IMAGE_OVERLAY", None)
     if IMAGE_OVERLAY and not os.path.exists(IMAGE_OVERLAY):
         IMAGE_OVERLAY = None
     IMAGE_STAMP = envbool("XPRA_CLIPBOARD_IMAGE_STAMP", True)
     if dtype in ("image/png", ) and (IMAGE_STAMP or IMAGE_OVERLAY):
         from xpra.codecs.pillow.decoder import open_only
         img = open_only(data, ("png", ))
         has_alpha = img.mode == "RGBA"
         if not has_alpha and IMAGE_OVERLAY:
             img = img.convert("RGBA")
         w, h = img.size
         if IMAGE_OVERLAY:
             from PIL import Image  #@UnresolvedImport
             overlay = Image.open(IMAGE_OVERLAY)
             if overlay.mode != "RGBA":
                 log.warn("Warning: cannot use overlay image '%s'",
                          IMAGE_OVERLAY)
                 log.warn(" invalid mode '%s'", overlay.mode)
             else:
                 log("adding clipboard image overlay to %s", dtype)
                 overlay_resized = overlay.resize((w, h), Image.ANTIALIAS)
                 composite = Image.alpha_composite(img, overlay_resized)
                 if not has_alpha and img.mode == "RGBA":
                     composite = composite.convert("RGB")
                 img = composite
         if IMAGE_STAMP:
             log("adding clipboard image stamp to %s", dtype)
             from datetime import datetime
             from PIL import ImageDraw
             img_draw = ImageDraw.Draw(img)
             w, h = img.size
             img_draw.text((10, max(0, h // 2 - 16)),
                           'via Xpra, %s' % datetime.now().isoformat(),
                           fill='black')
         buf = BytesIO()
         img.save(buf, "PNG")
         data = buf.getvalue()
         buf.close()
     return data
Esempio n. 7
0
def notify(hwnd, app_id, title, message, timeout=5000, icon=None):
    nid = PyNOTIFYICONDATA()
    nid.hWnd = hwnd
    nid.uID = app_id
    nid.uFlags = NIF_INFO
    nid.guidItem = XPRA_GUID_BYTES
    nid.szInfo = chop_string(message, 255, False)  #prevent overflow
    nid.szInfoTitle = chop_string(title, 63)
    if timeout <= 0:
        timeout = 5000
    nid.uTimeoutOrVersion = timeout
    #if no icon is supplied, we can use:
    # NIIF_INFO, NIIF_WARNING or NIIF_ERROR
    nid.dwInfoFlags = NIIF_INFO
    if icon:
        try:
            from PIL import Image
            from xpra.codecs.pillow.decoder import open_only
            w, h, data = icon[1:4]
            img = open_only(data)
            from xpra.platform.win32.win32_NotifyIcon import image_to_ICONINFO
            iw = GetSystemMetrics(SM_CXSMICON)
            ih = GetSystemMetrics(SM_CYSMICON)
            if w != iw or h != ih:
                img = img.resize((iw, ih), Image.ANTIALIAS)
                log("notification icon resized to %s", img.size)
            hicon = image_to_ICONINFO(img)
            log("notify: image_to_ICONINFO(%s)=%#x", img, hicon)
            nid.hIcon = hicon
            nid.hBalloonIcon = hicon
        except Exception as e:
            log("notify%s", (hwnd, app_id, title, message, timeout, icon),
                exc_info=True)
            log.error("Error: failed to set notification icon:")
            log.error(" %s", e)
        else:
            nid.dwInfoFlags = NIIF_USER
    Shell_NotifyIcon = windll.shell32.Shell_NotifyIcon
    Shell_NotifyIcon(NIM_MODIFY, nid.pack())
    log("notify using %s", Shell_NotifyIcon)
Esempio n. 8
0
def get_appimage(app_name, icondata=None, menu_icon_size=24):
    pixbuf = None
    if app_name and not icondata:
        #try to load from our icons:
        nstr = bytestostr(app_name).lower()
        icon_filename = os.path.join(get_icon_dir(), "%s.png" % nstr)
        if os.path.exists(icon_filename):
            pixbuf = GdkPixbuf.Pixbuf.new_from_file(icon_filename)
    if not pixbuf and icondata:
        #gtk pixbuf loader:
        try:
            loader = GdkPixbuf.PixbufLoader()
            loader.write(icondata)
            loader.close()
            pixbuf = loader.get_pixbuf()
        except Exception as e:
            log("pixbuf loader failed", exc_info=True)
            log.error("Error: failed to load icon data for '%s':",
                      bytestostr(app_name))
            log.error(" %s", e)
            log.error(" data=%s", repr_ellipsized(icondata))
    if not pixbuf and icondata:
        #let's try pillow:
        try:
            from xpra.codecs.pillow.decoder import open_only
            img = open_only(icondata)
            has_alpha = img.mode == "RGBA"
            width, height = img.size
            rowstride = width * (3 + int(has_alpha))
            pixbuf = get_pixbuf_from_data(img.tobytes(), has_alpha, width,
                                          height, rowstride)
            return scaled_image(pixbuf, icon_size=menu_icon_size)
        except Exception:
            log.error("Error: failed to load icon data for %s",
                      bytestostr(app_name),
                      exc_info=True)
            log.error(" data=%s", repr_ellipsized(icondata))
    if pixbuf:
        return scaled_image(pixbuf, icon_size=menu_icon_size)
    return None
Esempio n. 9
0
 def process_webcam_frame(self, device_id, frame_no, encoding, w, h, data):
     webcam = self.webcam_forwarding_devices.get(device_id)
     log(
         "process_webcam_frame: device %s, frame no %i: %s %ix%i, %i bytes, webcam=%s",
         device_id, frame_no, encoding, w, h, len(data), webcam)
     assert encoding and w and h and data
     if not webcam:
         log.error("Error: webcam forwarding is not active, dropping frame")
         self.send_webcam_stop(device_id, "not started")
         return False
     try:
         from xpra.codecs.pillow.decoder import open_only
         assert encoding in self.webcam_encodings, "invalid encoding specified: %s (must be one of %s)" % (
             encoding, self.webcam_encodings)
         rgb_pixel_format = "BGRX"  #BGRX
         img = open_only(data, (encoding, ))
         pixels = img.tobytes('raw', rgb_pixel_format)
         from xpra.codecs.image_wrapper import ImageWrapper
         bgrx_image = ImageWrapper(0,
                                   0,
                                   w,
                                   h,
                                   pixels,
                                   rgb_pixel_format,
                                   32,
                                   w * 4,
                                   planes=ImageWrapper.PACKED)
         src_format = webcam.get_src_format()
         if not src_format:
             #closed / closing
             return False
         #one of those two should be present
         try:
             csc_mod = "csc_libyuv"
             from xpra.codecs.csc_libyuv.colorspace_converter import (  #@UnresolvedImport
                 get_input_colorspaces, get_output_colorspaces,
                 ColorspaceConverter,
             )
         except ImportError:
             self.send_webcam_stop(device_id, "no csc module")
             return False
         try:
             assert rgb_pixel_format in get_input_colorspaces(
             ), "unsupported RGB pixel format %s" % rgb_pixel_format
             assert src_format in get_output_colorspaces(
                 rgb_pixel_format
             ), "unsupported output colourspace format %s" % src_format
         except Exception as e:
             log.error("Error: cannot convert %s to %s using %s:",
                       rgb_pixel_format, src_format, csc_mod)
             log.error(" input-colorspaces: %s",
                       csv(get_input_colorspaces()))
             log.error(" output-colorspaces: %s",
                       csv(get_output_colorspaces(rgb_pixel_format)))
             self.send_webcam_stop(device_id, "csc format error")
             return False
         tw = webcam.get_width()
         th = webcam.get_height()
         csc = ColorspaceConverter()
         csc.init_context(w, h, rgb_pixel_format, tw, th, src_format)
         image = csc.convert_image(bgrx_image)
         webcam.push_image(image)
         #tell the client all is good:
         self.send_webcam_ack(device_id, frame_no)
         return True
     except Exception as e:
         log("error on %ix%i frame %i using encoding %s",
             w,
             h,
             frame_no,
             encoding,
             exc_info=True)
         log.error("Error processing webcam frame:")
         msg = str(e)
         if not msg:
             msg = "unknown error"
             log.error(" %s error" % webcam, exc_info=True)
         log.error(" %s", msg)
         self.send_webcam_stop(device_id, msg)
         self.stop_virtual_webcam(device_id)
         return False