v0.8.7
This commit is contained in:
parent
815ccae18e
commit
b82c02b2fc
4 changed files with 387 additions and 405 deletions
14
README.adoc
14
README.adoc
|
|
@ -1,6 +1,6 @@
|
|||
= High level GTK4 and GTK3 bindings for the Nim programming language
|
||||
//(c) Stefan Salewski
|
||||
//Version 0.8.6
|
||||
//Version 0.8.7
|
||||
:experimental:
|
||||
:imagesdir: http://ssalewski.de/tmp
|
||||
//:source-highlighter: pygments
|
||||
|
|
@ -29,8 +29,16 @@ 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: This is version 0.8.6 of the gintro Nim GTK bindings.
|
||||
The package contains now all the standard gst modules, and due to a recent
|
||||
NOTE: This is version 0.8.7 of the gintro Nim GTK bindings.
|
||||
We did a larger internal cleanup for the gen.nim generator script but tried to
|
||||
generate output modules identical to v.0.8.6 still. For next release v0.8.8
|
||||
there will be some changes in the generated modules then.
|
||||
Also for this version 0.8.7 we do support webkit2 for GTK4, and we have
|
||||
fixed the newGFileTmp() issue, see https://github.com/StefanSalewski/gintro/issues/112.
|
||||
|
||||
|
||||
NOTE: Version 0.8.6 of the gintro Nim GTK bindings
|
||||
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
|
||||
|
|
|
|||
20
examples/gtk4/webkitgtk.nim
Normal file
20
examples/gtk4/webkitgtk.nim
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
# https://wiki.gnome.org/Projects/WebKitGtk/ProgrammingGuide/Tutorial
|
||||
# nim c --gc:arc webkitgtk.nim
|
||||
import gintro/[gtk4, glib, gobject, gio, webkit25]
|
||||
|
||||
proc appActivate (app: Application) =
|
||||
let window = newApplicationWindow(app)
|
||||
window.title = "WebKitGtk"
|
||||
window.defaultSize = (800, 600)
|
||||
let view = newWebView()
|
||||
view.loadUri("https://nim-lang.org/")
|
||||
window.setChild(view)
|
||||
window.show
|
||||
|
||||
proc main =
|
||||
let app = newApplication("org.gtk.example")
|
||||
connect(app, "activate", appActivate)
|
||||
discard app.run
|
||||
|
||||
main()
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Package
|
||||
|
||||
version = "0.8.6"
|
||||
version = "0.8.7"
|
||||
author = "Stefan Salewski"
|
||||
description = "High level GObject-Introspection based GTK3/GTK4 bindings"
|
||||
license = "MIT"
|
||||
|
|
|
|||
746
tests/gen.nim
746
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-28
|
||||
# v 0.8.7 2021-FEB-16
|
||||
# (c) S. Salewski 2018
|
||||
|
||||
# usefull for finding death code:
|
||||
|
|
@ -38,6 +38,9 @@
|
|||
|
||||
# NOTE: Currently we support subclassing only for constructor functions like gtk_button_new()
|
||||
|
||||
# CAUTION: some procs are advertised as constructor but do not construct new objects,
|
||||
# they just return existing ones as gdk_cursor_new_from_name()
|
||||
|
||||
from os import `/`, paramCount
|
||||
import gir, gobject, glib
|
||||
import strutils
|
||||
|
|
@ -351,8 +354,10 @@ const someEvent: HashSet[string] = """"
|
|||
|
||||
proc fixedModName(s: string): string =
|
||||
result = s
|
||||
if not ISGTK3 and (s == "gdk" or s == "gtk" or s == "gdkX11"):
|
||||
if not ISGTK3 and (s == "gdk" or s == "gtk" or s == "gdkx11"):
|
||||
result &= "4"
|
||||
if not ISGTK3 and (s == "javascriptcore" or s == "webkit2" or s == "webkit2webextension"):
|
||||
result &= "5"
|
||||
if not ISGTK3 and (s == "gtksource"):
|
||||
result &= "5"
|
||||
|
||||
|
|
@ -1337,7 +1342,11 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
|||
# see https://discourse.gnome.org/t/what-is-wrong-with-g-enum-complete-type-info-and/4489
|
||||
echo "Caution: No free/unref found for ", ' ', " (", sym, ')'
|
||||
else:
|
||||
if gBaseInfoGetName(info) notin ["Variant", "VariantType"]: # seems for glib.GVariant we have to guess -- or maybe just know
|
||||
#if gBaseInfoGetName(info) notin ["Variant", "VariantType"]: # seems for glib.GVariant we have to guess -- or maybe just know
|
||||
|
||||
if gBaseInfoGetName(info) notin ["Variant", "VariantType"] and # looks ugly, so hide for v0.8.7, investigate later...
|
||||
sym notin ["soup_xmlrpc_parse_request", "gst_audio_resampler_new", "gst_rtsp_connection_accept", "gst_rtsp_connection_create_from_socket", "gst_rtsp_connection_create", "gst_sdp_media_copy", "gst_sdp_media_new"]:
|
||||
|
||||
echo "Caution: Do guess free/unref for ", ' ', " (", sym, ')'
|
||||
if boxedFreeMeName == "gBoxedFreeGVariantType": # this does not work
|
||||
assert false
|
||||
|
|
@ -1354,6 +1363,97 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
|||
freeMeName = "generic_" & $g_object_info_get_unref_function(parent)
|
||||
assert(freeMeName != "")
|
||||
|
||||
template block8(prochead: string; errorcheckadd: bool): untyped =
|
||||
if isProxyCandidateret2:
|
||||
assert (gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, GITransfer.EVERYTHING}) # both occur
|
||||
if asym == "newFromStreamAsync" and sym.startsWith("gdk_pixbuf_animation_new"):
|
||||
asym = "newAnimationFromStreamAsync"
|
||||
if prochead.len == 0:
|
||||
methodBuffer.writeLine("\nproc " & asym & EM & pars.plist & " =")
|
||||
else:
|
||||
methodBuffer.writeLine(prochead)
|
||||
if not isProxyCandidateret2:
|
||||
methodBuffer.write(pars.tempRes)
|
||||
methodBuffer.write(pars.arrLex)
|
||||
methodBuffer.write(sss)
|
||||
var freeMeName{.inject.}: string
|
||||
var boxedFreeMeName{.inject.}: string
|
||||
for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
|
||||
freeMeName = ""
|
||||
boxedFreeMeName = ""
|
||||
let arg = gCallableInfoGetArg(minfo, j)
|
||||
let t = gArgInfoGetType(arg)
|
||||
var ngrt = newGenRec(t)
|
||||
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0):
|
||||
if gArgInfoGetDirection(arg) == GIDirection.IN and gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING and
|
||||
isProxyCandidate(t) and not callerAlloc.contains(ngrt.namePlainNS):
|
||||
# like gtk_widget_add_controller()
|
||||
let n = mangleName(gBaseInfoGetName(arg))
|
||||
if gArgInfoMayBeNull(arg): # and prochead.len != 0: # wrong to be compatible with 0.8.6
|
||||
methodBuffer.writeLine(" if " & n & " != nil:")
|
||||
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
||||
else:
|
||||
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
||||
if gArgInfoGetDirection(arg) == GIDirection.OUT and isProxyCandidate(t) and
|
||||
not callerAlloc.contains(ngrt.namePlainNS) and not gArgInfoIsCallerAllocates(arg):
|
||||
let tag = gTypeInfoGetTag(t)
|
||||
assert(tag == GITypeTag.INTERFACE)
|
||||
assert gArgInfoGetOwnershipTransfer(arg) != GITransfer.CONTAINER
|
||||
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING or
|
||||
gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING: # pass always the same finalizer for ARC
|
||||
let iface = gTypeInfoGetInterface(t)
|
||||
if gBaseInfoGetType(iface) == GIInfoType.OBJECT:
|
||||
let ttt = gArgInfoGetType(arg)
|
||||
freeMeName = modPrefix(ttt, sym) & "finalizeGObject" # TODO: investigate, we may need the full toggleRef stuff!
|
||||
else:
|
||||
let info = iface
|
||||
var freeMe{.inject.}: GIFunctionInfo
|
||||
findFreeProc(info, gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING)
|
||||
let h2 = mangleName(gBaseInfoGetName(arg))
|
||||
if gArgInfoIsOptional(arg):
|
||||
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
||||
if boxedFreeMeName != "":
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
||||
elif freeMeName == "":
|
||||
methodBuffer.writeLine(" new(" & h2 & ")")
|
||||
else:
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
||||
else:
|
||||
if boxedFreeMeName != "":
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
||||
elif freeMeName == "":
|
||||
methodBuffer.writeLine(" new(" & h2 & ")")
|
||||
else:
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
||||
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING:
|
||||
if gArgInfoIsOptional(arg):
|
||||
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
||||
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true")
|
||||
else:
|
||||
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||
if gCallableInfoCanThrowGerror(minfo):
|
||||
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
||||
if errorcheckadd:
|
||||
pars.arglist.insert(", addr gerror", pars.arglist.high)
|
||||
var multi = ""
|
||||
for k, v in pars.replist:
|
||||
if v[1].flags * {RecResFlag.namedA, cstringA} != {}:
|
||||
assert v[1].flags.contains(RecResFlag.array)
|
||||
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.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.strip(chars = {'`'}), v[1].name00])
|
||||
else:
|
||||
if v[1].optOut:
|
||||
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[0], k])
|
||||
else:
|
||||
methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v[0], k])
|
||||
|
||||
# assert(info != nil) # why can it be nil?
|
||||
# if Lib.len == 0: # xlib, fontconfig, freetype2 # but Lib is local to main(), so let it crash
|
||||
# return
|
||||
|
|
@ -1436,7 +1536,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
|||
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)
|
||||
processedFunctions.incl(sym)
|
||||
|
|
@ -1548,11 +1647,12 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
|||
#if sym == "pango_attr_background_new": echo "sss", info != nil, asym
|
||||
asym = fixedProcNames.getOrDefault(sym, asym)
|
||||
# BLOCKMARK8 : 3 cases: constructor, isProxyCandidate(ret2), plain else
|
||||
if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0:
|
||||
assert pars.replist.len == 0 # ok it's a fact for constructors, so we don't have to generate code for it
|
||||
for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
|
||||
let arg = gCallableInfoGetArg(minfo, j)
|
||||
assert gArgInfoGetDirection(arg) notin {GIDirection.OUT, INOUT} # so we can ignore this case!
|
||||
let isProxyCandidateret2 = isProxyCandidate(ret2)
|
||||
|
||||
#else: # BLOCKMARK8 assert gerror
|
||||
if not (isProxyCandidateret2 or isGObject):
|
||||
block8("", true)
|
||||
if isProxyCandidateret2 or isGObject: # BLOCKMARK8
|
||||
for itt in 0 .. 2: # generate the new(), the new(typedesc) and the init() proc
|
||||
var hhh = "\nproc " & asym & EM & pars.plist
|
||||
if itt == 1: # new(typedesc)
|
||||
|
|
@ -1568,399 +1668,242 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
|||
# hhh = hhh.replace("new", "init")
|
||||
hhh = hhh.replace("proc new", "proc init") # v0.8.2
|
||||
hhh = hhh.replace("*(", "*[T](result: var T" & semi)
|
||||
if itt == 2:
|
||||
if itt == 2 and ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0):
|
||||
depStr = " {.deprecated.}"
|
||||
methodBuffer.writeLine(hhh & depStr & " =")
|
||||
if itt == 2 or ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0):
|
||||
hhh = hhh & depStr & " ="
|
||||
else:
|
||||
hhh = hhh & " ="
|
||||
block8(hhh, itt == 0)
|
||||
if not isGObject:
|
||||
methodBuffer.write(pars.tempRes) # caution, gobjectTemp() may write tempRes too.
|
||||
methodBuffer.write(pars.arrLex)
|
||||
methodBuffer.write(sss)
|
||||
if gCallableInfoCanThrowGerror(minfo):
|
||||
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
||||
if itt == 0: pars.arglist.insert(", addr gerror", pars.arglist.high)
|
||||
if itt == 1 or itt == 2:
|
||||
methodBuffer.writeLine(" assert(result is $1)" % [manglename(gBaseInfoGetName(info))])
|
||||
if isGObject:
|
||||
# CAUTION: some procs are advertised as constructor but do not construct new objects,
|
||||
# they just return existing ones as gdk_cursor_new_from_name()
|
||||
gobjectTemp()
|
||||
###if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0 and
|
||||
### gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING:
|
||||
### methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.CONTAINER:
|
||||
assert false
|
||||
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING or
|
||||
gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # and gBaseInfoGetName(info) == "Variant":
|
||||
if false: #sym == "g_closure_new_simple":
|
||||
let nMethods = gStructInfoGetNMethods(info)
|
||||
for j in 0.cint ..< nMethods:
|
||||
echo "yes there is unref method! ", $gBaseInfoGetName(gStructInfoGetMethod(info, j))
|
||||
#assert(gStructInfoFindMethod(info, "unref") != nil) # TODO GI bug?
|
||||
assert info != nil
|
||||
var freeMe: GIFunctionInfo
|
||||
var freeMeName: string
|
||||
var boxedFreeMeName: string
|
||||
findFreeProc(info, gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" let impl0 = " & sym & pars.arglist) # fast return in case of error
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if impl0.isNil:")
|
||||
methodBuffer.writeLine(" return nil")
|
||||
#if sym == "g_closure_new_simple" or sym == "g_closure_new_object":
|
||||
# freeMeName = "unref" # TODO GI bug?
|
||||
#assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
|
||||
if false: #i > 0: # with ARC we have no finalizer support for user defined subclasses, so we have to leak mem!
|
||||
methodBuffer.writeLine(" new(result)")
|
||||
elif boxedFreeMeName != "":
|
||||
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
||||
elif freeMeName == "":
|
||||
assert false
|
||||
methodBuffer.writeLine(" new(result)")
|
||||
gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # for ARC we have always to use the same finalizer!
|
||||
let tag = gTypeInfoGetTag(ret2)
|
||||
assert tag == GITypeTag.INTERFACE
|
||||
var iface = gTypeInfoGetInterface(ret2)
|
||||
if gBaseInfoGetType(iface) == GIInfoType.INTERFACE:
|
||||
gobjectTemp()
|
||||
else:
|
||||
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" result.impl = impl0")
|
||||
else:
|
||||
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
||||
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0 and
|
||||
gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING) or
|
||||
((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0 and
|
||||
gBaseInfoGetName(info) == "Variant"):
|
||||
assert((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0)
|
||||
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||
else:
|
||||
assert false
|
||||
for k, v in pars.replist:
|
||||
assert false
|
||||
if false: #gCallableInfoCanThrowGerror(minfo):
|
||||
methodBuffer.writeLine(" if gerror != nil:")
|
||||
methodBuffer.writeLine(" let msg = $gerror.message")
|
||||
methodBuffer.writeLine(" g_error_free(gerror[])")
|
||||
methodBuffer.writeLine(" raise newException(GException, msg)")
|
||||
# end of for itt in 0 .. 2:
|
||||
elif isProxyCandidate(ret2): # BLOCKMARK8
|
||||
assert (gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, GITransfer.EVERYTHING}) # both occur
|
||||
methodBuffer.writeLine("\nproc " & asym & EM & pars.plist & " =")
|
||||
methodBuffer.write(pars.arrLex)
|
||||
methodBuffer.write(sss)
|
||||
if gCallableInfoCanThrowGerror(minfo):
|
||||
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
||||
pars.arglist.insert(", addr gerror", pars.arglist.high)
|
||||
for k, v in pars.replist:
|
||||
methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v[0], k])
|
||||
if isGObject:
|
||||
gobjectTemp()
|
||||
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING or
|
||||
gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # for ARC we have always to use the same finalizer!
|
||||
let tag = gTypeInfoGetTag(ret2)
|
||||
assert tag == GITypeTag.INTERFACE
|
||||
var iface = gTypeInfoGetInterface(ret2)
|
||||
if gBaseInfoGetType(iface) == GIInfoType.INTERFACE:
|
||||
gobjectTemp()
|
||||
else:
|
||||
assert(gBaseInfoGetType(iface) in {GIInfoType.STRUCT, GIInfoType.UNION, GIInfoType.OBJECT})
|
||||
var freeMeName: string
|
||||
var freeMe: GIFunctionInfo
|
||||
var boxedFreeMeName: string
|
||||
findFreeProc(iface, gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" let impl0 = " & sym & pars.arglist) # fast return in case of error
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if impl0.isNil:")
|
||||
methodBuffer.writeLine(" return nil")
|
||||
if boxedFreeMeName != "":
|
||||
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
||||
elif freeMeName == "":
|
||||
# assert false # TODO we have to fix this case manually
|
||||
# echo "xCaution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')' # check this from time to time!
|
||||
methodBuffer.writeLine(" new(result)")
|
||||
else:
|
||||
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" result.impl = impl0")
|
||||
else:
|
||||
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # for the none gobjects
|
||||
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||
elif false: #else:
|
||||
assert gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING
|
||||
methodBuffer.writeLine(" new(result)")
|
||||
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
||||
for k, v in pars.replist:
|
||||
methodBuffer.writeLine(" $1 = $2($3_00)" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
||||
else: # BLOCKMARK8
|
||||
if asym == "newFromStreamAsync" and sym.startsWith("gdk_pixbuf_animation_new"):
|
||||
asym = "newAnimationFromStreamAsync"
|
||||
methodBuffer.writeLine("\nproc " & asym & EM & pars.plist & " =")
|
||||
methodBuffer.write(pars.tempRes)
|
||||
methodBuffer.write(pars.arrLex)
|
||||
methodBuffer.write(sss)
|
||||
var freeMeName: string
|
||||
var boxedFreeMeName: string
|
||||
for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
|
||||
freeMeName = ""
|
||||
boxedFreeMeName = ""
|
||||
let arg = gCallableInfoGetArg(minfo, j)
|
||||
let t = gArgInfoGetType(arg)
|
||||
var ngrt = newGenRec(t)
|
||||
if gArgInfoGetDirection(arg) == GIDirection.IN and gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING and
|
||||
isProxyCandidate(t) and not callerAlloc.contains(ngrt.namePlainNS):
|
||||
# like gtk_widget_add_controller()
|
||||
let n = mangleName(gBaseInfoGetName(arg))
|
||||
if gArgInfoMayBeNull(arg):
|
||||
methodBuffer.writeLine(" if " & n & " != nil:")
|
||||
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
||||
else:
|
||||
methodBuffer.writeLine(" " & n & ".ignoreFinalizer = true")
|
||||
if gArgInfoGetDirection(arg) == GIDirection.OUT and isProxyCandidate(t) and
|
||||
not callerAlloc.contains(ngrt.namePlainNS) and not gArgInfoIsCallerAllocates(arg):
|
||||
let tag = gTypeInfoGetTag(t)
|
||||
assert(tag == GITypeTag.INTERFACE)
|
||||
assert gArgInfoGetOwnershipTransfer(arg) != GITransfer.CONTAINER
|
||||
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING or
|
||||
gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING: # pass always the same finalizer for ARC
|
||||
let iface = gTypeInfoGetInterface(t)
|
||||
if gBaseInfoGetType(iface) == GIInfoType.OBJECT:
|
||||
let ttt = gArgInfoGetType(arg)
|
||||
freeMeName = modPrefix(ttt, sym) & "finalizeGObject" # TODO: investigate, we may need the full toggleRef stuff!
|
||||
else:
|
||||
let info = iface
|
||||
var freeMe: GIFunctionInfo
|
||||
findFreeProc(info, gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING)
|
||||
let h2 = mangleName(gBaseInfoGetName(arg))
|
||||
if gArgInfoIsOptional(arg):
|
||||
#methodBuffer.writeLine(" if cast[ptr $1]($2) != nil:" % [ngrt.namePlain, h2])
|
||||
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
||||
assert(gBaseInfoGetType(iface) in {GIInfoType.STRUCT, GIInfoType.UNION, GIInfoType.OBJECT})
|
||||
var freeMeName: string
|
||||
var freeMe: GIFunctionInfo
|
||||
var boxedFreeMeName: string
|
||||
findFreeProc(iface, gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" let impl0 = " & sym & pars.arglist) # fast return in case of error
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if impl0.isNil:")
|
||||
methodBuffer.writeLine(" return nil")
|
||||
if boxedFreeMeName != "":
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
||||
methodBuffer.writeLine(" fnew(result, $1)" % boxedFreeMeName)
|
||||
elif freeMeName == "":
|
||||
methodBuffer.writeLine(" new(" & h2 & ")")
|
||||
# assert false # TODO we have to fix this case manually
|
||||
# echo "xCaution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')' # check this from time to time!
|
||||
methodBuffer.writeLine(" new(result)")
|
||||
else:
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
||||
else:
|
||||
if boxedFreeMeName != "":
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & boxedFreeMeName & ")")
|
||||
elif freeMeName == "":
|
||||
methodBuffer.writeLine(" new(" & h2 & ")")
|
||||
methodBuffer.writeLine(" fnew(result, $1)" % freeMeName)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" result.impl = impl0")
|
||||
else:
|
||||
methodBuffer.writeLine(" fnew(" & h2 & ", " & freeMeName & ")")
|
||||
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING:
|
||||
if gArgInfoIsOptional(arg):
|
||||
methodBuffer.writeLine(" if addr($2) != nil:" % [ngrt.namePlain, h2])
|
||||
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true")
|
||||
else:
|
||||
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||
if gCallableInfoCanThrowGerror(minfo):
|
||||
methodBuffer.writeLine(" var gerror: ptr glib.Error")
|
||||
pars.arglist.insert(", addr gerror", pars.arglist.high)
|
||||
var multi = ""
|
||||
for k, v in pars.replist:
|
||||
if v[1].flags * {RecResFlag.namedA, cstringA} != {}:
|
||||
assert v[1].flags.contains(RecResFlag.array)
|
||||
#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.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.strip(chars = {'`'}), v[1].name00])
|
||||
else:
|
||||
if v[1].optOut:
|
||||
methodBuffer.writeLine(" var $1_00: $2" % [k.strip(chars = {'`'}), v[0], k])
|
||||
else:
|
||||
methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v[0], k])
|
||||
if ngrRet.res == glist:
|
||||
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
||||
GITransfer.NOTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
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", "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:
|
||||
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
||||
if ngrRet.infoType != GIInfoType.INTERFACE:
|
||||
assert findFreeObject(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))).len == 0
|
||||
methodBuffer.writeLine(" result = glistObjects2seq($1, $2, $3)" % [ngrRet.childName, sym & pars.arglist,
|
||||
$elTransferFull])
|
||||
else:
|
||||
methodBuffer.writeLine(" discard")
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||
|
||||
elif ngrRet.res == gslist:
|
||||
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
||||
GITransfer.NOTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
||||
methodBuffer.writeLine(" result = gslistObjects2seq($1, resul0, $2)" % [ngrRet.childName, $elTransferFull])
|
||||
if ngrRet.infoType == GIInfoType.STRUCT:
|
||||
if gBaseInfoGetName(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))) notin ["Atom", "Variant"]: # care later
|
||||
methodBuffer.writeLine(" result = gslistStructs2seq[$1](resul0, $2)" % [ngrRet.childName, $(
|
||||
gCallableInfoGetCallerOwns(minfo) != GITransfer.EVERYTHING)])
|
||||
if gCallableInfoGetCallerOwns(minfo) != GITransfer.NOTHING:
|
||||
methodBuffer.writeLine(" g_slist_free(resul0)") # only free the list itself, the elements are moved to the seq
|
||||
else:
|
||||
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
||||
if ngrRet.infoType != GIInfoType.INTERFACE:
|
||||
assert findFreeObject(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))).len == 0
|
||||
methodBuffer.writeLine(" result = gslistObjects2seq($1, $2, $3)" % [ngrRet.childName, sym & pars.arglist,
|
||||
$elTransferFull])
|
||||
else:
|
||||
methodBuffer.writeLine(" discard")
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||
|
||||
elif ngrRet.flags.contains(RecResFlag.unamedA) and ngrRet.res == intAX:
|
||||
# https://discourse.gnome.org/t/g-key-file-get-integer-list-transfer-container/4729
|
||||
# for fundamental types GITransfer.EVERYTHING and GITransfer.CONTAINER are equivalent
|
||||
var co = gCallableInfoGetCallerOwns(minfo)
|
||||
assert ngrRet.flags.contains(RecResFlag.array)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or co in {GITransfer.EVERYTHING, CONTAINER}:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $1ToSeq(resul0, $2.int)" % [fixedName2(ngrRet.name00), pars.blex])
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $1ToSeq($3, $2.int)" % [fixedName2(ngrRet.name00), pars.blex, sym & pars.arglist])
|
||||
assert(co in {GITransfer.EVERYTHING, CONTAINER, NOTHING})
|
||||
if co in {GITransfer.EVERYTHING, CONTAINER}:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif ngrRet.flags.contains(RecResFlag.unamedA) and ngrRet.res == intA0:
|
||||
assert ngrRet.flags.contains(RecResFlag.array)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $1ZT2seq(resul0)" % [unCaped(fixedName2(ngrRet.name))])
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $1ZT2seq($2)" % [unCaped(fixedName2(ngrRet.name)), sym & pars.arglist])
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif isString(ret2):
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $resul0")
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $" & sym & pars.arglist)
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif RecResFlag.namedA in ngrRet.flags:
|
||||
assert ngrRet.flags.contains(RecResFlag.array)
|
||||
let h = ngrRet.name00
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $1ToSeq(resul0, $2_00.int)" % [fixedName2(h.replace("00")).unCap, pars.blex])
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $1ToSeq($3, $2_00.int)" % [fixedName2(h.replace("00")).unCap, pars.blex, sym & pars.arglist])
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif (pars.replist.len > 0 or gCallableInfoCanThrowGerror(minfo)) and ngrRet.name != "void":
|
||||
# caution dragons like g_key_file_get_locale_string_list()
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
discard # echo "Untamed dragon: ", sym
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.write(" result = ")
|
||||
if needTypeConv(ngrRet.name, ngrRet):
|
||||
methodBuffer.writeLine(doCt3nt(ngrRet.name, ngrRet) & '(' & "resul0" & ')')
|
||||
else:
|
||||
methodBuffer.writeLine("resul0")
|
||||
else:
|
||||
methodBuffer.write(" result = ")
|
||||
if needTypeConv(ngrRet.name, ngrRet):
|
||||
methodBuffer.writeLine(doCt3nt(ngrRet.name, ngrRet) & '(' & sym & pars.arglist & ')')
|
||||
else:
|
||||
methodBuffer.writeLine(sym & pars.arglist)
|
||||
elif needTypeConv(ngrRet.name, ngrRet):
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
if ngrRet.name == "ptr cstring" and ngrRet.flags.contains(RecResFlag.array) and gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" result = cstringArrayToSeq(resul0)")
|
||||
methodBuffer.writeLine(" g_strfreev(resul0)")
|
||||
else:
|
||||
methodBuffer.writeLine(" " & doCt3nt(ngrRet.name, ngrRet) & '(' & "resul0" & ')')
|
||||
else:
|
||||
if pars.tempResFree != "": # ugly, do we have a better test for this case
|
||||
#if ngrRet.name != "void":
|
||||
methodBuffer.writeLine(" result = " & doCt3nt(ngrRet.name, ngrRet) & '(' & sym & pars.arglist & ')')
|
||||
else:
|
||||
methodBuffer.writeLine(" " & doCt3nt(ngrRet.name, ngrRet) & '(' & sym & pars.arglist & ')')
|
||||
checkForGerror() # i.e. for nice_agent_set_remote_candidates, free GSList
|
||||
else:
|
||||
if gCallableInfoCanThrowGerror(minfo) and ngrRet.name != "void":
|
||||
assert false
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
else:
|
||||
methodBuffer.writeLine(" " & sym & pars.arglist)
|
||||
methodBuffer.writeLine(" result.impl = " & sym & pars.arglist)
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # for the none gobjects
|
||||
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0):
|
||||
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
|
||||
else: assert false
|
||||
if ((gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0 and gBaseInfoGetName(info) == "Variant"):
|
||||
methodBuffer.writeLine(" result.ignoreFinalizer = true")
|
||||
if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) == 0:
|
||||
break
|
||||
elif ngrRet.res == glist:
|
||||
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
||||
GITransfer.NOTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoCanThrowGerror(minfo) and ngrRet.name != "void":
|
||||
assert false
|
||||
methodBuffer.writeLine(" resul0 #####")
|
||||
for k, v in pars.replist:
|
||||
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.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])
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
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", "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:
|
||||
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
||||
if ngrRet.infoType != GIInfoType.INTERFACE:
|
||||
assert findFreeObject(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))).len == 0
|
||||
methodBuffer.writeLine(" result = glistObjects2seq($1, $2, $3)" % [ngrRet.childName, sym & pars.arglist,
|
||||
$elTransferFull])
|
||||
else:
|
||||
if v[1].optOut:
|
||||
methodBuffer.writeLine(" if $1.addr != nil:" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
||||
methodBuffer.writeLine(" $1 = $2($3_00)" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
||||
else:
|
||||
methodBuffer.writeLine(" $1 = $2($3_00)" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
||||
# BLOCKMARK8
|
||||
methodBuffer.writeLine(" discard")
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||
elif ngrRet.res == gslist:
|
||||
var elTransferFull = gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) !=
|
||||
GITransfer.NOTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
||||
methodBuffer.writeLine(" result = gslistObjects2seq($1, resul0, $2)" % [ngrRet.childName, $elTransferFull])
|
||||
if ngrRet.infoType == GIInfoType.STRUCT:
|
||||
if gBaseInfoGetName(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))) notin ["Atom", "Variant"]: # care later
|
||||
methodBuffer.writeLine(" result = gslistStructs2seq[$1](resul0, $2)" % [ngrRet.childName, $(
|
||||
gCallableInfoGetCallerOwns(minfo) != GITransfer.EVERYTHING)])
|
||||
if gCallableInfoGetCallerOwns(minfo) != GITransfer.NOTHING:
|
||||
methodBuffer.writeLine(" g_slist_free(resul0)") # only free the list itself, the elements are moved to the seq
|
||||
else:
|
||||
if ngrRet.infoType == GIInfoType.OBJECT or ngrRet.infoType == GIInfoType.INTERFACE:
|
||||
if ngrRet.infoType != GIInfoType.INTERFACE:
|
||||
assert findFreeObject(gTypeInfoGetInterface(gTypeInfoGetParamType(ret2, 0))).len == 0
|
||||
methodBuffer.writeLine(" result = gslistObjects2seq($1, $2, $3)" % [ngrRet.childName, sym & pars.arglist,
|
||||
$elTransferFull])
|
||||
else:
|
||||
methodBuffer.writeLine(" discard")
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||
elif ngrRet.flags.contains(RecResFlag.unamedA) and ngrRet.res == intAX:
|
||||
# https://discourse.gnome.org/t/g-key-file-get-integer-list-transfer-container/4729
|
||||
# for fundamental types GITransfer.EVERYTHING and GITransfer.CONTAINER are equivalent
|
||||
var co = gCallableInfoGetCallerOwns(minfo)
|
||||
assert ngrRet.flags.contains(RecResFlag.array)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or co in {GITransfer.EVERYTHING, CONTAINER}:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $1ToSeq(resul0, $2.int)" % [fixedName2(ngrRet.name00), pars.blex])
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $1ToSeq($3, $2.int)" % [fixedName2(ngrRet.name00), pars.blex, sym & pars.arglist])
|
||||
assert(co in {GITransfer.EVERYTHING, CONTAINER, NOTHING})
|
||||
if co in {GITransfer.EVERYTHING, CONTAINER}:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif ngrRet.flags.contains(RecResFlag.unamedA) and ngrRet.res == intA0:
|
||||
assert ngrRet.flags.contains(RecResFlag.array)
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $1ZT2seq(resul0)" % [unCaped(fixedName2(ngrRet.name))])
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $1ZT2seq($2)" % [unCaped(fixedName2(ngrRet.name)), sym & pars.arglist])
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING, GITransfer.CONTAINER})
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif isString(ret2):
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $resul0")
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $" & sym & pars.arglist)
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif RecResFlag.namedA in ngrRet.flags:
|
||||
assert ngrRet.flags.contains(RecResFlag.array)
|
||||
let h = ngrRet.name00
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.writeLine(" result = $1ToSeq(resul0, $2_00.int)" % [fixedName2(h.replace("00")).unCap, pars.blex])
|
||||
else:
|
||||
methodBuffer.writeLine(" result = $1ToSeq($3, $2_00.int)" % [fixedName2(h.replace("00")).unCap, pars.blex, sym & pars.arglist])
|
||||
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" cogfree(resul0)")
|
||||
elif (pars.replist.len > 0 or gCallableInfoCanThrowGerror(minfo)) and ngrRet.name != "void":
|
||||
# caution dragons like g_key_file_get_locale_string_list()
|
||||
if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING:
|
||||
discard # echo "Untamed dragon: ", sym
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
methodBuffer.write(" result = ")
|
||||
if needTypeConv(ngrRet.name, ngrRet):
|
||||
methodBuffer.writeLine(doCt3nt(ngrRet.name, ngrRet) & '(' & "resul0" & ')')
|
||||
else:
|
||||
methodBuffer.writeLine("resul0")
|
||||
else:
|
||||
methodBuffer.write(" result = ")
|
||||
if needTypeConv(ngrRet.name, ngrRet):
|
||||
methodBuffer.writeLine(doCt3nt(ngrRet.name, ngrRet) & '(' & sym & pars.arglist & ')')
|
||||
else:
|
||||
methodBuffer.writeLine(sym & pars.arglist)
|
||||
elif needTypeConv(ngrRet.name, ngrRet):
|
||||
if gCallableInfoCanThrowGerror(minfo) or gCallableInfoMayReturnNull(minfo) or gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoMayReturnNull(minfo):
|
||||
methodBuffer.writeLine(" if resul0.isNil:")
|
||||
methodBuffer.writeLine(" return")
|
||||
if ngrRet.name == "ptr cstring" and ngrRet.flags.contains(RecResFlag.array) and gCallableInfoGetCallerOwns(minfo) ==
|
||||
GITransfer.EVERYTHING:
|
||||
methodBuffer.writeLine(" result = cstringArrayToSeq(resul0)")
|
||||
methodBuffer.writeLine(" g_strfreev(resul0)")
|
||||
else:
|
||||
methodBuffer.writeLine(" " & doCt3nt(ngrRet.name, ngrRet) & '(' & "resul0" & ')')
|
||||
else:
|
||||
if pars.tempResFree != "": # ugly, do we have a better test for this case
|
||||
#if ngrRet.name != "void":
|
||||
methodBuffer.writeLine(" result = " & doCt3nt(ngrRet.name, ngrRet) & '(' & sym & pars.arglist & ')')
|
||||
else:
|
||||
methodBuffer.writeLine(" " & doCt3nt(ngrRet.name, ngrRet) & '(' & sym & pars.arglist & ')')
|
||||
checkForGerror() # i.e. for nice_agent_set_remote_candidates, free GSList
|
||||
else:
|
||||
if gCallableInfoCanThrowGerror(minfo) and ngrRet.name != "void":
|
||||
assert false
|
||||
methodBuffer.writeLine(" let resul0 = " & sym & pars.arglist)
|
||||
else:
|
||||
methodBuffer.writeLine(" " & sym & pars.arglist)
|
||||
checkForGerror()
|
||||
if gCallableInfoCanThrowGerror(minfo) and ngrRet.name != "void":
|
||||
assert false
|
||||
methodBuffer.writeLine(" resul0 #####")
|
||||
for k, v in pars.replist:
|
||||
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.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])
|
||||
else:
|
||||
if v[1].optOut:
|
||||
methodBuffer.writeLine(" if $1.addr != nil:" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
||||
methodBuffer.writeLine(" $1 = $2($3_00)" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
||||
else:
|
||||
methodBuffer.writeLine(" $1 = $2($3_00)" % [k, doCt3nt(v[0], v[1]), k.strip(chars = {'`'})])
|
||||
# BLOCKMARK8
|
||||
else: # } end of large proxy block BLOCK7
|
||||
asym = fixedProcNames.getOrDefault(sym, asym)
|
||||
pars = genPars(mInfo, false, info)
|
||||
|
|
@ -1970,7 +1913,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
|
|||
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" or asym == "destroy"): # v0.8.6
|
||||
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:")
|
||||
if gTypeInfoGetTag(ret2) != GITypeTag.VOID: # i.e. gst_sdp_media_free()
|
||||
|
|
@ -2764,7 +2708,8 @@ proc processInfo(i: GIBaseInfo) =
|
|||
elif gBaseInfoGetType(i) == GIInfoType.CONSTANT:
|
||||
writeConst(i)
|
||||
elif gBaseInfoGetType(i) == GIInfoType.Boxed:
|
||||
echo "gBaseInfoGetType(i) == GIInfoType.Boxed: ", gBaseInfoGetName(i)
|
||||
if $gBaseInfoGetName(i) notin ["TreeRowData", "ByteArray", "FileList"]: # hide ugly output for v0.8.7, investgate later
|
||||
echo "gBaseInfoGetType(i) == GIInfoType.Boxed: ", gBaseInfoGetName(i)
|
||||
# echo "++++++++ ", g_registered_type_info_get_g_type(i), g_registered_type_info_get_type_name(i)
|
||||
# assert false executed for gtk4
|
||||
else:
|
||||
|
|
@ -3245,7 +3190,6 @@ proc main(namespace: string; version: cstring = nil) =
|
|||
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:
|
||||
|
|
@ -3259,7 +3203,7 @@ proc main(namespace: string; version: cstring = nil) =
|
|||
var weImportGObject = false
|
||||
output.writeLine("# dependencies:")
|
||||
var importedModules = ""
|
||||
for j in 0 .. 12:
|
||||
for j in 0 .. 18: # stupid restriction!
|
||||
if dep[j].isNil: break
|
||||
if j == 0:
|
||||
importedModules = "import "
|
||||
|
|
@ -3828,6 +3772,13 @@ proc get$1*(builder: Builder; name: string): $1 =
|
|||
suff = "4"
|
||||
if namespace == "GtkSource" and version == nil:
|
||||
suff = "5"
|
||||
|
||||
if namespace in ["JavaScriptCore", "WebKit2", "WebKit2WebExtension"]:
|
||||
if version == "4.0":
|
||||
suff = ""
|
||||
if version == "5.0":
|
||||
suff = "5"
|
||||
|
||||
var o = open("nim_gi" / (namespace.toLowerAscii) & suff & ".nim", fmWrite)
|
||||
o.write(output.data)
|
||||
o.close()
|
||||
|
|
@ -3887,10 +3838,10 @@ proc launch() =
|
|||
main("Handy")
|
||||
main("Nice")
|
||||
main("cairo")
|
||||
main("WebKit2")
|
||||
main("JavaScriptCore")
|
||||
main("WebKit2", "4.0")
|
||||
main("JavaScriptCore", "4.0")
|
||||
main("Soup")
|
||||
main("WebKit2WebExtension")
|
||||
main("WebKit2WebExtension", "4.0")
|
||||
main("Gst")
|
||||
main("GstBase")
|
||||
main("GstAllocators")
|
||||
|
|
@ -3940,6 +3891,10 @@ proc launch() =
|
|||
# main("Handy") # not yet available for GTK4
|
||||
main("Nice")
|
||||
main("cairo")
|
||||
main("WebKit2", "5.0")
|
||||
main("JavaScriptCore", "5.0")
|
||||
main("Soup")
|
||||
main("WebKit2WebExtension", "5.0")
|
||||
main("Gst")
|
||||
main("GstBase")
|
||||
main("GstAllocators")
|
||||
|
|
@ -3993,7 +3948,7 @@ launch()
|
|||
# if not xcallerAlloc.contains(el):
|
||||
# echo el
|
||||
|
||||
# 3996 lines
|
||||
# 3951 lines
|
||||
# gtk_icon_view_get_tooltip_context bug Candidate
|
||||
# gtk_tree_view_get_cursor bug
|
||||
#
|
||||
|
|
@ -4010,4 +3965,3 @@ proc gst_structure_take(oldstrPtr: var ptr Structure00; newstr: ptr Structure00)
|
|||
proc take*(oldstrPtr: var Structure; newstr: Structure = nil): bool =
|
||||
toBool(gst_structure_take(if oldstrPtr.isNil: nil else: cast[ptr Structure00](oldstrPtr.impl), if newstr.isNil: nil else: cast[ptr Structure00](newstr.impl)))
|
||||
]#
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue