gtkd-developers / GtkD

GtkD is a D binding and OO wrapper of GTK+ originally created by Antonio Monteiro
http://gtkd.org
Other
322 stars 71 forks source link

Binding generation documentation #245

Closed baedert closed 6 years ago

baedert commented 6 years ago

Hey,

I'd like to try generating bindings for the current gtk+ master/gtk4 code, which has significant changes compared to the gtk3 version. Is there any documentation on how to do that and what to look out for?

MikeWey commented 6 years ago

There isn't a lot of documentation on how to generate bindings.

The GtkD bindings are generated with the gir-to-d tool found here: https://github.com/gtkd-developers/gir-to-d

If you don't want/need to change anything from the generated code the simplest option would be to run these commands:

girtod -i /usr/share/gir-1.0/Gtk-4.0.gir
girtod -i /usr/share/gir-1.0/Gdk-4.0.gir
girtod -i /usr/share/gir-1.0/Gsk-4.0.gir

With that you will end up with a binding for gtk4 gdk4 and gsk in ./out, tough they will depend on GtkD for the libraries gtk depends on. (glib, atk, pango, ...).

If the generated code needs some work a lookup file can be used as the input of girtod, a complete list of the options available can be found here: https://github.com/gtkd-developers/gir-to-d/blob/master/Readme_APILookup

For some example lookup files you can check:

https://github.com/gtkd-developers/GtkD/blob/master/src/APILookupRsvg.txt For a very minimal example, that only moves two functions around.

https://github.com/gtkd-developers/GtkD/blob/master/src/APILookupVte.txt For a small library that has some more going on.

And https://github.com/gtkd-developers/GtkD/blob/master/src/APILookupGtk.txt That has a lot of things going on, like changes for backwards compatibility, convenience functions, some things implemented manually so they work properly in D, among other things.

baedert commented 6 years ago

I've stopped working on this for the time being since I have no idea how to properly bind graphene. I've made some changes to the gir-to-d generator that I think were bugs but I didn't verify any of it.

Basically, graphene has simd types that are part of the struct definition, e.g. the vec4 has a value field:

      <field name="value" introspectable="0" readable="0" private="1">
        <type c:type="graphene_simd4f_t"/>
      </field>

But the simd type is never defined in the gir file and is private anyway.

baedert commented 6 years ago

Do you have any hints on how to solve the graphene problem? I'd like to look into this again in the next few days, i.e. start with successfully generating bindings for graphene and then work my way up to gtk+.

MikeWey commented 6 years ago

You will need to ad an alias for the graphene type.

Save this as a text file and use it as the input of girtod.

wrap: graphene
file: Graphene-1.0.gir

alias: graphene_simd4f_t __vector(float[4])
girtod -i YourTextFile.txt

Or if you want to use the aliases from core.simd:

wrap: graphene
file: Graphene-1.0.gir

addAliases: start
    public import core.simd;
addAliases: end

alias: graphene_simd4f_t float4
baedert commented 6 years ago

Thanks for the guidance so far. It seems like the generation gets confused with the _t suffix and sometimes uses graphene_vec4_t (for example in graphene/Vec4.d as the main struct) and grapheneVec4T in graphene/c/types.d.

It seems wrong to wrap all the graphene types as classes though since they are usually stack allocated and all boxed types and not GObjects. I guess that's not possible with girtod? Does that even work at all with aligned types etc. from D? Should I just manually wrap what I need instead?

MikeWey commented 6 years ago

Thanks for the guidance so far. It seems like the generation gets confused with the _t suffix and sometimes uses graphene_vec4_t (for example in graphene/Vec4.d as the main struct) and grapheneVec4T in graphene/c/types.d.

That probably a bug, i'll look into it.

It seems wrong to wrap all the graphene types as classes though since they are usually stack allocated and all boxed types and not GObjects. I guess that's not possible with girtod?

Currently most types are wrapped with classes.

Does that even work at all with aligned types etc. from D? Should I just manually wrap what I need instead?

As far as i can tell the gir files don't provide the alignment of a type, so if graphene uses an other alignment then the default those types will need to be wrapped manually. I'm not familiar enough with graphene to say if overriding the generation of those structs would be easier that doning the complete library by hand.

MikeWey commented 6 years ago

Thanks for the guidance so far. It seems like the generation gets confused with the _t suffix and sometimes uses graphene_vec4_t (for example in graphene/Vec4.d as the main struct) and grapheneVec4T in graphene/c/types.d.

Should be fixed with this commit: https://github.com/gtkd-developers/gir-to-d/commit/5f5f27b6ca2c9e68962265390c2e0e5366c70790

baedert commented 6 years ago

Thanks for that bug fix.

I have now heavily edited APILookupGtk.txt and APILookupGdk.txt files. One problem that I don't know how to tackle is the GdkSnapshot/GtkSnapshot stuff. GtkSnapshot is a GdkSnapshot subclass, so GdkSnapshot has a getSnapshotStruct() function returning a GdkSnapshot.

GtkSnapshot on the other hand has a getGtkSnapshotStruct() returning a GtkSnapshot*. In the API, only GtkSnapshot is ever used so everything should always use getGtkSnapshotStruct() but things call getSnapshotStruct() instead, e.g. in gtk/CellArea.d:

    public void snapshot(CellAreaContext context, Widget widget, Snapshot snapshot, GdkRectangle* backgroundArea, GdkRectangle* cellArea, GtkCellRendererState flags, bool paintFocus)
    {
        gtk_cell_area_snapshot(gtkCellArea, (context is null) ? null : context.getCellAreaContextStruct(), (widget is null) ? null : widget.getWidgetStruct(), (snapshot is null) ? null : snapshot.getSnapshotStruct(), backgroundArea, cellArea, flags, paintFocus);
    }

Which results in a type mismatch at compile time. Is this a bug in the generator as well?

MikeWey commented 6 years ago

That is/was a bug as well: https://github.com/gtkd-developers/gir-to-d/commit/a07c0fe5252b0f794e3a93c6daf037b5febca127