--gc:arc support added

This commit is contained in:
Stefan Salewski 2020-01-27 12:03:16 +01:00
commit 2628663637
7 changed files with 356 additions and 181 deletions

View file

@ -25,7 +25,35 @@ 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. 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. The `combinatorics` module was kindly provided by R. Behrends.
NOTE: Starting with current version v.0.6.0 we support gstreamer (gst). At the same time we have split
NOTE: Starting with current version v0.7.0 we support the new Nim memory management called ARC, see
https://forum.nim-lang.org/t/5734. Just compile your programs with `--gc:arc`. The main advantage is that
ARC is deterministic, so it is easier to find bugs in the bindings or in your programs. And
manually freeing resources, as we did previous for some cairo data structures to free them
without GC delay should be now unnecessary. Generally this version should be more stable:
Nim without option `--gc:arc` compiled new() calls silently with and without a finalizer proc parameter for
the same data type, but the finalizer was then always called. This behaviour was stated in the Nim manual,
but it was easy to forget this strange behaviour, so unintentionally finalizer calls may have ocurred.
Nim with --gc:arc detects at least some of these errors, and for gintro we now try hard to not mix these calls.
Generally we specify a finalizer, and use a field in the ref object to ignore the call when necessary.
For a type always the same finalizer has to be used (or always none) and finalizer must be defined in the
same module as the object type itself. For this to work reliable we have generally to qualify the
finalizer proc with its module prefix. All that made a larger rewrite of gen.nim generator script
necessary, with the danger of introducing bugs. We have not tested v0.7 much yet, the examples in
gtk3 directory compile and seems to start at least. We would still have to check the macros in gimpl.nim more
carefully -- we had to replace deepcopy by a plain copy and removed a (wrong?) GC_ref(). Generally we have
to investigate possible memory leaks. One leak is unavoidable: If we subclass Widgets, then
finalizer are not applied to the GTK object, so its memory leaks. See https://forum.nim-lang.org/t/5825#36241.
But that should be not a too serious problem, subclassed objects are generally only allocated once
in a program and generally live as long as the program is running any way. For the next version of
gintro we do consider using only destructors and no finalizers, see https://forum.nim-lang.org/t/5854
and https://forum.nim-lang.org/t/5786. That may simplify the code and enable subclassed GTK objects
to release its memory, but require rewriting gen.nim again. But then we would have to use `--gc:arc`
always. Maybe we can join both by specifying some conditional `when` expression -- we will see.
If for you installation or compiling with v0.7 should not work, then please report issues on
github issue tracker and continue using v0.6.1 for now.
NOTE: Starting with version v.0.6.0 we support gstreamer (gst). At the same time we have split
cairo module into an gobject-introspection basic part and an manually created part. Unfortunately the cairo module into an gobject-introspection basic part and an manually created part. Unfortunately the
gobject-introspection is not available for very old GTK/cairo libraries, so installation may fail for you. gobject-introspection is not available for very old GTK/cairo libraries, so installation may fail for you.
Use v0.5.5 in this case. Also we support gBoxed types now, this is assumed to work well but is not well tested yet. Use v0.5.5 in this case. Also we support gBoxed types now, this is assumed to work well but is not well tested yet.
@ -152,7 +180,7 @@ or function arguments or results may be so called _glists_,
list structures of `glib` library. These cases can not be processed automatically but needs carefully manual investigations. And there may be still functions and data list structures of `glib` library. These cases can not be processed automatically but needs carefully manual investigations. And there may be still functions and data
types missing: {GIR} query gives us many thousand lines of Nim interface code, and it is not really obvious if and what is missing. types missing: {GIR} query gives us many thousand lines of Nim interface code, and it is not really obvious if and what is missing.
Some functions and data types are missing for sure -- at least some low level ones, which are considered unneeded for high level bindings by {GIR}. Some functions and data types are missing for sure -- at least some low level ones, which are considered unneeded for high level bindings by {GIR}.
But maybe more is missing, we have to investigate that. Until now these bindings have been tested only for 64 bit Linux systems with GTK 3.22. But maybe more is missing, we have to investigate that. Until now these bindings have been tested only for 64 bit Linux systems with GTK 3.24.
These basic libraries are already partly tested: These basic libraries are already partly tested:
@ -180,7 +208,7 @@ get a longer error message which may help you to solve the issue.
NOTE: Nimble prepare should run for about 20 seconds, it compiles and executes the generator program `gen.nim`. NOTE: Nimble prepare should run for about 20 seconds, it compiles and executes the generator program `gen.nim`.
Unfortunately we can not guarantee that the generator command will be able to really build all the Unfortunately we can not guarantee that the generator command will be able to really build all the
desired modules. The built process highly depends on your OS and installed GTK version. For 64 bit Linux systems desired modules. The built process highly depends on your OS and installed GTK version. For 64 bit Linux systems
with GTK 3.22 and all required dependencies installed it should work. For never GTK versions it may fail, when that GTK with GTK 3.24 and all required dependencies installed it should work. For never GTK versions it may fail, when that GTK
release introduces for example new unknown data types like array containers. In that case manual fixes may be necessary. release introduces for example new unknown data types like array containers. In that case manual fixes may be necessary.
The {GIR} based built process generates bindings customized to the OS where the generator is executed, The {GIR} based built process generates bindings customized to the OS where the generator is executed,
so for older GTK releases or a 32 bit system different files are created. Later we may also provide pre-generated so for older GTK releases or a 32 bit system different files are created. Later we may also provide pre-generated

View file

@ -2,22 +2,23 @@ nim c app0.nim
nim c builder.nim nim c builder.nim
nim c button.nim nim c button.nim
nim c cairo_anim.nim nim c cairo_anim.nim
nim c cairoImage.nim
nim c celldatafunction.nim
nim c connect_args.nim nim c connect_args.nim
nim c count_button.nim nim c count_button.nim
nim c css_colored_listview.nim
nim c darea_test.nim nim c darea_test.nim
nim c drawingarea.nim nim c drawingarea.nim
nim c gaction.nim
nim c gaction2.nim nim c gaction2.nim
nim c gaction.nim
nim c gearsmenu.nim
nim c gsettings.nim nim c gsettings.nim
nim c gstBasicTutorial1.nim
nim c label.nim nim c label.nim
nim c listview.nim nim c listview.nim
nim c menubar.nim nim c menubar.nim
nim c t0.nim
nim c simpledrawingarea.nim
nim c css_colored_listview.nim
nim c gearsmenu.nim
nim c cairoImage.nim
nim c gstBasicTutorial1.nim
nim c sourceview_test.nim
nim c overlay_tree1.nim nim c overlay_tree1.nim
nim c celldatafunction.nim nim c simpledrawingarea.nim
nim c sourceview_test.nim
nim c t0.nim

24
examples/gtk3/makeAllArc Normal file
View file

@ -0,0 +1,24 @@
nim c --gc:arc app0.nim
nim c --gc:arc builder.nim
nim c --gc:arc button.nim
nim c --gc:arc cairo_anim.nim
nim c --gc:arc cairoImage.nim
nim c --gc:arc celldatafunction.nim
nim c --gc:arc connect_args.nim
nim c --gc:arc count_button.nim
nim c --gc:arc css_colored_listview.nim
nim c --gc:arc darea_test.nim
nim c --gc:arc drawingarea.nim
nim c --gc:arc gaction2.nim
nim c --gc:arc gaction.nim
nim c --gc:arc gearsmenu.nim
nim c --gc:arc gsettings.nim
nim c --gc:arc gstBasicTutorial1.nim
nim c --gc:arc label.nim
nim c --gc:arc listview.nim
nim c --gc:arc menubar.nim
nim c --gc:arc overlay_tree1.nim
nim c --gc:arc simpledrawingarea.nim
nim c --gc:arc sourceview_test.nim
nim c --gc:arc t0.nim

View file

@ -1,6 +1,6 @@
# Package # Package
version = "0.6.1" version = "0.7.0"
author = "Stefan Salewski" author = "Stefan Salewski"
description = "High level GObject-Introspection based GTK3/GTK4 bindings" description = "High level GObject-Introspection based GTK3/GTK4 bindings"
license = "MIT" license = "MIT"

View file

@ -1,7 +1,7 @@
# This is the high level cairo module for Nim -- based on the low level ngtk3 module, manually tuned. # This is the high level cairo module for Nim -- based on the low level ngtk3 module, manually tuned.
# (c) S. Salewski 2017, cairo 1.15.6 # (c) S. Salewski 2017, cairo 1.15.6
# v0.6.0 # v0.7.0
# 03-DEC-2019 # 27-JAN-2020
# starting with gintro v.0.6.0 we split cairo into the gobject-introspection generated cairo.nim and this file. # starting with gintro v.0.6.0 we split cairo into the gobject-introspection generated cairo.nim and this file.
@ -183,7 +183,7 @@ proc setUserData*(surface: Surface; key: ptr UserDataKey; userData: pointer; des
proc cairo_create*(target: ptr Surface00): ptr Context00 {.importc, libcairo.} proc cairo_create*(target: ptr Surface00): ptr Context00 {.importc, libcairo.}
# #
proc newContext*(target: Surface): Context = proc newContext*(target: Surface): Context =
new(result, destroy) new(result, gBoxedFreeCairoContext)
GC_ref(target) GC_ref(target)
result.impl = cairo_create(target.impl) result.impl = cairo_create(target.impl)
discard cairo_surface_set_user_data(target.impl, NUDK, cast[pointer](target), gcuref) discard cairo_surface_set_user_data(target.impl, NUDK, cast[pointer](target), gcuref)
@ -226,7 +226,6 @@ proc cairo_pattern_destroy*(pattern: ptr Pattern00) {.importc, libcairo.}
# #
proc patternDestroy*(pattern: Pattern) = proc patternDestroy*(pattern: Pattern) =
#cairo_pattern_destroy(pattern.impl) #cairo_pattern_destroy(pattern.impl)
if pattern != nil and pattern.impl != nil: if pattern != nil and pattern.impl != nil:
cairo_pattern_destroy(pattern.impl) cairo_pattern_destroy(pattern.impl)
pattern.impl = nil pattern.impl = nil
@ -240,7 +239,7 @@ proc setUserData*(pattern: Pattern; key: ptr UserDataKey; userData: pointer; des
proc cairo_pop_group*(cr: ptr Context00): ptr Pattern00 {.importc, libcairo.} proc cairo_pop_group*(cr: ptr Context00): ptr Pattern00 {.importc, libcairo.}
# #
proc popGroup*(cr: Context): Pattern = proc popGroup*(cr: Context): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pop_group(cr.impl) result.impl = cairo_pop_group(cr.impl)
GC_Ref(result) GC_Ref(result)
discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -723,21 +722,21 @@ type
proc cairo_font_options_destroy*(options: ptr FontOptions00) {.importc, libcairo.} proc cairo_font_options_destroy*(options: ptr FontOptions00) {.importc, libcairo.}
# #
proc fontOptionsDestroy(options: FontOptions) = #proc fontOptionsDestroy(options: FontOptions) =
cairo_font_options_destroy(options.impl) # cairo_font_options_destroy(options.impl)
# FontOptions00 is special -- there is no cairo_font_options_set_user_data() and no cairo_font_options_reference() # FontOptions00 is special -- there is no cairo_font_options_set_user_data() and no cairo_font_options_reference()
proc cairo_font_options_create*(): ptr FontOptions00 {.importc, libcairo.} proc cairo_font_options_create*(): ptr FontOptions00 {.importc, libcairo.}
# #
proc newFontOptions*(): FontOptions = proc newFontOptions*(): FontOptions =
new(result, fontOptionsDestroy) new(result, gBoxedFreeCairoFontOptions)
result.impl = cairo_font_options_create() result.impl = cairo_font_options_create()
###discard cairo_font_options_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ###discard cairo_font_options_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_font_options_copy*(original: ptr FontOptions00): ptr FontOptions00 {.importc, libcairo.} proc cairo_font_options_copy*(original: ptr FontOptions00): ptr FontOptions00 {.importc, libcairo.}
# #
proc fontOptionsCopy*(original: FontOptions): FontOptions = proc fontOptionsCopy*(original: FontOptions): FontOptions =
new(result, fontOptionsDestroy) new(result, gBoxedFreeCairoFontOptions)
result.impl = cairo_font_options_copy(original.impl) result.impl = cairo_font_options_copy(original.impl)
proc cairo_font_options_status*(options: ptr FontOptions00): Status {.importc, libcairo.} proc cairo_font_options_status*(options: ptr FontOptions00): Status {.importc, libcairo.}
@ -849,8 +848,8 @@ proc setFontOptions*(cr: Context; options: FontOptions) =
proc cairo_get_font_options*(cr: ptr Context00; options: ptr FontOptions00) {.importc, libcairo.} proc cairo_get_font_options*(cr: ptr Context00; options: ptr FontOptions00) {.importc, libcairo.}
# #
proc getFontOptions*(cr: Context; options: var FontOptions) = proc getFontOptions*(cr: Context; options: var FontOptions) =
###new(options, fontOptionsDestroy) ###new(options, gBoxedFreeCairoFontOptions)
new(options, fontOptionsDestroy) new(options, gBoxedFreeCairoFontOptions)
options.impl = cairo_font_options_create() options.impl = cairo_font_options_create()
cairo_get_font_options(cr.impl, options.impl) cairo_get_font_options(cr.impl, options.impl)
@ -918,8 +917,8 @@ proc setScaledFont*(cr: Context; scaledFont: ScaledFont) =
proc cairo_scaled_font_destroy*(scaled_font: ptr ScaledFont00) {.importc, libcairo.} proc cairo_scaled_font_destroy*(scaled_font: ptr ScaledFont00) {.importc, libcairo.}
# #
proc scaledFontDestroy*(scaledFont: ScaledFont) = #proc scaledFontDestroy*(scaledFont: ScaledFont) =
cairo_scaled_font_destroy(scaledFont.impl) # cairo_scaled_font_destroy(scaledFont.impl)
proc cairo_scaled_font_get_user_data*(scaledFont: ptr ScaledFont00; proc cairo_scaled_font_get_user_data*(scaledFont: ptr ScaledFont00;
key: ptr UserDataKey): pointer {.importc, libcairo.} key: ptr UserDataKey): pointer {.importc, libcairo.}
@ -948,7 +947,7 @@ proc getScaledFont*(cr: Context): ScaledFont =
let d = cairo_scaled_font_get_user_data(h, NUDK) let d = cairo_scaled_font_get_user_data(h, NUDK)
if d.isNil: if d.isNil:
#assert false # may this happen? #assert false # may this happen?
new(result, scaledFontDestroy) new(result, gBoxedFreeCairoScaledFont)
result.impl = h result.impl = h
discard cairo_scaled_font_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) discard cairo_scaled_font_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
discard cairo_scaled_font_reference(result.impl) discard cairo_scaled_font_reference(result.impl)
@ -1022,7 +1021,7 @@ proc cairo_scaled_font_create*(fontFace: ptr FontFace00;
fontMatrix: Matrix; ctm: Matrix; options: ptr FontOptions00): ptr ScaledFont00 {.importc, libcairo.} fontMatrix: Matrix; ctm: Matrix; options: ptr FontOptions00): ptr ScaledFont00 {.importc, libcairo.}
# #
proc scaledFontCreate*(fontFace: FontFace; fontMatrix: Matrix; ctm: Matrix; options: FontOptions): ScaledFont = proc scaledFontCreate*(fontFace: FontFace; fontMatrix: Matrix; ctm: Matrix; options: FontOptions): ScaledFont =
new(result, scaledFontDestroy) new(result, gBoxedFreeCairoScaledFont)
GC_ref(fontFace) GC_ref(fontFace)
result.impl = cairo_scaled_font_create(fontFace.impl, fontMatrix, ctm, options.impl) result.impl = cairo_scaled_font_create(fontFace.impl, fontMatrix, ctm, options.impl)
discard cairo_scaled_font_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) discard cairo_scaled_font_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1114,7 +1113,7 @@ proc cairo_scaled_font_get_font_options*(scaledFont: ptr ScaledFont00;
options: ptr FontOptions00) {.importc, libcairo.} options: ptr FontOptions00) {.importc, libcairo.}
# #
proc getFontOptions*(scaledFont: ScaledFont; options: var FontOptions) = proc getFontOptions*(scaledFont: ScaledFont; options: var FontOptions) =
new(options, fontOptionsDestroy) new(options, gBoxedFreeCairoFontOptions)
options.impl = cairo_font_options_create() options.impl = cairo_font_options_create()
cairo_scaled_font_get_font_options(scaledFont.impl, options.impl) cairo_scaled_font_get_font_options(scaledFont.impl, options.impl)
# #
@ -1244,7 +1243,7 @@ proc getSource*(cr: Context): Pattern =
let h = cairo_get_source(cr.impl) let h = cairo_get_source(cr.impl)
let d = cairo_pattern_get_user_data(h, NUDK) let d = cairo_pattern_get_user_data(h, NUDK)
if d.isNil: if d.isNil:
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_reference(h) result.impl = cairo_pattern_reference(h)
else: else:
result = cast[Pattern](d) result = cast[Pattern](d)
@ -1351,7 +1350,7 @@ proc getTarget*(cr: Context): Surface =
let d = cairo_surface_get_user_data(h, NUDK) let d = cairo_surface_get_user_data(h, NUDK)
if d.isNil: if d.isNil:
assert false # may this happen? assert false # may this happen?
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = h result.impl = h
discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
discard cairo_surface_reference(result.impl) discard cairo_surface_reference(result.impl)
@ -1368,7 +1367,7 @@ proc getGroupTarget*(cr: Context): Surface =
let d = cairo_surface_get_user_data(h, NUDK) let d = cairo_surface_get_user_data(h, NUDK)
if d.isNil: if d.isNil:
#assert false # may this happen? #assert false # may this happen?
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = h result.impl = h
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
### discard cairo_surface_reference(result.impl) ### discard cairo_surface_reference(result.impl)
@ -1475,7 +1474,7 @@ proc cairo_surface_create_similar*(other: ptr Surface00; content: Content; width
ptr Surface00 {.importc, libcairo.} ptr Surface00 {.importc, libcairo.}
proc createSimilar*(other: Surface; content: Content; width, height: int): Surface = proc createSimilar*(other: Surface; content: Content; width, height: int): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_surface_create_similar(other.impl, content, width.cint, height.cint) result.impl = cairo_surface_create_similar(other.impl, content, width.cint, height.cint)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1483,7 +1482,7 @@ proc cairo_surface_create_similar_image*(other: ptr Surface00; format: Format; w
ptr Surface00 {.importc, libcairo.} ptr Surface00 {.importc, libcairo.}
# #
proc createSimilarImage*(other: Surface; format: Format; width, height: int): Surface = proc createSimilarImage*(other: Surface; format: Format; width, height: int): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_surface_create_similar_image(other.impl, format, width.cint, height.cint) result.impl = cairo_surface_create_similar_image(other.impl, format, width.cint, height.cint)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1496,14 +1495,14 @@ proc cairo_surface_map_to_image*(surface: ptr Surface00; extents: RectangleInt):
# #
proc mapToImage*(surface: Surface; extents: RectangleInt): Surface = proc mapToImage*(surface: Surface; extents: RectangleInt): Surface =
#new(result, destroy) # no idea currently #new(result, destroy) # no idea currently
new(result) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_surface_map_to_image(surface.impl, extents) result.impl = cairo_surface_map_to_image(surface.impl, extents)
proc cairo_surface_create_for_rectangle*(target: ptr Surface00; x, y, width, height: cdouble): proc cairo_surface_create_for_rectangle*(target: ptr Surface00; x, y, width, height: cdouble):
ptr Surface00 {.importc, libcairo.} ptr Surface00 {.importc, libcairo.}
# #
proc surfaceCreateForRectangle*(target: Surface; x, y, width, height: float): Surface = proc surfaceCreateForRectangle*(target: Surface; x, y, width, height: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_surface_create_for_rectangle(target.impl, x.cdouble, y.cdouble, width.cdouble, height.cdouble) result.impl = cairo_surface_create_for_rectangle(target.impl, x.cdouble, y.cdouble, width.cdouble, height.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1516,7 +1515,7 @@ proc cairo_surface_create_observer*(target: ptr Surface00;
mode: SurfaceObserverMode): ptr Surface00 {.importc, libcairo.} mode: SurfaceObserverMode): ptr Surface00 {.importc, libcairo.}
# #
proc createObserver*(target: Surface; mode: SurfaceObserverMode): Surface = proc createObserver*(target: Surface; mode: SurfaceObserverMode): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_surface_create_observer(target.impl, mode) result.impl = cairo_surface_create_observer(target.impl, mode)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1640,7 +1639,7 @@ proc supportsMimeType*(surface: Surface; mimeType: string): bool =
proc cairo_surface_get_font_options*(surface: ptr Surface00; options: ptr FontOptions00) {.importc, libcairo.} proc cairo_surface_get_font_options*(surface: ptr Surface00; options: ptr FontOptions00) {.importc, libcairo.}
proc getFontOptions*(surface: Surface; options: var FontOptions) = proc getFontOptions*(surface: Surface; options: var FontOptions) =
new(options, fontOptionsDestroy) new(options, gBoxedFreeCairoFontOptions)
options.impl = cairo_font_options_create() options.impl = cairo_font_options_create()
cairo_surface_get_font_options(surface.impl, options.impl) cairo_surface_get_font_options(surface.impl, options.impl)
@ -1717,7 +1716,7 @@ proc hasShowTextGlyphs*(surface: Surface): bool =
proc cairo_image_surface_create*(format: Format; width, height: cint): ptr Surface00 {.importc, libcairo.} proc cairo_image_surface_create*(format: Format; width, height: cint): ptr Surface00 {.importc, libcairo.}
# #
proc imageSurfaceCreate*(format: Format; width, height: int): Surface = proc imageSurfaceCreate*(format: Format; width, height: int): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_image_surface_create(format, width.cint, height.cint) result.impl = cairo_image_surface_create(format, width.cint, height.cint)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1756,7 +1755,7 @@ when CAIRO_HAS_PNG_FUNCTIONS:
proc cairo_image_surface_create_from_png*(filename: cstring): ptr Surface00 {.importc, libcairo.} proc cairo_image_surface_create_from_png*(filename: cstring): ptr Surface00 {.importc, libcairo.}
proc imageSurfaceCreateFromPng*(filename: string): Surface = proc imageSurfaceCreateFromPng*(filename: string): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_image_surface_create_from_png(filename) result.impl = cairo_image_surface_create_from_png(filename)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1764,14 +1763,14 @@ when CAIRO_HAS_PNG_FUNCTIONS:
closure: pointer): ptr Surface00 {.importc, libcairo.} closure: pointer): ptr Surface00 {.importc, libcairo.}
# #
proc imageSurfaceCreateFromPngStream*(readFunc: ReadFunc00; closure: pointer): Surface = proc imageSurfaceCreateFromPngStream*(readFunc: ReadFunc00; closure: pointer): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_image_surface_create_from_png_stream(readFunc, closure) result.impl = cairo_image_surface_create_from_png_stream(readFunc, closure)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_recording_surface_create*(content: Content; extents: Rectangle): ptr Surface00 {.importc, libcairo.} proc cairo_recording_surface_create*(content: Content; extents: Rectangle): ptr Surface00 {.importc, libcairo.}
# #
proc recordingSurfaceCreate*(content: Content; extents: Rectangle): Surface = proc recordingSurfaceCreate*(content: Content; extents: Rectangle): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_recording_surface_create(content, extents) result.impl = cairo_recording_surface_create(content, extents)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1817,7 +1816,7 @@ proc cairo_pattern_create_raster_source*(userData: pointer; content: Content; wi
ptr Pattern00 {.importc, libcairo.} ptr Pattern00 {.importc, libcairo.}
# #
proc patternCreateRasterSource*(userData: pointer; content: Content; width, height: int): Pattern = proc patternCreateRasterSource*(userData: pointer; content: Content; width, height: int): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_create_raster_source(userData, content, width.cint, height.cint) result.impl = cairo_pattern_create_raster_source(userData, content, width.cint, height.cint)
### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -1876,42 +1875,42 @@ proc rasterSourcePatternGetFinish*(pattern: Pattern): RasterSourceFinishFunc00 =
proc cairo_pattern_create_rgb*(red, green, blue: cdouble): ptr Pattern00 {.importc, libcairo.} proc cairo_pattern_create_rgb*(red, green, blue: cdouble): ptr Pattern00 {.importc, libcairo.}
# #
proc patternCreateRgb*(red, green, blue: float): Pattern = proc patternCreateRgb*(red, green, blue: float): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_create_rgb(red.cdouble, green.cdouble, blue.cdouble) result.impl = cairo_pattern_create_rgb(red.cdouble, green.cdouble, blue.cdouble)
### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_pattern_create_rgba*(red, green, blue, alpha: cdouble): ptr Pattern00 {.importc, libcairo.} proc cairo_pattern_create_rgba*(red, green, blue, alpha: cdouble): ptr Pattern00 {.importc, libcairo.}
# #
proc patternCreateRgba*(red, green, blue, alpha: float): Pattern = proc patternCreateRgba*(red, green, blue, alpha: float): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_create_rgba(red.cdouble, green.cdouble, blue.cdouble, alpha.cdouble) result.impl = cairo_pattern_create_rgba(red.cdouble, green.cdouble, blue.cdouble, alpha.cdouble)
### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_pattern_create_for_surface*(surface: ptr Surface00): ptr Pattern00 {.importc, libcairo.} proc cairo_pattern_create_for_surface*(surface: ptr Surface00): ptr Pattern00 {.importc, libcairo.}
# #
proc patternCreateForSurface*(surface: Surface): Pattern = proc patternCreateForSurface*(surface: Surface): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_create_for_surface(surface.impl) result.impl = cairo_pattern_create_for_surface(surface.impl)
### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_pattern_create_linear*(x0, y0, x1, y1: cdouble): ptr Pattern00 {.importc, libcairo.} proc cairo_pattern_create_linear*(x0, y0, x1, y1: cdouble): ptr Pattern00 {.importc, libcairo.}
# #
proc patternCreateLinear*(x0, y0, x1, y1: float): Pattern = proc patternCreateLinear*(x0, y0, x1, y1: float): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_create_linear(x0.cdouble, y0.cdouble, x1.cdouble, y1.cdouble) result.impl = cairo_pattern_create_linear(x0.cdouble, y0.cdouble, x1.cdouble, y1.cdouble)
### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_pattern_create_radial*(cx0, cy0, radius0, cx1, cy1, radius1: cdouble): ptr Pattern00 {.importc, libcairo.} proc cairo_pattern_create_radial*(cx0, cy0, radius0, cx1, cy1, radius1: cdouble): ptr Pattern00 {.importc, libcairo.}
# #
proc patternCreateRadial*(cx0, cy0, radius0, cx1, cy1, radius1: float): Pattern = proc patternCreateRadial*(cx0, cy0, radius0, cx1, cy1, radius1: float): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_create_radial(cx0.cdouble, cy0.cdouble, radius0.cdouble, cx1.cdouble, cy1.cdouble, radius1.cdouble) result.impl = cairo_pattern_create_radial(cx0.cdouble, cy0.cdouble, radius0.cdouble, cx1.cdouble, cy1.cdouble, radius1.cdouble)
### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_pattern_create_mesh*(): ptr Pattern00 {.importc, libcairo.} proc cairo_pattern_create_mesh*(): ptr Pattern00 {.importc, libcairo.}
# #
proc patternCreateMesh*(): Pattern = proc patternCreateMesh*(): Pattern =
new(result, patternDestroy) new(result, gBoxedFreeCairoPattern)
result.impl = cairo_pattern_create_mesh() result.impl = cairo_pattern_create_mesh()
### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_pattern_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2031,7 +2030,7 @@ proc getSurface*(pattern: Pattern; surface: var Surface): Status =
let d = cairo_surface_get_user_data(h, NUDK) let d = cairo_surface_get_user_data(h, NUDK)
if d.isNil: if d.isNil:
assert false # may this happen? assert false # may this happen?
new(surface, destroy) new(surface, gBoxedFreeCairoSurface)
surface.impl = h surface.impl = h
discard cairo_surface_set_user_data(surface.impl, NUDK, cast[pointer](surface), gcuref) discard cairo_surface_set_user_data(surface.impl, NUDK, cast[pointer](surface), gcuref)
discard cairo_surface_reference(surface.impl) discard cairo_surface_reference(surface.impl)
@ -2183,14 +2182,14 @@ proc destroy*(region: Region) =
proc cairo_region_create*(): ptr Region00 {.importc, libcairo.} proc cairo_region_create*(): ptr Region00 {.importc, libcairo.}
# #
proc regionCreate*(): Region = proc regionCreate*(): Region =
new(result, destroy) new(result, gBoxedFreeCairoRegion)
result.impl = cairo_region_create() result.impl = cairo_region_create()
### discard cairo_region_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_region_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
proc cairo_region_create_rectangle*(rectangle: RectangleInt): ptr Region00 {.importc, libcairo.} proc cairo_region_create_rectangle*(rectangle: RectangleInt): ptr Region00 {.importc, libcairo.}
# #
proc regionCreateRectangle*(rectangle: RectangleInt): Region = proc regionCreateRectangle*(rectangle: RectangleInt): Region =
new(result, destroy) new(result, gBoxedFreeCairoRegion)
result.impl = cairo_region_create_rectangle(rectangle) result.impl = cairo_region_create_rectangle(rectangle)
# TODO # TODO
@ -2200,7 +2199,7 @@ proc cairo_region_create_rectangles*(rects: RectangleInt; count: cint): ptr Regi
proc cairo_region_copy*(original: ptr Region00): ptr Region00 {.importc, libcairo.} proc cairo_region_copy*(original: ptr Region00): ptr Region00 {.importc, libcairo.}
# #
proc regionCopy*(original: Region): Region = proc regionCopy*(original: Region): Region =
new(result, destroy) new(result, gBoxedFreeCairoRegion)
result.impl = cairo_region_copy(original.impl) result.impl = cairo_region_copy(original.impl)
proc cairo_region_reference*(region: ptr Region00): ptr Region00 {.importc, libcairo.} proc cairo_region_reference*(region: ptr Region00): ptr Region00 {.importc, libcairo.}
@ -2308,7 +2307,7 @@ when CAIRO_HAS_PDF_SURFACE:
importc, libcairo.} importc, libcairo.}
proc pdfSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface = proc pdfSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_pdf_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble) result.impl = cairo_pdf_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2316,7 +2315,7 @@ when CAIRO_HAS_PDF_SURFACE:
closure: pointer; widthInPoints, heightInPoints: cdouble): ptr Surface00 {.importc, libcairo.} closure: pointer; widthInPoints, heightInPoints: cdouble): ptr Surface00 {.importc, libcairo.}
# #
proc pdfSurfaceCreateForStream*(writeFunc: WriteFunc00; closure: pointer; widthInPoints, heightInPoints: float): Surface = proc pdfSurfaceCreateForStream*(writeFunc: WriteFunc00; closure: pointer; widthInPoints, heightInPoints: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_pdf_surface_create_for_stream(writeFunc, closure, widthInPoints.cdouble, heightInPoints.cdouble) result.impl = cairo_pdf_surface_create_for_stream(writeFunc, closure, widthInPoints.cdouble, heightInPoints.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2389,7 +2388,7 @@ when CAIRO_HAS_PS_SURFACE:
importc, libcairo.} importc, libcairo.}
# #
proc psSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface = proc psSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_ps_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble) result.impl = cairo_ps_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2397,7 +2396,7 @@ when CAIRO_HAS_PS_SURFACE:
widthInPoints, heightInPoints: cdouble): ptr Surface00 {.importc, libcairo.} widthInPoints, heightInPoints: cdouble): ptr Surface00 {.importc, libcairo.}
# #
proc psSurfaceCreateForStream*(writeFunc: WriteFunc00; closure: pointer; widthInPoints, heightInPoints: float): Surface = proc psSurfaceCreateForStream*(writeFunc: WriteFunc00; closure: pointer; widthInPoints, heightInPoints: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_ps_surface_create_for_stream(writeFunc, closure, widthInPoints.cdouble, heightInPoints.cdouble) result.impl = cairo_ps_surface_create_for_stream(writeFunc, closure, widthInPoints.cdouble, heightInPoints.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2456,7 +2455,7 @@ when CAIRO_HAS_SVG_SURFACE:
importc, libcairo.} importc, libcairo.}
# #
proc svgSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface = proc svgSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_svg_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble) result.impl = cairo_svg_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2464,7 +2463,7 @@ when CAIRO_HAS_SVG_SURFACE:
closure: pointer; widthInPoints, heightInPoints: cdouble): ptr Surface00 {.importc, libcairo.} closure: pointer; widthInPoints, heightInPoints: cdouble): ptr Surface00 {.importc, libcairo.}
# #
proc svgSurfaceCreateForstream*(writeFunc: WriteFunc00; closure: pointer; widthInPoints, heightInPoints: float): Surface = proc svgSurfaceCreateForstream*(writeFunc: WriteFunc00; closure: pointer; widthInPoints, heightInPoints: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_svg_surface_create_for_stream(writeFunc, closure, widthInPoints.cdouble, heightInPoints.cdouble) result.impl = cairo_svg_surface_create_for_stream(writeFunc, closure, widthInPoints.cdouble, heightInPoints.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2503,7 +2502,7 @@ when CAIRO_HAS_XML_SURFACE:
importc, libcairo.} importc, libcairo.}
# #
proc xmlSurfaceCreate*(xml: Device; content: Content; width, height: float): Surface = proc xmlSurfaceCreate*(xml: Device; content: Content; width, height: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_xml_surface_create(xml.impl, content, width.cdouble, height.cdouble) result.impl = cairo_xml_surface_create(xml.impl, content, width.cdouble, height.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2550,7 +2549,7 @@ when CAIRO_HAS_SCRIPT_SURFACE:
importc, libcairo.} importc, libcairo.}
# #
proc scriptSurfaceCreate*(script: Device; content: Content; width, height: float): Surface = proc scriptSurfaceCreate*(script: Device; content: Content; width, height: float): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_script_surface_create(script.impl, content, width.cdouble, height.cdouble) result.impl = cairo_script_surface_create(script.impl, content, width.cdouble, height.cdouble)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2558,7 +2557,7 @@ when CAIRO_HAS_SCRIPT_SURFACE:
target: ptr Surface00): ptr Surface00 {.importc, libcairo.} target: ptr Surface00): ptr Surface00 {.importc, libcairo.}
# #
proc scriptSurfaceCreateForTarget*(script: Device; target: Surface): Surface = proc scriptSurfaceCreateForTarget*(script: Device; target: Surface): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_script_surface_create_for_target(script.impl, target.impl) result.impl = cairo_script_surface_create_for_target(script.impl, target.impl)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2572,7 +2571,7 @@ when CAIRO_HAS_SKIA_SURFACE:
proc cairo_skia_surface_create*(format: Format; width, height: cint): ptr Surface00 {.importc, libcairo.} proc cairo_skia_surface_create*(format: Format; width, height: cint): ptr Surface00 {.importc, libcairo.}
# #
proc skiaSurfaceCreate*(format: Format; width, height: int): Surface = proc skiaSurfaceCreate*(format: Format; width, height: int): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_skia_surface_create(format, width.cint, height.cint) result.impl = cairo_skia_surface_create(format, width.cint, height.cint)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2614,7 +2613,7 @@ when CAIRO_HAS_TEE_SURFACE:
proc cairo_tee_surface_create*(master: ptr Surface00): ptr Surface00 {.importc, libcairo.} proc cairo_tee_surface_create*(master: ptr Surface00): ptr Surface00 {.importc, libcairo.}
# #
proc teeSurfaceCreate*(master: Surface): Surface = proc teeSurfaceCreate*(master: Surface): Surface =
new(result, destroy) new(result, gBoxedFreeCairoSurface)
result.impl = cairo_tee_surface_create(master.impl) result.impl = cairo_tee_surface_create(master.impl)
### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref) ### discard cairo_surface_set_user_data(result.impl, NUDK, cast[pointer](result), gcuref)
@ -2634,5 +2633,5 @@ when CAIRO_HAS_TEE_SURFACE:
discard cairo_tee_surface_index(surface.impl, index.cuint) discard cairo_tee_surface_index(surface.impl, index.cuint)
return surface return surface
# 2605 lines # 2636 lines

View file

@ -154,6 +154,7 @@ proc $1$2 {.cdecl.} =
r1s.add(" var " & names[i] & "1 {.global.}: " & types[i] & "\n") r1s.add(" var " & names[i] & "1 {.global.}: " & types[i] & "\n")
r1s.add(" if " & names[i] & "1" & ".isNil:\n") r1s.add(" if " & names[i] & "1" & ".isNil:\n")
r1s.add(" new " & names[i] & "1" & "\n") r1s.add(" new " & names[i] & "1" & "\n")
r1s.add(" " & names[i] & "1.ignoreFinalizer = true" & "\n")
r1s.add(" " & names[i] & "1.impl = " & names[i] & "\n") r1s.add(" " & names[i] & "1.impl = " & names[i] & "\n")
if not ignoreArg.boolVal: if not ignoreArg.boolVal:
if getTypeInst(arg).typeKind == ntyRef: if getTypeInst(arg).typeKind == ntyRef:
@ -191,7 +192,8 @@ proc $1(self: $2; p: proc $3; a: $4): culong {.discardable.} =
else: else:
var ar: ref $4 var ar: ref $4
new(ar) new(ar)
deepCopy(ar[], a) #deepCopy(ar[], a)
ar[] = a
GC_ref(ar) GC_ref(ar)
# sc$5(self, $6, cast[pointer](ar[])) # sc$5(self, $6, cast[pointer](ar[]))
sc$5(self, $6, cast[pointer](ar)) sc$5(self, $6, cast[pointer](ar))
@ -218,7 +220,8 @@ $1($7, $8, $9)
proc $1(self: $2; p: proc $3; a: $4): culong {.discardable.} = proc $1(self: $2; p: proc $3; a: $4): culong {.discardable.} =
var ar: ref $4 var ar: ref $4
new(ar) new(ar)
deepCopy(ar[], a) #deepCopy(ar[], a)
ar[] = a
GC_ref(ar) GC_ref(ar)
# sc$5(self, $6, cast[pointer](ar[])) # sc$5(self, $6, cast[pointer](ar[]))
sc$5(self, $6, cast[pointer](ar), $10) sc$5(self, $6, cast[pointer](ar), $10)
@ -256,7 +259,7 @@ proc $1(p: pointer): gboolean {.cdecl.} =
let a = cast[$3](p) let a = cast[$3](p)
result = $2(a).gboolean result = $2(a).gboolean
#when (a is ref object) or (a is seq): #when (a is ref object) or (a is seq):
GC_unref(a) #GC_unref(a)
""" % [$procNameCdecl, $p, ats] """ % [$procNameCdecl, $p, ats]
let r2s =""" let r2s ="""
@ -267,7 +270,8 @@ proc $1(a: $2): culong {.discardable.} =
else: else:
var ar: ref $2 var ar: ref $2
new(ar) new(ar)
deepCopy(ar[], a) #deepCopy(ar[], a)
ar[] = a
GC_ref(ar) GC_ref(ar)
return g_timeout_add_full(PRIORITY_DEFAULT, $3, $4, cast[pointer](ar), nil) return g_timeout_add_full(PRIORITY_DEFAULT, $3, $4, cast[pointer](ar), nil)
$1($5) $1($5)
@ -285,7 +289,7 @@ proc $1(p: pointer): gboolean {.cdecl.} =
let a = cast[$3](p) let a = cast[$3](p)
result = $2(a).gboolean result = $2(a).gboolean
#when (a is ref object) or (a is seq): #when (a is ref object) or (a is seq):
GC_unref(a) #GC_unref(a)
""" % [$procNameCdecl, $p, ats] """ % [$procNameCdecl, $p, ats]
let r2s =""" let r2s ="""
@ -296,7 +300,8 @@ proc $1(a: $2): culong {.discardable.} =
else: else:
var ar: ref $2 var ar: ref $2
new(ar) new(ar)
deepCopy(ar[], a) #deepCopy(ar[], a)
ar[] = a
GC_ref(ar) GC_ref(ar)
return g_idle_add_full(PRIORITY_DEFAULT_IDLE, $3, cast[pointer](ar[]), nil) return g_idle_add_full(PRIORITY_DEFAULT_IDLE, $3, cast[pointer](ar[]), nil)
$1($4) $1($4)
@ -413,7 +418,8 @@ $1(column, renderer, $6)
proc $1(column: TreeViewColumn; renderer: CellRenderer; pdata: $2) = proc $1(column: TreeViewColumn; renderer: CellRenderer; pdata: $2) =
var ar: ref $2 var ar: ref $2
new(ar) new(ar)
deepCopy(ar[], pdata) #deepCopy(ar[], pdata)
ar[] = pdata
GC_ref(ar) GC_ref(ar)
setCellDataFunc($3, $4, $5, cast[pointer](ar), $7) setCellDataFunc($3, $4, $5, cast[pointer](ar), $7)
$1(column, renderer, $6) $1(column, renderer, $6)

View file

@ -1,5 +1,6 @@
# High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language # High level gobject-introspection based GTK3/GTK4 bindings for the Nim programming language
# v 0.6.1 2019-DEC-05 # nimpretty --maxLineLen:130 gen.nim
# v 0.7.0 2020-JAN-27
# (c) S. Salewski 2018 # (c) S. Salewski 2018
# https://wiki.gnome.org/Projects/GObjectIntrospection # https://wiki.gnome.org/Projects/GObjectIntrospection
@ -47,6 +48,12 @@ template isCallbackInfo(info: untyped): untyped =
template isFunctionInfo(info: untyped): untyped = template isFunctionInfo(info: untyped): untyped =
gBaseInfoGetType(info) == GIInfoType.Function gBaseInfoGetType(info) == GIInfoType.Function
template isTypeInfo(info: untyped): untyped =
gBaseInfoGetType(info) == GIInfoType.Type
#define GI_IS_TYPE_INFO(info) \
# (g_base_info_get_type((GIBaseInfo*)info) == GI_INFO_TYPE_TYPE)
const const
WriteFields = false # starting with v0.5.3 we do not write the objectfields any more! WriteFields = false # starting with v0.5.3 we do not write the objectfields any more!
libprag = "libprag" libprag = "libprag"
@ -411,6 +418,29 @@ proc genRec(t: GITypeInfo; genProxy = false; fullQualified: bool = false): (stri
result[0] = "ptr " & result[0] result[0] = "ptr " & result[0]
result[0] = mangleType(result[0]) & rawmark result[0] = mangleType(result[0]) & rawmark
proc modPrefix(t: GITypeInfo; sym: string; full = true): string =
if sym == "gtk_renderer_cell_accessible_new":
return fixedModName("gtk") & "."
if sym == "gtk_mount_operation_new":
return fixedModName("gtk") & "."
if sym == "gtk_notebook_page_accessible_new":
return fixedModName("gtk") & "."
if sym in ["gtk_source_view_new", "gtk_source_view_new_with_buffer", "gtk_source_map_new",
"gtk_source_style_scheme_chooser_widget_new", "gtk_source_style_scheme_chooser_button_new",
"gtk_source_tag_new"]:
return fixedModName("gtksource") & "."
if full:
result = fixedModName(moduleNamespace) & "."
let tag = gTypeInfoGetTag(t)
if tag == GITypeTag.INTERFACE:
let iface = gTypeInfoGetInterface(t)
if gBaseInfoGetType(iface) == GIInfoType.CALLBACK:
discard
else:
var ns = ($gBaseInfoGetNamespace(iface)).toLowerAscii
if ns != moduleNamespace:
result = fixedModName(ns) & "."
proc isProxyCandidate(t: GITypeInfo): bool = proc isProxyCandidate(t: GITypeInfo): bool =
let tag = gTypeInfoGetTag(t) let tag = gTypeInfoGetTag(t)
if tag == GITypeTag.INTERFACE: if tag == GITypeTag.INTERFACE:
@ -422,6 +452,8 @@ proc isProxyCandidate(t: GITypeInfo): bool =
proc needProxyProc(info: GICallableInfo): bool = proc needProxyProc(info: GICallableInfo): bool =
if gCallableInfoIsMethod(info): if gCallableInfoIsMethod(info):
return true return true
if manglename(gBaseInfoGetName(info)) in ["free", "unref"]: # we need this for finalizerFree() currently
return true
let m = gCallableInfoGetNArgs(info) - 1 let m = gCallableInfoGetNArgs(info) - 1
for j in 0.cint .. m: for j in 0.cint .. m:
let arg = gCallableInfoGetArg(info, j) let arg = gCallableInfoGetArg(info, j)
@ -575,7 +607,8 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
if not genProxy and ct2nt.contains(str) and (str != "cstring" or gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT}): if not genProxy and ct2nt.contains(str) and (str != "cstring" or gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT}):
replist.add($name, $str) replist.add($name, $str)
if genProxy and ct2nt.contains(str): if genProxy and ct2nt.contains(str):
if gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT} and (not gArgInfoIsCallerAllocates(arg) or (str in ["int32", "uint32", "cstringArray", "cstring"])): if gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT} and (not gArgInfoIsCallerAllocates(arg) or (str in ["int32",
"uint32", "cstringArray", "cstring"])):
replist.add($name, $str) replist.add($name, $str)
if gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT} or str != "cstring": # new in 0.4.11 -- allow passing cstring if not a var if gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT} or str != "cstring": # new in 0.4.11 -- allow passing cstring if not a var
str = ct2nt[str] str = ct2nt[str]
@ -658,9 +691,9 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
resul = makeResul(resus, self, resusres).isplit(sym.len + "proc".len) resul = makeResul(resus, self, resusres).isplit(sym.len + "proc".len)
return (resul, arglist, replist, arrLex, blex) return (resul, arglist, replist, arrLex, blex)
proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
template gobjectTemp(): untyped = template gobjectTemp(ignoreFinalizer: bool): untyped =
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, EVERYTHING}) # both occur assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, EVERYTHING}) # both occur
methodBuffer.writeLine(" let gobj = " & sym & arglist) methodBuffer.writeLine(" let gobj = " & sym & arglist)
methodBuffer.writeLine(" if g_object_get_qdata(gobj, Quark) != nil:") methodBuffer.writeLine(" if g_object_get_qdata(gobj, Quark) != nil:")
@ -670,7 +703,10 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
if sym == "g_object_ref" or sym == "g_object_ref_sink": if sym == "g_object_ref" or sym == "g_object_ref_sink":
methodBuffer.writeLine(" assert(false)") methodBuffer.writeLine(" assert(false)")
else: else:
methodBuffer.writeLine(" new(result, finalizeGObject)") if ignoreFinalizer: # with ARC we have no finalizer support for user defined subclasses, so we have to leak mem!
methodBuffer.writeLine(" new(result)")
else:
methodBuffer.writeLine(" new(result, $1finalizeGObject)" % [mprefix])
methodBuffer.writeLine(" result.impl = gobj") methodBuffer.writeLine(" result.impl = gobj")
methodBuffer.writeLine(" GC_ref(result)") methodBuffer.writeLine(" GC_ref(result)")
methodBuffer.writeLine(" discard g_object_ref_sink(result.impl)") methodBuffer.writeLine(" discard g_object_ref_sink(result.impl)")
@ -680,37 +716,39 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))") methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))")
# prefer gboxed_free() but fall back for GVariant # prefer gboxed_free() but fall back for GVariant
template findFreeProc(info: GIBaseInfo): untyped = template findFreeProc(info: GIBaseInfo; noWarning: bool): untyped =
if gBaseInfoGetType(info) == GIInfoType.UNION: if gBaseInfoGetType(info) == GIInfoType.UNION or gBaseInfoGetType(info) == GIInfoType.STRUCT:
freeMe = gUnionInfoFindMethod(info, "free") if gBaseInfoGetType(info) == GIInfoType.UNION:
if freeMe.isNil: freeMe = gUnionInfoFindMethod(info, "free")
freeMe = gUnionInfoFindMethod(info, "unref") if freeMe.isNil:
else: freeMe = gUnionInfoFindMethod(info, "unref")
assert gBaseInfoGetType(info) == GIInfoType.STRUCT
freeMe = gStructInfoFindMethod(info, "free")
if freeMe.isNil:
freeMe = gStructInfoFindMethod(info, "unref")
if freeMe == nil:
if fixedDestroyNames.contains(sym):
freeMeName = fixedDestroyNames[sym]
else:
assert (not fixedDestroyNames.contains(sym))
freeMeName = $gBaseInfoGetName(freeMe)
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) == G_TYPE_BOXED:
boxedFreeMeName = "gBoxedFree" & $gRegisteredTypeInfoGetTypeName(info)
else:
boxedFreeMeName = ""
if gBaseInfoGetName(info) == "VariantType": # there is no g_variant_get_type()
boxedFreeMeName = ""
if boxedFreeMeName == "":
if freeMeName == "":
echo "Caution: No free/unref found for ", ' ', " (", sym, ')'
else: else:
if gBaseInfoGetName(info) notin ["Variant", "VariantType"]: # seems for glib.GVariant we have to guess -- or maybe just know assert gBaseInfoGetType(info) == GIInfoType.STRUCT
echo "Caution: Do guess free/unref for ", ' ', " (", sym, ')' freeMe = gStructInfoFindMethod(info, "free")
if boxedFreeMeName == "gBoxedFreeGVariantType": # this does not work if freeMe.isNil:
assert false freeMe = gStructInfoFindMethod(info, "unref")
if freeMe == nil:
if fixedDestroyNames.contains(sym):
freeMeName = fixedDestroyNames[sym]
else:
assert (not fixedDestroyNames.contains(sym))
freeMeName = "finalizer" & $gBaseInfoGetName(freeMe)
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) == G_TYPE_BOXED:
boxedFreeMeName = "gBoxedFree" & $gRegisteredTypeInfoGetTypeName(info)
else:
boxedFreeMeName = ""
if gBaseInfoGetName(info) == "VariantType": # there is no g_variant_get_type()
boxedFreeMeName = ""
if boxedFreeMeName == "" and not noWarning:
if freeMeName == "":
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
echo "Caution: Do guess free/unref for ", ' ', " (", sym, ')'
if boxedFreeMeName == "gBoxedFreeGVariantType": # this does not work
assert false
# assert(info != nil) # why can it be nil?
assert(isCallableInfo(mInfo)) assert(isCallableInfo(mInfo))
assert(isFunctionInfo(mInfo)) assert(isFunctionInfo(mInfo))
var plist, arglist, arrLex, blex: string var plist, arglist, arrLex, blex: string
@ -765,7 +803,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
if sym == "gtk_selection_data_get_targets": return if sym == "gtk_selection_data_get_targets": return
if sym == "g_strfreev": return if sym == "g_strfreev": return
if sym == "g_signal_emitv": return if sym == "g_signal_emitv": return
#if sym == "g_iconv": return # old fixed gobject-introspection bug
try: try:
(plist, arglist, replist, arrLex) = genPars(mInfo, false, info) (plist, arglist, replist, arrLex) = genPars(mInfo, false, info)
processedFunctions.incl(sym) processedFunctions.incl(sym)
@ -775,7 +813,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
var asym = manglename(gBaseInfoGetName(mInfo)) var asym = manglename(gBaseInfoGetName(mInfo))
if asym == "errorQuark" or asym == "quark": return if asym == "errorQuark" or asym == "quark": return
if (moduleNameSpace == "gst" and asym in ["appendAndTakeValue", "appendValue", "getSize", "getValue", "prependValue"]) or if (moduleNameSpace == "gst" and asym in ["appendAndTakeValue", "appendValue", "getSize", "getValue", "prependValue"]) or
asym in ["get", "getDefault", "from", "fromString", "getInfo", "listFree", "register", "find", "getList"] : asym in ["get", "getDefault", "from", "fromString", "getInfo", "listFree", "register", "find", "getList"]:
# or # maybe we should relax this later a bit for the case that first parameter type == gBaseInfoGetName(info) # or # maybe we should relax this later a bit for the case that first parameter type == gBaseInfoGetName(info)
asym.add($manglename(gBaseInfoGetName(info))) asym.add($manglename(gBaseInfoGetName(info)))
if sym == "gtk_buildable_get_name": asym = "buildableGetName" # conflict with gtk_widget_get_name() if sym == "gtk_buildable_get_name": asym = "buildableGetName" # conflict with gtk_widget_get_name()
@ -783,6 +821,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
if keywords.contains(asym) or nims.contains(asym): if keywords.contains(asym) or nims.contains(asym):
asym.add('P') asym.add('P')
var ret2 = gCallableInfoGetReturnType(minfo) var ret2 = gCallableInfoGetReturnType(minfo)
let mprefix = modPrefix(ret2, sym)
if moduleNameSpace == "graphene" and gCallableInfoGetNArgs(minfo) == 0 and not gCallableInfoIsMethod(minfo): if moduleNameSpace == "graphene" and gCallableInfoGetNArgs(minfo) == 0 and not gCallableInfoIsMethod(minfo):
asym.add($manglename(gBaseInfoGetName(info))) asym.add($manglename(gBaseInfoGetName(info)))
for run in 0 .. 1: for run in 0 .. 1:
@ -807,8 +846,10 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
let b7 = needProxyProc(mInfo) or isString(ret2) or replist.len > 0 or ct2nt.contains(genRec(ret2)[0]) let b7 = needProxyProc(mInfo) or isString(ret2) or replist.len > 0 or ct2nt.contains(genRec(ret2)[0])
# export only low level symbols that are needed internally -- maybe we should export only a private name for them # export only low level symbols that are needed internally -- maybe we should export only a private name for them
if run == 0: if run == 0:
if sym in ["g_quark_from_static_string", "g_error_free", "g_object_get_qdata", "g_object_ref_sink", "g_object_unref", "g_timeout_add_full", if sym in ["g_quark_from_static_string", "g_error_free", "g_object_get_qdata", "g_object_ref_sink", "g_object_unref",
"g_type_from_name", "g_type_check_instance_is_a", "g_idle_add_full", "g_quark_try_string", "vte_regex_unref", "gtk_builder_get_object"]: "g_timeout_add_full",
"g_type_from_name", "g_type_check_instance_is_a", "g_idle_add_full", "g_quark_try_string", "vte_regex_unref",
"gtk_builder_get_object"]:
methodBuffer.write("\nproc " & sym & EM & plist) methodBuffer.write("\nproc " & sym & EM & plist)
methodBuffer.writeLine(" {.\n importc, ", libprag, ".}") methodBuffer.writeLine(" {.\n importc, ", libprag, ".}")
if sym.startsWith("vte_regex_unref"): # this function is special, as it returns the object if sym.startsWith("vte_regex_unref"): # this function is special, as it returns the object
@ -818,6 +859,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
elif b7: elif b7:
methodBuffer.write("\nproc " & sym & plist) methodBuffer.write("\nproc " & sym & plist)
methodBuffer.writeLine(" {.\n importc, ", libprag, ".}") methodBuffer.writeLine(" {.\n importc, ", libprag, ".}")
if sym in ["g_object_ref_sink", "g_object_ref"]:
return
if b7: if b7:
var isGObject = false var isGObject = false
let tag = gTypeInfoGetTag(ret2) let tag = gTypeInfoGetTag(ret2)
@ -864,11 +907,12 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
if isGObject: if isGObject:
# CAUTION: some procs are advertised as constructor but do not construct new objects, # CAUTION: some procs are advertised as constructor but do not construct new objects,
# they just return existing ones as gdk_cursor_new_from_name() # they just return existing ones as gdk_cursor_new_from_name()
gobjectTemp() gobjectTemp(i > 0)
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.CONTAINER: elif gCallableInfoGetCallerOwns(minfo) == GITransfer.CONTAINER:
assert false assert false
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING: elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING or #: ###################
if sym == "g_closure_new_simple": gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # and gBaseInfoGetName(info) == "Variant":
if false: #sym == "g_closure_new_simple":
let nMethods = gStructInfoGetNMethods(info) let nMethods = gStructInfoGetNMethods(info)
for j in 0.cint ..< nMethods: for j in 0.cint ..< nMethods:
echo "yes there is unref method! ", $gBaseInfoGetName(gStructInfoGetMethod(info, j)) echo "yes there is unref method! ", $gBaseInfoGetName(gStructInfoGetMethod(info, j))
@ -877,21 +921,30 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
var freeMe: GIFunctionInfo var freeMe: GIFunctionInfo
var freeMeName: string var freeMeName: string
var boxedFreeMeName: string var boxedFreeMeName: string
findFreeProc(info) findFreeProc(info, gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING)
#if sym == "g_closure_new_simple" or sym == "g_closure_new_object": #if sym == "g_closure_new_simple" or sym == "g_closure_new_object":
# freeMeName = "unref" # TODO GI bug? # freeMeName = "unref" # TODO GI bug?
#assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING}) #assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
if boxedFreeMeName != "": if 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(" new(result, $1)" % boxedFreeMeName) methodBuffer.writeLine(" new(result, $1)" % boxedFreeMeName)
elif freeMeName == "": elif freeMeName == "":
methodBuffer.writeLine(" new(result)") methodBuffer.writeLine(" new(result)")
else: else:
methodBuffer.writeLine(" new(result, $1)" % freeMeName) methodBuffer.writeLine(" new(result, $1)" % freeMeName)
methodBuffer.writeLine(" result.impl = " & sym & arglist) methodBuffer.writeLine(" result.impl = " & sym & arglist)
#if gBaseInfoGetName(info) == "Variant":
# methodBuffer.writeLine(" discard g_variant_ref_sink(result.impl)")
else: else:
assert gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING echo "skipped ", sym
methodBuffer.writeLine(" new(result)") #assert false
methodBuffer.writeLine(" result.impl = " & sym & arglist) #assert gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING
#methodBuffer.writeLine(" new(result)")
#methodBuffer.writeLine(" result.ignoreFinalizer = true")
#methodBuffer.writeLine(" result.impl = " & sym & arglist)
if i == 0 and gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING:
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
for k, v in replist: for k, v in replist:
methodBuffer.writeLine(" $1 = $2($3_00)" % [k, ct3nt(v), k.strip(chars = {'`'})]) methodBuffer.writeLine(" $1 = $2($3_00)" % [k, ct3nt(v), k.strip(chars = {'`'})])
elif isProxyCandidate(ret2): # BLOCKMARK8 elif isProxyCandidate(ret2): # BLOCKMARK8
@ -905,33 +958,38 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
for k, v in replist: for k, v in replist:
methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v, k]) methodBuffer.writeLine(" var $1_00 = $2($3)" % [k.strip(chars = {'`'}), v, k])
if isGObject: if isGObject:
gobjectTemp() gobjectTemp(false)
elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING: elif gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING or
gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING: # for ARC we have always to use the same finalizer!
let tag = gTypeInfoGetTag(ret2) let tag = gTypeInfoGetTag(ret2)
assert tag == GITypeTag.INTERFACE assert tag == GITypeTag.INTERFACE
var iface = gTypeInfoGetInterface(ret2) var iface = gTypeInfoGetInterface(ret2)
if gBaseInfoGetType(iface) == GIInfoType.INTERFACE: if gBaseInfoGetType(iface) == GIInfoType.INTERFACE:
iface = gInterfaceInfoGetIfaceStruct(iface) iface = gInterfaceInfoGetIfaceStruct(iface)
methodBuffer.writeLine(" new(result, gobject.genericGObjectUnref)") methodBuffer.writeLine(" new(result, $1genericGObjectUnref)" % [mprefix])
methodBuffer.writeLine(" result.impl = " & sym & arglist) methodBuffer.writeLine(" result.impl = " & sym & arglist)
elif gBaseInfoGetType(iface) == GIInfoType.OBJECT: elif gBaseInfoGetType(iface) == GIInfoType.OBJECT:
echo "XXXXXXXXXXXXXXXXX what shall we do? for ", sym #echo "XXXXXXXXXXXXXXXXX what shall we do? for ", sym
methodBuffer.writeLine(" new(result, $1genericGObjectUnref)" % [mprefix])
methodBuffer.writeLine(" result.impl = " & sym & arglist)
else: else:
assert(gBaseInfoGetType(iface) in {GIInfoType.STRUCT, GIInfoType.UNION}) assert(gBaseInfoGetType(iface) in {GIInfoType.STRUCT, GIInfoType.UNION})
var freeMeName: string var freeMeName: string
var freeMe: GIFunctionInfo var freeMe: GIFunctionInfo
var boxedFreeMeName: string var boxedFreeMeName: string
findFreeProc(iface) findFreeProc(iface, gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING)
if boxedFreeMeName != "": if boxedFreeMeName != "":
methodBuffer.writeLine(" new(result, $1)" % boxedFreeMeName) methodBuffer.writeLine(" new(result, $1)" % boxedFreeMeName)
elif freeMeName == "": elif freeMeName == "":
# assert false # TODO we have to fix this case manually # assert false # TODO we have to fix this case manually
echo "Caution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')' #echo "xCaution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')'
methodBuffer.writeLine(" new(result)") methodBuffer.writeLine(" new(result)")
else: else:
methodBuffer.writeLine(" new(result, $1)" % freeMeName) methodBuffer.writeLine(" new(result, $1)" % freeMeName)
methodBuffer.writeLine(" result.impl = " & sym & arglist) methodBuffer.writeLine(" result.impl = " & sym & arglist)
else: if gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING:
methodBuffer.writeLine(" result.ignoreFinalizer = true") # as we have always to attach one with ARC.
elif false: #else:
assert gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING assert gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING
methodBuffer.writeLine(" new(result)") methodBuffer.writeLine(" new(result)")
methodBuffer.writeLine(" result.impl = " & sym & arglist) methodBuffer.writeLine(" result.impl = " & sym & arglist)
@ -955,21 +1013,27 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
let tag = gTypeInfoGetTag(t) let tag = gTypeInfoGetTag(t)
assert(tag == GITypeTag.INTERFACE) assert(tag == GITypeTag.INTERFACE)
assert gArgInfoGetOwnershipTransfer(arg) != GITransfer.CONTAINER assert gArgInfoGetOwnershipTransfer(arg) != GITransfer.CONTAINER
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING: if gArgInfoGetOwnershipTransfer(arg) == GITransfer.EVERYTHING or
gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING: # pass always the same finalizer for ARC
let iface = gTypeInfoGetInterface(t) let iface = gTypeInfoGetInterface(t)
if gBaseInfoGetType(iface) == GIInfoType.OBJECT: if gBaseInfoGetType(iface) == GIInfoType.OBJECT:
freeMeName = "finalizeGObject" # TODO: investigate, we may need the full toggleRef stuff! let ttt = gArgInfoGetType(arg)
freeMeName = modPrefix(ttt, sym) & "finalizeGObject" # TODO: investigate, we may need the full toggleRef stuff!
else: else:
let info = iface let info = iface
var freeMe: GIFunctionInfo var freeMe: GIFunctionInfo
findFreeProc(info) findFreeProc(info, gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING)
let h2 = mangleName(gBaseInfoGetName(arg)) let h2 = mangleName(gBaseInfoGetName(arg))
if boxedFreeMeName != "": if boxedFreeMeName != "":
methodBuffer.writeLine(" new(" & h2 & ", " & boxedFreeMeName & ")") methodBuffer.writeLine(" new(" & h2 & ", " & boxedFreeMeName & ")")
elif freeMeName == "": elif freeMeName == "":
methodBuffer.writeLine(" new(" & h2 & ")") methodBuffer.writeLine(" new(" & h2 & ")")
#############methodBuffer.writeLine(" $1.ignoreFinalizer = true" % [h2])
else: else:
methodBuffer.writeLine(" new(" & h2 & ", " & freeMeName & ")") methodBuffer.writeLine(" new(" & h2 & ", " & freeMeName & ")")
#if gCallableInfoGetCallerOwns(minfo) == GITransfer.NOTHING:
if gArgInfoGetOwnershipTransfer(arg) == GITransfer.NOTHING:
methodBuffer.writeLine(" " & h2 & ".ignoreFinalizer = true") # as we have always to attach one with ARC.
if gCallableInfoCanThrowGerror(minfo): if gCallableInfoCanThrowGerror(minfo):
methodBuffer.writeLine(" var gerror: ptr glib.Error") methodBuffer.writeLine(" var gerror: ptr glib.Error")
arglist.insert(", addr gerror", arglist.high) arglist.insert(", addr gerror", arglist.high)
@ -1037,12 +1101,20 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
if asym != "errorQuark" and asym != "getPlugin" and asym != "quark": if asym != "errorQuark" and asym != "getPlugin" and asym != "quark":
methodBuffer.write("\nproc " & asym & EM & plist) methodBuffer.write("\nproc " & asym & EM & plist)
methodBuffer.writeLine(" {.\n importc: \"", sym, "\", ", libprag, ".}") 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"):
methodBuffer.writeLine("\nproc finalizer" & asym & EM & "(self: $1) =" % [$gBaseInfoGetName(info)])
methodBuffer.writeLine(" if not self.ignoreFinalizer:")
methodBuffer.writeLine(" " & sym & "(self.impl)")
if sym == "gtk_window_set_default_size": if sym == "gtk_window_set_default_size":
methodBuffer.writeLine("\nproc `defaultSize=`*(self: Window; dim: tuple[width: int; height: int]) =") 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]))") methodBuffer.writeLine(" gtk_window_set_default_size(cast[ptr Window00](self.impl), int32(dim[0]), int32(dim[1]))")
if sym == "g_object_unref": if sym == "g_object_unref":
methodBuffer.writeLine("\nproc genericGObjectUnref*[T](self: T) =") methodBuffer.writeLine("\nproc genericGObjectUnref*[T](self: ref T) =")
methodBuffer.writeLine(" g_object_unref(cast[ptr Object00](self.impl))") methodBuffer.writeLine(" if not self.ignoreFinalizer:")
methodBuffer.writeLine(" g_object_unref(cast[ptr Object00](self.impl))")
except UndefEx: except UndefEx:
processedFunctions.excl(sym) processedFunctions.excl(sym)
delayedMethods.add((info, minfo)) delayedMethods.add((info, minfo))
@ -1055,15 +1127,17 @@ template genBoxedFree =
#assert(g_type_fundamental(g_registered_type_info_get_g_type(info)) == G_TYPE_BOXED) #assert(g_type_fundamental(g_registered_type_info_get_g_type(info)) == G_TYPE_BOXED)
if gTypeFundamental(gRegisteredTypeInfoGetGType(info)) != G_TYPE_BOXED: if gTypeFundamental(gRegisteredTypeInfoGetGType(info)) != G_TYPE_BOXED:
if gBaseInfoGetName(info) != "Variant": if gBaseInfoGetName(info) != "Variant":
echo moduleNamespace, gBaseInfoGetName(info) #echo moduleNamespace, gBaseInfoGetName(info)
assert false assert false
output.writeLine("\nproc gBoxedFree" & $gRegisteredTypeInfoGetTypeName(info) & "*(self: " & mangleName(gBaseInfoGetName(info)) & ") =") output.writeLine("\nproc gBoxedFree" & $gRegisteredTypeInfoGetTypeName(info) & "*(self: " & mangleName(gBaseInfoGetName(
info)) & ") =")
if moduleNameSpace == "cairo": # we may manually free cairo objects! if moduleNameSpace == "cairo": # we may manually free cairo objects!
output.writeLine(" if self.impl != nil:") output.writeLine(" if not self.ignoreFinalizer and self.impl != nil:")
output.writeLine(" boxedFree(", getTypeProc, "(), ", "cast[ptr " & mangleName(gBaseInfoGetName(info)) & "00](self.impl))") output.writeLine(" boxedFree(", getTypeProc, "(), ", "cast[ptr " & mangleName(gBaseInfoGetName(info)) & "00](self.impl))")
output.writeLine(" self.impl = nil") output.writeLine(" self.impl = nil")
else: else:
output.writeLine(" boxedFree(", getTypeProc, "(), ", "cast[ptr " & mangleName(gBaseInfoGetName(info)) & "00](self.impl))") output.writeLine(" if not self.ignoreFinalizer:")
output.writeLine(" boxedFree(", getTypeProc, "(), ", "cast[ptr " & mangleName(gBaseInfoGetName(info)) & "00](self.impl))")
proc writeUnion(info: GIUnionInfo) = proc writeUnion(info: GIUnionInfo) =
if not suppressType: if not suppressType:
@ -1081,6 +1155,7 @@ proc writeUnion(info: GIUnionInfo) =
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))): if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object") output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object")
output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00") output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00")
output.writeLine(" ignoreFinalizer*: bool")
var getTypeProc: string var getTypeProc: string
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE: if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
@ -1171,7 +1246,8 @@ proc writeStruct(info: GIStructInfo) =
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " {.pure, byRef.} = object") output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " {.pure, byRef.} = object")
else: else:
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object") output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM & " {.pure.} = object")
if WriteFields or callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))) or if WriteFields or callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(
info))) or
mangleName(gBaseInfoGetName(info)) == "TargetEntry": mangleName(gBaseInfoGetName(info)) == "TargetEntry":
for j in 0.cint ..< info.gStructInfoGetNFields(): for j in 0.cint ..< info.gStructInfoGetNFields():
let field = info.gStructInfoGetField(j) let field = info.gStructInfoGetField(j)
@ -1186,12 +1262,15 @@ proc writeStruct(info: GIStructInfo) =
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))): if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object") output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object")
output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00") output.writeLine(" impl*: ptr " & mangleName(gBaseInfoGetName(info)) & "00")
output.writeLine(" ignoreFinalizer*: bool")
var getTypeProc: string var getTypeProc: string
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE: if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
getTypeProc = $gRegisteredTypeInfoGetTypeInit(info) getTypeProc = $gRegisteredTypeInfoGetTypeInit(info)
if getTypeProc notin ["intern", "g_gstring_get_type"]: if getTypeProc notin ["intern", "g_gstring_get_type"]:
output.write("\nproc " & getTypeProc & "*(): GType ") output.write("\nproc " & getTypeProc & "*(): GType ")
output.writeLine("{.importc, " & libprag & ".}") output.writeLine("{.importc, " & libprag & ".}")
#if gBaseInfoGetName(info) == "Variant":
# output.writeLine("\nproc g_variant_ref_sink(self: ptr Variant00): ptr Variant00 {.importc, libprag.}\n")
genBoxedFree() genBoxedFree()
var mseq: seq[GIFunctionInfo] var mseq: seq[GIFunctionInfo]
@ -1226,12 +1305,16 @@ template writeSignal() =
memo = memo.replace("\"", "\\\"") memo = memo.replace("\"", "\\\"")
if moduleNamespace == "gtk" or moduleNamespace == "gdk" or moduleNamespace == "gdkX11": if moduleNamespace == "gtk" or moduleNamespace == "gdk" or moduleNamespace == "gdkX11":
if ISGTK3: if ISGTK3:
supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep & memo & "\",") supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) &
RecSep & memo & "\",")
else: else:
supmod4.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep & memo & "\",") supmod4.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) &
RecSep & memo & "\",")
else: else:
supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep & memo & "\",") supmod3.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep &
supmod4.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep & memo & "\",") memo & "\",")
supmod4.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & RecSep & $gBaseInfoGetName(info) & RecSep &
memo & "\",")
if gCallableInfoGetNArgs(signalInfo) > 0: if gCallableInfoGetNArgs(signalInfo) > 0:
h = h.replace(")", "; xdata: pointer)") h = h.replace(")", "; xdata: pointer)")
else: else:
@ -1435,6 +1518,7 @@ proc writeObj(info: GIObjectInfo) =
output.write(" impl*: ptr ") output.write(" impl*: ptr ")
output.write(gBaseInfoGetName(info)) output.write(gBaseInfoGetName(info))
output.writeLine("00") output.writeLine("00")
output.writeLine(" ignoreFinalizer*: bool")
#elif gBaseInfoGetName(info) == "ParamSpec": #elif gBaseInfoGetName(info) == "ParamSpec":
# output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of RootRef") # output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of RootRef")
# output.writeLine(" impl*: ptr ParamSpec00") # output.writeLine(" impl*: ptr ParamSpec00")
@ -1472,8 +1556,9 @@ proc writeObj(info: GIObjectInfo) =
output.writeLine(" GC_ref(cast[RootRef](data))") output.writeLine(" GC_ref(cast[RootRef](data))")
output.writeLine(" else:") output.writeLine(" else:")
output.writeLine(" GC_unref(cast[RootRef](data))") output.writeLine(" GC_unref(cast[RootRef](data))")
output.writeLine("\nproc finalizeGObject*[T](o: T) =") output.writeLine("\nproc finalizeGObject*[T](o: ref T) =")
output.writeLine(" g_object_remove_toggle_ref(o.impl, toggleNotify, addr(o[]))") output.writeLine("\n if not o.ignoreFinalizer:")
output.writeLine(" g_object_remove_toggle_ref(o.impl, toggleNotify, addr(o[]))")
var getTypeProc: string var getTypeProc: string
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE: if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
@ -1501,7 +1586,7 @@ proc writeObj(info: GIObjectInfo) =
if gBaseInfoGetName(info) == "Object" and moduleNamespace == "gobject": if gBaseInfoGetName(info) == "Object" and moduleNamespace == "gobject":
output.writeLine("type\n Object* = ref object of RootRef") output.writeLine("type\n Object* = ref object of RootRef")
output.writeLine(" impl*: ptr Object00") output.writeLine(" impl*: ptr Object00")
output.writeLine(" ignoreFinalizer*: bool")
proc extractFromUnion(tag: GITypeTag; arg: GIArgumentObj): string = proc extractFromUnion(tag: GITypeTag; arg: GIArgumentObj): string =
result = result =
case tag: case tag:
@ -1608,13 +1693,30 @@ proc seq2cstringArray*(s: openarray[string]; a: var cstringArray): cstringArray
const GTK_SOURCE_EPI = """ const GTK_SOURCE_EPI = """
proc getView(builder: Builder; name: string): View = proc nogetView(builder: Builder; name: string): View =
new result new result
let gt = g_type_from_name("GSource") let gt = g_type_from_name("GSource")
assert(gt != 0) assert(gt != 0)
result.impl = gtk_builder_get_object(cast[ptr Builder00](builder.impl), name) result.impl = gtk_builder_get_object(cast[ptr Builder00](builder.impl), name)
assert(toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](result.impl), gt))) assert(toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](result.impl), gt)))
proc getView*(builder: Builder; name: string): View =
#let gt = g_type_from_name("Gtk$1") # this worked also!
#let gt = $2
let gt = g_type_from_name("GSource")
assert(gt != g_type_invalid_get_type())
let gobj = gtk_builder_get_object(cast[ptr Builder00](builder.impl), name)
if g_object_get_qdata(gobj, Quark) != nil:
result = cast[type(result)](g_object_get_qdata(gobj, Quark))
assert(result.impl == gobj)
else:
new(result, gtksource.finalizeGObject)
result.impl = gobj
result.ignoreFinalizer = true
g_object_add_toggle_ref(result.impl, toggleNotify, addr(result[]))
assert(g_object_get_qdata(result.impl, Quark) == nil)
g_object_set_qdata(result.impl, Quark, addr(result[]))
assert(toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](result.impl), gt)))
""" """
const GDK3_EPI = """ const GDK3_EPI = """
@ -1626,7 +1728,7 @@ proc invalidateRect*(self: Window; rect: ptr Rectangle = nil; invalidateChildren
gdk_window_invalidate_nilrect(cast[ptr Window00](self.impl), rect, gboolean(invalidateChildren)) gdk_window_invalidate_nilrect(cast[ptr Window00](self.impl), rect, gboolean(invalidateChildren))
proc fixednewCursorFromName*(display: Display; name: string): Cursor = proc fixednewCursorFromName*(display: Display; name: string): Cursor =
new(result, finalizeGObject) new(result, gdk.finalizeGObject)
result.impl = gdk_cursor_new_from_name(cast[ptr Display00](display.impl), cstring(name)) result.impl = gdk_cursor_new_from_name(cast[ptr Display00](display.impl), cstring(name))
GC_ref(result) GC_ref(result)
discard g_object_ref_sink(result.impl) discard g_object_ref_sink(result.impl)
@ -1719,7 +1821,7 @@ proc newFileChooserDialog*(title: string = ""; parent: Window = nil; action: Fil
result = cast[type(result)](g_object_get_qdata(gobj, Quark)) result = cast[type(result)](g_object_get_qdata(gobj, Quark))
assert(result.impl == gobj) assert(result.impl == gobj)
else: else:
new(result, finalizeGObject) new(result, $1.finalizeGObject)
result.impl = gobj result.impl = gobj
GC_ref(result) GC_ref(result)
discard g_object_ref_sink(result.impl) discard g_object_ref_sink(result.impl)
@ -1735,7 +1837,7 @@ proc initFileChooserDialog*[T](result: var T; title: string = ""; parent: Window
result = cast[type(result)](g_object_get_qdata(gobj, Quark)) result = cast[type(result)](g_object_get_qdata(gobj, Quark))
assert(result.impl == gobj) assert(result.impl == gobj)
else: else:
new(result, finalizeGObject) new(result, $1.finalizeGObject)
result.impl = gobj result.impl = gobj
GC_ref(result) GC_ref(result)
discard g_object_ref_sink(result.impl) discard g_object_ref_sink(result.impl)
@ -1860,8 +1962,8 @@ proc main(namespace: string; version: cstring = nil) =
output.writeLine("const\n GLIB_SIZEOF_VOID_P = sizeof(pointer)") output.writeLine("const\n GLIB_SIZEOF_VOID_P = sizeof(pointer)")
output.writeLine("const\n GLIB_SIZEOF_SIZE_T* = GLIB_SIZEOF_VOID_P") output.writeLine("const\n GLIB_SIZEOF_SIZE_T* = GLIB_SIZEOF_VOID_P")
output.writeLine("const\n GLIB_SIZEOF_LONG* = sizeof(clong)") output.writeLine("const\n GLIB_SIZEOF_LONG* = sizeof(clong)")
output.writeLine("type\n Gssize* = csize") output.writeLine("type\n Gssize* = int # csize") # https://forum.nim-lang.org/t/5637#35015
output.writeLine("type\n Gsize* = csize # note: csize is signed in Nim!") output.writeLine("type\n Gsize* = uint # csize # note: csize is signed in Nim!")
#output.writeLine("type\n GType* = distinct cint") # wrong #output.writeLine("type\n GType* = distinct cint") # wrong
#stefan@nuc ~/Downloads/glib-2.53.3/gobject $ grep -A5 GLIB_SIZEOF_S *.h #stefan@nuc ~/Downloads/glib-2.53.3/gobject $ grep -A5 GLIB_SIZEOF_S *.h
#gtype.h:#if GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined __cplusplus #gtype.h:#if GLIB_SIZEOF_SIZE_T != GLIB_SIZEOF_LONG || !defined __cplusplus
@ -1998,6 +2100,15 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
output.writeLine("if g_quark_try_string(qt) != 0:") output.writeLine("if g_quark_try_string(qt) != 0:")
output.writeLine(" qt = \"NGIQ\" & $epochTime()") output.writeLine(" qt = \"NGIQ\" & $epochTime()")
output.writeLine("let Quark* = g_quark_from_static_string(qt)") output.writeLine("let Quark* = g_quark_from_static_string(qt)")
if namespace notin ["GObject", "GLib", "xlib", "GModule"]:
output.writeLine("\nproc finalizeGObject*[T](o: ref T) =")
output.writeLine("\n if not o.ignoreFinalizer:")
output.writeLine(" gobject.g_object_remove_toggle_ref(o.impl, gobject.toggleNotify, addr(o[]))")
output.writeLine("\nproc genericGObjectUnref*[T](self: ref T) =")
output.writeLine(" if not self.ignoreFinalizer:")
output.writeLine(" gobject.g_object_unref(cast[ptr gobject.Object00](self.impl))")
var n = gi.gIrepositoryGetNInfos(namespace) var n = gi.gIrepositoryGetNInfos(namespace)
var s: seq[GIBaseInfo] var s: seq[GIBaseInfo]
for i in 0.cint ..< n: for i in 0.cint ..< n:
@ -2005,7 +2116,8 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
gi.gIrepositoryGetInfo(namespace, i)))): gi.gIrepositoryGetInfo(namespace, i)))):
s.add(gi.gIrepositoryGetInfo(namespace, i)) s.add(gi.gIrepositoryGetInfo(namespace, i))
for i in s: for i in s:
if gBaseInfoGetType(i) in {GIInfoType.OBJECT, GIInfoType.INTERFACE, GIInfoType.STRUCT, GIInfoType.UNION} or isEnumInfo(i) or isCallbackInfo(i): if gBaseInfoGetType(i) in {GIInfoType.OBJECT, GIInfoType.INTERFACE, GIInfoType.STRUCT, GIInfoType.UNION} or isEnumInfo(i) or
isCallbackInfo(i):
allSyms.incl(mangleName(gBaseInfoGetName(i))) allSyms.incl(mangleName(gBaseInfoGetName(i)))
for i in 0 .. s.high: for i in 0 .. s.high:
if namespace == "GLib" and gBaseInfoGetType(s[ if namespace == "GLib" and gBaseInfoGetType(s[
@ -2089,7 +2201,8 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
ig.incl(h) ig.incl(h)
var k = -1 var k = -1
for p, el in s: for p, el in s:
if (gBaseInfoGetType(el) in {GIInfoType.OBJECT, GIInfoType.INTERFACE, GIInfoType.STRUCT} or isEnumInfo(el)) and gBaseInfoGetName(el) == h: if (gBaseInfoGetType(el) in {GIInfoType.OBJECT, GIInfoType.INTERFACE, GIInfoType.STRUCT} or isEnumInfo(el)) and
gBaseInfoGetName(el) == h:
k = p k = p
if k >= 0: if k >= 0:
s.add(s[k]) s.add(s[k])
@ -2135,7 +2248,8 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
try: try:
var h = false var h = false
for k in t: for k in t:
if gBaseInfoGetType(k) notin {GIInfoType.INTERFACE, GIInfoType.OBJECT, GIInfoType.STRUCT, GIInfoType.UNION} and not isCallbackInfo(k): if gBaseInfoGetType(k) notin {GIInfoType.INTERFACE, GIInfoType.OBJECT, GIInfoType.STRUCT, GIInfoType.UNION} and
not isCallbackInfo(k):
h = true h = true
if h: continue if h: continue
output.writeLine("type") output.writeLine("type")
@ -2195,7 +2309,7 @@ proc init* =
gtk_init(argc, argv) gtk_init(argc, argv)
""") """)
output.write(GTK_EPI) output.write(GTK_EPI % fixedModName("gtk"))
if ISGTK3: if ISGTK3:
output.write("include gisup3\n") output.write("include gisup3\n")
output.write("include gimpl\n") output.write("include gimpl\n")
@ -2205,8 +2319,10 @@ proc init* =
buildableList.add("MenuModel") buildableList.add("MenuModel")
for i in buildableList: for i in buildableList:
var prefix = "gtk" var prefix = "gtk"
var modname = fixedModName(moduleNamespace)
if i == "MenuModel": if i == "MenuModel":
prefix = "g" prefix = "g"
modname = "gio"
if i == "": continue if i == "": continue
output.write( output.write(
""" """
@ -2219,14 +2335,15 @@ proc get$1*(builder: Builder; name: string): $1 =
result = cast[type(result)](g_object_get_qdata(gobj, Quark)) result = cast[type(result)](g_object_get_qdata(gobj, Quark))
assert(result.impl == gobj) assert(result.impl == gobj)
else: else:
new(result, finalizeGObject) new(result, $3.finalizeGObject)
result.impl = gobj result.impl = gobj
result.ignoreFinalizer = true
g_object_add_toggle_ref(result.impl, toggleNotify, addr(result[])) g_object_add_toggle_ref(result.impl, toggleNotify, addr(result[]))
assert(g_object_get_qdata(result.impl, Quark) == nil) assert(g_object_get_qdata(result.impl, Quark) == nil)
g_object_set_qdata(result.impl, Quark, addr(result[])) g_object_set_qdata(result.impl, Quark, addr(result[]))
assert(toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](result.impl), gt))) assert(toBool(g_type_check_instance_is_a(cast[ptr TypeInstance00](result.impl), gt)))
""" % [i, prefix & "_" & myCamelToSnake(i) & "_get_type()"]) """ % [i, prefix & "_" & myCamelToSnake(i) & "_get_type()", modname])
output.write("") output.write("")
if namespace == "Gio": if namespace == "Gio":
@ -2236,29 +2353,29 @@ proc get$1*(builder: Builder; name: string): $1 =
output.write("include cairoimpl\n") output.write("include cairoimpl\n")
if namespace == "GObject": if namespace == "GObject":
output.writeLine("\nproc g_type_invalid_get_type*(): GType = g_type_from_name(\"(null)\")") output.writeLine("\nproc g_type_invalid_get_type*(): GType = g_type_from_name(\"(null)\")")
output.writeLine("\nproc g_type_none_get_type*(): GType = g_type_from_name(\"void\")") output.writeLine("\nproc g_type_none_get_type*(): GType = g_type_from_name(\"void\")")
output.writeLine("\nproc g_interface_get_type*(): GType = g_type_from_name(\"GInterface\")") output.writeLine("\nproc g_interface_get_type*(): GType = g_type_from_name(\"GInterface\")")
output.writeLine("\nproc g_char_get_type*(): GType = g_type_from_name(\"gchar\")") output.writeLine("\nproc g_char_get_type*(): GType = g_type_from_name(\"gchar\")")
output.writeLine("\nproc g_uchar_get_type*(): GType = g_type_from_name(\"guchar\")") output.writeLine("\nproc g_uchar_get_type*(): GType = g_type_from_name(\"guchar\")")
output.writeLine("\nproc g_boolean_get_type*(): GType = g_type_from_name(\"gboolean\")") output.writeLine("\nproc g_boolean_get_type*(): GType = g_type_from_name(\"gboolean\")")
output.writeLine("\nproc g_int_get_type*(): GType = g_type_from_name(\"gint\")") output.writeLine("\nproc g_int_get_type*(): GType = g_type_from_name(\"gint\")")
output.writeLine("\nproc g_uint_get_type*(): GType = g_type_from_name(\"guint\")") output.writeLine("\nproc g_uint_get_type*(): GType = g_type_from_name(\"guint\")")
output.writeLine("\nproc g_long_get_type*(): GType = g_type_from_name(\"glong\")") output.writeLine("\nproc g_long_get_type*(): GType = g_type_from_name(\"glong\")")
output.writeLine("\nproc g_ulong_get_type*(): GType = g_type_from_name(\"gulong\")") output.writeLine("\nproc g_ulong_get_type*(): GType = g_type_from_name(\"gulong\")")
output.writeLine("\nproc g_int64_get_type*(): GType = g_type_from_name(\"gint64\")") output.writeLine("\nproc g_int64_get_type*(): GType = g_type_from_name(\"gint64\")")
output.writeLine("\nproc g_uint64_get_type*(): GType = g_type_from_name(\"guint64\")") output.writeLine("\nproc g_uint64_get_type*(): GType = g_type_from_name(\"guint64\")")
output.writeLine("\nproc g_enum_get_type*(): GType = g_type_from_name(\"GEnum\")") output.writeLine("\nproc g_enum_get_type*(): GType = g_type_from_name(\"GEnum\")")
output.writeLine("\nproc g_flags_get_type*(): GType = g_type_from_name(\"GFlags\")") output.writeLine("\nproc g_flags_get_type*(): GType = g_type_from_name(\"GFlags\")")
output.writeLine("\nproc g_float_get_type*(): GType = g_type_from_name(\"gfloat\")") output.writeLine("\nproc g_float_get_type*(): GType = g_type_from_name(\"gfloat\")")
output.writeLine("\nproc g_double_get_type*(): GType = g_type_from_name(\"gdouble\")") output.writeLine("\nproc g_double_get_type*(): GType = g_type_from_name(\"gdouble\")")
output.writeLine("\nproc g_string_get_type*(): GType = g_type_from_name(\"gchararray\")") output.writeLine("\nproc g_string_get_type*(): GType = g_type_from_name(\"gchararray\")")
output.writeLine("\nproc g_pointer_get_type*(): GType = g_type_from_name(\"gpointer\")") output.writeLine("\nproc g_pointer_get_type*(): GType = g_type_from_name(\"gpointer\")")
output.writeLine("\nproc g_boxed_get_type*(): GType = g_type_from_name(\"GBoxed\")") output.writeLine("\nproc g_boxed_get_type*(): GType = g_type_from_name(\"GBoxed\")")
output.writeLine("\nproc g_param_get_type*(): GType = g_type_from_name(\"GParam\")") output.writeLine("\nproc g_param_get_type*(): GType = g_type_from_name(\"GParam\")")
#output.writeLine("\nproc g_object_get_type*(): GType = g_type_from_name(\"GObject\")") #output.writeLine("\nproc g_object_get_type*(): GType = g_type_from_name(\"GObject\")")
#output.writeLine("\nproc g_type_get_type*(): GType = g_type_from_name(\"GType\")") #output.writeLine("\nproc g_type_get_type*(): GType = g_type_from_name(\"GType\")")
output.writeLine("\nproc g_variant_get_type*(): GType = g_type_from_name(\"GVariant\")") output.writeLine("\nproc g_variant_get_type*(): GType = g_type_from_name(\"GVariant\")")
if namespace == "Gdk": if namespace == "Gdk":
if ISGTK3: if ISGTK3:
@ -2355,5 +2472,5 @@ proc launch() =
o.close() o.close()
supmod4.close supmod4.close
launch() launch() # depStr TODO
# 2360 lines # 2476 lines