more gst modules, GtkLayerShell support, and the init() calls.

This commit is contained in:
Stefan Salewski 2021-01-29 09:59:47 +01:00
commit 3f24dd1cd2
3 changed files with 276 additions and 63 deletions

View file

@ -1,10 +1,12 @@
= High level GTK4 and GTK3 bindings for the Nim programming language
//(c) Stefan Salewski
//Version 0.8.5
//Version 0.8.6
:experimental:
:imagesdir: http://ssalewski.de/tmp
:source-highlighter: pygments
:pygments-style: monokai
//:source-highlighter: pygments
//:pygments-style: monokai
:source-highlighter: rouge
:rouge-style: molokai
:icons: font
:toc: left
@ -15,6 +17,8 @@
//2018
TIP: A more fancy copy of this document with dark source code background is available at http://ssalewski.de/gintroreadme.html[GIntro README]
This document describes mainly the use of these bindings for GTK3. For GTK4 you may also consult the pre-print of the
*Nim GTK4 book* located at http://ssalewski.de/gtkprogramming.html.
WARNING: Please do not use the code from the examples in this page, but use the actual code from
https://github.com/StefanSalewski/gintro/tree/master/examples . The github readme.adoc does not
@ -25,6 +29,15 @@ with code inserted from files directly.
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by A. Rumpf, E. Bassi and other _Nim_ and _GTK/Gnome_ developers.
The `combinatorics` module was kindly provided by R. Behrends.
NOTE: We are currently preparing version 0.8.6 of the gintro Nim GTK bindings.
The package contains now all the standard gst modules, and due to a recent
request also the gtklayershell.nim module. Due to issues with some gst modules
we do now call init() for the gst module before we use it with gobject-introspection.
We do the same for GTK3 and GTK4 as these provide also an init() proc. According to
a recent discussion with the GTK core devs that init() call is necessary. The call is
done by use of dlopen(), for which we need to provide the names of the
dynamic libraries, which is some guesswork for Windows and Mac.
NOTE: This is version 0.8.5 of the gintro Nim GTK bindings.
Due to a serious request we have added webkitgtk support.
Unfortunately still only for GTK3, as the latest webkitgtk package 2.30.4
@ -717,8 +730,11 @@ done separately by the user. The following code shows a GTK button, which is
extended with a counter member field. That counter is decreased for
each button click. The amount of decrease (5) is passed to the callback as a int parameter.
[black yellow-background]#Recent tests proved that providing custom destructors is
not really needed any more, see https://forum.nim-lang.org/t/7360#46632.#
Since gintro version 0.7.1 we support destructors when compile option `--gc:arc` is used.
To destroy subclassed widgets we have to create a `=destroy()` proc as shown in the code below.
[line-through]#To destroy subclassed widgets we have to create a `=destroy()` proc as shown in the code below.#
This may look a bit verbose, and it is only necessary to avoid memory leaks for widgets
which are created and destroyed multiple times during program execution. Most widgets are
created at startup and live until program terminates, so there is no noticeable leak even

View file

@ -0,0 +1,24 @@
import
gintro/[gstallocators,
gstapp,
gstaudio,
gstbase,
gstcheck,
gstcontroller,
gstgl,
gstinsertbin,
gstmpegts,
gstnet,
gst,
gstpbutils,
gstplayer,
gstrtp,
gstrtsp,
gstsdp,
gsttag,
gstvideo,
gstwebrtc]
echo "OK"

View file

@ -1,6 +1,6 @@
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
# nimpretty --maxLineLen:130 gen.nim
# v 0.8.6 2021-JAN-13
# v 0.8.6 2021-JAN-28
# (c) S. Salewski 2018
# usefull for finding death code:
@ -89,6 +89,75 @@ template try tuple type using var when while xor yield
int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 pointer false true string char bool
""".split
import dynlib
type
GstInit = proc (argc: ptr cint; argv: ptr ptr cstring) {.cdecl.}
proc tryInitGst(): LibHandle =
# echo "Try to init gst"
when defined(windows):
const GstLibName = "gstreamer-1.0-0.dll"
elif defined(macosx):
const GstLibName = "libgstreamer-1.0.dylib"
else:
const GstLibName = "libgstreamer-1.0.so(|.0)"
let gstLib = loadLibPattern(GstLibName) # dlopen
if gstLib != nil:
let gstInit = cast[GstInit](gstLib.symAddr("gst_init"))
if gstInit != nil:
gstInit(nil, nil)
else:
echo "Can't init gst library!"
else:
echo "Can't load gst library!"
return gstLib
# unloadLib(gstLib)
type
Gtk3Init = proc (argc: ptr cint; argv: ptr ptr cstring) {.cdecl.}
proc tryInitGtk3(): LibHandle =
# echo "Try to init gtk3"
when defined(windows):
const Gtk3LibName = "libgtk-3-0.dll"
elif defined(macosx):
const Gtk3LibName = "libgtk-3.dylib"
else:
const Gtk3LibName = "libgtk-3.so(|.0)"
let gtk3Lib = loadLibPattern(Gtk3LibName) # dlopen
if gtk3Lib != nil:
let gtk3Init = cast[Gtk3Init](gtk3Lib.symAddr("gtk_init"))
if gtk3Init != nil:
gtk3Init(nil, nil)
else:
echo "Can't init gtk3 library!"
else:
echo "Can't load gtk3 library!"
return gtk3Lib
type
Gtk4Init = proc () {.cdecl.}
proc tryInitGtk4(): LibHandle =
# echo "Try to init gtk4"
when defined(windows):
const Gtk4LibName = "libgtk-4-0.dll"
elif defined(macosx):
const Gtk4LibName = "libgtk-4.dylib"
else:
const Gtk4LibName = "libgtk-4.so(|.0)"
let gtk4Lib = loadLibPattern(Gtk4LibName) # dlopen
if gtk4Lib != nil:
let gtk4Init = cast[Gtk4Init](gtk4Lib.symAddr("gtk_init"))
if gtk4Init != nil:
gtk4Init()
else:
echo "Can't init gtk4 library!"
else:
echo "Can't load gtk4 library!"
return gtk4Lib
proc unCap(s: var string) =
s[0] = s[0].toLowerAscii
@ -246,6 +315,12 @@ fixedProcNames["gdk_visual_get_system"] = "getSystemVisual"
fixedProcNames["gdk_visual_get_best_type"] = "getBestType"
fixedProcNames["gdk_pixbuf_get_formats"] = "getPixbufFormats"
fixedProcNames["gst_gl_base_memory_init_once"] = "baseMemoryInitOnce"
fixedProcNames["gst_gl_renderbuffer_init_once"] = "renderbufferInitOnce"
fixedProcNames["gst_gl_buffer_init_once"] = "bufferInitOnce"
fixedProcNames["gst_gl_memory_init_once"] = "memoryInitOnce"
fixedProcNames["gst_gl_memory_pbo_init_once"] = "memoryPboInitOnce"
defaultParameters["gtk_window_new"] = "`type` WindowType WindowType.toplevel"
defaultParameters["gtk_application_new"] = "flags gio.ApplicationFlags {}"
defaultParameters["gtk_builder_new_from_string"] = "length int64 -1"
@ -447,6 +522,11 @@ glib.SList
glib.List
nice.Address
gst.MapInfo
gstvideo.VideoRectangle
gstrtsp.RTSPRange
gstrtsp.RTSPTimeRange
gstrtsp.RTSPTime
gstrtsp.RTSPTime2
"""
const autoCallerAlloc = """
@ -1002,8 +1082,8 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; ge
if mayBeNil and gArgInfoGetDirection(arg) != GIDirection.OUT:
result.arglist.add("if " & name & ".isNil: nil else: cast[" & ngr.name00 & "](" & name & ".impl)")
else:
if gArgInfoGetDirection(arg) == GIDirection.OUT:
if gArgInfoIsOptional(arg):
if gArgInfoGetDirection(arg) == GIDirection.OUT or gArgInfoGetDirection(arg) == GIDirection.INOUT:
if gArgInfoIsOptional(arg): # INOUT i.e. for gst_gl_ensure_element_data
result.arglist.add("cast[var " & ngr.name00 & "](if addr(" & name & ") == nil: nil else: addr " & name & ".impl)")
else:
result.arglist.add("cast[var " & ngr.name00 & "](addr " & name & ".impl)")
@ -1063,9 +1143,7 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil; ge
str.add(" = " & h3)
if genProxy and (str == "string" or str == "cstring") and mayBeNil and not sym.contains("_button_new_with_label"):
#if genProxy and (str == "string" or str == "cstring") and mayBeNil and sym != "gtk_check_button_new_with_label":
str.add(" = \"\"")
if genProxy and m == 0:
if sym.contains("_set_") and str == "bool":
@ -1298,6 +1376,9 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
if sym.contains("__"): return
if processedFunctions.contains(sym): return
if gBaseInfoGetName(mInfo).len == 0: # <method name="" c:identifier="gst_video_chroma_resample" moved-to="video_chroma_resample">
return
# The following functions work with arrays, we should check each carefully -- some may not compile...
#if sym == "g_io_channel_read_to_end": return # fix later
if sym == "g_boxed_free": return # this is manually added at early position already
@ -1350,8 +1431,11 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
if sym == "gst_byte_reader_dup_string_utf32": return
if sym == "gst_byte_writer_reset_and_get_data": return
if sym == "gst_gl_filter_add_rgba_pad_templates": return
if sym == "nice_agent_get_selected_pair": return # was very wrong, fixed manually
if sym == "g_hash_table_destroy": return
try:
pars = genPars(mInfo, false, info)
@ -1678,13 +1762,13 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
#assert not (v[1].flags.contains(RecResFlag.zeroTerminated))
methodBuffer.writeLine(" var $1x$2: array[$3, pointer]" % [StringArrayName, multi, $StringArrayEntries])
methodBuffer.writeLine(" var $1$2: cstringArray = cast[cstringArray](addr $1x$2)" % [StringArrayName, multi])
methodBuffer.writeLine(" var $1_00 = seq2$2($3, $4$5)" % [k, v[0].replace("00").capitalizeAscii, k,
methodBuffer.writeLine(" var $1_00 = seq2$2($3, $4$5)" % [k.strip(chars = {'`'}), v[0].replace("00").capitalizeAscii, k,
StringArrayName, multi])
if multi == "":
multi = "1"
elif v[1].flags.contains(RecResFlag.unamedA):
assert v[1].flags.contains(RecResFlag.array)
methodBuffer.writeLine(" var $1_00: $2" % [k, v[1].name00])
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[1].name00])
else:
if v[1].optOut:
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[0], k])
@ -1702,9 +1786,11 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
methodBuffer.writeLine(" result = glistObjects2seq($1, resul0, $2)" % [ngrRet.childName, $elTransferFull])
if ngrRet.infoType == GIInfoType.STRUCT:
if gBaseInfoGetName(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))) notin ["Atom", "Variant"]: # care later
if gBaseInfoGetName(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))) notin ["Atom", "Variant", "TimedValue"]: # care later
methodBuffer.writeLine(" result = glistStructs2seq[$1](resul0, $2)" % [ngrRet.childName, $(
gCallableInfoGetCallerOwns(minfo) != GITransfer.EVERYTHING)])
# caution TimedValue is a "light" entity, so we need a different glistStructs2seq() for that!
if gCallableInfoGetCallerOwns(minfo) != GITransfer.NOTHING:
methodBuffer.writeLine(" g_list_free(resul0)") # only free the list itself, the elements are moved to the seq
else:
@ -1863,8 +1949,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
if v[1].flags.contains(RecResFlag.unamedA):
assert v[1].flags.contains(RecResFlag.array)
methodBuffer.writeLine(" $1.setLen($2)" % [k, pars.blex])
methodBuffer.writeLine(" copyMem(unsafeaddr $1[0], $1_00, $2.int * sizeof($1[0]))" % [k, pars.blex])
methodBuffer.writeLine(" cogfree($1_00)" % [k])
methodBuffer.writeLine(" copyMem(unsafeaddr $1[0], $1_00, $2.int * sizeof($1[0]))" % [k.strip(chars = {'`'}), pars.blex])
methodBuffer.writeLine(" cogfree($1_00)" % [k.strip(chars = {'`'})])
elif RecResFlag.namedA in v[1].flags:
assert v[1].flags.contains(RecResFlag.array)
methodBuffer.writeLine(" $1 = $2($3_00, $4)" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'}), pars.blex])
@ -1883,10 +1969,15 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
methodBuffer.writeLine(" {.\n importc: \"", sym, "\", ", libprag, ".}")
if info != nil and (gBaseInfoGetType(info) == GIInfoType.UNION or gBaseInfoGetType(info) == GIInfoType.STRUCT) and
gCallableInfoGetNArgs(minfo) == (if gCallableInfoIsMethod(minfo): 0 else: 1):
if not callerAlloc.contains(modulenamespace & '.' & $gBaseInfoGetName(info)) and (asym == "free" or asym == "unref"):
#if not callerAlloc.contains(modulenamespace & '.' & $gBaseInfoGetName(info)) and (asym == "free" or asym == "unref"):
if not callerAlloc.contains(modulenamespace & '.' & $gBaseInfoGetName(info)) and (asym == "free" or asym == "unref" or asym == "destroy"): # v0.8.6
methodBuffer.writeLine("\nproc finalizer" & asym & EM & "(self: $1) =" % [$gBaseInfoGetName(info)])
methodBuffer.writeLine(" if not self.ignoreFinalizer:")
methodBuffer.writeLine(" " & sym & "(self.impl)")
if gTypeInfoGetTag(ret2) != GITypeTag.VOID: # i.e. gst_sdp_media_free()
methodBuffer.writeLine(" discard " & sym & "(self.impl)")
else: #"(cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00]("
#methodBuffer.writeLine(" " & sym & "(self.impl)")
methodBuffer.writeLine(" " & sym & "(cast[ptr " & manglename(gBaseInfoGetName(info)) & "00](self.impl))")
if sym == "gtk_window_set_default_size":
methodBuffer.writeLine("\nproc `defaultSize=`*(self: Window; dim: tuple[width: int; height: int]) =")
methodBuffer.writeLine(" gtk_window_set_default_size(cast[ptr Window00](self.impl), int32(dim[0]), int32(dim[1]))")
@ -1920,7 +2011,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
methodBuffer.cut(p)
template genBoxedFree =
#echo gBaseInfoGetName(info)
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) ==
G_TYPE_BOXED and
@ -1949,6 +2039,7 @@ template genBoxedFree =
output.writeLine(" boxedFree(", getTypeProc, "(), ", "cast[ptr " & mangleName(gBaseInfoGetName(info)) & "00](self.impl))")
output.writeLine(" self.impl = nil")
# CAUTION: newWithFinalizer() seems to be rarely used, can we remove it fully?
output.writeLine("\nproc newWithFinalizer*(x: var " & mangleName(gBaseInfoGetName(info)) & ") =")
output.writeLine(" when defined(gcDestructors):")
output.writeLine(" new(x)")
@ -1993,15 +2084,19 @@ template genDestroyFreeUnref =
methodBuffer.writeLine("\nwhen defined(gcDestructors):")
methodBuffer.writeLine(" proc `=destroy`*(self: var typeof(" & mangleName(gBaseInfoGetName(info)) & "()[])) =")
methodBuffer.writeLine(" if not self.ignoreFinalizer and self.impl != nil:")
methodBuffer.writeLine(" $1(self.impl)" % [$gFunctionInfoGetSymbol(freeMe)])
if gTypeInfoGetTag(xret2) == GITypeTag.VOID:
methodBuffer.writeLine(" $1(self.impl)" % [$gFunctionInfoGetSymbol(freeMe)])
else:
methodBuffer.writeLine(" discard $1(self.impl)" % [$gFunctionInfoGetSymbol(freeMe)])
methodBuffer.writeLine(" self.impl = nil")
# new in v0.8.5
# new in v0.8.5 # CAUTION: newWithFinalizer() seems to be rarely used, can we remove it fully?
methodBuffer.writeLine("\nproc newWithFinalizer*(x: var " & mangleName(gBaseInfoGetName(info)) & ") =")
methodBuffer.writeLine(" when defined(gcDestructors):")
methodBuffer.writeLine(" new(x)")
methodBuffer.writeLine(" else:")
methodBuffer.writeLine(" new(x, $1)" % [$gBaseInfoGetName(freeMe)])
# methodBuffer.writeLine(" new(x, $1)" % [$gBaseInfoGetName(freeMe)])
methodBuffer.writeLine(" new(x, finalizer$1)" % [$gBaseInfoGetName(freeMe)]) # for v0.8.6
template writeGetTypeProc =
var getTypeProc {.inject.}: string
@ -2053,6 +2148,7 @@ proc writeUnion(info: GIUnionInfo) =
for i, mInfo in mseq:
writeMethod(info, minfo)
if i == 0:
let xret2 = gCallableInfoGetReturnType(minfo)
genDestroyFreeUnref()
const TargetEntryProx = """
@ -2194,6 +2290,7 @@ proc writeStruct(info: GIStructInfo) =
for i, mInfo in mseq:
writeMethod(info, minfo)
if i == 0:
let xret2 = gCallableInfoGetReturnType(minfo)
genDestroyFreeUnref()
template writeSignal() =
@ -2325,13 +2422,16 @@ proc writeEnum(info: GIEnumInfo) =
return
type T = tuple[v: int64; n: string]
var s: seq[T]
var alias: seq[string]
# var alias: seq[string]
var alias: HashSet[string] # double entry in gstvideo, see https://discourse.gnome.org/t/gstvideo-1-0-gir-double-entries/5442
var flags = ($gBaseInfoGetName(info)).endsWith("Flags")
output.writeLine("type")
let n = info.gEnumInfoGetNValues()
for j in 0.cint ..< n:
let value = info.gEnumInfoGetValue(j)
let name = mangleName(gBaseInfoGetName(value))
var name = mangleName(gBaseInfoGetName(value))
if name[0].isDigit:
name = "enum" & name # gstvideo, see https://discourse.gnome.org/t/gstvideo-1-0-gir-double-entries/5442
let v = gValueInfoGetValue(value)
s.add((v, name))
s.sort do (x, y: T) -> int:
@ -2360,7 +2460,7 @@ proc writeEnum(info: GIEnumInfo) =
if j > 0 and i.v == k.v:
if i.n != k.n:
let h = if flags: "Flag" else: ""
alias.add(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & h & '.' & k.n)
alias.incl(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & h & '.' & k.n)
continue
if flags:
val = countTrailingZeroBits(val) # firstSetBit(val)
@ -2868,7 +2968,7 @@ proc glistStructs2seq*[T](l: ptr glib.List; igFin: bool): seq[T] =
while el != nil:
if el.data == nil:
continue
newWithFinalizer(r)
newWithFinalizer(r) # CAUTION: newWithFinalizer() seems to be rarely used, can we remove it fully?
r.impl = cast[typeof(r.impl)](el.data)
r.ignoreFinalizer = igFin
result.add(r)
@ -2880,7 +2980,7 @@ proc gslistStructs2seq*[T](l: ptr glib.SList; igFin: bool): seq[T] =
while el != nil:
if el.data == nil:
continue
newWithFinalizer(r)
newWithFinalizer(r) # CAUTION: newWithFinalizer() seems to be rarely used, can we remove it fully?
r.impl = cast[typeof(r.impl)](el.data)
r.ignoreFinalizer = igFin
result.add(r)
@ -3040,6 +3140,13 @@ proc getPosition*(self: Event): (float, float) =
const GTK_EPI = """
proc setMargin*(w: Widget; m: int) =
setMarginStart(w, m)
setMarginEnd(w, m)
setMarginTop(w, m)
setMarginBottom(w, m)
# allow connecting GtkText and GtkEntry to "changed" signal of GtkEditable!
proc editable*(x: Text): Editable = cast[Editable](x)
@ -3093,6 +3200,11 @@ import macros, strutils
"""
var
gstLib: LibHandle
gtk3Lib: LibHandle
gtk4Lib: LibHandle
proc main(namespace: string; version: cstring = nil) =
priList = newSeq[string]()
var buildableList: seq[string]
@ -3114,6 +3226,7 @@ proc main(namespace: string; version: cstring = nil) =
let gi = gIrepositoryGetDefault()
assert(gi != nil)
moduleNamespace = namespace.toLowerAscii
#echo fixedModName(moduleNameSpace)
#let version: cstring = nil # latest
# export GI_TYPELIB_PATH=/opt/gtk/lib64/girepository-1.0
# echo $XDG_DATA_DIRS
@ -3121,6 +3234,18 @@ proc main(namespace: string; version: cstring = nil) =
#g_irepository_prepend_search_path("/opt/gtk/lib64/girepository-1.0")
# ISGTK3 = not (((namespace == "Gtk") or (namespace == "Gdk") or (namespace == "GdkX11")) and version == "4.0")
# ISGTK3 = parmCount() == 0 # we have to launch the generator two times, as typelibs can not be unloaded!
if namespace == "Gst" and gstLib == nil:
gstLib = tryInitGst()
if namespace == "Gtk" and version == "3.0" and gtk3Lib == nil:
gtk3Lib = tryInitGtk3()
if namespace == "Gtk" and version == "4.0" and gtk4Lib == nil:
gtk4Lib = tryInitGtk4()
let typelib = gi.gIrepositoryRequire(namespace, version, cast[GIRepositoryLoadFlags](0), error)
#let typelib = gIrepositoryRequirePrivate(nil, namespace, "/usr/lib/girepository-1.0", version, cast[GIRepositoryLoadFlags](0), error)
if typelib.isNil:
@ -3222,7 +3347,7 @@ proc main(namespace: string; version: cstring = nil) =
#proc fnew*[T](a: var ref T; finalizer: proc (x: ref T)) =
template fnew*(a: untyped; finalizer: untyped) =
when defined(gcDestructors):
new(a)
system.new(a)
else:
new(a, finalizer)
""")
@ -3358,6 +3483,13 @@ proc cstringArrayToSeq*(s: ptr cstring): seq[string] =
s.insert([h])
break
for i in 0 .. s.high:
if namespace == "GstRtsp" and gBaseInfoGetType(s[i]) == GIInfoType.ENUM and gBaseInfoGetName(s[i]) == "RTSPResult":
let h = s[i]
s.delete(i, i)
s.insert([h])
break
# https://discourse.gnome.org/t/what-is-the-difference-between-gmutex-and-gchecksum/4542
if namespace notin ["HarfBuzz", "cairo"]: # auto-detecting the "light" entities is too hard, but here we get some candidates
for info in s:
@ -3731,39 +3863,55 @@ proc launch() =
if ISGTK3:
echo "Generating bindings for GTK3..."
main("Gtk", "3.0") # the 3 new 4.0 releases in old version
#main("Pango")
when true:
main("Gdk", "3.0")
main("GdkX11", "3.0")
# main("Gsk") # not available for GTK3
main("Graphene")
main("GObject") # and the old common onces. GObject before Glib!
main("GLib")
main("Gio")
main("GdkPixbuf")
main("GModule")
main("GtkSource", "4")
main("Atk")
main("Pango")
main("PangoCairo")
main("PangoFT2")
main("fontconfig")
main("freetype2")
main("HarfBuzz")
main("Rsvg")
main("xlib")
main("Vte")
main("Notify")
main("Gst")
main("GstBase")
main("GstApp")
main("Handy")
main("Nice")
main("cairo")
main("WebKit2")
main("JavaScriptCore")
main("Soup")
main("WebKit2WebExtension")
main("Gdk", "3.0")
main("GdkX11", "3.0")
# main("Gsk") # not available for GTK3
main("Graphene")
main("GObject") # and the old common onces. GObject before Glib!
main("GLib")
main("Gio")
main("GdkPixbuf")
main("GModule")
main("GtkSource", "4")
main("Atk")
main("Pango")
main("PangoCairo")
main("PangoFT2")
main("fontconfig")
main("freetype2")
main("HarfBuzz")
main("Rsvg")
main("xlib")
main("Vte")
main("Notify")
main("Handy")
main("Nice")
main("cairo")
main("WebKit2")
main("JavaScriptCore")
main("Soup")
main("WebKit2WebExtension")
main("Gst")
main("GstBase")
main("GstAllocators")
main("GstApp")
main("GstAudio")
main("GstCheck")
main("GstController")
main("GstGL")
main("GstInsertBin")
main("GstMpegts")
main("GstNet")
main("GstPlayer")
main("GstRtp")
main("GstRtsp")
main("GstSdp")
main("GstTag")
main("GstVideo")
main("GstWebRTC")
main("GstApp")
main("GstPbutils")
main("GtkLayerShell")
else:
echo "First we try generating bindings for GTK4, this may fail when GTK4 is not properly installed"
echo "on your computer. But don't worry, you can still use GTK3"
@ -3777,7 +3925,7 @@ proc launch() =
main("Gio")
main("GdkPixbuf")
main("GModule")
main("GtkSource") # not yet available for GTK4
main("GtkSource")
main("Atk")
main("Pango")
main("PangoCairo")
@ -3789,10 +3937,29 @@ proc launch() =
main("xlib")
# main("Vte") # not yet available for GTK4
main("Notify")
main("Gst")
# main("Handy") # not yet available for GTK4
main("Nice")
main("cairo")
main("Gst")
main("GstBase")
main("GstAllocators")
main("GstApp")
main("GstAudio")
main("GstCheck")
main("GstController")
main("GstGL")
main("GstInsertBin")
main("GstMpegts")
main("GstNet")
main("GstPlayer")
main("GstRtp")
main("GstRtsp")
main("GstSdp")
main("GstTag")
main("GstVideo")
main("GstWebRTC")
main("GstApp")
main("GstPbutils")
if ISGTK3:
supmod3.writeLine(" ]")
@ -3808,6 +3975,12 @@ proc launch() =
o.write(supmod4.data)
o.close()
supmod4.close
if gstLib != nil:
unloadLib(gstLib)
if gtk3Lib != nil:
unloadLib(gtk3Lib)
if gtk4Lib != nil:
unloadLib(gtk4Lib)
launch()
@ -3820,7 +3993,7 @@ launch()
# if not xcallerAlloc.contains(el):
# echo el
# 3741 lines Extern import writeConst gBaseInfoGetNamespace atk writeStruct attribute destroy writeMethode builder include EM
# 3996 lines
# gtk_icon_view_get_tooltip_context bug Candidate
# gtk_tree_view_get_cursor bug
#