Skip to content

Instantly share code, notes, and snippets.

@MeanEYE
Created April 24, 2020 22:46
Show Gist options
  • Save MeanEYE/b6feea1e88abe95d06b876274a8a37cc to your computer and use it in GitHub Desktop.
Save MeanEYE/b6feea1e88abe95d06b876274a8a37cc to your computer and use it in GitHub Desktop.
# thanks to Jaap Karssenberg (github.com/jaap-karssenberg)
import gi
import ctypes
gi.require_version('Gtk', '3.0')
gi.require_version('GIRepository', '2.0')
from gi.repository import GIRepository, Gtk
def get_shared_library_filename(name):
repository = GIRepository.Repository.get_default()
return repository.get_shared_library(name).split(',')[0]
def c_func(dll, name, args, res=None):
result = getattr(dll, name)
result.restype = res
result.argtypes = args
return result
def atom_p(name):
return libgdk.gdk_atom_intern_static_string(name, False)
# import functions
libgtk = ctypes.CDLL(get_shared_library_filename('Gtk'))
libgdk = ctypes.CDLL(get_shared_library_filename('Gdk'))
gtk_clipboard_set_text = c_func(
libgtk,
'gtk_clipboard_set_text',
(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint)
)
gtk_clipboard_wait_for_text = c_func(
libgtk,
'gtk_clipboard_wait_for_text',
(),
res=ctypes.c_char_p
)
gtk_target_list_find = c_func(
libgtk,
'gtk_target_list_find',
(ctypes.c_void_p, ctypes.c_void_p),
res=ctypes.c_bool
)
gtk_clipboard_set_with_data = c_func(
libgtk,
'gtk_clipboard_set_with_data',
(
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_uint,
ctypes.c_void_p, #ctypes.POINTER(GetFuncType),
ctypes.c_void_p, #ctypes.POINTER(ClearFuncType),
ctypes.c_void_p
),
res=ctypes.c_bool
)
gtk_clipboard_wait_for_contents = c_func(
libgtk,
'gtk_clipboard_wait_for_contents',
(ctypes.c_void_p, ctypes.c_void_p),
res=ctypes.c_void_p
)
# get clipboard
clipboard = libgtk.gtk_clipboard_get(atom_p(b'CLIPBOARD'))
print('Clipboard:', clipboard, 'Atom:', atom_p(b'CLIPBOARD'))
assert clipboard != 0
# Test passing clipboard pointer works
print('Test pointers:')
test_data = b'Test data'
gtk_clipboard_set_text(clipboard, test_data, len(test_data))
print('\t- Set text:', test_data)
text = gtk_clipboard_wait_for_text(clipboard)
print('\t- Got text:', text)
assert text == test_data
print('Target:')
targets = libgtk.gtk_target_list_new(None, 0)
print('\t- Create list:', targets)
atoms = []
for mime_type in (
b'text/uri-list',
b'x-special/gnome-copied-files'
):
atom = atom_p(mime_type)
atoms.append(atom)
libgtk.gtk_target_list_add(targets, atom, 0, 0)
print('\t- Atoms:', atoms)
# ok = gtk_target_list_find(targets, atom_p(b'x-special/gnome-copied-files'), None)
# print('\t- Found target:', ok)
# assert ok
print('Set with data:')
GetFuncType = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
ClearFuncType = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p)
def get_func(clipboard, selection, info, data):
print('GET %r' % ((clipboard, selection, info, data),))
file_name = b'copy\n~/by.py'
libgtk.gtk_selection_data_set_text(selection, file_name, len(file_name))
def clear_func(clipboard, data):
print('CLEAR %r' % ((clipboard, data),))
c_get_func = GetFuncType(get_func)
c_clear_func = ClearFuncType(clear_func)
user_data = b'userdata 123'
ok = gtk_clipboard_set_with_data(clipboard, targets, len(atoms), c_get_func, c_clear_func, None)
print('\t- Copied:', ok)
data = gtk_clipboard_wait_for_contents(clipboard, atom)
print('\t- Wait for contents:', data)
text = gtk_clipboard_wait_for_text(clipboard)
print('\t- Wait for text:', text)
# assert text == b'Test 456'
# PS need global cache for data so it will not get garbage collected before "clear"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment