Created
April 24, 2020 22:46
-
-
Save MeanEYE/b6feea1e88abe95d06b876274a8a37cc to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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