def vfunc_info_get_address(vfunc_info, gtype): ''' GIRepository.vfunc_info_get_address almost does what we need... but it derefs the address, so it cannot be used for our purposes. This code is a translation of that C code into python ''' container_info = vfunc_info.get_container() if container_info.get_type() == GIRepository.InfoType.OBJECT: object_info = container_info interface_info = None struct_info = GIRepository.object_info_get_class_struct(object_info) else: interface_info = container_info object_info = None struct_info = GIRepository.interface_info_get_iface_struct( interface_info) field_info = GIRepository.struct_info_find_field(struct_info, vfunc_info.get_name()) if field_info is None: raise AttributeError("Could not find struct field for vfunc") implementor_class = GObject.type_class_ref(gtype) if object_info: implementor_vtable = implementor_class else: interface_type = GIRepository.registered_type_info_get_g_type( interface_info) implementor_vtable = GObject.type_interface_peek( implementor_class, interface_type) offset = GIRepository.field_info_get_offset(field_info) return hash(implementor_vtable) + offset
def __init__(cls, name, bases, dict_): # Let GObjectMeta do it's initialization GObjectMeta.__init__(cls, name, bases, dict_) do_drag_data_get = dict_.get('do_drag_data_get') if do_drag_data_get: repo = GIRepository.Repository.get_default() for base in cls.__mro__: typeinfo = repo.find_by_gtype(base.__gtype__) if typeinfo: vfunc = GIRepository.object_info_find_vfunc_using_interfaces( typeinfo, 'drag_data_get') if vfunc: break else: raise AttributeError("Could not find vfunc for drag_data_get") # Get the address of the vfunc so we can put our own callback in there address = vfunc_info_get_address(vfunc[0], cls.__gtype__) if address == 0: raise AttributeError("Could not get address for drag_data_get") # Make a thunk function closure, store it so it doesn't go out of scope do_drag_data_get._thunk = create_drag_data_get_thunk(cls) # Don't judge me... couldn't get a normal function pointer to work dbl_pointer = ctypes.POINTER(ctypes.c_void_p) addr = ctypes.cast(address, dbl_pointer) addr.contents.value = ctypes.cast(do_drag_data_get._thunk, ctypes.c_void_p).value
def get_required_by_typelibs(): deps = set() repo = GIRepository.Repository() for tl in os.listdir(repo.get_search_path()[0]): namespace, version = os.path.splitext(tl)[0].split("-", 1) repo.require(namespace, version, 0) lib = repo.get_shared_library(namespace) if lib: deps.update(lib.split(",")) return deps
def get_required_by_typelibs(): deps = set() repo = GIRepository.Repository() for tl in os.listdir(repo.get_search_path()[0]): namespace, version = os.path.splitext(tl)[0].split("-", 1) lib = get_shared_libraries(namespace, version) libs = lib.lower().split(",") if lib else [] for lib in libs: deps.add((namespace, version, lib)) return deps
def test_introspected_argument_info(self): self.assertTrue(isinstance(IntrospectedRepository.Argument.__info__, GIRepository.UnionInfo)) arg = IntrospectedRepository.Argument() self.assertTrue(isinstance(arg.__info__, GIRepository.UnionInfo)) old_info = IntrospectedRepository.Argument.__info__ IntrospectedRepository.Argument.__info__ = 'not an info' self.assertRaises(TypeError, IntrospectedRepository.Argument) IntrospectedRepository.Argument.__info__ = old_info
def _get_shared_libraries(q, namespace, version): repo = GIRepository.Repository() repo.require(namespace, version, 0) lib = repo.get_shared_library(namespace) q.put(lib)
#!/usr/bin/env python import gi gi.require_version("GIRepository", "2.0") gi.require_version("Clutter", "1.0") from gi.repository import GIRepository from gi.repository import Clutter from gi.repository import GObject repo = GIRepository.Repository().get_default() info = repo.find_by_name("Clutter", "PaintNode") type = GIRepository.registered_type_info_get_g_type(info) print(GObject.type_name(type))