From 765ecaf9cc15ff6e76b09f11aab47e14a7fa6f97 Mon Sep 17 00:00:00 2001 From: Stefan Salewski Date: Wed, 30 Aug 2017 12:10:19 +0200 Subject: [PATCH] release v0.2 --- README.adoc | 2 +- examples/app0.nim | 2 +- examples/button.nim | 2 +- examples/connect_args.nim | 2 +- examples/count_button.nim | 2 +- examples/label.nim | 2 +- examples/t0.nim | 2 +- gintro.nimble | 2 +- gintro/cairo.nim | 1465 +++++++++++++++++++++++++++++++++++++ gintro/gimpl.nim | 137 ++++ tests/gen.nim | 211 ++++-- tests/gen.nim.oldv0.1 | 1297 ++++++++++++++++++++++++++++++++ 12 files changed, 3048 insertions(+), 78 deletions(-) create mode 100644 gintro/cairo.nim create mode 100644 gintro/gimpl.nim create mode 100644 tests/gen.nim.oldv0.1 diff --git a/README.adoc b/README.adoc index c58ffac..a97c752 100644 --- a/README.adoc +++ b/README.adoc @@ -1,6 +1,6 @@ = High level GTK3 bindings for the Nim programming language (c) Stefan Salewski -//Version 0.1 2017 +//Version 0.2 2017 :experimental: :imagesdir: http://ssalewski.de/tmp :source-highlighter: pygments diff --git a/examples/app0.nim b/examples/app0.nim index 1c5d124..7cea5ad 100644 --- a/examples/app0.nim +++ b/examples/app0.nim @@ -1,6 +1,6 @@ # app0.nim -- minimal application style example # nim c app0.nim -import gintro/gtk +import gintro/[gtk, glib, gobject] import gintro/gio except Application, newApplication # we want to use GTK application #from gintro/gio import ApplicationFlags, scActivate, run diff --git a/examples/button.nim b/examples/button.nim index d49509f..d21b98d 100644 --- a/examples/button.nim +++ b/examples/button.nim @@ -1,5 +1,5 @@ # nim c button.nim -import gintro/[gtk, glib] +import gintro/[gtk, glib, gobject] import gintro/gio except Application, newApplication proc buttonClicked (button: Button) = diff --git a/examples/connect_args.nim b/examples/connect_args.nim index 8e077dc..958d4a7 100644 --- a/examples/connect_args.nim +++ b/examples/connect_args.nim @@ -1,5 +1,5 @@ # nim c connect_args.nim -import gintro/[gtk, glib] +import gintro/[gtk, glib, gobject] import gintro/gio except Application, newApplication type diff --git a/examples/count_button.nim b/examples/count_button.nim index 6735456..79c2a00 100644 --- a/examples/count_button.nim +++ b/examples/count_button.nim @@ -1,5 +1,5 @@ # nim c count_button.nim -import gintro/[gtk, glib] +import gintro/[gtk, glib, gobject] import gintro/gio except Application, newApplication type diff --git a/examples/label.nim b/examples/label.nim index 91df957..1ae3bc5 100644 --- a/examples/label.nim +++ b/examples/label.nim @@ -1,5 +1,5 @@ # nim c label.nim -import gintro/[gtk, glib] +import gintro/[gtk, glib, gobject] import gintro/gio except Application, newApplication proc activate(app: Application) = diff --git a/examples/t0.nim b/examples/t0.nim index f1236bd..639833a 100644 --- a/examples/t0.nim +++ b/examples/t0.nim @@ -1,5 +1,5 @@ # nim c t0.nim -import gintro/gtk +import gintro/[gtk, gobject] proc bye(w: Window) = mainQuit() diff --git a/gintro.nimble b/gintro.nimble index 26e8385..69bd0d0 100644 --- a/gintro.nimble +++ b/gintro.nimble @@ -1,6 +1,6 @@ # Package -version = "0.1.0" +version = "0.2.0" author = "Stefan Salewski" description = "High level GObject-Introspection based GTK3 bindings" license = "MIT" diff --git a/gintro/cairo.nim b/gintro/cairo.nim new file mode 100644 index 0000000..b228352 --- /dev/null +++ b/gintro/cairo.nim @@ -0,0 +1,1465 @@ +{.deadCodeElim: on.} + +when defined(windows): + const LIB_CAIRO* = "libcairo-2.dll" +elif defined(macosx): + const LIB_CAIRO* = "libcairo.dylib" +else: + const LIB_CAIRO* = "libcairo.so(|.2)" + +{.pragma: libcairo, cdecl, dynlib: LIB_CAIRO.} + +type + Context00* {.pure.} = object + Context* = ref object + impl*: ptr Context00 + +type + Surface00* {.pure.} = object + Surface* = ref object + impl*: ptr Surface00 + +type + Matrix00* {.pure.} = object + xx*: cdouble + yx*: cdouble + xy*: cdouble + yy*: cdouble + x0*: cdouble + y0*: cdouble + Matrix* = ref object + impl*: ptr Matrix00 + +type + Pattern00* {.pure.} = object + Pattern* = ref object + impl*: ptr Pattern00 + +type + Region00* {.pure.} = object + Region* = ref object + impl*: ptr Region00 + +type + Content* {.size: sizeof(cint), pure.} = enum + color = 0x1000, alpha = 0x2000, + color_alpha = 0x3000 + +type + FontOptions00* {.pure.} = object + FontOptions* = ref object + impl*: ptr FontOptions00 + +type + FontFace00* {.pure.} = object + FontFace* = ref object + impl*: ptr FontFace00 + +type + ScaledFont00* {.pure.} = object + ScaledFont* = ref object + impl*: ptr ScaledFont00 + +type + Status* {.size: sizeof(cint), pure.} = enum + success = 0, no_memory, invalid_restore, + invalid_pop_group, no_current_point, + invalid_matrix, invalid_status, + null_pointer, invalid_string, + invalid_path_data, read_error, + write_error, surface_finished, + surface_type_mismatch, pattern_type_mismatch, + invalid_content, invalid_format, + invalid_visual, file_not_found, + invalid_dash, invalid_dsc_comment, + invalid_index, clip_not_representable, + temp_file_error, invalid_stride, + font_type_mismatch, user_font_immutable, + user_font_error, negative_count, + invalid_clusters, invalid_slant, + invalid_weight, invalid_size, + user_font_not_implemented, device_type_mismatch, + device_error, invalid_mesh_construction, + device_finished, jbig2_global_missing, + png_error, freetype_error, + win32_gdi_error, tag_error, last_status + +type + PathDataType* {.size: sizeof(cint), pure.} = enum + move_to, line_to, curve_to, + close_path + +type + INNER_C_STRUCT_3330700347* = object + `type`*: PathDataType + length*: cint + + INNER_C_STRUCT_1651263489* = object + x*: cdouble + y*: cdouble + + PathData00* = object {.union.} + header*: INNER_C_STRUCT_3330700347 + point*: INNER_C_STRUCT_1651263489 + +type + Path00* {.pure.} = object + status*: Status + data*: ptr PathData00 + numData*: cint + Path* = ref object + impl*: ptr Path00 + +type + RectangleInt00* {.pure.} = object + x*: cint + y*: cint + width*: cint + height*: cint + RectangleInt* = ref object + impl*: ptr RectangleInt00 + +const + CAIRO_HAS_TEE_SURFACE = true + CAIRO_HAS_DRM_SURFACE = true + CAIRO_HAS_SKIA_SURFACE = true + CAIRO_HAS_SCRIPT_SURFACE = true + CAIRO_HAS_XML_SURFACE = true + CAIRO_HAS_SVG_SURFACE = true + CAIRO_HAS_PS_SURFACE = true + CAIRO_HAS_PDF_SURFACE = true + CAIRO_HAS_PNG_FUNCTIONS = true + +template cairo_Version_Encode*(major, minor, micro: untyped): untyped = + ((major * 10000) + (minor * 100) + (micro * 1)) + +proc cairoVersion*(): cint {.importc: "cairo_version", libcairo.} +proc cairoVersionString*(): cstring {.importc: "cairo_version_string", libcairo.} + +type + Bool00* = distinct cint + +# we should not need these constants often, because we have converters to and from Nim bool +const + CAIRO_FALSE* = Bool00(0) + CAIRO_TRUE* = Bool00(1) + +converter cbool*(nimbool: bool): Bool00 = + ord(nimbool).Bool00 + +converter toBool*(cbool: Bool00): bool = + int(cbool) != 0 + +type + Device00* = object + +type + DestroyFunc00* = proc (data: pointer) {.cdecl.} + +type + UserDataKey00* = object + unused: cint + + +type + Format* {.size: sizeof(cint), pure.} = enum + invalid = - 1, argb32 = 0, rgb24 = 1, + a8 = 2, a1 = 3, rgb16_565 = 4, + rgb30 = 5 + +type + WriteFunc00* = proc (closure: pointer; data: ptr cuchar; length: cuint): Status {.cdecl.} + +type + ReadFunc00* = proc (closure: pointer; data: ptr cuchar; length: cuint): Status {.cdecl.} + +proc cairoDestroy*(cr: ptr Context00) {.importc: "cairo_destroy", libcairo.} + +proc finalizeCairoContext[T](o: T) = + cairo_destroy(o.impl) + +proc cairoCreate*(target: ptr Surface00): ptr Context00 {.importc: "cairo_create", libcairo.} +# +proc newContext*(target: Surface): Context = + new(result, finalizeCairoContext) + result.impl = cairoCreate(target.impl) + + + + + + + + + +proc cairoReference*(cr: ptr Context00): ptr Context00 {.importc: "cairo_reference", + libcairo.} + +proc cairoGetReferenceCount*(cr: ptr Context00): cuint {. + importc: "cairo_get_reference_count", libcairo.} +proc cairoGetUserData*(cr: ptr Context00; key: ptr UserDataKey00): pointer {. + importc: "cairo_get_user_data", libcairo.} +proc cairoSetUserData*(cr: ptr Context00; key: ptr UserDataKey00; userData: pointer; + destroy: DestroyFunc00): Status {. + importc: "cairo_set_user_data", libcairo.} +proc cairoSave*(cr: ptr Context00) {.importc: "cairo_save", libcairo.} +proc cairoRestore*(cr: ptr Context00) {.importc: "cairo_restore", libcairo.} +proc cairoPushGroup*(cr: ptr Context00) {.importc: "cairo_push_group", libcairo.} +proc cairoPushGroupWithContent*(cr: ptr Context00; content: Content) {. + importc: "cairo_push_group_with_content", libcairo.} +proc cairoPopGroup*(cr: ptr Context00): ptr Pattern00 {.importc: "cairo_pop_group", + libcairo.} +proc cairoPopGroupToSource*(cr: ptr Context00) {.importc: "cairo_pop_group_to_source", + libcairo.} + +type + Operator* {.size: sizeof(cint), pure.} = enum + clear, source, over, + `in`, `out`, atop, + dest, dest_over, dest_in, + dest_out, dest_atop, `xor`, + add, saturate, multiply, + screen, overlay, darken, + lighten, color_dodge, color_burn, + hard_light, soft_light, + difference, exclusion, hsl_hue, + hsl_saturation, hsl_color, + hsl_luminosity + +proc cairoSetOperator*(cr: ptr Context00; op: Operator) {. + importc: "cairo_set_operator", libcairo.} +proc cairoSetSource*(cr: ptr Context00; source: ptr Pattern00) {. + importc: "cairo_set_source", libcairo.} + +proc cairoSetSourceRgb*(cr: ptr Context00; red: cdouble; green: cdouble; blue: cdouble) {. + importc: "cairo_set_source_rgb", libcairo.} +# +proc setSourceRgb*(cr: Context; red, green, blue: float) = + cairoSetSourceRgb(cr.impl, red.cdouble, green.cdouble, blue.cdouble) + + +proc cairoSetSourceRgba*(cr: ptr Context00; red: cdouble; green: cdouble; blue: cdouble; + alpha: cdouble) {.importc: "cairo_set_source_rgba", libcairo.} +# +proc setSourceRgba*(cr: Context; red, green, blue, alpha: float) = + cairoSetSourceRgba(cr.impl, red.cdouble, green.cdouble, blue.cdouble, alpha.cdouble) + +proc cairoSetSourceSurface*(cr: ptr Context00; surface: ptr Surface00; x: cdouble; + y: cdouble) {.importc: "cairo_set_source_surface", + libcairo.} +proc cairoSetTolerance*(cr: ptr Context00; tolerance: cdouble) {. + importc: "cairo_set_tolerance", libcairo.} + +type + Antialias* {.size: sizeof(cint), pure.} = enum + default, none, gray, + subpixel, fast, good, + best + +proc cairoSetAntialias*(cr: ptr Context00; antialias: Antialias) {. + importc: "cairo_set_antialias", libcairo.} + +type + FillRule* {.size: sizeof(cint), pure.} = enum + winding, even_odd + +proc cairoSetFillRule*(cr: ptr Context00; fillRule: FillRule) {. + importc: "cairo_set_fill_rule", libcairo.} +proc cairoSetLineWidth*(cr: ptr Context00; width: cdouble) {. + importc: "cairo_set_line_width", libcairo.} + +type + LineCap* {.size: sizeof(cint), pure.} = enum + butt, round, square + +proc cairoSetLineCap*(cr: ptr Context00; lineCap: LineCap) {. + importc: "cairo_set_line_cap", libcairo.} + +type + LineJoin* {.size: sizeof(cint), pure.} = enum + miter, round, bevel + +proc cairoSetLineJoin*(cr: ptr Context00; lineJoin: LineJoin) {. + importc: "cairo_set_line_join", libcairo.} +proc cairoSetDash*(cr: ptr Context00; dashes: var cdouble; numDashes: cint; offset: cdouble) {. + importc: "cairo_set_dash", libcairo.} +proc cairoSetMiterLimit*(cr: ptr Context00; limit: cdouble) {. + importc: "cairo_set_miter_limit", libcairo.} +proc cairoTranslate*(cr: ptr Context00; tx: cdouble; ty: cdouble) {. + importc: "cairo_translate", libcairo.} +proc cairoScale*(cr: ptr Context00; sx: cdouble; sy: cdouble) {.importc: "cairo_scale", + libcairo.} +proc cairoRotate*(cr: ptr Context00; angle: cdouble) {.importc: "cairo_rotate", libcairo.} +proc cairoTransform*(cr: ptr Context00; matrix: ptr Matrix00) {. + importc: "cairo_transform", libcairo.} +proc cairoSetMatrix*(cr: ptr Context00; matrix: ptr Matrix00) {. + importc: "cairo_set_matrix", libcairo.} +proc cairoIdentityMatrix*(cr: ptr Context00) {.importc: "cairo_identity_matrix", + libcairo.} +proc cairoUserToDevice*(cr: ptr Context00; x: var cdouble; y: var cdouble) {. + importc: "cairo_user_to_device", libcairo.} +proc cairoUserToDeviceDistance*(cr: ptr Context00; dx: var cdouble; dy: var cdouble) {. + importc: "cairo_user_to_device_distance", libcairo.} +proc cairoDeviceToUser*(cr: ptr Context00; x: var cdouble; y: var cdouble) {. + importc: "cairo_device_to_user", libcairo.} +proc cairoDeviceToUserDistance*(cr: ptr Context00; dx: var cdouble; dy: var cdouble) {. + importc: "cairo_device_to_user_distance", libcairo.} + +proc cairoNewPath*(cr: ptr Context00) {.importc: "cairo_new_path", libcairo.} + +proc cairoMoveTo*(cr: ptr Context00; x: cdouble; y: cdouble) {.importc: "cairo_move_to", + libcairo.} +# +proc moveTo*(cr: Context; x, y: float) = + cairoMoveTo(cr.impl, x.cdouble, y.cdouble) + + +proc cairoNewSubPath*(cr: ptr Context00) {.importc: "cairo_new_sub_path", libcairo.} + +proc cairoLineTo*(cr: ptr Context00; x, y: cdouble) {.importc: "cairo_line_to", libcairo.} +# +proc lineTo*(cr: Context; x, y: float) = cairoLineTo(cast[ptr Context00](cr.impl), cdouble(x), cdouble(y)) + +proc cairoCurveTo*(cr: ptr Context00; x1: cdouble; y1: cdouble; x2: cdouble; y2: cdouble; + x3: cdouble; y3: cdouble) {.importc: "cairo_curve_to", libcairo.} +proc cairoArc*(cr: ptr Context00; xc: cdouble; yc: cdouble; radius: cdouble; angle1: cdouble; + angle2: cdouble) {.importc: "cairo_arc", libcairo.} +proc cairoArcNegative*(cr: ptr Context00; xc: cdouble; yc: cdouble; radius: cdouble; + angle1: cdouble; angle2: cdouble) {. + importc: "cairo_arc_negative", libcairo.} + +proc cairoRelMoveTo*(cr: ptr Context00; dx: cdouble; dy: cdouble) {. + importc: "cairo_rel_move_to", libcairo.} +proc cairoRelLineTo*(cr: ptr Context00; dx: cdouble; dy: cdouble) {. + importc: "cairo_rel_line_to", libcairo.} +proc cairoRelCurveTo*(cr: ptr Context00; dx1: cdouble; dy1: cdouble; dx2: cdouble; + dy2: cdouble; dx3: cdouble; dy3: cdouble) {. + importc: "cairo_rel_curve_to", libcairo.} +proc cairoRectangle*(cr: ptr Context00; x: cdouble; y: cdouble; width: cdouble; + height: cdouble) {.importc: "cairo_rectangle", libcairo.} +# +proc rectangle*(cr: Context; x, y, width, height: float) = + cairoRectangle(cr.impl, x.cdouble, y.cdouble, width.cdouble, height.cdouble) + +proc cairoClosePath*(cr: ptr Context00) {.importc: "cairo_close_path", libcairo.} +proc cairoPathExtents*(cr: ptr Context00; x1: var cdouble; y1: var cdouble; x2: var cdouble; + y2: var cdouble) {.importc: "cairo_path_extents", libcairo.} + +proc cairoPaint*(cr: ptr Context00) {.importc: "cairo_paint", libcairo.} +# +proc paint*(cr: Context) = + cairoPaint(cr.impl) + +proc cairoPaintWithAlpha*(cr: ptr Context00; alpha: cdouble) {. + importc: "cairo_paint_with_alpha", libcairo.} +proc cairoMask*(cr: ptr Context00; pattern: ptr Pattern00) {.importc: "cairo_mask", + libcairo.} +proc cairoMaskSurface*(cr: ptr Context00; surface: ptr Surface00; surfaceX: cdouble; + surfaceY: cdouble) {.importc: "cairo_mask_surface", + libcairo.} + +proc cairoStroke*(cr: ptr Context00) {.importc: "cairo_stroke", libcairo.} +# +proc stroke*(cr: Context) = cairoStroke(cast[ptr Context00](cr.impl)) + +proc cairoStrokePreserve*(cr: ptr Context00) {.importc: "cairo_stroke_preserve", + libcairo.} +proc cairoFill*(cr: ptr Context00) {.importc: "cairo_fill", libcairo.} +# +proc fill*(cr: Context) = cairoFill(cr. impl) + +proc cairoFillPreserve*(cr: ptr Context00) {.importc: "cairo_fill_preserve", libcairo.} +proc cairoCopyPage*(cr: ptr Context00) {.importc: "cairo_copy_page", libcairo.} +proc cairoShowPage*(cr: ptr Context00) {.importc: "cairo_show_page", libcairo.} + +proc cairoInStroke*(cr: ptr Context00; x: cdouble; y: cdouble): Bool00 {. + importc: "cairo_in_stroke", libcairo.} +proc cairoInFill*(cr: ptr Context00; x: cdouble; y: cdouble): Bool00 {. + importc: "cairo_in_fill", libcairo.} +proc cairoInClip*(cr: ptr Context00; x: cdouble; y: cdouble): Bool00 {. + importc: "cairo_in_clip", libcairo.} + +proc cairoStrokeExtents*(cr: ptr Context00; x1: var cdouble; y1: var cdouble; + x2: var cdouble; y2: var cdouble) {. + importc: "cairo_stroke_extents", libcairo.} +proc cairoFillExtents*(cr: ptr Context00; x1: var cdouble; y1: var cdouble; x2: var cdouble; + y2: var cdouble) {.importc: "cairo_fill_extents", libcairo.} + +proc cairoResetClip*(cr: ptr Context00) {.importc: "cairo_reset_clip", libcairo.} +proc cairoClip*(cr: ptr Context00) {.importc: "cairo_clip", libcairo.} +proc cairoClipPreserve*(cr: ptr Context00) {.importc: "cairo_clip_preserve", libcairo.} +proc cairoClipExtents*(cr: ptr Context00; x1: var cdouble; y1: var cdouble; x2: var cdouble; + y2: var cdouble) {.importc: "cairo_clip_extents", libcairo.} + +type + Rectangle00* = object + x*: cdouble + y*: cdouble + width*: cdouble + height*: cdouble + +type + RectangleList00* = object + status*: Status + rectangles*: ptr Rectangle00 + numRectangles*: cint + +proc cairoCopyClipRectangleList*(cr: ptr Context00): ptr RectangleList00 {. + importc: "cairo_copy_clip_rectangle_list", libcairo.} +proc cairoRectangleListDestroy*(rectangleList: ptr RectangleList00) {. + importc: "cairo_rectangle_list_destroy", libcairo.} + +const + CAIRO_TAG_DEST* = "cairo.dest" + CAIRO_TAG_LINK* = "Link" + +proc cairoTagBegin*(cr: ptr Context00; tagName: cstring; attributes: cstring) {. + importc: "cairo_tag_begin", libcairo.} +proc cairoTagEnd*(cr: ptr Context00; tagName: cstring) {.importc: "cairo_tag_end", + libcairo.} + +type + Glyph00* = object + index*: culong + x*: cdouble + y*: cdouble + +proc cairoGlyphAllocate*(numGlyphs: cint): ptr Glyph00 {. + importc: "cairo_glyph_allocate", libcairo.} +proc cairoGlyphFree*(glyphs: ptr Glyph00) {.importc: "cairo_glyph_free", + libcairo.} + +type + TextCluster00* = object + numBytes*: cint + numGlyphs*: cint + +proc cairoTextClusterAllocate*(numClusters: cint): ptr TextCluster00 {. + importc: "cairo_text_cluster_allocate", libcairo.} +proc cairoTextClusterFree*(clusters: ptr TextCluster00) {. + importc: "cairo_text_cluster_free", libcairo.} + +type + TextClusterFlags* {.size: sizeof(cint), pure.} = enum + backward = 0x1 + +type + TextExtents00* = object + xBearing*: cdouble + yBearing*: cdouble + width*: cdouble + height*: cdouble + xAdvance*: cdouble + yAdvance*: cdouble + +type + FontExtents00* = object + ascent*: cdouble + descent*: cdouble + height*: cdouble + maxXAdvance*: 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 cairoFontOptionsCreate*(): ptr FontOptions00 {. + importc: "cairo_font_options_create", libcairo.} +proc cairoFontOptionsCopy*(original: ptr FontOptions00): ptr FontOptions00 {. + importc: "cairo_font_options_copy", libcairo.} +proc cairoFontOptionsDestroy*(options: ptr FontOptions00) {. + importc: "cairo_font_options_destroy", libcairo.} +proc cairoFontOptionsStatus*(options: ptr FontOptions00): Status {. + importc: "cairo_font_options_status", libcairo.} +proc cairoFontOptionsMerge*(options: ptr FontOptions00; + other: ptr FontOptions00) {. + importc: "cairo_font_options_merge", libcairo.} +proc cairoFontOptionsEqual*(options: ptr FontOptions00; + other: ptr FontOptions00): Bool00 {. + importc: "cairo_font_options_equal", libcairo.} +proc cairoFontOptionsHash*(options: ptr FontOptions00): culong {. + importc: "cairo_font_options_hash", libcairo.} +proc cairoFontOptionsSetAntialias*(options: ptr FontOptions00; + antialias: Antialias) {. + importc: "cairo_font_options_set_antialias", libcairo.} +proc cairoFontOptionsGetAntialias*(options: ptr FontOptions00): Antialias {. + importc: "cairo_font_options_get_antialias", libcairo.} +proc cairoFontOptionsSetSubpixelOrder*(options: ptr FontOptions00; + subpixelOrder: SubpixelOrder) {. + importc: "cairo_font_options_set_subpixel_order", libcairo.} +proc cairoFontOptionsGetSubpixelOrder*(options: ptr FontOptions00): SubpixelOrder {. + importc: "cairo_font_options_get_subpixel_order", libcairo.} +proc cairoFontOptionsSetHintStyle*(options: ptr FontOptions00; + hintStyle: HintStyle) {. + importc: "cairo_font_options_set_hint_style", libcairo.} +proc cairoFontOptionsGetHintStyle*(options: ptr FontOptions00): HintStyle {. + importc: "cairo_font_options_get_hint_style", libcairo.} +proc cairoFontOptionsSetHintMetrics*(options: ptr FontOptions00; + hintMetrics: HintMetrics) {. + importc: "cairo_font_options_set_hint_metrics", libcairo.} +proc cairoFontOptionsGetHintMetrics*(options: ptr FontOptions00): HintMetrics {. + importc: "cairo_font_options_get_hint_metrics", libcairo.} + +proc cairoSelectFontFace*(cr: ptr Context00; family: cstring; slant: FontSlant; + weight: FontWeight) {.importc: "cairo_select_font_face", libcairo.} +# +proc selectFontFace*(cr: Context; family: string; slant: FontSlant; weight: FontWeight) = + cairoSelectFontFace(cr.impl, family, slant, weight) + + +proc cairoSetFontSize*(cr: ptr Context00; size: cdouble) {. + importc: "cairo_set_font_size", libcairo.} +# +proc setFontSize*(cr: Context; size: float) = + cairoSetFontSize(cr.impl, size.cdouble) + +proc cairoSetFontMatrix*(cr: ptr Context00; matrix: ptr Matrix00) {. + importc: "cairo_set_font_matrix", libcairo.} +proc cairoGetFontMatrix*(cr: ptr Context00; matrix: ptr Matrix00) {. + importc: "cairo_get_font_matrix", libcairo.} +proc cairoSetFontOptions*(cr: ptr Context00; options: ptr FontOptions00) {. + importc: "cairo_set_font_options", libcairo.} +proc cairoGetFontOptions*(cr: ptr Context00; options: ptr FontOptions00) {. + importc: "cairo_get_font_options", libcairo.} + +proc cairoSetFontFace*(cr: ptr Context00; fontFace: ptr FontFace00) {. + importc: "cairo_set_font_face", libcairo.} + + + +proc cairoGetFontFace*(cr: ptr Context00): ptr FontFace00 {. + importc: "cairo_get_font_face", libcairo.} +proc cairoSetScaledFont*(cr: ptr Context00; scaledFont: ptr ScaledFont00) {. + importc: "cairo_set_scaled_font", libcairo.} +proc cairoGetScaledFont*(cr: ptr Context00): ptr ScaledFont00 {. + importc: "cairo_get_scaled_font", libcairo.} +proc cairoShowText*(cr: ptr Context00; utf8: cstring) {.importc: "cairo_show_text", + libcairo.} +# +proc showText*(cr: Context; utf8: string) = + cairoShowText(cr.impl, utf8) + +proc cairoShowGlyphs*(cr: ptr Context00; glyphs: ptr Glyph00; numGlyphs: cint) {. + importc: "cairo_show_glyphs", libcairo.} +proc cairoShowTextGlyphs*(cr: ptr Context00; utf8: cstring; utf8Len: cint; + glyphs: ptr Glyph00; numGlyphs: cint; + clusters: ptr TextCluster00; numClusters: cint; + clusterFlags: TextClusterFlags) {. + importc: "cairo_show_text_glyphs", libcairo.} +proc cairoTextPath*(cr: ptr Context00; utf8: cstring) {.importc: "cairo_text_path", + libcairo.} +proc cairoGlyphPath*(cr: ptr Context00; glyphs: ptr Glyph00; numGlyphs: cint) {. + importc: "cairo_glyph_path", libcairo.} +proc cairoTextExtents*(cr: ptr Context00; utf8: cstring; extents: ptr TextExtents00) {. + importc: "cairo_text_extents", libcairo.} +proc cairoGlyphExtents*(cr: ptr Context00; glyphs: ptr Glyph00; numGlyphs: cint; + extents: ptr TextExtents00) {. + importc: "cairo_glyph_extents", libcairo.} +proc cairoFontExtents*(cr: ptr Context00; extents: ptr FontExtents00) {. + importc: "cairo_font_extents", libcairo.} + +proc cairoFontFaceReference*(fontFace: ptr FontFace00): ptr FontFace00 {. + importc: "cairo_font_face_reference", libcairo.} +proc cairoFontFaceDestroy*(fontFace: ptr FontFace00) {. + importc: "cairo_font_face_destroy", libcairo.} +proc cairoFontFaceGetReferenceCount*(fontFace: ptr FontFace00): cuint {. + importc: "cairo_font_face_get_reference_count", libcairo.} +proc cairoFontFaceStatus*(fontFace: ptr FontFace00): Status {. + importc: "cairo_font_face_status", libcairo.} + +type + FontType* {.size: sizeof(cint), pure.} = enum + toy, ft, win32, + quartz, user + +proc cairoFontFaceGetType*(fontFace: ptr FontFace00): FontType {. + importc: "cairo_font_face_get_type", libcairo.} +proc cairoFontFaceGetUserData*(fontFace: ptr FontFace00; + key: ptr UserDataKey00): pointer {. + importc: "cairo_font_face_get_user_data", libcairo.} +proc cairoFontFaceSetUserData*(fontFace: ptr FontFace00; + key: ptr UserDataKey00; userData: pointer; + destroy: DestroyFunc00): Status {. + importc: "cairo_font_face_set_user_data", libcairo.} + +proc cairoScaledFontCreate*(fontFace: ptr FontFace00; + fontMatrix: ptr Matrix00; ctm: ptr Matrix00; + options: ptr FontOptions00): ptr ScaledFont00 {. + importc: "cairo_scaled_font_create", libcairo.} +proc cairoScaledFontReference*(scaledFont: ptr ScaledFont00): ptr ScaledFont00 {. + importc: "cairo_scaled_font_reference", libcairo.} +proc cairoScaledFontDestroy*(scaledFont: ptr ScaledFont00) {. + importc: "cairo_scaled_font_destroy", libcairo.} +proc cairoScaledFontGetReferenceCount*(scaledFont: ptr ScaledFont00): cuint {. + importc: "cairo_scaled_font_get_reference_count", libcairo.} +proc cairoScaledFontStatus*(scaledFont: ptr ScaledFont00): Status {. + importc: "cairo_scaled_font_status", libcairo.} +proc cairoScaledFontGetType*(scaledFont: ptr ScaledFont00): FontType {. + importc: "cairo_scaled_font_get_type", libcairo.} +proc cairoScaledFontGetUserData*(scaledFont: ptr ScaledFont00; + key: ptr UserDataKey00): pointer {. + importc: "cairo_scaled_font_get_user_data", libcairo.} +proc cairoScaledFontSetUserData*(scaledFont: ptr ScaledFont00; + key: ptr UserDataKey00; userData: pointer; + destroy: DestroyFunc00): Status {. + importc: "cairo_scaled_font_set_user_data", libcairo.} +proc cairoScaledFontExtents*(scaledFont: ptr ScaledFont00; + extents: ptr FontExtents00) {. + importc: "cairo_scaled_font_extents", libcairo.} +proc cairoScaledFontTextExtents*(scaledFont: ptr ScaledFont00; utf8: cstring; + extents: ptr TextExtents00) {. + importc: "cairo_scaled_font_text_extents", libcairo.} +proc cairoScaledFontGlyphExtents*(scaledFont: ptr ScaledFont00; + glyphs: ptr Glyph00; numGlyphs: cint; + extents: ptr TextExtents00) {. + importc: "cairo_scaled_font_glyph_extents", libcairo.} +proc cairoScaledFontTextToGlyphs*(scaledFont: ptr ScaledFont00; x: cdouble; + y: cdouble; utf8: cstring; utf8Len: cint; + glyphs: ptr ptr Glyph00; numGlyphs: var cint; + clusters: ptr ptr TextCluster00; + numClusters: var cint; + clusterFlags: var TextClusterFlags): Status {. + importc: "cairo_scaled_font_text_to_glyphs", libcairo.} +proc cairoScaledFontGetFontFace*(scaledFont: ptr ScaledFont00): ptr FontFace00 {. + importc: "cairo_scaled_font_get_font_face", libcairo.} +proc cairoScaledFontGetFontMatrix*(scaledFont: ptr ScaledFont00; + fontMatrix: ptr Matrix00) {. + importc: "cairo_scaled_font_get_font_matrix", libcairo.} +proc cairoScaledFontGetCtm*(scaledFont: ptr ScaledFont00; ctm: ptr Matrix00) {. + importc: "cairo_scaled_font_get_ctm", libcairo.} +proc cairoScaledFontGetScaleMatrix*(scaledFont: ptr ScaledFont00; + scaleMatrix: ptr Matrix00) {. + importc: "cairo_scaled_font_get_scale_matrix", libcairo.} +proc cairoScaledFontGetFontOptions*(scaledFont: ptr ScaledFont00; + options: ptr FontOptions00) {. + importc: "cairo_scaled_font_get_font_options", libcairo.} + +proc cairoToyFontFaceCreate*(family: cstring; slant: FontSlant; + weight: FontWeight): ptr FontFace00 {. + importc: "cairo_toy_font_face_create", libcairo.} +proc cairoToyFontFaceGetFamily*(fontFace: ptr FontFace00): cstring {. + importc: "cairo_toy_font_face_get_family", libcairo.} +proc cairoToyFontFaceGetSlant*(fontFace: ptr FontFace00): FontSlant {. + importc: "cairo_toy_font_face_get_slant", libcairo.} +proc cairoToyFontFaceGetWeight*(fontFace: ptr FontFace00): FontWeight {. + importc: "cairo_toy_font_face_get_weight", libcairo.} + +proc cairoUserFontFaceCreate*(): ptr FontFace00 {. + importc: "cairo_user_font_face_create", libcairo.} + +type + UserScaledFontInitFunc00* = proc (scaledFont: ptr ScaledFont00; + cr: ptr Context00; extents: ptr FontExtents00): Status {.cdecl.} + +type + UserScaledFontRenderGlyphFunc00* = proc (scaledFont: ptr ScaledFont00; + glyph: culong; cr: ptr Context00; extents: ptr TextExtents00): Status {.cdecl.} + +type + UserScaledFontTextToGlyphsFunc00* = proc (scaledFont: ptr ScaledFont00; + utf8: cstring; utf8Len: cint; glyphs: ptr ptr Glyph00; numGlyphs: var cint; + clusters: ptr ptr TextCluster00; numClusters: var cint; + clusterFlags: var TextClusterFlags): Status {.cdecl.} + +type + UserScaledFontUnicodeToGlyphFunc00* = proc (scaledFont: ptr ScaledFont00; + unicode: culong; glyphIndex: var culong): Status {.cdecl.} + +proc cairoUserFontFaceSetInitFunc*(fontFace: ptr FontFace00; + initFunc: UserScaledFontInitFunc00) {. + importc: "cairo_user_font_face_set_init_func", libcairo.} +proc cairoUserFontFaceSetRenderGlyphFunc*(fontFace: ptr FontFace00; + renderGlyphFunc: UserScaledFontRenderGlyphFunc00) {. + importc: "cairo_user_font_face_set_render_glyph_func", libcairo.} +proc cairoUserFontFaceSetTextToGlyphsFunc*(fontFace: ptr FontFace00; + textToGlyphsFunc: UserScaledFontTextToGlyphsFunc00) {. + importc: "cairo_user_font_face_set_text_to_glyphs_func", libcairo.} +proc cairoUserFontFaceSetUnicodeToGlyphFunc*(fontFace: ptr FontFace00; + unicodeToGlyphFunc: UserScaledFontUnicodeToGlyphFunc00) {. + importc: "cairo_user_font_face_set_unicode_to_glyph_func", libcairo.} + +proc cairoUserFontFaceGetInitFunc*(fontFace: ptr FontFace00): UserScaledFontInitFunc00 {. + importc: "cairo_user_font_face_get_init_func", libcairo.} +proc cairoUserFontFaceGetRenderGlyphFunc*(fontFace: ptr FontFace00): UserScaledFontRenderGlyphFunc00 {. + importc: "cairo_user_font_face_get_render_glyph_func", libcairo.} +proc cairoUserFontFaceGetTextToGlyphsFunc*(fontFace: ptr FontFace00): UserScaledFontTextToGlyphsFunc00 {. + importc: "cairo_user_font_face_get_text_to_glyphs_func", libcairo.} +proc cairoUserFontFaceGetUnicodeToGlyphFunc*(fontFace: ptr FontFace00): UserScaledFontUnicodeToGlyphFunc00 {. + importc: "cairo_user_font_face_get_unicode_to_glyph_func", libcairo.} + +proc cairoGetOperator*(cr: ptr Context00): Operator {. + importc: "cairo_get_operator", libcairo.} +proc cairoGetSource*(cr: ptr Context00): ptr Pattern00 {.importc: "cairo_get_source", + libcairo.} +proc cairoGetTolerance*(cr: ptr Context00): cdouble {.importc: "cairo_get_tolerance", + libcairo.} +proc cairoGetAntialias*(cr: ptr Context00): Antialias {. + importc: "cairo_get_antialias", libcairo.} +proc cairoHasCurrentPoint*(cr: ptr Context00): Bool00 {. + importc: "cairo_has_current_point", libcairo.} +proc cairoGetCurrentPoint*(cr: ptr Context00; x: var cdouble; y: var cdouble) {. + importc: "cairo_get_current_point", libcairo.} +proc cairoGetFillRule*(cr: ptr Context00): FillRule {. + importc: "cairo_get_fill_rule", libcairo.} +proc cairoGetLineWidth*(cr: ptr Context00): cdouble {.importc: "cairo_get_line_width", + libcairo.} +proc cairoGetLineCap*(cr: ptr Context00): LineCap {.importc: "cairo_get_line_cap", + libcairo.} +proc cairoGetLineJoin*(cr: ptr Context00): LineJoin {. + importc: "cairo_get_line_join", libcairo.} +proc cairoGetMiterLimit*(cr: ptr Context00): cdouble {.importc: "cairo_get_miter_limit", + libcairo.} +proc cairoGetDashCount*(cr: ptr Context00): cint {.importc: "cairo_get_dash_count", + libcairo.} +proc cairoGetDash*(cr: ptr Context00; dashes: var cdouble; offset: var cdouble) {. + importc: "cairo_get_dash", libcairo.} +proc cairoGetMatrix*(cr: ptr Context00; matrix: ptr Matrix00) {. + importc: "cairo_get_matrix", libcairo.} +proc cairoGetTarget*(cr: ptr Context00): ptr Surface00 {.importc: "cairo_get_target", + libcairo.} +proc cairoGetGroupTarget*(cr: ptr Context00): ptr Surface00 {. + importc: "cairo_get_group_target", libcairo.} + +proc cairoCopyPath*(cr: ptr Context00): ptr Path00 {.importc: "cairo_copy_path", + libcairo.} +proc cairoCopyPathFlat*(cr: ptr Context00): ptr Path00 {. + importc: "cairo_copy_path_flat", libcairo.} +proc cairoAppendPath*(cr: ptr Context00; path: ptr Path00) {. + importc: "cairo_append_path", libcairo.} +proc cairoPathDestroy*(path: ptr Path00) {.importc: "cairo_path_destroy", + libcairo.} + +proc cairoStatus*(cr: ptr Context00): Status {.importc: "cairo_status", libcairo.} +proc cairoStatusToString*(status: Status): cstring {. + importc: "cairo_status_to_string", libcairo.} + +proc cairoDeviceReference*(device: ptr Device00): ptr Device00 {. + importc: "cairo_device_reference", libcairo.} + +type + DeviceType* {.size: sizeof(cint), pure.} = enum + invalid = - 1, drm, gl, + script, xcb, xlib, + xml, cogl, win32 + +proc cairoDeviceGetType*(device: ptr Device00): DeviceType {. + importc: "cairo_device_get_type", libcairo.} +proc cairoDeviceStatus*(device: ptr Device00): Status {. + importc: "cairo_device_status", libcairo.} +proc cairoDeviceAcquire*(device: ptr Device00): Status {. + importc: "cairo_device_acquire", libcairo.} +proc cairoDeviceRelease*(device: ptr Device00) {. + importc: "cairo_device_release", libcairo.} +proc cairoDeviceFlush*(device: ptr Device00) {.importc: "cairo_device_flush", + libcairo.} +proc cairoDeviceFinish*(device: ptr Device00) {.importc: "cairo_device_finish", + libcairo.} +proc cairoDeviceDestroy*(device: ptr Device00) {. + importc: "cairo_device_destroy", libcairo.} +proc cairoDeviceGetReferenceCount*(device: ptr Device00): cuint {. + importc: "cairo_device_get_reference_count", libcairo.} +proc cairoDeviceGetUserData*(device: ptr Device00; key: ptr UserDataKey00): pointer {. + importc: "cairo_device_get_user_data", libcairo.} +proc cairoDeviceSetUserData*(device: ptr Device00; key: ptr UserDataKey00; + userData: pointer; destroy: DestroyFunc00): Status {. + importc: "cairo_device_set_user_data", libcairo.} + +proc cairoSurfaceCreateSimilar*(other: ptr Surface00; content: Content; + width: cint; height: cint): ptr Surface00 {. + importc: "cairo_surface_create_similar", libcairo.} +proc cairoSurfaceCreateSimilarImage*(other: ptr Surface00; format: Format; + width: cint; height: cint): ptr Surface00 {. + importc: "cairo_surface_create_similar_image", libcairo.} +proc cairoSurfaceMapToImage*(surface: ptr Surface00; + extents: ptr RectangleInt00): ptr Surface00 {. + importc: "cairo_surface_map_to_image", libcairo.} +proc cairoSurfaceUnmapImage*(surface: ptr Surface00; image: ptr Surface00) {. + importc: "cairo_surface_unmap_image", libcairo.} +proc cairoSurfaceCreateForRectangle*(target: ptr Surface00; x: cdouble; + y: cdouble; width: cdouble; height: cdouble): ptr Surface00 {. + importc: "cairo_surface_create_for_rectangle", libcairo.} + +type + SurfaceObserverMode* {.size: sizeof(cint), pure.} = enum + normal = 0, + record_operations = 0x1 + +proc cairoSurfaceCreateObserver*(target: ptr Surface00; + mode: SurfaceObserverMode): ptr Surface00 {. + importc: "cairo_surface_create_observer", libcairo.} +type + SurfaceObserverCallback00* = proc (observer: ptr Surface00; + target: ptr Surface00; data: pointer) {.cdecl.} + +proc cairoSurfaceObserverAddPaintCallback*(abstractSurface: ptr Surface00; + `func`: SurfaceObserverCallback00; data: pointer): Status {. + importc: "cairo_surface_observer_add_paint_callback", libcairo.} +proc cairoSurfaceObserverAddMaskCallback*(abstractSurface: ptr Surface00; + `func`: SurfaceObserverCallback00; data: pointer): Status {. + importc: "cairo_surface_observer_add_mask_callback", libcairo.} +proc cairoSurfaceObserverAddFillCallback*(abstractSurface: ptr Surface00; + `func`: SurfaceObserverCallback00; data: pointer): Status {. + importc: "cairo_surface_observer_add_fill_callback", libcairo.} +proc cairoSurfaceObserverAddStrokeCallback*(abstractSurface: ptr Surface00; + `func`: SurfaceObserverCallback00; data: pointer): Status {. + importc: "cairo_surface_observer_add_stroke_callback", libcairo.} +proc cairoSurfaceObserverAddGlyphsCallback*(abstractSurface: ptr Surface00; + `func`: SurfaceObserverCallback00; data: pointer): Status {. + importc: "cairo_surface_observer_add_glyphs_callback", libcairo.} +proc cairoSurfaceObserverAddFlushCallback*(abstractSurface: ptr Surface00; + `func`: SurfaceObserverCallback00; data: pointer): Status {. + importc: "cairo_surface_observer_add_flush_callback", libcairo.} +proc cairoSurfaceObserverAddFinishCallback*(abstractSurface: ptr Surface00; + `func`: SurfaceObserverCallback00; data: pointer): Status {. + importc: "cairo_surface_observer_add_finish_callback", libcairo.} +proc cairoSurfaceObserverPrint*(surface: ptr Surface00; + writeFunc: WriteFunc00; closure: pointer): Status {. + importc: "cairo_surface_observer_print", libcairo.} +proc cairoSurfaceObserverElapsed*(surface: ptr Surface00): cdouble {. + importc: "cairo_surface_observer_elapsed", libcairo.} +proc cairoDeviceObserverPrint*(device: ptr Device00; writeFunc: WriteFunc00; + closure: pointer): Status {. + importc: "cairo_device_observer_print", libcairo.} +proc cairoDeviceObserverElapsed*(device: ptr Device00): cdouble {. + importc: "cairo_device_observer_elapsed", libcairo.} +proc cairoDeviceObserverPaintElapsed*(device: ptr Device00): cdouble {. + importc: "cairo_device_observer_paint_elapsed", libcairo.} +proc cairoDeviceObserverMaskElapsed*(device: ptr Device00): cdouble {. + importc: "cairo_device_observer_mask_elapsed", libcairo.} +proc cairoDeviceObserverFillElapsed*(device: ptr Device00): cdouble {. + importc: "cairo_device_observer_fill_elapsed", libcairo.} +proc cairoDeviceObserverStrokeElapsed*(device: ptr Device00): cdouble {. + importc: "cairo_device_observer_stroke_elapsed", libcairo.} +proc cairoDeviceObserverGlyphsElapsed*(device: ptr Device00): cdouble {. + importc: "cairo_device_observer_glyphs_elapsed", libcairo.} +proc cairoSurfaceReference*(surface: ptr Surface00): ptr Surface00 {. + importc: "cairo_surface_reference", libcairo.} +proc cairoSurfaceFinish*(surface: ptr Surface00) {. + importc: "cairo_surface_finish", libcairo.} +proc cairoSurfaceDestroy*(surface: ptr Surface00) {. + importc: "cairo_surface_destroy", libcairo.} +proc cairoSurfaceGetDevice*(surface: ptr Surface00): ptr Device00 {. + importc: "cairo_surface_get_device", libcairo.} +proc cairoSurfaceGetReferenceCount*(surface: ptr Surface00): cuint {. + importc: "cairo_surface_get_reference_count", libcairo.} +proc cairoSurfaceStatus*(surface: ptr Surface00): Status {. + importc: "cairo_surface_status", libcairo.} + +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 cairoSurfaceGetType*(surface: ptr Surface00): SurfaceType {. + importc: "cairo_surface_get_type", libcairo.} +proc cairoSurfaceGetContent*(surface: ptr Surface00): Content {. + importc: "cairo_surface_get_content", libcairo.} +when CAIRO_HAS_PNG_FUNCTIONS: + proc cairoSurfaceWriteToPng*(surface: ptr Surface00; filename: cstring): Status {. + importc: "cairo_surface_write_to_png", libcairo.} +# + proc writeToPng*(surface: Surface; filename: string): Status = + cairoSurfaceWriteToPng(surface.impl, filename) + + proc cairoSurfaceWriteToPngStream*(surface: ptr Surface00; + writeFunc: WriteFunc00; closure: pointer): Status {. + importc: "cairo_surface_write_to_png_stream", libcairo.} +proc cairoSurfaceGetUserData*(surface: ptr Surface00; key: ptr UserDataKey00): pointer {. + importc: "cairo_surface_get_user_data", libcairo.} +proc cairoSurfaceSetUserData*(surface: ptr Surface00; + key: ptr UserDataKey00; userData: pointer; + destroy: DestroyFunc00): Status {. + importc: "cairo_surface_set_user_data", libcairo.} +const + MIME_TYPE_JPEG* = "image/jpeg" + MIME_TYPE_PNG* = "image/png" + MIME_TYPE_JP2* = "image/jp2" + MIME_TYPE_URI* = "text/x-uri" + MIME_TYPE_UNIQUE_ID* = "application/x-cairo.uuid" + MIME_TYPE_JBIG2* = "application/x-cairo.jbig2" + MIME_TYPE_JBIG2_GLOBAL* = "application/x-cairo.jbig2-global" + MIME_TYPE_JBIG2_GLOBAL_ID* = "application/x-cairo.jbig2-global-id" + +proc cairoSurfaceGetMimeData*(surface: ptr Surface00; mimeType: cstring; + data: ptr ptr cuchar; length: var culong) {. + importc: "cairo_surface_get_mime_data", libcairo.} +proc cairoSurfaceSetMimeData*(surface: ptr Surface00; mimeType: cstring; + data: ptr cuchar; length: culong; + destroy: DestroyFunc00; closure: pointer): Status {. + importc: "cairo_surface_set_mime_data", libcairo.} +proc cairoSurfaceSupportsMimeType*(surface: ptr Surface00; mimeType: cstring): Bool00 {. + importc: "cairo_surface_supports_mime_type", libcairo.} +proc cairoSurfaceGetFontOptions*(surface: ptr Surface00; + options: ptr FontOptions00) {. + importc: "cairo_surface_get_font_options", libcairo.} +proc cairoSurfaceFlush*(surface: ptr Surface00) {. + importc: "cairo_surface_flush", libcairo.} +proc cairoSurfaceMarkDirty*(surface: ptr Surface00) {. + importc: "cairo_surface_mark_dirty", libcairo.} +proc cairoSurfaceMarkDirtyRectangle*(surface: ptr Surface00; x: cint; y: cint; + width: cint; height: cint) {. + importc: "cairo_surface_mark_dirty_rectangle", libcairo.} +proc cairoSurfaceSetDeviceScale*(surface: ptr Surface00; xScale: cdouble; + yScale: cdouble) {. + importc: "cairo_surface_set_device_scale", libcairo.} +proc cairoSurfaceGetDeviceScale*(surface: ptr Surface00; xScale: var cdouble; + yScale: var cdouble) {. + importc: "cairo_surface_get_device_scale", libcairo.} +proc cairoSurfaceSetDeviceOffset*(surface: ptr Surface00; xOffset: cdouble; + yOffset: cdouble) {. + importc: "cairo_surface_set_device_offset", libcairo.} +proc cairoSurfaceGetDeviceOffset*(surface: ptr Surface00; xOffset: var cdouble; + yOffset: var cdouble) {. + importc: "cairo_surface_get_device_offset", libcairo.} +proc cairoSurfaceSetFallbackResolution*(surface: ptr Surface00; + xPixelsPerInch: cdouble; + yPixelsPerInch: cdouble) {. + importc: "cairo_surface_set_fallback_resolution", libcairo.} +proc cairoSurfaceGetFallbackResolution*(surface: ptr Surface00; + xPixelsPerInch: var cdouble; + yPixelsPerInch: var cdouble) {. + importc: "cairo_surface_get_fallback_resolution", libcairo.} +proc cairoSurfaceCopyPage*(surface: ptr Surface00) {. + importc: "cairo_surface_copy_page", libcairo.} +proc cairoSurfaceShowPage*(surface: ptr Surface00) {. + importc: "cairo_surface_show_page", libcairo.} +proc cairoSurfaceHasShowTextGlyphs*(surface: ptr Surface00): Bool00 {. + importc: "cairo_surface_has_show_text_glyphs", libcairo.} + +proc cairoImageSurfaceCreate*(format: Format; width: cint; height: cint): ptr Surface00 {. + importc: "cairo_image_surface_create", libcairo.} + +proc finalizeCairoSurface[T](o: T) = + cairo_surface_destroy(o.impl) + +proc newImageSurface*(format: Format; width: int; height: int): Surface = + new(result, finalizeCairoSurface) + result.impl = cairoImageSurfaceCreate(format, width.cint, height.cint) + + + + + + + +proc cairoFormatStrideForWidth*(format: Format; width: cint): cint {. + importc: "cairo_format_stride_for_width", libcairo.} +proc cairoImageSurfaceCreateForData*(data: ptr cuchar; format: Format; + width: cint; height: cint; stride: cint): ptr Surface00 {. + importc: "cairo_image_surface_create_for_data", libcairo.} +proc cairoImageSurfaceGetData*(surface: ptr Surface00): ptr cuchar {. + importc: "cairo_image_surface_get_data", libcairo.} +proc cairoImageSurfaceGetFormat*(surface: ptr Surface00): Format {. + importc: "cairo_image_surface_get_format", libcairo.} +proc cairoImageSurfaceGetWidth*(surface: ptr Surface00): cint {. + importc: "cairo_image_surface_get_width", libcairo.} +proc cairoImageSurfaceGetHeight*(surface: ptr Surface00): cint {. + importc: "cairo_image_surface_get_height", libcairo.} +proc cairoImageSurfaceGetStride*(surface: ptr Surface00): cint {. + importc: "cairo_image_surface_get_stride", libcairo.} +when CAIRO_HAS_PNG_FUNCTIONS: + proc cairoImageSurfaceCreateFromPng*(filename: cstring): ptr Surface00 {. + importc: "cairo_image_surface_create_from_png", libcairo.} + proc cairoImageSurfaceCreateFromPngStream*(readFunc: ReadFunc00; + closure: pointer): ptr Surface00 {. + importc: "cairo_image_surface_create_from_png_stream", libcairo.} + +proc cairoRecordingSurfaceCreate*(content: Content; + extents: ptr Rectangle00): ptr Surface00 {. + importc: "cairo_recording_surface_create", libcairo.} +proc cairoRecordingSurfaceInkExtents*(surface: ptr Surface00; x0: var cdouble; + y0: var cdouble; width: var cdouble; + height: var cdouble) {. + importc: "cairo_recording_surface_ink_extents", libcairo.} +proc cairoRecordingSurfaceGetExtents*(surface: ptr Surface00; + extents: ptr Rectangle00): Bool00 {. + importc: "cairo_recording_surface_get_extents", libcairo.} + +type + RasterSourceAcquireFunc00* = proc (pattern: ptr Pattern00; + callbackData: pointer; + target: ptr Surface00; + extents: ptr RectangleInt00): ptr Surface00 {.cdecl.} + +type + RasterSourceReleaseFunc00* = proc (pattern: ptr Pattern00; + callbackData: pointer; + surface: ptr Surface00) {.cdecl.} + +type + RasterSourceSnapshotFunc00* = proc (pattern: ptr Pattern00; + callbackData: pointer): Status {.cdecl.} + +type + RasterSourceCopyFunc00* = proc (pattern: ptr Pattern00; + callbackData: pointer; other: ptr Pattern00): Status {.cdecl.} + +type + RasterSourceFinishFunc00* = proc (pattern: ptr Pattern00; + callbackData: pointer) {.cdecl.} + +proc cairoPatternCreateRasterSource*(userData: pointer; content: Content; + width: cint; height: cint): ptr Pattern00 {. + importc: "cairo_pattern_create_raster_source", libcairo.} +proc cairoRasterSourcePatternSetCallbackData*(pattern: ptr Pattern00; + data: pointer) {.importc: "cairo_raster_source_pattern_set_callback_data", + libcairo.} +proc cairoRasterSourcePatternGetCallbackData*(pattern: ptr Pattern00): pointer {. + importc: "cairo_raster_source_pattern_get_callback_data", libcairo.} +proc cairoRasterSourcePatternSetAcquire*(pattern: ptr Pattern00; + acquire: RasterSourceAcquireFunc00; + release: RasterSourceReleaseFunc00) {. + importc: "cairo_raster_source_pattern_set_acquire", libcairo.} +proc cairoRasterSourcePatternGetAcquire*(pattern: ptr Pattern00; acquire: ptr RasterSourceAcquireFunc00; + release: ptr RasterSourceReleaseFunc00) {. + importc: "cairo_raster_source_pattern_get_acquire", libcairo.} +proc cairoRasterSourcePatternSetSnapshot*(pattern: ptr Pattern00; + snapshot: RasterSourceSnapshotFunc00) {. + importc: "cairo_raster_source_pattern_set_snapshot", libcairo.} +proc cairoRasterSourcePatternGetSnapshot*(pattern: ptr Pattern00): RasterSourceSnapshotFunc00 {. + importc: "cairo_raster_source_pattern_get_snapshot", libcairo.} +proc cairoRasterSourcePatternSetCopy*(pattern: ptr Pattern00; + copy: RasterSourceCopyFunc00) {. + importc: "cairo_raster_source_pattern_set_copy", libcairo.} +proc cairoRasterSourcePatternGetCopy*(pattern: ptr Pattern00): RasterSourceCopyFunc00 {. + importc: "cairo_raster_source_pattern_get_copy", libcairo.} +proc cairoRasterSourcePatternSetFinish*(pattern: ptr Pattern00; + finish: RasterSourceFinishFunc00) {. + importc: "cairo_raster_source_pattern_set_finish", libcairo.} +proc cairoRasterSourcePatternGetFinish*(pattern: ptr Pattern00): RasterSourceFinishFunc00 {. + importc: "cairo_raster_source_pattern_get_finish", libcairo.} + +proc cairoPatternCreateRgb*(red: cdouble; green: cdouble; blue: cdouble): ptr Pattern00 {. + importc: "cairo_pattern_create_rgb", libcairo.} +proc cairoPatternCreateRgba*(red: cdouble; green: cdouble; blue: cdouble; + alpha: cdouble): ptr Pattern00 {. + importc: "cairo_pattern_create_rgba", libcairo.} +proc cairoPatternCreateForSurface*(surface: ptr Surface00): ptr Pattern00 {. + importc: "cairo_pattern_create_for_surface", libcairo.} +proc cairoPatternCreateLinear*(x0: cdouble; y0: cdouble; x1: cdouble; y1: cdouble): ptr Pattern00 {. + importc: "cairo_pattern_create_linear", libcairo.} +proc cairoPatternCreateRadial*(cx0: cdouble; cy0: cdouble; radius0: cdouble; + cx1: cdouble; cy1: cdouble; radius1: cdouble): ptr Pattern00 {. + importc: "cairo_pattern_create_radial", libcairo.} +proc cairoPatternCreateMesh*(): ptr Pattern00 {. + importc: "cairo_pattern_create_mesh", libcairo.} +proc cairoPatternReference*(pattern: ptr Pattern00): ptr Pattern00 {. + importc: "cairo_pattern_reference", libcairo.} +proc cairoPatternDestroy*(pattern: ptr Pattern00) {. + importc: "cairo_pattern_destroy", libcairo.} +proc cairoPatternGetReferenceCount*(pattern: ptr Pattern00): cuint {. + importc: "cairo_pattern_get_reference_count", libcairo.} +proc cairoPatternStatus*(pattern: ptr Pattern00): Status {. + importc: "cairo_pattern_status", libcairo.} +proc cairoPatternGetUserData*(pattern: ptr Pattern00; key: ptr UserDataKey00): pointer {. + importc: "cairo_pattern_get_user_data", libcairo.} +proc cairoPatternSetUserData*(pattern: ptr Pattern00; + key: ptr UserDataKey00; userData: pointer; + destroy: DestroyFunc00): Status {. + importc: "cairo_pattern_set_user_data", libcairo.} + +type + PatternType* {.size: sizeof(cint), pure.} = enum + solid, surface, + linear, radial, mesh, + raster_source + +proc cairoPatternGetType*(pattern: ptr Pattern00): PatternType {. + importc: "cairo_pattern_get_type", libcairo.} +proc cairoPatternAddColorStopRgb*(pattern: ptr Pattern00; offset: cdouble; + red: cdouble; green: cdouble; blue: cdouble) {. + importc: "cairo_pattern_add_color_stop_rgb", libcairo.} +proc cairoPatternAddColorStopRgba*(pattern: ptr Pattern00; offset: cdouble; + red: cdouble; green: cdouble; blue: cdouble; + alpha: cdouble) {. + importc: "cairo_pattern_add_color_stop_rgba", libcairo.} +proc cairoMeshPatternBeginPatch*(pattern: ptr Pattern00) {. + importc: "cairo_mesh_pattern_begin_patch", libcairo.} +proc cairoMeshPatternEndPatch*(pattern: ptr Pattern00) {. + importc: "cairo_mesh_pattern_end_patch", libcairo.} +proc cairoMeshPatternCurveTo*(pattern: ptr Pattern00; x1: cdouble; y1: cdouble; + x2: cdouble; y2: cdouble; x3: cdouble; y3: cdouble) {. + importc: "cairo_mesh_pattern_curve_to", libcairo.} +proc cairoMeshPatternLineTo*(pattern: ptr Pattern00; x: cdouble; y: cdouble) {. + importc: "cairo_mesh_pattern_line_to", libcairo.} +proc cairoMeshPatternMoveTo*(pattern: ptr Pattern00; x: cdouble; y: cdouble) {. + importc: "cairo_mesh_pattern_move_to", libcairo.} +proc cairoMeshPatternSetControlPoint*(pattern: ptr Pattern00; pointNum: cuint; + x: cdouble; y: cdouble) {. + importc: "cairo_mesh_pattern_set_control_point", libcairo.} +proc cairoMeshPatternSetCornerColorRgb*(pattern: ptr Pattern00; + cornerNum: cuint; red: cdouble; + green: cdouble; blue: cdouble) {. + importc: "cairo_mesh_pattern_set_corner_color_rgb", libcairo.} +proc cairoMeshPatternSetCornerColorRgba*(pattern: ptr Pattern00; + cornerNum: cuint; red: cdouble; + green: cdouble; blue: cdouble; + alpha: cdouble) {. + importc: "cairo_mesh_pattern_set_corner_color_rgba", libcairo.} +proc cairoPatternSetMatrix*(pattern: ptr Pattern00; matrix: ptr Matrix00) {. + importc: "cairo_pattern_set_matrix", libcairo.} +proc cairoPatternGetMatrix*(pattern: ptr Pattern00; matrix: ptr Matrix00) {. + importc: "cairo_pattern_get_matrix", libcairo.} + +type + Extend* {.size: sizeof(cint), pure.} = enum + none, repeat, reflect, pad + +proc cairoPatternSetExtend*(pattern: ptr Pattern00; extend: Extend) {. + importc: "cairo_pattern_set_extend", libcairo.} +proc cairoPatternGetExtend*(pattern: ptr Pattern00): Extend {. + importc: "cairo_pattern_get_extend", libcairo.} + +type + Filter* {.size: sizeof(cint), pure.} = enum + fast, good, best, nearest, + bilinear, gaussian + +proc cairoPatternSetFilter*(pattern: ptr Pattern00; filter: Filter) {. + importc: "cairo_pattern_set_filter", libcairo.} +proc cairoPatternGetFilter*(pattern: ptr Pattern00): Filter {. + importc: "cairo_pattern_get_filter", libcairo.} +proc cairoPatternGetRgba*(pattern: ptr Pattern00; red: var cdouble; + green: var cdouble; blue: var cdouble; alpha: var cdouble): Status {. + importc: "cairo_pattern_get_rgba", libcairo.} +proc cairoPatternGetSurface*(pattern: ptr Pattern00; + surface: ptr ptr Surface00): Status {. + importc: "cairo_pattern_get_surface", libcairo.} +proc cairoPatternGetColorStopRgba*(pattern: ptr Pattern00; index: cint; + offset: var cdouble; red: var cdouble; + green: var cdouble; blue: var cdouble; + alpha: var cdouble): Status {. + importc: "cairo_pattern_get_color_stop_rgba", libcairo.} +proc cairoPatternGetColorStopCount*(pattern: ptr Pattern00; count: var cint): Status {. + importc: "cairo_pattern_get_color_stop_count", libcairo.} +proc cairoPatternGetLinearPoints*(pattern: ptr Pattern00; x0: var cdouble; + y0: var cdouble; x1: var cdouble; y1: var cdouble): Status {. + importc: "cairo_pattern_get_linear_points", libcairo.} +proc cairoPatternGetRadialCircles*(pattern: ptr Pattern00; x0: var cdouble; + y0: var cdouble; r0: var cdouble; x1: var cdouble; + y1: var cdouble; r1: var cdouble): Status {. + importc: "cairo_pattern_get_radial_circles", libcairo.} +proc cairoMeshPatternGetPatchCount*(pattern: ptr Pattern00; count: var cuint): Status {. + importc: "cairo_mesh_pattern_get_patch_count", libcairo.} +proc cairoMeshPatternGetPath*(pattern: ptr Pattern00; patchNum: cuint): ptr Path00 {. + importc: "cairo_mesh_pattern_get_path", libcairo.} +proc cairoMeshPatternGetCornerColorRgba*(pattern: ptr Pattern00; + patchNum: cuint; cornerNum: cuint; + red: var cdouble; green: var cdouble; + blue: var cdouble; alpha: var cdouble): Status {. + importc: "cairo_mesh_pattern_get_corner_color_rgba", libcairo.} +proc cairoMeshPatternGetControlPoint*(pattern: ptr Pattern00; patchNum: cuint; + pointNum: cuint; x: var cdouble; y: var cdouble): Status {. + importc: "cairo_mesh_pattern_get_control_point", libcairo.} + +proc cairoMatrixInit*(matrix: ptr Matrix00; xx: cdouble; yx: cdouble; xy: cdouble; + yy: cdouble; x0: cdouble; y0: cdouble) {. + importc: "cairo_matrix_init", libcairo.} +proc cairoMatrixInitIdentity*(matrix: ptr Matrix00) {. + importc: "cairo_matrix_init_identity", libcairo.} +proc cairoMatrixInitTranslate*(matrix: ptr Matrix00; tx: cdouble; ty: cdouble) {. + importc: "cairo_matrix_init_translate", libcairo.} +proc cairoMatrixInitScale*(matrix: ptr Matrix00; sx: cdouble; sy: cdouble) {. + importc: "cairo_matrix_init_scale", libcairo.} +proc cairoMatrixInitRotate*(matrix: ptr Matrix00; radians: cdouble) {. + importc: "cairo_matrix_init_rotate", libcairo.} +proc cairoMatrixTranslate*(matrix: ptr Matrix00; tx: cdouble; ty: cdouble) {. + importc: "cairo_matrix_translate", libcairo.} +proc cairoMatrixScale*(matrix: ptr Matrix00; sx: cdouble; sy: cdouble) {. + importc: "cairo_matrix_scale", libcairo.} +proc cairoMatrixRotate*(matrix: ptr Matrix00; radians: cdouble) {. + importc: "cairo_matrix_rotate", libcairo.} +proc cairoMatrixInvert*(matrix: ptr Matrix00): Status {. + importc: "cairo_matrix_invert", libcairo.} +proc cairoMatrixMultiply*(result: ptr Matrix00; a: ptr Matrix00; + b: ptr Matrix00) {.importc: "cairo_matrix_multiply", + libcairo.} +proc cairoMatrixTransformDistance*(matrix: ptr Matrix00; dx: var cdouble; + dy: var cdouble) {. + importc: "cairo_matrix_transform_distance", libcairo.} +proc cairoMatrixTransformPoint*(matrix: ptr Matrix00; x: var cdouble; + y: var cdouble) {. + importc: "cairo_matrix_transform_point", libcairo.} + +type + RegionOverlap* {.size: sizeof(cint), pure.} = enum + `in`, `out`, part + +proc cairoRegionCreate*(): ptr Region00 {.importc: "cairo_region_create", + libcairo.} +proc cairoRegionCreateRectangle*(rectangle: ptr RectangleInt00): ptr Region00 {. + importc: "cairo_region_create_rectangle", libcairo.} +proc cairoRegionCreateRectangles*(rects: ptr RectangleInt00; count: cint): ptr Region00 {. + importc: "cairo_region_create_rectangles", libcairo.} +proc cairoRegionCopy*(original: ptr Region00): ptr Region00 {. + importc: "cairo_region_copy", libcairo.} +proc cairoRegionReference*(region: ptr Region00): ptr Region00 {. + importc: "cairo_region_reference", libcairo.} +proc cairoRegionDestroy*(region: ptr Region00) {. + importc: "cairo_region_destroy", libcairo.} +proc cairoRegionEqual*(a: ptr Region00; b: ptr Region00): Bool00 {. + importc: "cairo_region_equal", libcairo.} +proc cairoRegionStatus*(region: ptr Region00): Status {. + importc: "cairo_region_status", libcairo.} +proc cairoRegionGetExtents*(region: ptr Region00; + extents: ptr RectangleInt00) {. + importc: "cairo_region_get_extents", libcairo.} +proc cairoRegionNumRectangles*(region: ptr Region00): cint {. + importc: "cairo_region_num_rectangles", libcairo.} +proc cairoRegionGetRectangle*(region: ptr Region00; nth: cint; + rectangle: ptr RectangleInt00) {. + importc: "cairo_region_get_rectangle", libcairo.} +proc cairoRegionIsEmpty*(region: ptr Region00): Bool00 {. + importc: "cairo_region_is_empty", libcairo.} +proc cairoRegionContainsRectangle*(region: ptr Region00; + rectangle: ptr RectangleInt00): RegionOverlap {. + importc: "cairo_region_contains_rectangle", libcairo.} +proc cairoRegionContainsPoint*(region: ptr Region00; x: cint; y: cint): Bool00 {. + importc: "cairo_region_contains_point", libcairo.} +proc cairoRegionTranslate*(region: ptr Region00; dx: cint; dy: cint) {. + importc: "cairo_region_translate", libcairo.} +proc cairoRegionSubtract*(dst: ptr Region00; other: ptr Region00): Status {. + importc: "cairo_region_subtract", libcairo.} +proc cairoRegionSubtractRectangle*(dst: ptr Region00; + rectangle: ptr RectangleInt00): Status {. + importc: "cairo_region_subtract_rectangle", libcairo.} +proc cairoRegionIntersect*(dst: ptr Region00; other: ptr Region00): Status {. + importc: "cairo_region_intersect", libcairo.} +proc cairoRegionIntersectRectangle*(dst: ptr Region00; + rectangle: ptr RectangleInt00): Status {. + importc: "cairo_region_intersect_rectangle", libcairo.} +proc cairoRegionUnion*(dst: ptr Region00; other: ptr Region00): Status {. + importc: "cairo_region_union", libcairo.} +proc cairoRegionUnionRectangle*(dst: ptr Region00; + rectangle: ptr RectangleInt00): Status {. + importc: "cairo_region_union_rectangle", libcairo.} +proc cairoRegionXor*(dst: ptr Region00; other: ptr Region00): Status {. + importc: "cairo_region_xor", libcairo.} +proc cairoRegionXorRectangle*(dst: ptr Region00; + rectangle: ptr RectangleInt00): Status {. + importc: "cairo_region_xor_rectangle", libcairo.} + +proc cairoDebugResetStaticData*() {.importc: "cairo_debug_reset_static_data", + libcairo.} + +when CAIRO_HAS_PDF_SURFACE: + type + PdfVersion* {.size: sizeof(cint), pure.} = enum + v1_4, v1_5 + proc cairoPdfSurfaceCreate*(filename: cstring; widthInPoints: cdouble; + heightInPoints: cdouble): ptr Surface00 {. + importc: "cairo_pdf_surface_create", libcairo.} + proc cairoPdfSurfaceCreateForStream*(writeFunc: WriteFunc00; + closure: pointer; widthInPoints: cdouble; + heightInPoints: cdouble): ptr Surface00 {. + importc: "cairo_pdf_surface_create_for_stream", libcairo.} + proc cairoPdfSurfaceRestrictToVersion*(surface: ptr Surface00; + version: PdfVersion) {. + importc: "cairo_pdf_surface_restrict_to_version", libcairo.} + proc cairoPdfGetVersions*(versions: ptr ptr PdfVersion; numVersions: var cint) {. + importc: "cairo_pdf_get_versions", libcairo.} + proc cairoPdfVersionToString*(version: PdfVersion): cstring {. + importc: "cairo_pdf_version_to_string", libcairo.} + proc cairoPdfSurfaceSetSize*(surface: ptr Surface00; widthInPoints: cdouble; + heightInPoints: cdouble) {. + importc: "cairo_pdf_surface_set_size", libcairo.} + type + PdfOutlineFlags* {.size: sizeof(cint), pure.} = enum + flag_open = 0x1, + flag_bold = 0x2, + flag_italic = 0x4 + const + CAIRO_PDF_OUTLINE_ROOT* = 0 + proc cairoPdfSurfaceAddOutline*(surface: ptr Surface00; parentId: cint; + utf8: cstring; dest: cstring; + flags: PdfOutlineFlags): cint {. + importc: "cairo_pdf_surface_add_outline", libcairo.} + type + PdfMetadata* {.size: sizeof(cint), pure.} = enum + title, author, + subject, keywords, + creator, create_date, + mod_date + proc cairoPdfSurfaceSetMetadata*(surface: ptr Surface00; + metadata: PdfMetadata; utf8: cstring) {. + importc: "cairo_pdf_surface_set_metadata", libcairo.} + proc cairoPdfSurfaceSetPageLabel*(surface: ptr Surface00; utf8: cstring) {. + importc: "cairo_pdf_surface_set_page_label", libcairo.} + proc cairoPdfSurfaceSetThumbnailSize*(surface: ptr Surface00; width: cint; + height: cint) {. + importc: "cairo_pdf_surface_set_thumbnail_size", libcairo.} + +when CAIRO_HAS_PS_SURFACE: + type + PS_Level* {.size: sizeof(cint), pure.} = enum + l2, l3 + proc cairoPsSurfaceCreate*(filename: cstring; widthInPoints: cdouble; + heightInPoints: cdouble): ptr Surface00 {. + importc: "cairo_ps_surface_create", libcairo.} + proc cairoPsSurfaceCreateForStream*(writeFunc: WriteFunc00; closure: pointer; + widthInPoints: cdouble; + heightInPoints: cdouble): ptr Surface00 {. + importc: "cairo_ps_surface_create_for_stream", libcairo.} + proc cairoPsSurfaceRestrictToLevel*(surface: ptr Surface00; + level: PsLevel) {. + importc: "cairo_ps_surface_restrict_to_level", libcairo.} + proc cairoPsGetLevels*(levels: ptr ptr PsLevel; numLevels: var cint) {. + importc: "cairo_ps_get_levels", libcairo.} + proc cairoPsLevelToString*(level: PsLevel): cstring {. + importc: "cairo_ps_level_to_string", libcairo.} + proc cairoPsSurfaceSetEps*(surface: ptr Surface00; eps: Bool00) {. + importc: "cairo_ps_surface_set_eps", libcairo.} + proc cairoPsSurfaceGetEps*(surface: ptr Surface00): Bool00 {. + importc: "cairo_ps_surface_get_eps", libcairo.} + proc cairoPsSurfaceSetSize*(surface: ptr Surface00; widthInPoints: cdouble; + heightInPoints: cdouble) {. + importc: "cairo_ps_surface_set_size", libcairo.} + proc cairoPsSurfaceDscComment*(surface: ptr Surface00; comment: cstring) {. + importc: "cairo_ps_surface_dsc_comment", libcairo.} + proc cairoPsSurfaceDscBeginSetup*(surface: ptr Surface00) {. + importc: "cairo_ps_surface_dsc_begin_setup", libcairo.} + proc cairoPsSurfaceDscBeginPageSetup*(surface: ptr Surface00) {. + importc: "cairo_ps_surface_dsc_begin_page_setup", libcairo.} + +when CAIRO_HAS_SVG_SURFACE: + type + SvgVersion* {.size: sizeof(cint), pure.} = enum + v1_1, v1_2 + proc cairoSvgSurfaceCreate*(filename: cstring; widthInPoints: cdouble; + heightInPoints: cdouble): ptr Surface00 {. + importc: "cairo_svg_surface_create", libcairo.} + proc cairoSvgSurfaceCreateForStream*(writeFunc: WriteFunc00; + closure: pointer; widthInPoints: cdouble; + heightInPoints: cdouble): ptr Surface00 {. + importc: "cairo_svg_surface_create_for_stream", libcairo.} + proc cairoSvgSurfaceRestrictToVersion*(surface: ptr Surface00; + version: SvgVersion) {. + importc: "cairo_svg_surface_restrict_to_version", libcairo.} + proc cairoSvgGetVersions*(versions: ptr ptr SvgVersion; numVersions: var cint) {. + importc: "cairo_svg_get_versions", libcairo.} + proc cairoSvgVersionToString*(version: SvgVersion): cstring {. + importc: "cairo_svg_version_to_string", libcairo.} + +when CAIRO_HAS_XML_SURFACE: + proc cairoXmlCreate*(filename: cstring): ptr Device00 {. + importc: "cairo_xml_create", libcairo.} + proc cairoXmlCreateForStream*(writeFunc: WriteFunc00; closure: pointer): ptr Device00 {. + importc: "cairo_xml_create_for_stream", libcairo.} + proc cairoXmlSurfaceCreate*(xml: ptr Device00; content: Content; + width: cdouble; height: cdouble): ptr Surface00 {. + importc: "cairo_xml_surface_create", libcairo.} + proc cairoXmlForRecordingSurface*(xml: ptr Device00; + surface: ptr Surface00): Status {. + importc: "cairo_xml_for_recording_surface", libcairo.} + +when CAIRO_HAS_SCRIPT_SURFACE: + type + ScriptMode* {.size: sizeof(cint), pure.} = enum + ascii, binary + proc cairoScriptCreate*(filename: cstring): ptr Device00 {. + importc: "cairo_script_create", libcairo.} + proc cairoScriptCreateForStream*(writeFunc: WriteFunc00; closure: pointer): ptr Device00 {. + importc: "cairo_script_create_for_stream", libcairo.} + proc cairoScriptWriteComment*(script: ptr Device00; comment: cstring; len: cint) {. + importc: "cairo_script_write_comment", libcairo.} + proc cairoScriptSetMode*(script: ptr Device00; mode: ScriptMode) {. + importc: "cairo_script_set_mode", libcairo.} + proc cairoScriptGetMode*(script: ptr Device00): ScriptMode {. + importc: "cairo_script_get_mode", libcairo.} + proc cairoScriptSurfaceCreate*(script: ptr Device00; content: Content; + width: cdouble; height: cdouble): ptr Surface00 {. + importc: "cairo_script_surface_create", libcairo.} + proc cairoScriptSurfaceCreateForTarget*(script: ptr Device00; + target: ptr Surface00): ptr Surface00 {. + importc: "cairo_script_surface_create_for_target", libcairo.} + proc cairoScriptFromRecordingSurface*(script: ptr Device00; + recordingSurface: ptr Surface00): Status {. + importc: "cairo_script_from_recording_surface", libcairo.} + +when CAIRO_HAS_SKIA_SURFACE: + proc cairoSkiaSurfaceCreate*(format: Format; width: cint; height: cint): ptr Surface00 {. + importc: "cairo_skia_surface_create", libcairo.} + proc cairoSkiaSurfaceCreateForData*(data: ptr cuchar; format: Format; + width: cint; height: cint; stride: cint): ptr Surface00 {. + importc: "cairo_skia_surface_create_for_data", libcairo.} + +when CAIRO_HAS_DRM_SURFACE: + type + UdevDevice* = object + proc cairoDrmDeviceGet*(device: ptr UdevDevice): ptr Device00 {. + importc: "cairo_drm_device_get", libcairo.} + proc cairoDrmDeviceGetForFd*(fd: cint): ptr Device00 {. + importc: "cairo_drm_device_get_for_fd", libcairo.} + proc cairoDrmDeviceDefault*(): ptr Device00 {. + importc: "cairo_drm_device_default", libcairo.} + proc cairoDrmDeviceGetFd*(device: ptr Device00): cint {. + importc: "cairo_drm_device_get_fd", libcairo.} + proc cairoDrmDeviceThrottle*(device: ptr Device00) {. + importc: "cairo_drm_device_throttle", libcairo.} + proc cairoDrmSurfaceCreate*(device: ptr Device00; format: Format; + width: cint; height: cint): ptr Surface00 {. + importc: "cairo_drm_surface_create", libcairo.} + proc cairoDrmSurfaceCreateForName*(device: ptr Device00; name: cuint; + format: Format; width: cint; height: cint; + stride: cint): ptr Surface00 {. + importc: "cairo_drm_surface_create_for_name", libcairo.} + proc cairoDrmSurfaceCreateFromCacheableImage*(device: ptr Device00; + surface: ptr Surface00): ptr Surface00 {. + importc: "cairo_drm_surface_create_from_cacheable_image", libcairo.} + proc cairoDrmSurfaceEnableScanOut*(surface: ptr Surface00): Status {. + importc: "cairo_drm_surface_enable_scan_out", libcairo.} + proc cairoDrmSurfaceGetHandle*(surface: ptr Surface00): cuint {. + importc: "cairo_drm_surface_get_handle", libcairo.} + proc cairoDrmSurfaceGetName*(surface: ptr Surface00): cuint {. + importc: "cairo_drm_surface_get_name", libcairo.} + proc cairoDrmSurfaceGetFormat*(surface: ptr Surface00): Format {. + importc: "cairo_drm_surface_get_format", libcairo.} + proc cairoDrmSurfaceGetWidth*(surface: ptr Surface00): cint {. + importc: "cairo_drm_surface_get_width", libcairo.} + proc cairoDrmSurfaceGetHeight*(surface: ptr Surface00): cint {. + importc: "cairo_drm_surface_get_height", libcairo.} + proc cairoDrmSurfaceGetStride*(surface: ptr Surface00): cint {. + importc: "cairo_drm_surface_get_stride", libcairo.} + proc cairoDrmSurfaceMapToImage*(surface: ptr Surface00): ptr Surface00 {. + importc: "cairo_drm_surface_map_to_image", libcairo.} + proc cairoDrmSurfaceUnmap*(drmSurface: ptr Surface00; + imageSurface: ptr Surface00) {. + importc: "cairo_drm_surface_unmap", libcairo.} + +when CAIRO_HAS_TEE_SURFACE: + proc cairoTeeSurfaceCreate*(master: ptr Surface00): ptr Surface00 {. + importc: "cairo_tee_surface_create", libcairo.} + proc cairoTeeSurfaceAdd*(surface: ptr Surface00; target: ptr Surface00) {. + importc: "cairo_tee_surface_add", libcairo.} + proc cairoTeeSurfaceRemove*(surface: ptr Surface00; target: ptr Surface00) {. + importc: "cairo_tee_surface_remove", libcairo.} + proc cairoTeeSurfaceIndex*(surface: ptr Surface00; index: cuint): ptr Surface00 {. + importc: "cairo_tee_surface_index", libcairo.} + diff --git a/gintro/gimpl.nim b/gintro/gimpl.nim new file mode 100644 index 0000000..4520666 --- /dev/null +++ b/gintro/gimpl.nim @@ -0,0 +1,137 @@ +let ct4nt = [ + "int32|int", + "uint32|int", + "gboolean|toBool", + "cstring|$"] + +proc ct5nt(s: string): string = + for i in ct4nt: + if i.startsWith(s): + return i[s.len + 1 .. ^1] + +proc findSignal(name, obj: NimNode): string = + let str = ($name).replace("-", "_") & "|" + for i in SCA: + if i.startsWith(str): + let t = i.split("|", 2)[1] + var n = obj + while true: + if n.kind != nnkBracketExpr: break + var h = $getType(n)[1].toStrLit + if h.endsWith(":ObjectType"): + h.setLen(h.len - 11) + if h == t: + return i + n = getType(n)[1] + n = getType(n)[1] + +var ProcID: int + +macro mconnect(widget: gobject.Object; signal: string; p: untyped; arg: typed; ignoreArg: bool): typed = + inc(ProcID) + let wt = getType(widget) + #echo "@@@", $(getTypeInst(widget).toStrLit) + let at = getTypeInst(arg) + let wts = ($(wt[1].toStrLit)).replace(":ObjectType") + #echo wts + let ats = $at.toStrLit + let signalName = ($signal).replace("-", "_") # maybe we should just use plain proc names + let procNameCdecl = "connect_for_signal_cdecl_" & signalName & $ProcID + let procName = "connect_for_signal_" & signalName & $ProcID + var sn, wid, num, all, ahl: string + let sci = findSignal(signal, wt) + var r1s = """ +proc $1$2 {.cdecl.} = + let h: pointer = g_object_get_qdata(self, Quark) +""" + if sci.isNil: + all = "(self: ptr gobject.Object00; xdata: pointer)" + ahl = "(self: gobject.Object)" + r1s.add(" $3(cast[$4](h)") + if not ignoreArg.boolVal: + r1s.add(", cast[$5](xdata)") + r1s.add(")\n") + else: + (sn, wid, num, ahl, all) = sci.split("|") + #echo ahl, all + var resl: string + if ahl.contains("): "): + resl = all.rsplit("): ", 1)[1] + var resu = " $3(cast[$4](h)" + if all.find(";") > 0: + var largs = all.split("; ") + #if largs.len > 0: + largs.delete(0) + largs[^1] = largs[^1].split(")")[0] + var names, types: array[10, string] + var plainArgs = newSeq[string]() + for i in 0 .. largs.high: + if largs[i].endsWith("00"): + (names[i], types[i]) = largs[i].split(": ptr ") + types[i].setLen(types[i].len - 2) + else: + var a1, a2: string + (a1, a2) = largs[i].split(": ") + let h = ct5nt(a2) + if h.len > 0: + a1 = h & "(" & a1 & ")" + plainArgs.add(a1) + #var resu = " $3(cast[$4](h)" + for i in 0 .. 9: + if names[i].isNil: break + resu.add(", " & names[i] & "1") + r1s.add(" var " & names[i] & "1: " & types[i] & "\n") + r1s.add(" new " & names[i] & "1" & "\n") + r1s.add(" " & names[i] & "1.impl = " & names[i] & "\n") + for i in plainArgs: + resu.add(", " & i) + if not ignoreArg.boolVal: + resu.add(", cast[$5](data)") + resu.add(")") + if resl == "gboolean": + resu.add(".ord.gboolean") + r1s.add(resu & "\n") + all = all.replace(")", "; data: pointer)") + r1s = r1s % [$procNameCdecl, all, $p, wts, ats] + #echo r1s + result = parseStmt(r1s) + if not ignoreArg.boolVal: + ahl = ahl.replace(")", "; arg: " & ats & ")") + #echo ahl + if ahl.find(";") > 0: + ahl = "(self: " & wts & ";" & ahl.split(";", 1)[1] + else: + ahl = "(self: " & wts & ")" & ahl.split(")", 1)[1] + #ahl = "(self: " & wts & ")" + + let r2s = + if ignoreArg.boolVal: + """ +proc $1(self: $2; p: proc $3) = + sc$4(self, $5, nil) +$1($6, $7) +""" % [$procName, wts, ahl, signalName, $procNameCdecl, $(widget.toStrLit), $p] + else: + """ +proc $1(self: $2; p: proc $3; a: $4) = + when a is RootRef: + GC_ref(a) + sc$5(self, $6, cast[pointer](a)) + else: + var ar: ref $4 + new(ar) + deepCopy(ar[], a) + GC_ref(ar) + sc$5(self, $6, cast[pointer](ar[])) +$1($7, $8, $9) +""" % [$procName, wts, ahl, ats, signalName, $procNameCdecl, $(widget.toStrLit), $p, $(arg.toStrLit)] + #echo r2s + result.add(parseStmt(r2s)) + +template connect*(widget: gobject.Object; signal: string; p: untyped; arg: typed): typed = + mconnect(widget, signal, p, arg, false) + +template connect*(widget: gobject.Object; signal: string; p: untyped): typed = + mconnect(widget, signal, p, "", true) + + diff --git a/tests/gen.nim b/tests/gen.nim index 2ac2a58..c8afb21 100644 --- a/tests/gen.nim +++ b/tests/gen.nim @@ -1,5 +1,5 @@ # High level gobject-introspection based GTK3 bindings for the Nim programming language -# v 0.1 2017-JUL-21 +# v 0.2 2017-AUG-29 # (c) S. Salewski 2017 # https://wiki.gnome.org/Projects/GObjectIntrospection @@ -69,7 +69,7 @@ type using var when while with without xor yield """ let nims = """ -int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 pointer +int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 pointer false true string char bool """ proc mysnakeToCamel(s: cstring): string = @@ -108,6 +108,7 @@ var fixedProcNames = newTable[string, string]() var mangledNames = newTable[string, string]() var gdkKeys = newTable[string, seq[string]]() var allSyms: HashSet[string] +#var scfilter: HashSet[string] var provInt = newTable[string, seq[string]]() var interfaceProvider = newTable[string, seq[string]]() var priList: seq[string] @@ -124,6 +125,12 @@ var classList: seq[GIBaseInfo] var ct: CountTable[string] fixedProcNames.add("gtk_button_new_with_label", "newButton") +fixedProcNames.add("pango_font_description_from_string", "newFontDescription") +fixedProcNames.add("pango_language_from_string", "languageFromString") +fixedProcNames.add("gdk_event_get", "getEvent") +fixedProcNames.add("gdk_display_manager_get", "getDisplayManager") +fixedProcNames.add("gdk_display_get_default", "getDefaultDisplay") + defaultParameters.add("gtk_window_new", "`type` WindowType WindowType.toplevel") defaultParameters.add("gtk_application_new", "flags gio.ApplicationFlags {}") for i in keywords.split: mangledNames.add(i, '`' & i & '`') @@ -224,6 +231,7 @@ proc mangleType(s: cstring): string = echo "!!!", result var output: StringStream +var supmod: StringStream var methodBuffer: StringStream proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (string, string, TableRef[string, string]) @@ -264,6 +272,7 @@ proc genRec(t: GITypeInfo; genProxy = false; fullQualified: bool = false): strin else: var ns = ($gBaseInfoGetNamespace(iface)).toLowerAscii result = mangleName($gBaseInfoGetName(iface)) + if ns == "cairo" and moduleNamespace == "pangocairo" and result == "FontType": return result # GI bug? if gBaseInfoGetType(iface) == GIInfoType.Object or gBaseInfoGetType(iface) == GIInfoType.STRUCT or gBaseInfoGetType(iface) == GIInfoType.UNION or gBaseInfoGetType(iface) == GIInfoType.INTERFACE: proxyResult = genProxy if not (genProxy or callerAlloc.contains(ns & '.' & result)): @@ -284,6 +293,7 @@ proc isProxyCandidate(t: GITypeInfo): bool = let iface = gTypeInfoGetInterface(t) var ns = ($gBaseInfoGetNamespace(iface)).toLowerAscii if callerAlloc.contains(ns & '.' & $gBaseInfoGetName(iface)): return false + if ns == "cairo" and moduleNamespace == "pangocairo" and $gBaseInfoGetName(iface) == "FontType": return false # GI bug? result = gBaseInfoGetType(iface) in {GIInfoType.Object, GIInfoType.STRUCT, GIInfoType.UNION, GIInfoType.INTERFACE} proc needProxyProc(info: GICallableInfo): bool = @@ -350,11 +360,12 @@ proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (str if gArgInfoIsCallerAllocates(arg): callerAllocCollector.incl(genRec(t, true, true)) var str = genRec(t, genProxy and not gArgInfoIsCallerAllocates(arg)) + if isSignalInfo(info) and isProxyCandidate(t) and not genProxy: + str.insert("ptr ") var userAlloc: bool if callerAlloc.contains(genRec(t, true, true)): userAlloc = true str = genRec(t, true) - if genProxy: let tag = gTypeInfoGetTag(t) if tag == GITypeTag.INTERFACE: @@ -364,7 +375,6 @@ proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (str let provider = interfaceProvider[str] for i in provider: discard mangleType(i) str = str & " | " & provider.join(" | ") - let name = mangleName(gBaseInfoGetName(arg)) if isProxyCandidate(t) and not gArgInfoIsCallerAllocates(arg) and not userAlloc: arglist.add("cast[" & genRec(t, false) & "](" & name & ".impl)") @@ -425,7 +435,6 @@ proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (str proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = assert(isCallableInfo(mInfo)) assert(isFunctionInfo(mInfo)) - var plist, arglist: string var replist: TableRef[string, string] let p = methodBuffer.getPosition @@ -453,8 +462,10 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = var asym = manglename(gBaseInfoGetName(mInfo)) if keywords.split.contains(asym) or nims.split.contains(asym): asym.add('P') var ret2 = gCallableInfoGetReturnType(minfo) + var ret22 = gCallableInfoGetReturnType(minfo) for run in 0 .. 1: if run == 1: + if fixedProcNames.contains(sym): continue if not (asym.startsWith("get") or asym.startsWith("set")) or asym == "getPlugin" or asym.len < 4: continue if asym.startsWith("get") and gTypeInfoGetTag(ret2) == GITypeTag.VOID: continue if asym.startsWith("set"): @@ -478,7 +489,6 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = if gBaseInfoGetType(iface) == GIInfoType.Object: isGObject = true (plist, arglist, replist) = genP(mInfo, true, info) - if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0: if info != nil: asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info))) @@ -502,6 +512,7 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = for k, v in replist: let kk = if k[0] == '`': k[1 .. ^2] else: k methodBuffer.writeLine(" var $1_00 = $2($3)" % [kk, v, k]) + #[ if isGObject: methodBuffer.writeLine(" new(result, finalizeGObject)") else: @@ -517,9 +528,45 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = methodBuffer.writeLine(" g_object_unref(result.impl)") methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)") methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))") + ]# + if isGObject: + # CAUTION: some procs are advertised as constructor but do not construct new objects, + # they just return existing ones as gdk_cursor_new_from_name() + methodBuffer.writeLine(" let gobj = " & sym & arglist) + methodBuffer.writeLine(" if g_object_get_qdata(gobj, Quark) != nil:") + let h = gBaseInfoGetContainer(minfo) + var rt: string + if gBaseInfoGetType(h) == GIInfoType.OBJECT: + rt = mangleType(mangleName(gBaseInfoGetName(h))) + else: + rt = genRec(ret2, true) + #methodBuffer.writeLine(" result = cast[$1](g_object_get_qdata(gobj, Quark))" % [rt]) + methodBuffer.writeLine(" result = cast[type(result)](g_object_get_qdata(gobj, Quark))" % [rt]) + methodBuffer.writeLine(" assert(result.impl == gobj)") + methodBuffer.writeLine(" else:") # I guess this will never get called... + if sym == "g_object_ref" or sym == "g_object_ref_sink": + methodBuffer.writeLine(" assert(false)") + else: + methodBuffer.writeLine(" new(result, finalizeGObject)") + methodBuffer.writeLine(" result.impl = gobj") + methodBuffer.writeLine(" GC_ref(result)") + methodBuffer.writeLine(" discard g_object_ref_sink(result.impl)") + methodBuffer.writeLine(" g_object_add_toggle_ref(result.impl, toggleNotify, addr(result[]))") + methodBuffer.writeLine(" g_object_unref(result.impl)") + methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)") + methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))") + else: + methodBuffer.writeLine(" new(result)") + methodBuffer.writeLine(" result.impl = " & sym & arglist) + for k, v in replist: + let kk = if k[0] == '`': k[1 .. ^2] else: k + methodBuffer.writeLine(" $1 = $2($3_00)" % [k, ct3nt(v), kk]) elif isProxyCandidate(ret2): if info != nil: asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info))) + #asym = asym.replace("get", "get" & manglename(gBaseInfoGetName(info))) + if fixedProcNames.contains(sym): + asym = fixedProcNames[sym] methodBuffer.writeLine("\nproc " & asym & EM & plist & " =") if gCallableInfoCanThrowGerror(minfo): methodBuffer.writeLine(" var gerror: ptr Error00") @@ -580,13 +627,11 @@ proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = for k, v in replist: let kk = if k[0] == '`': k[1 .. ^2] else: k methodBuffer.writeLine(" $1 = $2($3_00)" % [k, ct3nt(v), kk]) - if gCallableInfoCanThrowGerror(minfo): methodBuffer.writeLine(" if gerror != nil:") methodBuffer.writeLine(" let msg = $gerror.message") methodBuffer.writeLine(" g_error_free(gerror)") methodBuffer.writeLine(" raise newException(GException, msg)") - else: (plist, arglist, replist) = genP(mInfo, genProxy, info) if asym != "errorQuark" and asym != "getPlugin" and asym != "quark": @@ -718,15 +763,7 @@ proc writeEnum(info: GIEnumInfo) = proc writeObj(info: GIObjectInfo) = assert(gBaseInfoGetType(info) == GIInfoType.OBJECT) - let ninterfaces = info.gObjectInfoGetNInterfaces - #if ninterfaces > 0: - # stdout.write "||| ", gBaseInfoGetName(info), " has ", ninterfaces, " interf: " - # for i in 0 .. < ninterfaces: - # stdout.write " ", gBaseInfoGetName(info.gObjectInfoGetInterface(i)), "," - # stdout.writeLine("") - # stdout.flushFile - let class = gObjectInfoGetClassStruct(info) let n = info.gObjectInfoGetNFields let parent = gObjectInfoGetParent(info) # nil for Object of module gobject! @@ -754,6 +791,14 @@ proc writeObj(info: GIObjectInfo) = cnt = 9 if ns == "gio." and gBaseInfoGetName(info) == "NumerableIcon": cnt = 9 + if moduleNamespace == "gtksource" and gBaseInfoGetName(info) == "Buffer": + cnt = 9 + if moduleNamespace == "gtksource" and gBaseInfoGetName(info) == "Mark": + cnt = 9 + if moduleNamespace == "gtksource" and gBaseInfoGetName(info) == "CompletionInfo": + cnt = 9 + if moduleNamespace == "gtksource" and gBaseInfoGetName(info) == "View": + cnt = 9 if not suppressType: output.writeLine("type") if ns == "" and pname != "": # check forward exeption for parent name! @@ -781,7 +826,6 @@ proc writeObj(info: GIObjectInfo) = continue output.writeLine(" ", name, ": ", h) if mangleName(gBaseInfoGetName(info)) == "Object" and moduleNamespace == "gobject": - output.writeLine("type") output.writeLine(" GToggleNotify* = proc (data: pointer; obj: ptr Object00; isLastRef: gboolean) {.cdecl.}\n") output.writeLine("proc g_object_add_toggle_ref*(obj: ptr Object00; notify: GToggleNotify; data: pointer) {.") @@ -811,14 +855,41 @@ proc writeObj(info: GIObjectInfo) = if not c.isNil: echo "maybe we should process class closures!" if gBaseInfoGetName(signalInfo) == "notify": continue # XXX fix later - var h = genP(signalInfo)[0][1..^1] + var h = genP(signalInfo, false)[0][1..^1] + let zzzu = gCallableInfoGetReturnType(signalinfo) + if gCallableInfoGetNArgs(signalInfo) > 0 or gTypeInfoGetTag(zzzu) != GITypeTag.VOID: + var memo = "" + memo.add(gCallableInfoGetNArgs(signalInfo)) + memo.add('|') + var plist, arglist: string + var replist: TableRef[string, string] + (plist, arglist, replist) = genP(signalInfo, true, info) + memo.add(plist) + memo.add('|') + (plist, arglist, replist) = genP(signalInfo, false, info) + memo.add(plist) + memo = memo.replace("\n ", "") + supmod.writeLine(" \"" & ($gBaseInfoGetName(signalInfo)).replace("-", "_") & "|" & $gBaseInfoGetName(info) & "|" & memo & "\",") if gCallableInfoGetNArgs(signalInfo) > 0: + var plist, arglist: string + var replist: TableRef[string, string] + (plist, arglist, replist) = genP(signalInfo, false, nil) + echo plist + echo arglist + if replist.len > 0: + for k, v in replist: + stdout.write(k & "--" & v & " ") + stdout.writeLine("") + echo "PPP ", gBaseInfoGetName(signalInfo), gCallableInfoGetNArgs(signalInfo) h = h.replace(")", "; xdata: pointer)") else: h = h.replace(")", "xdata: pointer)") var xxx = mangleName(gBaseInfoGetName(info)) output.write("proc " & mangleName("sc_" & $gBaseInfoGetName(signalInfo)) & EM & "(self: " & xxx & "; ") - output.writeLine(" p: proc (self: ptr gobject.Object00; " & h & " {.cdecl.}, xdata: pointer = nil) =") + if gCallableInfoGetNArgs(signalInfo) > 0 or gTypeInfoGetTag(zzzu) != GITypeTag.VOID: + output.writeLine(" p: proc (self: ptr " & xxx & "00; " & h & " {.cdecl.}, xdata: pointer = nil) =") + else: + output.writeLine(" p: proc (self: ptr gobject.Object00; " & h & " {.cdecl.}, xdata: pointer = nil) =") output.write(" discard g_signal_connect_data(self.impl, \"") output.write($gBaseInfoGetName(signalInfo)) output.writeLine("\", cast[GCallback](p), xdata, nil, cast[ConnectFlags](0))") @@ -924,10 +995,31 @@ proc processInfo(i: GIBaseInfo) = writeConst(i) else: assert(false) +const GDK_EPI = """ + +proc gdk_window_invalidate_nilrect(self: ptr Window00; rect: ptr Rectangle; invalidateChildren: gboolean) {. + importc: "gdk_window_invalidate_rect", libprag.} + +proc invalidateRect*(self: Window; rect: ptr Rectangle = nil; invalidateChildren: bool = false) = + gdk_window_invalidate_nilrect(cast[ptr Window00](self.impl), rect, gboolean(invalidateChildren)) + +proc fixednewCursorFromName*(display: Display; name: string): Cursor = + new(result, finalizeGObject) + result.impl = gdk_cursor_new_from_name(cast[ptr Display00](display.impl), cstring(name)) + GC_ref(result) + discard g_object_ref_sink(result.impl) + g_object_add_toggle_ref(result.impl, toggleNotify, addr(result[])) + g_object_unref(result.impl) + #assert(g_object_get_qdata(result.impl, Quark) == nil) + g_object_set_qdata(result.impl, Quark, addr(result[])) + +""" + const GIO_EPI = """ proc run*(self: Application): int = int(g_application_run(cast[ptr Application00](self.impl), 0, nil)) + """ const GTK_EPI = """ @@ -942,56 +1034,11 @@ proc loadFromData*(self: CssProvider; data: cstring): bool = import macros, strutils -var ProcID: int - -macro mconnect(widget: gobject.Object; signal: string; p: untyped; arg: typed; widgett: typedesc; argt: typedesc): typed = - inc(ProcID) - let wt = getType(widgett)[1] # widget type - let at = getType(argt)[1] # argument type - let signalName = ($signal).replace("-", "_") # maybe we should just use plain proc names - let procNameCdecl = newIdentNode("connect_for_signal_cdecl_" & signalName & $ProcID) - let procName = newIdentNode("connect_for_signal_" & signalName & $ProcID) - let scName = newIdentNode("sc" & signalName) - result = quote do: - proc `procNameCdecl`(w: ptr gobject.Object00 , data: pointer) {.cdecl.} = - var h: pointer = g_object_get_qdata(w, Quark) - `p`(cast[`wt`](h), cast[`at`](data)) - - proc `procName`(self: `wt`; p: proc (self: `wt`, arg: `at`); a: `at`) = - when a is RootRef: - GC_ref(a) - `scName`(self, `procNameCdecl`, cast[pointer](a)) - else: - var ar: ref `at` - new(ar) - deepCopy(ar[], a) - GC_ref(ar) - `scName`(self, `procNameCdecl`, cast[pointer](ar[])) - `procName`(`widget`, `p`, `arg`) - -template connect*(widget: gobject.Object; signal: string; p: untyped; arg: typed) = - mconnect(widget, signal, p, arg, type(widget), type(arg)) - -macro mconnect(widget: gobject.Object; signal: string; p: untyped; widgett: typedesc): typed = - inc(ProcID) - let wt = getType(widgett)[1] - let signalName = ($signal).replace("-", "_") - let procNameCdecl = newIdentNode("connect_for_signal_cdecl_" & signalName & $ProcID) - let procName = newIdentNode("connect_for_signal_" & signalName & $ProcID) - let scName = newIdentNode("sc" & signalName) - result = quote do: - proc `procNameCdecl`(w: ptr gobject.Object00 , data: pointer) {.cdecl.} = - var h: pointer = g_object_get_qdata(w, Quark) - `p`(cast[`wt`](h)) - - proc `procName`(self: `wt`; p: proc (self: `wt`)) = - `scName`(self, `procNameCdecl`, nil) - `procName`(`widget`, `p`) - -template connect*(widget: gobject.Object; signal: string; p: untyped) = - mconnect(widget, signal, p, type(widget)) +include gisup +include gimpl """ + proc main(namespace: string) = priList = newSeq[string]() suppressType = false @@ -1038,7 +1085,8 @@ proc main(namespace: string) = output.writeLine("# ", libs) output.writeLine("{.deadCodeElim: on.}") output.writeLine(importedModules) - let Lib = if libs.isNil: "" else: ($libs).split(',', 2)[0] + var Lib = if libs.isNil: "" else: ($libs).split(',', 2)[0] + if namespace == "PangoCairo" and Lib.startsWith("libpango-"): Lib = Lib.replace("libpango-", "libpangocairo-") # GI bug? output.writeLine("const Lib* = \"$1\"" % Lib) output.writeLine("{.pragma: libprag, cdecl, dynlib: Lib.}") if namespace == "GObject": # declare array types to make it compile -- procs using these will need special care! @@ -1121,7 +1169,8 @@ proc main(namespace: string) = output.writeLine("type\n File00Array* = pointer") output.writeLine("type\n Array* = pointer") output.writeLine("type\n OutputVector00Array* = pointer") - + elif namespace == "GtkSource": + output.writeLine("import glib") if namespace == "GObject": output.writeLine("\nimport times") output.writeLine("var qt = \"NGIQ\" & $epochTime()") @@ -1207,6 +1256,7 @@ proc main(namespace: string) = unp.setLen(0) for k in delayedSyms: var pos = output.getPosition + var supmodpos = supmod.getPosition try: knownSyms.incl(mangleName(gBaseInfoGetName(k))) methodBuffer = newStringStream() @@ -1217,6 +1267,7 @@ proc main(namespace: string) = unp.add(k) knownSyms.excl(mangleName(gBaseInfoGetName(k))) output.cut(pos) + supmod.cut(supmodpos) delayedSyms = unp block myb: for a in 1 .. 2: # process clustered symbols into one single type section @@ -1226,6 +1277,7 @@ proc main(namespace: string) = unp = delayedSyms for t in unp.combinations(a + 1): var pos = output.getPosition + var supmodpos = supmod.getPosition methodBuffer = newStringStream() let x = delayedMethods.len try: @@ -1248,6 +1300,7 @@ proc main(namespace: string) = for k in t: knownSyms.excl(mangleName(gBaseInfoGetName(k))) output.setPosition(pos) + supmod.cut(supmodpos) assert delayedMethods.len >= x delayedMethods.setLen(x) suppressType = false @@ -1271,6 +1324,9 @@ proc main(namespace: string) = if namespace == "Gio": output.write(GIO_EPI) + if namespace == "Gdk": + output.write(GDK_EPI) + output.flush var o = open("nim_gi" / (namespace.toLowerAscii) & ".nim", fmWrite) o.write(output.data) @@ -1281,6 +1337,13 @@ proc main(namespace: string) = echo gBaseInfoGetName(el[1]) # when isMainModule: +#scfilter = initSet[string]() +supmod = newStringStream() +supmod.writeLine("const\n SCA = [") +main("fontconfig") +main("freetype2") +main("PangoCairo") +main("PangoFT2") main("GLib") main("GObject") main("GModule") @@ -1288,10 +1351,18 @@ main("xlib") main("Gio") main("Atk") main("Pango") -main("cairo") +# main("cairo") # that file is now hand crafted main("GdkPixbuf") main("Rsvg") main("Gdk") main("Gtk") +main("GtkSource") + +supmod.writeLine(" ]") +supmod.flush +var o = open("nim_gi" / "gisup.nim", fmWrite) +o.write(supmod.data) +o.close() +supmod.close #for i in callerAllocCollector: echo i diff --git a/tests/gen.nim.oldv0.1 b/tests/gen.nim.oldv0.1 new file mode 100644 index 0000000..2ac2a58 --- /dev/null +++ b/tests/gen.nim.oldv0.1 @@ -0,0 +1,1297 @@ +# High level gobject-introspection based GTK3 bindings for the Nim programming language +# v 0.1 2017-JUL-21 +# (c) S. Salewski 2017 + +# https://wiki.gnome.org/Projects/GObjectIntrospection +# https://developer.gnome.org/gi/1.50/index.html +# https://mail.gnome.org/archives/gtk-devel-list/2005-April/msg00095.html +# /usr/share/gir-1.0/GLib-2.0.gir + +# you may also compare the currently unmaintained work of +# https://github.com/jdmansour/nim-smartgi + +# This module itself is still based on the low level GTK 3.20 wrappers at +# https://github.com/ngtk3 + +# Currently we intentionally do not free any resources! + +# First goal is creating low level bindings similar to current ngtk3. #XXX DONE +# Then we will add the high level wrapper similar as done in Nim's libui wrapper. #XXX Mostly DONE +# What remains is carefully inspecting the generated code, adding special like list/array results +# and of course a lot of testing. + +# Known gobject-introspection related issues: +# - gFieldInfoGetSize() is always zero, so we have no bitfield support yet. +# - ParamSpec is reported as object, but has no parent +# - gBaseInfoGetName() is "" for g_iconv() +# - dirSep is wrong for unix -- that is an already reported gi bug +# - well there are more than 180 open issues about gobject introspection in gnome bugzilla :-( +# - + +# This module is really ugly currently -- the first goal was to get a working gi solution + +from os import `/` +import gir +import glib +import strutils +import sequtils +import streams +import sets +import bitops +import tables +import algorithm +from combinatorics import combinations + +template isCallbackInfo(info: untyped): untyped = + (gBaseInfoGetType(cast[GIBaseInfo](info)) == GIInfoType.Callback) + +template isFunctionInfo(info: untyped): untyped = + (gBaseInfoGetType(cast[GIBaseInfo](info)) == GIInfoType.Function) + +const EM = "*" + +# hope that will work reliable +proc cut(s: var StringStream; pos: int) = + assert(pos >= 0 and pos <= s.getPosition) + s.setPosition(pos) + s.data.setLen(pos) + s.setPosition(pos) + +var moduleNamespace: string +let libprag: string = "libprag" + +let keywords = """ +addr and as asm atomic bind block break case cast concept const continue converter +defer discard distinct div do elif else end enum except export finally for from func +generic if import in include interface is isnot iterator let macro method mixin mod +nil not notin object of or out proc ptr raise ref return shl shr static template try tuple +type using var when while with without xor yield +""" + +let nims = """ +int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 pointer +""" + +proc mysnakeToCamel(s: cstring): string = + var i, j: int + result = newString(s.len) + if s[i] == '_': inc(i) + while true: + if s[i] == '_' and (s[i + 1] == '\0' or s[i + 1] == '_'): + inc(i) + elif (s[i] == '_' or s[i] == '-') and s[i + 1].isLowerAscii and not s[i - 1].isUpperAscii: + inc(i) + result[j] = toUpperAscii(s[i]) + inc(i) + inc(j) + else: + result[j] = s[i] + inc(i) + inc(j) + if s[i] == '\0': + result.setLen(j) + break + if result[0] == '\0': # this may result, so we emit a dummy name as marker + result = "QQQ" + #assert(false) + +proc renumber(s: var string; i: int) = + var h = "" + if s[^1].isDigit: + h.add(s[^1]) + setLen(s, s.len - 1) + s.add($i) + s.add(h) + +var defaultParameters = newTable[string, string]() +var fixedProcNames = newTable[string, string]() +var mangledNames = newTable[string, string]() +var gdkKeys = newTable[string, seq[string]]() +var allSyms: HashSet[string] +var provInt = newTable[string, seq[string]]() +var interfaceProvider = newTable[string, seq[string]]() +var priList: seq[string] +var knownSyms: HashSet[string] +var suppressType = false +var suppressRaise = false +var droppedSyms = initSet[string]() +var callerAlloc = initSet[string]() +var callerAllocCollector = initSet[string]() +var privStr = initSet[string]() +var processedFunctions = initSet[string]() +var delayedMethods: seq[(GIBaseInfo, GIFunctionInfo)] +var classList: seq[GIBaseInfo] +var ct: CountTable[string] + +fixedProcNames.add("gtk_button_new_with_label", "newButton") +defaultParameters.add("gtk_window_new", "`type` WindowType WindowType.toplevel") +defaultParameters.add("gtk_application_new", "flags gio.ApplicationFlags {}") +for i in keywords.split: mangledNames.add(i, '`' & i & '`') + +mangledNames.add("CSET_A_2_Z", "CSET_A_2_Z_U") +mangledNames.add("CSET_a_2_z", "CSET_a_2_z_L") +mangledNames.add("2big", "tooBig") +mangledNames.add("2buttonPress", "twoButtonPress") +mangledNames.add("3buttonPress", "threeButtonPress") +mangledNames.add("result", "resu") + +proc mangleName(s: cstring): string = + result = mysnakeToCamel(s) + if mangledNames.contains(result): + result = mangledNames[result] + if result == "``": + # assert(false) + result = "xxx" # XXX + +var mangledTypes = newTable[string, string]() + +mangledTypes.add("gint8", "int8") +mangledTypes.add("gint16", "int16") +mangledTypes.add("gint32", "int32") +mangledTypes.add("gint64", "int64") +mangledTypes.add("guint8", "uint8") +mangledTypes.add("guint16", "uint16") +mangledTypes.add("guint32", "uint32") +mangledTypes.add("guint64", "uint64") +mangledTypes.add("gfloat", "cfloat") +mangledTypes.add("gdouble", "cdouble") +mangledTypes.add("ptr void", "pointer") +mangledTypes.add("ptr filename", "ucstring") # WRONG, var deleted to make it compile! +mangledTypes.add("ptr error", "ptr Error00") +mangledTypes.add("ptr ghash", "ptr HashTable00") +mangledTypes.add("ptr glist", "ptr pointer") +mangledTypes.add("ptr gslist", "ptr pointer") +mangledTypes.add("ptr utf8", "cstring") + +droppedSyms.incl("MININT8") +droppedSyms.incl("MININT16") +droppedSyms.incl("MININT32") +droppedSyms.incl("MININT64") + +# we may have to add digits to avoid name conflicts due to inheritance +privStr.incl("privat") +privStr.incl("priv") +privStr.incl("padding") +privStr.incl("pad") +privStr.incl("unused") +privStr.incl("privateData") + +callerAlloc.incl("atk.Rectangle") # ATK has TextRectangle and Rectangle! +callerAlloc.incl("pango.Color") # we have to add these manually -- maybe there are more plain structs to add + +const CA_Items = """ +pango.Style +pango.Stretch +glib.MarkupParser +glib.TimeVal +gtk.TextIter +pango.Weight +gdk.Rectangle +gtk.AccelKey +gtk.TextAttributes +gobject.Value +gobject.SignalQuery +gobject.TypeQuery +gtk.TreeIter +gtk.StockItem +glib.String +gdk.Atom +rsvg.PositionData +rsvg.DimensionData +pango.Variant +gdk.Color +gtk.Border +atk.TextRectangle +gdk.RGBA +pango.Rectangle +gtk.Requisition +""" +for i in CA_Items.split: + callerAlloc.incl(i) + +type + UndefEx = object of Exception + +proc mangleType(s: cstring): string = + result = mangleName(s) + if mangledTypes.contains(result): + result = mangledTypes[result] + if allSyms.contains(result) and not knownSyms.contains(result): + if not suppressRaise: + pri_list.add(result) + raise newException(UndefEx, "forward declaration") + else: + echo "!!!", result + +var output: StringStream +var methodBuffer: StringStream + +proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (string, string, TableRef[string, string]) + +proc isString(t: GITypeInfo): bool = + let tag = gTypeInfoGetTag(t) + tag == GITypeTag.UTF8 + +# recursive investigate that type -- resolve Arrays and Interfaces +proc genRec(t: GITypeInfo; genProxy = false; fullQualified: bool = false): string = + var rawmark = "" + var proxyResult = false#callerAllocCollector + let p = gTypeInfoIsPointer(t) + let tag = gTypeInfoGetTag(t) + if tag == GITypeTag.ARRAY: + let toa = gTypeInfoGetArrayType(t) # type of array + if toa == GIArrayType.ARRAY: result = "Array" + elif toa == GIArrayType.PTR_ARRAY: result = "PtrArray" + elif toa == GIArrayType.BYTE_ARRAY: result = "ByteArray00" + elif toa == GIArrayType.C: + let arrayType = gTypeInfoGetParamType(t, 0) + let arrayTag = gTypeInfoGetTag(arrayType) + let arrayFixedSize = gTypeInfoGetArrayFixedSize(t) + let arrayLength = gTypeInfoGetArrayLength(t) + let xxx = genRec(arrayType) + let child = mangleType(mangleName(genRec(arrayType))) + result = "array[$1, $2]" % [$arrayFixedSize, child] + if arrayFixedSize == -1: + result = child & "Array" + return + elif tag == GITypeTag.INTERFACE: + let iface = gTypeInfoGetInterface(t) + if gBaseInfoGetType(iface) == GIInfoType.CALLBACK: + if gBaseInfoGetName(iface)[0].isLowerAscii: + result = "proc" & genP(iface)[0] & " {.cdecl.}" + else: + result = mangleName(gBaseInfoGetName(iface)) + else: + var ns = ($gBaseInfoGetNamespace(iface)).toLowerAscii + result = mangleName($gBaseInfoGetName(iface)) + if gBaseInfoGetType(iface) == GIInfoType.Object or gBaseInfoGetType(iface) == GIInfoType.STRUCT or gBaseInfoGetType(iface) == GIInfoType.UNION or gBaseInfoGetType(iface) == GIInfoType.INTERFACE: + proxyResult = genProxy + if not (genProxy or callerAlloc.contains(ns & '.' & result)): + rawmark = "00" + if fullQualified or ns != moduleNamespace: + result = ns & '.' & result + else: + result = $gTypeTagToString(tag) + result = mangleType(result) + if p and (not proxyResult):# or callerAlloc.contains(result)): + result = "ptr " & result + var xxx = result + result = mangleType(result) & rawmark + +proc isProxyCandidate(t: GITypeInfo): bool = + let tag = gTypeInfoGetTag(t) + if tag == GITypeTag.INTERFACE: + let iface = gTypeInfoGetInterface(t) + var ns = ($gBaseInfoGetNamespace(iface)).toLowerAscii + if callerAlloc.contains(ns & '.' & $gBaseInfoGetName(iface)): return false + result = gBaseInfoGetType(iface) in {GIInfoType.Object, GIInfoType.STRUCT, GIInfoType.UNION, GIInfoType.INTERFACE} + +proc needProxyProc(info: GICallableInfo): bool = + result = gCallableInfoIsMethod(info) + let m = gCallableInfoGetNArgs(info) - 1 + for j in 0 .. m: + let arg = gCallableInfoGetArg(info, j) + let t = gArgInfoGetType(arg) + if isProxyCandidate(t): result = true + var ret = gCallableInfoGetReturnType(info) + assert(ret != nil) + let tag = gTypeInfoGetTag(ret) + if isFunctionInfo(info): + if (gFunctionInfoGetFlags(info).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0: + let h = gBaseInfoGetContainer(info) + if gBaseInfoGetType(h) == GIInfoType.OBJECT: + result = true + return result + if isProxyCandidate(ret): result = true + +var ct2nt = newTable[string, string]() +ct2nt.add("uint32", "int") +ct2nt.add("int32", "int") +ct2nt.add("cstring", "string") +ct2nt.add("gboolean", "bool") + +proc ct3nt(s: string): string = + assert(ct2nt.contains(s)) + result = + case s: + of "cstring": "$" + of "gboolean": "toBool" + else: ct2nt[s] + +proc genP(info: GICallableInfo; genProxy = false; binfo: GIBaseInfo = nil): (string, string, TableRef[string, string]) = + var cutat = 50 + var arglist: string + var resul: string + var replist = newTable[string, string]() + let m = gCallableInfoGetNArgs(info) - 1 + var sym = "" + if isFunctionInfo(info): + sym = $gFunctionInfoGetSymbol(info) + if binfo.isNil or not gCallableInfoIsMethod(info): + resul = "(" + arglist = "(" + else: + var ns = ($gBaseInfoGetNamespace(binfo)).toLowerAscii + if callerAlloc.contains(ns & '.' & manglename(gBaseInfoGetName(binfo))): + resul = "(self: " & manglename(gBaseInfoGetName(binfo)) + arglist = "(self" + else: + arglist = "(cast[ptr " & manglename(gBaseInfoGetName(binfo)) & "00](" & "self.impl)" + if genProxy: + resul = "(self: " & manglename(gBaseInfoGetName(binfo)) + else: + resul = "(self: ptr " & manglename(gBaseInfoGetName(binfo)) & "00" + if m >= 0: + resul.add("; ") + arglist.add(", ") + for j in 0 .. m: + let arg = gCallableInfoGetArg(info, j) + let t = gArgInfoGetType(arg) + if gArgInfoIsCallerAllocates(arg): + callerAllocCollector.incl(genRec(t, true, true)) + var str = genRec(t, genProxy and not gArgInfoIsCallerAllocates(arg)) + var userAlloc: bool + if callerAlloc.contains(genRec(t, true, true)): + userAlloc = true + str = genRec(t, true) + + if genProxy: + let tag = gTypeInfoGetTag(t) + if tag == GITypeTag.INTERFACE: + let iface = gTypeInfoGetInterface(t) + if gBaseInfoGetType(iface) == GIInfoType.INTERFACE: + if interfaceProvider.contains(str): + let provider = interfaceProvider[str] + for i in provider: discard mangleType(i) + str = str & " | " & provider.join(" | ") + + let name = mangleName(gBaseInfoGetName(arg)) + if isProxyCandidate(t) and not gArgInfoIsCallerAllocates(arg) and not userAlloc: + arglist.add("cast[" & genRec(t, false) & "](" & name & ".impl)") + else: + if ct2nt.contains(str) and (gArgInfoGetDirection(arg) == GIDirection.OUT or gArgInfoGetDirection(arg) == GIDirection.INOUT): + let kk = if name[0] == '`': name[1 .. ^2] else: name + arglist.add(kk & "_00") + elif ct2nt.contains(str): + arglist.add(str & '(' & name & ')') + else: + arglist.add(name) + if not genProxy and ct2nt.contains(str) and str != "cstring": + replist.add($name, $str) + if genProxy and ct2nt.contains(str): + if gArgInfoGetDirection(arg) == GIDirection.OUT or gArgInfoGetDirection(arg) == GIDirection.INOUT: + replist.add($name, $str) + str = ct2nt[str] + if gArgInfoGetDirection(arg) == GIDirection.OUT or gArgInfoGetDirection(arg) == GIDirection.INOUT: # caution cstringArray + str.insert("var ") + if genProxy and defaultParameters.contains(sym): + var h1, h2, h3: string + (h1, h2, h3) = defaultParameters[sym].split + if name == h1 and str == h2: + str.add(" = " & h3) + resul.add(name & ": " & str) + if j < m: + resul.add("; ") + arglist.add(", ") + if resul.len > cutat: + cutat = 3 * cutat + resul.add("\n ") + if not genProxy and gCallableInfoCanThrowGerror(info): + if resul[^1] != '(': resul.add("; ") + resul.add("error: ptr ptr Error00 = nil") + resul.add(')') + arglist.add(')') + var ret = gCallableInfoGetReturnType(info) + assert(ret != nil) + let tag = gTypeInfoGetTag(ret) + if isFunctionInfo(info): + if (gFunctionInfoGetFlags(info).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0: + let h = gBaseInfoGetContainer(info) + if gBaseInfoGetType(h) == GIInfoType.OBJECT: + if genProxy: + resul.add(": " & mangleType(mangleName(gBaseInfoGetName(h)))) + else: + resul.add(": ptr " & mangleType(mangleName(gBaseInfoGetName(h))) & "00") + return (resul, arglist, replist) + var r = genRec(ret, genProxy) + if gTypeInfoIsPointer(ret) and callerAlloc.contains(genRec(ret, true, true)) and (not r.startsWith("ptr")): + r = "ptr " & r + if r != "void": + if genProxy and ct2nt.contains(r): + r = ct2nt[r] + resul.add(": " & r) + return (resul, arglist, replist) + +proc writeMethod(info: GIBaseInfo; minfo: GIFunctionInfo; genProxy = false) = + assert(isCallableInfo(mInfo)) + assert(isFunctionInfo(mInfo)) + + var plist, arglist: string + var replist: TableRef[string, string] + let p = methodBuffer.getPosition + let sym = $gFunctionInfoGetSymbol(mInfo) + if sym[^1] == '_': return + if sym.contains("__"): return + if processedFunctions.contains(sym): return + if sym == "gtk_text_iter_copy": return + if sym == "gtk_widget_destroyed": return + if sym == "g_error_new_literal": return + for j in 0 ..< gCallableInfoGetNArgs(minfo): + let arg = gCallableInfoGetArg(minfo, j) + let t = gArgInfoGetType(arg) + if isProxyCandidate(t) and gArgInfoGetDirection(arg) == GIDirection.OUT and not gArgInfoIsCallerAllocates(arg): return + if sym == "g_iconv": + return + try: + (plist, arglist, replist) = genP(mInfo, genProxy, info) + methodBuffer.write("\nproc " & sym & EM & plist) + methodBuffer.writeLine(" {.\n importc: \"", sym, "\", ", libprag, ".}") + processedFunctions.incl(sym) + if sym.contains("g_param_spec_") or sym.contains("g_type_interface_") or sym.contains("g_object_interface_") or sym.contains("g_value_"): return + if sym.contains("gtk_widget_class_find_style_property") or sym.contains("gtk_container_class_find_child_property"): return + if sym.contains("gtk_cell_area_class_find_cell_property"): return + var asym = manglename(gBaseInfoGetName(mInfo)) + if keywords.split.contains(asym) or nims.split.contains(asym): asym.add('P') + var ret2 = gCallableInfoGetReturnType(minfo) + for run in 0 .. 1: + if run == 1: + if not (asym.startsWith("get") or asym.startsWith("set")) or asym == "getPlugin" or asym.len < 4: continue + if asym.startsWith("get") and gTypeInfoGetTag(ret2) == GITypeTag.VOID: continue + if asym.startsWith("set"): + if gCallableInfoGetNArgs(minfo) > 2: + continue + if gCallableInfoIsMethod(minfo) and gCallableInfoGetNArgs(minfo) > 1: + continue + if asym.startsWith("get"): + asym = asym[3 .. ^1] + asym[0] = asym[0].toLowerAscii + if asym.startsWith("set"): + asym = asym[3 .. ^1] + asym[0] = asym[0].toLowerAscii + asym = '`' & asym & '=' & '`' + if keywords.split.contains(asym) or nims.split.contains(asym): continue + if needProxyProc(mInfo) or isString(ret2) or replist.len > 0: + var isGObject = false + let tag = gTypeInfoGetTag(ret2) + if tag == GITypeTag.INTERFACE: + let iface = gTypeInfoGetInterface(ret2) + if gBaseInfoGetType(iface) == GIInfoType.Object: + isGObject = true + (plist, arglist, replist) = genP(mInfo, true, info) + + if (gFunctionInfoGetFlags(mInfo).int and GIFunctionInfoFlags.IS_CONSTRUCTOR.int) != 0: + if info != nil: + asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info))) + if fixedProcNames.contains(sym): + asym = fixedProcNames[sym] + for i in 0 .. 1: + var hhh = "\nproc " & asym & EM & plist + if i > 0: + let semi = if hhh.contains("()"): "" else: "; " + let p = hhh.find("): ") + hhh.setLen(p + 1) + hhh = hhh.replace("new", "init") + hhh = hhh.replace("*(", "*[T](result: var T" & semi) + methodBuffer.writeLine(hhh & " =") + if gCallableInfoCanThrowGerror(minfo): + methodBuffer.writeLine(" var gerror: ptr Error00") + if i == 0: arglist.insert(", addr gerror", arglist.high) + if i > 0: + methodBuffer.writeLine(" assert(result is $1)" % [manglename(gBaseInfoGetName(info))]) + assert(replist.len == 0) + for k, v in replist: + let kk = if k[0] == '`': k[1 .. ^2] else: k + methodBuffer.writeLine(" var $1_00 = $2($3)" % [kk, v, k]) + if isGObject: + methodBuffer.writeLine(" new(result, finalizeGObject)") + else: + methodBuffer.writeLine(" new(result)") + methodBuffer.writeLine(" result.impl = " & sym & arglist) + for k, v in replist: + let kk = if k[0] == '`': k[1 .. ^2] else: k + methodBuffer.writeLine(" $1 = $2($3_00)" % [k, ct3nt(v), kk]) + if isGObject: + methodBuffer.writeLine(" GC_ref(result)") + methodBuffer.writeLine(" discard g_object_ref_sink(result.impl)") + methodBuffer.writeLine(" g_object_add_toggle_ref(result.impl, toggleNotify, addr(result[]))") + methodBuffer.writeLine(" g_object_unref(result.impl)") + methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)") + methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))") + elif isProxyCandidate(ret2): + if info != nil: + asym = asym.replace("new", "new" & manglename(gBaseInfoGetName(info))) + methodBuffer.writeLine("\nproc " & asym & EM & plist & " =") + if gCallableInfoCanThrowGerror(minfo): + methodBuffer.writeLine(" var gerror: ptr Error00") + arglist.insert(", addr gerror", arglist.high) + for k, v in replist: + let kk = if k[0] == '`': k[1 .. ^2] else: k + methodBuffer.writeLine(" var $1_00 = $2($3)" % [kk, v, k]) + if isGObject: + methodBuffer.writeLine(" let gobj = " & sym & arglist) + methodBuffer.writeLine(" if g_object_get_qdata(gobj, Quark) != nil:") + methodBuffer.writeLine(" result = cast[$1](g_object_get_qdata(gobj, Quark))" % [genRec(ret2, true)]) + methodBuffer.writeLine(" assert(result.impl == gobj)") + methodBuffer.writeLine(" else:") # I guess this will never get called... + if sym == "g_object_ref" or sym == "g_object_ref_sink": + methodBuffer.writeLine(" assert(false)") + else: + methodBuffer.writeLine(" new(result, finalizeGObject)") + methodBuffer.writeLine(" result.impl = gobj") + methodBuffer.writeLine(" GC_ref(result)") + methodBuffer.writeLine(" discard g_object_ref_sink(result.impl)") + methodBuffer.writeLine(" g_object_add_toggle_ref(result.impl, toggleNotify, addr(result[]))") + methodBuffer.writeLine(" g_object_unref(result.impl)") + methodBuffer.writeLine(" assert(g_object_get_qdata(result.impl, Quark) == nil)") + methodBuffer.writeLine(" g_object_set_qdata(result.impl, Quark, addr(result[]))") + else: + methodBuffer.writeLine(" new(result)") + methodBuffer.writeLine(" result.impl = " & sym & arglist) + for k, v in replist: + let kk = if k[0] == '`': k[1 .. ^2] else: k + methodBuffer.writeLine(" $1 = $2($3_00)" % [k, ct3nt(v), kk]) + else: + if asym == "newFromStreamAsync" and sym.contains("gdk_pixbuf_animation_new"): + asym = "newAnimationFromStreamAsync" + methodBuffer.writeLine("\nproc " & asym & EM & plist & " =") + if gCallableInfoCanThrowGerror(minfo): + methodBuffer.writeLine(" var gerror: ptr Error00") + arglist.insert(", addr gerror", arglist.high) + for k, v in replist: + let kk = if k[0] == '`': k[1 .. ^2] else: k + methodBuffer.writeLine(" var $1_00 = $2($3)" % [kk, v, k]) + if isString(ret2): + methodBuffer.write(" let resul0 = ") + methodBuffer.writeLine(sym & arglist) + methodBuffer.writeLine(" result = $resul0") + assert(gCallableInfoGetCallerOwns(minfo) in {GITransfer.EVERYTHING, GITransfer.NOTHING}) + if gCallableInfoGetCallerOwns(minfo) == GITransfer.EVERYTHING: + methodBuffer.writeLine(" cogfree(resul0)") + elif (replist.len > 0 or gCallableInfoCanThrowGerror(minfo)) and genRec(ret2) != "void": + methodBuffer.write(" result = ") + if ct2nt.contains(genRec(ret2)): + methodBuffer.writeLine(ct3nt(genRec(ret2)) & '(' & sym & arglist & ')') + else: + methodBuffer.writeLine(sym & arglist) + elif ct2nt.contains(genRec(ret2)): + methodBuffer.writeLine(" " & ct3nt(genRec(ret2)) & '(' & sym & arglist & ')') + else: + methodBuffer.writeLine(" " & sym & arglist) + for k, v in replist: + let kk = if k[0] == '`': k[1 .. ^2] else: k + methodBuffer.writeLine(" $1 = $2($3_00)" % [k, ct3nt(v), kk]) + + if gCallableInfoCanThrowGerror(minfo): + methodBuffer.writeLine(" if gerror != nil:") + methodBuffer.writeLine(" let msg = $gerror.message") + methodBuffer.writeLine(" g_error_free(gerror)") + methodBuffer.writeLine(" raise newException(GException, msg)") + + else: + (plist, arglist, replist) = genP(mInfo, genProxy, info) + if asym != "errorQuark" and asym != "getPlugin" and asym != "quark": + methodBuffer.write("\nproc " & asym & EM & plist) + methodBuffer.writeLine(" {.\n importc: \"", sym, "\", ", libprag, ".}") + if sym == "gtk_window_set_default_size": + methodBuffer.writeLine("\nproc `defaultSize=`*(self: Window; dim: tuple[width: int; height: int]) =") + methodBuffer.writeLine(" gtk_window_set_default_size(cast[ptr Window00](self.impl), int32(dim[0]), int32(dim[1]))") + except UndefEx: + echo "delay ", sym#, delayedMethods.len + processedFunctions.excl(sym) + delayedMethods.add((info, minfo)) + methodBuffer.cut(p) + +proc writeUnion(info: GIUnionInfo) = + if not suppressType: + output.writeLine("type") + output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM, " = object {.union.}") + let n = info.gUnionInfoGetNFields() + for j in 0 .. int: + result = cmp(x.v, y.v) + if result == 0: + result = cmp(x.n, y.n) + for j in 0 .. s.high: + if s[j].v < 0: flags = false + if j == 0 and s[j].v == 0: continue + if bitops.popCount(s[j].v) != 1: flags = false + if s.len <= 1: flags = false + var tname = mangleName(gBaseInfoGetName(info)) + if flags: tname = tname[0 .. ^6] + if flags: + output.writeLine(" ", tname & "Flag" & EM, " {.size: sizeof(cint), pure.} = enum") + else: + output.writeLine(" ", tname & EM, " {.size: sizeof(cint), pure.} = enum") + var k: T + for j in 0 .. s.high: + let i = s[j] + var val = i.v + if flags and j == 0 and val == 0: continue + if j > 0 and i.v == k.v: + if i.n != k.n: + alias.add(" " & tname & i.n.capitalizeAscii & EM & " = " & tname & '.' & k.n) + continue + if flags: val = firstSetBit(val) + output.writeLine(" ", i.n, " = ", val) + k = i + if alias.len > 0: + output.writeLine("\nconst") + for i in alias: + output.writeLine(i) + if flags: + output.writeLine("\n ", tname & "Flags" & EM, " {.size: sizeof(cint).} = set[$1Flag]" % [tname]) + let nMethods = gEnumInfoGetNMethods(info) + ###assert(nMethods <= 0) + for j in 0 .. 0: + # stdout.write "||| ", gBaseInfoGetName(info), " has ", ninterfaces, " interf: " + # for i in 0 .. < ninterfaces: + # stdout.write " ", gBaseInfoGetName(info.gObjectInfoGetInterface(i)), "," + # stdout.writeLine("") + # stdout.flushFile + + let class = gObjectInfoGetClassStruct(info) + let n = info.gObjectInfoGetNFields + let parent = gObjectInfoGetParent(info) # nil for Object of module gobject! + var pname: string + var oof: string + var ns: string + var cnt: int + if parent.isNil: + assert(gBaseInfoGetName(info) == "Object" or gBaseInfoGetName(info) == "ParamSpec") + oof = "{.inheritable, pure.} = object" + ns = "" + pname = "" + cnt = 0 + else: + cnt = 1 + oof = " = object of " + pName = manglename(gBaseInfoGetName(parent)) + if ct.hasKey(pname): + cnt = ct[pname] + ns = ($gBaseInfoGetNamespace(parent)).toLowerAscii + if ns == moduleNamespace: ns = "" else: ns.add('.') + if ns == "gio." and gBaseInfoGetName(info) == "Application": # a few special cases for gtk.nim + cnt = 9 + if ns == "gio." and gBaseInfoGetName(info) == "MountOperation": + cnt = 9 + if ns == "gio." and gBaseInfoGetName(info) == "NumerableIcon": + cnt = 9 + if not suppressType: + output.writeLine("type") + if ns == "" and pname != "": # check forward exeption for parent name! + discard mangleType(pname) + if mangleName(gBaseInfoGetName(info)) == "Object" and moduleNamespace == "gobject": + discard + elif gBaseInfoGetName(info) == "ParamSpec": + output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of RootRef") + output.writeLine(" impl*: ptr ParamSpec00") + else: + output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & EM & " = ref object of " & ns & pname) + if pname != "": pname.add("00") + output.writeLine(" ", mangleName(gBaseInfoGetName(info)) & "00" & EM, oof, ns & $pname) + if mangleName(gBaseInfoGetName(info)) != "InitiallyUnowned": + for j in 0 .. 0: + renumber(name, cnt) + else: + name.add(EM) + let t = gFieldInfoGetType(field) + let h = genRec(t) + if j == 0 and parent != nil: + continue + output.writeLine(" ", name, ": ", h) + if mangleName(gBaseInfoGetName(info)) == "Object" and moduleNamespace == "gobject": + + output.writeLine("type") + output.writeLine(" GToggleNotify* = proc (data: pointer; obj: ptr Object00; isLastRef: gboolean) {.cdecl.}\n") + output.writeLine("proc g_object_add_toggle_ref*(obj: ptr Object00; notify: GToggleNotify; data: pointer) {.") + output.writeLine(" importc: \"g_object_add_toggle_ref\", libprag.}") + output.writeLine("proc g_object_remove_toggle_ref*(obj: ptr Object00; notify: GToggleNotify; data: pointer) {.") + output.writeLine(" importc: \"g_object_remove_toggle_ref\", libprag.}") + output.writeLine("\nproc g_object_set_qdata*(self: ptr Object00; quark: uint32; p: pointer) {.") + output.writeLine(" importc: \"g_object_set_qdata\", libprag.}") + output.writeLine("proc toggleNotify*(data: pointer; obj: ptr Object00; isLastRef: gboolean) {.cdecl.} =") + output.writeLine(" if isLastRef.int == 0:") + output.writeLine(" GC_ref(cast[RootRef](data))") + ###output.writeLine(" echo \"GC_ref(cast[RootRef](data)\"") + output.writeLine(" else:") + output.writeLine(" GC_unref(cast[RootRef](data))") + ###output.writeLine(" echo \"GC_unref(cast[RootRef](data)\"") + ###output.writeLine(" echo \"toggleNotify\"") + ###output.writeLine(" echo obj.ref_count") + output.writeLine("\nproc finalizeGObject*[T](o: T) =") + ###methodBuffer.writeLine(" echo(\"finalizeGObject\")") + output.writeLine(" g_object_remove_toggle_ref(o.impl, toggleNotify, addr(o[]))") + + let numsig = info.gObjectInfoGetNSignals + if numsig > 0: output.writeLine("") + for j in 0 .. 0: + h = h.replace(")", "; xdata: pointer)") + else: + h = h.replace(")", "xdata: pointer)") + var xxx = mangleName(gBaseInfoGetName(info)) + output.write("proc " & mangleName("sc_" & $gBaseInfoGetName(signalInfo)) & EM & "(self: " & xxx & "; ") + output.writeLine(" p: proc (self: ptr gobject.Object00; " & h & " {.cdecl.}, xdata: pointer = nil) =") + output.write(" discard g_signal_connect_data(self.impl, \"") + output.write($gBaseInfoGetName(signalInfo)) + output.writeLine("\", cast[GCallback](p), xdata, nil, cast[ConnectFlags](0))") + let nMethods = gObjectInfoGetNMethods(info) + for j in 0 .. 1: + if s.len == 2: + if h == s[0]: + tg = "U" + elif h == s[1]: + discard + else: + assert(false) + elif s.len == 3: # eth and thorn + if h == s[0]: + tg = "X" + elif h == s[2]: + discard + elif h == s[1]: + tg = "U" + else: + assert(false) + output.writeLine("const ", tg, h & EM, " = ", str) + else: + output.writeLine("const ", mangleName(h) & EM, " = ", str) + +proc processInfo(i: GIBaseInfo) = + if not isFunctionInfo(i): + output.write("\n") + if isCallableInfo(i): + if isFunctionInfo(i): + let s = $gFunctionInfoGetSymbol(i) + if s[^1] != '_' and not processedFunctions.contains(s) and not s.contains("__") and s != "g_type_add_interface_dynamic" and + s != "g_type_get_plugin" and s != "g_type_register_dynamic": + writeMethod(nil, i) + else: + assert(isCallbackInfo(i)) + if not suppressType: + output.write("type\n") + output.writeLine(" ", mangleName(gBaseInfoGetName(i)) & "* = proc " & genP(i)[0] & " {.cdecl.}") + elif gBaseInfoGetType(i) == GIInfoType.OBJECT: + writeObj(i) + elif gBaseInfoGetType(i) == GIInfoType.UNION: + writeUnion(i) + elif gBaseInfoGetType(i) == GIInfoType.INTERFACE: + let h = gInterfaceInfoGetIfaceStruct(i) + if h != nil: + writeInterface(i) + elif gBaseInfoGetType(i) == GIInfoType.STRUCT: + writeStruct(i) + elif isEnumInfo(i): + writeEnum(i) + elif gBaseInfoGetType(i) == GIInfoType.CONSTANT: + writeConst(i) + else: assert(false) + +const GIO_EPI = """ + +proc run*(self: Application): int = + int(g_application_run(cast[ptr Application00](self.impl), 0, nil)) +""" + +const GTK_EPI = """ + +proc init* = + var argc: int32 = 0 + var argv: cstringArray = nil + gtk_init(argc, argv) + +proc loadFromData*(self: CssProvider; data: cstring): bool = + loadFromData(self, uint8Array(data), -1) + +import macros, strutils + +var ProcID: int + +macro mconnect(widget: gobject.Object; signal: string; p: untyped; arg: typed; widgett: typedesc; argt: typedesc): typed = + inc(ProcID) + let wt = getType(widgett)[1] # widget type + let at = getType(argt)[1] # argument type + let signalName = ($signal).replace("-", "_") # maybe we should just use plain proc names + let procNameCdecl = newIdentNode("connect_for_signal_cdecl_" & signalName & $ProcID) + let procName = newIdentNode("connect_for_signal_" & signalName & $ProcID) + let scName = newIdentNode("sc" & signalName) + result = quote do: + proc `procNameCdecl`(w: ptr gobject.Object00 , data: pointer) {.cdecl.} = + var h: pointer = g_object_get_qdata(w, Quark) + `p`(cast[`wt`](h), cast[`at`](data)) + + proc `procName`(self: `wt`; p: proc (self: `wt`, arg: `at`); a: `at`) = + when a is RootRef: + GC_ref(a) + `scName`(self, `procNameCdecl`, cast[pointer](a)) + else: + var ar: ref `at` + new(ar) + deepCopy(ar[], a) + GC_ref(ar) + `scName`(self, `procNameCdecl`, cast[pointer](ar[])) + `procName`(`widget`, `p`, `arg`) + +template connect*(widget: gobject.Object; signal: string; p: untyped; arg: typed) = + mconnect(widget, signal, p, arg, type(widget), type(arg)) + +macro mconnect(widget: gobject.Object; signal: string; p: untyped; widgett: typedesc): typed = + inc(ProcID) + let wt = getType(widgett)[1] + let signalName = ($signal).replace("-", "_") + let procNameCdecl = newIdentNode("connect_for_signal_cdecl_" & signalName & $ProcID) + let procName = newIdentNode("connect_for_signal_" & signalName & $ProcID) + let scName = newIdentNode("sc" & signalName) + result = quote do: + proc `procNameCdecl`(w: ptr gobject.Object00 , data: pointer) {.cdecl.} = + var h: pointer = g_object_get_qdata(w, Quark) + `p`(cast[`wt`](h)) + + proc `procName`(self: `wt`; p: proc (self: `wt`)) = + `scName`(self, `procNameCdecl`, nil) + `procName`(`widget`, `p`) + +template connect*(widget: gobject.Object; signal: string; p: untyped) = + mconnect(widget, signal, p, type(widget)) + +""" +proc main(namespace: string) = + priList = newSeq[string]() + suppressType = false + suppressRaise = false + delayedMethods = newSeq[(GIBaseInfo, GIFunctionInfo)]() + classList = newSeq[GIBaseInfo]() + output = newStringStream() + methodBuffer = newStringStream() + var error: GError + ct = initCountTable[string]() + var delayedSyms = newSeq[GIBaseInfo]() + allSyms = initSet[string]() + provInt.clear + interfaceProvider.clear + var ig = initSet[string]() + knownSyms = initSet[string]() + let gi = gIrepositoryGetDefault() + assert(gi != nil) + moduleNamespace = namespace.toLowerAscii + let version: cstring = nil # latest + let typelib = gi.gIrepositoryRequire(namespace, version, cast[GIRepositoryLoadFlags](0), error) + if typelib.isNil: + echo error.message + let dep: cstringArray = gi.gIrepositoryGetDependencies(namespace) + output.writeLine("# dependencies:") + var importedModules = "" + for j in 0 .. 9: + if dep[j].isNil: break + if j == 0: + importedModules = "import " + output.writeLine("# ", dep[j]) + importedModules.add(($dep[j]).split('-',2)[0].toLowerAscii & ", ") + importedModules.removeSuffix(", ") + strfreev(dep) + let idep: cstringArray = gi.gIrepositoryGetImmediateDependencies(namespace) + output.writeLine("# immediate dependencies:") + for j in 0 .. 9: + if idep[j].isNil: break + output.writeLine("# ", idep[j]) + strfreev(idep) + let libs = gi.gIrepositoryGetSharedLibrary(namespace) + + output.writeLine("# libraries:") + output.writeLine("# ", libs) + output.writeLine("{.deadCodeElim: on.}") + output.writeLine(importedModules) + let Lib = if libs.isNil: "" else: ($libs).split(',', 2)[0] + output.writeLine("const Lib* = \"$1\"" % Lib) + output.writeLine("{.pragma: libprag, cdecl, dynlib: Lib.}") + if namespace == "GObject": # declare array types to make it compile -- procs using these will need special care! + output.writeLine("type\n GCallback* = proc () {.cdecl.}") + output.writeLine("type\n Parameter00Array* = pointer") + output.writeLine("type\n Object00Array* = pointer") + output.writeLine("type\n Value00Array* = pointer") + output.writeLine("type\n GTypeArray* = pointer") + output.writeLine("type\n ParamSpec00Array* = pointer") + output.writeLine("type\n TypePlugin00Array* = pointer") + output.writeLine("type\n uint32Array* = pointer") + output.writeLine("type\n VaClosureMarshal* = pointer") + output.writeLine("type\n TypePlugin00* = object") + elif namespace == "GLib": + output.writeLine("type\n GException* = object of Exception") + output.writeLine("type\n OptionEntry00Array* = pointer") + output.writeLine("type\n int8Array* = pointer") + output.writeLine("type\n uintArray* = pointer") + output.writeLine("type\n gbooleanArray* = pointer") + output.writeLine("type\n cdoubleArray* = pointer") + output.writeLine("type\n int32Array* = pointer") + output.writeLine("type\n PollFD00Array* = pointer") + output.writeLine("type\n Variant00Array* = pointer") + output.writeLine("type\n LogField00Array* = pointer") + output.writeLine("type\n VariantType00Array* = pointer") + output.writeLine("type\n DebugKey00Array* = pointer") + output.writeLine("type\n utf8Array* = pointer") + output.writeLine("type\n uint8Array* = pointer") + output.writeLine("type\n ucstringArray* = pointer") + output.writeLine("type\n ucstring* = distinct cstring") + output.writeLine("type\n gboolean* = distinct cint") + output.writeLine("type\n GType* = distinct cint") + output.writeLine("type\n gunichar* = uint32") + output.writeLine("type\n utf8* = char") + output.writeLine("const GFalse = gboolean(0)") + output.writeLine("const GTrue = gboolean(1)") + output.writeLine("proc cogfree*(mem: pointer) {.importc: \"g_free\", libprag.}") + output.writeLine("proc toBool*(g: gboolean): bool = g.int != 0") + elif namespace == "Gdk": + output.writeLine("type\n AtomArray* = pointer") + output.writeLine("type\n KeymapKey00Array* = pointer") + output.writeLine("type\n VisualTypeArray* = pointer") # enums! + output.writeLine("type\n RGBAArray* = pointer") + output.writeLine("type\n ColorArray* = pointer") + output.writeLine("type\n Point00Array* = pointer") + elif namespace == "Gtk": + output.writeLine("type\n TargetEntry00Array* = pointer") + output.writeLine("type\n AccelGroupEntry00Array* = pointer") + output.writeLine("type\n BindingArg00Array* = pointer") + output.writeLine("type\n StockItemArray* = pointer") + output.writeLine("type\n PageRange00Array* = pointer") + output.writeLine("type\n PadActionEntry00Array* = pointer") + output.writeLine("type\n Array* = pointer") + elif namespace == "Atk": + output.writeLine("type\n StateTypeArray* = pointer") # enums! + output.writeLine("type\n TextRange00Array* = pointer") + output.writeLine("type\n PtrArray* = pointer") + elif namespace == "Pango": + output.writeLine("type\n GlyphInfo00Array* = pointer") + output.writeLine("type\n LogAttr00Array* = pointer") + output.writeLine("type\n FontDescription00Array* = pointer") + output.writeLine("type\n FontFamily00Array* = pointer") + output.writeLine("type\n FontFace00Array* = pointer") + output.writeLine("type\n ScriptArray* = pointer") # array of enums! + elif namespace == "Gio": + output.writeLine("type\n ActionEntry00Array* = pointer") + output.writeLine("type\n DBusAnnotationInfo00Array* = pointer") + output.writeLine("type\n DBusArgInfo00Array* = pointer") + output.writeLine("type\n DBusMethodInfo00Array* = pointer") + output.writeLine("type\n DBusSignalInfo00Array* = pointer") + output.writeLine("type\n DBusPropertyInfo00Array* = pointer") + output.writeLine("type\n DBusInterfaceInfo00Array* = pointer") + output.writeLine("type\n DBusNodeInfo00Array* = pointer") + output.writeLine("type\n InputVector00Array* = pointer") + output.writeLine("type\n SocketControlMessage00Array* = pointer") + output.writeLine("type\n InputMessage00Array* = pointer") + output.writeLine("type\n OutputMessage00Array* = pointer") + output.writeLine("type\n utf8ArrayArray* = pointer") + output.writeLine("type\n cstringArrayArray* = pointer") + output.writeLine("type\n File00Array* = pointer") + output.writeLine("type\n Array* = pointer") + output.writeLine("type\n OutputVector00Array* = pointer") + + if namespace == "GObject": + output.writeLine("\nimport times") + output.writeLine("var qt = \"NGIQ\" & $epochTime()") + output.writeLine("if g_quark_try_string(qt) != 0:") + output.writeLine(" qt = \"NGIQ\" & $epochTime()") + output.writeLine("let Quark* = g_quark_from_static_string(qt)") + var n = gi.gIrepositoryGetNInfos(namespace) + var s = newSeq[GIBaseInfo]() + for i in 0 ..< n: + if not droppedSyms.contains(mangleName(gBaseInfoGetName(gi.gIrepositoryGetInfo(namespace, i)))): + s.add(gi.gIrepositoryGetInfo(namespace, i)) + for i in s: + if gBaseInfoGetType(i) == GIInfoType.OBJECT or gBaseInfoGetType(i) == GIInfoType.INTERFACE or gBaseInfoGetType(i) == GIInfoType.STRUCT or gBaseInfoGetType(i) == GIInfoType.UNION or isEnumInfo(i) or isCallbackInfo(i): + allSyms.incl(mangleName(gBaseInfoGetName(i))) + + for i in 0 .. s.high: + if namespace == "GLib" and gBaseInfoGetType(s[i]) == GIInfoType.STRUCT and gBaseInfoGetName(s[i]) == "Error": + let h = s[i] + s.delete(i, i) + s.insert([h]) + break + + for info in s: + if gBaseInfoGetType(info) == GIInfoType.OBJECT: + let ninterfaces = info.gObjectInfoGetNInterfaces + if ninterfaces > 0: + var interf = newSeq[string]() + let name = $gBaseInfoGetName(info) + + for i in 0 .. < ninterfaces: + interf.add($gBaseInfoGetName(info.gObjectInfoGetInterface(i))) + + if provInt.contains(name): + assert false + else: + provInt[name] = interf + + for obj, ifaces in provInt: + for i in ifaces: + if not interfaceProvider.contains(i): + interfaceProvider[i] = @[obj] + else: + interfaceProvider[i].add(obj) + + if namespace == "Gdk": # special care for gdk keys due to nim's style insensitivity! + for i in s: + var h = $gBaseInfoGetName(i) + if h.startsWith("KEY_"): + if gdkKeys.contains(h.toLowerAscii): + gdkKeys.mget(h.toLowerAscii).add(h) + else: + gdkKeys.add(h.toLowerAscii, @[h]) + for el in mvalues(gdkKeys): + sort(el, system.cmp) + var i: GIBaseInfo + var unp = newSeq[GIBaseInfo]() + reverse(s) + while s.len > 0: + if namespace == "GObject" and not knownSyms.contains("g_signal_connect_data"): + if knownSyms.contains("ClosureNotify") and knownSyms.contains("ConnectFlags"): + knownSyms.incl("g_signal_connect_data") + output.writeLine("proc g_signal_connect_data*(instance: pointer; detailedSignal: cstring; cHandler: GCallback;") + output.writeLine(" data: pointer; destroyData: ClosureNotify; connectFlags: ConnectFlags): culong {.") + output.writeLine(" importc: \"g_signal_connect_data\", libprag.}") + while priList.len > 0: # move missing symbols to top, but only once! + let h = priList.pop + if ig.contains(h): continue + ig.incl(h) + echo h + var k = -1 + for p, el in s: + if (gBaseInfoGetType(el) == GIInfoType.OBJECT or gBaseInfoGetType(el) == GIInfoType.INTERFACE or gBaseInfoGetType(el) == GIInfoType.STRUCT or isEnumInfo(el)) and gBaseInfoGetName(el) == h: + k = p + if k >= 0: + echo "moved" + s.add(s[k]) + s.delete(k) + + i = s.pop + delayedSyms.insert(i) + if classList.len > 0: + delayedSyms.insert(classList.pop) + unp.setLen(0) + for k in delayedSyms: + var pos = output.getPosition + try: + knownSyms.incl(mangleName(gBaseInfoGetName(k))) + methodBuffer = newStringStream() + processInfo(k) + output.write(methodBuffer.data) + echo "----------", gBaseInfoGetName(k) + except UndefEx: + unp.add(k) + knownSyms.excl(mangleName(gBaseInfoGetName(k))) + output.cut(pos) + delayedSyms = unp + block myb: + for a in 1 .. 2: # process clustered symbols into one single type section + if delayedSyms.len > a: + suppressType = true + methodBuffer = newStringStream() + unp = delayedSyms + for t in unp.combinations(a + 1): + var pos = output.getPosition + methodBuffer = newStringStream() + let x = delayedMethods.len + try: + var h = false + for k in t: + if gBaseInfoGetType(k) != GIInfoType.OBJECT and gBaseInfoGetType(k) != GIInfoType.STRUCT and gBaseInfoGetType(k) != GIInfoType.UNION and not isCallbackInfo(k): + h = true + if h: continue + output.writeLine("type") + for k in t: + knownSyms.incl(mangleName(gBaseInfoGetName(k))) + for k in t: + processInfo(k) + for k in t: + delayedSyms.keepItIf(mangleName(gBaseInfoGetName(k)) != mangleName(gBaseInfoGetName(it))) + suppressType = false + output.write(methodBuffer.data) + break myb + except UndefEx: + for k in t: + knownSyms.excl(mangleName(gBaseInfoGetName(k))) + output.setPosition(pos) + assert delayedMethods.len >= x + delayedMethods.setLen(x) + suppressType = false + + methodBuffer = newStringStream() + var h = delayedMethods + #delayedMethods.setLen(0) + delayedMethods = newSeq[(GIBaseInfo, GIFunctionInfo)]() + for el in h: + writeMethod(el[0], el[1]) + output.write(methodBuffer.data) + + suppressRaise = true + output.writeLine("# === remaining symbols:") # in best case there is nothing left + for i in delayedSyms: + processInfo(i) + + if namespace == "Gtk": + output.write(GTK_EPI) + + if namespace == "Gio": + output.write(GIO_EPI) + + output.flush + var o = open("nim_gi" / (namespace.toLowerAscii) & ".nim", fmWrite) + o.write(output.data) + o.close() + output.close + echo "Remaining delayed methods: ", delayedMethods.len + for el in delayedMethods: + echo gBaseInfoGetName(el[1]) + +# when isMainModule: +main("GLib") +main("GObject") +main("GModule") +main("xlib") +main("Gio") +main("Atk") +main("Pango") +main("cairo") +main("GdkPixbuf") +main("Rsvg") +main("Gdk") +main("Gtk") + +#for i in callerAllocCollector: echo i