added gstreamer and gboxed types support

This commit is contained in:
Stefan Salewski 2019-10-28 13:05:12 +01:00
commit c2b13b0b90
9 changed files with 350 additions and 3220 deletions

View file

@ -1,6 +1,6 @@
= High level GTK3 (and GTK4) bindings for the Nim programming language = High level GTK3 (and GTK4) bindings for the Nim programming language
(c) Stefan Salewski (c) Stefan Salewski
//Version 0.5.4 //Version 0.6.0
:experimental: :experimental:
:imagesdir: http://ssalewski.de/tmp :imagesdir: http://ssalewski.de/tmp
:source-highlighter: pygments :source-highlighter: pygments
@ -16,9 +16,14 @@
TIP: A more fancy copy of this document with dark source code background is available at http://ssalewski.de/gintroreadme.html[GIntro README] TIP: A more fancy copy of this document with dark source code background is available at http://ssalewski.de/gintroreadme.html[GIntro README]
NOTE: This work is partly based on earlier works of J. Mansour and has been supported by A. Rumpf 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
cairo module into an gobject-introspection basic part and an manually created part. Unfortunately the
gobject-introspection is not available for very old 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.
NOTE: Starting with release 0.5.3 we do not generate field entries for objects and we do NOTE: Starting with release 0.5.3 we do not generate field entries for objects and we do
not generate class structs and private objects. Also we stopped exporting the low level functions not generate class structs and private objects. Also we stopped exporting the low level functions
like gtk_button_new(). For a real high-level binding we should not need these. If that is a serious like gtk_button_new(). For a real high-level binding we should not need these. If that is a serious
@ -186,8 +191,8 @@ nim c app0.nim
./app0 ./app0
---- ----
or you may open the source files in your favorite Nim IDE or editor. Taking the source code from this Readme file is not or you may open the source files in your favorite Nim IDE or editor. [black yellow-background]#Taking the source code from this Readme file is not
really recommended, as these source code listings may be not the latest versions. really recommended, as these source code listings may be not the latest versions.#
GTK3 programs can use still the old _GTK2_ design, where you first initialize the GTK library, create your widgets and finally enter the GTK main loop. GTK3 programs can use still the old _GTK2_ design, where you first initialize the GTK library, create your widgets and finally enter the GTK main loop.
This style is still used in many tutorials as in http://zetcode.com/gui/gtk2/[Zetcode tutorial] or in the GTK book of A. Krause. This style is still used in many tutorials as in http://zetcode.com/gui/gtk2/[Zetcode tutorial] or in the GTK book of A. Krause.
@ -2343,5 +2348,37 @@ proc main =
main() main()
---- ----
== A GStreamer example
Recently someone asked about gstreamer support for gintro, see https://github.com/StefanSalewski/gintro/issues/59 .
So we added it. I don't know much about gstreamer, but I was told that it is used with
Python and lately with Rusts bindings, so there may be some use case.
[[gstBasicTutorial1.nim]]
[source,nim]
.gstBasicTutorial1.nim
----
# https://gstreamer.freedesktop.org/documentation/tutorials/basic/hello-world.html?gi-language=c
# nim c gstBasicTutorial1.nim
import gintro/gst
proc main =
var pipeline: gst.Element
var bus: gst.Bus
var msg: gst.Message
## Initialize GStreamer
gst.init()
## Build the pipeline
pipeline = gst.parseLaunch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm")
## Start playing
discard gst.setState(pipeline, gst.State.playing)
## Wait until error or EOS
bus = gst.getBus(pipeline)
msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
discard gst.setState(pipeline, gst.State.null) # is this necessary?
main()
----
NOTE: Related work: https://github.com/jdmansour/nim-smartgi NOTE: Related work: https://github.com/jdmansour/nim-smartgi

View file

@ -0,0 +1,20 @@
# https://gstreamer.freedesktop.org/documentation/tutorials/basic/hello-world.html?gi-language=c
# nim c gstBasicTutorial1.nim
import gintro/gst
proc main =
var pipeline: gst.Element
var bus: gst.Bus
var msg: gst.Message
## Initialize GStreamer
gst.init()
## Build the pipeline
pipeline = gst.parseLaunch("playbin uri=https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm")
## Start playing
discard gst.setState(pipeline, gst.State.playing)
## Wait until error or EOS
bus = gst.getBus(pipeline)
msg = gst.timedPopFiltered(bus, gst.Clock_Time_None, {gst.MessageFlag.error, gst.MessageFlag.eos})
discard gst.setState(pipeline, gst.State.null) # is this necessary?
main()

View file

@ -24,7 +24,7 @@ proc appendItem(widget: Button; entry: Entry) =
val: Value val: Value
iter: TreeIter iter: TreeIter
let store = listStore(getModel(list)) let store = listStore(getModel(list))
let gtype = typeFromName("gchararray") let gtype = gStringGetType() # typeFromName("gchararray")
discard init(val, gtype) discard init(val, gtype)
setString(val, entry.text) setString(val, entry.text)
store.append(iter) store.append(iter)
@ -57,7 +57,7 @@ proc initList(list: TreeView) =
column.packStart(renderer, true) column.packStart(renderer, true)
column.addAttribute(renderer, "text", LIST_ITEM) column.addAttribute(renderer, "text", LIST_ITEM)
discard list.appendColumn(column) discard list.appendColumn(column)
let gtype = typeFromName("gchararray") let gtype = gStringGetType() # typeFromName("gchararray")
let store = newListStore(N_COLUMNS, cast[pointer]( unsafeaddr gtype)) # cast due to bug in gtk.nim let store = newListStore(N_COLUMNS, cast[pointer]( unsafeaddr gtype)) # cast due to bug in gtk.nim
list.setModel(store) list.setModel(store)

View file

@ -16,3 +16,6 @@ nim c simpledrawingarea.nim
nim c css_colored_listview.nim nim c css_colored_listview.nim
nim c gearsmenu.nim nim c gearsmenu.nim
nim c cairoImage.nim nim c cairoImage.nim
nim c gstBasicTutorial1.nim
nim c sourceview_test.nim
nim c overlay_tree1.nim

View file

@ -0,0 +1,16 @@
import gintro/[gtk, glib, gobject, gio, gtksource]
proc appActivate (app: Application) =
let window = newApplicationWindow(app)
window.title = "GTKSourceView"
window.defaultSize = (250, 350)
let view = newView()
window.add(view)
window.showAll
proc main =
let app = newApplication("org.gtk.example")
connect(app, "activate", appActivate)
discard app.run
main()

View file

@ -1,6 +1,6 @@
# Package # Package
version = "0.5.5" version = "0.6.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"
@ -8,7 +8,7 @@ skipDirs = @["examples", "tests"]
# Dependencies # Dependencies
requires "nim >= 0.20.0" requires "nim >= 1.0.0"
when defined(nimdistros): when defined(nimdistros):
import distros import distros

View file

@ -1,7 +1,9 @@
# 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.5.04 # v0.6.0
# 14-SEP-2019 # 28-OCT-2019
# starting with gintro v.0.6.0 we split cairo into the gobject-introspection generated cairo.nim and this file.
# Cairo does not really support gobject introspection and gobject's toggle references. # Cairo does not really support gobject introspection and gobject's toggle references.
# So code for memory management is a bit different compared to other gtk modules. # So code for memory management is a bit different compared to other gtk modules.
@ -92,111 +94,6 @@ else:
{.pragma: libcairo, cdecl, dynlib: LIB_CAIRO.} {.pragma: libcairo, cdecl, dynlib: LIB_CAIRO.}
type
Context00* = object
Context* = ref object of RootRef
impl*: ptr Context00
type
Surface00* = object
Surface* = ref object of RootRef
impl*: ptr Surface00
type
Matrix* {.byRef.} = object
xx*: cdouble
yx*: cdouble
xy*: cdouble
yy*: cdouble
x0*: cdouble
y0*: cdouble
type
Pattern00* = object
Pattern* = ref object of RootRef
impl*: ptr Pattern00
type
Region00* = object
Region* = ref object of RootRef
impl*: ptr Region00
type
Content* {.size: sizeof(cint), pure.} = enum
color = 0x1000, alpha = 0x2000,
color_alpha = 0x3000
type
FontOptions00* = object
FontOptions* = ref object of RootRef
impl*: ptr FontOptions00
type
FontFace00* = object
FontFace* = ref object of RootRef
impl*: ptr FontFace00
type
ScaledFont00* = object
ScaledFont* = ref object of RootRef
impl*: ptr ScaledFont00
type
Status* {.size: sizeof(cint), pure.} = enum
success = 0, noMemory, invalidRestore,
invalidPopGroup, noCurrentPoint,
invalidMatrix, invalidStatus,
nullPointer, invalidString,
invalidPathData, readError,
writeError, surfaceFinished,
surfaceTypeMismatch, patternTypeMismatch,
invalidContent, invalidFormat,
invalidVisual, fileNotFound,
invalidDash, invalidDscComment,
invalidIndex, clipNotRepresentable,
tempFileError, invalidStride,
fontTypeMismatch, userFontImmutable,
userFontError, negativeCount,
invalidClusters, invalidSlant,
invalidWeight, invalidSize,
userFontNotImplemented, deviceTypeMismatch,
deviceError, invalidMeshConstruction,
deviceFinished, jbig2GlobalMissing,
pngError, freetypeError,
win32GdiError, tagError, lastStatus
type
PathDataType* {.size: sizeof(cint), pure.} = enum
moveTo, lineTo, curveTo, closePath
type
INNER_C_STRUCT_3330700347* = object
t*: PathDataType
length*: cint
INNER_C_STRUCT_1651263489* = object
x*: cdouble
y*: cdouble
PathData00* {.union.} = object
header*: INNER_C_STRUCT_3330700347
point*: INNER_C_STRUCT_1651263489
type
Path00* = object
status*: Status
data*: ptr PathData00
numData*: cint
Path* = ref object of RootRef
impl*: ptr Path00
type
RectangleInt* {.byRef.} = object
x*: cint
y*: cint
width*: cint
height*: cint
const const
CAIRO_HAS_TEE_SURFACE = true CAIRO_HAS_TEE_SURFACE = true
CAIRO_HAS_DRM_SURFACE = true CAIRO_HAS_DRM_SURFACE = true
@ -228,11 +125,6 @@ type
#converter toBool*(cbool: Bool00): bool = #converter toBool*(cbool: Bool00): bool =
# int(cbool) != 0 # int(cbool) != 0
type
Device00* = object
Device* = ref object of RootRef
impl*: ptr Device00
type type
DestroyFunc00* = proc (data: pointer) {.cdecl.} DestroyFunc00* = proc (data: pointer) {.cdecl.}
@ -248,12 +140,6 @@ proc gcuref(o: pointer) {.cdecl.} =
#echo "gcunref" #echo "gcunref"
GC_unref(cast[RootRef](o)) GC_unref(cast[RootRef](o))
type
Format* {.size: sizeof(cint), pure.} = enum
invalid = - 1, argb32 = 0, rgb24 = 1,
a8 = 2, a1 = 3, rgb16_565 = 4,
rgb30 = 5
type type
WriteFunc00* = proc (closure: pointer; data: ptr cuchar; length: cuint): Status {.cdecl.} WriteFunc00* = proc (closure: pointer; data: ptr cuchar; length: cuint): Status {.cdecl.}
@ -363,20 +249,6 @@ proc cairo_pop_group_to_source*(cr: ptr Context00) {.importc, libcairo.}
proc popGroupToSource*(cr: Context) = proc popGroupToSource*(cr: Context) =
cairo_pop_group_to_source(cr.impl) cairo_pop_group_to_source(cr.impl)
type
Operator* {.size: sizeof(cint), pure.} = enum
clear, source, over,
`in`, `out`, atop,
dest, destOver, destIn,
destOut, destAtop, `xor`,
add, saturate, multiply,
screen, overlay, darken,
lighten, color_dodge, colorBurn,
hardLight, softLight,
difference, exclusion, hslHue,
hslSaturation, hslColor,
hslLuminosity
proc cairo_set_operator*(cr: ptr Context00; op: Operator) {.importc, libcairo.} proc cairo_set_operator*(cr: ptr Context00; op: Operator) {.importc, libcairo.}
# #
proc setOperator*(cr: Context; op: Operator) = proc setOperator*(cr: Context; op: Operator) =
@ -430,12 +302,6 @@ proc setTolerance*(cr: Context; tolerance: float) =
# #
const `tolerance=`* = setTolerance const `tolerance=`* = setTolerance
type
Antialias* {.size: sizeof(cint), pure.} = enum
default, none, gray,
subpixel, fast, good,
best
proc cairo_set_antialias*(cr: ptr Context00; antialias: Antialias) {.importc, libcairo.} proc cairo_set_antialias*(cr: ptr Context00; antialias: Antialias) {.importc, libcairo.}
# #
proc setAntialias*(cr: Context; antialias = Antialias.default) = proc setAntialias*(cr: Context; antialias = Antialias.default) =
@ -443,10 +309,6 @@ proc setAntialias*(cr: Context; antialias = Antialias.default) =
# #
const `antialias=`* = setAntialias const `antialias=`* = setAntialias
type
FillRule* {.size: sizeof(cint), pure.} = enum
winding, evenOdd
proc cairo_set_fill_rule*(cr: ptr Context00; fillRule: FillRule) {.importc, libcairo.} proc cairo_set_fill_rule*(cr: ptr Context00; fillRule: FillRule) {.importc, libcairo.}
# #
proc setFillRule*(cr: Context; fillRule: FillRule) = proc setFillRule*(cr: Context; fillRule: FillRule) =
@ -461,20 +323,12 @@ proc setLineWidth*(cr: Context; width: float) =
# #
const `lineWidth=`* = setLineWidth const `lineWidth=`* = setLineWidth
type
LineCap* {.size: sizeof(cint), pure.} = enum
butt, round, square
proc cairo_set_line_cap*(cr: ptr Context00; lineCap: LineCap) {.importc, libcairo.} proc cairo_set_line_cap*(cr: ptr Context00; lineCap: LineCap) {.importc, libcairo.}
# #
proc setLineCap*(cr: Context; lineCap: LineCap) = proc setLineCap*(cr: Context; lineCap: LineCap) =
cairo_set_line_cap(cr.impl, lineCap) cairo_set_line_cap(cr.impl, lineCap)
# #
const `lineCap=`* = setLineCap const `lineCap=`* = setLineCap
type
LineJoin* {.size: sizeof(cint), pure.} = enum
miter, round, bevel
proc cairo_set_line_join*(cr: ptr Context00; lineJoin: Line_join) {.importc, libcairo.} proc cairo_set_line_join*(cr: ptr Context00; lineJoin: Line_join) {.importc, libcairo.}
# #
@ -571,7 +425,7 @@ proc newPath*(cr: Context) =
proc cairo_move_to*(cr: ptr Context00; x, y: cdouble) {.importc, libcairo.} proc cairo_move_to*(cr: ptr Context00; x, y: cdouble) {.importc, libcairo.}
# #
proc moveTo*(cr: Context; x, y: float) = proc moveTo*(cr: Context; x, y: float) =
cairo_move_to(cr.impl, x.cdouble, y.cdouble) cairo_move_to(cr.impl, x.cdouble, y.cdouble)
proc cairo_new_sub_path*(cr: ptr Context00) {.importc, libcairo.} proc cairo_new_sub_path*(cr: ptr Context00) {.importc, libcairo.}
# #
@ -586,7 +440,7 @@ proc lineTo*(cr: Context; x, y: float) =
proc cairo_curve_to*(cr: ptr Context00; x1, y1, x2, y2, x3, y3: cdouble) {.importc, libcairo.} proc cairo_curve_to*(cr: ptr Context00; x1, y1, x2, y2, x3, y3: cdouble) {.importc, libcairo.}
# #
proc curveTo*(cr: Context; x1, y1, x2, y2, x3, y3: float) = proc curveTo*(cr: Context; x1, y1, x2, y2, x3, y3: float) =
cairo_curve_to(cr.impl, x1.cdouble, y1.cdouble, x2.cdouble, y2.cdouble, x3.cdouble, y3.cdouble) cairo_curve_to(cr.impl, x1.cdouble, y1.cdouble, x2.cdouble, y2.cdouble, x3.cdouble, y3.cdouble)
proc cairo_arc*(cr: ptr Context00; xc, yc, radius, angle1, angle2: cdouble) {.importc, libcairo.} proc cairo_arc*(cr: ptr Context00; xc, yc, radius, angle1, angle2: cdouble) {.importc, libcairo.}
# #
@ -675,7 +529,7 @@ proc strokePreserve*(cr: Context) =
proc cairo_fill*(cr: ptr Context00) {.importc, libcairo.} proc cairo_fill*(cr: ptr Context00) {.importc, libcairo.}
# #
proc fill*(cr: Context) = proc fill*(cr: Context) =
cairo_fill(cr. impl) cairo_fill(cr.impl)
proc cairo_fill_preserve*(cr: ptr Context00) {.importc, libcairo.} proc cairo_fill_preserve*(cr: ptr Context00) {.importc, libcairo.}
# #
@ -754,24 +608,10 @@ proc clipExtents*(cr: Context; x1, y1, x2, y2: var float) =
const getClipExtents* = clipExtents const getClipExtents* = clipExtents
type
Rectangle00* = object
x*: cdouble
y*: cdouble
width*: cdouble
height*: cdouble
type
Rectangle* = object
x*: float
y*: float
width*: float
height*: float
type type
RectangleList00* = object RectangleList00* = object
status*: Status status*: Status
rectangles*: ptr Rectangle00 rectangles*: ptr Rectangle
numRectangles*: cint numRectangles*: cint
proc cairo_copy_clip_rectangle_list(cr: ptr Context00): ptr RectangleList00 {.importc, libcairo.} proc cairo_copy_clip_rectangle_list(cr: ptr Context00): ptr RectangleList00 {.importc, libcairo.}
@ -785,7 +625,7 @@ proc copyClipRectangleList*(cr: Context): seq[Rectangle] =
if r.status != Status.success or r.numRectangles == 0: return @[] if r.status != Status.success or r.numRectangles == 0: return @[]
result = newSeq[Rectangle]() result = newSeq[Rectangle]()
for i in 0 ..< r.numRectangles: for i in 0 ..< r.numRectangles:
let k = cast[ptr array[99, Rectangle00]](r.rectangles)[i] let k = cast[ptr array[99, Rectangle]](r.rectangles)[i]
h.x = k.x.float h.x = k.x.float
h.y = k.y.float h.y = k.y.float
h.width = k.width.float h.width = k.width.float
@ -812,7 +652,7 @@ type
x*: cdouble x*: cdouble
y*: cdouble y*: cdouble
Glyph* = ref object of RootRef Glyph* = ref object of RootRef
impl*: ptr Glyph00 impl*: ptr Glyph00
# TODO # TODO
@ -832,10 +672,6 @@ type
proc cairo_text_cluster_allocate*(num_clusters: cint): ptr Text_cluster00 {.importc, libcairo.} proc cairo_text_cluster_allocate*(num_clusters: cint): ptr Text_cluster00 {.importc, libcairo.}
proc cairo_text_cluster_free*(clusters: ptr Text_cluster00) {.importc, libcairo.} proc cairo_text_cluster_free*(clusters: ptr Text_cluster00) {.importc, libcairo.}
type
TextClusterFlags* {.size: sizeof(cint), pure.} = enum
backward = 0x1
type type
TextExtents* {.byRef.} = object TextExtents* {.byRef.} = object
xBearing*: cdouble xBearing*: cdouble
@ -853,28 +689,6 @@ type
maxXAdvance*: cdouble maxXAdvance*: cdouble
maxYAdvance*: cdouble maxYAdvance*: cdouble
type
FontSlant* {.size: sizeof(cint), pure.} = enum
normal, italic, oblique
type
FontWeight* {.size: sizeof(cint), pure.} = enum
normal, bold
type
SubpixelOrder* {.size: sizeof(cint), pure.} = enum
default, rgb,
bgr, vrgb, vbgr
type
HintStyle* {.size: sizeof(cint), pure.} = enum
default, none, slight,
medium, full
type
HintMetrics* {.size: sizeof(cint), pure.} = enum
default, off, on
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) =
@ -1059,8 +873,8 @@ proc getFontFace*(cr: Context): FontFace =
result = cast[FontFace](d) result = cast[FontFace](d)
assert(result.impl == h) assert(result.impl == h)
#discard cairo_font_face_reference(result.impl) # should be not necessary? #discard cairo_font_face_reference(result.impl) # should be not necessary?
# #
#const fontFace* = getFontFace #const fontFace* = getFontFace
proc cairo_set_scaled_font*(cr: ptr Context00; scaledFont: ptr ScaledFont00) {.importc, libcairo.} proc cairo_set_scaled_font*(cr: ptr Context00; scaledFont: ptr ScaledFont00) {.importc, libcairo.}
# #
@ -1110,8 +924,8 @@ proc getScaledFont*(cr: Context): ScaledFont =
result = cast[ScaledFont](d) result = cast[ScaledFont](d)
assert(result.impl == h) assert(result.impl == h)
#discard cairo_scaled_font_reference(result.impl) # should be not necessary? #discard cairo_scaled_font_reference(result.impl) # should be not necessary?
# #
#const scaledFont* = getScaledFont #const scaledFont* = getScaledFont
proc cairo_show_text*(cr: ptr Context00; utf8: cstring) {.importc, libcairo.} proc cairo_show_text*(cr: ptr Context00; utf8: cstring) {.importc, libcairo.}
# #
@ -1129,7 +943,7 @@ proc cairo_show_text_glyphs*(cr: ptr Context00; utf8: cstring; utf8_len: cint;
clusters: ptr TextCluster00; numClusters: cint; clusters: ptr TextCluster00; numClusters: cint;
clusterFlags: TextClusterFlags) {.importc, libcairo.} clusterFlags: TextClusterFlags) {.importc, libcairo.}
proc cairo_text_path*(cr: ptr Context00; utf8: cstring) {.importc,libcairo.} proc cairo_text_path*(cr: ptr Context00; utf8: cstring) {.importc, libcairo.}
# #
proc textPath*(cr: Context; utf8: string) = proc textPath*(cr: Context; utf8: string) =
cairo_text_path(cr.impl, utf8) cairo_text_path(cr.impl, utf8)
@ -1167,11 +981,6 @@ proc status*(fontFace: FontFace): Status =
# #
#const getStatus* = status # does not compile #const getStatus* = status # does not compile
type
FontType* {.size: sizeof(cint), pure.} = enum
toy, ft, win32,
quartz, user
proc cairo_font_face_get_type*(fontFace: ptr FontFace00): FontType {.importc, libcairo.} proc cairo_font_face_get_type*(fontFace: ptr FontFace00): FontType {.importc, libcairo.}
# #
proc getType*(fontFace: FontFace): FontType = proc getType*(fontFace: FontFace): FontType =
@ -1235,7 +1044,7 @@ proc cairo_scaled_font_text_to_glyphs*(scaled_font: ptr Scaled_font00; x, y: cdo
proc cairo_scaled_font_get_font_face*(scaled_font: ptr ScaledFont00): ptr FontFace00 {.importc, libcairo.} proc cairo_scaled_font_get_font_face*(scaled_font: ptr ScaledFont00): ptr FontFace00 {.importc, libcairo.}
# #
proc getFontFace*(scaledFont: ScaledFont): FontFace = proc getFontFace*(scaledFont: ScaledFont): FontFace =
let h =cairo_scaled_font_get_font_face(scaledFont.impl) let h = cairo_scaled_font_get_font_face(scaledFont.impl)
let d = cairo_font_face_get_user_data(h, NUDK) let d = cairo_font_face_get_user_data(h, NUDK)
if d.isNil: if d.isNil:
assert false # may this happen? assert false # may this happen?
@ -1502,8 +1311,6 @@ proc cairo_surface_get_user_data*(surface: ptr Surface00; key: ptr UserDataKey):
proc getUserData*(surface: Surface; key: ptr UserDataKey): pointer = proc getUserData*(surface: Surface; key: ptr UserDataKey): pointer =
cairo_surface_get_user_data(surface.impl, key) cairo_surface_get_user_data(surface.impl, key)
proc cairo_get_target*(cr: ptr Context00): ptr Surface00 {.importc, libcairo.} proc cairo_get_target*(cr: ptr Context00): ptr Surface00 {.importc, libcairo.}
# #
proc getTarget*(cr: Context): Surface = proc getTarget*(cr: Context): Surface =
@ -1580,12 +1387,6 @@ proc devicReference*(device: Device): Device =
discard cairo_device_reference(device.impl) discard cairo_device_reference(device.impl)
return device return device
type
DeviceType* {.size: sizeof(cint), pure.} = enum
invalid = - 1, drm, gl,
script, xcb, xlib,
xml, cogl, win32
proc cairo_device_get_type*(device: ptr Device00): DeviceType {.importc, libcairo.} proc cairo_device_get_type*(device: ptr Device00): DeviceType {.importc, libcairo.}
# #
proc getType*(device: Device): DeviceType = proc getType*(device: Device): DeviceType =
@ -1747,19 +1548,6 @@ proc status*(surface: Surface): Status =
# #
#const getStatus* = status #const getStatus* = status
type
SurfaceType* {.size: sizeof(cint), pure.} = enum
image, pdf, ps,
xlib, xcb, glitz,
quartz, win32, beos,
directfb, svg, os2,
win32_printing, quartz_image,
script, qt,
recording, vg, gl,
drm, tee, xml,
skia, subsurface,
cogl
proc cairo_surface_get_type*(surface: ptr Surface00): SurfaceType {.importc, libcairo.} proc cairo_surface_get_type*(surface: ptr Surface00): SurfaceType {.importc, libcairo.}
# #
proc getType*(surface: Surface): SurfaceType = proc getType*(surface: Surface): SurfaceType =
@ -1948,9 +1736,9 @@ when CAIRO_HAS_PNG_FUNCTIONS:
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: Rectangle00): ptr Surface00 {.importc, libcairo.} proc cairo_recording_surface_create*(content: Content; extents: Rectangle): ptr Surface00 {.importc, libcairo.}
# #
proc recordingSurfaceCreate*(content: Content; extents: Rectangle00): Surface = proc recordingSurfaceCreate*(content: Content; extents: Rectangle): Surface =
new(result, destroy) new(result, destroy)
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)
@ -1965,9 +1753,9 @@ proc recordingSurfaceInkExtents*(surface: Surface; x0, y0, width, height: var fl
width = width0.float width = width0.float
height = height0.float height = height0.float
proc cairo_recording_surface_get_extents*(surface: ptr Surface00; extents: Rectangle00): Bool00 {.importc, libcairo.} proc cairo_recording_surface_get_extents*(surface: ptr Surface00; extents: Rectangle): Bool00 {.importc, libcairo.}
# #
proc recordingSurfaceGetExtents*(surface: Surface; extents: Rectangle00): bool = proc recordingSurfaceGetExtents*(surface: Surface; extents: Rectangle): bool =
cairo_recording_surface_get_extents(surface.impl, extents).bool cairo_recording_surface_get_extents(surface.impl, extents).bool
type type
@ -2001,7 +1789,7 @@ proc patternCreateRasterSource*(userData: pointer; content: Content; width, heig
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)
proc cairo_raster_source_pattern_set_callback_data*(pattern: ptr Pattern00; data: pointer) {.importc,libcairo.} proc cairo_raster_source_pattern_set_callback_data*(pattern: ptr Pattern00; data: pointer) {.importc, libcairo.}
# #
proc rasterSourcePatternSetCallbackData*(pattern: Pattern; data: pointer) = proc rasterSourcePatternSetCallbackData*(pattern: Pattern; data: pointer) =
cairo_raster_source_pattern_set_callback_data(pattern.impl, data) cairo_raster_source_pattern_set_callback_data(pattern.impl, data)
@ -2095,19 +1883,11 @@ proc patternCreateMesh*(): Pattern =
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)
proc cairo_pattern_status*(pattern: ptr Pattern00): Status {.importc, libcairo.} proc cairo_pattern_status*(pattern: ptr Pattern00): Status {.importc, libcairo.}
# #
proc status*(pattern: Pattern): Status = proc status*(pattern: Pattern): Status =
cairo_pattern_status(pattern.impl) cairo_pattern_status(pattern.impl)
type
PatternType* {.size: sizeof(cint), pure.} = enum
solid, surface,
linear, radial, mesh,
raster_source
proc cairo_pattern_get_type*(pattern: ptr Pattern00): PatternType {.importc, libcairo.} proc cairo_pattern_get_type*(pattern: ptr Pattern00): PatternType {.importc, libcairo.}
# #
proc getType*(pattern: Pattern): PatternType = proc getType*(pattern: Pattern): PatternType =
@ -2175,10 +1955,6 @@ proc cairo_pattern_get_matrix*(pattern: ptr Pattern00; matrix: var Matrix) {.imp
proc patternGetMatrix*(pattern: Pattern; matrix: var Matrix) = proc patternGetMatrix*(pattern: Pattern; matrix: var Matrix) =
cairo_pattern_get_matrix(pattern.impl, matrix) cairo_pattern_get_matrix(pattern.impl, matrix)
type
Extend* {.size: sizeof(cint), pure.} = enum
none, repeat, reflect, pad
proc cairo_pattern_set_extend*(pattern: ptr Pattern00; extend: Extend) {.importc, libcairo.} proc cairo_pattern_set_extend*(pattern: ptr Pattern00; extend: Extend) {.importc, libcairo.}
# #
proc setExtend*(pattern: Pattern; extend: Extend) = proc setExtend*(pattern: Pattern; extend: Extend) =
@ -2191,11 +1967,6 @@ proc cairo_pattern_get_extend*(pattern: ptr Pattern00): Extend {.importc, libcai
proc getExtend*(pattern: Pattern): Extend = proc getExtend*(pattern: Pattern): Extend =
cairo_pattern_get_extend(pattern.impl) cairo_pattern_get_extend(pattern.impl)
type
Filter* {.size: sizeof(cint), pure.} = enum
fast, good, best, nearest,
bilinear, gaussian
proc cairo_pattern_set_filter*(pattern: ptr Pattern00; filter: Filter) {.importc, libcairo.} proc cairo_pattern_set_filter*(pattern: ptr Pattern00; filter: Filter) {.importc, libcairo.}
# #
proc setFilter*(pattern: Pattern; filter: Filter) = proc setFilter*(pattern: Pattern; filter: Filter) =
@ -2348,8 +2119,8 @@ proc rotate*(matrix: var Matrix; radians: float) =
proc cairo_matrix_invert*(matrix: var Matrix): Status {.importc, libcairo.} proc cairo_matrix_invert*(matrix: var Matrix): Status {.importc, libcairo.}
# #
const invert* = cairo_matrix_invert const invert* = cairo_matrix_invert
#proc invert*(matrix: var Matrix): Status = #proc invert*(matrix: var Matrix): Status =
# cairo_matrix_invert(matrix) # cairo_matrix_invert(matrix)
proc cairo_matrix_multiply*(result: var Matrix; a: Matrix; b: Matrix) {.importc, libcairo.} proc cairo_matrix_multiply*(result: var Matrix; a: Matrix; b: Matrix) {.importc, libcairo.}
# #
@ -2371,10 +2142,6 @@ proc transformPoint*(matrix: var Matrix; x, y: var float) =
x = x0 x = x0
y = y0 y = y0
type
RegionOverlap* {.size: sizeof(cint), pure.} = enum
`in`, `out`, part
proc cairo_region_destroy*(region: ptr Region00) {.importc, libcairo.} proc cairo_region_destroy*(region: ptr Region00) {.importc, libcairo.}
# #
proc destroy*(region: Region) = proc destroy*(region: Region) =
@ -2507,7 +2274,7 @@ when CAIRO_HAS_PDF_SURFACE:
v1_4, v1_5 v1_4, v1_5
proc cairo_pdf_surface_create*(filename: cstring; widthInPoints, heightInPoints: cdouble): ptr Surface00 {. proc cairo_pdf_surface_create*(filename: cstring; widthInPoints, heightInPoints: cdouble): ptr Surface00 {.
importc, libcairo.} importc, libcairo.}
#pong
proc pdfSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface = proc pdfSurfaceCreate*(filename: string; widthInPoints, heightInPoints: float): Surface =
new(result, destroy) new(result, destroy)
result.impl = cairo_pdf_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble) result.impl = cairo_pdf_surface_create(filename, widthInPoints.cdouble, heightInPoints.cdouble)
@ -2835,5 +2602,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
# 2851 lines # 2605 lines

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
# 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.5.5 2019-SEP-21 # v 0.6.0 2019-OCT-28
# (c) S. Salewski 2018 # (c) S. Salewski 2018
# https://wiki.gnome.org/Projects/GObjectIntrospection # https://wiki.gnome.org/Projects/GObjectIntrospection
@ -23,17 +23,15 @@
# Known gobject-introspection related issues: # Known gobject-introspection related issues:
# - gFieldInfoGetSize() is always zero, so we have no bitfield support yet. # - gFieldInfoGetSize() is always zero, so we have no bitfield support yet.
# - ParamSpec is reported as object, but has no parent # - ParamSpec is reported as object, but has no parent # not really a bug, gst has more gobjects without parent
# - gBaseInfoGetName() is "" for g_iconv() #XXX fixed # - gBaseInfoGetName() is "" for g_iconv() #XXX fixed
# - dirSep is wrong for unix -- that is an already reported gi bug # - dirSep is wrong for unix -- that is an already reported gi bug
# - well there are more than 140 open issues about gobject introspection in gnome bugzilla :-( # - well there are more than 140 open issues about gobject introspection in gnome bugzilla :-(
# -
# This module is really ugly currently -- the first goal was to get a working gi solution # This module is really ugly currently -- the first goal was to get a working gi solution
from os import `/`, paramCount from os import `/`, paramCount
import gir import gir, gobject, glib
import glib
import strutils import strutils
import sequtils import sequtils
import streams import streams
@ -50,10 +48,10 @@ template isFunctionInfo(info: untyped): untyped =
gBaseInfoGetType(info) == GIInfoType.Function gBaseInfoGetType(info) == GIInfoType.Function
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"
EM = "*" EM = "*"
RecSep = "!" # Record separator for entries in gisup.nim, also defined in gimpl.nim RecSep = "!" # Record separator for entries in gisup.nim, also defined in gimpl.nim
UnnamedArrayCandidates = ["uint8", "int32", "uint32"] UnnamedArrayCandidates = ["uint8", "int32", "uint32"]
UnnamedArrays = UnnamedArrayCandidates.mapIt(it & "Array") UnnamedArrays = UnnamedArrayCandidates.mapIt(it & "Array")
NamedArrays = ["TargetEntry00Array", "PageRangeArray", "KeymapKeyArray"] NamedArrays = ["TargetEntry00Array", "PageRangeArray", "KeymapKeyArray"]
@ -76,16 +74,16 @@ int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64
proc unCap(s: var string) = proc unCap(s: var string) =
s[0] = s[0].toLowerAscii s[0] = s[0].toLowerAscii
proc unCap(s: string): string =
result = s
result[0] = result[0].toLowerAscii
proc firstPart(s: var string) = proc firstPart(s: var string) =
while s.len > 0 and s[^1].isLowerAscii: while s.len > 0 and s[^1].isLowerAscii:
s.setLen(s.len - 1) s.setLen(s.len - 1)
assert(s.len > 1) assert(s.len > 1)
s.setLen(s.len - 1) s.setLen(s.len - 1)
proc unCap(s: string): string =
result = s
result[0] = result[0].toLowerAscii
proc startsWith(s: string; x: varargs[string]): bool = proc startsWith(s: string; x: varargs[string]): bool =
for i in x: for i in x:
if s.startsWith(i): if s.startsWith(i):
@ -108,6 +106,13 @@ proc cut(s: var StringStream; pos: int) =
s.data.setLen(pos) s.data.setLen(pos)
s.setPosition(pos) s.setPosition(pos)
proc myCamelToSnake(s: cstring): string =
result.add(s[0].toLowerAscii)
for i in 1 .. s.high:
if s[i].isUpperAscii and not s[i - 1].isUpperAscii:
result.add('_')
result.add(s[i].toLowerAscii)
proc mysnakeToCamel(s: cstring): string = proc mysnakeToCamel(s: cstring): string =
var i, j: int var i, j: int
result = newString(s.len) result = newString(s.len)
@ -164,10 +169,10 @@ var ISGTK3: bool
var suppressType = false var suppressType = false
var suppressRaise = false var suppressRaise = false
fixedDestroyNames.add("gdk_window_create_similar_surface", "cairo.destroy") # fixedDestroyNames.add("gdk_window_create_similar_surface", "cairo.destroy")
fixedDestroyNames.add("gdk_window_create_similar_image_surface", "cairo.destroy") # fixedDestroyNames.add("gdk_window_create_similar_image_surface", "cairo.destroy")
fixedDestroyNames.add("gdk_cairo_region_create_from_surface", "cairo.destroy") # fixedDestroyNames.add("gdk_cairo_region_create_from_surface", "cairo.destroy")
fixedDestroyNames.add("gdk_cairo_surface_create_from_pixbuf", "cairo.destroy") # fixedDestroyNames.add("gdk_cairo_surface_create_from_pixbuf", "cairo.destroy")
fixedProcNames.add("gtk_button_new_with_label", "newButton") fixedProcNames.add("gtk_button_new_with_label", "newButton")
fixedProcNames.add("pango_font_description_from_string", "newFontDescription") fixedProcNames.add("pango_font_description_from_string", "newFontDescription")
@ -190,6 +195,7 @@ fixedProcNames.add("gsk_shadow_node_get_child", "shadowNodeGetChild")
fixedProcNames.add("gsk_transform_node_get_child", "transformNodeGetChild") fixedProcNames.add("gsk_transform_node_get_child", "transformNodeGetChild")
fixedProcNames.add("gtk_settings_get_for_display", "getSettingsForDisplay") fixedProcNames.add("gtk_settings_get_for_display", "getSettingsForDisplay")
fixedProcNames.add("gtk_icon_theme_get_for_display", "getIconThemeForDisplay") fixedProcNames.add("gtk_icon_theme_get_for_display", "getIconThemeForDisplay")
fixedProcNames.add("gst_element_factory_find", "findElementFactory")
defaultParameters.add("gtk_window_new", "`type` WindowType WindowType.toplevel") defaultParameters.add("gtk_window_new", "`type` WindowType WindowType.toplevel")
defaultParameters.add("gtk_application_new", "flags gio.ApplicationFlags {}") defaultParameters.add("gtk_application_new", "flags gio.ApplicationFlags {}")
@ -317,6 +323,9 @@ graphene.Matrix
graphene.Plane graphene.Plane
graphene.Ray graphene.Ray
graphene.Euler graphene.Euler
#cairo.Matrix
cairo.Rectangle
cairo.RectangleInt
""".split.toHashSet """.split.toHashSet
type type
@ -366,7 +375,7 @@ proc genRec(t: GITypeInfo; genProxy = false; fullQualified: bool = false): (stri
child = mangleType(mangleName(child)) child = mangleType(mangleName(child))
if arrayFixedSize != -1: if arrayFixedSize != -1:
result[0] = "array[$1, $2]" % [$arrayFixedSize, child] result[0] = "array[$1, $2]" % [$arrayFixedSize, child]
elif g_type_info_is_zero_terminated(t): elif gTypeInfoIsZeroTerminated(t):
result[0] = child & "Array" result[0] = child & "Array"
result[1] = intA0 result[1] = intA0
return return
@ -450,7 +459,7 @@ proc ct3nt(s: string): string =
of "TargetEntry00Array": "targetEntryArrayToSeq" of "TargetEntry00Array": "targetEntryArrayToSeq"
of "KeymapKeyArray": "keymapKeyArrayToSeq" of "KeymapKeyArray": "keymapKeyArrayToSeq"
of "PageRangeArray": "pageRangeArrayToSeq" of "PageRangeArray": "pageRangeArrayToSeq"
else: ct2nt.getOrDefault(s, s) else: ct2nt.getOrDefault(s, s)
proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): ( proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
string, string, TableRef[string, string], string, string) = string, string, TableRef[string, string], string, string) =
@ -504,8 +513,8 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
let t = gArgInfoGetType(arg) let t = gArgInfoGetType(arg)
let mayBeNil = gArgInfoMayBeNull(arg) let mayBeNil = gArgInfoMayBeNull(arg)
var str = genRec(t, genProxy and not gArgInfoIsCallerAllocates(arg))[0] var str = genRec(t, genProxy and not gArgInfoIsCallerAllocates(arg))[0]
if (str in UnnamedArrays or str in NamedArrays) and genProxy and not g_type_info_is_zero_terminated(t): if (str in UnnamedArrays or str in NamedArrays) and genProxy and not gTypeInfoIsZeroTerminated(t):
resusLen = g_type_info_get_array_length(t) resusLen = gTypeInfoGetArrayLength(t)
if resusLen >= 0: if resusLen >= 0:
resusIn = gArgInfoGetDirection(gCallableInfoGetArg(info, resusLen.cint)) == GIDirection.IN resusIn = gArgInfoGetDirection(gCallableInfoGetArg(info, resusLen.cint)) == GIDirection.IN
lastName = gBaseInfoGetName(arg) lastName = gBaseInfoGetName(arg)
@ -570,7 +579,7 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
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]
if gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT} and not (str in UnnamedArrays and gArgInfoIsCallerAllocates(arg)): if gArgInfoGetDirection(arg) in {GIDirection.OUT, INOUT} and not (str in UnnamedArrays and gArgInfoIsCallerAllocates(arg)):
str.insert("var ") str.insert("var ")
if genProxy and defaultParameters.contains(sym): if genProxy and defaultParameters.contains(sym):
var h1, h2, h3: string var h1, h2, h3: string
(h1, h2, h3) = defaultParameters[sym].split (h1, h2, h3) = defaultParameters[sym].split
@ -598,7 +607,7 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
else: else:
str = "openArray[string]" str = "openArray[string]"
if str == "seq[uint8]": # allow to pass a string for a seq[uint8] argument too if str == "seq[uint8]": # allow to pass a string for a seq[uint8] argument too
str = "seq[uint8] | string" str = "seq[uint8] | string"
resus.add((name, str)) resus.add((name, str))
if j < m: if j < m:
arglist.add(", ") arglist.add(", ")
@ -607,8 +616,8 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
arglist.add(')') arglist.add(')')
var ret = gCallableInfoGetReturnType(info) var ret = gCallableInfoGetReturnType(info)
assert(ret != nil) assert(ret != nil)
if resusLen < 0 and not g_type_info_is_zero_terminated(ret): if resusLen < 0 and not gTypeInfoIsZeroTerminated(ret):
resusLen = g_type_info_get_array_length(ret) resusLen = gTypeInfoGetArrayLength(ret)
if isFunctionInfo(info): if isFunctionInfo(info):
if (gFunctionInfoGetFlags(info).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0: if (gFunctionInfoGetFlags(info).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0:
let h = gBaseInfoGetContainer(info) let h = gBaseInfoGetContainer(info)
@ -624,7 +633,7 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
arrLex = " let $1 = $2($3.len)\n" % [resus[resusLen][0], h, lastName] arrLex = " let $1 = $2($3.len)\n" % [resus[resusLen][0], h, lastName]
resus.delete(resusLen) resus.delete(resusLen)
else: else:
arrLex = ""#"#??\n" arrLex = "" #"#??\n"
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)
var r = genRec(ret, genProxy)[0] var r = genRec(ret, genProxy)[0]
@ -644,11 +653,11 @@ proc genPars(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (
arrLex = " let $1 = $2($3.len)\n" % [resus[resusLen][0], h, lastName] arrLex = " let $1 = $2($3.len)\n" % [resus[resusLen][0], h, lastName]
resus.delete(resusLen) resus.delete(resusLen)
else: else:
arrLex = ""#"#??\n" arrLex = "" #"#??\n"
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) = proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) = # module
template gobjectTemp(): untyped = template gobjectTemp(): untyped =
assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, EVERYTHING}) # both occur assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.NOTHING, EVERYTHING}) # both occur
@ -669,7 +678,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)") methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)")
methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))") methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))")
template findFreeProc(): untyped = # prefer gboxed_free() but fall back for GVariant
template findFreeProc(info: GIBaseInfo): untyped =
if gBaseInfoGetType(info) == GIInfoType.UNION: if gBaseInfoGetType(info) == GIInfoType.UNION:
freeMe = gUnionInfoFindMethod(info, "free") freeMe = gUnionInfoFindMethod(info, "free")
if freeMe.isNil: if freeMe.isNil:
@ -682,11 +692,23 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
if freeMe == nil: if freeMe == nil:
if fixedDestroyNames.contains(sym): if fixedDestroyNames.contains(sym):
freeMeName = fixedDestroyNames[sym] freeMeName = fixedDestroyNames[sym]
else:
echo "Caution: No free/unref found for ", ' ', " (", sym, ')' # Mostly missing cairo functions...
else: else:
assert (not fixedDestroyNames.contains(sym)) assert (not fixedDestroyNames.contains(sym))
freeMeName = $gBaseInfoGetName(freeMe) 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:
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(isCallableInfo(mInfo)) assert(isCallableInfo(mInfo))
assert(isFunctionInfo(mInfo)) assert(isFunctionInfo(mInfo))
@ -704,6 +726,13 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
# The following functions work with arrays, we should check each carefully -- some may not compile... # The following functions work with arrays, we should check each carefully -- some may not compile...
#if sym == "g_io_channel_read_to_end": return # fix later #if sym == "g_io_channel_read_to_end": return # fix later
if sym == "g_boxed_free": return # this is manually added at early position already
if sym == "gst_param_spec_fraction": return # fix later
if sym == "gst_param_spec_array": return # fix later
if sym == "gst_message_new_state_changed": return # fix later
if sym == "gst_mini_object_replace": return # fix later
if sym == "gst_mini_object_take": return # fix later
if sym == "gst_object_replace": return # fix later
if sym == "g_base64_decode_inplace": return # fix later if sym == "g_base64_decode_inplace": return # fix later
if sym == "g_base64_encode_close": return # fix later if sym == "g_base64_encode_close": return # fix later
if sym == "g_base64_encode_step": return # fix later if sym == "g_base64_encode_step": return # fix later
@ -744,7 +773,8 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
"gtk_cell_area_class_find_cell_property"]: return "gtk_cell_area_class_find_cell_property"]: return
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 asym in ["get", "getDefault", "from", "fromString"]: if (moduleNameSpace == "gst" and asym in ["appendAndTakeValue", "appendValue", "getSize", "getValue", "prependValue"]) or
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()
@ -777,7 +807,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
# 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_timeout_add_full",
"g_type_from_name", "g_type_check_instance_is_a", "g_idle_add_full", "g_quark_try_string", "vte_regex_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"]:
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
@ -813,7 +843,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
assert replist.len == 0 # ok it's a fact for constructors, so we don't have to generate code for it assert replist.len == 0 # ok it's a fact for constructors, so we don't have to generate code for it
for j in 0.cint ..< gCallableInfoGetNArgs(minfo): for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
let arg = gCallableInfoGetArg(minfo, j) let arg = gCallableInfoGetArg(minfo, j)
assert gArgInfoGetDirection(arg) notin {GIDirection.OUT, INOUT} # so we can ignore this case! assert gArgInfoGetDirection(arg) notin {GIDirection.OUT, INOUT} # so we can ignore this case!
for i in 0 .. 1: # generate the new() and the init() proc for i in 0 .. 1: # generate the new() and the init() proc
var hhh = "\nproc " & asym & EM & plist var hhh = "\nproc " & asym & EM & plist
if i > 0: if i > 0:
@ -845,11 +875,14 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
assert info != nil assert info != nil
var freeMe: GIFunctionInfo var freeMe: GIFunctionInfo
var freeMeName: string var freeMeName: string
findFreeProc() var boxedFreeMeName: string
if sym == "g_closure_new_simple" or sym == "g_closure_new_object": findFreeProc(info)
freeMeName = "unref" # TODO GI bug? #if sym == "g_closure_new_simple" or sym == "g_closure_new_object":
# freeMeName = "unref" # TODO GI bug?
#assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING}) #assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING})
if freeMeName == "": if boxedFreeMeName != "":
methodBuffer.writeLine(" new(result, $1)" % boxedFreeMeName)
elif freeMeName == "":
methodBuffer.writeLine(" new(result)") methodBuffer.writeLine(" new(result)")
else: else:
methodBuffer.writeLine(" new(result, $1)" % freeMeName) methodBuffer.writeLine(" new(result, $1)" % freeMeName)
@ -880,19 +913,17 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
iface = gInterfaceInfoGetIfaceStruct(iface) iface = gInterfaceInfoGetIfaceStruct(iface)
methodBuffer.writeLine(" new(result, gobject.genericGObjectUnref)") methodBuffer.writeLine(" new(result, gobject.genericGObjectUnref)")
methodBuffer.writeLine(" result.impl = " & sym & arglist) methodBuffer.writeLine(" result.impl = " & sym & arglist)
elif gBaseInfoGetType(iface) == GIInfoType.OBJECT:
echo "XXXXXXXXXXXXXXXXX what shall we do? for ", sym
else: else:
let nMethods = gStructInfoGetNMethods(iface) assert(gBaseInfoGetType(iface) in {GIInfoType.STRUCT, GIInfoType.UNION})
var freeMeName: string var freeMeName: string
for j in 0.cint ..< nMethods: var freeMe: GIFunctionInfo
let h = $gBaseInfoGetName(gStructInfoGetMethod(iface, j)) var boxedFreeMeName: string
if h.endsWith("free"): findFreeProc(iface)
freeMeName = "free" if boxedFreeMeName != "":
break methodBuffer.writeLine(" new(result, $1)" % boxedFreeMeName)
elif h.endsWith("unref"): elif freeMeName == "":
freeMeName = "unref"
break
freeMeName = fixedDestroyNames.getOrDefault(sym, freeMeName)
if 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 "Caution: No free/unref found for ", ' ', gBaseInfoGetName(iface), " (", sym, ')'
methodBuffer.writeLine(" new(result)") methodBuffer.writeLine(" new(result)")
@ -912,8 +943,10 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
methodBuffer.write(arrLex) methodBuffer.write(arrLex)
methodBuffer.write(sss) methodBuffer.write(sss)
var freeMeName: string var freeMeName: string
var boxedFreeMeName: string
for j in 0.cint ..< gCallableInfoGetNArgs(minfo): for j in 0.cint ..< gCallableInfoGetNArgs(minfo):
freeMeName = "" freeMeName = ""
boxedFreeMeName = ""
let arg = gCallableInfoGetArg(minfo, j) let arg = gCallableInfoGetArg(minfo, j)
let t = gArgInfoGetType(arg) let t = gArgInfoGetType(arg)
if gArgInfoGetDirection(arg) == GIDirection.OUT and isProxyCandidate(t) and if gArgInfoGetDirection(arg) == GIDirection.OUT and isProxyCandidate(t) and
@ -928,9 +961,11 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
else: else:
let info = iface let info = iface
var freeMe: GIFunctionInfo var freeMe: GIFunctionInfo
findFreeProc() findFreeProc(info)
let h2 = mangleName(gBaseInfoGetName(arg)) let h2 = mangleName(gBaseInfoGetName(arg))
if freeMeName == "": if boxedFreeMeName != "":
methodBuffer.writeLine(" new(" & h2 & ", " & boxedFreeMeName & ")")
elif freeMeName == "":
methodBuffer.writeLine(" new(" & h2 & ")") methodBuffer.writeLine(" new(" & h2 & ")")
else: else:
methodBuffer.writeLine(" new(" & h2 & ", " & freeMeName & ")") methodBuffer.writeLine(" new(" & h2 & ", " & freeMeName & ")")
@ -1012,6 +1047,23 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo) =
delayedMethods.add((info, minfo)) delayedMethods.add((info, minfo))
methodBuffer.cut(p) methodBuffer.cut(p)
template genBoxedFree =
if not callerAlloc.contains(($gBaseInfoGetNamespace(info)).toLowerAscii & '.' & mangleName(gBaseInfoGetName(info))):
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE and gTypeFundamental(gRegisteredTypeInfoGetGType(info)) == G_TYPE_BOXED:
# For example, GVariant has a GType but is not a boxed type
#assert(g_type_fundamental(g_registered_type_info_get_g_type(info)) == G_TYPE_BOXED)
if gTypeFundamental(gRegisteredTypeInfoGetGType(info)) != G_TYPE_BOXED:
if gBaseInfoGetName(info) != "Variant":
echo moduleNamespace, gBaseInfoGetName(info)
assert false
output.writeLine("\nproc gBoxedFree" & $gRegisteredTypeInfoGetTypeName(info) & "*(self: " & mangleName(gBaseInfoGetName(info)) & ") =")
if moduleNameSpace == "cairo": # we may manually free cairo objects!
output.writeLine(" if self.impl != nil:")
output.writeLine(" boxedFree(", getTypeProc, "(), ", "cast[ptr " & mangleName(gBaseInfoGetName(info)) & "00](self.impl))")
output.writeLine(" self.impl = nil")
else:
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:
output.writeLine("type") output.writeLine("type")
@ -1028,6 +1080,15 @@ 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")
var getTypeProc: string
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
getTypeProc = $gRegisteredTypeInfoGetTypeInit(info)
if getTypeProc notin ["intern", "g_gstring_get_type"]:
output.write("\nproc " & getTypeProc & "*(): GType ")
output.writeLine("{.importc, " & libprag & ".}")
genBoxedFree()
var mseq: seq[GIFunctionInfo] var mseq: seq[GIFunctionInfo]
var freePos = -1 var freePos = -1
for j in 0.cint ..< gUnionInfoGetNMethods(info): for j in 0.cint ..< gUnionInfoGetNMethods(info):
@ -1094,7 +1155,7 @@ proc keymapKeyArrayToSeq(s: KeymapKeyArray; n: int): seq[KeymapKey] =
""" % [$StringArrayEntries] """ % [$StringArrayEntries]
proc writeStruct(info: GIStructInfo) = proc writeStruct(info: GIStructInfo) =
if g_struct_info_is_gtype_struct(info) and gBaseInfoGetName(info) != "ObjectClass": if gStructInfoIsGtypeStruct(info) and gBaseInfoGetName(info) != "ObjectClass":
return # we should not need the class and interface structs return # we should not need the class and interface structs
if gBaseInfoGetName(info).endsWith("Private"): # since v0.5.3 we do not write private structs if gBaseInfoGetName(info).endsWith("Private"): # since v0.5.3 we do not write private structs
return return
@ -1124,6 +1185,14 @@ 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")
var getTypeProc: string
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
getTypeProc = $gRegisteredTypeInfoGetTypeInit(info)
if getTypeProc notin ["intern", "g_gstring_get_type"]:
output.write("\nproc " & getTypeProc & "*(): GType ")
output.writeLine("{.importc, " & libprag & ".}")
genBoxedFree()
var mseq: seq[GIFunctionInfo] var mseq: seq[GIFunctionInfo]
var freePos = -1 var freePos = -1
for j in 0.cint ..< gStructInfoGetNMethods(info): for j in 0.cint ..< gStructInfoGetNMethods(info):
@ -1207,7 +1276,7 @@ proc writeInterface(info: GIInterfaceInfo) =
# write a few of the strange enum sets # write a few of the strange enum sets
proc writeModifierType(info: GIEnumInfo) = proc writeModifierType(info: GIEnumInfo) =
let we = gBaseInfoGetName(info) let we = gBaseInfoGetName(info)
assert(we in ["ModifierType", "EventMask", "AccelFlags", "AttachOptions"]) assert(we in ["ModifierType", "EventMask", "AccelFlags", "AttachOptions", "MessageType"])
type T = tuple[v: int64; n: string] type T = tuple[v: int64; n: string]
var s: seq[T] var s: seq[T]
var alias: seq[string] var alias: seq[string]
@ -1254,7 +1323,8 @@ proc writeModifierType(info: GIEnumInfo) =
writeMethod(info, minfo) writeMethod(info, minfo)
proc writeEnum(info: GIEnumInfo) = proc writeEnum(info: GIEnumInfo) =
if mangleName(gBaseInfoGetName(info)) in ["ModifierType", "EventMask", "AccelFlags", "AttachOptions"]: if mangleName(gBaseInfoGetName(info)) in ["ModifierType", "EventMask", "AccelFlags", "AttachOptions"] or
(moduleNameSpace == "gst" and mangleName(gBaseInfoGetName(info)) == "MessageType"):
writeModifierType(info) writeModifierType(info)
return return
type T = tuple[v: int64; n: string] type T = tuple[v: int64; n: string]
@ -1293,18 +1363,22 @@ proc writeEnum(info: GIEnumInfo) =
if flags and j == 0 and val == 0: continue if flags and j == 0 and val == 0: continue
if j > 0 and i.v == k.v: if j > 0 and i.v == k.v:
if i.n != k.n: if i.n != k.n:
alias.add(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & '.' & k.n) let h = if flags: "Flag" else: ""
alias.add(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & h & '.' & k.n)
continue continue
if flags: if flags:
val = countTrailingZeroBits(val) # firstSetBit(val) val = countTrailingZeroBits(val) # firstSetBit(val)
output.writeLine(" ", i.n, " = ", val) output.writeLine(" ", i.n, " = ", val)
k = i k = i
if flags:
output.writeLine("\n ", tname & "Flags" & EM, " {.size: sizeof(cint).} = set[$1Flag]" % [tname])
if alias.len > 0: if alias.len > 0:
output.writeLine("\nconst") output.writeLine("\nconst")
for i in alias: for i in alias:
output.writeLine(i) output.writeLine(i)
if flags:
output.writeLine("\n ", tname & "Flags" & EM, " {.size: sizeof(cint).} = set[$1Flag]" % [tname])
for j in 0.cint ..< gEnumInfoGetNMethods(info): for j in 0.cint ..< gEnumInfoGetNMethods(info):
let mInfo = gEnumInfoGetMethod(info, j) let mInfo = gEnumInfoGetMethod(info, j)
writeMethod(info, minfo) writeMethod(info, minfo)
@ -1320,7 +1394,8 @@ proc writeObj(info: GIObjectInfo) =
var ns: string var ns: string
var cnt: int var cnt: int
if parent.isNil: if parent.isNil:
assert(gBaseInfoGetName(info) == "Object" or gBaseInfoGetName(info) == "ParamSpec") #assert(gBaseInfoGetName(info) == "Object" or gBaseInfoGetName(info) == "ParamSpec")
#echo "??? ", gBaseInfoGetName(info)
oof = "{.inheritable, pure.} = object" oof = "{.inheritable, pure.} = object"
ns = "" ns = ""
pname = "" pname = ""
@ -1354,9 +1429,14 @@ proc writeObj(info: GIObjectInfo) =
discard mangleType(pname) discard mangleType(pname)
if mangleName(gBaseInfoGetName(info)) == "Object" and moduleNamespace == "gobject": if mangleName(gBaseInfoGetName(info)) == "Object" and moduleNamespace == "gobject":
discard discard
elif gBaseInfoGetName(info) == "ParamSpec": elif parent.isNil: # this is new for v0.6.0 with gstreamer support
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.write(" impl*: ptr ")
output.write(gBaseInfoGetName(info))
output.writeLine("00")
#elif gBaseInfoGetName(info) == "ParamSpec":
# output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of RootRef")
# output.writeLine(" impl*: ptr ParamSpec00")
else: else:
output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of " & ns & pname) output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of " & ns & pname)
if pname != "": pname.add("00") if pname != "": pname.add("00")
@ -1393,6 +1473,13 @@ proc writeObj(info: GIObjectInfo) =
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: T) =")
output.writeLine(" g_object_remove_toggle_ref(o.impl, toggleNotify, addr(o[]))") output.writeLine(" g_object_remove_toggle_ref(o.impl, toggleNotify, addr(o[]))")
var getTypeProc: string
if gRegisteredTypeInfoGetGType(info) != G_TYPE_NONE:
getTypeProc = $gRegisteredTypeInfoGetTypeInit(info)
if getTypeProc notin ["intern", "g_gstring_get_type"]:
output.write("\nproc " & getTypeProc & "*(): GType ")
output.writeLine("{.importc, " & libprag & ".}")
let numsig = info.gObjectInfoGetNSignals let numsig = info.gObjectInfoGetNSignals
if numsig > 0: signalbuffer.writeLine("") if numsig > 0: signalbuffer.writeLine("")
for j in 0.cint ..< numsig: for j in 0.cint ..< numsig:
@ -1431,13 +1518,13 @@ proc extractFromUnion(tag: GITypeTag; arg: GIArgumentObj): string =
of GITypeTag.UTF8: '"' & $arg.vstring & '"' of GITypeTag.UTF8: '"' & $arg.vstring & '"'
#of GITypeTag.FILENAME: $arg. #of GITypeTag.FILENAME: $arg.
#of GITypeTag.ARRAY: $arg. #of GITypeTag.ARRAY: $arg.
#of GITypeTag.INTERFACE: $arg. of GITypeTag.INTERFACE: """"INTERFCE (unsuported)""""
#of GITypeTag.GLIST: $arg. #of GITypeTag.GLIST: $arg.
#of GITypeTag.GSLIST: $arg. #of GITypeTag.GSLIST: $arg.
#of GITypeTag.GHASH: $arg. #of GITypeTag.GHASH: $arg.
#of GITypeTag.ERROR: $arg. #of GITypeTag.ERROR: $arg.
#of GITypeTag.UNICHAR: $arg. #of GITypeTag.UNICHAR: $arg.
else: "XXX" else: "XXX" & $tag
proc writeConst(info: GIConstantInfo) = proc writeConst(info: GIConstantInfo) =
var tg = "" var tg = ""
@ -1501,7 +1588,8 @@ proc processInfo(i: GIBaseInfo) =
elif gBaseInfoGetType(i) == GIInfoType.CONSTANT: elif gBaseInfoGetType(i) == GIInfoType.CONSTANT:
writeConst(i) writeConst(i)
elif gBaseInfoGetType(i) == GIInfoType.Boxed: elif gBaseInfoGetType(i) == GIInfoType.Boxed:
echo "gBaseInfoGetType(i) == GIInfoType.Boxed:" echo "gBaseInfoGetType(i) == GIInfoType.Boxed: ", gBaseInfoGetName(i)
# echo "++++++++ ", g_registered_type_info_get_g_type(i), g_registered_type_info_get_type_name(i)
else: else:
assert(false) assert(false)
@ -1526,88 +1614,6 @@ proc getView(builder: Builder; name: string): View =
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 completionContextGetType*(): GType {.importc: "gtk_source_completion_context_get_type", libprag.}
proc completionProviderGetType*(): GType {.importc: "gtk_source_completion_provider_get_type", libprag.}
proc completionWordsGetType*(): GType {.importc: "gtk_source_completion_words_get_type", libprag.}
proc bufferGetType*(): GType {.importc: "gtk_source_buffer_get_type", libprag.}
proc completionGetType*(): GType {.importc: "gtk_source_completion_get_type", libprag.}
proc completionInfoGetType*(): GType {.importc: "gtk_source_completion_info_get_type", libprag.}
proc completionItemGetType*(): GType {.importc: "gtk_source_completion_item_get_type", libprag.}
proc completionProposalGetType*(): GType {.importc: "gtk_source_completion_proposal_get_type", libprag.}
proc encodingGetType*(): GType {.importc: "gtk_source_encoding_get_type", libprag.}
proc fileGetType*(): GType {.importc: "gtk_source_file_get_type", libprag.}
proc fileLoaderGetType*(): GType {.importc: "gtk_source_file_loader_get_type", libprag.}
proc fileSaverGetType*(): GType {.importc: "gtk_source_file_saver_get_type", libprag.}
proc gutterGetType*(): GType {.importc: "gtk_source_gutter_get_type", libprag.}
proc gutterRendererGetType*(): GType {.importc: "gtk_source_gutter_renderer_get_type", libprag.}
proc gutterRendererTextGetType*(): GType {.importc: "gtk_source_gutter_renderer_text_get_type", libprag.}
proc gutterRendererPixbufGetType*(): GType {.importc: "gtk_source_gutter_renderer_pixbuf_get_type", libprag.}
proc languageGetType*(): GType {.importc: "gtk_source_language_get_type", libprag.}
proc languageManagerGetType*(): GType {.importc: "gtk_source_language_manager_get_type", libprag.}
proc viewGetType*(): GType {.importc: "gtk_source_view_get_type", libprag.}
proc mapGetType*(): GType {.importc: "gtk_source_map_get_type", libprag.}
proc markGetType*(): GType {.importc: "gtk_source_mark_get_type", libprag.}
proc markAttributesGetType*(): GType {.importc: "gtk_source_mark_attributes_get_type", libprag.}
proc printCompositorGetType*(): GType {.importc: "gtk_source_print_compositor_get_type", libprag.}
proc regionGetType*(): GType {.importc: "gtk_source_region_get_type", libprag.}
proc searchContextGetType*(): GType {.importc: "gtk_source_search_context_get_type", libprag.}
proc searchSettingsGetType*(): GType {.importc: "gtk_source_search_settings_get_type", libprag.}
proc spaceDrawerGetType*(): GType {.importc: "gtk_source_space_drawer_get_type", libprag.}
proc styleGetType*(): GType {.importc: "gtk_source_style_get_type", libprag.}
proc styleSchemeGetType*(): GType {.importc: "gtk_source_style_scheme_get_type", libprag.}
proc styleSchemeChooserGetType*(): GType {.importc: "gtk_source_style_scheme_chooser_get_type", libprag.}
proc styleSchemeChooserButtonGetType*(): GType {.importc: "gtk_source_style_scheme_chooser_button_get_type", libprag.}
proc styleSchemeChooserWidgetGetType*(): GType {.importc: "gtk_source_style_scheme_chooser_widget_get_type", libprag.}
proc styleSchemeManagerGetType*(): GType {.importc: "gtk_source_style_scheme_manager_get_type", libprag.}
proc tagGetType*(): GType {.importc: "gtk_source_tag_get_type", libprag.}
proc undoManagerGetType*(): GType {.importc: "gtk_source_undo_manager_get_type", libprag.}
proc completionWordsProposalGetType*(): GType {.importc: "gtk_source_completion_words_proposal_get_type", libprag.}
proc completionWordsLibraryGetType*(): GType {.importc: "gtk_source_completion_words_library_get_type", libprag.}
proc completionWordsBufferGetType*(): GType {.importc: "gtk_source_completion_words_buffer_get_type", libprag.}
# register the GObject types so builder can use them, see
# https://mail.gnome.org/archives/gtk-list/2015-March/msg00016.html
discard viewGetType()
discard completionInfoGetType()
discard styleSchemeChooserButtonGetType()
""" """
const GDK3_EPI = """ const GDK3_EPI = """
@ -1818,7 +1824,17 @@ proc main(namespace: string; version: cstring = nil) =
output.writeLine("type\n TypePlugin00Array* = pointer") output.writeLine("type\n TypePlugin00Array* = pointer")
output.writeLine("type\n uint32Array* = pointer") output.writeLine("type\n uint32Array* = pointer")
output.writeLine("type\n VaClosureMarshal* = pointer") output.writeLine("type\n VaClosureMarshal* = pointer")
output.writeLine("\nproc boxedFree*(boxedType: GType; boxed: pointer) {.")
output.writeLine(" importc: \"g_boxed_free\", libprag.}")
elif namespace == "GLib": elif namespace == "GLib":
# we need gobject.
let gobjectlibs = gi.gIrepositoryGetSharedLibrary("GObject")
var GobjectLib = if gobjectlibs.isNil: "" else: ($gobjectlibs).split(',', 2)[0]
output.writeLine("const GobjectLib* = \"$1\"" % GobjectLib)
output.writeLine("{.pragma: gobjectlibprag, cdecl, dynlib: GobjectLib.}")
output.writeLine("type\n GException* = object of Exception") output.writeLine("type\n GException* = object of Exception")
output.writeLine("type\n OptionEntry00Array* = pointer") output.writeLine("type\n OptionEntry00Array* = pointer")
output.writeLine("type\n GArray00* = pointer") output.writeLine("type\n GArray00* = pointer")
@ -1860,6 +1876,9 @@ proc main(namespace: string; version: cstring = nil) =
output.writeLine("const GFalse* = gboolean(0)") output.writeLine("const GFalse* = gboolean(0)")
output.writeLine("const GTrue* = gboolean(1)") output.writeLine("const GTrue* = gboolean(1)")
output.writeLine("\nproc boxedFree(boxedType: GType; boxed: pointer) {.")
output.writeLine(" importc: \"g_boxed_free\", gobjectlibprag.}")
output.writeLine(""" output.writeLine("""
proc int32ArrayZT2seq*(p: pointer): seq[int32] = proc int32ArrayZT2seq*(p: pointer): seq[int32] =
let a = cast[ptr UncheckedArray[int32]](p) let a = cast[ptr UncheckedArray[int32]](p)
@ -1927,6 +1946,9 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
elif namespace == "Atk": elif namespace == "Atk":
output.writeLine("type\n StateTypeArray* = pointer") # enums! output.writeLine("type\n StateTypeArray* = pointer") # enums!
output.writeLine("type\n TextRange00Array* = pointer") output.writeLine("type\n TextRange00Array* = pointer")
elif namespace == "cairo":
output.writeLine("\nfrom gobject import boxedFree")
output.writeLine("from glib import GType")
elif namespace == "Pango": elif namespace == "Pango":
output.writeLine("type\n GlyphInfo00Array* = pointer") output.writeLine("type\n GlyphInfo00Array* = pointer")
output.writeLine("type\n LogAttr00Array* = pointer") output.writeLine("type\n LogAttr00Array* = pointer")
@ -1965,6 +1987,8 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
elif namespace == "Vte": elif namespace == "Vte":
output.writeLine("import glib\n") output.writeLine("import glib\n")
output.writeLine("type\n Regex00Array* = pointer") output.writeLine("type\n Regex00Array* = pointer")
elif namespace == "Gst":
output.writeLine("type\n FormatArray* = pointer")
if namespace == "GObject": if namespace == "GObject":
output.writeLine("\nimport times") output.writeLine("\nimport times")
output.writeLine("var qt = \"NGIQ\" & $epochTime()") output.writeLine("var qt = \"NGIQ\" & $epochTime()")
@ -2122,7 +2146,7 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
suppressType = false suppressType = false
methodBuffer = newStringStream() methodBuffer = newStringStream()
var h = delayedMethods var h = delayedMethods
delayedMethods= newSeq[(GIBaseInfo, GIFunctionInfo)]() delayedMethods = newSeq[(GIBaseInfo, GIFunctionInfo)]()
for el in h: for el in h:
writeMethod(el[0], el[1]) writeMethod(el[0], el[1])
output.write(methodBuffer.data) output.write(methodBuffer.data)
@ -2136,6 +2160,16 @@ proc uint8ArrayZT2seq*(p: pointer): seq[uint8] =
for i in externInterfaces: for i in externInterfaces:
output.writeLine("") output.writeLine("")
output.writeLine(i) output.writeLine(i)
if namespace == "Gst":
output.write(
"""
proc init* =
var argc: int32 = 0
var argv: cstringArray = nil
gst_init(argc, argv)
""")
if namespace == "Gtk": if namespace == "Gtk":
if ISGTK3: if ISGTK3:
output.write( output.write(
@ -2145,6 +2179,7 @@ proc init* =
var argv: cstringArray = nil var argv: cstringArray = nil
gtk_init(argc, argv) gtk_init(argc, argv)
""") """)
output.write(GTK_EPI) output.write(GTK_EPI)
if ISGTK3: if ISGTK3:
output.write("include gisup3\n") output.write("include gisup3\n")
@ -2157,8 +2192,9 @@ proc init* =
output.write( output.write(
""" """
proc get$1*(builder: Builder; name: string): $1 = proc get$1*(builder: Builder; name: string): $1 =
let gt = g_type_from_name("Gtk$1") #let gt = g_type_from_name("Gtk$1") # this worked also!
assert(gt != 0) let gt = $2
assert(gt != g_type_invalid_get_type())
let gobj = gtk_builder_get_object(cast[ptr Builder00](builder.impl), name) let gobj = gtk_builder_get_object(cast[ptr Builder00](builder.impl), name)
if g_object_get_qdata(gobj, Quark) != nil: if g_object_get_qdata(gobj, Quark) != nil:
result = cast[type(result)](g_object_get_qdata(gobj, Quark)) result = cast[type(result)](g_object_get_qdata(gobj, Quark))
@ -2171,10 +2207,39 @@ proc get$1*(builder: Builder; name: string): $1 =
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]) """ % [i, "gtk_" & myCamelToSnake(i) & "_get_type()"])
output.write("") output.write("")
if namespace == "Gio": if namespace == "Gio":
output.write(GIO_EPI) output.write(GIO_EPI)
if namespace == "cairo":
output.write("include cairoimpl\n")
if namespace == "GObject":
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_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_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_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_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_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_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_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_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_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_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_variant_get_type*(): GType = g_type_from_name(\"GVariant\")")
if namespace == "Gdk": if namespace == "Gdk":
if ISGTK3: if ISGTK3:
output.write(GDK3_EPI) output.write(GDK3_EPI)
@ -2202,7 +2267,9 @@ proc launch() =
# as typelib does not support reloading, we have to generate all libs twice # as typelib does not support reloading, we have to generate all libs twice
# note cairo is handcrafted! # note cairo is handcrafted!
if ISGTK3: if ISGTK3:
echo "Generating bindings for GTK3..."
main("Gtk", "3.0") # the 3 new 4.0 releases in old version main("Gtk", "3.0") # the 3 new 4.0 releases in old version
main("Gdk", "3.0") main("Gdk", "3.0")
main("GdkX11", "3.0") main("GdkX11", "3.0")
@ -2224,7 +2291,11 @@ proc launch() =
main("xlib") main("xlib")
main("Vte") main("Vte")
main("Notify") main("Notify")
main("Gst")
main("cairo")
else: else:
echo "First we try generating bindings for GTK4, this may fail when GTK4 is not properly installed"
echo "on your computer. But don't worry, you can still use GTK3"
main("Gtk", "4.0") # the 3 new 4.0 releases main("Gtk", "4.0") # the 3 new 4.0 releases
main("Gdk", "4.0") main("Gdk", "4.0")
main("GdkX11", "4.0") main("GdkX11", "4.0")
@ -2246,6 +2317,8 @@ proc launch() =
main("xlib") main("xlib")
# main("Vte") # not yet available for GTK4 # main("Vte") # not yet available for GTK4
main("Notify") main("Notify")
main("Gst")
main("cairo")
if ISGTK3: if ISGTK3:
supmod3.writeLine(" ]") supmod3.writeLine(" ]")
@ -2263,5 +2336,4 @@ proc launch() =
supmod4.close supmod4.close
launch() launch()
# 2264 lines # 2339 lines