diff --git a/examples/app0.nim b/examples/app0.nim index 7cea5ad..0b7b37e 100644 --- a/examples/app0.nim +++ b/examples/app0.nim @@ -4,7 +4,7 @@ import gintro/[gtk, glib, gobject] import gintro/gio except Application, newApplication # we want to use GTK application #from gintro/gio import ApplicationFlags, scActivate, run -proc activate(app: Application) = +proc appActivate(app: Application) = let window = newApplicationWindow(app) window.title = "GTK3 & Nim" window.defaultSize = (200, 200) @@ -12,7 +12,7 @@ proc activate(app: Application) = proc main = let app = newApplication("org.gtk.example") - connect(app, "activate", activate) + connect(app, "activate", appActivate) discard run(app) main() diff --git a/examples/button.nim b/examples/button.nim index d21b98d..636a2bb 100644 --- a/examples/button.nim +++ b/examples/button.nim @@ -5,7 +5,7 @@ import gintro/gio except Application, newApplication proc buttonClicked (button: Button) = button.label = utf8Strreverse(button.label, -1) -proc activate (app: Application) = +proc appActivate (app: Application) = let window = newApplicationWindow(app) window.title = "GNOME Button" window.defaultSize = (250, 50) @@ -16,7 +16,7 @@ proc activate (app: Application) = proc main = let app = newApplication("org.gtk.example") - connect(app, "activate", activate) + connect(app, "activate", appActivate) discard app.run main() diff --git a/examples/cairo_anim.nim b/examples/cairo_anim.nim index 12b2eb0..d7335a5 100644 --- a/examples/cairo_anim.nim +++ b/examples/cairo_anim.nim @@ -25,7 +25,7 @@ proc drawingAreaDrawCb(widget: DrawingArea; context: Context): bool = inc(redrawNumber) return true # TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further. -proc activate(app: Application) = +proc appActivate(app: Application) = let window = newApplicationWindow(app) window.title = "Drawing example" window.defaultSize = (400, 400) @@ -37,7 +37,7 @@ proc activate(app: Application) = proc main = let app = newApplication("org.gtk.example") - connect(app, "activate", activate) + connect(app, "activate", appActivate) discard run(app) main() diff --git a/examples/connect_args.nim b/examples/connect_args.nim index 958d4a7..3c58be9 100644 --- a/examples/connect_args.nim +++ b/examples/connect_args.nim @@ -21,7 +21,7 @@ proc b4Callback(button: Button; w: ApplicationWindow) = else: w.title = "Nim with GTK3" -proc activate (app: Application) = +proc appActivate (app: Application) = var o: O var r: ref O new r @@ -47,7 +47,7 @@ proc activate (app: Application) = proc main = let app = newApplication("org.gtk.example") - connect(app, "activate", activate) + connect(app, "activate", appActivate) discard app.run main() diff --git a/examples/count_button.nim b/examples/count_button.nim index 79c2a00..347c9f9 100644 --- a/examples/count_button.nim +++ b/examples/count_button.nim @@ -11,7 +11,7 @@ proc buttonClicked (button: CountButton; decrement: int) = button.label = "Counter: " & $button.counter echo "Counter is now: ", button.counter -proc activate (app: Application) = +proc appActivate (app: Application) = var button: CountButton let window = newApplicationWindow(app) window.title = "Count Button" @@ -23,7 +23,7 @@ proc activate (app: Application) = proc main = let app = newApplication("org.gtk.example") - connect(app, "activate", activate) + connect(app, "activate", appActivate) discard app.run main() diff --git a/examples/label.nim b/examples/label.nim index 1ae3bc5..0e844d8 100644 --- a/examples/label.nim +++ b/examples/label.nim @@ -2,7 +2,7 @@ import gintro/[gtk, glib, gobject] import gintro/gio except Application, newApplication -proc activate(app: Application) = +proc appActivate(app: Application) = let window = newApplicationWindow(app) let label = newLabel("Yellow text on green background") let cssProvider = newCssProvider() @@ -17,7 +17,7 @@ proc activate(app: Application) = proc main = let app = newApplication("org.gtk.example") - connect(app, "activate", activate) + connect(app, "activate", appActivate) discard run(app) main() diff --git a/gintro/gimpl.nim b/gintro/gimpl.nim index f0554fb..cfca9b5 100644 --- a/gintro/gimpl.nim +++ b/gintro/gimpl.nim @@ -14,19 +14,28 @@ proc ct5nt(s: string): string = proc findSignal(name, obj: NimNode): string = let str = ($name).replace("-", "_") & RecSep + var ipros: seq[string] for i in SCA: if i.startsWith(str): - let t = i.split(RecSep, 2)[1] - var n = obj - while true: - if n.kind != nnkBracketExpr: break - var h = $getType(n)[1].toStrLit - if h.endsWith(":ObjectType"): - h.setLen(h.len - 11) - if h == t: - return i - n = getType(n)[1] - n = getType(n)[1] + let h1 = i.split(RecSep)[3] + let h2 = h1.split(": ")[1] + let h = h2.split({';', ')'})[0] + if h.contains("|"): + ipros = h.split(" | ") + else: + ipros = @[h] + assert(ipros[0] == i.split(RecSep, 2)[1]) + for t in ipros: + var n = obj + while true: + if n.kind != nnkBracketExpr: break + var h = $getType(n)[1].toStrLit + if h.endsWith(":ObjectType"): + h.setLen(h.len - 11) + if h == t: + return i + n = getType(n)[1] + n = getType(n)[1] var ProcID: int # from file gisup.nim we have: @@ -73,7 +82,7 @@ proc $1$2 {.cdecl.} = if hargs[i].contains("|"): ipos = i break - assert(ipos >= 0) # indeed assert(ipos > 0) as first parameter should be plain widget/gobject + assert(ipos >= 0) let ipronode = p.symbol.getImpl().params[ipos + 1][1] # the actual data type for interface providers if ipronode.isNil: quit("Error: Signal-Handler has too few parameters: " & $(p.symbol.getImpl().name.toStrLit) & $(p.symbol.getImpl().params.toStrLit)) @@ -92,6 +101,7 @@ proc $1$2 {.cdecl.} = if ahl.contains("): "): resl = all.rsplit("): ", 1)[1] var resu = " $3(cast[$4](h)" + if all.find(";") > 0: # more than one argument var largs = all.split("; ") largs.delete(0) @@ -109,7 +119,10 @@ proc $1$2 {.cdecl.} = if h.len > 0: a1 = h & "(" & a1 & ")" names[i] = a1 - if ipro != nil: types[ipos - 1] = ipro + + if ipos > 0: + types[ipos - 1] = ipro + for i in 0 .. largs.high: if types[i] == nil: resu.add(", " & names[i]) @@ -118,6 +131,7 @@ proc $1$2 {.cdecl.} = r1s.add(" var " & names[i] & "1: " & types[i] & "\n") r1s.add(" new " & names[i] & "1" & "\n") r1s.add(" " & names[i] & "1.impl = " & names[i] & "\n") + if not ignoreArg.boolVal: resu.add(", cast[$5](data)") resu.add(")") @@ -134,6 +148,7 @@ proc $1$2 {.cdecl.} = ahl = "(self: " & wts & ";" & ahl.split(";", 1)[1] else: ahl = "(self: " & wts & ")" & ahl.split(")", 1)[1] + let r2s = if ignoreArg.boolVal: """ diff --git a/tests/gen.nim b/tests/gen.nim index 177087c..29bd592 100644 --- a/tests/gen.nim +++ b/tests/gen.nim @@ -1,5 +1,5 @@ # High level gobject-introspection based GTK3 bindings for the Nim programming language -# v 0.2 2017-SEP-19 +# v 0.2 2017-SEP-27 # (c) S. Salewski 2017 # https://wiki.gnome.org/Projects/GObjectIntrospection @@ -240,6 +240,7 @@ proc mangleType(s: cstring): string = var output: StringStream var supmod: StringStream var methodBuffer: StringStream +var signalBuffer: StringStream proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (string, string, TableRef[string, string]) @@ -355,6 +356,12 @@ proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (str arglist = "(cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" & "self.impl)" if genProxy: var h = manglename(gBaseInfoGetName(binfo)) + + if interfaceProvider.contains(h): + let provider = interfaceProvider[h] + for i in provider: discard mangleType(i) + h = h & " | " & provider.join(" | ") + if (sym.startsWith("gdk_events_get_") or sym.startsWith("gdk_event_get_")) and h == "Event": h = "SomeEvent" resul = "(self: " & h @@ -481,6 +488,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = var replist: TableRef[string, string] let p = methodBuffer.getPosition let sym = $gFunctionInfoGetSymbol(mInfo) + if sym[^1] == '_': return if sym.contains("__"): return if processedFunctions.contains(sym): return @@ -494,6 +502,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = if sym == "g_iconv": return try: + #if sym == "g_value_get_string": echo "g_value_get_string"; quit() (plist, arglist, replist) = genP(mInfo, genProxy, info) methodBuffer.write("\nproc " & sym & EM & plist) methodBuffer.writeLine(" {.\n importc: \"", sym, "\", ", libprag, ".}") @@ -506,6 +515,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = asym.add($manglename(gBaseInfoGetName(info))) if keywords.split.contains(asym) or nims.split.contains(asym): asym.add('P') var ret2 = gCallableInfoGetReturnType(minfo) + #if sym == "g_value_get_string": echo isString(ret2); quit() var ret22 = gCallableInfoGetReturnType(minfo) for run in 0 .. 1: if run == 1: @@ -835,7 +845,7 @@ proc writeInterface(info: GIInterfaceInfo) = ################################ let numsig = info.gInterfaceInfoGetNSignals - if numsig > 0: output.writeLine("") + if numsig > 0: signalbuffer.writeLine("") for j in 0 .. 0 or gTypeInfoGetTag(zzzu) != GITypeTag.VOID: - output.writeLine(" p: proc (self: ptr " & xxx & "00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") + signalbuffer.writeLine(" p: proc (self: ptr " & yyy & "00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") else: - output.writeLine(" p: proc (self: ptr gobject.Object00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") - output.write(" g_signal_connect_data(self.impl, \"") - output.write($gBaseInfoGetName(signalInfo)) - output.writeLine("\", cast[GCallback](p), xdata, nil, cast[ConnectFlags](0))") + signalbuffer.writeLine(" p: proc (self: ptr gobject.Object00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") + signalbuffer.write(" g_signal_connect_data(self.impl, \"") + signalbuffer.write($gBaseInfoGetName(signalInfo)) + signalbuffer.writeLine("\", cast[GCallback](p), xdata, nil, cast[ConnectFlags](0))") ################################ @@ -1099,7 +1119,7 @@ proc writeObj(info: GIObjectInfo) = output.writeLine(" g_object_remove_toggle_ref(o.impl, toggleNotify, addr(o[]))") let numsig = info.gObjectInfoGetNSignals - if numsig > 0: output.writeLine("") + if numsig > 0: signalbuffer.writeLine("") for j in 0 .. 0 or gTypeInfoGetTag(zzzu) != GITypeTag.VOID: - output.writeLine(" p: proc (self: ptr " & xxx & "00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") + signalbuffer.writeLine(" p: proc (self: ptr " & yyy & "00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") else: - output.writeLine(" p: proc (self: ptr gobject.Object00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") - output.write(" g_signal_connect_data(self.impl, \"") - output.write($gBaseInfoGetName(signalInfo)) - output.writeLine("\", cast[GCallback](p), xdata, nil, cast[ConnectFlags](0))") + signalbuffer.writeLine(" p: proc (self: ptr gobject.Object00; " & h & " {.cdecl.}, xdata: pointer = nil): culong =") + signalbuffer.write(" g_signal_connect_data(self.impl, \"") + signalbuffer.write($gBaseInfoGetName(signalInfo)) + signalbuffer.writeLine("\", cast[GCallback](p), xdata, nil, cast[ConnectFlags](0))") let nMethods = gObjectInfoGetNMethods(info) for j in 0 .. 0: + var more_runs = 50 + while s.len > 0 or more_runs > 0: + if s.len == 0: dec(more_runs) if namespace == "GObject" and not knownSyms.contains("g_signal_connect_data"): if knownSyms.contains("ClosureNotify") and knownSyms.contains("ConnectFlags"): knownSyms.incl("g_signal_connect_data") @@ -1516,8 +1545,9 @@ proc main(namespace: string) = s.add(s[k]) s.delete(k) - i = s.pop - delayedSyms.insert(i) + if s.len > 0: + i = s.pop + delayedSyms.insert(i) if classList.len > 0: delayedSyms.insert(classList.pop) unp.setLen(0) @@ -1525,9 +1555,12 @@ proc main(namespace: string) = var pos = output.getPosition var supmodpos = supmod.getPosition try: + echo "try process ", mangleName(gBaseInfoGetName(k)) knownSyms.incl(mangleName(gBaseInfoGetName(k))) methodBuffer = newStringStream() + signalBuffer = newStringStream() processInfo(k) + output.write(signalBuffer.data) output.write(methodBuffer.data) echo "----------", gBaseInfoGetName(k) except UndefEx: @@ -1541,19 +1574,22 @@ proc main(namespace: string) = if delayedSyms.len > a: suppressType = true methodBuffer = newStringStream() + signalBuffer = newStringStream() unp = delayedSyms for t in unp.combinations(a + 1): var pos = output.getPosition var supmodpos = supmod.getPosition methodBuffer = newStringStream() + signalBuffer = newStringStream() let x = delayedMethods.len try: var h = false for k in t: - if gBaseInfoGetType(k) != GIInfoType.OBJECT and gBaseInfoGetType(k) != GIInfoType.STRUCT and gBaseInfoGetType(k) != GIInfoType.UNION and not isCallbackInfo(k): + if gBaseInfoGetType(k) != GIInfoType.INTERFACE and gBaseInfoGetType(k) != GIInfoType.OBJECT and gBaseInfoGetType(k) != GIInfoType.STRUCT and gBaseInfoGetType(k) != GIInfoType.UNION and not isCallbackInfo(k): h = true if h: continue output.writeLine("type") + for k in t: knownSyms.incl(mangleName(gBaseInfoGetName(k))) for k in t: @@ -1561,7 +1597,9 @@ proc main(namespace: string) = for k in t: delayedSyms.keepItIf(mangleName(gBaseInfoGetName(k)) != mangleName(gBaseInfoGetName(it))) suppressType = false + output.write(signalBuffer.data) output.write(methodBuffer.data) + break myb except UndefEx: for k in t: @@ -1633,4 +1671,4 @@ o.close() supmod.close #for i in callerAllocCollector: echo i -# 1530 lines +# 1660 lines