diff --git a/README.adoc b/README.adoc index 8f1b3d2..0c5c9bc 100644 --- a/README.adoc +++ b/README.adoc @@ -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 diff --git a/examples/gtk3/fullgstcompiletest.nim b/examples/gtk3/fullgstcompiletest.nim new file mode 100644 index 0000000..3912b46 --- /dev/null +++ b/examples/gtk3/fullgstcompiletest.nim @@ -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" + + diff --git a/tests/gen.nim b/tests/gen.nim index 93bc830..f33082d 100644 --- a/tests/gen.nim +++ b/tests/gen.nim @@ -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: # + 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 #