3 Native GTK bindings from D.
6 "Native" for two reasons:
8 1. Uses the C API directly. No class wrappers and no function wrappers.
9 2. OO interface, giving a native D look and feel.
12 The code generated when using these bindings is identical to the
13 equivalent C version. Bit-for-bit, there is zero overhead. [1]
18 The D modules in this package give access to:
30 There is also a minimal <cairo-1.0> stub, which only allows the GTK
31 stack to build, but isn't really usable.
34 HOW IS THIS DIFFERENT FROM EXISTING GTK D BINDINGS
36 A struct containing only four ints like <gdk.Rectangle> is not wrapped
37 in a D class with just one visible field - a pointer to the real struct.
38 A class which needs to be allocated every time a new Rectangle is seen,
39 even if it comes embedded in another structure (eg. an Event) and has
40 to be accessed using class methods that also add overhead by doing extra
41 null pointer checks etc.
43 Here, a <gdk.Rectangle> is just the raw GDK structure. It has "methods",
44 but using them results in calls to the real <gdk_rectangle_*()> library
45 functions with appropriate arguments. No classes, no allocations, no
51 - As much as possible of the API is exposed. This includes things that
52 are marked as unintrospectable. Not everything will be directly
53 usable from D, but there are no artificial limitations.
54 (There are a few things that could be exposed, but so far aren't
55 - simply because I had no need for them yet)
57 - The C API, ie all the function signatures and data types, is also available.
58 It is possible to use the raw C API directly, ignoring all the D extras.
60 - The applications are linked with the dynamic GTK libs directly.
61 No dlopen() games at applications startup. If a program was successfully
62 built, it won't fail or print scary messages at startup because some
63 library is missing or the versions does not exatcly match.
64 (static linking might even work, but is untested)
69 Well, the GTK API is documented eg here: http://developer.gnome.org/
70 It's exposed more or less directly.
72 The bundled examples should be enough to get you started:
74 example_gtk1.d -- Basic Hello World app, using just the std GTK API.
75 example_gtk2.d -- Same as above, but using a few extra features specific
76 to these bindings (try: "diff -u example_gtk[12].d")
77 example_gtk3.d -- A trivial GTK calculator application. Not to be trusted
78 to get the math right. :) Just a example showing how to
79 create custom GTK widgets and handling certain common
82 The generated gtk*/*.d modules have a lot of doc comments - they are not
83 always 100% complete, but often good enough.
88 I wanted to have GTK2 working before targetting GTK3, working on GTK2
89 would have been a very low priority task once GTK3 was working...
90 GTK3 support will happen as soon as the D interface becomes stable,
91 then the D package name will change from "gtk2" to "gtk".
94 D GTK EXTRAS ADDED BY THESE BINDINGS:
97 Not really an "extra", but one area where the C->D mapping has a quirk.
98 Constructors are named 'new_()', eg 'gtk2.Window.new_()' due to the
101 For the builtin GTK types the D struct allocators could be used, if there
102 was a way to avoid the default struct initialization that happens after
103 returning from the allocator (the signature restrictions on <this()>
104 can be trivially worked around). Still, this would only allow for
105 parameter-less constructors, at least when using the "natural" syntax
106 (ie. "new(gtk.WindowType.TOPLEVEL) gtk.Window()" would not really be
107 an improvement over "gtk.Window.new_(gtk.WindowType.TOPLEVEL)")
108 Once D gains a way for the allocators to access the constructor
109 arguments /and/ control initialization, "proper" constructors can be
113 A "Container.add(Widget* w)" function can be called with any derived
114 widget, using the "container.add(&mywidget.widget);" idiom. This <widget>
115 can be embedded in the <mywidget> struct (like in the case of builtin GTK
116 widgets), but does not need to - it can be a pointer to such an object,
117 the pointed-to widget will then be automatically used instead.
119 For this to work any "derived" struct must contain a lower-cased symbol
120 of the right type - this convention is used internally (it's mostly
121 already present in GTK, and every other place is taken care of while
122 generating the bindings).
123 This symbol can be present anywhere in the object hierarchy, ie any of
124 the parent objects can contain it.
125 See the <Keypad> and <AppWin> widgets in "example_gtk3.d" for examples.
127 Once D supports reference-type structs and properly lowers all implicit
128 casts the upcasts can be made implicit. Doing this with just pointer args
129 could be to dangerous, even if it was possible (the user might not expect
130 to have pointer values swapped, under the hood). Using ref args for the
131 bindings *is* currently possible, but that introduces inconsistencies and
132 it would become too easy to accidentally copy-by-value. Not to mention that
133 the "add(*mywidget);" syntax doesn't look good and I'm not sure if, right
134 now, D can be made to do the required casts implicitly.
136 - signal_connect!(string signal_name)(T callback) templates.
137 Convenience templates, wrapping <signal_connect_data()> and ensuring the
138 callback's signature is correct.
139 Note: some callback declarations in the GIR data are wrong; you'll have
140 to add casts for these cases. The common ones *do* work; using the
141 "generic" callback type would need a cast anyway .
142 (adding the right overloads with <mixin/*.d> might be possible)
144 - gtk._dumpobj(object* o).
145 Will print the contents of any GTK structure <o> to stdout. For debugging.
146 See the examples, where it's used to dump the gdk.Event's in the callbacks.
149 BUGS AND LIMITATIONS:
151 - GTK "interface" support is incomplete.
152 http://developer.gnome.org/gobject/stable/gtype-non-instantiable-classed.html
153 - Variadic struct methods are not available - use the C API directly.
154 (IIRC, this is because D mangles the names of <extern "C"> functions
155 declared inside a struct, so the "alias" solution can't be used;
156 it's fixable by either handling varargs or aliasing the D name to
157 the unmangled C one.)
158 - Some array function parameter types are wrong (missing a '*').
159 eg. glib:g_key_file_set_locale_string_list(...char **list...)
160 The issue is: the <parameter><array> c:type's are inconsistent;
161 mostly they are complete, but sometimes they're missing the last '*'.
162 Which wouldn't be a problem if this was always the case, but - as it
163 is - figuring out when the type refers to the *element* seems
165 - Some methods are wrongly documented (in the GIR XML) as functions.
166 Eg. GObject:g_object_*(). Use the C prototypes, the methods are
167 mostly <introspectable="0"> anyway.
172 - Windows support, using eg http://www.gtk.org/download/win32.php
173 Won't do this myself, but if anyone gets it working, please document
174 how, and send me any required patches.
179 The generated D bindings almost entirely consist of machine translations
180 of the data types, function signatures and constants provided by the GIR
181 files (</usr/share/gir-*/*.gir>, see http://live.gnome.org/GObjectIntrospection/
182 for more info on GObject introspection).
183 All extra mixins (from <mixin/*.d>) and fixups (done by <girtod.d>) added by
184 this package to the gtk*/*.d files do not add any additional restrictions.
186 The girtod.d converter license is:
188 // Copyright Artur Skawina 2012.
189 // Distributed under the Boost Software License, Version 1.0.
190 // (See accompanying file LICENSE_1_0.txt or copy at
191 // http://www.boost.org/LICENSE_1_0.txt)
195 [1] Assumes a properly working compiler, one that will inline the
197 GDC will do this when using LTO and could probably be made to it
198 w/o LTO by using templates instead of functions. I've not done
199 the latter as the whole difference is: instead of a direct
200 call via the PLT, the non-LTO case is a call to an empty function
201 which immediately jumps to the PLT target. As long as GDC cross
202 module inlining doesn't work, the extra jump per library call isn't
203 likely to be a bottleneck. :) (apparently, another workaround is to
204 build all the *.d files together; I've never tried this)