Beispiel #1
0
 def got_token(self,
               targets,
               target_data=None,
               claim=True,
               _synchronous_client=False):
     # the remote end now owns the clipboard
     self.cancel_emit_token()
     if not self._enabled:
         return
     self._got_token_events += 1
     log(
         "got token, selection=%s, targets=%s, target data=%s, claim=%s, can-receive=%s",
         self._selection, targets, target_data, claim, self._can_receive)
     if self._can_receive:
         self.targets = _filter_targets(targets or ())
         self.target_data = target_data or {}
         if targets:
             self.got_contents("TARGETS", "ATOM", 32, targets)
         if target_data:
             for target, td_def in target_data.items():
                 dtype, dformat, data = td_def
                 dtype = bytestostr(dtype)
                 self.got_contents(target, dtype, dformat, data)
         #since we claim to be greedy
         #the peer should have sent us the target and target_data,
         #if not then request it:
         if not targets:
             self.send_clipboard_request_handler(self, self._selection,
                                                 "TARGETS")
     if not claim:
         log("token packet without claim, not setting the token flag")
         return
     self._have_token = True
     if self._can_receive:
         self.claim()
Beispiel #2
0
    def get_contents(self, target, got_contents):
        log("get_contents%s", (target, got_contents))
        if target == "TARGETS":
            #we only support text at the moment:
            got_contents("ATOM", 32, [
                "TEXT", "STRING", "text/plain", "text/plain;charset=utf-8",
                "UTF8_STRING"
            ])
            return
        if target not in ("TEXT", "STRING", "text/plain",
                          "text/plain;charset=utf-8", "UTF8_STRING"):
            #we don't know how to handle this target,
            #return an empty response:
            got_contents(target, 8, b"")
            return

        def got_text(text):
            log("got_text(%s)", ellipsizer(text))
            got_contents(target, 8, text)

        def errback(error_text=""):
            log.error("Error: failed to get clipboard data")
            if error_text:
                log.error(" %s", error_text)
            got_contents(target, 8, b"")

        self.get_clipboard_text(got_text, errback)
Beispiel #3
0
 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)
Beispiel #4
0
 def got_image(img_data, trusted=False):
     log("got_image(%i bytes)", len(img_data))
     img_data = self.filter_data(dtype=target,
                                 dformat=8,
                                 data=img_data,
                                 trusted=trusted)
     got_contents(target, 8, img_data)
Beispiel #5
0
 def with_clipboard_lock(self,
                         success_callback,
                         failure_callback,
                         retries=RETRY,
                         delay=DELAY):
     log("with_clipboard_lock%s",
         (success_callback, failure_callback, retries, delay))
     r = OpenClipboard(self.window)
     if r:
         log("OpenClipboard(%#x)=%s", self.window, r)
         try:
             r = success_callback()
             log("%s()=%s", success_callback, r)
             if r:
                 return
         finally:
             r = CloseClipboard()
             log("CloseClipboard()=%s", r)
     e = WinError(GetLastError())
     owner = GetClipboardOwner()
     log("OpenClipboard(%#x)=%s, current owner: %s", self.window, e,
         get_owner_info(owner, self.window))
     if retries <= 0:
         failure_callback(
             "OpenClipboard: too many failed attempts, giving up")
         return
     #try again later:
     GLib.timeout_add(delay, self.with_clipboard_lock, success_callback,
                      failure_callback, retries - 1, delay + 5)
Beispiel #6
0
 def set_clipboard_text(self, text, retry=5):
     log("set_clipboard_text(%s, %i)", text, retry)
     r = self.do_set_clipboard_text(text)
     if not r:
         if retry > 0:
             glib.timeout_add(5, self.set_clipboard_text, text, retry - 1)
         else:
             self.set_err("failed to set clipboard buffer")
Beispiel #7
0
 def got_contents(self, target, dtype=None, dformat=None, data=None):
     #if this is the special target 'TARGETS', cache the result:
     if target == "TARGETS" and dtype == "ATOM" and dformat == 32:
         self.targets = _filter_targets(data)
         #TODO: tell system what targets we have
         log("got_contents: tell OS we have %s", csv(self.targets))
     if dformat == 8 and dtype in TEXT_TARGETS:
         log("we got a byte string: %s", data)
         self.set_clipboard_text(data)
Beispiel #8
0
 def set_clipboard_text(self, text):
     #convert to wide char
     #get the length in wide chars:
     if CONVERT_LINE_ENDINGS:
         text = text.decode("utf8").replace("\n", "\r\n").encode("utf8")
     wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text, len(text), None, 0)
     if not wlen:
         self.set_err("failed to prepare to convert to wide char")
         return True
     log("MultiByteToWideChar wlen=%i", wlen)
     #allocate some memory for it:
     l = (wlen+1)*2
     buf = GlobalAlloc(GMEM_MOVEABLE, l)
     if not buf:
         self.set_err("failed to allocate %i bytes of global memory" % l)
         return True
     log("GlobalAlloc buf=%#x", buf)
     locked = GlobalLock(buf)
     if not locked:
         self.set_err("failed to lock buffer %#x" % buf)
         GlobalFree(buf)
         return True
     try:
         locked_buf = cast(locked, LPWSTR)
         r = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text, len(text), locked_buf, wlen)
         if not r:
             self.set_err("failed to convert to wide char")
             GlobalFree(buf)
             return True
     finally:
         GlobalUnlock(locked)
     #we're going to alter the clipboard ourselves,
     #ignore messages until we're done:
     self._block_owner_change = True
     def cleanup():
         GLib.idle_add(self.remove_block)
     def set_clipboard_data():
         r = EmptyClipboard()
         log("EmptyClipboard()=%s", r)
         if not r:
             self.set_err("failed to empty the clipboard")
             return False
         r = SetClipboardData(win32con.CF_UNICODETEXT, buf)
         if not r:
             e = WinError(GetLastError())
             log("SetClipboardData(CF_UNICODETEXT, %i chars)=%s (%s)", wlen, r, e)
             return False
         log("SetClipboardData(CF_UNICODETEXT, %i chars)=%s", wlen, r)
         cleanup()
         return True
     def set_clipboard_error(error_text=""):
         log("set_clipboard_error(%s)", error_text)
         if error_text:
             log.warn("Warning: failed to set clipboard data")
             log.warn(" %s", error_text)
         cleanup()
     self.with_clipboard_lock(set_clipboard_data, set_clipboard_error)
Beispiel #9
0
 def wnd_proc(self, hwnd, msg, wparam, lparam):
     r = DefWindowProcW(hwnd, msg, wparam, lparam)
     if msg in CLIPBOARD_EVENTS:
         log("clipboard event: %s", CLIPBOARD_EVENTS.get(msg))
     if msg == WM_CLIPBOARDUPDATE:
         for proxy in self._clipboard_proxies.values():
             if not proxy._block_owner_change:
                 proxy.schedule_emit_token()
     return r
Beispiel #10
0
 def do_set_data():
     if not EmptyClipboard():
         self.set_err("failed to empty the clipboard")
     if not SetClipboardData(win32con.CF_UNICODETEXT, buf):
         #no need to warn here
         #set_clipboard_text() will try again
         return
     log("SetClipboardData(..) done")
     cleanup()
     ret[0] = True
Beispiel #11
0
 def do_set_clipboard_text(self, text):
     #convert to wide char
     #get the length in wide chars:
     wlen = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text, len(text), None, 0)
     if not wlen:
         self.set_err("failed to prepare to convert to wide char")
         return False
     log("MultiByteToWideChar wlen=%i", wlen)
     #allocate some memory for it:
     l = (wlen+1)*2
     buf = GlobalAlloc(GMEM_MOVEABLE, l)
     if not buf:
         self.set_err("failed to allocate %i bytes of global memory" % l)
         return False
     log("GlobalAlloc buf=%#x", buf)
     locked = GlobalLock(buf)
     if not locked:
         self.set_err("failed to lock buffer %#x" % buf)
         GlobalFree(buf)
         return False
     try:
         locked_buf = cast(locked, LPWSTR)
         r = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, text, len(text), locked_buf, wlen)
         if not r:
             self.set_err("failed to convert to wide char")
             return False
     finally:
         GlobalUnlock(locked)
     #we're going to alter the clipboard ourselves,
     #ignore messages until we're done:
     self._block_owner_change = True
     #def empty_error():
     #    self.set_err("failed to empty the clipboard")
     #self.with_clipboard_lock(EmptyClipboard, empty_error)
     def cleanup():
         GlobalFree(buf)
         glib.idle_add(self.remove_block)
     ret = [False]
     def do_set_data():
         if not EmptyClipboard():
             self.set_err("failed to empty the clipboard")
         if not SetClipboardData(win32con.CF_UNICODETEXT, buf):
             #no need to warn here
             #set_clipboard_text() will try again
             return
         log("SetClipboardData(..) done")
         cleanup()
         ret[0] = True
     def set_error(error_text=""):
         log.error("Error: failed to set clipboard data")
         if error_text:
             log.error(" %s", error_text)
         cleanup()
     self.with_clipboard_lock(do_set_data, set_error)
     return ret[0]
Beispiel #12
0
def get_clipboard_formats():
    formats = []
    fmt = 0
    while True:
        fmt = EnumClipboardFormats(fmt)
        if fmt:
            formats.append(fmt)
        else:
            break
    log("get_clipboard formats()=%s", csv(format_name(x) for x in formats))
    return formats
Beispiel #13
0
 def got_clipboard_lock():
     EmptyClipboard()
     c = 0
     for fmt, handle in image_formats.items():
         log("do_set_clipboard_image: %s", format_name(fmt))
         r = SetClipboardData(fmt, handle)
         if not r:
             e = WinError(GetLastError())
             log("SetClipboardData(%s, %#x)=%s (%s)", format_name(fmt), handle, r, e)
         else:
             c += 1
     return bool(c)
Beispiel #14
0
 def got_clipboard_lock():
     formats = get_clipboard_formats()
     fnames = format_names(formats)
     targets = []
     if win32con.CF_UNICODETEXT in formats:
         targets += ["text/plain;charset=utf-8", "UTF8_STRING", "CF_UNICODETEXT"]
     if win32con.CF_TEXT in formats or win32con.CF_OEMTEXT in formats:
         targets += ["TEXT", "STRING", "text/plain"]
     #if any(x in fnames for x in ("CF_DIB", "CF_BITMAP", "CF_DIBV5")):
     if "CF_DIBV5" in fnames:
         targets += ["image/png", "image/jpeg"]
     log("targets(%s)=%s", csv(fnames), csv(targets))
     got_contents("ATOM", 32, targets)
     return True
Beispiel #15
0
 def get_contents(self, target, got_contents):
     log("get_contents%s", (target, got_contents))
     if target=="TARGETS":
         def got_clipboard_lock():
             formats = get_clipboard_formats()
             fnames = format_names(formats)
             targets = []
             if win32con.CF_UNICODETEXT in formats:
                 targets += ["text/plain;charset=utf-8", "UTF8_STRING", "CF_UNICODETEXT"]
             if win32con.CF_TEXT in formats or win32con.CF_OEMTEXT in formats:
                 targets += ["TEXT", "STRING", "text/plain"]
             #if any(x in fnames for x in ("CF_DIB", "CF_BITMAP", "CF_DIBV5")):
             if "CF_DIBV5" in fnames:
                 targets += ["image/png", "image/jpeg"]
             log("targets(%s)=%s", csv(fnames), csv(targets))
             got_contents("ATOM", 32, targets)
             return True
         def lockerror(_message):
             #assume text:
             got_contents("ATOM", 32, ["TEXT", "STRING", "text/plain", "text/plain;charset=utf-8", "UTF8_STRING"])
         self.with_clipboard_lock(got_clipboard_lock, lockerror)
         return
     def nodata(*args):
         log("nodata%s", args)
         got_contents(target, 8, b"")
     if target in ("image/png", "image/jpeg"):
         def got_image(img_data, trusted=False):
             log("got_image(%i bytes)", len(img_data))
             img_data = self.filter_data(dtype=target, dformat=8, data=img_data, trusted=trusted)
             got_contents(target, 8, img_data)
         img_format = target.split("/")[-1].upper()  #ie: "PNG" or "JPEG"
         self.get_clipboard_image(img_format, got_image, nodata)
         return
     if target not in ("TEXT", "STRING", "text/plain", "text/plain;charset=utf-8", "UTF8_STRING"):
         #we don't know how to handle this target,
         #return an empty response:
         nodata()
         return
     def got_text(text):
         log("got_text(%s)", ellipsizer(text))
         got_contents(target, 8, text)
     def errback(error_text=""):
         log("errback(%s)", error_text)
         if error_text:
             log.warn("Warning: failed to get clipboard data as text")
             log.warn(" %s", error_text)
         got_contents(target, 8, b"")
     utf8 = target.lower().find("utf")>=0
     self.get_clipboard_text(utf8, got_text, errback)
Beispiel #16
0
 def wnd_proc(self, hwnd, msg, wparam, lparam):
     r = DefWindowProcW(hwnd, msg, wparam, lparam)
     if msg in CLIPBOARD_EVENTS:
         owner = GetClipboardOwner()
         log("clipboard event: %s, current owner: %s",
             CLIPBOARD_EVENTS.get(msg), get_owner_info(owner, self.window))
     if msg == WM_CLIPBOARDUPDATE and owner != self.window:
         owner = GetClipboardOwner()
         owner_info = get_owner_info(owner, self.window)
         if is_blacklisted(owner_info):
             #ie: don't try to sync from VirtualBox
             log("CLIPBOARDUPDATE coming from '%s' ignored", owner_info)
             return r
         for proxy in self._clipboard_proxies.values():
             if not proxy._block_owner_change:
                 proxy.schedule_emit_token()
     return r
Beispiel #17
0
def w_to_utf8(data):
    wstr = cast(data, LPCWSTR)
    ulen = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, None, 0, None, None)
    if ulen>MAX_CLIPBOARD_PACKET_SIZE:
        raise Exception("unicode data is too large: %i bytes" % ulen)
    buf = create_string_buffer(ulen)
    l = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, byref(buf), ulen, None, None)
    if l==0:
        raise Exception("failed to convert to UTF8: %s" % FormatError(get_last_error()))
    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:
        return s.decode("utf8").replace("\r\n", "\n").encode("utf8")
    return strtobytes(s)
Beispiel #18
0
 def with_clipboard_lock(self, success_callback, failure_callback, retries=5, delay=5):
     r = OpenClipboard(self.window)
     log("OpenClipboard(%#x)=%s", self.window, r)
     if r:
         try:
             success_callback()
             return
         finally:
             CloseClipboard()
     if GetLastError()!=ERROR_ACCESS_DENIED:
         failure_callback("OpenClipboard: access denied")
         return
     log("clipboard lock: access denied")
     if retries<=0:
         failure_callback("OpenClipboard: too many failed attemps, giving up")
         return
     #try again later:
     glib.timeout_add(delay, self.with_clipboard_lock,
                      success_callback, failure_callback, retries-1, delay)
Beispiel #19
0
 def init_window(self):
     log("Win32Clipboard.init_window() creating clipboard window class and instance"
         )
     self.wndclass = WNDCLASSEX()
     self.wndclass.cbSize = sizeof(WNDCLASSEX)
     self.wndclass.lpfnWndProc = WNDPROC(self.wnd_proc)
     self.wndclass.style = win32con.CS_GLOBALCLASS
     self.wndclass.hInstance = GetModuleHandleA(0)
     self.wndclass.lpszClassName = clipboard_window_class_name
     self.wndclass_handle = RegisterClassExW(byref(self.wndclass))
     log("RegisterClassExA(%s)=%#x", self.wndclass.lpszClassName,
         self.wndclass_handle)
     if self.wndclass_handle == 0:
         raise WinError()
     style = win32con.WS_CAPTION  #win32con.WS_OVERLAPPED
     self.window = CreateWindowExW(0, self.wndclass_handle, u"Clipboard",
                                   style, 0, 0, win32con.CW_USEDEFAULT,
                                   win32con.CW_USEDEFAULT,
                                   win32con.HWND_MESSAGE, 0,
                                   self.wndclass.hInstance, None)
     log("clipboard window=%s", self.window)
     if not self.window:
         raise WinError()
     if not AddClipboardFormatListener(self.window):
         log.warn("Warning: failed to setup clipboard format listener")
         log.warn(" %s", get_last_error())
Beispiel #20
0
 def with_clipboard_lock(self,
                         success_callback,
                         failure_callback,
                         retries=5,
                         delay=5):
     r = OpenClipboard(self.window)
     if r:
         log("OpenClipboard(%#x)=%s", self.window, r)
         try:
             success_callback()
             return
         finally:
             CloseClipboard()
     log("OpenClipboard(%#x)=%s, owner=%#x", self.window,
         WinError(GetLastError()), GetClipboardOwner())
     if retries <= 0:
         failure_callback(
             "OpenClipboard: too many failed attemps, giving up")
         return
     #try again later:
     glib.timeout_add(delay, self.with_clipboard_lock, success_callback,
                      failure_callback, retries - 1, delay + 5)
Beispiel #21
0
    def set_clipboard_image(self, img_format, img_data):
        image_formats = {}
        if COMPRESSED_IMAGES:
            #first save it as binary compressed data:
            fmt_name = LPCSTR(img_format.upper().encode("latin1")+b"\0")   #ie: "PNG"
            fmt = RegisterClipboardFormatA(fmt_name)
            if fmt:
                buf = create_string_buffer(img_data)
                pbuf = cast(byref(buf), c_void_p)
                l = len(img_data)
                data_handle = GlobalAlloc(GMEM_MOVEABLE, l)
                if not data_handle:
                    log.error("Error: failed to allocate %i bytes of global memory", l)
                    return True
                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 %i bytes of '%s' data", data, l, img_format)
                try:
                    memmove(data, pbuf, l)
                finally:
                    GlobalUnlock(data)
                image_formats[fmt] = data_handle

        #also convert it to a bitmap:
        from PIL import Image
        buf = BytesIO(img_data)
        img = Image.open(buf)
        if img.mode!="RGBA":
            img = img.convert("RGBA")
        rgb_data = img.tobytes("raw", "BGRA")
        w, h = img.size
        log("set_clipboard_image(%s, %s) image size=%s, BGR buffer=%i bytes",
            img_format, ellipsizer(data), img.size, len(rgb_data))
        header = BITMAPINFOHEADER()
        memset(byref(header), 0, sizeof(BITMAPINFOHEADER ))
        header.biSize       = sizeof(BITMAPINFOHEADER)
        header.biWidth      = w
        header.biHeight     = -h
        header.biPlanes     = 1
        header.biBitCount   = 32
        header.biCompression    = BI_RGB
        header.biSizeImage      = 0
        header.biXPelsPerMeter  = 10
        header.biYPelsPerMeter  = 10
        bitmapinfo = BITMAPINFO()
        bitmapinfo.bmiColors = 0
        memmove(byref(bitmapinfo.bmiHeader), byref(header), sizeof(BITMAPINFOHEADER))
        rgb_buf = create_string_buffer(rgb_data)
        pbuf = cast(byref(rgb_buf), c_void_p)
        hdc = GetDC(None)
        CBM_INIT = 4
        bitmap = CreateDIBitmap(hdc, byref(header), CBM_INIT, pbuf, byref(bitmapinfo), win32con.DIB_RGB_COLORS)
        ReleaseDC(None, hdc)
        image_formats[win32con.CF_BITMAP] = bitmap

        self.do_set_clipboard_image(image_formats)
Beispiel #22
0
 def set_clipboard_data():
     r = EmptyClipboard()
     log("EmptyClipboard()=%s", r)
     if not r:
         self.set_err("failed to empty the clipboard")
         return False
     r = SetClipboardData(win32con.CF_UNICODETEXT, buf)
     if not r:
         e = WinError(GetLastError())
         log("SetClipboardData(CF_UNICODETEXT, %i chars)=%s (%s)", wlen, r, e)
         return False
     log("SetClipboardData(CF_UNICODETEXT, %i chars)=%s", wlen, r)
     cleanup()
     return True
Beispiel #23
0
 def got_contents(self, target, dtype=None, dformat=None, data=None):
     #if this is the special target 'TARGETS', cache the result:
     if target=="TARGETS" and dtype=="ATOM" and dformat==32:
         self.targets = _filter_targets(data)
         #TODO: tell system what targets we have
         log("got_contents: tell OS we have %s", csv(self.targets))
         image_formats = tuple(x for x in ("image/png", "image/jpeg") if x in self.targets)
         if image_formats:
             #request it:
             self.send_clipboard_request_handler(self, self._selection, image_formats[0])
     elif dformat==8 and dtype in TEXT_TARGETS:
         log("we got a byte string: %s", data)
         self.set_clipboard_text(data)
     elif dformat==8 and dtype.startswith("image/"):
         img_format = dtype.split("/")[-1]   #ie: 'png'
         self.set_clipboard_image(img_format, data)
     else:
         log("no handling: target=%s, dtype=%s, dformat=%s, data=%s",
             target, dtype, dformat, ellipsizer(data))
Beispiel #24
0
 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)
Beispiel #25
0
 def got_text(text):
     log("got_text(%s)", ellipsizer(text))
     got_contents(target, 8, text)
Beispiel #26
0
CLIPBOARD_FORMATS = {
    win32con.CF_BITMAP: "CF_BITMAP",
    win32con.CF_DIB: "CF_DIB",
    win32con.CF_DIBV5: "CF_DIBV5",
    win32con.CF_ENHMETAFILE: "CF_ENHMETAFILE",
    win32con.CF_METAFILEPICT: "CF_METAFILEPICT",
    win32con.CF_OEMTEXT: "CF_OEMTEXT",
    win32con.CF_TEXT: "CF_TEXT",
    win32con.CF_UNICODETEXT: "CF_UNICODETEXT",
}

RETRY = envint("XPRA_CLIPBOARD_RETRY", 5)
DELAY = envint("XPRA_CLIPBOARD_INITIAL_DELAY", 10)
CONVERT_LINE_ENDINGS = envbool("XPRA_CONVERT_LINE_ENDINGS", True)
log("win32 clipboard: RETRY=%i, DELAY=%i, CONVERT_LINE_ENDINGS=%s", RETRY,
    DELAY, CONVERT_LINE_ENDINGS)
#can be used to blacklist problematic clipboard peers:
#ie: VBoxTray.exe
BLACKLISTED_CLIPBOARD_CLIENTS = [
    x for x in os.environ.get("XPRA_BLACKLISTED_CLIPBOARD_CLIENTS", "").split(
        ",") if x
]
log("BLACKLISTED_CLIPBOARD_CLIENTS=%s", BLACKLISTED_CLIPBOARD_CLIENTS)

clipboard_window_class_name = "XpraWin32Clipboard"


def is_blacklisted(owner_info):
    return any(owner_info.find(x) >= 0 for x in BLACKLISTED_CLIPBOARD_CLIENTS)

Beispiel #27
0
 def empty_clipboard(self):
     r = EmptyClipboard()
     log("EmptyClipboard()=%s", r)
     return True
Beispiel #28
0
 def set_clipboard_error(error_text=""):
     log("set_clipboard_error(%s)", error_text)
     if error_text:
         log.warn("Warning: failed to set clipboard data")
         log.warn(" %s", error_text)
     cleanup()
Beispiel #29
0
 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)
Beispiel #30
0
 def errback(error_text=""):
     log("errback(%s)", error_text)
     if error_text:
         log.warn("Warning: failed to get clipboard data")
         log.warn(" %s", error_text)
     got_contents(target, 8, b"")