def _read_image(disp, stream): try: header = stream.read(2 * 4) if not header: return None (width, height) = struct.unpack("=II", header) data = stream.read(width * height * 4) if len(data) < width * height * 4: log.warn("Corrupt _NET_WM_ICON") return None except Exception as e: log.warn("Weird corruption in _NET_WM_ICON: %s", e) return None # Cairo wants a native-endian array here, and since the icon is # transmitted as CARDINALs, that's what we get. It might seem more # sensible to use ImageSurface.create_for_data (at least it did to me!) # but then you end up with a surface that refers to the memory you pass in # directly, and also .get_data() doesn't work on it, and it breaks the # test suite and blah. This at least works, as odd as it is: surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) # old versions of cairo do not have this method, just ignore it if not hasattr(surf, "get_data"): log.warn("Your Cairo is too old! Carrying on as best I can, " "but don't expect a miracle") return None surf.get_data()[:] = data # Cairo uses premultiplied alpha. EWMH actually doesn't specify what it # uses, but apparently the de-facto standard is non-premultiplied. (At # least that's what Compiz's sources say.) premultiply_argb_in_place(surf.get_data()) return (width * height, surf)
# sensible to use ImageSurface.create_for_data (at least it did to me!) # but then you end up with a surface that refers to the memory you pass in # directly, and also .get_data() doesn't work on it, and it breaks the # test suite and blah. This at least works, as odd as it is: surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) # old versions of cairo do not have this method, just ignore it if not hasattr(surf, "get_data"): log.warn("Your Cairo is too old! Carrying on as best I can, " "but don't expect a miracle") return None surf.get_data()[:] = data # Cairo uses premultiplied alpha. EWMH actually doesn't specify what it # uses, but apparently the de-facto standard is non-premultiplied. (At # least that's what Compiz's sources say.) if premultiply_argb_in_place: premultiply_argb_in_place(surf.get_data()) return (width * height, surf) # This returns a cairo ImageSurface which contains the largest icon defined in # a _NET_WM_ICON property. def NetWMIcons(disp, data): icons = [] stream = StringIOClass(data) while True: size_image = _read_image(disp, stream) if size_image is None: break icons.append(size_image) if not icons: return None icons.sort()
# transmitted as CARDINALs, that's what we get. It might seem more # sensible to use ImageSurface.create_for_data (at least it did to me!) # but then you end up with a surface that refers to the memory you pass in # directly, and also .get_data() doesn't work on it, and it breaks the # test suite and blah. This at least works, as odd as it is: surf = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height) # old versions of cairo do not have this method, just ignore it if not hasattr(surf, "get_data"): log.warn("Your Cairo is too old! Carrying on as best I can, " "but don't expect a miracle") return None surf.get_data()[:] = data # Cairo uses premultiplied alpha. EWMH actually doesn't specify what it # uses, but apparently the de-facto standard is non-premultiplied. (At # least that's what Compiz's sources say.) premultiply_argb_in_place(surf.get_data()) return (width * height, surf) # This returns a cairo ImageSurface which contains the largest icon defined in # a _NET_WM_ICON property. def NetWMIcons(disp, data): icons = [] stream = StringIOClass(data) while True: size_image = _read_image(disp, stream) if size_image is None: break icons.append(size_image) if not icons: return None icons.sort()