Example #1
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     if len(cursor_data)>=9 and cursor_types:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name, gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels)<w*h*4:
         import binascii
         cursorlog.warn("not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)", w*h*4, len(pixels), binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w*4)
     x = max(0, min(xhot, w-1))
     y = max(0, min(yhot, h-1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data)>=11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog("new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s", xhot,yhot, serial, w,h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw>0 and fh>0 and (w!=fw or h!=fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w<=fw and h<=fh:
             cursorlog("pasting cursor of size %ix%i onto clear pixbuf of size %ix%i", w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0"*fw*fh*4, True, fw, fh, fw*4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i", w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w)/fw, float(h)/fh
             x, y = int(x/xratio), int(y/yratio)
     elif w>cmaxw or h>cmaxh or (csize>0 and (csize<w or csize<h)):
         ratio = max(float(w)/cmaxw, float(h)/cmaxh, float(max(w,h))/csize)
         x, y, w, h = int(x/ratio), int(y/ratio), int(w/ratio), int(h/ratio)
         cursorlog("downscaling cursor %s by %.2f: %sx%s", pixbuf, ratio, w, h)
         cursor_pixbuf = pixbuf.scale_simple(w, h, INTERP_BILINEAR)
     else:
         cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w-1))
     y = max(0, min(y, h-1))
     return new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)
Example #2
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 pixbuf_save_to_memory, get_pixbuf_from_data
     tray_icon = get_pixbuf_from_data(pixels, has_alpha, w, h, rowstride)
     png_data = pixbuf_save_to_memory(tray_icon)
     tmp_dir = osexpand(get_xpra_tmp_dir())
     if not os.path.exists(tmp_dir):
         os.mkdir(tmp_dir, 0o755)
     fd = None
     try:
         fd, self.tmp_filename = tempfile.mkstemp(prefix="tray",
                                                  suffix=".png",
                                                  dir=tmp_dir)
         log("set_icon_from_data%s using temporary file %s",
             ("%s pixels" % len(pixels), has_alpha, w, h, rowstride),
             self.tmp_filename)
         os.write(fd, png_data)
     except OSError as e:
         log("error saving temporary file", exc_info=True)
         log.error("Error saving icon data to temporary file")
         log.error(" %s", e)
         return
     finally:
         if fd:
             os.fchmod(fd, 0o644)
             os.close(fd)
     self.do_set_icon_from_file(self.tmp_filename)
Example #3
0
def cairo_paint_pointer_overlay(context, cursor_data, px: int, py: int,
                                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 = get_pixbuf_from_data(img_data, True, cw, ch, cw * 4)
    context.set_operator(cairo.OPERATOR_OVER)
    Gdk.cairo_set_source_pixbuf(context, pixbuf, 0, 0)
    context.paint()
Example #4
0
 def populate_table(self):
     commands_info = typedict(self.client.server_last_info).dictget("commands")
     if self.commands_info!=commands_info and commands_info:
         log("populate_table() new commands_info=%s", commands_info)
         self.commands_info = commands_info
         if self.table:
             self.alignment.remove(self.table)
         tb = TableBuilder(rows=1, columns=2, row_spacings=15)
         self.table = tb.get_table()
         headers = [gtk.Label(""), gtk.Label("PID"), gtk.Label("Command"), gtk.Label("Exit Code")]
         if self.client.server_commands_signals:
             headers.append(gtk.Label("Send Signal"))
         tb.add_row(*headers)
         for procinfo in self.commands_info.values():
             if not isinstance(procinfo, dict):
                 continue
             #some records aren't procinfos:
             pi = typedict(procinfo)
             command = pi.strlistget("command")
             pid = pi.intget("pid", 0)
             returncode = pi.intget("returncode", None)
             if pid>0 and command:
                 cmd_str = " ".join(command)
                 rstr = ""
                 if returncode is not None:
                     rstr = "%s" % returncode
                 #find the windows matching this pid
                 windows = ()
                 from xpra.client import mixin_features
                 if mixin_features.windows:
                     windows = tuple(w for w in self.client._id_to_window.values() if getattr(w, "_metadata", {}).get("pid")==pid)
                     log("windows matching pid=%i: %s", pid, windows)
                 icon = gtk.Label()
                 if windows:
                     try:
                         icons = tuple(getattr(w, "_current_icon", None) for w in windows)
                         icons = tuple(x for x in icons if x is not None)
                         log("icons: %s", icons)
                         if icons:
                             from PIL import Image
                             img = icons[0].resize((24, 24), Image.ANTIALIAS)
                             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)
                             icon = gtk.Image()
                             icon.set_from_pixbuf(pixbuf)
                     except Exception:
                         log("failed to get window icon", exc_info=True)
                 items = [icon, gtk.Label("%s" % pid), gtk.Label(cmd_str), gtk.Label(rstr)]
                 if self.client.server_commands_signals:
                     if returncode is None:
                         items.append(self.signal_button(pid))
                     else:
                         items.append(gtk.Label(""))
                 tb.add_row(*items)
         self.alignment.add(self.table)
         self.table.show_all()
     self.client.send_info_request()
     return True
Example #5
0
 def set_icon_from_pixbuf(self, tray_icon):
     if not tray_icon or not self.tray_widget:
         return
     tw, th = self.get_geometry()[2:4]
     if (tw <= 2 or th <= 2) or (tw == 200 and th == 200):
         log("bogus tray icon size: %ix%i", tw, th)
         tw = th = 48
     w = tray_icon.get_width()
     h = tray_icon.get_height()
     log("set_icon_from_pixbuf(%s) geometry=%s, icon size=%s", tray_icon,
         self.get_geometry(), (w, h))
     if tw != w or th != h:
         if tw != th and not PYTHON3:
             #paste the scaled icon in the middle of the rectangle:
             minsize = min(tw, th)
             new_icon = get_pixbuf_from_data(b"\0" * tw * th * 4, True, tw,
                                             th, tw * 4)
             scaled_w, scaled_h = minsize, minsize
             if tw == 24 and th == 64:
                 #special case for the gnome-shell dimensions - stretch height..
                 scaled_w, scaled_h = 24, 48
             tray_icon = tray_icon.scale_simple(scaled_w, scaled_h,
                                                INTERP_HYPER)
             tray_icon.copy_area(0, 0, scaled_w, scaled_h, new_icon,
                                 (tw - scaled_w) // 2, (th - scaled_h) // 2)
             tray_icon = new_icon
         else:
             tray_icon = tray_icon.scale_simple(tw, th, INTERP_HYPER)
     self.tray_widget.set_from_pixbuf(tray_icon)
     self.icon_timestamp = monotonic_time()
Example #6
0
 def set_icon_from_data(self,
                        pixels,
                        has_alpha,
                        w,
                        h,
                        rowstride,
                        _options={}):
     tray_icon = get_pixbuf_from_data(pixels, has_alpha, w, h, rowstride)
     self.set_icon_from_pixbuf(tray_icon)
Example #7
0
 def set_icon_from_data(self,
                        pixels,
                        has_alpha,
                        w,
                        h,
                        rowstride,
                        options=None):
     tray_icon = get_pixbuf_from_data(pixels, has_alpha, w, h, rowstride)
     self.macapp.set_dock_icon_pixbuf(tray_icon)
     self.icon_timestamp = monotonic()
Example #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)

    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
 def update_icon(self, width, height, coding, data):
     coding = bytestostr(coding)
     iconlog("%s.update_icon(%s, %s, %s, %s bytes)", self, width, height, coding, len(data))
     if PYTHON3 and WIN32:
         iconlog("not setting icon to prevent crashes..")
         return
     if coding == "premult_argb32":            #we usually cannot do in-place and this is not performance critical
         data = unpremultiply_argb(data)
         rgba = memoryview_to_bytes(bgra_to_rgba(data))
         pixbuf = get_pixbuf_from_data(rgba, True, width, height, width*4)
     else:
         loader = PixbufLoader()
         loader.write(data)
         loader.close()
         pixbuf = loader.get_pixbuf()
     #for debugging, save to a file so we can see it:
     #pixbuf.save("C-%s-%s.png" % (self._id, int(time.time())), "png")
     iconlog("%s.set_icon(%s)", self, pixbuf)
     self.set_icon(pixbuf)
Example #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 = unpremultiply_argb(data)
         rgba = byte_buffer_to_buffer(bgra_to_rgba(data))
         pixbuf = get_pixbuf_from_data(rgba, True, 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)
 def update_icon(self, width, height, coding, data):
     coding = bytestostr(coding)
     iconlog("%s.update_icon(%s, %s, %s, %s bytes)", self, width, height,
             coding, len(data))
     if PYTHON3 and WIN32:
         iconlog("not setting icon to prevent crashes..")
         return
     if coding == "premult_argb32":  #we usually cannot do in-place and this is not performance critical
         data = unpremultiply_argb(data)
         rgba = memoryview_to_bytes(bgra_to_rgba(data))
         pixbuf = get_pixbuf_from_data(rgba, True, width, height, width * 4)
     else:
         loader = PixbufLoader()
         loader.write(data)
         loader.close()
         pixbuf = loader.get_pixbuf()
     #for debugging, save to a file so we can see it:
     #pixbuf.save("C-%s-%s.png" % (self._id, int(time.time())), "png")
     iconlog("%s.set_icon(%s)", self, pixbuf)
     self.set_icon(pixbuf)
Example #12
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
Example #13
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 = unpremultiply_argb(data)
         rgba = byte_buffer_to_buffer(bgra_to_rgba(data))
         pixbuf = get_pixbuf_from_data(rgba, True, 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)
Example #14
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     cursorlog(
         "make_cursor: has-name=%s, has-cursor-types=%s, xscale=%s, yscale=%s, USE_LOCAL_CURSORS=%s",
         len(cursor_data) >= 9, bool(cursor_types), self.xscale,
         self.yscale, USE_LOCAL_CURSORS)
     #named cursors cannot be scaled (round to 10 to compare so 0.95 and 1.05 are considered the same as 1.0, no scaling):
     if len(cursor_data) >= 9 and cursor_types and iround(
             self.xscale * 10) == 10 and iround(self.yscale * 10) == 10:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name and USE_LOCAL_CURSORS:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name,
                           gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels) < w * h * 4:
         import binascii
         cursorlog.warn(
             "not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)",
             w * h * 4, len(pixels),
             binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w * 4)
     x = max(0, min(xhot, w - 1))
     y = max(0, min(yhot, h - 1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data) >= 11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog(
         "new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s",
         xhot, yhot, serial, w, h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw > 0 and fh > 0 and (w != fw or h != fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w <= fw and h <= fh:
             cursorlog(
                 "pasting cursor of size %ix%i onto clear pixbuf of size %ix%i",
                 w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0" * fw * fh * 4, True,
                                                  fw, fh, fw * 4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i",
                       w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w) / fw, float(h) / fh
             x, y = iround(x / xratio), iround(y / yratio)
     else:
         sx, sy, sw, sh = x, y, w, h
         #scale the cursors:
         if self.xscale != 1 or self.yscale != 1:
             sx, sy, sw, sh = self.srect(x, y, w, h)
         sw = max(1, sw)
         sh = max(1, sh)
         #ensure we honour the max size if there is one:
         if (cmaxw > 0 and sw > cmaxw) or (cmaxh > 0 and sh > cmaxh):
             ratio = 1.0
             if cmaxw > 0:
                 ratio = max(ratio, float(w) / cmaxw)
             if cmaxh > 0:
                 ratio = max(ratio, float(h) / cmaxh)
             cursorlog("clamping cursor size to %ix%i using ratio=%s",
                       cmaxw, cmaxh, ratio)
             sx, sy, sw, sh = iround(x / ratio), iround(y / ratio), min(
                 cmaxw, iround(w / ratio)), min(cmaxh, iround(h / ratio))
         if sw != w or sh != h:
             cursorlog(
                 "scaling cursor from %ix%i hotspot at %ix%i to %ix%i hotspot at %ix%i",
                 w, h, x, y, sw, sh, sx, sy)
             cursor_pixbuf = pixbuf.scale_simple(sw, sh, INTERP_BILINEAR)
             x, y = sx, sy
         else:
             cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w - 1))
     y = max(0, min(y, h - 1))
     try:
         c = new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)
     except RuntimeError as e:
         log.error("Error: failed to create cursor:")
         log.error(" %s", e)
         log.error(" using %s of size %ix%i with hotspot at %ix%i",
                   cursor_pixbuf, w, h, x, y)
         c = None
     return c
Example #15
0
def small_empty_cursor():
	#same as xterm when pressing a modifier key
	w, h = 6, 13
	rgb_data = b"\0"*w*h*4
	pixbuf = get_pixbuf_from_data(rgb_data, True, w, h, w*4)
	return Gdk.Cursor(Gdk.display_get_default(), pixbuf, 0, 11)
Example #16
0
 def set_icon_from_data(self, pixels, has_alpha, w, h, rowstride):
     tray_icon = get_pixbuf_from_data(pixels, has_alpha, w, h, rowstride)
     self.set_icon_from_pixbuf(tray_icon)
Example #17
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     cursorlog("make_cursor: has-name=%s, has-cursor-types=%s, xscale=%s, yscale=%s, USE_LOCAL_CURSORS=%s", len(cursor_data)>=9, bool(cursor_types), self.xscale, self.yscale, USE_LOCAL_CURSORS)
     #named cursors cannot be scaled (round to 10 to compare so 0.95 and 1.05 are considered the same as 1.0, no scaling):
     if len(cursor_data)>=9 and cursor_types and iround(self.xscale*10)==10 and iround(self.yscale*10)==10:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name and USE_LOCAL_CURSORS:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name, gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels)<w*h*4:
         import binascii
         cursorlog.warn("not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)", w*h*4, len(pixels), binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w*4)
     x = max(0, min(xhot, w-1))
     y = max(0, min(yhot, h-1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data)>=11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog("new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s", xhot,yhot, serial, w,h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw>0 and fh>0 and (w!=fw or h!=fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w<=fw and h<=fh:
             cursorlog("pasting cursor of size %ix%i onto clear pixbuf of size %ix%i", w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0"*fw*fh*4, True, fw, fh, fw*4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i", w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w)/fw, float(h)/fh
             x, y = iround(x/xratio), iround(y/yratio)
     else:
         sx, sy, sw, sh = x, y, w, h
         #scale the cursors:
         if self.xscale!=1 or self.yscale!=1:
             sx, sy, sw, sh = self.srect(x, y, w, h)
         sw = max(1, sw)
         sh = max(1, sh)
         #ensure we honour the max size if there is one:
         if (cmaxw>0 and sw>cmaxw) or (cmaxh>0 and sh>cmaxh):
             ratio = 1.0
             if cmaxw>0:
                 ratio = max(ratio, float(w)/cmaxw)
             if cmaxh>0:
                 ratio = max(ratio, float(h)/cmaxh)
             cursorlog("clamping cursor size to %ix%i using ratio=%s", cmaxw, cmaxh, ratio)
             sx, sy, sw, sh = iround(x/ratio), iround(y/ratio), min(cmaxw, iround(w/ratio)), min(cmaxh, iround(h/ratio))
         if sw!=w or sh!=h:
             cursorlog("scaling cursor from %ix%i hotspot at %ix%i to %ix%i hotspot at %ix%i", w, h, x, y, sw, sh, sx, sy)
             cursor_pixbuf = pixbuf.scale_simple(sw, sh, INTERP_BILINEAR)
             x, y = sx, sy
         else:
             cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w-1))
     y = max(0, min(y, h-1))
     try:
         c = new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)
     except RuntimeError as e:
         log.error("Error: failed to create cursor:")
         log.error(" %s", e)
         log.error(" using %s of size %ix%i with hotspot at %ix%i", cursor_pixbuf, w, h, x, y)
         c = None
     return c
Example #18
0
 def make_cursor(self, cursor_data):
     #if present, try cursor ny name:
     display = display_get_default()
     if len(cursor_data) >= 9 and cursor_types:
         cursor_name = bytestostr(cursor_data[8])
         if cursor_name:
             gdk_cursor = cursor_types.get(cursor_name.upper())
             if gdk_cursor is not None:
                 cursorlog("setting new cursor by name: %s=%s", cursor_name,
                           gdk_cursor)
                 return new_Cursor_for_display(display, gdk_cursor)
             else:
                 global missing_cursor_names
                 if cursor_name not in missing_cursor_names:
                     cursorlog("cursor name '%s' not found", cursor_name)
                     missing_cursor_names.add(cursor_name)
     #create cursor from the pixel data:
     w, h, xhot, yhot, serial, pixels = cursor_data[2:8]
     if len(pixels) < w * h * 4:
         import binascii
         cursorlog.warn(
             "not enough pixels provided in cursor data: %s needed and only %s bytes found (%s)",
             w * h * 4, len(pixels),
             binascii.hexlify(pixels)[:100])
         return
     pixbuf = get_pixbuf_from_data(pixels, True, w, h, w * 4)
     x = max(0, min(xhot, w - 1))
     y = max(0, min(yhot, h - 1))
     csize = display.get_default_cursor_size()
     cmaxw, cmaxh = display.get_maximal_cursor_size()
     if len(cursor_data) >= 11:
         ssize = cursor_data[9]
         smax = cursor_data[10]
         cursorlog("server cursor sizes: default=%s, max=%s", ssize, smax)
     cursorlog(
         "new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s, default cursor size is %s, maximum=%s",
         xhot, yhot, serial, w, h, len(pixels), csize, (cmaxw, cmaxh))
     fw, fh = get_fixed_cursor_size()
     if fw > 0 and fh > 0 and (w != fw or h != fh):
         #OS wants a fixed cursor size! (win32 does, and GTK doesn't do this for us)
         if w <= fw and h <= fh:
             cursorlog(
                 "pasting cursor of size %ix%i onto clear pixbuf of size %ix%i",
                 w, h, fw, fh)
             cursor_pixbuf = get_pixbuf_from_data("\0" * fw * fh * 4, True,
                                                  fw, fh, fw * 4)
             pixbuf.copy_area(0, 0, w, h, cursor_pixbuf, 0, 0)
         else:
             cursorlog("scaling cursor from %ix%i to fixed OS size %ix%i",
                       w, h, fw, fh)
             cursor_pixbuf = pixbuf.scale_simple(fw, fh, INTERP_BILINEAR)
             xratio, yratio = float(w) / fw, float(h) / fh
             x, y = int(x / xratio), int(y / yratio)
     elif w > cmaxw or h > cmaxh or (csize > 0 and
                                     (csize < w or csize < h)):
         ratio = max(
             float(w) / cmaxw,
             float(h) / cmaxh,
             float(max(w, h)) / csize)
         x, y, w, h = int(x / ratio), int(y / ratio), int(w / ratio), int(
             h / ratio)
         cursorlog("downscaling cursor %s by %.2f: %sx%s", pixbuf, ratio, w,
                   h)
         cursor_pixbuf = pixbuf.scale_simple(w, h, INTERP_BILINEAR)
     else:
         cursor_pixbuf = pixbuf
     #clamp to pixbuf size:
     w = cursor_pixbuf.get_width()
     h = cursor_pixbuf.get_height()
     x = max(0, min(x, w - 1))
     y = max(0, min(y, h - 1))
     return new_Cursor_from_pixbuf(display, cursor_pixbuf, x, y)