Skip to content

Commit

Permalink
reintroduce some macros, define g_type for interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
jwahlstrand committed Nov 29, 2024
1 parent 5a5b15c commit f1aad48
Show file tree
Hide file tree
Showing 16 changed files with 687 additions and 8,704 deletions.
1,232 changes: 69 additions & 1,163 deletions Adwaita/src/gen/adw_structs

Large diffs are not rendered by default.

33 changes: 13 additions & 20 deletions GI/src/giimport.jl
Original file line number Diff line number Diff line change
Expand Up @@ -221,23 +221,15 @@ function gobject_decl(objectinfo)
println("get_g_type returns void -- not in library? : ", get_name(objectinfo))
end

type_init = Symbol(get_type_init(objectinfo))
libs=get_shlibs(GINamespace(get_namespace(objectinfo)))
lib=libs[findfirst(find_symbol(type_init),libs)]

exprs=Expr[]
decl=quote
abstract type $oname <: $pname end
mutable struct $leafname <: $oname
handle::Ptr{GObject}
function $leafname(handle::Ptr{GObject}, owns=false)
if handle == C_NULL
error($("Cannot construct $leafname with a NULL pointer"))
end
GLib.gobject_maybe_sink(handle,owns)
return gobject_ref(new(handle))
end
end
gtype_wrapper_cache[$(QuoteNode(oname))] = $leafname
$(unblock(typeinit_def(objectinfo, oname)))
@GLib.Gobject $oname $pname $(symbol_from_lib(lib)) $type_init
end
push!(exprs, decl)
push!(exprs, MacroTools.striplines(unblock(decl)))
# if there are signals, add "signal_return_type" method, and "signal_arg_types" method
signals = get_all_signals(objectinfo)
sigdict = signal_dict_incl_parents(objectinfo)
Expand Down Expand Up @@ -310,19 +302,20 @@ end

function decl(interfaceinfo::GIInterfaceInfo)
g_type = get_g_type(interfaceinfo)

type_init = Symbol(get_type_init(interfaceinfo))
libs=get_shlibs(GINamespace(get_namespace(interfaceinfo)))
lib=libs[findfirst(find_symbol(type_init),libs)]

iname = Symbol(GLib.g_type_name(g_type))

if iname === :void
println("get_g_type returns void -- not in library? : ", get_name(interfaceinfo))
end
decl=quote
struct $iname <: GInterface
handle::Ptr{GObject}
gc::Any
$iname(x::GObject) = new(unsafe_convert(Ptr{GObject}, x), x)
end
@GLib.Giface $iname $(symbol_from_lib(lib)) $type_init
end
unblock(decl)
MacroTools.striplines(unblock(decl))
end

function get_closure(callbackinfo::GICallbackInfo)
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "Gtk4"
uuid = "9db2cae5-386f-4011-9d63-a5602296539b"
version = "0.7.1"
version = "0.7.2"

[deps]
BitFlags = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35"
Expand Down
21 changes: 3 additions & 18 deletions examples/custom_widget.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,12 @@ function GLib.g_type(::Type{T}) where T <: MyWidget
if gt > 0
return gt
else
base_gtype = GLib.g_type(GtkWidget)
tq=GLib.G_.type_query(base_gtype)
typeinfo = _GTypeInfo(tq.class_size,
C_NULL, # base_init
C_NULL, # base_finalize
@cfunction(object_class_init, Cvoid, (Ptr{_GObjectClass}, Ptr{Cvoid})),
C_NULL, # class_finalize
C_NULL, # class_data
tq.instance_size,
0, # n_preallocs
C_NULL, # instance_init
C_NULL) # value_table
return GLib.G_.type_register_static(base_gtype,:MyWidget,Ref(typeinfo),GLib.TypeFlags_FINAL)
object_class_init_cfunc = @cfunction(object_class_init, Cvoid, (Ptr{_GObjectClass}, Ptr{Cvoid}))
return GLib.register_subtype(GtkWidget, :MyWidget, object_class_init_cfunc)
end
end

function MyWidget()
gtype = GLib.g_type(MyWidget)
h = ccall(("g_object_new", GLib.libgobject), Ptr{GObject}, (UInt64, Ptr{Cvoid}), gtype, C_NULL)
MyWidget(h)
end
MyWidget() = GLib.gobject_new(MyWidget)

w = MyWidget()

Expand Down
13 changes: 13 additions & 0 deletions src/GLib/gio.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,16 @@ function cancel_after_delay(timeout)
end
cancellable
end

mutable struct _GActionInterface
g_iface::_GTypeInterface
get_name::Ptr{Cvoid}
get_parameter_type::Ptr{Cvoid}
get_state_type::Ptr{Cvoid}
get_state_hint::Ptr{Cvoid}
get_enabled::Ptr{Cvoid}
get_state::Ptr{Cvoid}
change_state::Ptr{Cvoid}
activate::Ptr{Cvoid}
end

28 changes: 28 additions & 0 deletions src/GLib/gobject.jl
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ Related GTK function: [`g_binding_unbind`](https://docs.gtk.org/gobject/method.B
"""
unbind_property(b::GBinding) = G_.unbind(b)

## Below is experimental and unstable!

mutable struct _GObjectClass
g_type_class::_GTypeClass
construct_properties::Ptr{GLib._GSList{Ptr{Nothing}}}
Expand All @@ -171,3 +173,29 @@ mutable struct _GObjectClass
pdummy2::Ptr{Nothing}
pdummy3::Ptr{Nothing}
end

function register_subtype(::Type{T}, typename::Symbol, object_class_init_cfunc) where T<:GObject
base_gtype = g_type(T)
tq=G_.type_query(base_gtype)
typeinfo = _GTypeInfo(tq.class_size,
C_NULL, # base_init
C_NULL, # base_finalize
object_class_init_cfunc,
C_NULL, # class_finalize
C_NULL, # class_data
tq.instance_size,
0, # n_preallocs
C_NULL, # instance_init
C_NULL) # value_table
G_.type_register_static(base_gtype,typename,Ref(typeinfo),TypeFlags_FINAL)
end

function override_property(class::Ptr{_GObjectClass}, property_id, name::AbstractString)
ccall((:g_object_class_override_property, libgobject), Cvoid, (Ptr{_GObjectClass}, Cuint, Cstring), class, property_id, name)
end

function gobject_new(juliatype, args...)
gtype = GLib.g_type(juliatype)
h=ccall(("g_object_new", GLib.libgobject), Ptr{GObject}, (UInt64, Ptr{Cvoid}), gtype, C_NULL)
juliatype(h, args...)
end
74 changes: 58 additions & 16 deletions src/GLib/gtype.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,61 @@ const fundamental_types = (
g_type_from_name(name::Symbol) = ccall((:g_type_from_name, libgobject), GType, (Ptr{UInt8},), name)
const fundamental_ids = tuple(GType[g_type_from_name(name) for (name, c, j, f, v) in fundamental_types]...)

function get_gtype_decl(name::Symbol, lib, callname::Symbol)
:(GLib.g_type(::Type{T}) where T <: $(esc(name)) =
ccall(($(String(callname)), $(esc(lib))), GType, ()))
end

function get_interface_decl(iname::Symbol)
quote
struct $(esc(iname)) <: GInterface
handle::Ptr{GObject}
gc::Any
$(esc(iname))(x::GObject) = new(unsafe_convert(Ptr{GObject}, x), x)
end
end
end

function get_object_decl(iname::Symbol,parentname::Symbol)
leafname = Symbol(String(iname),"Leaf")
undeferrmessage = "Cannot construct $leafname with a NULL pointer"
quote
abstract type $(esc(iname)) <: $(esc(parentname)) end
mutable struct $(esc(leafname)) <: $(esc(iname))
handle::Ptr{GObject}
function $(esc(leafname))(handle::Ptr{GObject}, owns = false)
if handle == C_NULL
error($undeferrmessage)
end
GLib.gobject_maybe_sink(handle, owns)
return gobject_ref(new(handle))
end
end
gtype_wrapper_cache[$(QuoteNode(iname))] = $(esc(leafname))
end
end

macro Giface(iname, lib, callname)
gtype_decl = get_gtype_decl(iname, lib, callname)
interf_decl = get_interface_decl(iname)
ex=quote
$(interf_decl)
$(gtype_decl)
end
Base.remove_linenums!(ex)
end

macro Gobject(iname, pname, lib, callname)
gtype_decl = get_gtype_decl(iname, lib, callname)
obj_decl = get_object_decl(iname, pname)
ex=quote
$(obj_decl)
$(gtype_decl)
end
Base.remove_linenums!(ex)
end


"""
g_type(x)
Expand Down Expand Up @@ -288,12 +343,7 @@ function delref(@nospecialize(x::GObject))
# internal helper function
exiting[] && return # unnecessary to cleanup if we are about to die anyways
if gc_preserve_glib_lock[] || g_yielded[]
lock(await_lock)
try
push!(await_finalize, x)
finally
unlock(await_lock)
end
@lock await_lock push!(await_finalize, x)
return # avoid running finalizers at random times
end
finalize_gc_unref(x)
Expand All @@ -318,12 +368,7 @@ function gobject_ref(x::T) where T <: GObject
if ccall((:g_object_get_qdata, libgobject), Ptr{Cvoid},
(Ptr{GObject}, UInt32), x, jlref_quark::UInt32) != C_NULL
# have set up metadata for this before, but its weakref has been cleared. restore the ref.
lock(await_lock)
try
delete!(await_finalize, x)
finally
unlock(await_lock)
end
@lock await_lock delete!(await_finalize, x)
finalizer(delref, x)
gc_preserve_glib[WeakRef(x)] = false # record the existence of the object, but allow the finalizer
else
Expand Down Expand Up @@ -357,14 +402,11 @@ function run_delayed_finalizers()
filter!(x->!(isa(x.first,WeakRef) && x.first.value === nothing),gc_preserve_glib)
gc_preserve_glib_lock[] = false
end
lock(await_lock)
try
@lock await_lock begin
while !isempty(await_finalize)
x = pop!(await_finalize)
finalize_gc_unref(x)
end
finally
unlock(await_lock)
end
topfinalizer[] = true
end
Expand Down
4 changes: 4 additions & 0 deletions src/GLib/gvariant.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,7 @@ end
GVariantType(t::Type{T}) where T = G_.VariantType_new(variant_type_string(t))

Base.:(==)(lhs::GVariantType, rhs::GVariantType) = G_.equal(lhs,rhs)

function show(io::IO, gvt::GVariantType)
print(io, "GVariantType(\""*G_.dup_string(gvt)*"\")")
end
Loading

0 comments on commit f1aad48

Please sign in to comment.