2 <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
3 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
6 <title>Code contributions</title>
7 <subtitle>Conventions used by the ADG canvas project</subtitle>
9 <para>This is a high-level guide on how the ADG project is organized and
10 how to get started hacking on it. Just keep in mind the following
11 statements should be considered recommendations, not rules.</para>
14 <simplesect id="HACKING.patches">
15 <title>Hints on how to submit patches</title>
17 <para>Any patch worth the inclusion in the mainstream can be submitted in
18 different ways:</para>
21 <listitem>attach it to the <ulink url="http://dev.entidi.com/p/adg/issues/">bug tracker</ulink>
22 when a specific issue is addressed;</listitem>
23 <listitem>via <ulink url="http://lists.sourceforge.net/lists/listinfo/adg-devel">mailing list</ulink>
24 if the patch probably needs further discussion;</listitem>
25 <listitem>send a pull request in any of the public git repository listed
26 belowif you are already registered in one of them.</listitem>
29 <para>The project uses <ulink url="http://git-scm.com/">git</ulink> as version control system.
30 In the following the public repository that we keep up to date:</para>
33 <listitem><ulink url="http://github.com/ntd/adg">GitHub</ulink></listitem>
34 <listitem><ulink url="http://gitorious.org/adg">Gitorious</ulink></listitem>
35 <listitem><ulink url="http://p.sf.net/adg/git">SourceForge</ulink></listitem>
36 <listitem><ulink url="http://repo.or.cz/w/adg.git">repo.cz</ulink></listitem>
39 <para>The preferred way to create a patch is by using <command>git format-patch</command> to
40 generate the file. A typical usage involves the following steps:</para>
42 <informalexample><programlisting language="sh">git clone git://repo.or.cz/adg.git
46 # Write the commit message
47 git format-patch HEAD^
48 # A 0001-* file with your patch has been created</programlisting></informalexample>
51 <simplesect id="HACKING.style">
52 <title>Coding style</title>
54 <para>The easiest way to hack the core of the ADG project (plain C language)
55 is by following the code close to the place you are hacking, but if you
56 want a written down set of rules, the coding style is loosely based on
57 the <ulink url="http://www.netbsd.org/docs/kernel/programming.html">kernel normal form</ulink>
58 style using a 4 space indentation. The tabs should be expanded to spaces
59 and there must not be any trailing spaces at the end of line or empty
60 lines at the end of a file (they are a PITA in version control). A
61 common way to deal with the latter problem is to enable the
62 <ulink url="http://dev.entidi.com/p/adg/source/tree/master/nodist/pre-commit">pre-commit</ulink>
63 hook in your own repository:</para>
65 <informalexample><programlisting language="sh">cd adg
66 cp nodist/pre-commit .git/hooks
67 chmod 0755 .git/hooks/pre-commit</programlisting></informalexample>
70 <simplesect id="HACKING.API">
71 <title>API conventions</title>
73 <para>The rules used by the API are more rigid and they are strictly tied to the
74 <ulink url="http://library.gnome.org/devel/gobject/stable/gtype-conventions.html">GObject</ulink>
75 API conventions. The prefixes must be <code>ADG</code>, <code>Adg</code> and <code>adg</code> for the ADG canvas
76 and <code>CPML</code>, <code>Cpml</code> and <code>cpml</code> for the cairo path manipulation library. In
77 addition, the following suggestions/rules also apply:</para>
79 <informalexample><programlisting language="C">/* Method emitting "signal-name" */
80 void adg_object_signal_name (AdgObject *object,
81 /* Other parameters */);
83 /* Generic setter method */
84 void adg_object_set_value (AdgObject *object,
85 const AdgValue *value);
86 /* Setter method for boolean values */
87 void adg_object_switch_boolean_value (AdgObject *object,
90 /* Generic getter method */
91 const AdgValue *adg_object_get_value (AdgObject *object);
93 /* Getter method for boolean values */
94 gboolean adg_object_has_boolean_value (AdgObject *object);
96 /* Getter method for reference counted values: an object could be
97 * referenced and unreferenced also if read-only, so no const needed */
98 AdgObject * adg_object_get_object (AdgObject *object);
100 /* Getter method returning scalar values must not be const:
101 * they are passed by value */
102 ScalarType adg_object_get_scalar_value (AdgObject *object);
104 /* Alternative getter method to use when the generic syntax is
105 * not allowed, such as when the value is dynamically generated */
106 void adg_object_put_value (AdgObject *object,
109 /* Different version of the same setter method for pair values */
110 void adg_object_set_value (AdgObject *object,
111 const AdgPair *value);
112 void adg_object_set_value_explicit (AdgObject *object,
115 void adg_object_set_value_from_model (AdgADim *adim,
117 const gchar *named_pair);</programlisting></informalexample>
119 <para>The methods should be grouped by argument, that is methods working on the
120 same subject should be adjacents. The constructors must be the first ones
121 while the helper methods for signal emission should be the last ones.
122 It is preferable to keep the setter before the getter in the list.</para>
124 <para>For any other non-C contribution (makefiles, translations, bindings,
125 documentation, whatever) just follow the surronding text using a bit of
126 common sense. When no surrounding text exists, use your preferred style
127 and use it consistently.</para>
131 <simplesect id="HACKING.Use">
132 <title>How the API should be used</title>
134 <para>The getter methods must be considered read-only. Although in some
135 circumstances some of them do not return a <emphasis>const</emphasis> value,
136 this is done just to allow referencing and unreferencing an object,
137 but still that object should be considered read-only. This means to
138 change a property you should write something along these lines:</para>
139 <informalexample><programlisting language="C">CpmlExtents extents;
141 cpml_extents_copy(&extents, adg_entity_get_extents(entity));
142 /* Modify extents... */
143 adg_entity_set_extents(entity, &extents);</programlisting></informalexample>
145 <para>The <emphasis>put</emphasis> version of a getter usually does not have the setter
146 counterpart (because the returned value is typically computed) so the
147 above will be reduced to:</para>
148 <informalexample><programlisting language="C">CpmlExtents extents;
150 cpml_segment_put_extents(segment, &extents);
151 /* Use extents... */</programlisting></informalexample>