diff --git a/kivy/__init__.py b/kivy/__init__.py index f38019308..c4bf46034 100644 --- a/kivy/__init__.py +++ b/kivy/__init__.py @@ -189,7 +189,7 @@ kivy_options = { 'image': ('tex', 'imageio', 'dds', 'gif', 'pil', 'pygame', 'ffpy', 'sdl2'), 'camera': ('opencv', 'gi', 'pygst', 'videocapture', 'avfoundation'), 'spelling': ('enchant', 'osxappkit', ), - 'clipboard': ('android', 'pygame', 'dummy', 'sdl2'), } + 'clipboard': ('android', 'winctypes', 'dbusklipper', 'nspaste', 'pygame', 'sdl2', 'dummy'), } # Read environment for option in kivy_options: @@ -209,6 +209,7 @@ for option in kivy_options: #: Kivy directory kivy_base_dir = dirname(sys.modules[__name__].__file__) #: Kivy modules directory + kivy_modules_dir = environ.get('KIVY_MODULES_DIR', join(kivy_base_dir, 'modules')) #: Kivy extension directory diff --git a/kivy/core/clipboard/__init__.py b/kivy/core/clipboard/__init__.py index c87171e1b..8caee16d8 100644 --- a/kivy/core/clipboard/__init__.py +++ b/kivy/core/clipboard/__init__.py @@ -1,3 +1,4 @@ + ''' Clipboard ========= @@ -120,10 +121,20 @@ if _platform == 'android': _clipboards.append( ('android', 'clipboard_android', 'ClipboardAndroid')) elif _platform in ('macosx', 'linux', 'win'): + if _platform == 'macosx': + _clipboards.append( + ('nspaste', 'clipboard_nspaste', 'ClipboardNSPaste')) + elif _platform == 'win': + _clipboards.append( + ('winctypes', 'clipboard_winctypes', 'ClipboardWindows')) + elif _platform == 'linux': + _clipboards.append(('dbusklipper', 'clipboard_dbusklipper', 'ClipboardDbusKlipper')) + _clipboards.append( ('pygame', 'clipboard_pygame', 'ClipboardPygame')) - _clipboards.append( - ('sdl2', 'clipboard_sdl2', 'ClipboardSDL2')) + +_clipboards.append( + ('sdl2', 'clipboard_sdl2', 'ClipboardSDL2')) _clipboards.append( ('dummy', 'clipboard_dummy', 'ClipboardDummy')) @@ -131,3 +142,4 @@ Clipboard = core_select_lib('clipboard', _clipboards, True) del _clipboards del _platform + diff --git a/kivy/core/clipboard/clipboard_dbusklipper.py b/kivy/core/clipboard/clipboard_dbusklipper.py new file mode 100644 index 000000000..f7891281a --- /dev/null +++ b/kivy/core/clipboard/clipboard_dbusklipper.py @@ -0,0 +1,41 @@ +''' +Clipboard Dbus: an implementation of the Clipboard using dbus and klipper. +''' + +__all__ = ('ClipboardDbusKlipper', ) + +from kivy.utils import platform +from kivy.core.clipboard import ClipboardBase + +if platform != 'linux': + raise SystemError('unsupported platform for dbus kde clipboard') + +try: + import dbus + bus = dbus.SessionBus() + proxy = bus.get_object("org.kde.klipper", "/klipper") +except: + raise + + +class ClipboardDbusKlipper(ClipboardBase): + + _is_init = False + + def init(self): + if ClipboardDbusKlipper._is_init: + return + self.iface = dbus.Interface(proxy, "org.kde.klipper.klipper") + ClipboardDbusKlipper._is_init = True + + def get(self, mimetype='text/plain'): + self.init() + return str(self.iface.getClipboardContents()) + + def put(self, data, mimetype='text/plain'): + self.init() + self.iface.setClipboardContents(data.replace('\x00', '')) + + def get_types(self): + self.init() + return 'text/plain' diff --git a/kivy/core/clipboard/clipboard_nspaste.py b/kivy/core/clipboard/clipboard_nspaste.py new file mode 100644 index 000000000..f251a7a32 --- /dev/null +++ b/kivy/core/clipboard/clipboard_nspaste.py @@ -0,0 +1,40 @@ +''' +Clipboard OsX: implementation of clipboard using Appkit +''' + +__all__ = ('ClipboardNSPaste', ) + +from kivy.core.clipboard import ClipboardBase +from kivy.utils import platform + +if platform != 'macosx': + raise SystemError('Unsupported platform for appkit clipboard.') +try: + from pyobjus import autoclass + from pyobjus.dylib_manager import load_framework, INCLUDE + load_framework(INCLUDE.AppKit) +except ImportError: + raise SystemError('Pyobjus not installed. Please run the following' + ' command to install it. `pip install --user pyobjus`') + +NSPasteboard = autoclass('NSPasteboard') +NSString = autoclass('NSString') + + +class ClipboardNSPaste(ClipboardBase): + + def __init__(self): + super(ClipboardNSPaste, self).__init__() + self._clipboard = NSPasteboard.generalPasteboard() + + def get(self, mimetype='text/plain'): + pb = self._clipboard + return pb.stringForType_('public.utf8-plain-text').UTF8String() + + def put(self, data, mimetype='text/plain'): + pb = self._clipboard + pb.clearContents() + pb.writeObjects_([data]) + + def get_types(self): + return list('text/plain',) diff --git a/kivy/core/clipboard/clipboard_winctypes.py b/kivy/core/clipboard/clipboard_winctypes.py new file mode 100644 index 000000000..23b275bf6 --- /dev/null +++ b/kivy/core/clipboard/clipboard_winctypes.py @@ -0,0 +1,47 @@ +''' +Clipboard windows: an implementation of the Clipboard using ctypes. +''' + +__all__ = ('ClipboardWindows', ) + +from kivy.utils import platform +from kivy.core.clipboard import ClipboardBase + +if platform != 'win': + raise SystemError('unsupported platform for Windows clipboard') + +import ctypes +user32 = ctypes.windll.user32 +kernel32 = ctypes.windll.kernel32 +msvcrt = ctypes.cdll.msvcrt +c_char_p = ctypes.c_char_p +c_wchar_p = ctypes.c_wchar_p + + +class ClipboardWindows(ClipboardBase): + + def get(self, mimetype='text/plain'): + user32.OpenClipboard(0) + # 1 is CF_TEXT + pcontents = user32.GetClipboardData(13) + data = c_wchar_p(pcontents).value.encode('utf-16') + #ctypes.windll.kernel32.GlobalUnlock(pcontents) + user32.CloseClipboard() + return data + + def put(self, text, mimetype='text/plain'): + GMEM_DDESHARE = 0x2000 + CF_UNICODETEXT = 13 + user32.OpenClipboard(None) + user32.EmptyClipboard() + hCd = kernel32.GlobalAlloc(GMEM_DDESHARE, len(text) + 2) + pchData = kernel32.GlobalLock(hCd) + msvcrt.wcscpy(c_wchar_p(pchData), text) + kernel32.GlobalUnlock(hCd) + user32.SetClipboardData(CF_UNICODETEXT, hCd) + user32.CloseClipboard() + + def get_types(self): + return list('text/plain',) + +