def get_text(): formats = get_clipboard_formats() matching = [] for u in (utf8, not utf8): if u: fmts = [win32con.CF_UNICODETEXT] else: fmts = [win32con.CF_TEXT, win32con.CF_OEMTEXT] matching += [fmt for fmt in formats if fmt in fmts] log("supported formats: %s (prefer utf8: %s)", csv(format_names(matching)), utf8) if not matching: log("no supported formats, only: %s", csv(format_names(formats))) errback() return True data_handle = None fmt = None for fmt in matching: data_handle = GetClipboardData(fmt) log("GetClipboardData(%s)=%#x", format_name(fmt), data_handle or 0) if data_handle: break if not data_handle: log("no valid data handle using %s (may try again)", csv(format_names(matching))) return False data = GlobalLock(data_handle) if not data: log("failed to lock data handle %#x (may try again)", data_handle) return False log("got data handle lock %#x for format '%s'", data, format_name(fmt)) try: if fmt == win32con.CF_UNICODETEXT: try: v = w_to_utf8(data) except Exception as e: log("w_to_utf8(..)", exc_info=True) errback(str(e)) return True callback(v) return True #CF_TEXT or CF_OEMTEXT: astr = cast(data, LPCSTR) s = astr.value.decode("latin1") if CONVERT_LINE_ENDINGS: s = s.replace("\r\n", "\n") b = s.encode("latin1") ulen = len(b) if ulen > MAX_CLIPBOARD_PACKET_SIZE: errback("text data is too large: %i characters" % ulen) return True log("got %i bytes of TEXT data: %s", len(b), ellipsizer(b)) callback(b) return True finally: GlobalUnlock(data)
def get_text(): data_handle = GetClipboardData(win32con.CF_UNICODETEXT) if not data_handle: errback("no data handle") return data = GlobalLock(data_handle) if not data: errback("failed to lock handle") return try: wstr = cast(data, LPCWSTR) ulen = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, None, 0, None, None) if ulen>MAX_CLIPBOARD_PACKET_SIZE: errback("too much data") return buf = create_string_buffer(ulen) l = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, byref(buf), ulen, None, None) if l>0: if buf.raw[l-1:l]==b"\0": s = buf.raw[:l-1] else: s = buf.raw[:l] log("got %i bytes of data: %s", len(s), repr_ellipsized(str(s))) callback(strtobytes(s)) else: errback("failed to convert to UTF8: %s" % FormatError(get_last_error())) finally: GlobalUnlock(data)
def get_text(): formats = [] fmt = 0 while True: fmt = EnumClipboardFormats(fmt) if fmt: formats.append(fmt) else: break log("clipboard formats: %s", csv(format_name(x) for x in formats)) matching = [] for u in (utf8, not utf8): if u: fmts = [win32con.CF_UNICODETEXT] else: fmts = [win32con.CF_TEXT, win32con.CF_OEMTEXT] matching += [fmt for fmt in formats if fmt in fmts] log("supported formats: %s (prefer utf8: %s)", csv(format_name(x) for x in matching), utf8) if not matching: log("no supported formats, only: %s", csv(format_name(x) for x in formats)) errback() return True data_handle = None for fmt in matching: data_handle = GetClipboardData(fmt) log("GetClipboardData(%s)=%#x", format_name(fmt), data_handle or 0) if data_handle: break if not data_handle: log("no valid data handle using %s (may try again)", csv(format_name(x) for x in matching)) return False data = GlobalLock(data_handle) if not data: log("failed to lock data handle %#x (may try again)", data_handle) return False log("got data handle lock %#x for format '%s'", data, format_name(fmt)) try: if fmt == win32con.CF_UNICODETEXT: wstr = cast(data, LPCWSTR) ulen = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, None, 0, None, None) if ulen > MAX_CLIPBOARD_PACKET_SIZE: errback("unicode data is too large: %i bytes" % ulen) return True buf = create_string_buffer(ulen) l = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, byref(buf), ulen, None, None) if l == 0: errback("failed to convert to UTF8: %s" % FormatError(get_last_error())) return True if buf.raw[l - 1:l] == b"\0": s = buf.raw[:l - 1] else: s = buf.raw[:l] log("got %i bytes of UNICODE data: %s", len(s), ellipsizer(s)) if CONVERT_LINE_ENDINGS: v = s.decode("utf8").replace("\r\n", "\n").encode("utf8") else: v = strtobytes(s) callback(v) return True #CF_TEXT or CF_OEMTEXT: astr = cast(data, LPCSTR) s = astr.value.decode("latin1") if CONVERT_LINE_ENDINGS: s = s.replace("\r\n", "\n") b = s.encode("latin1") ulen = len(b) if ulen > MAX_CLIPBOARD_PACKET_SIZE: errback("text data is too large: %i characters" % ulen) return True log("got %i bytes of TEXT data: %s", len(b), ellipsizer(b)) callback(b) return True finally: GlobalUnlock(data)
def got_clipboard_lock(): if COMPRESSED_IMAGES: fmt_name = LPCSTR(img_format.upper().encode("latin1") + b"\0") #ie: "PNG" fmt = RegisterClipboardFormatA(fmt_name) if fmt: data_handle = GetClipboardData(fmt) if data_handle: size = GlobalSize(data_handle) data = GlobalLock(data_handle) log("GetClipboardData(%s)=%#x size=%s, data=%#x", img_format.upper(), data_handle, size, data) if data and size: try: cdata = (c_char * size).from_address(data) finally: GlobalUnlock(data) got_image(bytes(cdata), False) return True data_handle = GetClipboardData(win32con.CF_DIBV5) log("CF_BITMAP=%s", data_handle) data = GlobalLock(data_handle) if not data: log("failed to lock data handle %#x (may try again)", data_handle) return False try: header = cast(data, PBITMAPV5HEADER).contents offset = header.bV5Size + header.bV5ClrUsed * 4 w, h = header.bV5Width, abs(header.bV5Height) bits = header.bV5BitCount log( "offset=%s, width=%i, height=%i, compression=%s", offset, w, h, BI_FORMATS.get(header.bV5Compression, header.bV5Compression)) log("planes=%i, bitcount=%i", header.bV5Planes, bits) log("colorspace=%s", COLOR_PROFILES.get(header.bV5CSType, header.bV5CSType)) #if header.bV5Compression in (BI_JPEG, BI_PNG): # pass if header.bV5Compression != BI_RGB: errback( "cannot handle %s compression yet" % BI_FORMATS.get( header.bV5Compression, header.bV5Compression)) return True if bits == 24: save_format = "RGB" rgb_format = "BGR" stride = roundup(w * 3, 4) elif bits == 32: save_format = "RGBA" rgb_format = "BGRA" stride = w * 4 else: errback( "cannot handle image data with %i bits per pixel yet" % bits) return True img_size = stride * h rgb_data = (c_char * img_size).from_address(data + offset) from PIL import Image, ImageOps img = Image.frombytes(save_format, (w, h), rgb_data, "raw", rgb_format, stride, 1) if header.bV5Height > 0: img = ImageOps.flip(img) buf = BytesIO() img.save(buf, format=save_format) data = buf.getvalue() buf.close() got_image(data, True) return True finally: GlobalUnlock(data)