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)
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]
def cleanup(): GlobalFree(buf) glib.idle_add(self.remove_block)