Xitij Ritesh Patel avatar Xitij Ritesh Patel committed 93543c2

Added Clipboard class to allow access to system clipboard.

Comments (0)

Files changed (3)

tart/python/bb/clipboard.py

+'''Wrappers for libclipboard routines'''
+
+import ctypes
+from ctypes import (c_bool, c_float, c_double, c_int, c_char, c_char_p, c_void_p, c_uint,
+    POINTER, Structure, CFUNCTYPE)
+
+from ._wrap import _func, _register_funcs
+
+get_clipboard_path = _func(c_int, c_char_p, c_uint)
+set_clipboard_path = _func(c_int, c_char_p, c_uint)
+set_clipboard_check_perimeters = _func(None, c_int)
+get_clipboard_can_write = _func(c_int)
+set_clipboard_data = _func(c_int, c_char_p, c_uint, POINTER(c_char))
+get_clipboard_data = _func(c_uint, c_char_p, POINTER(POINTER(c_char)))
+empty_clipboard = _func(c_int)
+empty_clipboard_by = _func(c_int, c_char_p)
+is_clipboard_format_present = _func(c_int, c_char_p)
+get_clipboard_format_path = _func(c_int, c_char_p, c_char_p, c_int)
+
+_register_funcs('libclipboard.so', globals(), True)

tart/python/tart/app.py

             d = self._bps_dispatcher = BpsEventDispatcher()
         return d
 
+    #---------------------------------------------
+    # Transparently create Clipboard when it's requested,
+    # allowing us to access the system clipboard data.
+    @property
+    def clipboard(self):
+        try:
+            d = self._clipboard
+        except AttributeError:
+            from .clipboard import Clipboard
+            d = self._clipboard = Clipboard()
+        return d
+
 
     #---------------------------------------------
     # Useful things with which to help JavaScript debugging.

tart/python/tart/clipboard.py

+from bb.clipboard import *
+from ctypes import (c_int, byref, POINTER, pointer,
+    create_string_buffer, string_at, sizeof, get_errno, cast)
+import tart
+import errno
+
+PATH_MAX = 255
+CLIPBOARD_BUFFER_SIZE = 16384
+
+class ClipboardError(Exception):
+    '''represents a failure in Clipboard call.'''
+
+class Clipboard:
+    def __init__(self, path=None):
+        if path:
+           print('Clipboard set_clipboard_path {!r}'.format(path)) 
+           rc = set_clipboard_path(c_char_p(path.encode('utf-8')), len(path))
+           print('set clipboard path, rc', rc)
+
+        buf = create_string_buffer(PATH_MAX)
+        rc = get_clipboard_path(buf, len(buf))
+        if rc == -1:
+            raise ClipboardError('get_clipboard_path')
+        self.path = buf.value.decode('utf-8')
+
+    def contains(self, mimeType):
+        ''' 
+        Returns True if the data exists in the clipboard for the specified type and accessible for the caller. False otherwise. 
+        '''
+
+        print('Clipboard contains type {!r}'.format(mimeType))
+        rc = is_clipboard_format_present(c_char_p(mimeType.encode('utf-8')))
+        exists = True if rc == 0 else False
+        restricted = False
+        if not exists:
+            restricted = True if get_errno() == errno.EACCES else False
+        print('contains exists = {!r}, restricted = {!r}'.format(exists, restricted))
+        if restricted:
+            raise ClipboardError('Access restricted.')
+
+        return exists
+
+    def value(self, mimeType):
+        '''
+        Returns data (byte string) from the clipboard for the specified type.
+
+        Will return the data requested if it's able to be accessed. If not, it will be None.
+        '''
+
+        print('Clipboard get_clipboarddataa type {!r}'.format(mimeType))
+        buf = (c_char * CLIPBOARD_BUFFER_SIZE)()
+        t = cast(buf, POINTER(c_char))
+        rc = get_clipboard_data(c_char_p(mimeType.encode('utf-8')), byref(t))
+        if rc == 4294967295: # -1 in as unsigned int
+            restricted = True if get_errno() == errno.EACCES else False
+            size = 0
+            data = None
+        else:
+            restricted = False
+            size = rc
+            data = b""
+            for i in range(size):
+                data += t[i]
+        print('value restricted {!r}, size {!r}, data {!r}'.format(restricted, size, data))
+
+        if restricted:
+            raise ClipboardError('Access restricted.')
+
+        return data
+
+    def insert(self, mimeType, data):
+        '''
+        Adds new data to the clipboard for the specified type.
+
+        If the data already exists for the type, it's replaced. Data for other types is unaffected.
+        '''
+
+        print('Clipboard set_clipboard_data type {!r}'.format(mimeType))
+        if isinstance(data, str):
+            buf = create_string_buffer(data.encode('utf-8'))
+        elif isintance(data, bytes):
+            buf = (c_char * len(data))()
+            for i in range(len(data)):
+                buf[i] = data[i]
+        else:
+            raise ClipboardError('Unsupported data type.')
+
+        t = cast(buf, POINTER(c_char))
+        rc = set_clipboard_data(mimeType.encode('utf-8'), len(data), t)
+        size = 0 if rc == -1 else rc
+        restricted = False
+        if size == -1:
+            restricted = True if get_errno() == errno.EACCES else False
+        print('insert restricted {!r}, bytes written {!r}'.format(restricted, size))
+        if restricted:
+            raise ClipboardError('Access restricted.')
+        return size
+
+    def remove(self, mimeType):
+        '''
+        Deletes data from the clipboard for the specified type
+
+        Returns True if the data was deleted successfully. False otherwise.
+        '''
+
+        print('Clipboard empty_clipboard_by type {!r}'.format(mimeType))
+        rc = empty_clipboard_by(mimeType.encode('utf-8'))
+        success = True if rc == -1 else False
+        restricted = False
+        if not success:
+            restricted = True if get_errno() == errno.EACCES else False
+        print('remove restricted {!r}, success {!r}'.format(restricted, success))
+        if restricted:
+            raise ClipboardError('Access restricted.')
+        return success
+
+    def clear(self):
+        '''
+        Deletes all data from the clipboard.
+
+        Returns True if all data was deleted successfully. False otherwise.
+        '''
+
+        print('Clipboard empty_clipboard')
+        rc = empty_clipboard()
+        success = True if rc == -1 else False
+        restricted = False
+        if not success:
+            restricted = True if get_errno() == errno.EACCES else False
+        print('clear restricted {!r}, success {!r}'.format(restricted, success))
+        if restricted:
+            raise ClipboardError('Access restricted.')
+        return success
+
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.